@zhaiye/codebase-ontology 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +106 -0
- package/SKILL.md +215 -0
- package/agents/openai.yaml +4 -0
- package/bin/codebase-ontology.js +206 -0
- package/package.json +39 -0
- package/references/ontology-output-structure.md +609 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zhaiye
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Codebase Ontology Skill
|
|
2
|
+
|
|
3
|
+
一个给 AI agent 使用的 skill,用于阅读代码库,并在目标 codebase 中生成业务 Ontology 五要素 YAML 文档。
|
|
4
|
+
|
|
5
|
+
生成结果会写入目标 codebase 的 `.ontology/` 目录,并按五要素拆分:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
.ontology/
|
|
9
|
+
README.md
|
|
10
|
+
index.yaml
|
|
11
|
+
object-types/object-types.yaml
|
|
12
|
+
properties/properties.yaml
|
|
13
|
+
link-types/link-types.yaml
|
|
14
|
+
action-types/action-types.yaml
|
|
15
|
+
functions/functions.yaml
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
使用 npm 全局安装:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g @zhaiye/codebase-ontology
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
安装到 Codex 全局 skills:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
codebase-ontology install --agent codex
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
安装到 Claude Code 全局 skills:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
codebase-ontology install --agent claude
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
同时安装到 Codex 和 Claude Code:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
codebase-ontology install --agent all
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
安装到当前项目:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
codebase-ontology install --agent codex --scope project
|
|
48
|
+
codebase-ontology install --agent claude --scope project
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
项目级安装路径分别是:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
Codex: .codex/skills/codebase-ontology/
|
|
55
|
+
Claude: .claude/skills/codebase-ontology/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 使用
|
|
59
|
+
|
|
60
|
+
在目标代码库中,让 agent 使用该 skill:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
使用 $codebase-ontology 为当前代码库生成 .ontology 五要素 YAML 文档。
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
也可以直接描述任务:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
请分析这个 codebase,生成业务 ontology,并把五要素分别写到 .ontology 目录下。
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## CLI
|
|
73
|
+
|
|
74
|
+
查看将安装到哪里:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
codebase-ontology doctor
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
预览安装但不写文件:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
codebase-ontology install --agent all --dry-run
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
指定安装目录:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
codebase-ontology install --target-dir ~/.codex/skills
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
卸载:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
codebase-ontology uninstall --agent codex --yes
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 仓库结构
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
SKILL.md
|
|
102
|
+
references/ontology-output-structure.md
|
|
103
|
+
agents/openai.yaml
|
|
104
|
+
bin/codebase-ontology.js
|
|
105
|
+
package.json
|
|
106
|
+
```
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-ontology
|
|
3
|
+
description: 生成代码库 Ontology 五要素文档。用于分析一个 codebase,并在该 codebase 根目录创建或更新 .ontology 目录,分别生成 Object Types、Properties、Link Types、Action Types、Functions 五类 YAML 文件;当用户要求 ontology 抽取、codebase ontology、业务实体建模、ontology.yaml 生成或按五要素整理代码库业务语义时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Codebase Ontology
|
|
7
|
+
|
|
8
|
+
## 核心目标
|
|
9
|
+
|
|
10
|
+
使用本 skill 阅读目标 codebase,并在该 codebase 根目录生成 `.ontology/` 目录。输出必须按五要素拆分为五个子目录和五个 YAML 文件,而不是写成一个大文档。
|
|
11
|
+
|
|
12
|
+
强制目标结构:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
<codebase-root>/
|
|
16
|
+
.ontology/
|
|
17
|
+
README.md
|
|
18
|
+
index.yaml
|
|
19
|
+
object-types/object-types.yaml
|
|
20
|
+
properties/properties.yaml
|
|
21
|
+
link-types/link-types.yaml
|
|
22
|
+
action-types/action-types.yaml
|
|
23
|
+
functions/functions.yaml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
不要把本 skill 的说明文件复制进目标 codebase。只生成目标 codebase 的 ontology 产物。
|
|
27
|
+
|
|
28
|
+
## 建模原则
|
|
29
|
+
|
|
30
|
+
- 建模真实业务世界,不机械复制数据库表、API schema、类图或目录结构。
|
|
31
|
+
- 使用代码、测试、数据库 migration、API 路由、文档作为证据。
|
|
32
|
+
- 没有证据不要臆造;不确定内容写入 `openQuestions`。
|
|
33
|
+
- 五要素为:`Object Type`、`Property`、`Link Type`、`Action Type`、`Function`。
|
|
34
|
+
- `Interface`、`Shared Property`、`Value Type` 只是扩展能力,可在相关 YAML 中作为辅助结构出现,不创建额外强制目录。
|
|
35
|
+
- 每个重要 item 都要有 `sourceEvidence` 和 `confidence`。
|
|
36
|
+
- 生成的 YAML 内容语言必须为中文;schema key、ID、代码路径、symbol、原始枚举值和外部系统名称可保持原文。
|
|
37
|
+
|
|
38
|
+
## 输出语言要求
|
|
39
|
+
|
|
40
|
+
生成到目标 codebase `.ontology/` 下的所有 YAML 文件,内容语言必须以中文为主。
|
|
41
|
+
|
|
42
|
+
必须使用中文的字段:
|
|
43
|
+
|
|
44
|
+
- `displayName`
|
|
45
|
+
- `description`
|
|
46
|
+
- `notes`
|
|
47
|
+
- `question`
|
|
48
|
+
- `suggestedResolution`
|
|
49
|
+
- `qualityChecks.*.notes`
|
|
50
|
+
- `guide.definition`
|
|
51
|
+
- `guide` 下所有解释性文字
|
|
52
|
+
- `.ontology/README.md` 中的人类可读内容
|
|
53
|
+
- object、property、link、action、function 的业务语义说明
|
|
54
|
+
|
|
55
|
+
可以保留原文的字段:
|
|
56
|
+
|
|
57
|
+
- YAML schema key,如 `metadata`、`items`、`sourceEvidence`
|
|
58
|
+
- 稳定机器 ID,如 `order`、`customerPlacesOrder`、`calculateOrderTotal`
|
|
59
|
+
- 代码路径,如 `src/domain/order/Order.ts`
|
|
60
|
+
- 代码 symbol,如 `OrderService.cancelOrder`
|
|
61
|
+
- API path,如 `POST /orders/{orderId}/cancel`
|
|
62
|
+
- 数据库表名、列名、外键名
|
|
63
|
+
- 源代码中的枚举值和状态值,如 `draft`、`placed`、`cancelled`
|
|
64
|
+
- 外部系统或第三方产品名称
|
|
65
|
+
|
|
66
|
+
如果原始 codebase 使用英文领域词,`id` 可以保持英文 lowerCamelCase,但 `displayName` 和 `description` 必须翻译成中文。原始英文名称写入 `aliases` 或 `sourceEvidence`,不要丢失。
|
|
67
|
+
|
|
68
|
+
## 工作流程
|
|
69
|
+
|
|
70
|
+
1. 定位 codebase 根目录,确认要写入 `<codebase-root>/.ontology/`。
|
|
71
|
+
2. 阅读 README、产品文档、API schema、路由、数据库 migration、ORM model、domain/service 层、测试。
|
|
72
|
+
3. 总结业务域、用户角色、核心流程,写入 `.ontology/index.yaml` 和 `.ontology/README.md`。
|
|
73
|
+
4. 抽取 Object Types:业务实体或业务事件。
|
|
74
|
+
5. 抽取 Properties:对象的业务特征。
|
|
75
|
+
6. 抽取 Link Types:对象之间的业务关系。
|
|
76
|
+
7. 抽取 Action Types:用户、系统、任务或 agent 可执行的业务变更。
|
|
77
|
+
8. 抽取 Functions:可复用业务逻辑,如计算、校验、权限、聚合、排序、推荐、风控。
|
|
78
|
+
9. 为每个要素写证据,记录不确定问题。
|
|
79
|
+
10. 运行质量检查,更新每个 YAML 的 `qualityChecks`。
|
|
80
|
+
11. 检查所有生成 YAML 的人类可读内容是否为中文。
|
|
81
|
+
|
|
82
|
+
## 文件写入规则
|
|
83
|
+
|
|
84
|
+
必须创建或更新:
|
|
85
|
+
|
|
86
|
+
- `.ontology/index.yaml`:索引、元数据、统计摘要、跨文件引用。
|
|
87
|
+
- `.ontology/README.md`:人类可读摘要,简短说明核心对象、关系、动作、函数和未决问题。
|
|
88
|
+
- `.ontology/object-types/object-types.yaml`:只放 Object Type 结果。
|
|
89
|
+
- `.ontology/properties/properties.yaml`:只放 Property 结果,可包含 `valueTypes`、`sharedProperties`。
|
|
90
|
+
- `.ontology/link-types/link-types.yaml`:只放 Link Type 结果。
|
|
91
|
+
- `.ontology/action-types/action-types.yaml`:只放 Action Type 结果。
|
|
92
|
+
- `.ontology/functions/functions.yaml`:只放 Function 结果。
|
|
93
|
+
|
|
94
|
+
每个五要素 YAML 文件必须包含:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
metadata: {}
|
|
98
|
+
guide: {}
|
|
99
|
+
items: []
|
|
100
|
+
sourceEvidence: []
|
|
101
|
+
openQuestions: []
|
|
102
|
+
qualityChecks: {}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
详细模板和示例见 `references/ontology-output-structure.md`。当需要写入实际 YAML 文件时,必须先读取该参考文件。
|
|
106
|
+
|
|
107
|
+
## 五要素抽取准则
|
|
108
|
+
|
|
109
|
+
### Object Type
|
|
110
|
+
|
|
111
|
+
创建条件:
|
|
112
|
+
|
|
113
|
+
- 代表业务人员会自然讨论的实体或事件。
|
|
114
|
+
- 有稳定身份,如 ID、编号、唯一键、事件 ID。
|
|
115
|
+
- 有生命周期、状态、权限、审计或业务规则。
|
|
116
|
+
- 会被多个功能读取、修改、关联或展示。
|
|
117
|
+
|
|
118
|
+
不要创建:
|
|
119
|
+
|
|
120
|
+
- Controller、Handler、Repository、Service、Client、Adapter。
|
|
121
|
+
- Request DTO、Response DTO、Form、ViewModel,除非它本身就是业务提交记录。
|
|
122
|
+
- 临时缓存、分页对象、排序条件、查询参数。
|
|
123
|
+
- 纯 join table,除非关系本身有业务属性或生命周期。
|
|
124
|
+
|
|
125
|
+
### Property
|
|
126
|
+
|
|
127
|
+
创建条件:
|
|
128
|
+
|
|
129
|
+
- 描述对象的身份、状态、分类、时间、数量、金额、位置、归属或业务含义。
|
|
130
|
+
- 被查询、筛选、排序、展示、校验或用于权限判断。
|
|
131
|
+
- 参与动作输入、动作结果、业务规则、关系或函数。
|
|
132
|
+
|
|
133
|
+
关键约束:
|
|
134
|
+
|
|
135
|
+
- 主键必须稳定、唯一,不应使用可变业务状态。
|
|
136
|
+
- 枚举必须列出允许值。
|
|
137
|
+
- 金额、邮箱、国家码、百分比等领域字段优先建 `valueTypes`。
|
|
138
|
+
- 派生字段必须说明 derivation 或引用 Function。
|
|
139
|
+
- 敏感字段必须标注 `sensitivity`。
|
|
140
|
+
|
|
141
|
+
### Link Type
|
|
142
|
+
|
|
143
|
+
创建条件:
|
|
144
|
+
|
|
145
|
+
- 两个 Object Types 之间存在业务关系。
|
|
146
|
+
- 关系会被查询、导航、展示、授权、动作或函数使用。
|
|
147
|
+
- 关系有方向、基数、生命周期或自身属性。
|
|
148
|
+
|
|
149
|
+
关键约束:
|
|
150
|
+
|
|
151
|
+
- Link Type 必须连接 Object Type,不连接裸 Property。
|
|
152
|
+
- 必须写 `cardinality`、`directionality`、`reverseDisplayName`。
|
|
153
|
+
- many-to-many 关系若有业务属性或生命周期,考虑提升为 Object Type。
|
|
154
|
+
|
|
155
|
+
### Action Type
|
|
156
|
+
|
|
157
|
+
创建条件:
|
|
158
|
+
|
|
159
|
+
- 创建、更新、删除对象,或建立/删除链接。
|
|
160
|
+
- 表达明确业务意图,如 approve、assign、cancel、capture、submit、close。
|
|
161
|
+
- 包含权限、校验、审批、通知或外部系统调用。
|
|
162
|
+
|
|
163
|
+
不要创建:
|
|
164
|
+
|
|
165
|
+
- 只读操作,如 get、list、search、export。
|
|
166
|
+
- 单纯 getter、setter、helper。
|
|
167
|
+
- 每个字段一个 action 的机械拆分。
|
|
168
|
+
|
|
169
|
+
### Function
|
|
170
|
+
|
|
171
|
+
创建条件:
|
|
172
|
+
|
|
173
|
+
- 可复用业务逻辑。
|
|
174
|
+
- 根据对象和关系计算、校验、聚合、评分、排序、推荐或授权。
|
|
175
|
+
- 支撑 Action Type、派生 Property、API、报表或 agent 工具能力。
|
|
176
|
+
|
|
177
|
+
不要创建:
|
|
178
|
+
|
|
179
|
+
- 简单 getter/setter。
|
|
180
|
+
- 纯 mapper、serializer、framework helper。
|
|
181
|
+
- 没有业务语义的一次性 glue code。
|
|
182
|
+
|
|
183
|
+
## 质量检查
|
|
184
|
+
|
|
185
|
+
交付前检查:
|
|
186
|
+
|
|
187
|
+
- Object Type 是否代表业务概念,而不是技术结构。
|
|
188
|
+
- 每个 Object Type 是否有稳定主键和标题属性。
|
|
189
|
+
- Property 是否有类型、必填性、空值语义、敏感性和证据。
|
|
190
|
+
- Link Type 是否有方向、基数和反向名称。
|
|
191
|
+
- Action Type 是否表达业务动作,而不是字段更新。
|
|
192
|
+
- Function 是否是可复用业务逻辑,而不是 helper。
|
|
193
|
+
- 每个重要判断是否有 source evidence。
|
|
194
|
+
- 不确定问题是否进入 `openQuestions`。
|
|
195
|
+
- YAML 中面向人类阅读的内容是否为中文。
|
|
196
|
+
|
|
197
|
+
常见反模式:
|
|
198
|
+
|
|
199
|
+
- `System Silo`:按系统/服务/数据库边界建模。
|
|
200
|
+
- `Department Silo`:不同团队重复创建同一业务对象。
|
|
201
|
+
- `Kitchen Sink`:把所有字段塞进一个对象。
|
|
202
|
+
- `God Object`:一个对象承担过多职责。
|
|
203
|
+
- `Action Sprawl`:为每个字段创建一个 action。
|
|
204
|
+
|
|
205
|
+
## 最终回复
|
|
206
|
+
|
|
207
|
+
完成后,最终回复只需说明:
|
|
208
|
+
|
|
209
|
+
- 目标 codebase 的 `.ontology/` 路径。
|
|
210
|
+
- 已生成或更新的文件列表。
|
|
211
|
+
- 核心对象、关系、动作、函数摘要。
|
|
212
|
+
- open questions 数量及最高优先级问题。
|
|
213
|
+
- 质量检查是否通过。
|
|
214
|
+
|
|
215
|
+
不要在最终回复中粘贴完整 YAML,除非用户明确要求。
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const SKILL_NAME = "codebase-ontology";
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
9
|
+
const SKILL_ENTRIES = ["SKILL.md", "references", "agents"];
|
|
10
|
+
|
|
11
|
+
function usage() {
|
|
12
|
+
console.log(`codebase-ontology
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
codebase-ontology install [--agent codex|claude|all] [--scope global|project] [--target-dir DIR] [--project-dir DIR] [--dry-run] [--force]
|
|
16
|
+
codebase-ontology uninstall [--agent codex|claude|all] [--scope global|project] [--target-dir DIR] [--project-dir DIR] [--dry-run] [--yes]
|
|
17
|
+
codebase-ontology doctor [--project-dir DIR]
|
|
18
|
+
codebase-ontology --help
|
|
19
|
+
|
|
20
|
+
Defaults:
|
|
21
|
+
--agent all
|
|
22
|
+
--scope global
|
|
23
|
+
--project-dir current directory
|
|
24
|
+
|
|
25
|
+
Default destinations:
|
|
26
|
+
Codex global: ~/.codex/skills/codebase-ontology
|
|
27
|
+
Codex project: <project>/.codex/skills/codebase-ontology
|
|
28
|
+
Claude Code global: ~/.claude/skills/codebase-ontology
|
|
29
|
+
Claude Code project:<project>/.claude/skills/codebase-ontology
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
const opts = {
|
|
35
|
+
command: "help",
|
|
36
|
+
agent: "all",
|
|
37
|
+
scope: "global",
|
|
38
|
+
projectDir: process.cwd(),
|
|
39
|
+
targetDir: null,
|
|
40
|
+
dryRun: false,
|
|
41
|
+
force: false,
|
|
42
|
+
yes: false
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
if (argv.length > 0 && !argv[0].startsWith("-")) {
|
|
46
|
+
opts.command = argv.shift();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
50
|
+
const arg = argv[i];
|
|
51
|
+
switch (arg) {
|
|
52
|
+
case "--agent":
|
|
53
|
+
opts.agent = requireValue(argv, ++i, arg);
|
|
54
|
+
break;
|
|
55
|
+
case "--scope":
|
|
56
|
+
opts.scope = requireValue(argv, ++i, arg);
|
|
57
|
+
break;
|
|
58
|
+
case "--target-dir":
|
|
59
|
+
opts.targetDir = path.resolve(expandHome(requireValue(argv, ++i, arg)));
|
|
60
|
+
break;
|
|
61
|
+
case "--project-dir":
|
|
62
|
+
opts.projectDir = path.resolve(expandHome(requireValue(argv, ++i, arg)));
|
|
63
|
+
break;
|
|
64
|
+
case "--dry-run":
|
|
65
|
+
opts.dryRun = true;
|
|
66
|
+
break;
|
|
67
|
+
case "--force":
|
|
68
|
+
opts.force = true;
|
|
69
|
+
break;
|
|
70
|
+
case "--yes":
|
|
71
|
+
case "-y":
|
|
72
|
+
opts.yes = true;
|
|
73
|
+
break;
|
|
74
|
+
case "--help":
|
|
75
|
+
case "-h":
|
|
76
|
+
opts.command = "help";
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
fail(`Unknown option: ${arg}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!["help", "install", "uninstall", "doctor"].includes(opts.command)) {
|
|
84
|
+
fail(`Unknown command: ${opts.command}`);
|
|
85
|
+
}
|
|
86
|
+
if (!["codex", "claude", "all"].includes(opts.agent)) {
|
|
87
|
+
fail(`Invalid --agent: ${opts.agent}`);
|
|
88
|
+
}
|
|
89
|
+
if (!["global", "project"].includes(opts.scope)) {
|
|
90
|
+
fail(`Invalid --scope: ${opts.scope}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return opts;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function requireValue(argv, index, flag) {
|
|
97
|
+
const value = argv[index];
|
|
98
|
+
if (!value || value.startsWith("-")) {
|
|
99
|
+
fail(`${flag} requires a value`);
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function expandHome(p) {
|
|
105
|
+
if (p === "~") return os.homedir();
|
|
106
|
+
if (p.startsWith("~/")) return path.join(os.homedir(), p.slice(2));
|
|
107
|
+
return p;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function selectedAgents(agent) {
|
|
111
|
+
return agent === "all" ? ["codex", "claude"] : [agent];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function skillsRoot(agent, scope, projectDir) {
|
|
115
|
+
if (scope === "global") {
|
|
116
|
+
if (agent === "codex") return path.join(os.homedir(), ".codex", "skills");
|
|
117
|
+
if (agent === "claude") return path.join(os.homedir(), ".claude", "skills");
|
|
118
|
+
}
|
|
119
|
+
if (agent === "codex") return path.join(projectDir, ".codex", "skills");
|
|
120
|
+
if (agent === "claude") return path.join(projectDir, ".claude", "skills");
|
|
121
|
+
fail(`Unsupported agent: ${agent}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function destinations(opts) {
|
|
125
|
+
if (opts.targetDir) {
|
|
126
|
+
return [{ agent: "custom", root: opts.targetDir, dest: path.join(opts.targetDir, SKILL_NAME) }];
|
|
127
|
+
}
|
|
128
|
+
return selectedAgents(opts.agent).map((agent) => {
|
|
129
|
+
const root = skillsRoot(agent, opts.scope, opts.projectDir);
|
|
130
|
+
return { agent, root, dest: path.join(root, SKILL_NAME) };
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function install(opts) {
|
|
135
|
+
for (const target of destinations(opts)) {
|
|
136
|
+
console.log(`${opts.dryRun ? "[dry-run] " : ""}Install ${SKILL_NAME} -> ${target.dest}`);
|
|
137
|
+
if (opts.dryRun) continue;
|
|
138
|
+
|
|
139
|
+
if (fs.existsSync(target.dest)) {
|
|
140
|
+
if (!opts.force) {
|
|
141
|
+
console.log(` Exists; updating in place. Use --force to replace cleanly.`);
|
|
142
|
+
} else {
|
|
143
|
+
fs.rmSync(target.dest, { recursive: true, force: true });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fs.mkdirSync(target.dest, { recursive: true });
|
|
148
|
+
for (const entry of SKILL_ENTRIES) {
|
|
149
|
+
copyRecursive(path.join(PACKAGE_ROOT, entry), path.join(target.dest, entry));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function uninstall(opts) {
|
|
155
|
+
if (!opts.yes && !opts.dryRun) {
|
|
156
|
+
fail("Refusing to uninstall without --yes. Re-run with --yes or --dry-run.");
|
|
157
|
+
}
|
|
158
|
+
for (const target of destinations(opts)) {
|
|
159
|
+
console.log(`${opts.dryRun ? "[dry-run] " : ""}Remove ${target.dest}`);
|
|
160
|
+
if (!opts.dryRun) {
|
|
161
|
+
fs.rmSync(target.dest, { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function doctor(opts) {
|
|
167
|
+
console.log(`Package root: ${PACKAGE_ROOT}`);
|
|
168
|
+
for (const agent of ["codex", "claude"]) {
|
|
169
|
+
for (const scope of ["global", "project"]) {
|
|
170
|
+
const root = skillsRoot(agent, scope, opts.projectDir);
|
|
171
|
+
const dest = path.join(root, SKILL_NAME);
|
|
172
|
+
const status = fs.existsSync(path.join(dest, "SKILL.md")) ? "installed" : "missing";
|
|
173
|
+
console.log(`${agent.padEnd(6)} ${scope.padEnd(7)} ${status.padEnd(9)} ${dest}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function copyRecursive(src, dest) {
|
|
179
|
+
const stat = fs.statSync(src);
|
|
180
|
+
if (stat.isDirectory()) {
|
|
181
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
182
|
+
for (const child of fs.readdirSync(src)) {
|
|
183
|
+
copyRecursive(path.join(src, child), path.join(dest, child));
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
188
|
+
fs.copyFileSync(src, dest);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function fail(message) {
|
|
192
|
+
console.error(`Error: ${message}`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
197
|
+
|
|
198
|
+
if (opts.command === "help") {
|
|
199
|
+
usage();
|
|
200
|
+
} else if (opts.command === "install") {
|
|
201
|
+
install(opts);
|
|
202
|
+
} else if (opts.command === "uninstall") {
|
|
203
|
+
uninstall(opts);
|
|
204
|
+
} else if (opts.command === "doctor") {
|
|
205
|
+
doctor(opts);
|
|
206
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zhaiye/codebase-ontology",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent skill for generating codebase ontology YAML files.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"bin": {
|
|
8
|
+
"codebase-ontology": "bin/codebase-ontology.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"SKILL.md",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"agents",
|
|
15
|
+
"references",
|
|
16
|
+
"bin"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+ssh://git@github.com/zhaiyeact/codebase_ontology.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/zhaiyeact/codebase_ontology/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/zhaiyeact/codebase_ontology#readme",
|
|
26
|
+
"keywords": [
|
|
27
|
+
"agent",
|
|
28
|
+
"skill",
|
|
29
|
+
"ontology",
|
|
30
|
+
"codex",
|
|
31
|
+
"claude-code"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
# Ontology 输出结构参考
|
|
2
|
+
|
|
3
|
+
当使用 `codebase-ontology` skill 写入实际 `.ontology/` 文件时,读取本文件。
|
|
4
|
+
|
|
5
|
+
本文件只定义输出结构、模板和示例,不包含外部参考资料。
|
|
6
|
+
|
|
7
|
+
## 0. 输出语言要求
|
|
8
|
+
|
|
9
|
+
生成到目标 codebase `.ontology/` 下的 YAML 文件,内容语言必须为中文。
|
|
10
|
+
|
|
11
|
+
必须写成中文的值:
|
|
12
|
+
|
|
13
|
+
- `displayName`
|
|
14
|
+
- `description`
|
|
15
|
+
- `notes`
|
|
16
|
+
- `question`
|
|
17
|
+
- `suggestedResolution`
|
|
18
|
+
- `qualityChecks.*.notes`
|
|
19
|
+
- `guide.definition`
|
|
20
|
+
- object、property、link、action、function 的业务语义描述
|
|
21
|
+
- `.ontology/README.md` 中的人类可读内容
|
|
22
|
+
|
|
23
|
+
允许保持原文的值:
|
|
24
|
+
|
|
25
|
+
- YAML schema key。
|
|
26
|
+
- 稳定机器 ID。
|
|
27
|
+
- 代码路径和 symbol。
|
|
28
|
+
- API path。
|
|
29
|
+
- 数据库表名、列名和外键名。
|
|
30
|
+
- 代码中已有的枚举值、状态值和常量值。
|
|
31
|
+
- 第三方系统名称。
|
|
32
|
+
|
|
33
|
+
示例:`id: calculateOrderTotal` 可以保持英文,但 `displayName` 应写成 `计算订单总额`,`description` 应写成中文。
|
|
34
|
+
|
|
35
|
+
## 1. 目录结构
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
<codebase-root>/
|
|
39
|
+
.ontology/
|
|
40
|
+
README.md
|
|
41
|
+
index.yaml
|
|
42
|
+
object-types/
|
|
43
|
+
object-types.yaml
|
|
44
|
+
properties/
|
|
45
|
+
properties.yaml
|
|
46
|
+
link-types/
|
|
47
|
+
link-types.yaml
|
|
48
|
+
action-types/
|
|
49
|
+
action-types.yaml
|
|
50
|
+
functions/
|
|
51
|
+
functions.yaml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 2. index.yaml
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
metadata:
|
|
58
|
+
ontologyId: codebaseOntology
|
|
59
|
+
name: 代码库 Ontology
|
|
60
|
+
description: 从当前代码库抽取的业务 Ontology。
|
|
61
|
+
generatedAt: "YYYY-MM-DD"
|
|
62
|
+
generatedBy: "codex"
|
|
63
|
+
codebase:
|
|
64
|
+
name: ""
|
|
65
|
+
rootPath: ""
|
|
66
|
+
repositoryUrl: ""
|
|
67
|
+
commit: ""
|
|
68
|
+
scope:
|
|
69
|
+
includedPaths: []
|
|
70
|
+
excludedPaths: []
|
|
71
|
+
assumptions: []
|
|
72
|
+
|
|
73
|
+
files:
|
|
74
|
+
objectTypes: .ontology/object-types/object-types.yaml
|
|
75
|
+
properties: .ontology/properties/properties.yaml
|
|
76
|
+
linkTypes: .ontology/link-types/link-types.yaml
|
|
77
|
+
actionTypes: .ontology/action-types/action-types.yaml
|
|
78
|
+
functions: .ontology/functions/functions.yaml
|
|
79
|
+
|
|
80
|
+
summary:
|
|
81
|
+
domains: []
|
|
82
|
+
objectTypeCount: 0
|
|
83
|
+
propertyCount: 0
|
|
84
|
+
linkTypeCount: 0
|
|
85
|
+
actionTypeCount: 0
|
|
86
|
+
functionCount: 0
|
|
87
|
+
openQuestionCount: 0
|
|
88
|
+
|
|
89
|
+
qualityStatus:
|
|
90
|
+
passed: false
|
|
91
|
+
blockingIssues: []
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 3. 通用证据格式
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
sourceEvidence:
|
|
98
|
+
- id: evidenceId
|
|
99
|
+
kind: file | symbol | endpoint | database | test | documentation | inferred
|
|
100
|
+
path: string
|
|
101
|
+
symbol: string | null
|
|
102
|
+
lines: string | null
|
|
103
|
+
excerpt: string
|
|
104
|
+
notes: string
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
要求:
|
|
108
|
+
|
|
109
|
+
- `path` 使用相对 codebase 根目录的路径。
|
|
110
|
+
- `excerpt` 只放短片段。
|
|
111
|
+
- 推断内容使用 `kind: inferred`,并在 `notes` 解释依据。
|
|
112
|
+
|
|
113
|
+
## 4. object-types/object-types.yaml
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
metadata:
|
|
117
|
+
fileType: objectTypes
|
|
118
|
+
generatedAt: "YYYY-MM-DD"
|
|
119
|
+
codebaseRoot: ""
|
|
120
|
+
|
|
121
|
+
guide:
|
|
122
|
+
definition: Object Type 用于建模真实业务世界中的实体或事件。
|
|
123
|
+
|
|
124
|
+
items:
|
|
125
|
+
- id: objectTypeId
|
|
126
|
+
displayName: 对象类型名称
|
|
127
|
+
pluralDisplayName: 对象类型复数名称
|
|
128
|
+
category: entity | event | document | actor | configuration | metric
|
|
129
|
+
description: 该对象类型的业务含义。
|
|
130
|
+
aliases: []
|
|
131
|
+
domain: domainId
|
|
132
|
+
primaryKey: id
|
|
133
|
+
titleProperty: name
|
|
134
|
+
lifecycle:
|
|
135
|
+
states: []
|
|
136
|
+
stateProperty: null
|
|
137
|
+
createdByActions: []
|
|
138
|
+
modifiedByActions: []
|
|
139
|
+
deletedByActions: []
|
|
140
|
+
implements: []
|
|
141
|
+
properties:
|
|
142
|
+
- propertyId
|
|
143
|
+
links:
|
|
144
|
+
outgoing: []
|
|
145
|
+
incoming: []
|
|
146
|
+
actions: []
|
|
147
|
+
functions: []
|
|
148
|
+
excludedFields:
|
|
149
|
+
- field: ""
|
|
150
|
+
reason: ""
|
|
151
|
+
sourceEvidence: []
|
|
152
|
+
sourceEvidence: []
|
|
153
|
+
confidence: high | medium | low
|
|
154
|
+
|
|
155
|
+
sourceEvidence: []
|
|
156
|
+
openQuestions: []
|
|
157
|
+
qualityChecks:
|
|
158
|
+
objectTypesHavePrimaryKeys:
|
|
159
|
+
passed: false
|
|
160
|
+
notes: ""
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
示例:
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
items:
|
|
167
|
+
- id: order
|
|
168
|
+
displayName: 订单
|
|
169
|
+
pluralDisplayName: 订单
|
|
170
|
+
category: entity
|
|
171
|
+
description: 客户购买一个或多个商品时形成的商业请求。
|
|
172
|
+
aliases:
|
|
173
|
+
- OrderEntity
|
|
174
|
+
- orders
|
|
175
|
+
domain: ordering
|
|
176
|
+
primaryKey: orderId
|
|
177
|
+
titleProperty: orderNumber
|
|
178
|
+
lifecycle:
|
|
179
|
+
states:
|
|
180
|
+
- draft
|
|
181
|
+
- placed
|
|
182
|
+
- paid
|
|
183
|
+
- fulfilled
|
|
184
|
+
- cancelled
|
|
185
|
+
stateProperty: status
|
|
186
|
+
createdByActions:
|
|
187
|
+
- placeOrder
|
|
188
|
+
modifiedByActions:
|
|
189
|
+
- cancelOrder
|
|
190
|
+
- capturePayment
|
|
191
|
+
deletedByActions: []
|
|
192
|
+
implements:
|
|
193
|
+
- auditable
|
|
194
|
+
properties:
|
|
195
|
+
- orderId
|
|
196
|
+
- orderNumber
|
|
197
|
+
- status
|
|
198
|
+
- totalAmount
|
|
199
|
+
links:
|
|
200
|
+
outgoing:
|
|
201
|
+
- orderContainsOrderLine
|
|
202
|
+
- orderHasPayment
|
|
203
|
+
incoming:
|
|
204
|
+
- customerPlacesOrder
|
|
205
|
+
actions:
|
|
206
|
+
- placeOrder
|
|
207
|
+
- cancelOrder
|
|
208
|
+
- capturePayment
|
|
209
|
+
functions:
|
|
210
|
+
- calculateOrderTotal
|
|
211
|
+
- canCancelOrder
|
|
212
|
+
excludedFields:
|
|
213
|
+
- field: internalSyncVersion
|
|
214
|
+
reason: 仅用于实现层同步的字段,不属于业务属性。
|
|
215
|
+
sourceEvidence:
|
|
216
|
+
- orderEntity
|
|
217
|
+
sourceEvidence:
|
|
218
|
+
- orderEntity
|
|
219
|
+
- orderMigration
|
|
220
|
+
- orderStateTransitionTests
|
|
221
|
+
confidence: high
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 5. properties/properties.yaml
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
metadata:
|
|
228
|
+
fileType: properties
|
|
229
|
+
generatedAt: "YYYY-MM-DD"
|
|
230
|
+
codebaseRoot: ""
|
|
231
|
+
|
|
232
|
+
guide:
|
|
233
|
+
definition: Property 用于建模对象类型的业务特征。
|
|
234
|
+
|
|
235
|
+
items:
|
|
236
|
+
- id: propertyId
|
|
237
|
+
objectType: objectTypeId
|
|
238
|
+
displayName: 属性名称
|
|
239
|
+
description: 该属性的业务含义。
|
|
240
|
+
type: string | integer | long | decimal | float | double | boolean | date | timestamp | enum | array | object | struct | geoPoint | geoShape | attachment | mediaReference | timeSeries
|
|
241
|
+
required: false
|
|
242
|
+
nullable: true
|
|
243
|
+
unique: false
|
|
244
|
+
source: stored | derived | computed | external | writeback
|
|
245
|
+
sensitivity: public | internal | confidential | restricted
|
|
246
|
+
constraints: {}
|
|
247
|
+
derivation: null
|
|
248
|
+
sourceEvidence: []
|
|
249
|
+
confidence: high | medium | low
|
|
250
|
+
|
|
251
|
+
valueTypes: []
|
|
252
|
+
sharedProperties: []
|
|
253
|
+
sourceEvidence: []
|
|
254
|
+
openQuestions: []
|
|
255
|
+
qualityChecks:
|
|
256
|
+
propertiesHaveTypes:
|
|
257
|
+
passed: false
|
|
258
|
+
notes: ""
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
示例:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
items:
|
|
265
|
+
- id: status
|
|
266
|
+
objectType: order
|
|
267
|
+
displayName: 状态
|
|
268
|
+
description: 订单当前所处的生命周期状态。
|
|
269
|
+
type: enum
|
|
270
|
+
required: true
|
|
271
|
+
nullable: false
|
|
272
|
+
unique: false
|
|
273
|
+
source: stored
|
|
274
|
+
sensitivity: internal
|
|
275
|
+
constraints:
|
|
276
|
+
allowedValues:
|
|
277
|
+
- draft
|
|
278
|
+
- placed
|
|
279
|
+
- paid
|
|
280
|
+
- fulfilled
|
|
281
|
+
- cancelled
|
|
282
|
+
derivation: null
|
|
283
|
+
sourceEvidence:
|
|
284
|
+
- orderStatusEnum
|
|
285
|
+
- orderStateTransitionTests
|
|
286
|
+
confidence: high
|
|
287
|
+
|
|
288
|
+
- id: totalAmount
|
|
289
|
+
objectType: order
|
|
290
|
+
displayName: 订单总金额
|
|
291
|
+
description: 所有订单明细在折扣后的总金额。
|
|
292
|
+
type:
|
|
293
|
+
valueType: money
|
|
294
|
+
required: true
|
|
295
|
+
nullable: false
|
|
296
|
+
unique: false
|
|
297
|
+
source: derived
|
|
298
|
+
sensitivity: internal
|
|
299
|
+
constraints:
|
|
300
|
+
minimum: 0
|
|
301
|
+
derivation:
|
|
302
|
+
function: calculateOrderTotal
|
|
303
|
+
sourceEvidence:
|
|
304
|
+
- calculateOrderTotalFunction
|
|
305
|
+
confidence: high
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 6. link-types/link-types.yaml
|
|
309
|
+
|
|
310
|
+
```yaml
|
|
311
|
+
metadata:
|
|
312
|
+
fileType: linkTypes
|
|
313
|
+
generatedAt: "YYYY-MM-DD"
|
|
314
|
+
codebaseRoot: ""
|
|
315
|
+
|
|
316
|
+
guide:
|
|
317
|
+
definition: Link Type 用于建模对象类型之间的业务关系。
|
|
318
|
+
|
|
319
|
+
items:
|
|
320
|
+
- id: sourceRelatesToTarget
|
|
321
|
+
displayName: 源对象关联目标对象
|
|
322
|
+
description: 该关系的业务含义。
|
|
323
|
+
fromObjectType: sourceObject
|
|
324
|
+
toObjectType: targetObject
|
|
325
|
+
reverseDisplayName: 目标对象被源对象关联
|
|
326
|
+
cardinality: oneToOne | oneToMany | manyToOne | manyToMany
|
|
327
|
+
directionality: directed | bidirectional
|
|
328
|
+
required: false
|
|
329
|
+
properties: []
|
|
330
|
+
backing:
|
|
331
|
+
kind: foreignKey | joinTable | objectReference | eventReference | inferred
|
|
332
|
+
details: ""
|
|
333
|
+
sourceEvidence: []
|
|
334
|
+
confidence: high | medium | low
|
|
335
|
+
|
|
336
|
+
sourceEvidence: []
|
|
337
|
+
openQuestions: []
|
|
338
|
+
qualityChecks:
|
|
339
|
+
linksHaveCardinality:
|
|
340
|
+
passed: false
|
|
341
|
+
notes: ""
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
示例:
|
|
345
|
+
|
|
346
|
+
```yaml
|
|
347
|
+
items:
|
|
348
|
+
- id: customerPlacesOrder
|
|
349
|
+
displayName: 客户下订单
|
|
350
|
+
description: 一个客户创建或提交一个订单。
|
|
351
|
+
fromObjectType: customer
|
|
352
|
+
toObjectType: order
|
|
353
|
+
reverseDisplayName: 订单由客户提交
|
|
354
|
+
cardinality: oneToMany
|
|
355
|
+
directionality: directed
|
|
356
|
+
required: true
|
|
357
|
+
properties: []
|
|
358
|
+
backing:
|
|
359
|
+
kind: foreignKey
|
|
360
|
+
details: orders.customer_id references customers.id
|
|
361
|
+
sourceEvidence:
|
|
362
|
+
- orderMigration
|
|
363
|
+
- orderEntity
|
|
364
|
+
confidence: high
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## 7. action-types/action-types.yaml
|
|
368
|
+
|
|
369
|
+
```yaml
|
|
370
|
+
metadata:
|
|
371
|
+
fileType: actionTypes
|
|
372
|
+
generatedAt: "YYYY-MM-DD"
|
|
373
|
+
codebaseRoot: ""
|
|
374
|
+
|
|
375
|
+
guide:
|
|
376
|
+
definition: Action Type 用于建模会改变对象、属性或链接的业务操作。
|
|
377
|
+
|
|
378
|
+
items:
|
|
379
|
+
- id: performBusinessAction
|
|
380
|
+
displayName: 执行业务动作
|
|
381
|
+
description: 该动作的业务意图和结果。
|
|
382
|
+
actors:
|
|
383
|
+
- role: ""
|
|
384
|
+
description: ""
|
|
385
|
+
targets:
|
|
386
|
+
- objectType: objectTypeId
|
|
387
|
+
parameter: objectId
|
|
388
|
+
cardinality: single | set
|
|
389
|
+
inputParameters:
|
|
390
|
+
- id: objectId
|
|
391
|
+
displayName: 对象 ID
|
|
392
|
+
type: string
|
|
393
|
+
required: true
|
|
394
|
+
nullable: false
|
|
395
|
+
description: ""
|
|
396
|
+
constraints: {}
|
|
397
|
+
rules:
|
|
398
|
+
preconditions: []
|
|
399
|
+
validations: []
|
|
400
|
+
authorization: []
|
|
401
|
+
effects:
|
|
402
|
+
creates: []
|
|
403
|
+
updates: []
|
|
404
|
+
deletes: []
|
|
405
|
+
links: []
|
|
406
|
+
unlinks: []
|
|
407
|
+
sideEffects:
|
|
408
|
+
notifications: []
|
|
409
|
+
webhooks: []
|
|
410
|
+
externalCalls: []
|
|
411
|
+
scheduledJobs: []
|
|
412
|
+
reversible: false
|
|
413
|
+
usedFunctions: []
|
|
414
|
+
sourceEvidence: []
|
|
415
|
+
confidence: high | medium | low
|
|
416
|
+
|
|
417
|
+
sourceEvidence: []
|
|
418
|
+
openQuestions: []
|
|
419
|
+
qualityChecks:
|
|
420
|
+
actionsDescribeBusinessIntent:
|
|
421
|
+
passed: false
|
|
422
|
+
notes: ""
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
示例:
|
|
426
|
+
|
|
427
|
+
```yaml
|
|
428
|
+
items:
|
|
429
|
+
- id: cancelOrder
|
|
430
|
+
displayName: 取消订单
|
|
431
|
+
description: 取消一个尚未履约完成的订单。
|
|
432
|
+
actors:
|
|
433
|
+
- role: customer
|
|
434
|
+
description: 客户取消自己的订单。
|
|
435
|
+
- role: supportAgent
|
|
436
|
+
description: 客服人员代客户取消订单。
|
|
437
|
+
targets:
|
|
438
|
+
- objectType: order
|
|
439
|
+
parameter: orderId
|
|
440
|
+
cardinality: single
|
|
441
|
+
inputParameters:
|
|
442
|
+
- id: orderId
|
|
443
|
+
displayName: 订单 ID
|
|
444
|
+
type: string
|
|
445
|
+
required: true
|
|
446
|
+
nullable: false
|
|
447
|
+
description: 需要取消的订单。
|
|
448
|
+
constraints: {}
|
|
449
|
+
- id: reason
|
|
450
|
+
displayName: 取消原因
|
|
451
|
+
type: string
|
|
452
|
+
required: false
|
|
453
|
+
nullable: true
|
|
454
|
+
description: 可选的取消原因。
|
|
455
|
+
constraints:
|
|
456
|
+
maxLength: 500
|
|
457
|
+
rules:
|
|
458
|
+
preconditions:
|
|
459
|
+
- 订单状态必须是 draft、placed 或 paid。
|
|
460
|
+
validations:
|
|
461
|
+
- 已履约完成的订单不能取消。
|
|
462
|
+
authorization:
|
|
463
|
+
- 执行人必须拥有该订单,或具有 supportAgent 角色。
|
|
464
|
+
effects:
|
|
465
|
+
creates: []
|
|
466
|
+
updates:
|
|
467
|
+
- objectType: order
|
|
468
|
+
property: status
|
|
469
|
+
value: cancelled
|
|
470
|
+
deletes: []
|
|
471
|
+
links: []
|
|
472
|
+
unlinks: []
|
|
473
|
+
sideEffects:
|
|
474
|
+
notifications:
|
|
475
|
+
- 发送订单取消通知。
|
|
476
|
+
webhooks: []
|
|
477
|
+
externalCalls:
|
|
478
|
+
- 如果订单已收款,向支付供应商请求退款。
|
|
479
|
+
scheduledJobs: []
|
|
480
|
+
reversible: false
|
|
481
|
+
usedFunctions:
|
|
482
|
+
- canCancelOrder
|
|
483
|
+
sourceEvidence:
|
|
484
|
+
- cancelOrderEndpoint
|
|
485
|
+
- orderServiceCancelOrder
|
|
486
|
+
- orderStateTransitionTests
|
|
487
|
+
confidence: high
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## 8. functions/functions.yaml
|
|
491
|
+
|
|
492
|
+
```yaml
|
|
493
|
+
metadata:
|
|
494
|
+
fileType: functions
|
|
495
|
+
generatedAt: "YYYY-MM-DD"
|
|
496
|
+
codebaseRoot: ""
|
|
497
|
+
|
|
498
|
+
guide:
|
|
499
|
+
definition: Function 用于建模可复用的业务逻辑。
|
|
500
|
+
|
|
501
|
+
items:
|
|
502
|
+
- id: calculateBusinessValue
|
|
503
|
+
displayName: 计算业务值
|
|
504
|
+
description: 可复用的业务逻辑。
|
|
505
|
+
inputs:
|
|
506
|
+
- id: inputId
|
|
507
|
+
type: string
|
|
508
|
+
required: true
|
|
509
|
+
outputs:
|
|
510
|
+
type: string
|
|
511
|
+
description: ""
|
|
512
|
+
reads:
|
|
513
|
+
objectTypes: []
|
|
514
|
+
properties: []
|
|
515
|
+
linkTypes: []
|
|
516
|
+
writes:
|
|
517
|
+
objectTypes: []
|
|
518
|
+
properties: []
|
|
519
|
+
linkTypes: []
|
|
520
|
+
usedBy:
|
|
521
|
+
actionTypes: []
|
|
522
|
+
properties: []
|
|
523
|
+
endpoints: []
|
|
524
|
+
jobs: []
|
|
525
|
+
determinism: deterministic | timeDependent | userDependent | externalDependent
|
|
526
|
+
externalDependencies: []
|
|
527
|
+
errorCases: []
|
|
528
|
+
sourceEvidence: []
|
|
529
|
+
confidence: high | medium | low
|
|
530
|
+
|
|
531
|
+
sourceEvidence: []
|
|
532
|
+
openQuestions: []
|
|
533
|
+
qualityChecks:
|
|
534
|
+
functionsAreReusableBusinessLogic:
|
|
535
|
+
passed: false
|
|
536
|
+
notes: ""
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
示例:
|
|
540
|
+
|
|
541
|
+
```yaml
|
|
542
|
+
items:
|
|
543
|
+
- id: calculateOrderTotal
|
|
544
|
+
displayName: 计算订单总额
|
|
545
|
+
description: 根据订单明细计算订单总金额。
|
|
546
|
+
inputs:
|
|
547
|
+
- id: orderId
|
|
548
|
+
type: string
|
|
549
|
+
required: true
|
|
550
|
+
outputs:
|
|
551
|
+
type:
|
|
552
|
+
valueType: money
|
|
553
|
+
description: 该订单的总金额。
|
|
554
|
+
reads:
|
|
555
|
+
objectTypes:
|
|
556
|
+
- order
|
|
557
|
+
- orderLine
|
|
558
|
+
properties:
|
|
559
|
+
- orderLine.quantity
|
|
560
|
+
- orderLine.unitPrice
|
|
561
|
+
linkTypes:
|
|
562
|
+
- orderContainsOrderLine
|
|
563
|
+
writes:
|
|
564
|
+
objectTypes: []
|
|
565
|
+
properties: []
|
|
566
|
+
linkTypes: []
|
|
567
|
+
usedBy:
|
|
568
|
+
actionTypes:
|
|
569
|
+
- placeOrder
|
|
570
|
+
- capturePayment
|
|
571
|
+
properties:
|
|
572
|
+
- order.totalAmount
|
|
573
|
+
endpoints: []
|
|
574
|
+
jobs: []
|
|
575
|
+
determinism: deterministic
|
|
576
|
+
externalDependencies: []
|
|
577
|
+
errorCases:
|
|
578
|
+
- 当订单没有明细时返回校验错误。
|
|
579
|
+
sourceEvidence:
|
|
580
|
+
- calculateOrderTotalFunction
|
|
581
|
+
- orderTotalTests
|
|
582
|
+
confidence: high
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
## 9. README.md 摘要模板
|
|
586
|
+
|
|
587
|
+
```markdown
|
|
588
|
+
# 代码库 Ontology
|
|
589
|
+
|
|
590
|
+
生成时间:YYYY-MM-DD
|
|
591
|
+
代码库:<name>
|
|
592
|
+
|
|
593
|
+
## 摘要
|
|
594
|
+
|
|
595
|
+
- Object Types: N
|
|
596
|
+
- Properties: N
|
|
597
|
+
- Link Types: N
|
|
598
|
+
- Action Types: N
|
|
599
|
+
- Functions: N
|
|
600
|
+
- Open Questions: N
|
|
601
|
+
|
|
602
|
+
## 核心业务域
|
|
603
|
+
|
|
604
|
+
...
|
|
605
|
+
|
|
606
|
+
## 主要未决问题
|
|
607
|
+
|
|
608
|
+
...
|
|
609
|
+
```
|