mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 21:05:21 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Instances expose ~23 experimental feature settings, all declared in one shared zod schema and toggled per instance > - Deployment tooling and hosting control planes have no machine-readable list of those feature keys for a given release — the schema is only reachable from code that imports the package > - Any external system that references feature keys therefore does so as free text, and typos drift silently > - This pull request derives a versioned `feature-catalog.json` build artifact from the schema, with a compiler-checked metadata map so the schema stays the single source of truth > - The benefit is a stable contract external tooling can validate feature-key references against, with zero runtime behavior change ## Linked Issues or Issue Description No public issue exists; `feature_request` template fields: **Problem or motivation:** External deployment tooling cannot enumerate or validate an instance's feature keys per release; free-text references fail silently when keys are renamed or removed. **Proposed solution:** A metadata map keyed by the settings schema's own keys (compiler flags drift) plus a build step emitting `feature-catalog.json` (keys, tiers, defaults, `catalogVersion`) as a release artifact. **Alternatives considered:** A hand-maintained catalog file (drifts from the schema); serving the schema from a runtime API (requires a running instance at validation time — a build artifact works offline and pins to a release). **Roadmap alignment:** Supports the in-progress "Cloud deployments" milestone in `ROADMAP.md`. ## What Changed Adds a metadata map (title, description, tier, cloud/self-hosted defaults) keyed by the keys of `instanceExperimentalSettingsSchema`, so the schema stays the single source of truth and the compiler flags any drift. A new build step (`build:feature-catalog --version <v>`) emits `feature-catalog.json` — all 23 feature keys, their tiers, and a `catalogVersion` — as a release artifact that managed-hosting control planes can validate feature-flag writes against. No runtime behavior changes. - New `packages/shared/src/feature-catalog.ts`: per-flag metadata map keyed by a type derived from the settings schema (adding/removing/renaming a flag without updating the map is a compile error), plus `featureCatalogArtifactSchema` and `buildFeatureCatalogArtifact`/`renderFeatureCatalogArtifact` for the artifact - New `scripts/generate-feature-catalog.ts` wired as `pnpm build:feature-catalog --version <v>` - `scripts/create-github-release.sh` generates the artifact and uploads it as a GitHub Release asset (with a dry-run preview line) - Tests in `packages/shared/src/feature-catalog.test.ts` ## Verification - `vitest run packages/shared/src/feature-catalog.test.ts` — 9 tests: schema-key coverage, drift detection, artifact shape - `pnpm --filter @paperclipai/shared typecheck` - Artifact generation run end-to-end: `pnpm build:feature-catalog --version 0.0.0-test` emits 23 keys with `catalogVersion` ## Risks Low risk — no runtime behavior changes; the change is metadata, a build script, and a release-artifact emission step only. ## Model Used Claude Fable 5 (`claude-fable-5`), extended thinking, agentic tool use; independently peer-reviewed by a second AI agent before push ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
101 lines
6.4 KiB
JSON
101 lines
6.4 KiB
JSON
{
|
|
"name": "paperclip",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"postinstall": "node scripts/link-plugin-dev-sdk.mjs",
|
|
"preflight:workspace-links": "node cli/node_modules/tsx/dist/cli.mjs scripts/ensure-workspace-package-links.ts",
|
|
"dev": "pnpm --filter @paperclipai/server exec tsx ../scripts/dev-runner.ts watch",
|
|
"dev:watch": "pnpm --filter @paperclipai/server exec tsx ../scripts/dev-runner.ts watch",
|
|
"dev:once": "pnpm --filter @paperclipai/server exec tsx ../scripts/dev-runner.ts dev",
|
|
"dev:list": "pnpm --filter @paperclipai/server exec tsx ../scripts/dev-service.ts list",
|
|
"dev:stop": "pnpm --filter @paperclipai/server exec tsx ../scripts/dev-service.ts stop",
|
|
"dev:server": "pnpm --filter @paperclipai/server dev",
|
|
"dev:ui": "pnpm --filter @paperclipai/ui dev",
|
|
"storybook": "pnpm --filter @paperclipai/ui storybook",
|
|
"build-storybook": "pnpm --filter @paperclipai/ui build-storybook",
|
|
"build": "pnpm run preflight:workspace-links && pnpm -r build",
|
|
"build:feature-catalog": "node cli/node_modules/tsx/dist/cli.mjs scripts/generate-feature-catalog.ts",
|
|
"typecheck": "pnpm run preflight:workspace-links && pnpm -r typecheck",
|
|
"typecheck:build-gaps": "pnpm run preflight:workspace-links && pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && pnpm --filter @paperclipai/server build && node scripts/run-typecheck-build-gaps.mjs",
|
|
"test": "pnpm run test:run",
|
|
"test:watch": "pnpm run preflight:workspace-links && vitest",
|
|
"test:run": "pnpm run preflight:workspace-links && node scripts/run-vitest-stable.mjs",
|
|
"test:run:general": "pnpm run preflight:workspace-links && pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && node scripts/run-vitest-stable.mjs --mode general",
|
|
"test:run:serialized": "pnpm run preflight:workspace-links && pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && node scripts/run-vitest-stable.mjs --mode serialized",
|
|
"db:generate": "pnpm --filter @paperclipai/db generate",
|
|
"db:migrate": "pnpm --filter @paperclipai/db migrate",
|
|
"issue-references:backfill": "pnpm run preflight:workspace-links && tsx scripts/backfill-issue-reference-mentions.ts",
|
|
"secrets:migrate-inline-env": "tsx scripts/migrate-inline-env-secrets.ts",
|
|
"db:backup": "./scripts/backup-db.sh",
|
|
"paperclipai": "node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts",
|
|
"build:npm": "./scripts/build-npm.sh",
|
|
"release": "./scripts/release.sh",
|
|
"release:canary": "./scripts/release.sh canary",
|
|
"release:stable": "./scripts/release.sh stable",
|
|
"release:github": "./scripts/create-github-release.sh",
|
|
"release:rollback": "./scripts/rollback-latest.sh",
|
|
"release:bootstrap-package": "node scripts/bootstrap-npm-package.mjs",
|
|
"check:tokens": "node scripts/check-forbidden-tokens.mjs",
|
|
"check:token-gates": "node scripts/check-token-gates.mjs",
|
|
"check:no-git-push": "node scripts/check-no-git-push.mjs",
|
|
"test:check-no-git-push": "node --test scripts/check-no-git-push.test.mjs",
|
|
"test:hermes-gateway-smoke": "node --test scripts/smoke/hermes-gateway-smoke.test.mjs",
|
|
"docs:dev": "cd docs && npx mintlify dev",
|
|
"smoke:hermes-gateway-join": "./scripts/smoke/hermes-gateway-join.sh",
|
|
"smoke:hermes-gateway-e2e": "./scripts/smoke/hermes-gateway-e2e.sh",
|
|
"smoke:openclaw-join": "./scripts/smoke/openclaw-join.sh",
|
|
"smoke:openclaw-docker-ui": "./scripts/smoke/openclaw-docker-ui.sh",
|
|
"smoke:openclaw-sse-standalone": "./scripts/smoke/openclaw-sse-standalone.sh",
|
|
"smoke:mcp-fixtures": "node scripts/smoke/mcp-fixture-harness.mjs",
|
|
"smoke:pipelines-tutorial": "./scripts/smoke/pipelines-tutorial-smoke.sh",
|
|
"smoke:terminal-bench-loop-skill": "node scripts/smoke/terminal-bench-loop-skill-smoke.mjs",
|
|
"test:release-registry": "node --test scripts/verify-release-registry-state.test.mjs scripts/release-package-map.test.mjs scripts/check-release-package-bootstrap.test.mjs scripts/check-no-git-push.test.mjs scripts/release-lib.test.mjs scripts/release-registry-versions.test.mjs scripts/link-plugin-dev-sdk.test.js scripts/acpx-patch-packaging.test.mjs",
|
|
"storybook-visual:baseline": "node scripts/storybook-visual-baseline.mjs",
|
|
"test:storybook-visual": "node scripts/storybook-visual-baseline.mjs download && node scripts/storybook-visual-baseline.mjs verify && pnpm build-storybook && npx playwright test --config tests/storybook-visual/playwright.config.ts",
|
|
"test:storybook-visual:update": "node scripts/storybook-visual-baseline.mjs download && pnpm build-storybook && npx playwright test --config tests/storybook-visual/playwright.config.ts --update-snapshots && node scripts/storybook-visual-baseline.mjs pack",
|
|
"test:e2e": "npx playwright test --config tests/e2e/playwright.config.ts",
|
|
"test:e2e:mcp-user-stories": "node scripts/e2e-mcp-user-stories.mjs",
|
|
"test:e2e:headed": "npx playwright test --config tests/e2e/playwright.config.ts --headed",
|
|
"test:e2e:multiuser-authenticated": "npx playwright test --config tests/e2e/playwright-multiuser-authenticated.config.ts",
|
|
"evals:smoke": "cd evals/promptfoo && npx promptfoo@0.103.3 eval",
|
|
"test:release-smoke": "npx playwright test --config tests/release-smoke/playwright.config.ts",
|
|
"test:release-smoke:headed": "npx playwright test --config tests/release-smoke/playwright.config.ts --headed",
|
|
"metrics:paperclip-commits": "tsx scripts/paperclip-commit-metrics.ts",
|
|
"perf:issue-chat-long-thread": "node scripts/measure-issue-chat-long-thread.mjs",
|
|
"connections:ingest-app-definitions": "node scripts/ingest-app-definitions.mjs"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.61.1",
|
|
"cross-env": "^10.1.0",
|
|
"esbuild": "^0.28.1",
|
|
"typescript": "^5.7.3",
|
|
"vitest": "^4.1.10"
|
|
},
|
|
"engines": {
|
|
"node": ">=20"
|
|
},
|
|
"packageManager": "pnpm@9.15.4",
|
|
"pnpm": {
|
|
"patchedDependencies": {
|
|
"embedded-postgres@18.1.0-beta.16": "patches/embedded-postgres@18.1.0-beta.16.patch",
|
|
"acpx@0.12.0": "patches/acpx@0.12.0.patch"
|
|
},
|
|
"overrides": {
|
|
"rollup": ">=4.59.0",
|
|
"react": "^19.2.7",
|
|
"react-dom": "^19.2.7",
|
|
"lexical": "0.46.0",
|
|
"@lexical/clipboard": "0.46.0",
|
|
"@lexical/link": "0.46.0",
|
|
"@lexical/list": "0.46.0",
|
|
"@lexical/markdown": "0.46.0",
|
|
"@lexical/plain-text": "0.46.0",
|
|
"@lexical/react": "0.46.0",
|
|
"@lexical/rich-text": "0.46.0",
|
|
"@lexical/selection": "0.46.0",
|
|
"@lexical/utils": "0.46.0"
|
|
}
|
|
}
|
|
}
|