@yss123/cage-cli 0.3.2 → 0.4.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 (134) hide show
  1. package/README.md +1 -1
  2. package/dist/analyze.js +3 -0
  3. package/dist/analyze.js.map +1 -1
  4. package/dist/capabilities.js +10 -0
  5. package/dist/capabilities.js.map +1 -1
  6. package/dist/config.d.ts +4 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/context.js +2 -2
  9. package/dist/context.js.map +1 -1
  10. package/dist/doctor.js +1 -1
  11. package/dist/doctor.js.map +1 -1
  12. package/dist/findings.d.ts +1 -1
  13. package/dist/findings.js +2 -2
  14. package/dist/findings.js.map +1 -1
  15. package/dist/graph-business.d.ts +11 -8
  16. package/dist/graph-business.js +16 -16
  17. package/dist/graph-business.js.map +1 -1
  18. package/dist/graph-relations.js +3 -5
  19. package/dist/graph-relations.js.map +1 -1
  20. package/dist/impact.js +1 -4
  21. package/dist/impact.js.map +1 -1
  22. package/dist/ontology-names.d.ts +17 -0
  23. package/dist/ontology-names.js +42 -0
  24. package/dist/ontology-names.js.map +1 -0
  25. package/dist/sync.d.ts +5 -1
  26. package/dist/sync.js +16 -9
  27. package/dist/sync.js.map +1 -1
  28. package/graph-ui/app.js +3 -2
  29. package/graph-ui/business.js +11 -3
  30. package/graph-ui/graph-business.js +16 -16
  31. package/graph-ui/graph-relations.js +3 -5
  32. package/package.json +6 -6
  33. package/templates/app/.agents/skills/cage-development/SKILL.md +1 -1
  34. package/templates/app/AGENTS.md +12 -9
  35. package/templates/app/README.md +2 -2
  36. package/templates/app/apps/api/package.json +2 -2
  37. package/templates/app/apps/web/package.json +3 -1
  38. package/templates/app/apps/web/src/app/styles/global.css +12 -11
  39. package/templates/app/apps/web/src/main.tsx +18 -7
  40. package/templates/app/apps/web/src/shared/lib/error-message.ts +1 -1
  41. package/templates/app/apps/web/src/shared/ui/approval-member-picker.tsx +1 -1
  42. package/templates/app/cage.config.json +2 -1
  43. package/templates/app/docs/README.md +6 -4
  44. package/templates/app/docs/development/README.md +21 -5
  45. package/templates/app/docs/development/examples/note/note.ts +8 -4
  46. package/templates/app/docs/development/examples/purchase-example.md +5 -5
  47. package/templates/app/docs/development/getting-started/architecture.md +5 -5
  48. package/templates/app/docs/development/getting-started/workflow.md +17 -23
  49. package/templates/app/docs/development/guides/approvals.md +4 -4
  50. package/templates/app/docs/development/guides/business-collaboration.md +3 -1
  51. package/templates/app/docs/development/guides/frontend-ui.md +30 -0
  52. package/templates/app/docs/development/guides/intelligence.md +14 -12
  53. package/templates/app/docs/development/guides/ontology-modeling.md +83 -0
  54. package/templates/app/docs/development/guides/recipes.md +28 -14
  55. package/templates/app/docs/development/guides/relations.md +31 -8
  56. package/templates/app/docs/development/reference/commenting.md +7 -4
  57. package/templates/app/docs/development/reference/primitives.md +5 -3
  58. package/templates/app/docs/development/skills/cage-development/SKILL.md +30 -20
  59. package/templates/app/docs/development/tools/diagnostics.md +4 -1
  60. package/templates/app/docs/development/tools/ontology-context.md +1 -1
  61. package/templates/app/docs/development/tools/troubleshooting.md +3 -3
  62. package/templates/app/docs/errors/CAGE-APPR-007.md +1 -1
  63. package/templates/app/docs/errors/CAGE-GRANT-001.md +18 -12
  64. package/templates/app/docs/errors/CAGE-GRANT-002.md +2 -2
  65. package/templates/app/docs/errors/CAGE-GRANT-003.md +3 -3
  66. package/templates/app/docs/errors/CAGE-ONTOLOGY-001.md +52 -0
  67. package/templates/app/docs/errors/CAGE-STATE-003.md +1 -1
  68. package/templates/app/docs/errors/CAGE-SYNC-001.md +2 -2
  69. package/templates/app/docs/errors/README.md +7 -1
  70. package/templates/app/docs/errors/runtime.md +1 -1
  71. package/templates/app/package.json +3 -3
  72. package/templates/app/packages/contracts/package.json +1 -1
  73. package/templates/app/packages/contracts/src/aggregates/role/index.ts +2 -2
  74. package/templates/app/packages/contracts/src/aggregates/user/index.ts +3 -3
  75. package/templates/app/packages/domain/package.json +5 -5
  76. package/templates/app/packages/domain/src/modules/purchase/approval-members.ts +1 -1
  77. package/templates/app/packages/domain/src/modules/purchase/approvals.ts +2 -2
  78. package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +4 -4
  79. package/templates/app/packages/domain/src/modules/purchase/purchase-order.test.ts +10 -17
  80. package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +4 -5
  81. package/templates/app/packages/domain/src/workflows/purchase-process.ts +1 -1
  82. package/templates/blank/.agents/skills/cage-development/SKILL.md +1 -1
  83. package/templates/blank/AGENTS.md +12 -9
  84. package/templates/blank/apps/api/package.json +1 -1
  85. package/templates/blank/apps/web/package.json +3 -1
  86. package/templates/blank/apps/web/src/app/styles/global.css +6 -5
  87. package/templates/blank/apps/web/src/main.tsx +18 -7
  88. package/templates/blank/cage.config.json +1 -0
  89. package/templates/blank/docs/README.md +6 -4
  90. package/templates/blank/docs/development/README.md +21 -5
  91. package/templates/blank/docs/development/examples/note/note.ts +8 -4
  92. package/templates/blank/docs/development/examples/purchase-example.md +5 -5
  93. package/templates/blank/docs/development/getting-started/architecture.md +5 -5
  94. package/templates/blank/docs/development/getting-started/workflow.md +17 -23
  95. package/templates/blank/docs/development/guides/approvals.md +4 -4
  96. package/templates/blank/docs/development/guides/business-collaboration.md +3 -1
  97. package/templates/blank/docs/development/guides/frontend-ui.md +30 -0
  98. package/templates/blank/docs/development/guides/intelligence.md +14 -12
  99. package/templates/blank/docs/development/guides/ontology-modeling.md +83 -0
  100. package/templates/blank/docs/development/guides/recipes.md +28 -14
  101. package/templates/blank/docs/development/guides/relations.md +31 -8
  102. package/templates/blank/docs/development/reference/commenting.md +7 -4
  103. package/templates/blank/docs/development/reference/primitives.md +5 -3
  104. package/templates/blank/docs/development/skills/cage-development/SKILL.md +30 -20
  105. package/templates/blank/docs/development/tools/diagnostics.md +4 -1
  106. package/templates/blank/docs/development/tools/ontology-context.md +1 -1
  107. package/templates/blank/docs/development/tools/troubleshooting.md +3 -3
  108. package/templates/blank/docs/errors/CAGE-APPR-007.md +1 -1
  109. package/templates/blank/docs/errors/CAGE-GRANT-001.md +18 -12
  110. package/templates/blank/docs/errors/CAGE-GRANT-002.md +2 -2
  111. package/templates/blank/docs/errors/CAGE-GRANT-003.md +3 -3
  112. package/templates/blank/docs/errors/CAGE-ONTOLOGY-001.md +52 -0
  113. package/templates/blank/docs/errors/CAGE-STATE-003.md +1 -1
  114. package/templates/blank/docs/errors/CAGE-SYNC-001.md +2 -2
  115. package/templates/blank/docs/errors/README.md +7 -1
  116. package/templates/blank/docs/errors/runtime.md +1 -1
  117. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +12 -11
  118. package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +18 -7
  119. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +1 -1
  120. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/approval-member-picker.tsx +1 -1
  121. package/templates/blank/docs/examples/purchase-admin/cage.config.json +2 -1
  122. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +2 -2
  123. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +3 -3
  124. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approval-members.ts +1 -1
  125. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +2 -2
  126. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +4 -4
  127. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +10 -17
  128. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +4 -5
  129. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +1 -1
  130. package/templates/blank/package.json +3 -3
  131. package/templates/blank/packages/contracts/package.json +1 -1
  132. package/templates/blank/packages/contracts/src/aggregates/role/index.ts +2 -2
  133. package/templates/blank/packages/contracts/src/aggregates/user/index.ts +3 -3
  134. package/templates/blank/packages/domain/package.json +5 -5
@@ -19,16 +19,17 @@
19
19
  body {
20
20
  margin: 0;
21
21
  }
22
- button,
22
+ button:not(.ant-btn),
23
23
  input {
24
24
  font: inherit;
25
25
  }
26
- button,
26
+ button:not(.ant-btn),
27
27
  a,
28
28
  input {
29
29
  outline-offset: 4px;
30
30
  }
31
- button {
31
+ /* 原生按钮规则服务于范例中现有的手写 DOM 控件,不覆盖新增的 Ant Design Button。 */
32
+ button:not(.ant-btn) {
32
33
  border: 1px solid var(--line);
33
34
  background: #fff;
34
35
  color: var(--green);
@@ -37,10 +38,10 @@ button {
37
38
  cursor: pointer;
38
39
  transition: background 0.15s;
39
40
  }
40
- button:hover {
41
+ button:not(.ant-btn):hover {
41
42
  background: #edf2e8;
42
43
  }
43
- button:disabled {
44
+ button:not(.ant-btn):disabled {
44
45
  opacity: 0.45;
45
46
  cursor: default;
46
47
  }
@@ -295,7 +296,7 @@ header {
295
296
  gap: 7px;
296
297
  flex-wrap: wrap;
297
298
  }
298
- .filters button {
299
+ .filters button:not(.ant-btn) {
299
300
  border: 0;
300
301
  background: none;
301
302
  font-size: 12px;
@@ -305,7 +306,7 @@ header {
305
306
  background: #edf3e6;
306
307
  color: var(--green);
307
308
  }
308
- .toolbar > button {
309
+ .toolbar > button:not(.ant-btn) {
309
310
  font-size: 11px;
310
311
  }
311
312
  /**
@@ -373,7 +374,7 @@ tr:last-child td {
373
374
  display: flex;
374
375
  gap: 7px;
375
376
  }
376
- .actions button {
377
+ .actions button:not(.ant-btn) {
377
378
  font-size: 11px;
378
379
  padding: 6px 9px;
379
380
  }
@@ -386,7 +387,7 @@ tr:last-child td {
386
387
  font-size: 11px;
387
388
  color: var(--muted);
388
389
  }
389
- .pagination button {
390
+ .pagination button:not(.ant-btn) {
390
391
  font-size: 11px;
391
392
  margin-left: 7px;
392
393
  }
@@ -442,7 +443,7 @@ tr:last-child td {
442
443
  font-size: 12px;
443
444
  margin-bottom: 20px;
444
445
  }
445
- .notice button {
446
+ .notice button:not(.ant-btn) {
446
447
  background: transparent;
447
448
  border: 0;
448
449
  }
@@ -459,7 +460,7 @@ tr:last-child td {
459
460
  align-items: end;
460
461
  padding: 22px;
461
462
  }
462
- .stock-form button {
463
+ .stock-form button:not(.ant-btn) {
463
464
  margin-bottom: 18px;
464
465
  }
465
466
  label {
@@ -1,18 +1,29 @@
1
1
  /**
2
- * 采购 Web 的浏览器启动入口:创建共享查询缓存,将应用路由挂到 root DOM 节点。
3
- * 契约客户端负责网络与会话协议,页面只在 Provider 内消费 hooks;这里不注册领域或启动后端。
4
- * 全局样式在此加载,账号切换时的缓存清理由 useSession 和应用壳负责。
2
+ * 采购 Web 的浏览器启动入口:装配 Ant Design 中文主题、共享查询缓存并挂载应用路由。
3
+ * 页面通过 Provider 消费 UI 上下文、生成契约客户端和查询 hooks;入口不注册领域或启动后端。
4
+ * AntD reset 与业务全局样式在此加载,账号切换时的缓存清理由 useSession 和应用壳负责。
5
5
  */
6
- // 唯一浏览器启动入口:挂载 React、全局 Provider 和样式;业务从 app 组合进入。
6
+ // 唯一浏览器启动入口:挂载 React、Ant Design 与查询 Provider;业务从 app 组合进入。
7
7
  import { createRoot } from 'react-dom/client';
8
8
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
9
+ import { App as AntdApp, ConfigProvider } from 'antd';
10
+ import zhCN from 'antd/locale/zh_CN';
9
11
  import { App } from './app/app';
12
+ import 'antd/dist/reset.css';
10
13
  import './app/styles/global.css';
11
14
 
12
15
  const queryClient = new QueryClient();
13
16
 
17
+ /**
18
+ * ConfigProvider 提供简体中文文案与统一绿色主题;AntdApp 为 message、modal、notification 等反馈 API 提供上下文。
19
+ * QueryClientProvider 继续承载生成查询 hooks 的缓存;Provider 均只创建一次并覆盖整套路由。
20
+ */
14
21
  createRoot(document.getElementById('root')!).render(
15
- <QueryClientProvider client={queryClient}>
16
- <App />
17
- </QueryClientProvider>,
22
+ <ConfigProvider locale={zhCN} theme={{ token: { colorPrimary: '#173e35', borderRadius: 4 } }}>
23
+ <AntdApp>
24
+ <QueryClientProvider client={queryClient}>
25
+ <App />
26
+ </QueryClientProvider>
27
+ </AntdApp>
28
+ </ConfigProvider>,
18
29
  );
@@ -16,7 +16,7 @@ export function errorMessage(r: Extract<CageResult<unknown, string>, { ok: false
16
16
  INVALID_INPUT: '请检查填写内容',
17
17
  CONFLICT: '数据或任务已更新,请刷新后重试',
18
18
  UNAUTHENTICATED: '登录已过期',
19
- CONSTRAINT_VIOLATED: '未满足审批条件,请检查审批人或额度',
19
+ CONSTRAINT_VIOLATED: '未满足业务条件,请检查操作人及具体原因',
20
20
  STOCK_SHORT: '库存不足',
21
21
  REVIEWERS_REQUIRED: '请为专业会签选择 1–5 位协作人',
22
22
  REVIEWERS_NOT_REQUIRED: '取消专业会签时请清空复核人员',
@@ -46,6 +46,6 @@ export function ApprovalMemberPicker({ value, onChange, max = 5, exclude = [], d
46
46
  {query.data && entries.length === 0 && <p className="muted">当前页没有匹配人员,请调整筛选或联系名录维护人。</p>}
47
47
  {(query.data?.total ?? 0) > 200 && <div className="actions"><button type="button" disabled={page === 1} onClick={() => setPage(page - 1)}>上一页</button>
48
48
  <span>第 {page} 页</span><button type="button" disabled={page * 200 >= query.data!.total} onClick={() => setPage(page + 1)}>下一页</button></div>}
49
- <small className="muted">名录只提供选人信息,处理权限、数据范围和最终额度仍以服务端校验为准。</small>
49
+ <small className="muted">名录只提供选人信息,处理权限和数据范围仍以服务端校验为准。</small>
50
50
  </fieldset>;
51
51
  }
@@ -5,6 +5,7 @@
5
5
  "typecheck": ["packages/domain", "packages/contracts", "apps/api", "apps/web"],
6
6
  "graph": {
7
7
  "title": "采购业务图谱",
8
+ "naming": "required",
8
9
  "labels": {
9
10
  "module:purchase": "采购管理",
10
11
  "module:inventory": "库存管理",
@@ -125,7 +126,7 @@
125
126
  "state:Role.archived": "已停用",
126
127
  "field:Role.code": "角色编码",
127
128
  "field:Role.name": "角色名称",
128
- "field:Role.capabilities": "能力点与额度",
129
+ "field:Role.capabilities": "能力点",
129
130
  "field:Role.scopes": "数据访问范围",
130
131
  "capability:Role.read": "查看角色",
131
132
  "capability:Role.export": "导出角色",
@@ -1,11 +1,13 @@
1
1
  # 本地框架文档
2
2
 
3
- 从 [框架学习入口](development/README.md) 或 [Cage 开发 Skill](development/skills/cage-development/SKILL.md) 开始。
3
+ 编程 agent 先读项目 [AGENTS.md](../AGENTS.md),按 [Cage 开发 Skill](development/skills/cage-development/SKILL.md) 理解需求、澄清、查证能力、说明实现映射,再编码与验收。
4
4
 
5
- - `development/getting-started`:运行模型、完整入门课和开发步骤。
6
- - `development/guides`:[业务澄清与共同设计](development/guides/business-collaboration.md)、能力选择与各专题接入。
5
+ [任务导航](development/README.md) 说明各类文档的分工,按本次需要选择资料:
6
+
7
+ - `development/getting-started`:运行模型、完整业务链和操作命令。
8
+ - `development/guides`:[业务澄清](development/guides/business-collaboration.md)、[能力选择与实现映射](development/guides/recipes.md)、各专题接入。
7
9
  - `development/reference`:原语与工程规范。
8
10
  - `development/tools`:诊断、本体查询和排错。
9
11
  - `development/examples`:教学源码与采购导读。
10
- - `development/skills`:框架开发方法。
12
+ - `development/skills`:唯一的 agent 工作流程。
11
13
  - [错误码册](errors/README.md):按实际错误定位原因。
@@ -1,6 +1,8 @@
1
1
  # Cage 框架学习入口
2
2
 
3
- 本目录是开发者与编程 Agent 共用的 Cage 应用开发教材,帮助你理解框架并把业务需求落实为可运行的应用。开发方法的统一入口是 [cage-development Skill](skills/cage-development/SKILL.md)。教材由框架维护,随脚手架分发;读取教材无需额外服务、模型或向量索引。
3
+ 本目录面向使用 Cage 编写业务的 agent,帮助 agent 理解需求、查证框架并完成真实实现。先读项目 AGENTS.md,再按 [cage-development Skill](skills/cage-development/SKILL.md) 工作;本页只负责按任务定位资料。教材由框架维护,随脚手架分发,读取无需额外服务、模型或向量索引。
4
+
5
+ 工作主线:**理解需求 → 提出疑问与建议 → 核对现有业务和框架能力 → 说明实现映射 → 编码 → 按规则验收**。明确的规则直接采用,技术事实自行查证,需要用户决定的业务取舍再交给用户选择。
4
6
 
5
7
  模型接入、智能助理和 AI 审批属于框架的原生 AI 能力,具体接入见[原生 AI 专题](guides/intelligence.md)。
6
8
 
@@ -10,19 +12,33 @@
10
12
  | --- | --- | --- |
11
13
  | 第一次使用 Cage | [Skill 的运行模型](skills/cage-development/SKILL.md#先建立正确的运行模型) → [第一条完整业务链](getting-started/first-feature.md) | 理解声明、导出、生成、授权、契约与持久读写如何连接 |
12
14
  | 用户描述或文档不清楚 | [业务澄清与共同设计](guides/business-collaboration.md) | 主动提出疑问、可行选项与建议,与用户选择业务规则,再落实到实现和验收 |
13
- | 把需求转成设计 | [业务设计与能力选择](guides/recipes.md) | 确定聚合边界、命令、范围、关系和一致性要求 |
14
- | 实现或修改功能 | [Skill 的实施流程](skills/cage-development/SKILL.md#4-沿一条真实链路实施再扩展) → [开发步骤](getting-started/workflow.md) | 沿实际调用链完成受影响的功能,并取得验证证据 |
15
+ | 把需求转成设计 | [业务设计与能力选择](guides/recipes.md) → [编码前的映射](skills/cage-development/SKILL.md#4-写代码前说明实现映射) | 业务规则、查证过的能力、修改位置和验收例子一一对应 |
16
+ | 表达对象、状态和关系的业务含义 | [本体建模](guides/ontology-modeling.md) → [对象关系](guides/relations.md) | 名称写入真实声明,关系有正确方向、基数及执行依据,图谱能用业务用语阅读 |
17
+ | AI 生成 React 页面与选择组件 | [前端组件指南](guides/frontend-ui.md) → [路由](guides/routing.md) | 生成可维护的真实 TSX 页面,使用 Ant Design 组合 UI,并按 Cage 契约读写 |
18
+ | 实现或修改功能 | [Skill 的实施流程](skills/cage-development/SKILL.md#5-沿一条真实链路实施再扩展) → [开发步骤](getting-started/workflow.md) | 沿实际调用链完成受影响的功能,并取得验证证据 |
15
19
  | 已有功能不正常 | [排错方法](tools/troubleshooting.md) → [诊断工具](tools/diagnostics.md) / [错误码册](../errors/README.md) | 找到第一个失败边界,修复原因并复验 |
16
20
  | 查询一个能力的用法 | 下方专题表,必要时本地搜索术语 | 找到当前任务的 API、接入前提与限制 |
17
21
 
18
22
  已经熟悉框架时不必每次重读课程。不要将所有专题一次加载,也不要把参考业务注册到客户应用。
19
23
 
24
+ ## 各类文件的责任
25
+
26
+ | 文件 | 负责什么 |
27
+ | --- | --- |
28
+ | 项目 AGENTS.md | 项目入口、代码与环境约束;项目业务约定保留在框架托管区外 |
29
+ | [Skill](skills/cage-development/SKILL.md) | agent 的工作顺序、判断依据及何时与用户互动 |
30
+ | [业务澄清](guides/business-collaboration.md) | 如何发现疑点、比较方案、保留并落实用户选择 |
31
+ | [能力选择](guides/recipes.md) | 业务规则如何映射到 Cage,包含编码前的映射示例 |
32
+ | [本体建模](guides/ontology-modeling.md) | 业务含义、结构化名称、对象关系和触发链写在哪里,以及怎样检查和验收 |
33
+ | [开发步骤](getting-started/workflow.md) | 已确定设计的修改、生成、迁移和验证命令 |
34
+ | 其他专题、参考与源码 | 当前能力用法、前提与边界,按需阅读;示例业务不成为当前需求 |
35
+
20
36
  ## 按资料用途查找
21
37
 
22
38
  | 目录 | 内容与入口 |
23
39
  | --- | --- |
24
40
  | `getting-started/` 入门 | [运行模型](getting-started/architecture.md)、[完整入门课](getting-started/first-feature.md)、[开发步骤](getting-started/workflow.md) |
25
- | `guides/` 专题指南 | [业务澄清](guides/business-collaboration.md)、[能力选择](guides/recipes.md)、[审批](guides/approvals.md)、[文件](guides/files.md)、[关系](guides/relations.md)、[路由](guides/routing.md)、[数据传输](guides/transfers.md)、[原生 AI](guides/intelligence.md) |
41
+ | `guides/` 专题指南 | [业务澄清](guides/business-collaboration.md)、[能力选择](guides/recipes.md)、[本体建模](guides/ontology-modeling.md)、[前端组件](guides/frontend-ui.md)、[审批](guides/approvals.md)、[文件](guides/files.md)、[关系](guides/relations.md)、[路由](guides/routing.md)、[数据传输](guides/transfers.md)、[原生 AI](guides/intelligence.md) |
26
42
  | `reference/` 参考规范 | [原语](reference/primitives.md)、[目录组织](reference/project-structure.md)、[中文注释](reference/commenting.md) |
27
43
  | `tools/` 工具与排错 | [诊断](tools/diagnostics.md)、[本体上下文](tools/ontology-context.md)、[排错方法](tools/troubleshooting.md) |
28
44
  | `examples/` 教学示例 | [便笺源码](examples/note/note.ts)、[采购导读](examples/purchase-example.md);按入门课与导读阅读,源码不自动注册 |
@@ -36,7 +52,7 @@
36
52
 
37
53
  空白模板只启用组织基础;`docs/examples/purchase-admin` 是离线采购参考源码,不参与注册、编译或迁移。采购模板直接在业务目录包含该范例。框架仓库的应用根目录是 `examples/purchase-admin`,规范教材位于仓库 `docs/development`,以应用 AGENTS.md 的说明为准。
38
54
 
39
- `docs/development` 是框架教学内容的唯一手写来源;Skills 发现入口和模板副本由同步脚本生成。用户的业务约定保留在项目 AGENTS.md 的托管区外。教材分发检查只能证明资料存在且一致,模型是否学会需要框架维护者另做任务评估。
55
+ `docs/development` 是框架教学内容的唯一手写来源;Skills 发现入口和模板副本由同步脚本生成。用户的业务约定保留在项目已有业务文档或 AGENTS.md 的托管区外。教材分发检查只能证明资料存在且一致,模型是否学会需要框架维护者另做任务评估。
40
56
 
41
57
  ## 当前实现边界
42
58
 
@@ -15,13 +15,17 @@ export const Note = aggregate('Note', {
15
15
  description: '部门便笺',
16
16
  fields: {
17
17
  /** 标题最多 120 字符;命令先去除两端空白,不变量拒绝空白标题。 */
18
- title: text(120),
18
+ title: text(120).describe('便笺标题'),
19
19
  /** 内核新建时按当前主体填充的部门,用于服务端范围过滤。 */
20
- deptId: ref('Dept'),
20
+ deptId: ref('Dept').describe('所属部门'),
21
21
  /** 内核新建时记录的创建人,可用于本人范围;不接受客户端指定。 */
22
- createdBy: ref('User'),
22
+ createdBy: ref('User').describe('创建人'),
23
23
  },
24
- states: states('active', 'archived', { terminal: ['archived'] }),
24
+ // 机器状态用于命令和存储,业务名供图谱与上下文读取;普通注释不会替代 labels。
25
+ states: states('active', 'archived', {
26
+ terminal: ['archived'],
27
+ labels: { active: '使用中', archived: '已归档' },
28
+ }),
25
29
  scope: scope.deptSubtree('deptId'),
26
30
  invariants: { titleNotBlank: (record) => record.title.trim().length > 0 },
27
31
  });
@@ -22,7 +22,7 @@
22
22
  | `packages/contracts/src/aggregates/purchase-order/index.ts` | 生成的前端协议与类型 | 只读它,不手改;process/external 命令不生成浏览器写方法 |
23
23
  | `apps/web/src/main.tsx`、`app` | 挂载、全局 Provider、会话与导航组合 | 入口保持简洁,从模块公开入口组装页面 |
24
24
  | `apps/web/src/modules/purchase`、`inventory`、`approval` | 各业务页面与交互 | 调契约、处理错误、刷新列表、展示导出任务;不互相穿透 |
25
- | `packages/domain/src/modules/purchase/purchase-order.test.ts` | 有业务数据的成功/拒绝用例 | 越权、自审批、额度、库存锁、晚到 ERP 回执 |
25
+ | `packages/domain/src/modules/purchase/purchase-order.test.ts` | 有业务数据的成功/拒绝用例 | 越权、自审批、库存锁、晚到 ERP 回执 |
26
26
 
27
27
  ## 一次正常采购发生了什么
28
28
 
@@ -37,7 +37,7 @@
37
37
  → 申请启用专业复核时:所选专业人员全部会签
38
38
  → 金额 > 50000 时:财务共享候选任务,由 finance 成员领取后处理
39
39
  → 流程完成 → 调用 approve
40
- → 职责分离、额度、库存检查
40
+ → 职责分离、库存检查
41
41
  → approved + OrderApproved
42
42
  → 同事务 lockOnApprove → InventoryLock.held
43
43
  → worker 消费 OrderApproved → fake/真实 ERP 推单
@@ -80,11 +80,11 @@ submit 返回成功只表示单据和事件已提交,不表示待办、ERP 或
80
80
  | 模型管理者 | `Sys.ai.models.manage`;在 `/admin/#/models` 配置并启用 `main`,部署主密钥见[智能能力指南](../guides/intelligence.md) |
81
81
  | 助理性格管理者 | `Sys.ai.personalities.manage`;在 `/admin/#/personalities` 编辑预设、自定义性格、设置默认并试聊 |
82
82
  | AI 预审角色 | 创建 code 为 `purchase_ai_reviewer` 的角色,授予 `PurchaseOrder.read/returnForChanges` 及覆盖申请范围的数据权限;本例 AI 仅预审,不执行最终 approve |
83
- | 经理 | `PurchaseOrder.read/approve/reject/returnForChanges`,适当数据范围,`approve` 的 `ceiling` 额度参数 |
84
- | 专业协作人 | 真实账号及同样的审批能力、范围、额度;由名录管理员通过 `ApprovalMember.create` 登记公开业务姓名、专业说明;需要在任务中选人时授予 `ApprovalMember.read` |
83
+ | 经理 | `PurchaseOrder.read/approve/reject/returnForChanges` 和适当数据范围 |
84
+ | 专业协作人 | 真实账号及所需审批能力和范围;由名录管理员通过 `ApprovalMember.create` 登记公开业务姓名、专业说明;需要在任务中选人时授予 `ApprovalMember.read` |
85
85
  | 名录管理员 | 显式授予 `ApprovalMember.create/update/retire/read`;登记、更新资料或退役不修改用户角色,不自动给采购参与者授予 `User.read` |
86
86
  | 部门 | 将采购员所属部门的负责人设为经理;不能为空 |
87
- | 财务 | 角色 **code** 为 `finance`,给至少两位实际用户分配以体验共享候选池;配置审批所需权限、范围及足够额度;领取后才能处理 |
87
+ | 财务 | 角色 **code** 为 `finance`,给至少两位实际用户分配以体验共享候选池;配置审批所需权限和范围;领取后才能处理 |
88
88
  | 库存台账 | 预先登记与采购明细相同的 sku,数量满足演示检查 |
89
89
  | 连接器环境 | fake 阶段使用 worker 注册的 fake;真实环境另配 host 对应密钥及回调签名密钥 |
90
90
 
@@ -43,7 +43,7 @@ domain/index.ts 导出的声明
43
43
  → 校验输入、上下文、调用身份与能力
44
44
  → 幂等检查
45
45
  → 按范围加载并锁定记录,检查状态与版本
46
- → 硬约束(职责分离、额度、二次认证等)
46
+ → 硬约束(职责分离、二次认证等)
47
47
  → 绑定 reads,只运行 handler 的业务计算
48
48
  → 合并结果,内核设置目标状态,校验字段及不变量
49
49
  → 写记录、版本、审计和 outbox,执行同事务反应
@@ -85,12 +85,12 @@ worker → 消费 outbox → 异步反应 / 审批 / 连接器
85
85
  | 调用身份 | `user/process/job/external` | `process` 命令不给浏览器生成直接写接口;这不是角色名 |
86
86
  | 能力点 | `PurchaseOrder.submit`、`PurchaseOrder.read` | 代码声明能力目录,管理员在目录范围内授权 |
87
87
  | 数据范围 | 本人、本部门、部门及下级、指定部门、全部 | 决定能触及哪些记录,越范围详情通常表现为 404 |
88
- | 业务硬约束 | 不是提单人、额度不超过 ceiling | 即使被选为审批人也必须通过 |
88
+ | 业务硬约束 | 不是提单人 | 即使被选为审批人也必须通过 |
89
89
  | 明文能力 | `PurchaseOrder.unmask.phone` | 没有该能力时,安全读侧对电话掩码 |
90
90
 
91
91
  `scope.deptSubtree('deptId')` 描述聚合的部门字段和建议范围;**实际范围取决于角色授权数据**。`scope.none()` 表示没有部门/创建人范围字段,仍然需要能力和适当的 `all` 范围授权,不能理解成“任何人能读”。多角色范围合并为并集,缺少显式范围时默认本人范围,不是全部。
92
92
 
93
- `useCan()`、`can()` 只决定按钮呈现;前端隐藏按钮不能代替后端授权。新增命令不会自动授给已有生产角色,角色分配和额度调整也受防提权约束。
93
+ `useCan()`、`can()` 只决定按钮呈现;前端隐藏按钮不能代替后端授权。新增命令不会自动授给普通生产角色,角色分配也受防提权约束。首次初始化的超级管理员拥有当前及以后新增的全部能力和本租户全部范围。
94
94
 
95
95
  授权通知监听异常时不再复用缓存,每次重新读取授权;重新订阅后清空缓存,并阻止旧请求回填旧上下文。`/readyz` 反映数据库和授权监听健康,`/healthz` 仅表示存活。诊断入口受 `Sys.ops.read` 及相关对象 read/范围控制,`explain` 解释调用身份、能力、范围、状态与硬约束,不能预测 handler 的业务结果;新建对象的最终范围无法提前确定时返回 unknown。
96
96
 
@@ -143,6 +143,6 @@ APP、READ、MIGRATE 指向**同一个已经存在的数据库**,用不同账
143
143
 
144
144
  图谱抽取命令状态迁移与事件、反应调用、审批 start/cancelOn、约束/路由字段、查询读依赖和外部映射;另以虚线标记按标识推导的所属聚合。关系解释区分显式声明、规则推导与文本匹配,箭头要按各自含义阅读。开发前可用[本体上下文工具](../tools/ontology-context.md)检索相关业务与源码。
145
145
 
146
- `cage analyze` 将图写到 `.cage/ontology.json`;`cage graph` 提供浏览器工作台。中文显示名写在 `cage.config.json` 的 `graph.labels`,例如 `"command:PurchaseOrder.submit": "提交审批"`。显示名不更改能力标识、源码符号或表名。
146
+ `cage analyze` 将图写到 `.cage/ontology.json`;`cage graph` 提供浏览器工作台。业务名称优先与领域声明一起维护:对象和操作用 `description`,字段用 `.describe(...)`,状态用 `states` 的 `labels`。`cage.config.json` 的 `graph.labels` 可覆盖显示名,例如 `"command:PurchaseOrder.submit": "提交审批"`。这些名称不更改能力标识、源码符号或表名;普通注释和页面翻译不会自动进入图谱。详见[本体建模指南](../guides/ontology-modeling.md)。
147
147
 
148
- 图规则能检查“离开持有状态是否声明了释放”等结构问题,无法证明 `map` 的任意分支或 handler 计算一定正确。因此重要的资源释放条件、权限拒绝、额度边界仍需对应业务回归用例。
148
+ 图规则能检查“离开持有状态是否声明了释放”等结构问题,无法证明 `map` 的任意分支或 handler 计算一定正确。因此重要的资源释放条件、权限拒绝、业务条件边界仍需对应业务回归用例。
@@ -2,6 +2,8 @@
2
2
 
3
3
  [返回学习入口](../README.md) · [框架开发 Skill](../skills/cage-development/SKILL.md) · [完整入门课](first-feature.md) · [详细中文注释](../reference/commenting.md)
4
4
 
5
+ 本页提供应用启动、修改和验证的操作命令。需求理解、与用户澄清、能力查证和编码前的实现映射统一按[Skill](../skills/cage-development/SKILL.md)执行;下列操作用于落实已经明确的设计。
6
+
5
7
  本页命令在**应用根目录**执行,除非注明“框架根目录”。使用项目安装的 CLI:`pnpm exec cage ...`。项目脚本可简写为 `pnpm gen / pnpm migrate / pnpm dev / pnpm verify`;不要假定机器已全局安装 cage。
6
8
 
7
9
  ## 第一次启动应用
@@ -25,21 +27,22 @@ pnpm dev
25
27
 
26
28
  `init` 自动创建独立账号与随机密码,填写 APP/READ/MIGRATE 连接和 Cookie 密钥,成功后删除文件中的管理员连接。三个连接使用同一数据库。已有 Cage 集群账号时复用原连接,不能重置其他应用的账号密码。生产环境可由平台直接提供账号连接,不必执行本地 init。
27
29
 
28
- `bootstrap` 独立初始化组织,不自动授予业务能力。管理员凭据只进入新的受限文件,不进入服务控制台;已有用户时不重置。交付后移除凭据文件。日常 API 启动不初始化组织;生产缺少合格 Cookie 密钥会拒绝启动。具体文件权限与诊断用法见[能力发现与状态诊断](../tools/diagnostics.md)。
30
+ `bootstrap` 独立初始化组织,并给初始超级管理员当前及以后新增的全部能力和本租户全部数据范围。超级管理员可以直接为普通角色配置能力和范围;普通角色不会自动获得新增能力。管理员凭据只进入新的受限文件,不进入服务控制台;已有用户时不重置账号,也不会自动升级已有角色。交付后移除凭据文件。日常 API 启动不初始化组织;生产缺少合格 Cookie 密钥会拒绝启动。具体文件权限与诊断用法见[能力发现与状态诊断](../tools/diagnostics.md)。
29
31
 
30
32
  `.env.example` 是配置说明,`.env` 是本机私密配置,二者不混用。CLI 自动加载应用 `.env`,部署环境同名变量优先。API 和 worker 启动需重启后读取变更;不要输出整个 `.env` 排障。
31
33
 
32
34
  框架仓库首次先在根目录 `pnpm install`、`pnpm build`,再进入 `examples/purchase-admin` 配置。`dev` 不自动执行迁移;生成新迁移后要审查并显式运行 migrate。
33
35
 
34
- ## 做一项业务修改
36
+ ## 按已明确的设计修改业务
37
+
38
+ 只执行实现映射涉及的操作;文案或样式调整无需修改 domain、生成迁移或重新授权。实现过程中发现业务规则尚不清楚,回到[业务澄清](../guides/business-collaboration.md)处理相关部分。
35
39
 
36
- 1. 读 AGENTS.md 和[框架开发 Skill](../skills/cage-development/SKILL.md),确认需求属于领域模块、前端模块、组织配置还是框架。阅读需求和文档后,按[业务澄清与共同设计](../guides/business-collaboration.md)主动提出疑问、选项和建议,与用户确定相关规则及验收;已明确部分继续推进。按任务选手册,必要时本地搜索术语;用 `capabilities` 核对公开 API、`context "需求关键词"` 定位当前业务。按需 `graph search/inspect/path`,阅读对应源码、范例与测试;证据边界见[本体上下文指南](../tools/ontology-context.md)。遵守[目录规范](../reference/project-structure.md)和[详细中文注释规范](../reference/commenting.md),发现能力缺口先说明,不编造 API。
37
- 2. 涉及已存在业务含义变化时,**修改前**运行 `pnpm exec cage snapshot save before-change` 保存命名基线;也可使用真实 Git 提交或独立本体图文件。
38
- 3. 在所属领域模块写字段、状态、不变量和命令输入;再实现 handler、事件、查询与审批。跨模块反应放 workflows,第三方协议放 integrations。从模块 index 到 domain 总入口逐层导出,避免跨文件 export 名冲突。同步编写详细中文注释:文件职责与调用链、导出声明及输入字段、权限/状态/reads/事件/事务、关键步骤和失败边界;涉及已有行为时补齐受影响的上下游说明。
39
- 4. `pnpm exec cage check` 检查声明和图规则;`pnpm gen` 更新契约与迁移草稿。聚合和命令填写中文 `description`,需要覆盖时补 `cage.config.json` 的 `graph.labels`(如 `aggregate:Note`、`command:Note.archive`、`capability:Note.export`)。这些名称同时用于图谱和 `/admin` 授权界面;修改后重启 API。不重命名实际能力点来实现翻译。在图谱确认连接与资源生命周期。
40
- 5. 审查数据库变更,特别是非空字段、数据回填、删列和索引。已执行的迁移不可改写。需要落库时显式 `pnpm migrate`。
41
- 6. 页面和表单放 `apps/web/src/modules/<业务>`,从模块公开入口接入 app 的 URL 路由;依赖生成 contracts,处理失败结果。列表、详情等多页面使用 React Router,筛选和分页进入 URL;组件状态只管理页面内临时交互。新增能力由管理员授权,页面按钮可用 `useCan` 控制。按[路由与浏览器验收](../guides/routing.md)检查直达、刷新、前进后退和登录回跳。
42
- 7. 补足重要业务反例并运行相关验证;测试解释夹具目的、所保护的规则和覆盖边界。按注释规范审查本次 diff,核对页面、组件/hooks、类型字段、脚本副作用和恢复流程的说明是否完整准确。提交源声明、契约和审查过的迁移,报告跳过及未执行项。
40
+ 1. **保存基线。** 涉及已存在业务含义变化时,修改前运行 `pnpm exec cage snapshot save before-change`;也可使用真实 Git 提交或独立本体图文件。
41
+ 2. **修改声明与导出。** 按[目录规范](../reference/project-structure.md)在所属领域模块修改字段、状态、不变量、命令及必要的后续流程。按[本体建模指南](../guides/ontology-modeling.md)把对象含义、关系方向与基数、状态和操作结果写进真实声明;名称用 description、字段 .describe 和每个状态的 labels 维护,普通注释与页面翻译不能代替。跨模块反应放 workflows,第三方协议放 integrations;从模块 index 到 domain 总入口逐层导出,避免重名丢失。按[注释规范](../reference/commenting.md)同步解释职责、输入、权限/状态/reads、事件/事务与失败边界。
42
+ 3. **检查与生成。** `pnpm exec cage check` 检查声明和图规则,处理 `CAGE-ONTOLOGY-001` 指出的缺名;`pnpm gen` 更新契约与迁移草稿,不手改生成物。名称显示覆盖可写 `cage.config.json` 的 `graph.labels`(如 `aggregate:Note`、`command:Note.archive`、`capability:Note.export`),不重命名能力点来翻译。图谱中核对业务名称、关系、状态迁移与资源生命周期;名称齐全不能证明联动已经实现。
43
+ 4. **审查与迁移。** 核对非空字段、回填、删列和索引,保留已执行迁移;有结构变化且需落库时显式 `pnpm migrate`。按需要配置能力、范围和外部服务,API/worker 使用一致声明。
44
+ 5. **接入页面。** 在 `apps/web/src/modules/<业务>` 使用真实生成契约,从模块入口接入 app 路由。处理业务失败与版本冲突;多页面使用独立 URL,筛选/分页进入 URL。`useCan` 只控制按钮,服务端仍校验授权;成功后重新读取或失效查询。按[浏览器验收](../guides/routing.md)检查对应操作和导航。
45
+ 6. **核对规则与交付。** 对照编码前的规则与验收例子,补足关键反例,执行下文与改动匹配的检查。审查 diff 中的业务变化、生成物和中文注释;交付源声明、契约、审查过的迁移及配置要求,分别报告通过、跳过、未执行。
43
46
 
44
47
  ### 如何保存和比较基线
45
48
 
@@ -62,7 +65,7 @@ pnpm exec cage impact --base main
62
65
  | --- | --- | --- |
63
66
  | 增加字段 | 修改 aggregate;按命令更新 input/handler;重新生成 | 是否敏感、是否可选、旧数据如何回填、查询/事件/页面受影响吗 |
64
67
  | 增加状态或撤回 | 修改 states 和 command;声明事件及资源处理 | 可达性、非终态出边、审批 cancelOn、CAGE-PAIR-002 |
65
- | 修改审批 | 修改 route/approval;按需要增加 routable | 负责人/role code、步骤 mode、结论命令、额度和职责分离 |
68
+ | 修改审批 | 修改 route/approval;按需要增加 routable | 负责人/role code、步骤 mode、业务分支条件、结论命令和职责分离 |
66
69
  | 增加报表 | 声明 query 的 reads、input 和 sql/build | 安全视图、参数化、调用人 read 权限、生成 queries 契约 |
67
70
  | 接入第三方 | 声明 connector/op/outbound/inbound;配置运行环境密钥 | 请求响应白名单、幂等、超时、验签、永久/可重试错误和补偿 |
68
71
  | 改后台管理配置 | 通过组织模型与系统接口修改 | 防提权、实际授权范围、角色缓存刷新、操作人权限 |
@@ -128,7 +131,7 @@ CSV 编码、限制、SDK 与完整接口见本项目自带的[业务页导入
128
131
 
129
132
  - 文档、文案、可逆的小改动:检查链接、格式、资料分发;不需要重复运行全套数据库测试。
130
133
  - 所有源码变更:按[注释交付清单](../reference/commenting.md#交付前逐项核对)人工核对中文职责、接口与关键流程说明;静态检查不能替代注释准确性检查。仅补注释时不新增复述实现的测试、不改写已执行迁移。
131
- - 命令/约束/反应变化:针对成功路径及真正的风险增加用例,如越权拒绝、额度边界、资源释放、同事务回滚。不要写只复述实现的测试。
134
+ - 命令/约束/反应变化:针对成功路径及真正的风险增加用例,如越权拒绝、业务条件边界、资源释放、同事务回滚。不要写只复述实现的测试。
132
135
  - 领域结构变化:check、gen、生成一致性、类型检查;有数据库影响时在独立测试库验证迁移和读写。
133
136
  - 页面或导航变化:构建后按[浏览器配方](../guides/routing.md)实际操作,包含深链接、新标签页、刷新、前进后退、登录回跳、无权限和 404。check/verify 不自动执行浏览器验收;未操作时明确报告未执行,不能写“页面功能完整”。
134
137
  - 发布前:按项目要求执行完整 verify/build/test,核对分发包。没有执行的项目明确写出原因。
@@ -137,17 +140,8 @@ CSV 编码、限制、SDK 与完整接口见本项目自带的[业务页导入
137
140
 
138
141
  派生测试无法凭空推断所有业务合法输入,会报告跳过。它们证明的是通用性质,不能代替采购 happy path、审批配置和第三方真实联调。
139
142
 
140
- ## 可以交给 AI 的任务描述
141
-
142
- ```text
143
- 先读 AGENTS.md 和它指定的 docs/development/README.md,再参考对应标准范例。
144
- 需求:为某业务增加……
145
- 阅读需求、业务文档和现有代码,主动指出疑点与建议,给出可行选项、影响和推荐理由,让我选择业务规则;已给出的答案直接沿用,技术事实自行查证。
146
- 先用 cage context 查询现有业务,必要时 graph inspect/path,确认候选与关系后阅读实现。
147
- 把已确定的规则映射到字段、状态、能力与范围、事件/资源和验收,再修改 domain、生成契约和迁移草稿、接入业务页面;等待业务选择时推进独立部分。
148
- 使用真实公开 API;不要手写业务路由、直接写表或新增本地数据库生命周期命令。
149
- 按 docs/development/reference/commenting.md 给新建和修改代码写详细中文注释,覆盖职责、API/字段、步骤、原因和边界,同步修正相关上下游说明。
150
- 按改动运行必要检查,报告通过/跳过/未执行项和需要的管理员配置。
151
- ```
143
+ ## 交付说明
144
+
145
+ 可复用的需求输入见[任务模板](../guides/recipes.md#给编程工具的任务模板),工作流程使用 Skill,不另维护一套提示词。
152
146
 
153
147
  交付说明至少包含行为变化、源文件、生成物/迁移、角色授权需求、详细中文注释覆盖的主要职责与边界、验证结果,以及尚未做的真实外部联调。注释未覆盖项如实说明,不能用聊天中的解释代替源码注释。遇到错误先修复根因;不把待办未生成、任务已接受或 fake 成功写成业务全部完成。
@@ -6,7 +6,7 @@
6
6
 
7
7
  1. 业务对象有草稿、待审批和相应结论状态。提交命令声明 emits 并成功发出提交事件;通过/拒绝等结论声明为 process 命令。
8
8
  2. approval 绑定提交事件、结论命令和取消事件,route 定义步骤与选人;两者都从 domain 入口导出。routable 只包含选路和任务需要的业务快照字段。
9
- 3. 配置实际负责人/角色成员,并分别授予所需能力、范围和额度;声明 role code 不会创建角色或分配人员。检查迁移和运行中的 worker。
9
+ 3. 配置实际负责人/角色成员,并分别授予所需能力和范围;声明 role code 不会创建角色或分配人员。检查迁移和运行中的 worker。
10
10
  4. 页面先通过业务契约提交,再读取真实待办,通过公开任务接口携带当前 revision 作出决定。业务列表中的“待审批”不等于当前用户拥有待办。
11
11
  5. 观察提交事件、待办、决定与领域最终状态;用不合格主体验证拒绝,按需求验证撤回。缺少待办时按[排错方法](../tools/troubleshooting.md)查具体断点,不直接把单据改成通过。
12
12
 
@@ -48,7 +48,7 @@ step('专业审核', approver.field('reviewers'), {
48
48
 
49
49
  字段缺失或为 `null` 时解析为空候选,开启节点报 `CAGE-APPR-007`;空数组、非法 UUID、数组中包含非字符串或超过 200 项报 `INVALID_INPUT`。开启字段选人或候选节点时,所有选中的 ID 必须属于当前租户且账号 active,否则整批失败,不静默去掉无效人员或默认批准。旧的固定用户/部门负责人直派规则保持原有开启行为。
50
50
 
51
- 开启节点的账号校验不会替用户授予批准/read 能力或数据范围。领取、转办、委派、加签和实际决定仍按当时的权限核验;配置了有效用户也不代表其最终额度、职责分离等业务硬约束一定满足。
51
+ 开启节点的账号校验不会替用户授予批准/read 能力或数据范围。领取、转办、委派、加签和实际决定仍按当时的权限核验;配置了有效用户也不代表职责分离等业务硬约束一定满足。
52
52
 
53
53
  ## 结构化并行分支与 AND 汇合
54
54
 
@@ -85,7 +85,7 @@ export const documentRoute = route('document-review', [
85
85
 
86
86
  拒绝、退回或取消结束整个审批轮次,关闭其他分支中的活动节点和 pending/waiting 任务;尚未开启的后续节点不再创建。正常推进在实例锁内检查持久前驱状态,节点唯一键防止并发分支重复创建同一汇合后继。若同一次启动或推进中的任一新节点无法开启,整个本次事务回滚,不留下部分成功的分支入口。已经在较早事务中通过的票仍保留。
87
87
 
88
- 最终业务结论仍以实际推进完成的办理人身份调用领域命令。并行组后没有明确的最终审批节点时,最后完成分支的人可能承担该身份;额度、职责分离或状态约束不满足会回滚本次决定。需要固定最终责任人时,应像上例一样在 AND 汇合后声明明确的最终节点。
88
+ 最终业务结论仍以实际推进完成的办理人身份调用领域命令。并行组后没有明确的最终审批节点时,最后完成分支的人可能承担该身份;职责分离或状态约束不满足会回滚本次决定。需要固定最终责任人时,应像上例一样在 AND 汇合后声明明确的最终节点。
89
89
 
90
90
  ### 快照、历史和界面定位
91
91
 
@@ -140,7 +140,7 @@ waiting 任务只能查看,不能决定或执行任务管理动作。前签完
140
140
 
141
141
  任一当前可决定的任务拒绝或退回,会调用原有领域结论命令;成功后关闭同轮次剩余 pending 和 waiting。取消或重新提交也会关闭旧轮次两种状态的任务。不能通过释放仍带未完成前/后/并行子票的候选任务来丢弃必签责任。
142
142
 
143
- 最终推进流程的实际决定人必须通过领域结论命令的额度、职责分离、状态和版本约束。后签人可能成为最终签署人;若其额度不足,最后决定、版本、阶段变化及本次历史共同回滚,之前已提交的父票保留。引擎不会自动改用更早审批人的身份。
143
+ 最终推进流程的实际决定人必须通过领域结论命令的职责分离、状态和版本约束。后签人可能成为最终签署人;若其不满足职责分离,最后决定、版本、阶段变化及本次历史共同回滚,之前已提交的父票保留。引擎不会自动改用更早审批人的身份。
144
144
 
145
145
  ## 客户端调用
146
146
 
@@ -43,7 +43,9 @@
43
43
 
44
44
  简单任务在对话中简短记录即可;需要后续维护的规则写入项目已有业务文档或 AGENTS.md 的托管区外,并从项目入口引用。保留“已确定的规则及依据”“尚待决定的事项”“可选建议”的区别。客户业务事实不写进框架通用教材,也不写进会被 `cage sync` 覆盖的区域。
45
45
 
46
- 确定规则后,按[能力选择](recipes.md)映射到聚合、命令、状态、范围、审批或连接器,同时补充能观察结果的验收例子。记录不要求固定文件格式,也不要求每项小改动新增计划文件。
46
+ 回答应变成可以核对的业务规则和验收例子,保留来源;不要只记“用户同意方案 A”,丢失选项当时的含义。接着查证现有实现与框架能力,按[编码前的实现映射](recipes.md#写代码前的实现映射)说明如何落到声明、页面、配置和验收,再实施。只有规则已确定而技术做法尚未查清时,继续查证,不把技术猜测混进用户的业务选择。
47
+
48
+ 记录不要求固定文件格式,也不要求每项小改动新增计划文件。已明确的技术方案无需再设一轮批准,普通实现取舍由 agent 负责。
47
49
 
48
50
  ## 示例:文档没有写清金额边界
49
51
 
@@ -0,0 +1,30 @@
1
+ # React 前端与组件库
2
+
3
+ 本指南约束 Cage 应用中的 AI 生成式 React 开发。AI 在开发阶段根据业务需求编写、修改并验证真实 `.tsx` 页面与组件;运行时仍是普通 React 应用,不引入页面描述语言、schema 渲染器或固定 CRUD 页面模板。
4
+
5
+ ## 组件库选择
6
+
7
+ Cage Web 默认使用 Ant Design(`antd`)和 `@ant-design/icons`。Ant Design 提供覆盖面完整的 React 控件、中文 locale、表格/表单/反馈组件和成熟文档,适合由 agent 按具体页面组合使用。通用 React 生态中也有 Mantine、MUI 等选择;本仓库采用 Ant Design 是为了统一范例和模板的默认组件接口,不要求业务页面套用某种固定版式。
8
+
9
+ 需要构建对话、消息气泡、提示词或 AI 推理步骤等 AI 原生交互时,可以评估 Ant Design X;普通表单、详情、筛选、数据表格仍使用 `antd`。模板不预装这项可选依赖,只有用户需求确实包含这类交互时才添加。不要把 ProComponents 或整套后台脚手架作为默认页面生成方式;它们的高层 CRUD 约定容易把页面形态固定下来,而真实字段、操作与范围必须由业务需求和 Cage 契约决定。
10
+
11
+ ## 应用入口与调用边界
12
+
13
+ 范例和模板已在 Web 入口安装 `ConfigProvider`、简体中文 locale、共享主题 token 与 Ant Design `App` 上下文。生成组件可从 `antd` 和 `@ant-design/icons` 导入控件;需要消息、通知或确认框时,在 React 子组件中调用 `App.useApp()` 返回的方法,使反馈使用入口提供的上下文。不要在模块中重复创建 Provider,也不要使用无法继承应用上下文的静态反馈 API。
14
+
15
+ 页面仍按 `apps/web/src/modules/<module>` 组织,并从模块公开入口导出,由 `app` 层组合到 React Router。筛选、排序和分页等可分享状态进入 URL 查询参数;列表和详情使用各自稳定 URL。组件状态只保存尚未提交的交互草稿,不代替服务端记录。
16
+
17
+ 业务数据使用生成契约和 Cage Client/现有 hooks:读取经过安全读侧,写操作调用对应命令,并处理 `CageResult`、并发冲突和查询刷新。前端 `can()` 只控制入口或按钮显示,服务端仍执行能力、数据范围和业务状态检查。不得为了让生成页面看起来完整而增加伪造统计、静态仓储或绕开契约的直接数据库访问。
18
+
19
+ ## 生成页面的组合准则
20
+
21
+ - 先按当前任务选择控件:`Form`/输入组件负责编辑,`Table` 负责需要行列比较的数据,`Descriptions` 负责详情字段,`Tag`/`Badge` 表示已有状态,`Result`/`Empty`/`Skeleton`/`Alert` 分别表达结果、空态、加载和错误。
22
+ - 用 `Layout`、`Flex`、`Grid`、`Space`、`Typography` 和局部 CSS 建立页面层次;页面布局由任务决定,不为每个区块机械套卡片,也不生成与用户目标无关的仪表盘。
23
+ - 优先使用 Ant Design 的 `Button`、`Input` 等组件 props 和主题 token 表达样式与状态。不要把现有业务 CSS 类(如 `.primary`)直接赋给 Ant Design 控件;项目里的旧全局原生按钮规则与其业务类仅服务于原有 DOM 页面。
24
+ - 图标从 `@ant-design/icons` 按需导入;只有图标含义不明确时加 Tooltip,主要操作按清楚的文字命名。
25
+ - 每个页面自行呈现真实加载、空结果、请求失败、无权限和提交中状态;避免通过组件默认值把未知状态渲染成零或成功。
26
+ - 表格给稳定的 `rowKey`,分页与筛选变化同步 URL 和服务端查询;不能只在当前页本地过滤服务端分页结果。
27
+ - 表单校验帮助使用者尽早发现输入问题,不能取代服务端 schema、领域不变量或权限校验;成功后按现有查询键刷新数据,失败时保留输入并显示可处理的原因。
28
+ - 保持布局在窄屏可用,避免固定宽度、横向溢出及把操作只放在 hover 上;可复用的业务组件留在所属模块,只有确实跨模块复用时才进入 `shared`。
29
+
30
+ 实现前阅读相关页面、模块入口和契约类型。组件库提供的是可组合的 UI 原语,AI 应根据实际业务含义选择与组织它们;组件本身不会生成 Cage 领域声明、API、授权或持久化行为。
@@ -10,13 +10,13 @@
10
10
 
11
11
  | 需求关键词 | 公开入口 | 本页使用说明 |
12
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: ... })` | “大本体按需加载”;工具、历史、页面与输出共同受预算约束 |
13
+ | AI审批、智能审批、转人工 | `@yss123/cage-approval` 的 `step`、`AiStepOptions` | [AI 审批步骤](#ai-是一个正常审批步骤);沿用 `approval`,声明三态及真实角色 |
14
+ | 业务助理、本体助理 | `@yss123/cage-ai` 的 `ai` | [启用后端](#启用后端)、[工具来源](#助理工具来自注册表);框架编译工具,应用提供声明 |
15
+ | 页面上下文、随页助理 | `@yss123/cage-client` 的 `useAssistant`、`useAiPageContext`、`AiPageContext` | [SDK 与页面内容](#sdk-传入页面内容);应用维护界面与语义快照 |
16
+ | 模型管理、动态配置 | `@yss123/cage-ai` 的 `managedModel` | [启用后端](#启用后端);Admin 配置连接,部署配置凭据加密密钥 |
17
+ | Responses | `managedModel` 的 Admin 协议选项;代码配置用 `responsesModel` | [Responses 配置](#responses-会话与上下文配置);实际验证网关接续及压缩支持 |
18
+ | 性格、自定义人设 | `useAssistant`、`client.ai`;类型由 `@yss123/cage-ai-protocol` 提供 | [Admin 性格配置](#admin-配置助理性格);内置预设与自定义表达,不改变审核策略 |
19
+ | 上下文预算、大本体 | `@yss123/cage-ai` 的 `AiContextOptions`,传入 `ai({ context: ... })` | [按需加载](#大本体按需加载);工具、历史、页面与输出共同受预算约束 |
20
20
 
21
21
  在应用根目录按需查询,例如:
22
22
 
@@ -38,6 +38,8 @@ pnpm exec cage capabilities "Responses" --format json
38
38
 
39
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
40
 
41
+ 按本次实现范围选择阅读顺序:业务助理走[后端启用与迁移授权](#启用后端) → [工具边界](#助理工具来自注册表) → [页面 SDK](#sdk-传入页面内容) → [验收](#接入后的验收);AI 审批走同一后端前提 → [审批步骤](#ai-是一个正常审批步骤) → [验收](#接入后的验收)。Responses、性格和预算按需求补读。先按 Skill 明确助理应帮助用户完成哪些动作、审批采用哪些规则,再选择接入点。
42
+
41
43
  ## 启用后端
42
44
 
43
45
  在应用 domain 包安装与框架同版本的 `@yss123/cage-ai`,把声明从 domain 根入口导出。API 和 worker 使用同一 domain,标准 `createServer` / `startWorker` 自动装配服务,不需要手写业务路由或后台循环。
@@ -61,6 +63,8 @@ export const intelligence = ai({
61
63
  });
62
64
  ```
63
65
 
66
+ 只有 AI 审批时可以省略 `assistant`。审查并执行 `pnpm migrate` 后再启动 API/worker;新增命名系统迁移由框架携带,`cage doctor` 会列出未执行项,不把建表放到服务启动。管理员显式向使用助理的人授予 `Sys.ai.use`,再按需授予领域 `read`、命令与范围;启用服务不自动授予业务权限。AI 审批的执行角色与授权按下文审批步骤配置。
67
+
64
68
  `managedModel` 是框架托管的模型入口。应用引用稳定别名,实际模型名称、HTTP / HTTPS API 基地址、API Key、接口协议、上下文窗口、超时及启停状态在 `/admin/#/models` 配置。可声明多个入口供审批和助理分别使用。不需要在业务项目定义模型配置表、管理路由或环境变量读取逻辑。
65
69
 
66
70
  部署向 API 和 worker 注入同一份 `CAGE_AI_ENCRYPTION_KEY`(32 字节随机密钥的标准 Base64),也可通过连接器 `SecretProvider` 提供。它是加密模型凭据的部署主密钥,不是模型 API Key;应稳定保存并与数据库分开备份。不要随进程启动重新生成,也不要直接轮换它而不重新加密旧配置。未配置时不能保存 API Key。
@@ -71,6 +75,8 @@ export const intelligence = ai({
71
75
 
72
76
  需要代码配置或离线测试时,可使用 `chatModel('language-model', { model, hosts, secret, fake })` 或同包导出的 `responsesModel`:`secret` 是 SecretProvider 的密钥名称;默认遵循 `CAGE_STAGE`,fake 阶段必须显式提供模拟函数且禁止外呼;`environment: 'test' | 'prod'` 可独立选择真实模型环境。自定义 `credential` 解析器只在服务端按次调用,不参与声明序列化。两者默认 HTTPS,可显式设置 `protocol: 'http:'` 连接 HTTP 网关。所有标准模型外呼经过框架连接器的地址校验、限流、取消和超时。
73
77
 
78
+ `ModelProvider` 是服务端扩展接口,可适配其他协议;适配器必须响应 `AbortSignal`。运行时仍会在超时后放弃等待,迟到结果不会被提交。
79
+
74
80
  ### Responses 会话与上下文配置
75
81
 
76
82
  Admin 的 `apiFormat` 默认 `chat-completions`,旧模型升级后保持该协议;选择 `responses` 后启用服务端接续。`contextWindowTokens` 默认 32768,可配置 8192 至 2000000,必须按实际模型容量填写;窗口包括输入、输出及推理 Token,和 `assistant.limits.tokenBudget` 的单轮累计消耗分别控制。代码模型使用同名选项。
@@ -83,10 +89,6 @@ Responses 请求使用 `store: true` 和 `previous_response_id`。框架持久
83
89
 
84
90
  升级执行系统迁移 `cage:ai_context_001` 和 `cage:ai_execution_001`:前者增加模型协议/窗口及接续状态,后者将调用预留、尝试次数、接续兼容性及工具预算单独持久化;不改写已有迁移。旧运行的已有计数保留,不追溯推测其费用。前端调用 `client.ai` 的发送、流式订阅与交互方法不变。
85
91
 
86
- 只有 AI 审批时可以省略 `assistant`。`ModelProvider` 是服务端扩展接口,可适配其他协议;适配器必须响应 `AbortSignal`。运行时仍会在超时后放弃等待,迟到结果不会被提交。
87
-
88
- 审查并执行 `pnpm migrate` 后再启动 API/worker。新增命名系统迁移由框架携带,`cage doctor` 会列出未执行项。不要把建表放到服务启动。管理员显式向使用助理的人授予 `Sys.ai.use`,再按需授予领域 `read`、命令与范围;启用服务不自动授予业务权限。
89
-
90
92
  ## Admin 配置助理性格
91
93
 
92
94
  性格是框架提供的租户配置,无需应用声明性格聚合或编写工具。启用 `ai({ models, assistant })`、执行系统迁移后即可使用;管理员需显式获得 **`Sys.ai.personalities.manage`**,从 `/admin/#/personalities` 管理。它与 `Sys.ai.models.manage`、普通用户的 `Sys.ai.use` 分开授权。
@@ -173,7 +175,7 @@ export const reviewRoute = route('document-review', [
173
175
 
174
176
  三个结论命令必须属于该聚合并声明 `invokedBy: 'process'`。`onReturned` 与最终拒绝 `onRejected` 独立。修订后再次触发 start 事件,会创建新轮次,从第一个步骤重新开始;旧步骤和旧任务不能继续生效。通知申请人可以由结论命令发事件,再接已有通知反应/连接器;框架不会猜测通知渠道。
175
177
 
176
- `automatedBy` 是真实组织角色的 code,不是模型可选身份。角色需显式拥有对象读取、所需查询读取、通过/退回命令,以及相应范围与额度。没有隐式全范围,也不冒充提交人。`sod.notSameAs` 要求可核验的真人操作人,自动节点不能绕过该约束;这种命令会转人工。
178
+ `automatedBy` 是真实组织角色的 code,不是模型可选身份。角色需显式拥有对象读取、所需查询读取、通过/退回命令,以及相应范围。没有隐式全范围,也不冒充提交人。`sod.notSameAs` 要求可核验的真人操作人,自动节点不能绕过该约束;这种命令会转人工。
177
179
 
178
180
  `context.fields` 白名单定义单据上下文;`context.queries` 引用已导出的 query 名称,AI 可按查询 schema 补参数。审核阶段只能调用这些查询、`review_decide` 及读取本次证据的 `context_read`,不能访问其他会话、动态加载其他业务工具或调用助理写工具。证据引用会校验来源是否已提供,但不会把模型判断当作数学证明。
179
181