@yss123/cage-cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -3
- package/bin/cage.js +5 -0
- package/bin/create-cage-app.js +5 -0
- package/dist/analyze.d.ts +16 -0
- package/dist/analyze.js +18 -2
- package/dist/analyze.js.map +1 -1
- package/dist/baseline.d.ts +8 -0
- package/dist/baseline.js +13 -0
- package/dist/baseline.js.map +1 -1
- package/dist/bootstrap.d.ts +20 -0
- package/dist/bootstrap.js +75 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/budget.d.ts +7 -0
- package/dist/budget.js +49 -5
- package/dist/budget.js.map +1 -1
- package/dist/capabilities.d.ts +38 -0
- package/dist/capabilities.js +133 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/config.d.ts +31 -2
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +14 -0
- package/dist/context.js +35 -2
- package/dist/context.js.map +1 -1
- package/dist/create-prompt.d.ts +7 -0
- package/dist/create-prompt.js +12 -0
- package/dist/create-prompt.js.map +1 -1
- package/dist/create.d.ts +21 -1
- package/dist/create.js +23 -1
- package/dist/create.js.map +1 -1
- package/dist/derive.d.ts +23 -0
- package/dist/derive.js +40 -0
- package/dist/derive.js.map +1 -1
- package/dist/dev.d.ts +6 -0
- package/dist/dev.js +11 -0
- package/dist/dev.js.map +1 -1
- package/dist/doctor.d.ts +98 -0
- package/dist/doctor.js +93 -0
- package/dist/doctor.js.map +1 -0
- package/dist/env.d.ts +6 -0
- package/dist/env.js +11 -0
- package/dist/env.js.map +1 -1
- package/dist/findings.d.ts +27 -0
- package/dist/findings.js +20 -0
- package/dist/findings.js.map +1 -1
- package/dist/gen/contracts.d.ts +28 -0
- package/dist/gen/contracts.js +52 -12
- package/dist/gen/contracts.js.map +1 -1
- package/dist/gen/index.d.ts +26 -0
- package/dist/gen/index.js +69 -1
- package/dist/gen/index.js.map +1 -1
- package/dist/gen/zod-code.d.ts +42 -0
- package/dist/gen/zod-code.js +178 -16
- package/dist/gen/zod-code.js.map +1 -1
- package/dist/graph-approvals.d.ts +60 -0
- package/dist/graph-approvals.js +80 -0
- package/dist/graph-approvals.js.map +1 -0
- package/dist/graph-business.d.ts +135 -0
- package/dist/graph-business.js +404 -0
- package/dist/graph-business.js.map +1 -0
- package/dist/graph-command.d.ts +17 -0
- package/dist/graph-command.js +21 -0
- package/dist/graph-command.js.map +1 -1
- package/dist/graph-model.d.ts +44 -0
- package/dist/graph-model.js +36 -3
- package/dist/graph-model.js.map +1 -1
- package/dist/graph-presentation.d.ts +16 -0
- package/dist/graph-presentation.js +10 -1
- package/dist/graph-presentation.js.map +1 -1
- package/dist/graph-query.d.ts +95 -0
- package/dist/graph-query.js +62 -0
- package/dist/graph-query.js.map +1 -1
- package/dist/graph-relations.d.ts +20 -0
- package/dist/graph-relations.js +34 -4
- package/dist/graph-relations.js.map +1 -1
- package/dist/graph-search.d.ts +35 -0
- package/dist/graph-search.js +36 -0
- package/dist/graph-search.js.map +1 -1
- package/dist/graph-snapshot.d.ts +26 -0
- package/dist/graph-snapshot.js +30 -1
- package/dist/graph-snapshot.js.map +1 -1
- package/dist/graph.d.ts +13 -2
- package/dist/graph.js +59 -4
- package/dist/graph.js.map +1 -1
- package/dist/impact.d.ts +50 -0
- package/dist/impact.js +62 -2
- package/dist/impact.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +12 -0
- package/dist/init.js +15 -0
- package/dist/init.js.map +1 -1
- package/dist/load.d.ts +10 -0
- package/dist/load.js +15 -0
- package/dist/load.js.map +1 -1
- package/dist/main.d.ts +6 -0
- package/dist/main.js +93 -5
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +12 -0
- package/dist/migrate.js +17 -0
- package/dist/migrate.js.map +1 -1
- package/dist/ontology.d.ts +67 -2
- package/dist/ontology.js +89 -2
- package/dist/ontology.js.map +1 -1
- package/dist/process-rules.d.ts +21 -0
- package/dist/process-rules.js +100 -0
- package/dist/process-rules.js.map +1 -0
- package/dist/process.d.ts +32 -0
- package/dist/process.js +32 -0
- package/dist/process.js.map +1 -1
- package/dist/project-structure.d.ts +5 -0
- package/dist/project-structure.js +10 -0
- package/dist/project-structure.js.map +1 -1
- package/dist/registration.d.ts +16 -0
- package/dist/registration.js +56 -0
- package/dist/registration.js.map +1 -0
- package/dist/rules.d.ts +52 -0
- package/dist/rules.js +58 -0
- package/dist/rules.js.map +1 -1
- package/dist/runtime-diagnostics.d.ts +27 -0
- package/dist/runtime-diagnostics.js +60 -0
- package/dist/runtime-diagnostics.js.map +1 -0
- package/dist/snapshots.d.ts +40 -0
- package/dist/snapshots.js +62 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/static-check.d.ts +33 -0
- package/dist/static-check.js +37 -1
- package/dist/static-check.js.map +1 -1
- package/dist/sync.d.ts +11 -0
- package/dist/sync.js +65 -8
- package/dist/sync.js.map +1 -1
- package/dist/upgrade.d.ts +16 -0
- package/dist/upgrade.js +21 -0
- package/dist/upgrade.js.map +1 -1
- package/dist/verify.d.ts +14 -0
- package/dist/verify.js +19 -0
- package/dist/verify.js.map +1 -1
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -1
- package/graph-ui/app.js +321 -27
- package/graph-ui/approval-flow.js +165 -0
- package/graph-ui/business.css +985 -0
- package/graph-ui/business.js +549 -0
- package/graph-ui/flowchart-interaction.js +177 -0
- package/graph-ui/flowchart.js +1059 -0
- package/graph-ui/graph-approvals.js +79 -0
- package/graph-ui/graph-business.js +403 -0
- package/graph-ui/graph-model.js +36 -3
- package/graph-ui/graph-relations.js +34 -4
- package/graph-ui/graph-search.js +36 -0
- package/graph-ui/index.html +26 -12
- package/graph-ui/model.js +28 -0
- package/graph-ui/relations.js +4 -0
- package/graph-ui/structure.js +44 -0
- package/graph-ui/style.css +12 -0
- package/package.json +6 -4
- package/templates/app/.dockerignore +2 -0
- package/templates/app/.env.example +10 -0
- package/templates/app/AGENTS.md +49 -9
- package/templates/app/README.md +4 -1
- package/templates/app/_gitignore +1 -0
- package/templates/app/apps/api/package.json +2 -2
- package/templates/app/apps/api/src/main.ts +5 -1
- package/templates/app/apps/api/src/worker.ts +3 -0
- package/templates/app/apps/web/index.html +1 -0
- package/templates/app/apps/web/package.json +7 -3
- package/templates/app/apps/web/src/app/app.tsx +122 -12
- package/templates/app/apps/web/src/app/styles/global.css +88 -8
- package/templates/app/apps/web/src/app/use-session.ts +43 -0
- package/templates/app/apps/web/src/app/workspace-layout.tsx +58 -19
- package/templates/app/apps/web/src/main.tsx +5 -0
- package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +11 -0
- package/templates/app/apps/web/src/modules/approval/index.ts +4 -0
- package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +20 -1
- package/templates/app/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
- package/templates/app/apps/web/src/modules/inventory/index.ts +4 -0
- package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
- package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
- package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +25 -3
- package/templates/app/apps/web/src/modules/purchase/index.ts +5 -0
- package/templates/app/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-intelligence.css +15 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +52 -22
- package/templates/app/apps/web/src/modules/workspace/index.ts +5 -0
- package/templates/app/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
- package/templates/app/apps/web/src/shared/hooks/use-command.ts +13 -0
- package/templates/app/apps/web/src/shared/lib/error-message.ts +9 -0
- package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/app/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
- package/templates/app/apps/web/src/shared/ui/assistant-panel.css +134 -0
- package/templates/app/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
- package/templates/app/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
- package/templates/app/apps/web/src/shared/ui/attachment-upload.css +28 -0
- package/templates/app/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
- package/templates/app/apps/web/src/shared/ui/notice.tsx +7 -0
- package/templates/app/apps/web/src/shared/ui/page-heading.tsx +7 -0
- package/templates/app/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/app/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/app/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/app/apps/web/vite.config.ts +5 -0
- package/templates/app/cage.config.json +9 -0
- package/templates/app/db/migrations/0002_draft.sql +12 -0
- package/templates/app/db/migrations/0003_draft.sql +8 -0
- package/templates/app/deploy/nginx.conf +52 -0
- package/templates/app/docs/ai/README.md +21 -0
- package/templates/app/docs/ai/architecture.md +26 -0
- package/templates/app/docs/ai/commenting.md +203 -0
- package/templates/app/docs/ai/diagnostics.md +80 -0
- package/templates/app/docs/ai/files.md +93 -0
- package/templates/app/docs/ai/intelligence.md +348 -0
- package/templates/app/docs/ai/ontology-context.md +59 -4
- package/templates/app/docs/ai/primitives.md +33 -0
- package/templates/app/docs/ai/project-structure.md +8 -3
- package/templates/app/docs/ai/purchase-example.md +16 -2
- package/templates/app/docs/ai/recipes.md +9 -1
- package/templates/app/docs/ai/routing.md +86 -0
- package/templates/app/docs/ai/troubleshooting.md +5 -0
- package/templates/app/docs/ai/workflow.md +24 -11
- package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/app/docs/errors/CAGE-APPR-001.md +7 -6
- package/templates/app/docs/errors/CAGE-APPR-002.md +2 -2
- package/templates/app/docs/errors/CAGE-APPR-003.md +1 -1
- package/templates/app/docs/errors/CAGE-APPR-004.md +4 -4
- package/templates/app/docs/errors/CAGE-APPR-005.md +1 -1
- package/templates/app/docs/errors/CAGE-APPR-006.md +12 -6
- package/templates/app/docs/errors/CAGE-APPR-007.md +3 -3
- package/templates/app/docs/errors/CAGE-APPR-010.md +5 -5
- package/templates/app/docs/errors/CAGE-AUDIT-001.md +53 -0
- package/templates/app/docs/errors/CAGE-AUTH-001.md +1 -1
- package/templates/app/docs/errors/CAGE-BIZ-001.md +51 -0
- package/templates/app/docs/errors/CAGE-BIZ-002.md +49 -0
- package/templates/app/docs/errors/CAGE-BUDGET-001.md +1 -1
- package/templates/app/docs/errors/CAGE-BUDGET-002.md +1 -1
- package/templates/app/docs/errors/CAGE-BUDGET-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CMD-002.md +1 -1
- package/templates/app/docs/errors/CAGE-CMD-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-001.md +3 -3
- package/templates/app/docs/errors/CAGE-CONN-002.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-004.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-005.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-006.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-007.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-008.md +5 -5
- package/templates/app/docs/errors/CAGE-CONN-009.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-010.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-011.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-012.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-013.md +49 -0
- package/templates/app/docs/errors/CAGE-CONN-014.md +48 -0
- package/templates/app/docs/errors/CAGE-CONN-015.md +49 -0
- package/templates/app/docs/errors/CAGE-CREATE-001.md +10 -9
- package/templates/app/docs/errors/CAGE-DECL-001.md +2 -2
- package/templates/app/docs/errors/CAGE-DECL-002.md +7 -6
- package/templates/app/docs/errors/CAGE-DECL-003.md +1 -1
- package/templates/app/docs/errors/CAGE-DECL-004.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-001.md +2 -2
- package/templates/app/docs/errors/CAGE-DEP-002.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-003.md +2 -2
- package/templates/app/docs/errors/CAGE-DEP-004.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-005.md +1 -1
- package/templates/app/docs/errors/CAGE-DIAG-001.md +53 -0
- package/templates/app/docs/errors/CAGE-DLQ-001.md +2 -2
- package/templates/app/docs/errors/CAGE-ENV-001.md +4 -4
- package/templates/app/docs/errors/CAGE-ENV-002.md +51 -0
- package/templates/app/docs/errors/CAGE-ENV-003.md +48 -0
- package/templates/app/docs/errors/CAGE-EVENT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-EVENT-002.md +7 -7
- package/templates/app/docs/errors/CAGE-FIELD-001.md +2 -2
- package/templates/app/docs/errors/CAGE-FIELD-002.md +1 -1
- package/templates/app/docs/errors/CAGE-FIELD-003.md +1 -1
- package/templates/app/docs/errors/CAGE-FIELD-004.md +1 -1
- package/templates/app/docs/errors/CAGE-FILE-001.md +56 -0
- package/templates/app/docs/errors/CAGE-GEN-001.md +2 -2
- package/templates/app/docs/errors/CAGE-GEN-002.md +1 -1
- package/templates/app/docs/errors/CAGE-GEN-003.md +53 -0
- package/templates/app/docs/errors/CAGE-GRANT-001.md +3 -3
- package/templates/app/docs/errors/CAGE-GRANT-002.md +2 -2
- package/templates/app/docs/errors/CAGE-GRANT-003.md +7 -6
- package/templates/app/docs/errors/CAGE-IMPACT-001.md +2 -2
- package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -0
- package/templates/app/docs/errors/CAGE-INIT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-003.md +2 -2
- package/templates/app/docs/errors/CAGE-INIT-004.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-005.md +52 -0
- package/templates/app/docs/errors/CAGE-JOB-001.md +1 -1
- package/templates/app/docs/errors/CAGE-JOB-002.md +1 -1
- package/templates/app/docs/errors/CAGE-JOB-003.md +1 -1
- package/templates/app/docs/errors/CAGE-LINT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-001.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-002.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-005.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-001.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-002.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-003.md +3 -3
- package/templates/app/docs/errors/CAGE-NAME-004.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-005.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-006.md +1 -1
- package/templates/app/docs/errors/CAGE-ORG-001.md +7 -6
- package/templates/app/docs/errors/CAGE-PAIR-002.md +6 -5
- package/templates/app/docs/errors/CAGE-QUERY-001.md +1 -1
- package/templates/app/docs/errors/CAGE-QUERY-002.md +2 -2
- package/templates/app/docs/errors/CAGE-QUERY-003.md +7 -6
- package/templates/app/docs/errors/CAGE-REACT-001.md +3 -3
- package/templates/app/docs/errors/CAGE-REACT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-REACT-003.md +50 -0
- package/templates/app/docs/errors/CAGE-READS-001.md +9 -6
- package/templates/app/docs/errors/CAGE-REG-001.md +13 -12
- package/templates/app/docs/errors/CAGE-REG-002.md +2 -1
- package/templates/app/docs/errors/CAGE-REG-003.md +1 -1
- package/templates/app/docs/errors/CAGE-REL-001.md +14 -14
- package/templates/app/docs/errors/CAGE-ROUTE-001.md +7 -6
- package/templates/app/docs/errors/CAGE-SCOPE-001.md +1 -1
- package/templates/app/docs/errors/CAGE-SCOPE-002.md +2 -2
- package/templates/app/docs/errors/CAGE-SECRET-001.md +2 -2
- package/templates/app/docs/errors/CAGE-SECRET-002.md +1 -1
- package/templates/app/docs/errors/CAGE-SENS-001.md +5 -5
- package/templates/app/docs/errors/CAGE-SQL-001.md +1 -1
- package/templates/app/docs/errors/CAGE-SQL-002.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-001.md +3 -3
- package/templates/app/docs/errors/CAGE-STATE-002.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-003.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-004.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-005.md +3 -2
- package/templates/app/docs/errors/CAGE-STATE-010.md +5 -5
- package/templates/app/docs/errors/CAGE-STATE-011.md +5 -5
- package/templates/app/docs/errors/CAGE-STRUCT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-STRUCT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-SYNC-001.md +3 -2
- package/templates/app/docs/errors/CAGE-TEST-001.md +1 -1
- package/templates/app/docs/errors/CAGE-TEST-002.md +50 -0
- package/templates/app/docs/errors/CAGE-TEST-003.md +52 -0
- package/templates/app/docs/errors/CAGE-UNSAFE-001.md +3 -2
- package/templates/app/docs/errors/CAGE-UPGRADE-001.md +2 -2
- package/templates/app/docs/errors/CAGE-WORKER-001.md +48 -0
- package/templates/app/docs/errors/CAGE-WORKER-002.md +50 -0
- package/templates/app/docs/errors/CAGE-WORKER-003.md +48 -0
- package/templates/app/docs/errors/README.md +50 -0
- package/templates/app/package.json +3 -3
- package/templates/app/packages/contracts/package.json +1 -1
- package/templates/app/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/app/packages/contracts/src/aggregates/inventory/index.ts +5 -5
- package/templates/app/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
- package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +26 -12
- package/templates/app/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/app/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/app/packages/contracts/src/index.ts +7 -1
- package/templates/app/packages/contracts/src/queries/index.ts +2 -2
- package/templates/app/packages/domain/package.json +5 -4
- package/templates/app/packages/domain/src/index.ts +4 -0
- package/templates/app/packages/domain/src/integrations/erp.ts +15 -0
- package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
- package/templates/app/packages/domain/src/modules/inventory/index.ts +1 -0
- package/templates/app/packages/domain/src/modules/inventory/inventory.ts +12 -0
- package/templates/app/packages/domain/src/modules/purchase/approvals.ts +22 -1
- package/templates/app/packages/domain/src/modules/purchase/index.ts +1 -0
- package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
- package/templates/app/packages/domain/src/modules/purchase/jobs.ts +5 -0
- package/templates/app/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
- package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +70 -0
- package/templates/app/packages/domain/src/modules/purchase/queries.ts +5 -0
- package/templates/app/packages/domain/src/workflows/purchase-inventory.ts +6 -0
- package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
- package/templates/blank/.dockerignore +2 -0
- package/templates/blank/.env.example +10 -0
- package/templates/blank/AGENTS.md +49 -9
- package/templates/blank/README.md +4 -1
- package/templates/blank/_gitignore +1 -0
- package/templates/blank/apps/api/package.json +1 -1
- package/templates/blank/apps/api/src/main.ts +4 -1
- package/templates/blank/apps/api/src/worker.ts +2 -0
- package/templates/blank/apps/web/index.html +1 -0
- package/templates/blank/apps/web/package.json +7 -3
- package/templates/blank/apps/web/src/app/app.tsx +80 -18
- package/templates/blank/apps/web/src/app/styles/global.css +90 -0
- package/templates/blank/apps/web/src/app/use-session.ts +43 -0
- package/templates/blank/apps/web/src/app/workspace-layout.tsx +30 -5
- package/templates/blank/apps/web/src/main.tsx +5 -0
- package/templates/blank/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +18 -1
- package/templates/blank/apps/web/src/modules/directory/index.ts +7 -0
- package/templates/blank/apps/web/src/modules/directory/pages/user-detail-page.tsx +78 -0
- package/templates/blank/apps/web/src/modules/directory/pages/users-page.tsx +93 -0
- package/templates/blank/apps/web/src/modules/workspace/index.ts +4 -0
- package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +17 -0
- package/templates/blank/apps/web/src/shared/lib/error-message.ts +11 -0
- package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/blank/apps/web/src/shared/ui/brand.tsx +10 -2
- package/templates/blank/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/blank/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/blank/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/blank/apps/web/vite.config.ts +5 -0
- package/templates/blank/deploy/nginx.conf +52 -0
- package/templates/blank/docs/ai/README.md +21 -0
- package/templates/blank/docs/ai/architecture.md +26 -0
- package/templates/blank/docs/ai/commenting.md +203 -0
- package/templates/blank/docs/ai/diagnostics.md +80 -0
- package/templates/blank/docs/ai/files.md +93 -0
- package/templates/blank/docs/ai/intelligence.md +348 -0
- package/templates/blank/docs/ai/ontology-context.md +59 -4
- package/templates/blank/docs/ai/primitives.md +33 -0
- package/templates/blank/docs/ai/project-structure.md +8 -3
- package/templates/blank/docs/ai/purchase-example.md +16 -2
- package/templates/blank/docs/ai/recipes.md +9 -1
- package/templates/blank/docs/ai/routing.md +86 -0
- package/templates/blank/docs/ai/troubleshooting.md +5 -0
- package/templates/blank/docs/ai/workflow.md +24 -11
- package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/blank/docs/errors/CAGE-APPR-001.md +7 -6
- package/templates/blank/docs/errors/CAGE-APPR-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-APPR-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-APPR-004.md +4 -4
- package/templates/blank/docs/errors/CAGE-APPR-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-APPR-006.md +12 -6
- package/templates/blank/docs/errors/CAGE-APPR-007.md +3 -3
- package/templates/blank/docs/errors/CAGE-APPR-010.md +5 -5
- package/templates/blank/docs/errors/CAGE-AUDIT-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-AUTH-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-BIZ-001.md +51 -0
- package/templates/blank/docs/errors/CAGE-BIZ-002.md +49 -0
- package/templates/blank/docs/errors/CAGE-BUDGET-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-BUDGET-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-BUDGET-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CMD-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-CMD-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-CONN-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-006.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-007.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-008.md +5 -5
- package/templates/blank/docs/errors/CAGE-CONN-009.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-010.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-011.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-012.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-013.md +49 -0
- package/templates/blank/docs/errors/CAGE-CONN-014.md +48 -0
- package/templates/blank/docs/errors/CAGE-CONN-015.md +49 -0
- package/templates/blank/docs/errors/CAGE-CREATE-001.md +10 -9
- package/templates/blank/docs/errors/CAGE-DECL-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-DECL-002.md +7 -6
- package/templates/blank/docs/errors/CAGE-DECL-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-DECL-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-DEP-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-003.md +2 -2
- package/templates/blank/docs/errors/CAGE-DEP-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-DIAG-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-DLQ-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-ENV-001.md +4 -4
- package/templates/blank/docs/errors/CAGE-ENV-002.md +51 -0
- package/templates/blank/docs/errors/CAGE-ENV-003.md +48 -0
- package/templates/blank/docs/errors/CAGE-EVENT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-EVENT-002.md +7 -7
- package/templates/blank/docs/errors/CAGE-FIELD-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-FIELD-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-FIELD-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-FIELD-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-FILE-001.md +56 -0
- package/templates/blank/docs/errors/CAGE-GEN-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-GEN-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-GEN-003.md +53 -0
- package/templates/blank/docs/errors/CAGE-GRANT-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-GRANT-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-GRANT-003.md +7 -6
- package/templates/blank/docs/errors/CAGE-IMPACT-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -0
- package/templates/blank/docs/errors/CAGE-INIT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-003.md +2 -2
- package/templates/blank/docs/errors/CAGE-INIT-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-005.md +52 -0
- package/templates/blank/docs/errors/CAGE-JOB-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-JOB-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-JOB-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-LINT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-003.md +3 -3
- package/templates/blank/docs/errors/CAGE-NAME-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-006.md +1 -1
- package/templates/blank/docs/errors/CAGE-ORG-001.md +7 -6
- package/templates/blank/docs/errors/CAGE-PAIR-002.md +6 -5
- package/templates/blank/docs/errors/CAGE-QUERY-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-QUERY-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-QUERY-003.md +7 -6
- package/templates/blank/docs/errors/CAGE-REACT-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-REACT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-REACT-003.md +50 -0
- package/templates/blank/docs/errors/CAGE-READS-001.md +9 -6
- package/templates/blank/docs/errors/CAGE-REG-001.md +13 -12
- package/templates/blank/docs/errors/CAGE-REG-002.md +2 -1
- package/templates/blank/docs/errors/CAGE-REG-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-REL-001.md +14 -14
- package/templates/blank/docs/errors/CAGE-ROUTE-001.md +7 -6
- package/templates/blank/docs/errors/CAGE-SCOPE-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-SCOPE-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-SECRET-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-SECRET-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-SENS-001.md +5 -5
- package/templates/blank/docs/errors/CAGE-SQL-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-SQL-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-STATE-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-005.md +3 -2
- package/templates/blank/docs/errors/CAGE-STATE-010.md +5 -5
- package/templates/blank/docs/errors/CAGE-STATE-011.md +5 -5
- package/templates/blank/docs/errors/CAGE-STRUCT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-STRUCT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-SYNC-001.md +3 -2
- package/templates/blank/docs/errors/CAGE-TEST-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-TEST-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-TEST-003.md +52 -0
- package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +3 -2
- package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-WORKER-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-WORKER-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-WORKER-003.md +48 -0
- package/templates/blank/docs/errors/README.md +50 -0
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +5 -1
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +3 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +122 -12
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +88 -8
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/use-session.ts +43 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +58 -19
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +11 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +20 -1
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.tsx +25 -3
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-intelligence.css +15 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +52 -22
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/hooks/use-command.ts +13 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +9 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.css +134 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.css +28 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +7 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +7 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/blank/docs/examples/purchase-admin/cage.config.json +9 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +5 -5
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +26 -12
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +7 -1
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +2 -2
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +15 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/intelligence.ts +20 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +1 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +12 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +22 -1
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +1 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +70 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +6 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -0
- package/templates/blank/package.json +3 -3
- package/templates/blank/packages/contracts/package.json +1 -1
- package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/blank/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/blank/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/blank/packages/contracts/src/index.ts +1 -1
- package/templates/blank/packages/contracts/src/queries/index.ts +1 -1
- package/templates/blank/packages/domain/package.json +5 -4
- package/templates/blank/packages/domain/src/index.ts +2 -1
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @yss123/cage-cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Cage 是通过 TypeScript 声明业务、由框架统一执行权限和数据规则的中后台框架。此包是框架的一部分。
|
|
3
|
+
Cage 的开发命令行:创建项目,抽取领域声明,生成契约与迁移草稿,检查图规则与目录边界,浏览业务图谱,查询能力和运行诊断,并管理开发进程及显式迁移。CLI 是开发与部署工具,不能代替业务命令或自动授予生产权限。
|
|
6
4
|
|
|
7
5
|
## 使用
|
|
8
6
|
|
|
@@ -12,6 +10,50 @@ pnpm add -D @yss123/cage-cli
|
|
|
12
10
|
|
|
13
11
|
首次使用建议通过脚手架创建完整项目,所需依赖由模板统一配置。需要 Node.js 24 或更新版本。
|
|
14
12
|
|
|
13
|
+
## 从零开始
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
pnpm exec cage create my-app --template blank
|
|
17
|
+
cd my-app
|
|
18
|
+
pnpm install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
在新项目中复制 `.env.example` 为 `.env`,只在本地填写已有 PostgreSQL 数据库的 `CAGE_ADMIN_DATABASE_URL`。然后执行:
|
|
22
|
+
|
|
23
|
+
```powershell
|
|
24
|
+
pnpm exec cage init
|
|
25
|
+
pnpm build:app
|
|
26
|
+
pnpm gen
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
审查 `db/migrations` 的变更后,再执行:
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
pnpm migrate
|
|
33
|
+
pnpm exec cage bootstrap --credentials-file .cage/admin-credentials.json
|
|
34
|
+
pnpm dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`init` 准备账号、schema 权限和本地连接配置,不创建数据库、不安装 PostgreSQL 或启动 Docker。`gen` 只生成文件,`migrate` 才变更数据库;bootstrap 显式交付初始凭据,不把它们输出到日志或提交源码。
|
|
38
|
+
|
|
39
|
+
## 日常开发命令
|
|
40
|
+
|
|
41
|
+
以下命令在应用根目录运行;`cage.config.json` 定位 domain、contracts、迁移和模块结构。
|
|
42
|
+
|
|
43
|
+
| 命令 | 解决的问题 |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `pnpm exec cage check` | 声明、目录、依赖与本体图规则检查 |
|
|
46
|
+
| `pnpm exec cage gen` | 生成前端 contracts、SQL、状态图和迁移草稿,不手改生成物 |
|
|
47
|
+
| `pnpm exec cage capabilities "文件" --format json` | 查当前已安装框架的公开 API 与签名 |
|
|
48
|
+
| `pnpm exec cage context "需求关键词"` | 查本应用相关节点、源码和候选证据 |
|
|
49
|
+
| `pnpm exec cage graph` | 打开可交互业务图谱 |
|
|
50
|
+
| `pnpm exec cage doctor` | 区分注册、生成、迁移、授权和实际进程状态;unknown 不是通过 |
|
|
51
|
+
| `pnpm exec cage verify` | 汇总项目门禁与测试;数据库测试需要独立测试配置 |
|
|
52
|
+
| `pnpm exec cage sync` | 更新 AGENTS 框架托管区,保留标记外业务约定 |
|
|
53
|
+
| `pnpm exec cage upgrade` | 框架升级辅助与检查,使用前阅读当前版本升级说明 |
|
|
54
|
+
|
|
55
|
+
此外提供 `analyze/impact/test/budget` 等维护入口。可用 `pnpm exec cage --help` 查询参数;包根导出分析、生成、诊断等可组合函数,普通项目优先使用命令行,避免依赖内部文件路径。
|
|
56
|
+
|
|
15
57
|
`pnpm exec cage create my-app` 交互选择空白业务项目或采购示例项目;也可显式指定 `--template blank` 或 `--template purchase`。省略目录时可交互输入,非交互终端必须同时提供目录与模板。`--framework-path F:/cage` 可链接已构建的本地框架。
|
|
16
58
|
|
|
17
59
|
自 `0.2.0` 起,两种产物都包含根目录 `AGENTS.md`、`docs/ai` 业务开发教材和 `docs/errors` 离线错误码册。空白项目只运行组织模型,采购参考代码在 `docs/examples/purchase-admin`;采购项目运行完整演示链路。让 Codex 等编程工具先读 `AGENTS.md`,无需另行克隆框架源码。
|
|
@@ -20,6 +62,8 @@ pnpm add -D @yss123/cage-cli
|
|
|
20
62
|
|
|
21
63
|
## 用本体图开发业务
|
|
22
64
|
|
|
65
|
+
`pnpm exec cage graph` 默认打开业务地图:业务板块 → 流程入口 → 流程图 → 实现代码。板块按模块目录收纳对象,未分模块的项目按对象展示;可通过 `graph.labels` 的 `module:模块目录名` 设置板块中文标题。流程图使用业务节点、审批菱形及方向箭头,保留同事务、异步、条件映射和审批分支。普通滚轮缩放,拖动空白处平移,拖动节点时连线跟随;提供抓手、缩放比例、适应、重排和展开画布,支持横向/纵向布局。点击节点查看同一次抽取的声明代码,保留当前视野与手动布局。地址支持分享、刷新与前进后退;“对象与字段”“完整本体”和复制 AI 上下文仍可使用。
|
|
66
|
+
|
|
23
67
|
在应用根目录执行:
|
|
24
68
|
|
|
25
69
|
```powershell
|
package/bin/cage.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* npm cage 可执行包装器,保留 shebang 并调用已构建 main。
|
|
4
|
+
* Promise 完成后设置退出码;异常只打印 message,具体受控诊断由命令模块负责。
|
|
5
|
+
* 不强制 process.exit,让开发服务等句柄按自己的生命周期退出;运行前必须已有 dist。
|
|
6
|
+
*/
|
|
2
7
|
import { main } from '../dist/main.js';
|
|
3
8
|
main().then((code) => { process.exitCode = code; }).catch((error) => {
|
|
4
9
|
console.error(error.message);
|
package/bin/create-cage-app.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* create-cage-app 的薄包装器,为同一 CLI main 前置 create 子命令。
|
|
4
|
+
* 透传用户参数并设置返回退出码,异常打印 message 后标记失败。
|
|
5
|
+
* 不复制第二套脚手架实现,模板选择、写盘和取消行为由 main/create 模块统一负责。
|
|
6
|
+
*/
|
|
2
7
|
import { main } from '../dist/main.js';
|
|
3
8
|
main(['create', ...process.argv.slice(2)]).then((code) => { process.exitCode = code; }).catch((error) => {
|
|
4
9
|
console.error(error.message);
|
package/dist/analyze.d.ts
CHANGED
|
@@ -2,17 +2,33 @@ import { type CageConfig } from './config.js';
|
|
|
2
2
|
import { type Finding } from './findings.js';
|
|
3
3
|
import { type Ontology } from './ontology.js';
|
|
4
4
|
/** 静态检查先于模块求值;发现动态声明或 IO 时不执行模块。 */
|
|
5
|
+
/**
|
|
6
|
+
* 执行当前应用的声明检查与语义抽取,不运行具体业务命令。
|
|
7
|
+
* 静态错误时返回已有 source/findings;可求值时继续附注册表、本体及可选导出链。
|
|
8
|
+
* @param cfg 应用目录和 domain 入口配置。
|
|
9
|
+
* @param opts base 用于事件兼容检查,write 才保存当前图,registration 强制收集完整导出证据。
|
|
10
|
+
* @returns 分阶段分析结果;模块导入、注册或文件 IO 异常直接抛出。
|
|
11
|
+
*/
|
|
5
12
|
export declare function analyze(cfg: CageConfig, opts?: {
|
|
6
13
|
base?: Ontology;
|
|
7
14
|
write?: boolean;
|
|
15
|
+
registration?: boolean;
|
|
8
16
|
}): Promise<{
|
|
9
17
|
source: import("./static-check.js").StaticResult;
|
|
10
18
|
findings: Finding[];
|
|
11
19
|
registry?: undefined;
|
|
12
20
|
graph?: undefined;
|
|
21
|
+
registration?: undefined;
|
|
13
22
|
} | {
|
|
14
23
|
source: import("./static-check.js").StaticResult;
|
|
15
24
|
registry: import("@yss123/cage-kernel").Registry;
|
|
16
25
|
graph: Ontology;
|
|
17
26
|
findings: Finding[];
|
|
27
|
+
registration: {
|
|
28
|
+
name: string;
|
|
29
|
+
file: string;
|
|
30
|
+
line: number;
|
|
31
|
+
exportedAs: string[];
|
|
32
|
+
chain: string[];
|
|
33
|
+
}[] | undefined;
|
|
18
34
|
}>;
|
package/dist/analyze.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 声明分析总入口,供 check、gen、verify、doctor 与本体快照共同调用。
|
|
3
|
+
* 先检查目录、顶层声明及禁止的 IO,再导入领域入口构建注册表、抽取本体并运行图规则。
|
|
4
|
+
* 这里只求值声明,不执行命令;write 选项才会更新当前本体文件,静态错误会阻止模块求值。
|
|
5
|
+
*/
|
|
1
6
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
7
|
import { abs } from './config.js';
|
|
3
8
|
import { errorsOnly } from './findings.js';
|
|
@@ -6,23 +11,34 @@ import { extract } from './ontology.js';
|
|
|
6
11
|
import { runRules } from './rules.js';
|
|
7
12
|
import { staticCheck, unexportedFindings } from './static-check.js';
|
|
8
13
|
import { checkProjectStructure } from './project-structure.js';
|
|
14
|
+
import { registrationEvidence } from './registration.js';
|
|
9
15
|
/** 静态检查先于模块求值;发现动态声明或 IO 时不执行模块。 */
|
|
16
|
+
/**
|
|
17
|
+
* 执行当前应用的声明检查与语义抽取,不运行具体业务命令。
|
|
18
|
+
* 静态错误时返回已有 source/findings;可求值时继续附注册表、本体及可选导出链。
|
|
19
|
+
* @param cfg 应用目录和 domain 入口配置。
|
|
20
|
+
* @param opts base 用于事件兼容检查,write 才保存当前图,registration 强制收集完整导出证据。
|
|
21
|
+
* @returns 分阶段分析结果;模块导入、注册或文件 IO 异常直接抛出。
|
|
22
|
+
*/
|
|
10
23
|
export async function analyze(cfg, opts = {}) {
|
|
11
24
|
const source = staticCheck(cfg);
|
|
12
25
|
source.findings.push(...checkProjectStructure(cfg));
|
|
13
26
|
if (errorsOnly(source.findings).length)
|
|
14
27
|
return { source, findings: source.findings };
|
|
15
28
|
const { mod, registry } = await loadRegistry(abs(cfg, cfg.domain));
|
|
29
|
+
const exportedNames = new Set(Object.keys(mod));
|
|
30
|
+
// Common explicit exports need no second TS program. Resolve aliases only for apparent gaps or a full doctor report.
|
|
31
|
+
const registration = opts.registration || source.sites.some(site => !exportedNames.has(site.exportName)) ? registrationEvidence(cfg, source.sites) : undefined;
|
|
16
32
|
const graph = extract(registry, source.sites, source.unsafeCount);
|
|
17
33
|
const findings = [
|
|
18
34
|
...source.findings,
|
|
19
|
-
...unexportedFindings(source.sites, new Set(
|
|
35
|
+
...unexportedFindings(source.sites, registration ? new Set(registration.filter(entry => entry.exportedAs.length).map(entry => entry.name)) : exportedNames),
|
|
20
36
|
...runRules(graph, opts.base),
|
|
21
37
|
];
|
|
22
38
|
if (opts.write) {
|
|
23
39
|
mkdirSync(abs(cfg, '.cage'), { recursive: true });
|
|
24
40
|
writeFileSync(abs(cfg, '.cage/ontology.json'), JSON.stringify(graph, null, 2) + '\n');
|
|
25
41
|
}
|
|
26
|
-
return { source, registry, graph, findings };
|
|
42
|
+
return { source, registry, graph, findings, registration };
|
|
27
43
|
}
|
|
28
44
|
//# sourceMappingURL=analyze.js.map
|
package/dist/analyze.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,GAAG,EAAmB,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,UAAU,EAAgB,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,OAAO,EAAiB,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,GAAG,EAAmB,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,UAAU,EAAgB,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,OAAO,EAAiB,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,oCAAoC;AACpC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAe,EAAE,OAAqE,EAAE;IACpH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IACrF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,qHAAqH;IACrH,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/J,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAc;QAC1B,GAAG,MAAM,CAAC,QAAQ;QAClB,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAC3J,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;KAC9B,CAAC;IACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,qBAAqB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAC7D,CAAC"}
|
package/dist/baseline.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { type CageConfig } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* 选择显式文件或真实 Git 提交作为修改前的比较依据,baseFile 优先。
|
|
4
|
+
* Git 路径使用当前依赖解释旧声明,不能证明旧项目在原依赖版本下的行为。
|
|
5
|
+
* @param cfg 当前应用位置。
|
|
6
|
+
* @param opts base 为 Git ref,baseFile 为本体或命名快照路径;都省略则不启用基线。
|
|
7
|
+
* @returns 读取或重新抽取的本体,未指定基线时为 undefined。
|
|
8
|
+
* @throws ref 无效、抽取失败、读写或 worktree 清理失败时抛出。
|
|
9
|
+
*/
|
|
2
10
|
export declare function loadBaseline(cfg: CageConfig, opts: {
|
|
3
11
|
base?: string;
|
|
4
12
|
baseFile?: string;
|
package/dist/baseline.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 为影响分析加载显式 JSON 基线或 Git 提交中的领域声明。
|
|
3
|
+
* 文件基线直接读取;Git 基线在独立临时 worktree 中共享当前已安装依赖并由子进程抽取。
|
|
4
|
+
* 不切换当前分支、不安装基线依赖;结束时解除本次 junction 并清理临时工作树,错误向调用方传播。
|
|
5
|
+
*/
|
|
1
6
|
// 基线来自显式 JSON 文件,或 Git 提交里的业务声明。
|
|
2
7
|
// Git 比较在独立临时工作树中抽取,不切换用户当前分支,也不安装/执行基线脚本。
|
|
3
8
|
import { execFileSync } from 'node:child_process';
|
|
@@ -8,6 +13,14 @@ import { abs } from './config.js';
|
|
|
8
13
|
import { readOntology } from './impact.js';
|
|
9
14
|
import { run } from './process.js';
|
|
10
15
|
import { projectManifests } from './upgrade.js';
|
|
16
|
+
/**
|
|
17
|
+
* 选择显式文件或真实 Git 提交作为修改前的比较依据,baseFile 优先。
|
|
18
|
+
* Git 路径使用当前依赖解释旧声明,不能证明旧项目在原依赖版本下的行为。
|
|
19
|
+
* @param cfg 当前应用位置。
|
|
20
|
+
* @param opts base 为 Git ref,baseFile 为本体或命名快照路径;都省略则不启用基线。
|
|
21
|
+
* @returns 读取或重新抽取的本体,未指定基线时为 undefined。
|
|
22
|
+
* @throws ref 无效、抽取失败、读写或 worktree 清理失败时抛出。
|
|
23
|
+
*/
|
|
11
24
|
export async function loadBaseline(cfg, opts) {
|
|
12
25
|
if (opts.baseFile)
|
|
13
26
|
return readOntology(abs(cfg, opts.baseFile));
|
package/dist/baseline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CageConfig } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* 独占创建新凭据文件,在任何密码写入前收紧可读写范围。
|
|
4
|
+
* POSIX 请求 0600;Windows 使用实际进程 SID 替换继承 ACL,不信任环境用户名。
|
|
5
|
+
* @param file 已解析的目标路径,父目录必须存在,目标不得已存在。
|
|
6
|
+
* @throws 创建或 ACL 限制失败时抛出 CAGE-INIT-005;已创建空文件可能保留,不能视为交付成功。
|
|
7
|
+
*/
|
|
8
|
+
export declare function protectCredentialFile(file: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* 显式初始化组织并把首次管理员凭据交给受限文件,供 main 的 bootstrap 分支调用。
|
|
11
|
+
* 只注册组织模型;已有用户时不重置账号,返回未创建结果。交付回调失败使初始化事务失败。
|
|
12
|
+
* @param cfg 应用配置,用于解析相对凭据路径。
|
|
13
|
+
* @param credentialsFile 必须指定的新文件路径。
|
|
14
|
+
* @returns created 和凭据文件绝对路径;函数完成后 kernel 已关闭。
|
|
15
|
+
* @throws 凭据准备或初始化失败时返回受控错误,避免 SQL 参数和密码进入日志。
|
|
16
|
+
*/
|
|
17
|
+
export declare function bootstrapOrganization(cfg: CageConfig, credentialsFile: string): Promise<{
|
|
18
|
+
created: boolean;
|
|
19
|
+
credentialsFile: string;
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 的组织初始化与管理员凭据交付边界,由 bootstrap 子命令调用。
|
|
3
|
+
* 先独占创建并限制凭据文件权限,再仅注册组织领域执行 bootstrapOrg,凭据交付参与初始化事务。
|
|
4
|
+
* 不隐式授予业务能力、不打印密码;无论初始化成功与否均关闭临时 kernel,文件交付失败不能被当成成功。
|
|
5
|
+
*/
|
|
6
|
+
// Explicit organization initialization. Credentials are delivered only through a newly protected file.
|
|
7
|
+
import { randomBytes } from 'node:crypto';
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
|
+
import { closeSync, openSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { bootstrapOrg } from '@yss123/cage-admin';
|
|
11
|
+
import * as organization from '@yss123/cage-admin/domain';
|
|
12
|
+
import { createKernel, silentLogger, urlsFromEnv } from '@yss123/cage-kernel';
|
|
13
|
+
import { abs } from './config.js';
|
|
14
|
+
/**
|
|
15
|
+
* 独占创建新凭据文件,在任何密码写入前收紧可读写范围。
|
|
16
|
+
* POSIX 请求 0600;Windows 使用实际进程 SID 替换继承 ACL,不信任环境用户名。
|
|
17
|
+
* @param file 已解析的目标路径,父目录必须存在,目标不得已存在。
|
|
18
|
+
* @throws 创建或 ACL 限制失败时抛出 CAGE-INIT-005;已创建空文件可能保留,不能视为交付成功。
|
|
19
|
+
*/
|
|
20
|
+
export function protectCredentialFile(file) {
|
|
21
|
+
try {
|
|
22
|
+
closeSync(openSync(file, 'wx', 0o600));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error('[CAGE-INIT-005] 无法创建新的受限凭据文件;请使用不存在的文件,并检查父目录及其权限');
|
|
26
|
+
}
|
|
27
|
+
if (process.platform === 'win32') {
|
|
28
|
+
try {
|
|
29
|
+
// Shell/sandbox accounts may differ from USERNAME. Grant the actual process identity by SID.
|
|
30
|
+
const identity = execFileSync('whoami', ['/user', '/fo', 'csv', '/nh'], { encoding: 'utf8', windowsHide: true, stdio: 'pipe' });
|
|
31
|
+
const sid = identity.match(/\bS-\d+(?:-\d+)+\b/)?.[0];
|
|
32
|
+
if (!sid)
|
|
33
|
+
throw new Error('Current Windows SID unavailable');
|
|
34
|
+
execFileSync('icacls', [file, '/inheritance:r', '/grant:r', `*${sid}:(F)`], { windowsHide: true, stdio: 'pipe' });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new Error('[CAGE-INIT-005] 无法限制凭证文件权限;未生成或写入凭证,请修正文件 ACL 后重试');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 显式初始化组织并把首次管理员凭据交给受限文件,供 main 的 bootstrap 分支调用。
|
|
43
|
+
* 只注册组织模型;已有用户时不重置账号,返回未创建结果。交付回调失败使初始化事务失败。
|
|
44
|
+
* @param cfg 应用配置,用于解析相对凭据路径。
|
|
45
|
+
* @param credentialsFile 必须指定的新文件路径。
|
|
46
|
+
* @returns created 和凭据文件绝对路径;函数完成后 kernel 已关闭。
|
|
47
|
+
* @throws 凭据准备或初始化失败时返回受控错误,避免 SQL 参数和密码进入日志。
|
|
48
|
+
*/
|
|
49
|
+
export async function bootstrapOrganization(cfg, credentialsFile) {
|
|
50
|
+
if (!credentialsFile)
|
|
51
|
+
throw new Error('[CAGE-INIT-005] 指定 --credentials-file <新的受限文件>,初始化密码不会写入控制台');
|
|
52
|
+
const file = abs(cfg, credentialsFile);
|
|
53
|
+
protectCredentialFile(file);
|
|
54
|
+
// Only organization declarations are registered, so no business capabilities are granted implicitly.
|
|
55
|
+
const kernel = createKernel({ domain: organization, urls: urlsFromEnv(process.env), logger: silentLogger });
|
|
56
|
+
try {
|
|
57
|
+
const password = randomBytes(24).toString('base64url');
|
|
58
|
+
const result = await bootstrapOrg(kernel, {
|
|
59
|
+
adminPassword: password,
|
|
60
|
+
// Delivery is part of the initialization transaction: a failed write must not strand an administrator.
|
|
61
|
+
deliverCredentials: credentials => writeFileSync(file, JSON.stringify({ ...credentials, note: '仅初始化组织与系统管理能力。业务能力由管理员显式配置;妥善保管并在交付后移除此文件。' }, null, 2) + '\n'),
|
|
62
|
+
});
|
|
63
|
+
if (!result.created)
|
|
64
|
+
writeFileSync(file, JSON.stringify({ created: false, note: '组织已有用户,未修改账号或密码。' }, null, 2) + '\n');
|
|
65
|
+
return { created: result.created, credentialsFile: file };
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Do not surface SQL arguments or initialization inputs through a generic error formatter.
|
|
69
|
+
throw new Error('[CAGE-INIT-005] 组织初始化失败;检查迁移与数据库账号,凭证未输出到日志。');
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
await kernel.close();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/budget.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type CageConfig } from './config.js';
|
|
2
2
|
import type { Ontology } from './ontology.js';
|
|
3
3
|
import type { Finding } from './findings.js';
|
|
4
|
+
/**
|
|
5
|
+
* 计算静态预算并给出超限诊断,不自动豁免或改写基线。
|
|
6
|
+
* @param cfg 用于查找本地 kernel 源码;普通安装项目可能没有这些文件。
|
|
7
|
+
* @param graph 当前本体,其中 unsafeCount 表示扫描到的逃生口数量。
|
|
8
|
+
* @param base 已审查本体,省略时 unsafe 允许量为零。
|
|
9
|
+
* @returns 体积/词汇/unsafe 指标和超限 Finding;缺源码的指标为 null。
|
|
10
|
+
*/
|
|
4
11
|
export declare function budget(cfg: CageConfig, graph: Ontology, base?: Ontology): {
|
|
5
12
|
metrics: Record<string, number | null>;
|
|
6
13
|
findings: Finding[];
|
package/dist/budget.js
CHANGED
|
@@ -1,13 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 面向框架维护和业务门禁计算内核规模、公共词汇与 unsafe 增量预算。
|
|
3
|
+
* 读取本地源码及本体元数据,返回 metrics 和 Finding,不修改源码、不连接数据库。
|
|
4
|
+
* 源码包不存在时对应体积指标为 null;体积按含语法 token 的物理行计数,排除注释和空白。
|
|
5
|
+
*/
|
|
1
6
|
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import ts from 'typescript';
|
|
2
8
|
import { abs } from './config.js';
|
|
3
9
|
import { listTs } from './static-check.js';
|
|
10
|
+
/**
|
|
11
|
+
* 统计一份 TypeScript 源码实际占用的代码行,让中文 JSDoc 不消耗内核实现预算。
|
|
12
|
+
* 使用语法树的叶子 token 定位原始物理行,不重新格式化源码,也不把字符串、正则或模板内的注释符当注释。
|
|
13
|
+
* JSDoc 子树和 EOF 不代表实现;跨行 token 覆盖的全部行仍计入,因此模板文字中的空行属于代码内容。
|
|
14
|
+
* 同一行有多个 token 只计一次,行尾注释不增加行数;本函数不做类型检查或修改文件。
|
|
15
|
+
* @param file 文件名,交给 TypeScript 判断源码类型。
|
|
16
|
+
* @param sourceText 完整源码,保留原有换行。
|
|
17
|
+
* @returns 含至少一个语法 token 的物理行数。
|
|
18
|
+
*/
|
|
19
|
+
function codeLineCount(file, sourceText) {
|
|
20
|
+
const source = ts.createSourceFile(file, sourceText, ts.ScriptTarget.Latest, true);
|
|
21
|
+
const lines = new Set();
|
|
22
|
+
/** 遍历语法 token;必须跳过 JSDoc 整棵子树,避免其中的标识符和类型被当作实现。 */
|
|
23
|
+
const visit = (node) => {
|
|
24
|
+
if (node.kind >= ts.SyntaxKind.FirstJSDocNode && node.kind <= ts.SyntaxKind.LastJSDocNode)
|
|
25
|
+
return;
|
|
26
|
+
const children = node.getChildren(source);
|
|
27
|
+
if (children.length) {
|
|
28
|
+
children.forEach(visit);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (node.kind === ts.SyntaxKind.EndOfFileToken || node.kind === ts.SyntaxKind.SyntaxList)
|
|
32
|
+
return;
|
|
33
|
+
const start = node.getStart(source), end = node.getEnd();
|
|
34
|
+
if (end <= start)
|
|
35
|
+
return;
|
|
36
|
+
const first = source.getLineAndCharacterOfPosition(start).line;
|
|
37
|
+
const last = source.getLineAndCharacterOfPosition(end - 1).line;
|
|
38
|
+
for (let line = first; line <= last; line++)
|
|
39
|
+
lines.add(line);
|
|
40
|
+
};
|
|
41
|
+
visit(source);
|
|
42
|
+
return lines.size;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 计算静态预算并给出超限诊断,不自动豁免或改写基线。
|
|
46
|
+
* @param cfg 用于查找本地 kernel 源码;普通安装项目可能没有这些文件。
|
|
47
|
+
* @param graph 当前本体,其中 unsafeCount 表示扫描到的逃生口数量。
|
|
48
|
+
* @param base 已审查本体,省略时 unsafe 允许量为零。
|
|
49
|
+
* @returns 体积/词汇/unsafe 指标和超限 Finding;缺源码的指标为 null。
|
|
50
|
+
*/
|
|
4
51
|
export function budget(cfg, graph, base) {
|
|
5
52
|
const kernel = abs(cfg, 'packages/kernel/src');
|
|
6
53
|
const lines = existsSync(kernel)
|
|
7
|
-
? listTs(kernel).reduce((n, f) => n +
|
|
8
|
-
readFileSync(f, 'utf8')
|
|
9
|
-
.split('\n')
|
|
10
|
-
.filter((l) => l.trim() && !l.trim().startsWith('//')).length, 0)
|
|
54
|
+
? listTs(kernel).reduce((n, f) => n + codeLineCount(f, readFileSync(f, 'utf8')), 0)
|
|
11
55
|
: null;
|
|
12
56
|
const primitivesFile = abs(cfg, 'packages/kernel/src/brands.ts');
|
|
13
57
|
// 使用公共词汇表计数;品牌还含内部扩展标记,不能把两者混算。
|
|
@@ -21,7 +65,7 @@ export function budget(cfg, graph, base) {
|
|
|
21
65
|
const vocabulary = new Set(['field', 'capability', 'scope', 'constraint', 'invariant']);
|
|
22
66
|
if (existsSync(primitivesFile)) {
|
|
23
67
|
for (const match of readFileSync(primitivesFile, 'utf8').matchAll(/export const (\w+) = Symbol\.for\(/g)) {
|
|
24
|
-
if (['CONSUMERS', 'SYSTEM_DDL'].includes(match[1]))
|
|
68
|
+
if (['CONSUMERS', 'SYSTEM_DDL', 'RUNTIME', 'MIGRATIONS'].includes(match[1]))
|
|
25
69
|
continue;
|
|
26
70
|
vocabulary.add(families[match[1]] ?? match[1].toLowerCase());
|
|
27
71
|
}
|
package/dist/budget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,GAAG,EAAmB,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CageConfig } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* 读取安装版本的公开导出签名,按关键词筛选可用 API 的证据。
|
|
4
|
+
* 查询只做归一化后的连续文本包含判断,不进行同义词推理;无结果和未检查包都不能说明能力不存在。
|
|
5
|
+
* @param cfg 用于定位应用不同包的依赖解析边界。
|
|
6
|
+
* @param query 公开名称、JSDoc 或维护的业务词条;空字符串返回全部已发现符号。
|
|
7
|
+
* @returns 包检查状态、真实签名、声明位置和本地 guide;不加载运行时实现或修改文件。
|
|
8
|
+
*/
|
|
9
|
+
export declare function publicCapabilities(cfg: CageConfig, query?: string): {
|
|
10
|
+
schemaVersion: number;
|
|
11
|
+
cliVersion: string;
|
|
12
|
+
query: string;
|
|
13
|
+
packages: {
|
|
14
|
+
inspected: boolean;
|
|
15
|
+
name: string;
|
|
16
|
+
version: string | null;
|
|
17
|
+
}[];
|
|
18
|
+
capabilities: {
|
|
19
|
+
key: string;
|
|
20
|
+
package: string;
|
|
21
|
+
version: string | null;
|
|
22
|
+
name: string;
|
|
23
|
+
public: boolean;
|
|
24
|
+
description: string;
|
|
25
|
+
signatures: string[];
|
|
26
|
+
guide: string;
|
|
27
|
+
example: {
|
|
28
|
+
code: string;
|
|
29
|
+
context: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
limitations: string[];
|
|
32
|
+
source: {
|
|
33
|
+
file: string;
|
|
34
|
+
line: number;
|
|
35
|
+
};
|
|
36
|
+
}[];
|
|
37
|
+
limitations: string[];
|
|
38
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按当前安装包的声明文件建立公开能力目录,供 agent 查真实签名与本地指南。
|
|
3
|
+
* 依次尝试领域、契约、Web、项目及 CLI 的依赖边界,用 TypeScript 类型检查器解析公开导出。
|
|
4
|
+
* 关键词提示只帮助召回,不创造不存在的 API;未解析到包或声明文件时记录未检查,不据此判定框架不支持。
|
|
5
|
+
*/
|
|
6
|
+
// Public capability discovery reads installed declarations, never framework implementation bodies.
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
import ts from 'typescript';
|
|
11
|
+
import { abs } from './config.js';
|
|
12
|
+
import { VERSION } from './version.js';
|
|
13
|
+
const modules = ['kernel', 'approval', 'connectors', 'client', 'admin', 'files', 'ai', 'ai-protocol', 'ontology'];
|
|
14
|
+
// 关键词负责把需求指向真实公开符号;签名仍来自当前安装包,不能用词表伪造可用 API。
|
|
15
|
+
const topics = {
|
|
16
|
+
ai: { words: '智能助理 业务助理 本体助理 全能助理 AI审批 AI 审批 智能审批 运行时 执行循环 loop 工具 会话 记忆 上下文预算', guide: 'intelligence.md',
|
|
17
|
+
limitations: ['须从 domain 入口导出并完成迁移、模型配置、角色授权和 worker 启动;框架支持不代表应用已启用。'] },
|
|
18
|
+
AiContextOptions: { words: '上下文预算 上下文窗口 大本体 按需加载 工具发现 工具搜索 历史 记忆 token', guide: 'intelligence.md' },
|
|
19
|
+
chatModel: { words: '模型接入 Chat Completions 流式输出 fake', guide: 'intelligence.md' },
|
|
20
|
+
responsesModel: { words: '模型接入 Responses 接口协议 会话接续 previous_response_id 服务端压缩', guide: 'intelligence.md',
|
|
21
|
+
limitations: ['Responses 接口可用不等于网关支持接续或压缩;接续历史仍占上下文与输入用量。'] },
|
|
22
|
+
managedModel: { words: '模型管理 模型配置 动态配置 密钥 admin HTTP HTTPS Chat Completions Responses', guide: 'intelligence.md',
|
|
23
|
+
limitations: ['Admin 管理需显式授予 Sys.ai.models.manage,并配置部署加密密钥;连接测试不代表工具和业务联调通过。'] },
|
|
24
|
+
'@yss123/cage-approval#step': { words: '审批步骤 AI审批 AI 审批 智能审批 通过 退回修改 转人工', guide: 'intelligence.md',
|
|
25
|
+
limitations: ['AI 使用 step 的 kind: ai 重载;handoff 指定本步骤接管人,角色与结论命令仍须授权。'] },
|
|
26
|
+
AiStepOptions: { words: 'AI审批 AI 审批 智能审批 审核策略 退回修改 转人工', guide: 'intelligence.md' },
|
|
27
|
+
AiDecision: { words: 'AI审批 AI 审批 智能审批 三态裁决 通过 退回修改 转人工', guide: 'intelligence.md' },
|
|
28
|
+
useAssistant: { words: '智能助理 业务助理 本体助理 全能助理 随页助理 会话 前端 SDK 性格 流式输出 悬浮窗 Markdown', guide: 'intelligence.md',
|
|
29
|
+
limitations: ['SDK 提供状态与动作;悬浮窗、Markdown 和交互卡片由应用实现,不能等待发送 Promise 完成后才展示增量文字。'] },
|
|
30
|
+
AiClient: { words: '业务助理 随页助理 前端 SDK 会话 记忆 性格 流式输出 模型管理', guide: 'intelligence.md' },
|
|
31
|
+
AiPageContext: { words: '页面上下文 随页助理 当前页面 快照 选中项 草稿 标签页', guide: 'intelligence.md' },
|
|
32
|
+
useAiPageContext: { words: '页面上下文 随页助理 当前页面 快照 选中项 草稿 标签页', guide: 'intelligence.md',
|
|
33
|
+
limitations: ['应用主动提供语义快照,SDK 不抓取整个 DOM;服务端按当前身份重新读取并校验业务对象。'] },
|
|
34
|
+
PageContext: { words: '页面上下文 随页助理 当前页面 快照 选中项 草稿 标签页', guide: 'intelligence.md' },
|
|
35
|
+
AiPersonality: { words: '性格 人设 表达风格 默认预设 admin', guide: 'intelligence.md',
|
|
36
|
+
limitations: ['性格只影响助理表达,不改变权限、工具或审批策略;管理需 Sys.ai.personalities.manage。'] },
|
|
37
|
+
AiPersonalityInput: { words: '性格 人设 表达风格 自定义配置', guide: 'intelligence.md' },
|
|
38
|
+
runtimeOntology: { words: '领域本体 业务本体 本体助理 自动工具 运行时', guide: 'intelligence.md' },
|
|
39
|
+
file: { words: '文件 附件 上传 单文件', guide: 'files.md' },
|
|
40
|
+
files: { words: '文件 附件 上传 多文件', guide: 'files.md' },
|
|
41
|
+
FileService: { words: '文件 断点续传 分片 上传 存储', guide: 'files.md' },
|
|
42
|
+
FileStorage: { words: '文件 对象存储 S3 适配器', guide: 'files.md' },
|
|
43
|
+
LocalFileStorage: { words: '文件 本地 私有 存储', guide: 'files.md' },
|
|
44
|
+
FileUploadTask: { words: '文件 上传 暂停 恢复 断点续传', guide: 'files.md' },
|
|
45
|
+
scope: { words: '本人 owner 部门 数据范围 授权', guide: 'architecture.md' },
|
|
46
|
+
reaction: { words: '跨对象 事务 事件 反应 原子', guide: 'primitives.md' },
|
|
47
|
+
reactionEach: { words: '批量 集合 多条 上限 顺序 事务', guide: 'diagnostics.md' },
|
|
48
|
+
approver: { words: '审批 选人 部门负责人 角色', guide: 'primitives.md' },
|
|
49
|
+
connector: { words: '第三方 ERP 外呼 外部', guide: 'primitives.md' },
|
|
50
|
+
command: { words: '命令 写入 校验 业务操作', guide: 'primitives.md' },
|
|
51
|
+
query: { words: '查询 报表 安全读取', guide: 'primitives.md' },
|
|
52
|
+
};
|
|
53
|
+
const examples = {
|
|
54
|
+
ai: "export const intelligence = ai({ models: { main: managedModel('main') }, assistant: { model: 'main', confirmWrites: true } })",
|
|
55
|
+
managedModel: "models: { main: managedModel('main') } // ai() 的配置片段;连接信息在 Admin 保存",
|
|
56
|
+
'@yss123/cage-approval#step': "step('材料预审', { kind: 'ai', model: 'main', instructions: '资料不足时转人工,并说明缺失信息。', context: { fields: ['reason'] }, handoff: approver.role('reviewer') })",
|
|
57
|
+
useAssistant: 'const assistant = useAssistant(client.ai, page); // page 由 useAiPageContext 提供,按 streamingText / progress 渲染',
|
|
58
|
+
scope: "scope.self('applicantId'); scope.deptSubtree('deptId', 'applicantId')",
|
|
59
|
+
reaction: "reaction(OrderApproved, { command: reserve, tx: 'same', map: event => ({ id: event.stockId }) })",
|
|
60
|
+
reactionEach: "reactionEach(Allocated, { command: reserve, tx: 'same', order: 2, maxItems: 20, orderBy: 'id', items: event => event.devices, map: item => ({ id: item.id }) })",
|
|
61
|
+
approver: "step('部门负责人', approver.deptLeader('deptId'))",
|
|
62
|
+
query: "query('recentOrders', { reads: [Order], input: z.object({}), sql: 'select id from safe.order limit 20' })",
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 读取安装版本的公开导出签名,按关键词筛选可用 API 的证据。
|
|
66
|
+
* 查询只做归一化后的连续文本包含判断,不进行同义词推理;无结果和未检查包都不能说明能力不存在。
|
|
67
|
+
* @param cfg 用于定位应用不同包的依赖解析边界。
|
|
68
|
+
* @param query 公开名称、JSDoc 或维护的业务词条;空字符串返回全部已发现符号。
|
|
69
|
+
* @returns 包检查状态、真实签名、声明位置和本地 guide;不加载运行时实现或修改文件。
|
|
70
|
+
*/
|
|
71
|
+
export function publicCapabilities(cfg, query = '') {
|
|
72
|
+
const requests = [createRequire(abs(cfg, cfg.domain)), createRequire(abs(cfg, `${cfg.contracts}/index.ts`)), createRequire(abs(cfg, `${cfg.web}/package.json`)), createRequire(abs(cfg, 'package.json')), createRequire(import.meta.url)];
|
|
73
|
+
const packages = modules.flatMap(module => {
|
|
74
|
+
const name = `@yss123/cage-${module}`;
|
|
75
|
+
try {
|
|
76
|
+
const workspace = abs(cfg, `packages/${module}/package.json`);
|
|
77
|
+
const resolvers = existsSync(workspace) ? [createRequire(workspace), ...requests] : requests;
|
|
78
|
+
let resolved;
|
|
79
|
+
for (const request of resolvers) {
|
|
80
|
+
try {
|
|
81
|
+
resolved = request.resolve(name);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
catch { /* Try the next configured package boundary. */ }
|
|
85
|
+
}
|
|
86
|
+
if (!resolved)
|
|
87
|
+
return [{ name, version: null, entry: null }];
|
|
88
|
+
const entry = resolved.replace(/\.js$/, '.d.ts');
|
|
89
|
+
const manifest = join(dirname(dirname(entry)), 'package.json');
|
|
90
|
+
if (!existsSync(entry))
|
|
91
|
+
return [{ name, version: null, entry: null }];
|
|
92
|
+
return [{ name, version: JSON.parse(readFileSync(manifest, 'utf8')).version, entry }];
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return [{ name, version: null, entry: null }];
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const entries = packages.flatMap(p => p.entry ? [p.entry] : []);
|
|
99
|
+
const program = ts.createProgram(entries, { target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.NodeNext, moduleResolution: ts.ModuleResolutionKind.NodeNext, skipLibCheck: true });
|
|
100
|
+
const checker = program.getTypeChecker();
|
|
101
|
+
const needle = query.normalize('NFKC').toLowerCase();
|
|
102
|
+
const capabilities = packages.flatMap(pkg => {
|
|
103
|
+
if (!pkg.entry)
|
|
104
|
+
return [];
|
|
105
|
+
const file = program.getSourceFile(pkg.entry);
|
|
106
|
+
const module = file && checker.getSymbolAtLocation(file);
|
|
107
|
+
if (!module)
|
|
108
|
+
return [];
|
|
109
|
+
return checker.getExportsOfModule(module).flatMap(symbol => {
|
|
110
|
+
const target = symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
111
|
+
const declaration = target.declarations?.[0];
|
|
112
|
+
if (!declaration)
|
|
113
|
+
return [];
|
|
114
|
+
const name = symbol.name;
|
|
115
|
+
const description = ts.displayPartsToString(target.getDocumentationComment(checker));
|
|
116
|
+
// 内核日志和审批路由都导出 step;同名符号的用法必须按包限定。
|
|
117
|
+
const key = `${pkg.name}#${name}`, topic = topics[key] ?? topics[name];
|
|
118
|
+
const example = examples[key] ?? examples[name];
|
|
119
|
+
if (needle && !`${name} ${description} ${topic?.words ?? ''}`.normalize('NFKC').toLowerCase().includes(needle))
|
|
120
|
+
return [];
|
|
121
|
+
const type = checker.getTypeOfSymbolAtLocation(target, declaration);
|
|
122
|
+
const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call).map(s => checker.signatureToString(s, declaration, ts.TypeFormatFlags.NoTruncation));
|
|
123
|
+
return [{ key, package: pkg.name, version: pkg.version, name, public: true, description,
|
|
124
|
+
signatures: signatures.length ? signatures : [declaration.getText().slice(0, 6000)],
|
|
125
|
+
guide: `docs/ai/${topic?.guide ?? 'README.md'}`, example: example ? { code: example, context: '组合片段;声明中的业务符号须来自当前项目,完整可运行例子见 guide' } : undefined,
|
|
126
|
+
limitations: topic ? ['能力和数据范围仍由实际授权决定;按照当前签名与指南使用。', ...(topic.limitations ?? [])] : [],
|
|
127
|
+
source: { file: declaration.getSourceFile().fileName, line: declaration.getSourceFile().getLineAndCharacterOfPosition(declaration.getStart()).line + 1 } }];
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
return { schemaVersion: 1, cliVersion: VERSION, query, packages: packages.map(({ entry, ...p }) => ({ ...p, inspected: !!entry })), capabilities,
|
|
131
|
+
limitations: ['仅展示当前安装版本的公共导出;签名不代表任意组合均有效。按 guide 查看最小例子、限制及相关错误码。', '未安装的包标为未检查,不据此断言框架不支持。'] };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=capabilities.js.map
|