@yss123/cage-cli 0.1.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.
Files changed (734) hide show
  1. package/README.md +69 -3
  2. package/bin/cage.js +5 -0
  3. package/bin/create-cage-app.js +5 -0
  4. package/dist/analyze.d.ts +16 -0
  5. package/dist/analyze.js +20 -2
  6. package/dist/analyze.js.map +1 -1
  7. package/dist/baseline.d.ts +8 -0
  8. package/dist/baseline.js +13 -0
  9. package/dist/baseline.js.map +1 -1
  10. package/dist/bootstrap.d.ts +20 -0
  11. package/dist/bootstrap.js +75 -0
  12. package/dist/bootstrap.js.map +1 -0
  13. package/dist/budget.d.ts +7 -0
  14. package/dist/budget.js +49 -5
  15. package/dist/budget.js.map +1 -1
  16. package/dist/capabilities.d.ts +38 -0
  17. package/dist/capabilities.js +133 -0
  18. package/dist/capabilities.js.map +1 -0
  19. package/dist/config.d.ts +33 -4
  20. package/dist/config.js +22 -1
  21. package/dist/config.js.map +1 -1
  22. package/dist/context.d.ts +86 -0
  23. package/dist/context.js +235 -0
  24. package/dist/context.js.map +1 -0
  25. package/dist/create-prompt.d.ts +12 -0
  26. package/dist/create-prompt.js +62 -0
  27. package/dist/create-prompt.js.map +1 -0
  28. package/dist/create.d.ts +38 -1
  29. package/dist/create.js +52 -13
  30. package/dist/create.js.map +1 -1
  31. package/dist/derive.d.ts +23 -0
  32. package/dist/derive.js +40 -0
  33. package/dist/derive.js.map +1 -1
  34. package/dist/dev.d.ts +6 -0
  35. package/dist/dev.js +23 -51
  36. package/dist/dev.js.map +1 -1
  37. package/dist/doctor.d.ts +98 -0
  38. package/dist/doctor.js +93 -0
  39. package/dist/doctor.js.map +1 -0
  40. package/dist/env.d.ts +6 -0
  41. package/dist/env.js +11 -0
  42. package/dist/env.js.map +1 -1
  43. package/dist/findings.d.ts +27 -0
  44. package/dist/findings.js +20 -0
  45. package/dist/findings.js.map +1 -1
  46. package/dist/gen/contracts.d.ts +28 -0
  47. package/dist/gen/contracts.js +81 -20
  48. package/dist/gen/contracts.js.map +1 -1
  49. package/dist/gen/index.d.ts +26 -0
  50. package/dist/gen/index.js +112 -4
  51. package/dist/gen/index.js.map +1 -1
  52. package/dist/gen/zod-code.d.ts +43 -1
  53. package/dist/gen/zod-code.js +180 -16
  54. package/dist/gen/zod-code.js.map +1 -1
  55. package/dist/graph-approvals.d.ts +60 -0
  56. package/dist/graph-approvals.js +80 -0
  57. package/dist/graph-approvals.js.map +1 -0
  58. package/dist/graph-business.d.ts +135 -0
  59. package/dist/graph-business.js +404 -0
  60. package/dist/graph-business.js.map +1 -0
  61. package/dist/graph-command.d.ts +28 -0
  62. package/dist/graph-command.js +88 -0
  63. package/dist/graph-command.js.map +1 -0
  64. package/dist/graph-model.d.ts +65 -0
  65. package/dist/graph-model.js +134 -0
  66. package/dist/graph-model.js.map +1 -0
  67. package/dist/graph-presentation.d.ts +27 -0
  68. package/dist/graph-presentation.js +34 -0
  69. package/dist/graph-presentation.js.map +1 -0
  70. package/dist/graph-query.d.ts +266 -0
  71. package/dist/graph-query.js +304 -0
  72. package/dist/graph-query.js.map +1 -0
  73. package/dist/graph-relations.d.ts +34 -0
  74. package/dist/graph-relations.js +172 -0
  75. package/dist/graph-relations.js.map +1 -0
  76. package/dist/graph-search.d.ts +56 -0
  77. package/dist/graph-search.js +99 -0
  78. package/dist/graph-search.js.map +1 -0
  79. package/dist/graph-snapshot.d.ts +28 -4
  80. package/dist/graph-snapshot.js +32 -20
  81. package/dist/graph-snapshot.js.map +1 -1
  82. package/dist/graph.d.ts +13 -2
  83. package/dist/graph.js +78 -5
  84. package/dist/graph.js.map +1 -1
  85. package/dist/impact.d.ts +56 -0
  86. package/dist/impact.js +90 -18
  87. package/dist/impact.js.map +1 -1
  88. package/dist/index.d.ts +15 -1
  89. package/dist/index.js +15 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/init.d.ts +18 -0
  92. package/dist/init.js +146 -0
  93. package/dist/init.js.map +1 -0
  94. package/dist/load.d.ts +10 -0
  95. package/dist/load.js +15 -0
  96. package/dist/load.js.map +1 -1
  97. package/dist/main.d.ts +6 -0
  98. package/dist/main.js +170 -37
  99. package/dist/main.js.map +1 -1
  100. package/dist/migrate.d.ts +15 -6
  101. package/dist/migrate.js +31 -53
  102. package/dist/migrate.js.map +1 -1
  103. package/dist/ontology.d.ts +69 -2
  104. package/dist/ontology.js +101 -4
  105. package/dist/ontology.js.map +1 -1
  106. package/dist/process-rules.d.ts +21 -0
  107. package/dist/process-rules.js +100 -0
  108. package/dist/process-rules.js.map +1 -0
  109. package/dist/process.d.ts +32 -0
  110. package/dist/process.js +32 -0
  111. package/dist/process.js.map +1 -1
  112. package/dist/project-structure.d.ts +13 -0
  113. package/dist/project-structure.js +104 -0
  114. package/dist/project-structure.js.map +1 -0
  115. package/dist/registration.d.ts +16 -0
  116. package/dist/registration.js +56 -0
  117. package/dist/registration.js.map +1 -0
  118. package/dist/rules.d.ts +52 -0
  119. package/dist/rules.js +58 -0
  120. package/dist/rules.js.map +1 -1
  121. package/dist/runtime-diagnostics.d.ts +27 -0
  122. package/dist/runtime-diagnostics.js +60 -0
  123. package/dist/runtime-diagnostics.js.map +1 -0
  124. package/dist/snapshots.d.ts +40 -0
  125. package/dist/snapshots.js +62 -0
  126. package/dist/snapshots.js.map +1 -0
  127. package/dist/static-check.d.ts +33 -0
  128. package/dist/static-check.js +38 -5
  129. package/dist/static-check.js.map +1 -1
  130. package/dist/sync.d.ts +11 -0
  131. package/dist/sync.js +139 -10
  132. package/dist/sync.js.map +1 -1
  133. package/dist/upgrade.d.ts +16 -0
  134. package/dist/upgrade.js +21 -0
  135. package/dist/upgrade.js.map +1 -1
  136. package/dist/verify.d.ts +14 -0
  137. package/dist/verify.js +19 -0
  138. package/dist/verify.js.map +1 -1
  139. package/dist/version.js +5 -0
  140. package/dist/version.js.map +1 -1
  141. package/graph-ui/app.js +367 -35
  142. package/graph-ui/approval-flow.js +165 -0
  143. package/graph-ui/business.css +985 -0
  144. package/graph-ui/business.js +549 -0
  145. package/graph-ui/flowchart-interaction.js +177 -0
  146. package/graph-ui/flowchart.js +1059 -0
  147. package/graph-ui/graph-approvals.js +79 -0
  148. package/graph-ui/graph-business.js +403 -0
  149. package/graph-ui/graph-model.js +133 -0
  150. package/graph-ui/graph-relations.js +171 -0
  151. package/graph-ui/graph-search.js +98 -0
  152. package/graph-ui/index.html +26 -12
  153. package/graph-ui/model.js +47 -77
  154. package/graph-ui/relations.js +6 -125
  155. package/graph-ui/structure.js +48 -1
  156. package/graph-ui/style.css +33 -0
  157. package/package.json +10 -8
  158. package/templates/app/.dockerignore +2 -0
  159. package/templates/app/.env.example +68 -14
  160. package/templates/app/AGENTS.md +135 -12
  161. package/templates/app/Dockerfile +2 -0
  162. package/templates/app/README.md +49 -16
  163. package/templates/app/_gitignore +9 -0
  164. package/templates/app/apps/api/package.json +2 -2
  165. package/templates/app/apps/api/src/main.ts +5 -1
  166. package/templates/app/apps/api/src/worker.ts +3 -0
  167. package/templates/app/apps/web/index.html +1 -0
  168. package/templates/app/apps/web/package.json +7 -3
  169. package/templates/app/apps/web/src/app/app.tsx +128 -0
  170. package/templates/app/apps/web/src/{style.css → app/styles/global.css} +88 -8
  171. package/templates/app/apps/web/src/app/use-session.ts +43 -0
  172. package/templates/app/apps/web/src/app/workspace-layout.tsx +109 -0
  173. package/templates/app/apps/web/src/main.tsx +9 -543
  174. package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
  175. package/templates/app/apps/web/src/modules/approval/index.ts +6 -0
  176. package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
  177. package/templates/app/apps/web/src/modules/auth/index.ts +5 -0
  178. package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
  179. package/templates/app/apps/web/src/modules/inventory/index.ts +5 -0
  180. package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
  181. package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
  182. package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
  183. package/templates/app/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
  184. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
  185. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +82 -0
  186. package/templates/app/apps/web/src/modules/purchase/index.ts +7 -0
  187. package/templates/app/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
  188. package/templates/app/apps/web/src/modules/purchase/pages/purchase-intelligence.css +15 -0
  189. package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
  190. package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
  191. package/templates/app/apps/web/src/modules/workspace/index.ts +5 -0
  192. package/templates/app/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
  193. package/templates/app/apps/web/src/shared/hooks/use-command.ts +42 -0
  194. package/templates/app/apps/web/src/shared/lib/error-message.ts +24 -0
  195. package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -0
  196. package/templates/app/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
  197. package/templates/app/apps/web/src/shared/ui/assistant-panel.css +134 -0
  198. package/templates/app/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  199. package/templates/app/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  200. package/templates/app/apps/web/src/shared/ui/attachment-upload.css +28 -0
  201. package/templates/app/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  202. package/templates/app/apps/web/src/shared/ui/notice.tsx +20 -0
  203. package/templates/app/apps/web/src/shared/ui/page-heading.tsx +35 -0
  204. package/templates/app/apps/web/src/shared/ui/page-state.css +47 -0
  205. package/templates/app/apps/web/src/shared/ui/page-state.tsx +76 -0
  206. package/templates/app/apps/web/src/shared/ui/require-capability.tsx +34 -0
  207. package/templates/app/apps/web/vite.config.ts +8 -0
  208. package/templates/app/cage.config.json +10 -1
  209. package/templates/app/db/migrations/0002_draft.sql +12 -0
  210. package/templates/app/db/migrations/0003_draft.sql +8 -0
  211. package/templates/app/deploy/nginx.conf +52 -0
  212. package/templates/app/docs/ai/README.md +98 -0
  213. package/templates/app/docs/ai/architecture.md +148 -0
  214. package/templates/app/docs/ai/commenting.md +203 -0
  215. package/templates/app/docs/ai/diagnostics.md +80 -0
  216. package/templates/app/docs/ai/files.md +93 -0
  217. package/templates/app/docs/ai/intelligence.md +348 -0
  218. package/templates/app/docs/ai/ontology-context.md +172 -0
  219. package/templates/app/docs/ai/primitives.md +282 -0
  220. package/templates/app/docs/ai/project-structure.md +128 -0
  221. package/templates/app/docs/ai/purchase-example.md +111 -0
  222. package/templates/app/docs/ai/recipes.md +89 -0
  223. package/templates/app/docs/ai/relations.md +160 -0
  224. package/templates/app/docs/ai/routing.md +86 -0
  225. package/templates/app/docs/ai/transfers.md +92 -0
  226. package/templates/app/docs/ai/troubleshooting.md +65 -0
  227. package/templates/app/docs/ai/workflow.md +152 -0
  228. package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
  229. package/templates/app/docs/errors/CAGE-APPR-001.md +48 -0
  230. package/templates/app/docs/errors/CAGE-APPR-002.md +47 -0
  231. package/templates/app/docs/errors/CAGE-APPR-003.md +47 -0
  232. package/templates/app/docs/errors/CAGE-APPR-004.md +47 -0
  233. package/templates/app/docs/errors/CAGE-APPR-005.md +47 -0
  234. package/templates/app/docs/errors/CAGE-APPR-006.md +53 -0
  235. package/templates/app/docs/errors/CAGE-APPR-007.md +50 -0
  236. package/templates/app/docs/errors/CAGE-APPR-010.md +48 -0
  237. package/templates/app/docs/errors/CAGE-AUDIT-001.md +53 -0
  238. package/templates/app/docs/errors/CAGE-AUTH-001.md +47 -0
  239. package/templates/app/docs/errors/CAGE-BIZ-001.md +51 -0
  240. package/templates/app/docs/errors/CAGE-BIZ-002.md +49 -0
  241. package/templates/app/docs/errors/CAGE-BUDGET-001.md +47 -0
  242. package/templates/app/docs/errors/CAGE-BUDGET-002.md +47 -0
  243. package/templates/app/docs/errors/CAGE-BUDGET-003.md +47 -0
  244. package/templates/app/docs/errors/CAGE-CMD-002.md +47 -0
  245. package/templates/app/docs/errors/CAGE-CMD-003.md +47 -0
  246. package/templates/app/docs/errors/CAGE-CONN-001.md +47 -0
  247. package/templates/app/docs/errors/CAGE-CONN-002.md +47 -0
  248. package/templates/app/docs/errors/CAGE-CONN-003.md +47 -0
  249. package/templates/app/docs/errors/CAGE-CONN-004.md +47 -0
  250. package/templates/app/docs/errors/CAGE-CONN-005.md +47 -0
  251. package/templates/app/docs/errors/CAGE-CONN-006.md +47 -0
  252. package/templates/app/docs/errors/CAGE-CONN-007.md +47 -0
  253. package/templates/app/docs/errors/CAGE-CONN-008.md +47 -0
  254. package/templates/app/docs/errors/CAGE-CONN-009.md +47 -0
  255. package/templates/app/docs/errors/CAGE-CONN-010.md +47 -0
  256. package/templates/app/docs/errors/CAGE-CONN-011.md +47 -0
  257. package/templates/app/docs/errors/CAGE-CONN-012.md +47 -0
  258. package/templates/app/docs/errors/CAGE-CONN-013.md +49 -0
  259. package/templates/app/docs/errors/CAGE-CONN-014.md +48 -0
  260. package/templates/app/docs/errors/CAGE-CONN-015.md +49 -0
  261. package/templates/app/docs/errors/CAGE-CREATE-001.md +53 -0
  262. package/templates/app/docs/errors/CAGE-DECL-001.md +48 -0
  263. package/templates/app/docs/errors/CAGE-DECL-002.md +48 -0
  264. package/templates/app/docs/errors/CAGE-DECL-003.md +47 -0
  265. package/templates/app/docs/errors/CAGE-DECL-004.md +47 -0
  266. package/templates/app/docs/errors/CAGE-DEP-001.md +48 -0
  267. package/templates/app/docs/errors/CAGE-DEP-002.md +47 -0
  268. package/templates/app/docs/errors/CAGE-DEP-003.md +47 -0
  269. package/templates/app/docs/errors/CAGE-DEP-004.md +47 -0
  270. package/templates/app/docs/errors/CAGE-DEP-005.md +47 -0
  271. package/templates/app/docs/errors/CAGE-DIAG-001.md +53 -0
  272. package/templates/app/docs/errors/CAGE-DLQ-001.md +48 -0
  273. package/templates/app/docs/errors/CAGE-ENV-001.md +52 -0
  274. package/templates/app/docs/errors/CAGE-ENV-002.md +51 -0
  275. package/templates/app/docs/errors/CAGE-ENV-003.md +48 -0
  276. package/templates/app/docs/errors/CAGE-EVENT-001.md +47 -0
  277. package/templates/app/docs/errors/CAGE-EVENT-002.md +50 -0
  278. package/templates/app/docs/errors/CAGE-FIELD-001.md +47 -0
  279. package/templates/app/docs/errors/CAGE-FIELD-002.md +47 -0
  280. package/templates/app/docs/errors/CAGE-FIELD-003.md +47 -0
  281. package/templates/app/docs/errors/CAGE-FIELD-004.md +47 -0
  282. package/templates/app/docs/errors/CAGE-FILE-001.md +56 -0
  283. package/templates/app/docs/errors/CAGE-GEN-001.md +48 -0
  284. package/templates/app/docs/errors/CAGE-GEN-002.md +47 -0
  285. package/templates/app/docs/errors/CAGE-GEN-003.md +53 -0
  286. package/templates/app/docs/errors/CAGE-GRANT-001.md +49 -0
  287. package/templates/app/docs/errors/CAGE-GRANT-002.md +48 -0
  288. package/templates/app/docs/errors/CAGE-GRANT-003.md +48 -0
  289. package/templates/app/docs/errors/CAGE-IMPACT-001.md +48 -0
  290. package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -0
  291. package/templates/app/docs/errors/CAGE-INIT-001.md +47 -0
  292. package/templates/app/docs/errors/CAGE-INIT-002.md +49 -0
  293. package/templates/app/docs/errors/CAGE-INIT-003.md +48 -0
  294. package/templates/app/docs/errors/CAGE-INIT-004.md +48 -0
  295. package/templates/app/docs/errors/CAGE-INIT-005.md +52 -0
  296. package/templates/app/docs/errors/CAGE-JOB-001.md +47 -0
  297. package/templates/app/docs/errors/CAGE-JOB-002.md +47 -0
  298. package/templates/app/docs/errors/CAGE-JOB-003.md +47 -0
  299. package/templates/app/docs/errors/CAGE-LINT-001.md +47 -0
  300. package/templates/app/docs/errors/CAGE-MIG-001.md +47 -0
  301. package/templates/app/docs/errors/CAGE-MIG-002.md +47 -0
  302. package/templates/app/docs/errors/CAGE-MIG-003.md +5 -0
  303. package/templates/app/docs/errors/CAGE-MIG-004.md +5 -0
  304. package/templates/app/docs/errors/CAGE-MIG-005.md +47 -0
  305. package/templates/app/docs/errors/CAGE-NAME-001.md +47 -0
  306. package/templates/app/docs/errors/CAGE-NAME-002.md +47 -0
  307. package/templates/app/docs/errors/CAGE-NAME-003.md +47 -0
  308. package/templates/app/docs/errors/CAGE-NAME-004.md +47 -0
  309. package/templates/app/docs/errors/CAGE-NAME-005.md +47 -0
  310. package/templates/app/docs/errors/CAGE-NAME-006.md +47 -0
  311. package/templates/app/docs/errors/CAGE-ORG-001.md +50 -0
  312. package/templates/app/docs/errors/CAGE-PAIR-002.md +51 -0
  313. package/templates/app/docs/errors/CAGE-QUERY-001.md +47 -0
  314. package/templates/app/docs/errors/CAGE-QUERY-002.md +47 -0
  315. package/templates/app/docs/errors/CAGE-QUERY-003.md +50 -0
  316. package/templates/app/docs/errors/CAGE-REACT-001.md +47 -0
  317. package/templates/app/docs/errors/CAGE-REACT-002.md +47 -0
  318. package/templates/app/docs/errors/CAGE-REACT-003.md +50 -0
  319. package/templates/app/docs/errors/CAGE-READS-001.md +50 -0
  320. package/templates/app/docs/errors/CAGE-REG-001.md +54 -0
  321. package/templates/app/docs/errors/CAGE-REG-002.md +49 -0
  322. package/templates/app/docs/errors/CAGE-REG-003.md +47 -0
  323. package/templates/app/docs/errors/CAGE-REL-001.md +64 -0
  324. package/templates/app/docs/errors/CAGE-ROUTE-001.md +48 -0
  325. package/templates/app/docs/errors/CAGE-SCOPE-001.md +47 -0
  326. package/templates/app/docs/errors/CAGE-SCOPE-002.md +47 -0
  327. package/templates/app/docs/errors/CAGE-SECRET-001.md +48 -0
  328. package/templates/app/docs/errors/CAGE-SECRET-002.md +47 -0
  329. package/templates/app/docs/errors/CAGE-SENS-001.md +48 -0
  330. package/templates/app/docs/errors/CAGE-SQL-001.md +47 -0
  331. package/templates/app/docs/errors/CAGE-SQL-002.md +47 -0
  332. package/templates/app/docs/errors/CAGE-STATE-001.md +49 -0
  333. package/templates/app/docs/errors/CAGE-STATE-002.md +47 -0
  334. package/templates/app/docs/errors/CAGE-STATE-003.md +47 -0
  335. package/templates/app/docs/errors/CAGE-STATE-004.md +47 -0
  336. package/templates/app/docs/errors/CAGE-STATE-005.md +49 -0
  337. package/templates/app/docs/errors/CAGE-STATE-010.md +48 -0
  338. package/templates/app/docs/errors/CAGE-STATE-011.md +48 -0
  339. package/templates/app/docs/errors/CAGE-STRUCT-001.md +51 -0
  340. package/templates/app/docs/errors/CAGE-STRUCT-002.md +51 -0
  341. package/templates/app/docs/errors/CAGE-SYNC-001.md +49 -0
  342. package/templates/app/docs/errors/CAGE-TEST-001.md +47 -0
  343. package/templates/app/docs/errors/CAGE-TEST-002.md +50 -0
  344. package/templates/app/docs/errors/CAGE-TEST-003.md +52 -0
  345. package/templates/app/docs/errors/CAGE-UNSAFE-001.md +49 -0
  346. package/templates/app/docs/errors/CAGE-UPGRADE-001.md +48 -0
  347. package/templates/app/docs/errors/CAGE-WORKER-001.md +48 -0
  348. package/templates/app/docs/errors/CAGE-WORKER-002.md +50 -0
  349. package/templates/app/docs/errors/CAGE-WORKER-003.md +48 -0
  350. package/templates/app/docs/errors/README.md +357 -0
  351. package/templates/app/docs/errors/runtime.md +50 -0
  352. package/templates/app/package.json +4 -7
  353. package/templates/app/packages/contracts/package.json +1 -1
  354. package/templates/app/packages/contracts/src/{dept.ts → aggregates/dept/index.ts} +11 -11
  355. package/templates/app/packages/contracts/src/{inventory.ts → aggregates/inventory/index.ts} +6 -6
  356. package/templates/app/packages/contracts/src/{inventory-lock.ts → aggregates/inventory-lock/index.ts} +5 -5
  357. package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +86 -0
  358. package/templates/app/packages/contracts/src/{role.ts → aggregates/role/index.ts} +16 -16
  359. package/templates/app/packages/contracts/src/aggregates/user/index.ts +89 -0
  360. package/templates/app/packages/contracts/src/index.ts +20 -14
  361. package/templates/app/packages/contracts/src/{queries.ts → queries/index.ts} +2 -2
  362. package/templates/app/packages/domain/package.json +5 -4
  363. package/templates/app/packages/domain/src/index.ts +8 -7
  364. package/templates/app/packages/domain/src/{erp.ts → integrations/erp.ts} +16 -1
  365. package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
  366. package/templates/app/packages/domain/src/modules/inventory/index.ts +3 -0
  367. package/templates/app/packages/domain/src/{inventory.ts → modules/inventory/inventory.ts} +12 -0
  368. package/templates/app/packages/domain/src/modules/purchase/approvals.ts +39 -0
  369. package/templates/app/packages/domain/src/modules/purchase/index.ts +7 -0
  370. package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
  371. package/templates/app/packages/domain/src/{jobs.ts → modules/purchase/jobs.ts} +5 -0
  372. package/templates/app/packages/domain/src/{purchase-order.test.ts → modules/purchase/purchase-order.test.ts} +11 -2
  373. package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
  374. package/templates/app/packages/domain/src/{queries.ts → modules/purchase/queries.ts} +5 -0
  375. package/templates/app/packages/domain/src/{reactions.ts → workflows/purchase-inventory.ts} +8 -2
  376. package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
  377. package/templates/blank/.dockerignore +12 -0
  378. package/templates/blank/.env.example +71 -0
  379. package/templates/blank/.github/workflows/cage.yml +44 -0
  380. package/templates/blank/AGENTS.md +136 -0
  381. package/templates/blank/Dockerfile +25 -0
  382. package/templates/blank/README.md +40 -0
  383. package/templates/blank/_gitignore +9 -0
  384. package/templates/blank/apps/api/package.json +15 -0
  385. package/templates/blank/apps/api/src/main.ts +14 -0
  386. package/templates/blank/apps/api/src/worker.ts +10 -0
  387. package/templates/blank/apps/api/tsconfig.json +5 -0
  388. package/templates/blank/apps/web/index.html +14 -0
  389. package/templates/blank/apps/web/package.json +26 -0
  390. package/templates/blank/apps/web/src/app/app.tsx +106 -0
  391. package/templates/blank/apps/web/src/app/styles/global.css +606 -0
  392. package/templates/blank/apps/web/src/app/use-session.ts +43 -0
  393. package/templates/blank/apps/web/src/app/workspace-layout.tsx +95 -0
  394. package/templates/blank/apps/web/src/main.tsx +18 -0
  395. package/templates/blank/apps/web/src/modules/auth/index.ts +5 -0
  396. package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +104 -0
  397. package/templates/blank/apps/web/src/modules/directory/index.ts +7 -0
  398. package/templates/blank/apps/web/src/modules/directory/pages/user-detail-page.tsx +78 -0
  399. package/templates/blank/apps/web/src/modules/directory/pages/users-page.tsx +93 -0
  400. package/templates/blank/apps/web/src/modules/workspace/index.ts +5 -0
  401. package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +62 -0
  402. package/templates/blank/apps/web/src/shared/lib/error-message.ts +22 -0
  403. package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
  404. package/templates/blank/apps/web/src/shared/ui/brand.tsx +19 -0
  405. package/templates/blank/apps/web/src/shared/ui/page-state.css +47 -0
  406. package/templates/blank/apps/web/src/shared/ui/page-state.tsx +76 -0
  407. package/templates/blank/apps/web/src/shared/ui/require-capability.tsx +34 -0
  408. package/templates/blank/apps/web/tsconfig.json +11 -0
  409. package/templates/blank/apps/web/vite.config.ts +24 -0
  410. package/templates/blank/cage.config.json +14 -0
  411. package/templates/blank/db/migrations/0001_init.sql +63 -0
  412. package/templates/blank/deploy/nginx.conf +52 -0
  413. package/templates/blank/docs/ai/README.md +98 -0
  414. package/templates/blank/docs/ai/architecture.md +148 -0
  415. package/templates/blank/docs/ai/commenting.md +203 -0
  416. package/templates/blank/docs/ai/diagnostics.md +80 -0
  417. package/templates/blank/docs/ai/files.md +93 -0
  418. package/templates/blank/docs/ai/intelligence.md +348 -0
  419. package/templates/blank/docs/ai/ontology-context.md +172 -0
  420. package/templates/blank/docs/ai/primitives.md +282 -0
  421. package/templates/blank/docs/ai/project-structure.md +128 -0
  422. package/templates/blank/docs/ai/purchase-example.md +111 -0
  423. package/templates/blank/docs/ai/recipes.md +89 -0
  424. package/templates/blank/docs/ai/relations.md +160 -0
  425. package/templates/blank/docs/ai/routing.md +86 -0
  426. package/templates/blank/docs/ai/transfers.md +92 -0
  427. package/templates/blank/docs/ai/troubleshooting.md +65 -0
  428. package/templates/blank/docs/ai/workflow.md +152 -0
  429. package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
  430. package/templates/blank/docs/errors/CAGE-APPR-001.md +48 -0
  431. package/templates/blank/docs/errors/CAGE-APPR-002.md +47 -0
  432. package/templates/blank/docs/errors/CAGE-APPR-003.md +47 -0
  433. package/templates/blank/docs/errors/CAGE-APPR-004.md +47 -0
  434. package/templates/blank/docs/errors/CAGE-APPR-005.md +47 -0
  435. package/templates/blank/docs/errors/CAGE-APPR-006.md +53 -0
  436. package/templates/blank/docs/errors/CAGE-APPR-007.md +50 -0
  437. package/templates/blank/docs/errors/CAGE-APPR-010.md +48 -0
  438. package/templates/blank/docs/errors/CAGE-AUDIT-001.md +53 -0
  439. package/templates/blank/docs/errors/CAGE-AUTH-001.md +47 -0
  440. package/templates/blank/docs/errors/CAGE-BIZ-001.md +51 -0
  441. package/templates/blank/docs/errors/CAGE-BIZ-002.md +49 -0
  442. package/templates/blank/docs/errors/CAGE-BUDGET-001.md +47 -0
  443. package/templates/blank/docs/errors/CAGE-BUDGET-002.md +47 -0
  444. package/templates/blank/docs/errors/CAGE-BUDGET-003.md +47 -0
  445. package/templates/blank/docs/errors/CAGE-CMD-002.md +47 -0
  446. package/templates/blank/docs/errors/CAGE-CMD-003.md +47 -0
  447. package/templates/blank/docs/errors/CAGE-CONN-001.md +47 -0
  448. package/templates/blank/docs/errors/CAGE-CONN-002.md +47 -0
  449. package/templates/blank/docs/errors/CAGE-CONN-003.md +47 -0
  450. package/templates/blank/docs/errors/CAGE-CONN-004.md +47 -0
  451. package/templates/blank/docs/errors/CAGE-CONN-005.md +47 -0
  452. package/templates/blank/docs/errors/CAGE-CONN-006.md +47 -0
  453. package/templates/blank/docs/errors/CAGE-CONN-007.md +47 -0
  454. package/templates/blank/docs/errors/CAGE-CONN-008.md +47 -0
  455. package/templates/blank/docs/errors/CAGE-CONN-009.md +47 -0
  456. package/templates/blank/docs/errors/CAGE-CONN-010.md +47 -0
  457. package/templates/blank/docs/errors/CAGE-CONN-011.md +47 -0
  458. package/templates/blank/docs/errors/CAGE-CONN-012.md +47 -0
  459. package/templates/blank/docs/errors/CAGE-CONN-013.md +49 -0
  460. package/templates/blank/docs/errors/CAGE-CONN-014.md +48 -0
  461. package/templates/blank/docs/errors/CAGE-CONN-015.md +49 -0
  462. package/templates/blank/docs/errors/CAGE-CREATE-001.md +53 -0
  463. package/templates/blank/docs/errors/CAGE-DECL-001.md +48 -0
  464. package/templates/blank/docs/errors/CAGE-DECL-002.md +48 -0
  465. package/templates/blank/docs/errors/CAGE-DECL-003.md +47 -0
  466. package/templates/blank/docs/errors/CAGE-DECL-004.md +47 -0
  467. package/templates/blank/docs/errors/CAGE-DEP-001.md +48 -0
  468. package/templates/blank/docs/errors/CAGE-DEP-002.md +47 -0
  469. package/templates/blank/docs/errors/CAGE-DEP-003.md +47 -0
  470. package/templates/blank/docs/errors/CAGE-DEP-004.md +47 -0
  471. package/templates/blank/docs/errors/CAGE-DEP-005.md +47 -0
  472. package/templates/blank/docs/errors/CAGE-DIAG-001.md +53 -0
  473. package/templates/blank/docs/errors/CAGE-DLQ-001.md +48 -0
  474. package/templates/blank/docs/errors/CAGE-ENV-001.md +52 -0
  475. package/templates/blank/docs/errors/CAGE-ENV-002.md +51 -0
  476. package/templates/blank/docs/errors/CAGE-ENV-003.md +48 -0
  477. package/templates/blank/docs/errors/CAGE-EVENT-001.md +47 -0
  478. package/templates/blank/docs/errors/CAGE-EVENT-002.md +50 -0
  479. package/templates/blank/docs/errors/CAGE-FIELD-001.md +47 -0
  480. package/templates/blank/docs/errors/CAGE-FIELD-002.md +47 -0
  481. package/templates/blank/docs/errors/CAGE-FIELD-003.md +47 -0
  482. package/templates/blank/docs/errors/CAGE-FIELD-004.md +47 -0
  483. package/templates/blank/docs/errors/CAGE-FILE-001.md +56 -0
  484. package/templates/blank/docs/errors/CAGE-GEN-001.md +48 -0
  485. package/templates/blank/docs/errors/CAGE-GEN-002.md +47 -0
  486. package/templates/blank/docs/errors/CAGE-GEN-003.md +53 -0
  487. package/templates/blank/docs/errors/CAGE-GRANT-001.md +49 -0
  488. package/templates/blank/docs/errors/CAGE-GRANT-002.md +48 -0
  489. package/templates/blank/docs/errors/CAGE-GRANT-003.md +48 -0
  490. package/templates/blank/docs/errors/CAGE-IMPACT-001.md +48 -0
  491. package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -0
  492. package/templates/blank/docs/errors/CAGE-INIT-001.md +47 -0
  493. package/templates/blank/docs/errors/CAGE-INIT-002.md +49 -0
  494. package/templates/blank/docs/errors/CAGE-INIT-003.md +48 -0
  495. package/templates/blank/docs/errors/CAGE-INIT-004.md +48 -0
  496. package/templates/blank/docs/errors/CAGE-INIT-005.md +52 -0
  497. package/templates/blank/docs/errors/CAGE-JOB-001.md +47 -0
  498. package/templates/blank/docs/errors/CAGE-JOB-002.md +47 -0
  499. package/templates/blank/docs/errors/CAGE-JOB-003.md +47 -0
  500. package/templates/blank/docs/errors/CAGE-LINT-001.md +47 -0
  501. package/templates/blank/docs/errors/CAGE-MIG-001.md +47 -0
  502. package/templates/blank/docs/errors/CAGE-MIG-002.md +47 -0
  503. package/templates/blank/docs/errors/CAGE-MIG-003.md +5 -0
  504. package/templates/blank/docs/errors/CAGE-MIG-004.md +5 -0
  505. package/templates/blank/docs/errors/CAGE-MIG-005.md +47 -0
  506. package/templates/blank/docs/errors/CAGE-NAME-001.md +47 -0
  507. package/templates/blank/docs/errors/CAGE-NAME-002.md +47 -0
  508. package/templates/blank/docs/errors/CAGE-NAME-003.md +47 -0
  509. package/templates/blank/docs/errors/CAGE-NAME-004.md +47 -0
  510. package/templates/blank/docs/errors/CAGE-NAME-005.md +47 -0
  511. package/templates/blank/docs/errors/CAGE-NAME-006.md +47 -0
  512. package/templates/blank/docs/errors/CAGE-ORG-001.md +50 -0
  513. package/templates/blank/docs/errors/CAGE-PAIR-002.md +51 -0
  514. package/templates/blank/docs/errors/CAGE-QUERY-001.md +47 -0
  515. package/templates/blank/docs/errors/CAGE-QUERY-002.md +47 -0
  516. package/templates/blank/docs/errors/CAGE-QUERY-003.md +50 -0
  517. package/templates/blank/docs/errors/CAGE-REACT-001.md +47 -0
  518. package/templates/blank/docs/errors/CAGE-REACT-002.md +47 -0
  519. package/templates/blank/docs/errors/CAGE-REACT-003.md +50 -0
  520. package/templates/blank/docs/errors/CAGE-READS-001.md +50 -0
  521. package/templates/blank/docs/errors/CAGE-REG-001.md +54 -0
  522. package/templates/blank/docs/errors/CAGE-REG-002.md +49 -0
  523. package/templates/blank/docs/errors/CAGE-REG-003.md +47 -0
  524. package/templates/blank/docs/errors/CAGE-REL-001.md +64 -0
  525. package/templates/blank/docs/errors/CAGE-ROUTE-001.md +48 -0
  526. package/templates/blank/docs/errors/CAGE-SCOPE-001.md +47 -0
  527. package/templates/blank/docs/errors/CAGE-SCOPE-002.md +47 -0
  528. package/templates/blank/docs/errors/CAGE-SECRET-001.md +48 -0
  529. package/templates/blank/docs/errors/CAGE-SECRET-002.md +47 -0
  530. package/templates/blank/docs/errors/CAGE-SENS-001.md +48 -0
  531. package/templates/blank/docs/errors/CAGE-SQL-001.md +47 -0
  532. package/templates/blank/docs/errors/CAGE-SQL-002.md +47 -0
  533. package/templates/blank/docs/errors/CAGE-STATE-001.md +49 -0
  534. package/templates/blank/docs/errors/CAGE-STATE-002.md +47 -0
  535. package/templates/blank/docs/errors/CAGE-STATE-003.md +47 -0
  536. package/templates/blank/docs/errors/CAGE-STATE-004.md +47 -0
  537. package/templates/blank/docs/errors/CAGE-STATE-005.md +49 -0
  538. package/templates/blank/docs/errors/CAGE-STATE-010.md +48 -0
  539. package/templates/blank/docs/errors/CAGE-STATE-011.md +48 -0
  540. package/templates/blank/docs/errors/CAGE-STRUCT-001.md +51 -0
  541. package/templates/blank/docs/errors/CAGE-STRUCT-002.md +51 -0
  542. package/templates/blank/docs/errors/CAGE-SYNC-001.md +49 -0
  543. package/templates/blank/docs/errors/CAGE-TEST-001.md +47 -0
  544. package/templates/blank/docs/errors/CAGE-TEST-002.md +50 -0
  545. package/templates/blank/docs/errors/CAGE-TEST-003.md +52 -0
  546. package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +49 -0
  547. package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +48 -0
  548. package/templates/blank/docs/errors/CAGE-WORKER-001.md +48 -0
  549. package/templates/blank/docs/errors/CAGE-WORKER-002.md +50 -0
  550. package/templates/blank/docs/errors/CAGE-WORKER-003.md +48 -0
  551. package/templates/blank/docs/errors/README.md +357 -0
  552. package/templates/blank/docs/errors/runtime.md +50 -0
  553. package/templates/blank/docs/examples/purchase-admin/README.md +5 -0
  554. package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +14 -0
  555. package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +17 -0
  556. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +128 -0
  557. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +743 -0
  558. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/use-session.ts +43 -0
  559. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +109 -0
  560. package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +18 -0
  561. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
  562. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +6 -0
  563. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
  564. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +5 -0
  565. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
  566. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +5 -0
  567. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
  568. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
  569. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
  570. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
  571. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
  572. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.tsx +82 -0
  573. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +7 -0
  574. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
  575. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-intelligence.css +15 -0
  576. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
  577. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
  578. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/index.ts +5 -0
  579. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
  580. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/hooks/use-command.ts +42 -0
  581. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +24 -0
  582. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/navigation.ts +21 -0
  583. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
  584. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.css +134 -0
  585. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  586. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  587. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.css +28 -0
  588. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  589. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +20 -0
  590. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +35 -0
  591. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.css +47 -0
  592. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.tsx +76 -0
  593. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/require-capability.tsx +34 -0
  594. package/templates/blank/docs/examples/purchase-admin/cage.config.json +123 -0
  595. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +74 -0
  596. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +57 -0
  597. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +52 -0
  598. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +86 -0
  599. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +85 -0
  600. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +89 -0
  601. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +87 -0
  602. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +17 -0
  603. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +10 -0
  604. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +51 -0
  605. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/intelligence.ts +20 -0
  606. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +3 -0
  607. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +55 -0
  608. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +39 -0
  609. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +7 -0
  610. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
  611. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +18 -0
  612. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +146 -0
  613. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
  614. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +15 -0
  615. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +30 -0
  616. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -0
  617. package/templates/blank/package.json +22 -0
  618. package/templates/blank/packages/contracts/package.json +16 -0
  619. package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +74 -0
  620. package/templates/blank/packages/contracts/src/aggregates/role/index.ts +85 -0
  621. package/templates/blank/packages/contracts/src/aggregates/user/index.ts +89 -0
  622. package/templates/blank/packages/contracts/src/index.ts +55 -0
  623. package/templates/blank/packages/contracts/src/queries/index.ts +13 -0
  624. package/templates/blank/packages/contracts/tsconfig.json +5 -0
  625. package/templates/blank/packages/domain/package.json +24 -0
  626. package/templates/blank/packages/domain/src/index.ts +5 -0
  627. package/templates/blank/packages/domain/tsconfig.json +5 -0
  628. package/templates/blank/pnpm-workspace.yaml +10 -0
  629. package/templates/blank/renovate.json +5 -0
  630. package/templates/blank/tsconfig.base.json +8 -0
  631. package/dist/database.d.ts +0 -5
  632. package/dist/database.js +0 -70
  633. package/dist/database.js.map +0 -1
  634. package/managed/errors/CAGE-APPR-001.md +0 -32
  635. package/managed/errors/CAGE-APPR-002.md +0 -32
  636. package/managed/errors/CAGE-APPR-003.md +0 -32
  637. package/managed/errors/CAGE-APPR-004.md +0 -32
  638. package/managed/errors/CAGE-APPR-005.md +0 -32
  639. package/managed/errors/CAGE-APPR-006.md +0 -32
  640. package/managed/errors/CAGE-APPR-007.md +0 -32
  641. package/managed/errors/CAGE-APPR-010.md +0 -32
  642. package/managed/errors/CAGE-AUTH-001.md +0 -32
  643. package/managed/errors/CAGE-BUDGET-001.md +0 -32
  644. package/managed/errors/CAGE-BUDGET-002.md +0 -32
  645. package/managed/errors/CAGE-BUDGET-003.md +0 -32
  646. package/managed/errors/CAGE-CMD-002.md +0 -32
  647. package/managed/errors/CAGE-CMD-003.md +0 -34
  648. package/managed/errors/CAGE-CONN-001.md +0 -32
  649. package/managed/errors/CAGE-CONN-002.md +0 -32
  650. package/managed/errors/CAGE-CONN-003.md +0 -32
  651. package/managed/errors/CAGE-CONN-004.md +0 -32
  652. package/managed/errors/CAGE-CONN-005.md +0 -32
  653. package/managed/errors/CAGE-CONN-006.md +0 -32
  654. package/managed/errors/CAGE-CONN-007.md +0 -32
  655. package/managed/errors/CAGE-CONN-008.md +0 -32
  656. package/managed/errors/CAGE-CONN-009.md +0 -32
  657. package/managed/errors/CAGE-CONN-010.md +0 -32
  658. package/managed/errors/CAGE-CONN-011.md +0 -32
  659. package/managed/errors/CAGE-CONN-012.md +0 -32
  660. package/managed/errors/CAGE-CREATE-001.md +0 -32
  661. package/managed/errors/CAGE-DECL-001.md +0 -34
  662. package/managed/errors/CAGE-DECL-002.md +0 -34
  663. package/managed/errors/CAGE-DECL-003.md +0 -34
  664. package/managed/errors/CAGE-DECL-004.md +0 -34
  665. package/managed/errors/CAGE-DEP-001.md +0 -34
  666. package/managed/errors/CAGE-DEP-002.md +0 -34
  667. package/managed/errors/CAGE-DEP-003.md +0 -34
  668. package/managed/errors/CAGE-DEP-004.md +0 -34
  669. package/managed/errors/CAGE-DEP-005.md +0 -34
  670. package/managed/errors/CAGE-DLQ-001.md +0 -32
  671. package/managed/errors/CAGE-ENV-001.md +0 -32
  672. package/managed/errors/CAGE-EVENT-001.md +0 -32
  673. package/managed/errors/CAGE-EVENT-002.md +0 -32
  674. package/managed/errors/CAGE-FIELD-001.md +0 -32
  675. package/managed/errors/CAGE-FIELD-002.md +0 -32
  676. package/managed/errors/CAGE-FIELD-003.md +0 -32
  677. package/managed/errors/CAGE-FIELD-004.md +0 -32
  678. package/managed/errors/CAGE-GEN-001.md +0 -33
  679. package/managed/errors/CAGE-GEN-002.md +0 -33
  680. package/managed/errors/CAGE-GRANT-001.md +0 -32
  681. package/managed/errors/CAGE-GRANT-002.md +0 -32
  682. package/managed/errors/CAGE-GRANT-003.md +0 -32
  683. package/managed/errors/CAGE-IMPACT-001.md +0 -32
  684. package/managed/errors/CAGE-JOB-001.md +0 -32
  685. package/managed/errors/CAGE-JOB-002.md +0 -32
  686. package/managed/errors/CAGE-JOB-003.md +0 -32
  687. package/managed/errors/CAGE-LINT-001.md +0 -32
  688. package/managed/errors/CAGE-MIG-001.md +0 -32
  689. package/managed/errors/CAGE-MIG-002.md +0 -32
  690. package/managed/errors/CAGE-MIG-003.md +0 -32
  691. package/managed/errors/CAGE-MIG-004.md +0 -32
  692. package/managed/errors/CAGE-MIG-005.md +0 -32
  693. package/managed/errors/CAGE-NAME-001.md +0 -32
  694. package/managed/errors/CAGE-NAME-002.md +0 -32
  695. package/managed/errors/CAGE-NAME-003.md +0 -32
  696. package/managed/errors/CAGE-NAME-004.md +0 -32
  697. package/managed/errors/CAGE-NAME-005.md +0 -32
  698. package/managed/errors/CAGE-NAME-006.md +0 -32
  699. package/managed/errors/CAGE-ORG-001.md +0 -32
  700. package/managed/errors/CAGE-PAIR-002.md +0 -33
  701. package/managed/errors/CAGE-QUERY-001.md +0 -32
  702. package/managed/errors/CAGE-QUERY-002.md +0 -32
  703. package/managed/errors/CAGE-QUERY-003.md +0 -32
  704. package/managed/errors/CAGE-REACT-001.md +0 -32
  705. package/managed/errors/CAGE-REACT-002.md +0 -32
  706. package/managed/errors/CAGE-READS-001.md +0 -32
  707. package/managed/errors/CAGE-REG-001.md +0 -32
  708. package/managed/errors/CAGE-REG-002.md +0 -32
  709. package/managed/errors/CAGE-REG-003.md +0 -32
  710. package/managed/errors/CAGE-ROUTE-001.md +0 -32
  711. package/managed/errors/CAGE-SCOPE-001.md +0 -32
  712. package/managed/errors/CAGE-SCOPE-002.md +0 -32
  713. package/managed/errors/CAGE-SECRET-001.md +0 -32
  714. package/managed/errors/CAGE-SECRET-002.md +0 -32
  715. package/managed/errors/CAGE-SENS-001.md +0 -32
  716. package/managed/errors/CAGE-SQL-001.md +0 -32
  717. package/managed/errors/CAGE-SQL-002.md +0 -32
  718. package/managed/errors/CAGE-STATE-001.md +0 -32
  719. package/managed/errors/CAGE-STATE-002.md +0 -32
  720. package/managed/errors/CAGE-STATE-003.md +0 -32
  721. package/managed/errors/CAGE-STATE-004.md +0 -32
  722. package/managed/errors/CAGE-STATE-005.md +0 -32
  723. package/managed/errors/CAGE-STATE-010.md +0 -32
  724. package/managed/errors/CAGE-STATE-011.md +0 -32
  725. package/managed/errors/CAGE-SYNC-001.md +0 -35
  726. package/managed/errors/CAGE-TEST-001.md +0 -33
  727. package/managed/errors/CAGE-UNSAFE-001.md +0 -32
  728. package/managed/errors/CAGE-UPGRADE-001.md +0 -32
  729. package/managed/errors/README.md +0 -99
  730. package/templates/app/compose.yaml +0 -39
  731. package/templates/app/packages/contracts/src/purchase-order.ts +0 -72
  732. package/templates/app/packages/contracts/src/user.ts +0 -89
  733. package/templates/app/packages/domain/src/approvals.ts +0 -18
  734. package/templates/app/packages/domain/src/purchase-order.ts +0 -122
@@ -0,0 +1,348 @@
1
+ # 原生智能助理与 AI 审批
2
+
3
+ [返回学习入口](README.md) · [审批与命令](primitives.md) · [架构与执行模型](architecture.md)
4
+
5
+ 这是当前框架的可选运行能力,使用自研持久状态机,不依赖 DeepSeek-Harness。框架提供模型适配、工具、任务、记忆、HTTP 和 SDK;应用提供领域声明、审核策略、角色授权及界面。开发阶段的 `cage context` 查询源码本体,与这里面向登录用户的运行时助理用途不同。
6
+
7
+ ## 按需求定位接入点
8
+
9
+ 编程工具从项目 `AGENTS.md` 进入本页,按需求阅读对应部分。公开符号以当前安装包为准,片段中的业务对象和角色必须来自当前应用。
10
+
11
+ | 需求关键词 | 公开入口 | 本页使用说明 |
12
+ | --- | --- | --- |
13
+ | AI审批、智能审批、转人工 | `@yss123/cage-approval` 的 `step`、`AiStepOptions` | “AI 是一个正常审批步骤”;沿用 `approval`,声明三态及真实角色 |
14
+ | 业务助理、本体助理 | `@yss123/cage-ai` 的 `ai` | “启用后端”“助理工具来自注册表”;框架编译工具,应用提供声明 |
15
+ | 页面上下文、随页助理 | `@yss123/cage-client` 的 `useAssistant`、`useAiPageContext`、`AiPageContext` | “SDK 传入页面内容”;应用维护界面与语义快照 |
16
+ | 模型管理、动态配置 | `@yss123/cage-ai` 的 `managedModel` | “启用后端”;Admin 配置连接,部署配置凭据加密密钥 |
17
+ | Responses | `managedModel` 的 Admin 协议选项;代码配置用 `responsesModel` | “Responses 会话与上下文配置”;实际验证网关接续及压缩支持 |
18
+ | 性格、自定义人设 | `useAssistant`、`client.ai`;类型由 `@yss123/cage-ai-protocol` 提供 | “Admin 配置助理性格”;内置预设与自定义表达,不改变审核策略 |
19
+ | 上下文预算、大本体 | `@yss123/cage-ai` 的 `AiContextOptions`,传入 `ai({ context: ... })` | “大本体按需加载”;工具、历史、页面与输出共同受预算约束 |
20
+
21
+ 在应用根目录按需查询,例如:
22
+
23
+ ```powershell
24
+ pnpm exec cage capabilities "AI审批" --format json
25
+ pnpm exec cage capabilities "页面上下文" --format json
26
+ pnpm exec cage capabilities "Responses" --format json
27
+ ```
28
+
29
+ `capabilities` 返回框架公开 API;`cage context "业务关键词"` 定位本项目的业务声明。后者未发现业务节点时,仍需查前者判断框架是否已有接入能力。未安装的包或未命中的关键词也不能证明框架不支持;核对包版本、公开符号和本页说明。
30
+
31
+ 接入时分别记录以下证据:
32
+
33
+ | 状态 | 核对内容 |
34
+ | --- | --- |
35
+ | 框架支持 | 所需依赖的公开导出、签名与指南存在;浏览器只依赖 client、协议和契约 |
36
+ | 项目已启用 | domain 根入口导出 `ai()`、API/worker 使用相同声明、系统迁移已执行、模型及相关角色权限已配置;有助理需求时包含 `assistant` 并接入 SDK |
37
+ | 实际验证通过 | 真实角色和模型下完成本次需求的读取、交互、审批或写入验收;报告通过、跳过与未执行项 |
38
+
39
+ 先查现有 domain 入口,已有 AI 运行时就扩展该声明;框架只允许一个 `ai()` 运行时。空白模板只注册组织模型,`docs/examples/purchase-admin` 是参考源码,不代表启用了助理。标准范例可沿 `packages/domain/src/integrations/intelligence.ts`、`packages/domain/src/modules/purchase/approvals.ts` 和 `apps/web/src/shared/ui/assistant-panel.tsx` 阅读,路径规则见[学习入口](README.md)。后端循环、通用工具、会话表和性格管理使用框架;应用侧完成业务策略、授权与界面组合。
40
+
41
+ ## 启用后端
42
+
43
+ 在应用 domain 包安装与框架同版本的 `@yss123/cage-ai`,把声明从 domain 根入口导出。API 和 worker 使用同一 domain,标准 `createServer` / `startWorker` 自动装配服务,不需要手写业务路由或后台循环。
44
+
45
+ ```ts
46
+ import { ai, managedModel } from '@yss123/cage-ai';
47
+
48
+ export const intelligence = ai({
49
+ models: {
50
+ main: managedModel('main'),
51
+ },
52
+ assistant: {
53
+ model: 'main',
54
+ instructions: '请用中文解释,并引用读取到的对象或规则。',
55
+ confirmWrites: true,
56
+ limits: { maxSteps: 12, maxToolCalls: 30, tokenBudget: 40_000, timeoutMs: 120_000 },
57
+ },
58
+ maxConcurrentRuns: 2,
59
+ maxQueuedPerUser: 8,
60
+ delegationTtlMs: 30 * 60_000,
61
+ });
62
+ ```
63
+
64
+ `managedModel` 是框架托管的模型入口。应用引用稳定别名,实际模型名称、HTTP / HTTPS API 基地址、API Key、接口协议、上下文窗口、超时及启停状态在 `/admin/#/models` 配置。可声明多个入口供审批和助理分别使用。不需要在业务项目定义模型配置表、管理路由或环境变量读取逻辑。
65
+
66
+ 部署向 API 和 worker 注入同一份 `CAGE_AI_ENCRYPTION_KEY`(32 字节随机密钥的标准 Base64),也可通过连接器 `SecretProvider` 提供。它是加密模型凭据的部署主密钥,不是模型 API Key;应稳定保存并与数据库分开备份。不要随进程启动重新生成,也不要直接轮换它而不重新加密旧配置。未配置时不能保存 API Key。
67
+
68
+ 向管理者显式授予 `Sys.ai.models.manage` 后,在 Admin 填写服务信息并启用,保存后点击“测试连接”。普通助理用户不需要此管理能力。接口与页面均不回显 API Key,留空保留旧值;更换服务地址必须同时填写新密钥,避免把旧密钥转发到新的地址。更新需要配置版本,冲突时刷新后重试。配置按租户隔离,使用 AES-256-GCM 加密,变更与不含密钥的审计同事务提交。
69
+
70
+ 每个模型步进重新读取配置,API 与 worker 无需重启;已发出的请求继续使用当时的快照。托管模型始终调用实际服务,独立于 ERP 等连接器的 `CAGE_STAGE=fake`。接口协议可选 **Chat Completions** 或 **Responses**,服务须支持所选协议的 SSE 与函数工具。地址可填 `https://服务主机/v1` 或完整的 `/chat/completions`、`/responses` 路径,框架按协议选择终点。连接测试只发送固定诊断文字,不携带业务数据;成功不代表工具支持或审批判断质量已验收。
71
+
72
+ 需要代码配置或离线测试时,可使用 `chatModel('language-model', { model, hosts, secret, fake })` 或同包导出的 `responsesModel`:`secret` 是 SecretProvider 的密钥名称;默认遵循 `CAGE_STAGE`,fake 阶段必须显式提供模拟函数且禁止外呼;`environment: 'test' | 'prod'` 可独立选择真实模型环境。自定义 `credential` 解析器只在服务端按次调用,不参与声明序列化。两者默认 HTTPS,可显式设置 `protocol: 'http:'` 连接 HTTP 网关。所有标准模型外呼经过框架连接器的地址校验、限流、取消和超时。
73
+
74
+ ### Responses 会话与上下文配置
75
+
76
+ Admin 的 `apiFormat` 默认 `chat-completions`,旧模型升级后保持该协议;选择 `responses` 后启用服务端接续。`contextWindowTokens` 默认 32768,可配置 8192 至 2000000,必须按实际模型容量填写;窗口包括输入、输出及推理 Token,和 `assistant.limits.tokenBudget` 的单轮累计消耗分别控制。代码模型使用同名选项。
77
+
78
+ Responses 请求使用 `store: true` 和 `previous_response_id`。框架持久化返回的 response ID,后续只发送新增用户消息或 `function_call_output`;每次都重发当前系统规则、性格和页面上下文,因为服务不会继承前次的 instructions。更换模型配置版本、权限或注册声明后不接续旧链。worker 重启通过数据库中的接续状态继续,浏览器不维护也不能指定 response ID。
79
+
80
+ `previous_response_id` **不免除历史 Token 的上下文占用和输入计费**。Admin 的“服务端自动压缩”默认关闭,仅当服务明确支持 `context_management` 时开启;代码模型可设 `compaction: true`。框架在配置窗口的 60% 设置压缩阈值,不开启自动丢弃最早输入的 truncation。部分兼容网关虽然提供 `/responses`,但会拒绝 `previous_response_id`(例如要求 OpenAI API-key account);框架识别这一稳定错误并从本地完整记录重建当前请求,不把它当成业务失败,也不偷偷切换 Chat 协议。参考 [OpenAI 会话状态](https://developers.openai.com/api/docs/guides/conversation-state)和[压缩说明](https://developers.openai.com/api/docs/guides/compaction)。
81
+
82
+ 远端链条超过本地估算预算,或服务返回历史不存在时,框架用本地记录重建有界请求。原始工具计划、命令回执及模型返回的不透明推理项仍在后端;同配置恢复时保留原生输出项,跨配置不复用它们。已完成的命令从回执恢复,不再次提交。外部服务的会话保存不能代替 Cage 的审计、授权和恢复记录。
83
+
84
+ 升级执行系统迁移 `cage:ai_context_001` 和 `cage:ai_execution_001`:前者增加模型协议/窗口及接续状态,后者将调用预留、尝试次数、接续兼容性及工具预算单独持久化;不改写已有迁移。旧运行的已有计数保留,不追溯推测其费用。前端调用 `client.ai` 的发送、流式订阅与交互方法不变。
85
+
86
+ 只有 AI 审批时可以省略 `assistant`。`ModelProvider` 是服务端扩展接口,可适配其他协议;适配器必须响应 `AbortSignal`。运行时仍会在超时后放弃等待,迟到结果不会被提交。
87
+
88
+ 审查并执行 `pnpm migrate` 后再启动 API/worker。新增命名系统迁移由框架携带,`cage doctor` 会列出未执行项。不要把建表放到服务启动。管理员显式向使用助理的人授予 `Sys.ai.use`,再按需授予领域 `read`、命令与范围;启用服务不自动授予业务权限。
89
+
90
+ ## Admin 配置助理性格
91
+
92
+ 性格是框架提供的租户配置,无需应用声明性格聚合或编写工具。启用 `ai({ models, assistant })`、执行系统迁移后即可使用;管理员需显式获得 **`Sys.ai.personalities.manage`**,从 `/admin/#/personalities` 管理。它与 `Sys.ai.models.manage`、普通用户的 `Sys.ai.use` 分开授权。
93
+
94
+ 框架内置六种业务无关的预设:
95
+
96
+ | key | 名称 | 表达特点 |
97
+ | --- | --- | --- |
98
+ | partner | 靠谱搭档(默认) | 自然直接,先讲结论和下一步 |
99
+ | minimalist | 极简高手 | 简短明确,减少铺垫 |
100
+ | teacher | 耐心老师 | 分步解释,帮助理解概念 |
101
+ | energetic | 元气搭子 | 轻快积极,适当表情 |
102
+ | detective | 冷面侦探 | 分清证据、推断和待核实事项 |
103
+ | butler | 幽默管家 | 得体幽默,重要结论表达清晰 |
104
+
105
+ 管理员可编辑预设,也可新增自定义性格:名称、头像符号、自然语言描述、回复长度、用户称呼、表情频率和最多三句说话示例。每租户含预设最多 30 种;通过启停控制用户是否可选。默认项必须已启用,停用默认项之前需先设置其他默认项。配置和默认项分别使用版本号防止覆盖并发修改,并留下事务审计。预设从框架代码读取,只有实际编辑时才保存租户覆盖值。
106
+
107
+ “试聊一下”使用未保存的编辑内容和应用助理绑定的模型,逐段显示回复,可随时停止;不携带业务工具、页面、会话历史或记忆,不保存成正常会话。每次只调用一次模型,最多 600 个输出 Token、20 秒,同一用户同时一条、每个运行时最多四条。它用于体验语气;正常助理仍有本体与工具上下文,措辞可能有所不同。
108
+
109
+ 会话的 `personalityKey: null` 表示跟随租户默认。用户也可选择具体性格,切换保留会话、历史和页面上下文。**每次提交消息时保存完整性格快照**,之后的编辑、默认项调整或切换仅影响后续消息;已提交的任务及幂等重试继续使用原快照。若显式选中的性格被停用,下次提交会要求重新选择,框架不会偷偷替换。
110
+
111
+ 性格只作用于助理的表达。AI 审批不加载它;工具可用性、读取范围、写入确认、参数校验和业务状态约束均由服务端执行层决定,性格描述不能更改这些约束。普通用户的目录仅包含名称、符号、key 和版本,不公开内部描述与示例。
112
+
113
+ SDK 的状态层可直接接到应用自己的下拉框或卡片:
114
+
115
+ ```tsx
116
+ const assistant = useAssistant(client.ai, page);
117
+ // assistant.personalities:已启用的性格摘要。
118
+ // assistant.personality:当前表达身份;personalityKey 为 null 表示跟随默认。
119
+ // assistant.defaultPersonalityKey:租户默认项。
120
+ // assistant.personalityBusy / personalityError:切换状态与错误。
121
+ await assistant.setPersonality('teacher');
122
+ await assistant.setPersonality(null); // 恢复跟随默认
123
+ await assistant.refreshPersonalities(); // 再次打开面板时刷新配置
124
+ ```
125
+
126
+ 以上 hooks 和 `client` 从 `@yss123/cage-client` 导入,`page` 是应用提供的页面上下文。切换期间应用应暂时禁用发送和交互按钮;正在生成时 hook 不接受切换。`AiRun.personality` 是该轮实际使用的摘要,历史消息标签应从运行结果读取,不能用当前选择重新标注旧回复。字段型式与管理接口均在浏览器可用的 `@yss123/cage-ai-protocol`,AI 运行时不进入浏览器。
127
+
128
+ 非 React 应用可使用 `client.ai.personalities()`、`createSession({ title, personalityKey })` 和 `selectPersonality(sessionId, { key, version: session.personalityVersion })`。旧的 `createSession('标题')` 调用仍可使用。管理客户端另有 `personalitySettings()`、`savePersonality()`、`savePersonalitySettings()` 和返回完整结果的 `previewPersonality()`;Admin 的即时试聊使用同一预览接口的 POST SSE 模式。
129
+
130
+ 升级已有应用时,新的 `cage:ai_personalities_001` 系统迁移新增配置表及会话/运行字段,旧会话自动跟随默认。执行迁移并显式授予管理能力即可;不需要修改业务声明或重新创建会话。
131
+
132
+ ## AI 是一个正常审批步骤
133
+
134
+ 在原有 `step` 中声明 `kind: 'ai'`,可放在人工节点前后,也可成为唯一或最后一个节点。下面是组合片段:`Document`、`Submitted`、`Withdrawn` 与三个结论命令来自应用现有领域模块。
135
+
136
+ ```ts
137
+ import { approval } from '@yss123/cage-kernel';
138
+ import { route, step, approver } from '@yss123/cage-approval';
139
+ import { Document, Submitted, Withdrawn, accept, reject, revise } from './document.js';
140
+
141
+ export const review = approval(Document, {
142
+ process: 'document-review',
143
+ start: Submitted,
144
+ cancelOn: [Withdrawn],
145
+ routable: [],
146
+ onApproved: accept,
147
+ onRejected: reject,
148
+ onReturned: revise,
149
+ automatedBy: 'ai_reviewer',
150
+ });
151
+
152
+ export const reviewRoute = route('document-review', [
153
+ step('智能审核', {
154
+ kind: 'ai',
155
+ model: 'main',
156
+ instructions: '检查说明是否足以支持申请。材料不足时退回并给出修改建议;无法可靠判断则转人工。',
157
+ context: { fields: ['reason'], queries: [] },
158
+ handoff: approver.role('reviewer'),
159
+ limits: { maxSteps: 5, maxToolCalls: 8, timeoutMs: 60_000 },
160
+ onFailure: 'manual',
161
+ }),
162
+ // 如需后续人工审批,在此继续加入普通 step。
163
+ ]);
164
+ ```
165
+
166
+ `handoff` 指定当前节点的接管人,不创建嵌套流程。三个模型结果分别是 `pass`、`return`、`manual`:
167
+
168
+ | 结果 | 流程行为 | 领域行为 |
169
+ | --- | --- | --- |
170
+ | pass | 推进下一个步骤;已经是末步则结束 | 末步调用 onApproved |
171
+ | return | 结束本次审批轮次 | 调用 onReturned,通常进入可修改状态 |
172
+ | manual | 当前步骤创建人工待办 | 由接管人通过、拒绝或退回后继续 |
173
+
174
+ 三个结论命令必须属于该聚合并声明 `invokedBy: 'process'`。`onReturned` 与最终拒绝 `onRejected` 独立。修订后再次触发 start 事件,会创建新轮次,从第一个步骤重新开始;旧步骤和旧任务不能继续生效。通知申请人可以由结论命令发事件,再接已有通知反应/连接器;框架不会猜测通知渠道。
175
+
176
+ `automatedBy` 是真实组织角色的 code,不是模型可选身份。角色需显式拥有对象读取、所需查询读取、通过/退回命令,以及相应范围与额度。没有隐式全范围,也不冒充提交人。`sod.notSameAs` 要求可核验的真人操作人,自动节点不能绕过该约束;这种命令会转人工。
177
+
178
+ `context.fields` 白名单定义单据上下文;`context.queries` 引用已导出的 query 名称,AI 可按查询 schema 补参数。审核阶段只能调用这些查询、`review_decide` 及读取本次证据的 `context_read`,不能访问其他会话、动态加载其他业务工具或调用助理写工具。证据引用会校验来源是否已提供,但不会把模型判断当作数学证明。
179
+
180
+ 模型故障、预算耗尽或无裁决默认转人工,原因明确记录为系统失败。`onFailure: 'failed'` 则保留失败步骤,须修复配置并通过应用的撤回/重提流程恢复。找不到接管人时同样记录失败,不静默通过。单据版本已变化时迟到裁决被拒,需撤回/重新提交当前内容。
181
+
182
+ `client.approvalHistory(aggregate, id)` 查看当前可读对象的轮次、节点、理由和建议。生成解释如涉及额外查询范围或敏感明文,会进一步核验访问者授权;无权查看的解释返回 `detailRestricted: true`。原有待办接口新增 `POST /api/approval/tasks/:id/return`。
183
+
184
+ ## 助理工具来自注册表
185
+
186
+ 框架从聚合、命令、查询和审批声明构建运行本体;`pnpm gen` 也输出 `generated/ai/ontology.json`。运行时默认直接使用当前注册表生成的清单。传入 `ontology` 时必须匹配注册指纹。清单不包含 handler 源码、原始 SQL、隐藏字段或模型密钥。
187
+
188
+ | 工具 | 执行边界 |
189
+ | --- | --- |
190
+ | ontology_search | 当前权限内的本体摘要目录,支持关键词、聚合和分页 |
191
+ | ontology_describe | 按 key 展开 overview / fields / input / related;字段、关联节点可分页 |
192
+ | tool_search / tool_load | 搜索在预算内自动加载命中工具;已知 key 可显式加载;均保留完整 schema 与授权校验 |
193
+ | context_read | 按本会话 runId / 动作引用 / path 分页取回页面、回执和早期对话;重新核验授权指纹 |
194
+ | data_get / data_list / data_related | ReadSide 的只读账号、安全视图、掩码和读取审计 |
195
+ | data_query | 有界字段/过滤/统计计划,注册字段映射成参数化查询,不接收 SQL |
196
+ | query_* | 为已有 query 生成,沿用 reads 和输入校验 |
197
+ | command_* | 为允许 user 调用且已授权的命令生成;修改须携带 expectedVersion |
198
+ | approval_history | 当前可读单据的审批轮次、步骤进度与审核理由;沿用审批记录的解释权限过滤 |
199
+ | approval_tasks / approval_decide | 当前用户自己的待办;决定走审批引擎与结论命令 |
200
+ | request_input / request_page_context | 持久化互动、释放执行者,收到回复再继续 |
201
+ | memory_remember | 确认后保存偏好;最多 50 条,可查询和删除 |
202
+
203
+ 普通写操作默认需要确认,可由应用明确设置 `confirmWrites: false`。记忆保存始终需要确认。确认展示的是持久动作计划;回复不能换命令、目标、参数或版本。批量操作由多个独立动作串行处理,具有各自回执与确认,不承诺整批事务原子性。
204
+
205
+ ### 大本体按需加载
206
+
207
+ 完整本体只在后端构建和索引,不整份塞进每个模型请求。框架按完整工具定义的估算 Token、协议工具数量上限,以及扣除系统规则、页面、历史和输出预留后的实际空间选择工具。全部授权工具能在预算内放下时直接提供,不加入工具搜索与加载入口;超出时按显式加载结果、本轮问题、页面聚合和表单命令选取候选,并提供发现工具。没有固定“超过 8 个业务工具就搜索”的规则。
208
+
209
+ `tool_search` 返回摘要、分页信息及 `loaded/notLoaded`,同时将能放下的候选完整定义持久化,下一次模型请求即可调用,不需要再经历一次 `tool_load` 决策。`tool_load` 供已知 key 的显式选择使用;定义无法完整容纳时明确报错。选择与搜索回执同事务保存,停机后可恢复;搜索只准备工具,绝不直接执行业务命令。
210
+
211
+ 应用可在框架的 `ai()` 声明中调整延迟与上下文的取舍,无需编写业务工具:
212
+
213
+ ```ts
214
+ ai({
215
+ models: { main: managedModel('main') },
216
+ assistant: { model: 'main', limits: { maxSteps: 12, maxModelRetries: 2 } },
217
+ context: { maxToolTokens: 8000, maxTools: 128, maxHistoryTokens: 12000 },
218
+ });
219
+ ```
220
+
221
+ 这些可选上限仍受模型窗口和本轮剩余预算约束。默认工具预算取窗口的 25%(至少容纳通用工具),`maxTools` 默认 128 且包含通用工具;默认近期历史预算不超过窗口的 40% 或本轮输入预算的一半。若工具定义较大,可在真实窗口允许的范围内提高 `maxToolTokens`。Token 是跨供应商的保守估算,框架另预留窗口的 10% 作为误差余量,不应当作精确计费分词器。
222
+
223
+ 本体搜索使用确定性关键词及中文相邻词匹配,返回摘要和 `total/nextOffset`;它没有语义向量检索。未命中时可缩短关键词、按聚合筛选或空查询分页浏览全部授权目录。`ontology_describe` 可读取已声明输入、规则与双向对象关系,不把当前页面限定为整个业务范围。约束或不变量只导出名称时,模型不能从名称推断未声明的条件或阈值。读取权限和命令权限分别判断,只有创建能力的人也能发现合法创建输入;流程专用命令不能被加载为助理写工具。
224
+
225
+ 上下文预算统一计入系统指令、性格、页面事实、消息历史、工具定义和工具结果,并为输出及估算误差留空间。工具 schema 和本轮用户问题不被截断;工具定义过大时减少候选,显式加载仍放不下则要求分批或调整真实模型窗口。无法容纳必要输入时报 `AI_CONTEXT_TOO_LARGE`;累计预算耗尽时报 `AI_BUDGET_EXCEEDED`。
226
+
227
+ 大型页面/结果只向模型发送有界预览,完整的已授权上下文与工具返回值保存在数据库,可用 `context_read` 按引用、路径和分页取回。查询本身的行数上限仍然有效:预览收起与查询截断是不同层次,未查询的行需继续分页或缩小范围,不会凭空存入回执。长历史优先收起旧轮次,再整体收起已完成的工具调用/结果组;不会拆散配对,或删除持久记录。最近的工具组和当前问题保持完整。
228
+
229
+ Chat Completions 和本地重建按预算读取近期完整交互,包括用户补充、工具调用、回执及最终回答,不固定只取六轮问答。每条运行只取自己的消息段,避免历史递归重复。失败或取消的轮次会注明状态,未配对调用不会伪装为成功;用户补充在当前轮次不作为普通工具结果裁成预览。超过窗口时逐个移出旧轮次,原文可用 `context_read` 的 `conversation` 来源及 `messages` 路径分页找回;不透明推理项只用于协议恢复,不经该工具返回给模型。
230
+
231
+ Responses 正常接续只发新增条目;明确拒绝接续时释放本次预留并从本地重建,不消耗有效模型步数。尝试次数有独立上限 `maxSteps + maxModelRetries`,后者默认 2、允许 0 至 8,避免故障造成无限重试。网关“不支持接续”的标记独立保留,重启或后续会话轮次不会重复探测;新会话或模型配置版本改变后可以重新尝试。启用压缩不等于压缩已经发生,预算不因开关自行假定历史缩小。
232
+
233
+ 旧轮次不因新权限复用:权限指纹或注册指纹变化会拒绝旧运行输出/互动。偏好是用户数据,不可用来存放凭据、授权或代替业务事实。
234
+
235
+ 这种结构保留原始规则与证据的可访问性,但不能保证所有模型回答与全量输入完全一致。关键词召回、模型是否继续取证、服务端压缩都可能影响效果。应评测跨模块查询、少见术语、长上下文原文回查、规则例外、权限变化和审批转人工;不能只以请求变小或连接成功作为精度验收。
236
+
237
+ ## SDK 传入页面内容
238
+
239
+ 前端只依赖 `@yss123/cage-client` 和生成契约。应用明确提供语义上下文,SDK 不抓取整个 DOM。
240
+
241
+ ```ts
242
+ import { client, AiPageContext } from '@yss123/cage-client';
243
+
244
+ // record、selectedIds、filters、form 是当前页面已加载的数据与本地状态。
245
+ const page = new AiPageContext({
246
+ page: { id: 'document-detail', title: '对象详情', kind: 'form', route: location.pathname },
247
+ subject: { aggregate: 'Document', id: record.id, observedVersion: record.version },
248
+ selection: { aggregate: 'Document', ids: selectedIds },
249
+ view: { aggregate: 'Document', input: filters, visibleIds: [record.id] },
250
+ draft: { command: 'Document.edit', values: form, baseVersion: record.version },
251
+ visibleContent: [{ id: 'help', text: '当前页面的填写提示' }],
252
+ });
253
+
254
+ const session = await client.ai.createSession('当前对象');
255
+ if (session.ok) {
256
+ const result = await client.ai.send(session.data.id, {
257
+ message: '帮我检查当前还没保存的说明',
258
+ pageContext: page.snapshot(),
259
+ }, { idempotencyKey: crypto.randomUUID() });
260
+ if (result.ok) {
261
+ const state = await client.ai.watch(result.data.id, event => {
262
+ // 应用把 message.delta / tool.completed / interaction.required 渲染到自己的界面。
263
+ renderEvent(event);
264
+ });
265
+ renderRun(state);
266
+ }
267
+ }
268
+ ```
269
+
270
+ `pageInstanceId` 区分页面实例,`revision` 由 `page.update(...)` 递增;发送时复制快照。修改另一个标签页不会改变已提交消息。补充页面交互只接受原页面相同或更高 revision,不接受另一个实例。切换到不同对象时页面应创建新 `AiPageContext`,React 页面可按 URL 对象 ID 设置组件 key。
271
+
272
+ 服务端按当前授权重新读取 subject、selection 和 visibleIds。`visibleContent`、标题、筛选描述是客户端提示;草稿标记为未保存,并剔除对应聚合隐藏字段、按权限掩码。它们都不能改变系统指令或授权。不要往可见文字和草稿中装入凭据;草稿只保留对应聚合声明字段,不把自定义命令的任意中间参数当成业务记录。
273
+
274
+ 页面快照最大 64 KiB,选择或可见 ID 最多 100 个,可见文字最多 10 段。上下文过大将明确报告截断并要求缩小范围,不把部分结果当完整业务集合。
275
+
276
+ React 可使用以下状态层,界面仍由应用编写:
277
+
278
+ ```tsx
279
+ const page = useAiPageContext({
280
+ page: { id: 'detail', title: '对象详情', kind: 'detail', route: location.pathname },
281
+ subject: { aggregate: 'Document', id: record.id, observedVersion: record.version },
282
+ });
283
+ const assistant = useAssistant(client.ai, page);
284
+ // assistant.send(message)
285
+ // assistant.respond(interaction.id, { approved: true })
286
+ // assistant.respond(interaction.id, { answer: '补充参数' })
287
+ // assistant.respond(interaction.id, { pageContext: page.snapshot() })
288
+ // assistant.cancel()
289
+ // 状态:session、run、events、busy、error、streamingText、progress。
290
+ // streamingText:当前模型步骤已收到的完整文字,可直接交给应用的 Markdown 组件。
291
+ // progress.stage:idle / queued / context / model / tool / waiting / done。
292
+ // progress.tool / toolName / toolState:当前工具及执行状态。
293
+ ```
294
+
295
+ 以上片段的 hooks 从 `@yss123/cage-client` 导入,record/location 是应用路由与数据。SDK 会在卸载、退出和切换账号时取消订阅并清理 hook 状态;应用其他缓存仍须按[开发步骤](workflow.md)处理。
296
+
297
+ `send` / `respond` 返回的 Promise 等待本轮完成或需要用户交互;界面应在等待期间渲染 `streamingText` 和 `progress`。`run.status`、步数、工具调用数和待确认操作也随事件更新,不必等 Promise 返回。`model.started` 表示开始一次模型调用,`message.delta` 是增量文本,`tool.started` / `tool.completed` 表示实际工具进度;这些事件不包含模型的私有推理内容。新的模型步骤会重置当前文本,最终以 `message.completed` 校准。
298
+
299
+ `events` 只保留最近 1000 条诊断事件,不要从它重建完整回复;`streamingText` 独立累计,长回复不会丢失开头,断线按事件序号续传。停止后保留已收到的部分文字。Markdown 渲染、滚动跟随和交互卡片由应用负责;采购范例用 `react-markdown` / `remark-gfm` 渲染标题、列表、代码与表格,禁用原始 HTML,并将模型图片转换为说明文字。
300
+
301
+ 模型适配器须在生成期间调用 `onText` 才能实时显示文字。运行时首段立即持久化,后续通常以最多 40ms 的短窗口合并,减少逐 token 数据库往返;HTTP 每 100ms 追赶一次事件,有积压时连续读取。以上是调度间隔,不是总延迟保证,实际首字还受模型推理、worker 排队、网络和数据库耗时影响。
302
+
303
+ 部署时必须保持 SSE 不缓冲:`/api/ai/runs/:id/events` 和 `/api/ai/admin/personality-preview` 使用 HTTP/1.1 或更高协议,关闭代理缓冲、缓存和压缩,代理读超时至少覆盖服务端 55 秒的单次事件流连接。框架返回 `X-Accel-Buffering: no` 和 `Cache-Control: no-cache, no-store, no-transform`;采购范例的 `deploy/nginx.conf` 提供独立 location。若代理仍缓冲,浏览器可能直到请求结束才看到文本。
304
+
305
+ ## 协议、恢复与当前边界
306
+
307
+ | 接口 | 用途 |
308
+ | --- | --- |
309
+ | GET /api/ai/admin/models | 本租户托管模型入口和配置状态;不含密钥 |
310
+ | POST /api/ai/admin/models/:key | 保存配置(版本校验、加密及审计) |
311
+ | POST /api/ai/admin/models/:key/test | 测试已保存的连接(最多 20 秒) |
312
+ | GET /api/ai/personalities | 当前租户已启用性格摘要与默认项 |
313
+ | GET /api/ai/admin/personalities | 性格管理配置和设置版本;需独立管理能力 |
314
+ | POST /api/ai/admin/personalities/:key | 保存预设覆盖或自定义性格;带配置版本 |
315
+ | POST /api/ai/admin/assistant-settings | 修改租户默认性格;带设置版本 |
316
+ | POST /api/ai/admin/personality-preview | 未保存草稿试聊;Accept: text/event-stream 使用 SSE |
317
+ | GET /api/ai/sessions;POST 同路径 | 本人会话列表 / 新建 |
318
+ | POST /api/ai/sessions/:id/personality | 选择会话性格;带 personalityVersion,key 可为 null |
319
+ | POST /api/ai/sessions/:id/messages | 提交消息;必须有 Idempotency-Key,返回 202 |
320
+ | GET /api/ai/sessions/:id/runs | 本人会话轮次 |
321
+ | GET /api/ai/runs/:id | 运行状态、结果、等待的互动 |
322
+ | GET /api/ai/runs/:id/events?after=N | 有序事件;Accept: text/event-stream 使用 SSE |
323
+ | POST /api/ai/runs/:id/interactions/:interactionId | 回复确认、补充输入或页面快照 |
324
+ | POST /api/ai/runs/:id/cancel | 取消;已提交的业务动作保留回执 |
325
+ | GET /api/ai/memory;DELETE /api/ai/memory/:id | 本人偏好列表 / 删除 |
326
+
327
+ HTTP 复用会话、CSRF、限流,并持续检查身份。后台委托绑定真实登录 session;注销、过期或授权变化后不继续执行。直接调用服务端 `AiRuntime.submit(ctx, ...)` 的 ctx 必须来自可信认证代码,不接受模型或客户端传入。
328
+
329
+ 数据库保留 `ai_session/run/event/action/interaction/memory`,审批增加独立的 `approval_step`。worker 用 `SKIP LOCKED` 领取任务、定期续租,通过租约 token 阻止旧执行者提交。每个会话串行,跨会话可以并发;某个任务结束就补充空闲名额,已有慢请求时也会每 100ms 检查空闲名额可领取的新任务。并发和连接器限流是每进程上限。等待互动不占执行者,但仍受委托期限限制。
330
+
331
+ 模型调用前持久化尝试次数和独立预算预留,完成后按 usage 结算消耗并增加有效步数;明确接续拒绝释放预留,网络中断或崩溃导致结果未知时保守结算一次预留。工具计划先落库,业务写入与动作回执同事务提交。进程在提交后中断也不会重复写;回执不依赖 24 小时内核幂等缓存。读工具可重试。三次相同工具无进展、步数/尝试次数/调用/Token 预算或总超时会终止;输入校验与业务冲突可以成为 Observation 供模型修正。
332
+
333
+ `context.updated` 记录全量/发现模式、加载数量与估算预算;`model.completed` 记录请求耗时、首段文字到达时间、用量来源和工具调用数量;`model.failed` 区分明确拒绝与结果未知。首段文字时间从调用模型适配器开始计量,包含连接器限流及网络耗时,不等同于上游服务自身的 TTFB。
334
+
335
+ 排查失败时,`AI_TIMEOUT` 表示整个运行超过截止时间;`AI_MODEL_TIMEOUT` 表示单次模型请求超时。HTTP 拒绝、限流、网络异常、上游流内错误、输出上限、响应缺失或格式异常分别使用 `AI_MODEL_HTTP_ERROR`、`AI_MODEL_RATE_LIMITED`、`AI_MODEL_CONNECTION_FAILED`、`AI_MODEL_UPSTREAM_ERROR`、`AI_MODEL_OUTPUT_LIMIT`、`AI_MODEL_INCOMPLETE`、`AI_MODEL_RESPONSE_INVALID`。`model.failed` 保存 `code/reason/durationMs/firstTextMs`,有证据时附带 HTTP 状态及稳定错误码,不保存上游错误正文、密钥或 JSON 解析器片段。未知异常仍使用 `AI_EXECUTION_FAILED`,不能仅凭这个代码判断超时;这些分类不自动开启失败重试。
336
+
337
+ Token 使用优先按模型返回 usage 核算;缺少 usage 时使用文本估算和输出预留额度,不能用于精确计费。兼容服务分词方式不同,输入窗口仍需留余量。上下文采用目录检索、有界输入及可选的 Responses 服务端压缩,没有向量检索或长期业务事实知识库。当前不提供通用浏览器操作、任意代码/SQL 执行、第三方非幂等写工具或现成聊天页面。运行记录不自动清理,部署时须为这些表制定保留策略;审计与回执清理不能破坏仍有效的操作去重。
338
+
339
+ ## 接入后的验收
340
+
341
+ 按本次接入范围验证,不必为只调整入口文档的变更重复数据库和模型测试:
342
+
343
+ - 业务助理:使用普通角色完成一次实际只读查询,核对结果来源及数据范围;需写入时检查确认内容、取消确认和版本冲突,只有成功回执才显示完成。
344
+ - 随页界面:验证当前对象、选中项、未保存草稿和页面切换;生成期间展示增量文字与工具进度,完成后核对 Markdown,退出或切换账号时清理状态。
345
+ - AI 审批:覆盖 pass、return、manual,检查退回修改后的新轮次从头开始;模型失败应按节点配置转人工或留在失败状态,不得伪造通过。
346
+ - 管理配置:验证模型连接和一次实际工具交互,性格切换作用于后续消息;需要 Responses 接续或压缩时分别核对实际支持,连接成功不能替代这些验证。
347
+
348
+ `cage doctor` 可辅助检查注册、迁移和进程证据,但未知项不能当作通过;诊断用法见[能力发现与状态诊断](diagnostics.md)。模型输出质量需要应用使用自己的规则样例评测。框架验证的是权限、状态、预算和事务边界;发布前需使用实际模型服务、实际角色和审批样例联调。
@@ -0,0 +1,172 @@
1
+ # 用本体图辅助 AI 开发业务
2
+
3
+ [返回学习入口](README.md) · [开发步骤](workflow.md)
4
+
5
+ 本页命令在**应用根目录**运行,使用项目安装的 CLI。工具直接分析当前注册的 domain,无需启动 API、worker 或数据库。不要把 Web 截图作为 AI 理解业务的唯一材料:优先取得结构化上下文,再按源码位置阅读实现。
6
+
7
+ ## 在浏览器按业务阅读
8
+
9
+ 运行 `pnpm exec cage graph` 打开业务地图,默认从业务板块进入,再选择完整流程,点击阶段查看规则与实现代码。声明了 `businessProcess` 的板块优先展示完整业务流程;其他板块按真实状态迁移展示对象生命周期。具体操作与查询收在折叠区中。模块目录下的业务对象归入同一板块,未分模块的项目按业务对象组织;查询、任务和外部通知按已声明的读取或调用关系出现在相关板块。系统组织模型默认隐藏,可单独开启。
10
+
11
+ 板块默认使用所属对象的中文名称。可在 `cage.config.json` 的 `graph.labels` 设置 `"module:purchase": "采购管理"` 这样的板块标题;未分模块的对象沿用 `aggregate:对象名`。板块标题属于显示配置,不改变节点身份、本体哈希或业务逻辑。
12
+
13
+ 完整流程以矩形展示业务阶段、菱形展示决定分支、圆角终点展示结束结果。绿色箭头标记业务走向,并注明参与人、自动或等待;棕色箭头标记展开的次要分支;虚线标记涉及的业务对象。取消等次要路径可以展开,审批通过/驳回等主要分支保持可见。主线保持同一轴线,侧面分支使用独立出口和通道,汇合复用已有阶段。长线在源节点附近也显示方向箭头,分支文字注明动作与去向,回路入口注明来源;文字放在线旁,悬停或点选连线可突出显示对应的起点与终点。
14
+
15
+ 主要实现绑定了代码审批路由的阶段默认展开为审批子流程:按声明顺序展示每一步的标题、审批人、任一或全部同意规则;条件用菱形展示,“是”进入该组审批,“否”从侧边跳过整组,再继续后续步骤。所需步骤全部通过才继续业务,任一步骤驳回则结束本轮审批。审批字段和角色使用 `graph.labels` 中的中文名称,点击容器仍可查看原审批及路由源码。未抽取到绑定路由时明确提示缺少步骤;取消审批只作为终止动作展示。这是声明的静态阅读图,不表示某张单据当前走到了哪一步。
16
+
17
+ 普通滚轮以光标为中心缩放,空白处拖动平移;选择模式下可拖动节点,箭头随之更新,抓手模式、空格或中键可从任意位置平移。工具栏支持横向/纵向布局、100% 缩放、适应画布、回到起点、重置节点布局及展开画布(Esc 退出);触屏支持单指平移与双指缩放。长流程首次按可读字号展示起点,点击“适应”查看全图。点击节点或箭头打开步骤详情与代码面板,查看详情和切换页签保留当前视野与手动布局;这些调整只影响本次页面中的展示,不改写业务声明。
18
+
19
+ 展开具体操作时,触发图只沿事件触发、反应调用、审批结论与外部成功回写展开,异步连线使用虚线。任务的 calls 只表示可调用,反应的 map 仍可能返回 null;读取依赖、同对象归属、状态相接不表示操作必然依次执行。旧项目的生命周期只展示允许的状态迁移,不把人工的下一步当作自动执行。
20
+
21
+ “实现代码”预览本次抽取保存的完整声明调用,包括 handler、map 或审批路由,提供文件和行号;依赖中的帮助函数仍需按源码阅读。字段、状态和能力点只有聚合位置时,明确显示所属聚合的声明;依赖包没有本地源码位置时不伪造预览。服务只按已注册节点提供快照中的代码,不接受任意文件路径。改代码后点击“重新抽取”,图谱、代码和复制的 AI 上下文才一起更新。
22
+
23
+ 板块、流程、步骤和代码页签保存在 URL 中,支持复制地址、刷新及前进后退。需要查看字段或全部技术关系时,切换“对象与字段”或“完整本体”;步骤详情也可直接进入完整本体及复制 AI 上下文。
24
+
25
+ ## 声明完整业务流程
26
+
27
+ `businessProcess` 把已有执行声明组织成业务阅读规格,适合把申请、审批、履约、结算串成一条完整主线。它不调度命令、不生成写接口,也不改变数据表或授权。跨模块流程放在 domain 的 `workflows`,单个模块内的流程可放在对应模块,所有引用及流程本身都从 domain 入口导出。
28
+
29
+ 采购范例的完整声明位于 `packages/domain/src/workflows/purchase-process.ts`(空白项目在采购参考源码目录中查找)。以下片段说明主要选项,变量引用该范例已有的聚合、命令和审批:
30
+
31
+ ```ts
32
+ export const purchaseOverview = businessProcess('purchase-overview', {
33
+ title: '采购申请到批准', description: '看清申请人提交与审批结论。',
34
+ area: { id: 'purchase', title: '采购管理', description: '采购申请、审批、收货与库存协作。' },
35
+ subject: PurchaseOrder, entry: 'create',
36
+ stages: {
37
+ create: { title: '填写采购申请', description: '保存采购草稿。', actor: '申请人', action: create },
38
+ submit: { title: '提交申请', description: '校验后提交审批。', actor: '申请人', action: submit },
39
+ review: { title: '采购审批', description: '按现有审批规则选人。', kind: 'decision', action: poApproval },
40
+ approved: { title: '批准并锁定库存', description: '审批通过后同事务占用库存。', kind: 'end', action: approve,
41
+ related: [{ object: InventoryLock, label: '锁定采购所需库存', via: acquireLock }] },
42
+ rejected: { title: '审批驳回', description: '本轮采购申请结束。', kind: 'end', action: reject },
43
+ },
44
+ transitions: [
45
+ { from: 'create', to: 'submit', mode: 'manual', label: '申请人提交' },
46
+ { from: 'submit', to: 'review', mode: 'automatic', label: '启动审批' },
47
+ { from: 'review', to: 'approved', mode: 'automatic', label: '审批通过' },
48
+ { from: 'review', to: 'rejected', mode: 'automatic', label: '审批驳回' },
49
+ ],
50
+ });
51
+ ```
52
+
53
+ - `action` 引用该阶段的主要实现;`details` 可补充命令、反应等实现依据,点击后能分别查看代码。
54
+ - `manual` 的目标必须允许用户调用;`automatic` 必须能沿真实触发链到达;`wait` 用于外部通知或定时处理。仅有状态相接不能证明自动执行。
55
+ - `related` 的 `object` 引用实际聚合,`via` 引用本阶段实际可触发且涉及该对象的声明。对象关联显示为虚线,不参与流程先后排序。
56
+ - `branch: true` 将次要路径收起;每个阶段都需要从入口可达,并能到达至少一个 `kind: 'end'` 的结果。回路直接指向原阶段 ID。
57
+ - 同一板块 ID 的名称和说明保持一致;流程按源码声明顺序展示,可把全流程放在专题流程之前。
58
+
59
+ `cage check` 用 [CAGE-BIZ-001](../errors/CAGE-BIZ-001.md) 和 [CAGE-BIZ-002](../errors/CAGE-BIZ-002.md) 检查声明与实现关系。它不执行 handler、map 或审批,所以仍需业务回归证明运行行为。
60
+
61
+ 阶段直接使用 `title`、`description`、`actor` 的中文文案;操作和字段等继续用 `graph.labels`,审批角色可用 `"role:finance": "财务"`。状态也可在 `states(..., { labels: { draft: '草稿' } })` 中维护中文名;这些名称不更改原有状态标识。
62
+
63
+ ## 开发一项需求的入口
64
+
65
+ 以采购模板为例:
66
+
67
+ ```powershell
68
+ # 根据中文需求取得一份可阅读的上下文,默认 Markdown。
69
+ pnpm exec cage context "修改采购单取消逻辑"
70
+ # 用完整节点身份缩小入口;保存 JSON 供编程工具读取。
71
+ pnpm exec cage context command:PurchaseOrder.cancel --format json --out .cage/cancel-context.json
72
+ ```
73
+
74
+ 报告提供中文名称、稳定 key、候选命中依据、相关业务事实、连接原因与用途、源码位置、契约、前端引用和测试候选、迁移及授权审查提示。没有执行其中的命令或测试,也没有写入数据库。
75
+
76
+ 中文检索按名称、description、标识和所属对象匹配,支持相邻中文词片段;它没有调用语言模型,不保证理解任意自然语言需求。比如“采购单取消”和“取消采购单”可以匹配,但业务同义词、否定句、复杂规则仍需要 AI 阅读源码并结合用户需求确认。
77
+
78
+ - `selection.mode=exact`:完整 key、唯一 ID 或唯一中文全称定位到一个入口。
79
+ - `selection.mode=keyword-candidates`:选取得分接近的最多三个入口生成子图,同时返回其他候选和命中原因。先确认入口符合需求;可复制候选 key 再运行一次。
80
+ - 没有命中不表示框架不支持该业务。尝试较短关键词或代码标识。空白模板只注册组织模型,`docs/examples/purchase-admin` 是参考资料,不会被提取为当前项目的采购业务。
81
+
82
+ ## 四个命令怎样配合
83
+
84
+ ```powershell
85
+ # 1. 按中文或英文找业务;--kind 可限定节点类型。
86
+ pnpm exec cage graph search "取消" --kind command --limit 8
87
+ # 2. 精确查看节点属性、所有直接关联及声明位置。
88
+ pnpm exec cage graph inspect command:PurchaseOrder.cancel
89
+ # 3. 查看两个节点之间的最短关系路径。
90
+ pnpm exec cage graph path command:PurchaseOrder.cancel command:InventoryLock.release
91
+ # 4. 组织为本次开发所需的上下文。
92
+ pnpm exec cage context command:PurchaseOrder.cancel --depth 3 --limit 40
93
+ ```
94
+
95
+ 这些查询均支持 `--format md|json` 和 `--out <文件>`,默认 Markdown。输出路径相对应用根目录;可通过 `--root <目录>` 指定另一个应用。`cage graph` 不带子命令时仍启动 Web 工作台。
96
+
97
+ | 查询 | 结果与边界 |
98
+ | --- | --- |
99
+ | `graph search` | 返回排序候选、score、matches 和源码位置;默认最多 10 项,truncated 表示候选被截断 |
100
+ | `graph inspect` | 只接受完整 key、唯一 ID 或唯一中文全称;有歧义或只有模糊匹配时返回候选,请使用完整 key 重试 |
101
+ | `graph path` | 默认沿箭头,深度最多 6;用 `--direction both` 探索双向依赖,每一步明确标出逆向遍历 |
102
+ | `context` | 默认深度 3、最多 40 个节点;附带的表、字段和状态不继续展开,避免扩大为整张系统图 |
103
+
104
+ 节点身份由类型与 ID 共同构成,例如 `command:PurchaseOrder.cancel`。命令、状态、能力点可以同名,不能只用 ID 合并节点。审批路由的 ID 自带 `route:`,因此完整 key 可能是 `route:route:po-approval`;直接复制工具返回的 key。
105
+
106
+ 路径展示的是**关系链**。读取箭头指向数据来源;双向遍历不改变声明方向。归属虚线不会参与路径搜索,避免经同一所属对象制造两个命令之间的调用关系。没有在深度内找到路径,不代表任意代码之间绝无联系;可提高 `--depth`,或使用双向探索。状态迁移路径会保留 `via` 命令。
107
+
108
+ ## 采购单取消的实际阅读方式
109
+
110
+ 工具可以追踪以下声明:
111
+
112
+ ```text
113
+ command:PurchaseOrder.cancel
114
+ → event:OrderCancelled
115
+ → reaction:releaseOnCancel
116
+ → command:InventoryLock.release
117
+ ```
118
+
119
+ 同时会看到 `OrderCancelled → poApproval` 的 `cancels` 关系,依据是审批绑定的 `cancelOn`。这条关系负责取消审批;释放库存锁由另一条业务反应完成,两者分别检查。
120
+
121
+ 接着阅读报告指向的 `workflows/purchase-inventory.ts`:`releaseOnCancel.map` 仅在事件 `previousStatus === 'approved'` 时返回释放输入,其余返回 null。图能解释订阅、目标和资源标签,不能仅凭存在一条连线就判定每次取消都会释放资源。
122
+
123
+ 源码位置有两个精度:
124
+
125
+ - `declaration`:定位到顶层声明的文件与行号。
126
+ - `aggregate`:字段、状态等只定位到所属聚合声明;继续在该声明内查找具体成员。
127
+
128
+ `source=null` 表示当前项目静态索引没有位置,常见于来自框架依赖的组织模型;应查依赖的公开 API 和本地指南。报告不会伪造字段的精确行号或复制依赖内部实现。
129
+
130
+ ## 判断证据强度和覆盖范围
131
+
132
+ 每条关系都带 `why`、`purpose` 和 `evidence`:
133
+
134
+ | evidence.basis | 可以据此判断什么 |
135
+ | --- | --- |
136
+ | `declared` | 来自 reads、emits、reaction、cancelOn、约束字段等显式声明;仍需阅读执行条件 |
137
+ | `inferred` | 从标识推导归属,或由默认事件映射、出站同名字段规则建立关联;核对映射实现 |
138
+ | `text-match` | 从 SQL/build 文本匹配字段名;可能命中注释或同名内容,只作为查询依赖线索 |
139
+
140
+ 前端候选按聚合/查询代码名称匹配,项目测试候选按源码标识匹配,均不是完整依赖分析。派生测试按 subject 选择,不意味着这些用例一定能构造有效输入或已经运行成功。
141
+
142
+ 每份报告都带 `extractedAt`、`graphHash`、`freshness`、当前 `findings` 和使用边界。CLI 每次独立进程重新抽取,不读取旧图缓存;Web 复制使用当前图谱快照,明确标为 `displayed-snapshot`,改代码后先点“重新抽取”。`graph.labels` 的显示覆盖独立保存,不改变本体节点 ID 和语义哈希;声明内的 description 仍可能影响语义比较,特别是字段口径说明。
143
+
144
+ `coverage.truncated` 表示节点上限造成遗漏;`depthBoundary` 指出因深度限制未继续展开的节点。扩大 `--limit` / `--depth` 或改用更精确入口;不能把未出现在子图中的对象当成没有影响。测试、前端候选还分别报告自己的截断情况。
145
+
146
+ 图规则有错误时,只要仍能抽取出图,就输出报告和问题,CLI 返回非零退出码。静态检查阻止 domain 求值时,先按诊断修复,再重新请求上下文。未命中、inspect 歧义、深度内无路径也返回非零;不要因为已经生成文件就当作成功。
147
+
148
+ ## 修改前后形成闭环
149
+
150
+ ```powershell
151
+ # 开发前:先取得上下文、阅读实际实现,再保存独立基线。
152
+ pnpm exec cage context "采购单取消"
153
+ pnpm exec cage snapshot save before-change
154
+ # 在源码修改业务声明和实现……
155
+ pnpm exec cage check
156
+ pnpm gen
157
+ pnpm exec cage impact --snapshot before-change
158
+ # 按影响和实际风险选择必要测试,审查迁移与管理员授权。
159
+ ```
160
+
161
+ `context`、`graph search/inspect/path` 不写入当前 `.cage/ontology.json`;`analyze/gen` 才更新当前图。命名快照写到 `.cage/snapshots`,同名拒绝覆盖,`snapshot list` 显示保存时间、版本与指纹。独立本体图文件和真实 Git 基线仍可使用。基线保留到验收结束,不能把修改后的当前图当作旧图。`context` 用于开发前定位,`impact` 用于修改后比较;二者都不能替代业务验收。详见[诊断与快照](diagnostics.md)。
162
+
163
+ 可直接交给编程工具的要求:
164
+
165
+ ```text
166
+ 先读 AGENTS.md 和 docs/ai/README.md。
167
+ 需求:修改……
168
+ 先运行 cage context 查询需求相关业务,再用 graph inspect/path 消除入口和关系歧义。
169
+ 按报告的源码位置阅读条件与实现;说明选中的业务入口、影响范围和图的覆盖边界。
170
+ 修改前另存本体图基线,修改后 check、gen、impact,按风险运行相关验证。
171
+ 不要只凭名称、连线或测试候选判断需求已完成。
172
+ ```