@prd-improve/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/dist/anchor-slicer.d.ts +18 -0
- package/dist/anchor-slicer.js +114 -0
- package/dist/anchor-slicer.js.map +1 -0
- package/dist/api/client.d.ts +68 -0
- package/dist/api/client.js +175 -0
- package/dist/api/client.js.map +1 -0
- package/dist/changelog.d.ts +9 -0
- package/dist/changelog.js +34 -0
- package/dist/changelog.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +258 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/admin/_adminJson.d.ts +18 -0
- package/dist/commands/admin/_adminJson.js +27 -0
- package/dist/commands/admin/_adminJson.js.map +1 -0
- package/dist/commands/admin/_authResolve.d.ts +8 -0
- package/dist/commands/admin/_authResolve.js +56 -0
- package/dist/commands/admin/_authResolve.js.map +1 -0
- package/dist/commands/admin/index.d.ts +22 -0
- package/dist/commands/admin/index.js +100 -0
- package/dist/commands/admin/index.js.map +1 -0
- package/dist/commands/admin/io.d.ts +15 -0
- package/dist/commands/admin/io.js +30 -0
- package/dist/commands/admin/io.js.map +1 -0
- package/dist/commands/admin/member.d.ts +43 -0
- package/dist/commands/admin/member.js +362 -0
- package/dist/commands/admin/member.js.map +1 -0
- package/dist/commands/admin/project.d.ts +40 -0
- package/dist/commands/admin/project.js +182 -0
- package/dist/commands/admin/project.js.map +1 -0
- package/dist/commands/admin/team.d.ts +31 -0
- package/dist/commands/admin/team.js +157 -0
- package/dist/commands/admin/team.js.map +1 -0
- package/dist/commands/admin/teamMember.d.ts +33 -0
- package/dist/commands/admin/teamMember.js +262 -0
- package/dist/commands/admin/teamMember.js.map +1 -0
- package/dist/commands/admin/token.d.ts +29 -0
- package/dist/commands/admin/token.js +125 -0
- package/dist/commands/admin/token.js.map +1 -0
- package/dist/commands/admin/user.d.ts +2 -0
- package/dist/commands/admin/user.js +85 -0
- package/dist/commands/admin/user.js.map +1 -0
- package/dist/commands/config.d.ts +9 -0
- package/dist/commands/config.js +178 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/context.d.ts +11 -0
- package/dist/commands/context.js +235 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/diff.d.ts +6 -0
- package/dist/commands/diff.js +208 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/freeze.d.ts +10 -0
- package/dist/commands/freeze.js +269 -0
- package/dist/commands/freeze.js.map +1 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.js +229 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +26 -0
- package/dist/commands/login.js +241 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.js +75 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/migrate-yaml.d.ts +17 -0
- package/dist/commands/migrate-yaml.js +288 -0
- package/dist/commands/migrate-yaml.js.map +1 -0
- package/dist/commands/project.d.ts +7 -0
- package/dist/commands/project.js +87 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/pull.d.ts +16 -0
- package/dist/commands/pull.js +197 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +9 -0
- package/dist/commands/push.js +392 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/refresh.d.ts +9 -0
- package/dist/commands/refresh.js +123 -0
- package/dist/commands/refresh.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +190 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/team.d.ts +6 -0
- package/dist/commands/team.js +84 -0
- package/dist/commands/team.js.map +1 -0
- package/dist/commands/validate.d.ts +5 -0
- package/dist/commands/validate.js +129 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.js +81 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config/adminBackend.d.ts +43 -0
- package/dist/config/adminBackend.js +33 -0
- package/dist/config/adminBackend.js.map +1 -0
- package/dist/config/rc.d.ts +70 -0
- package/dist/config/rc.js +148 -0
- package/dist/config/rc.js.map +1 -0
- package/dist/config/schema.d.ts +132 -0
- package/dist/config/schema.js +36 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/diff/engine.d.ts +35 -0
- package/dist/diff/engine.js +305 -0
- package/dist/diff/engine.js.map +1 -0
- package/dist/diff/render.d.ts +18 -0
- package/dist/diff/render.js +129 -0
- package/dist/diff/render.js.map +1 -0
- package/dist/formatter/colors.d.ts +17 -0
- package/dist/formatter/colors.js +35 -0
- package/dist/formatter/colors.js.map +1 -0
- package/dist/formatter/human.d.ts +7 -0
- package/dist/formatter/human.js +70 -0
- package/dist/formatter/human.js.map +1 -0
- package/dist/fs/atomicWrite.d.ts +7 -0
- package/dist/fs/atomicWrite.js +37 -0
- package/dist/fs/atomicWrite.js.map +1 -0
- package/dist/i18n/dispatch.d.ts +19 -0
- package/dist/i18n/dispatch.js +27 -0
- package/dist/i18n/dispatch.js.map +1 -0
- package/dist/i18n/en.d.ts +3 -0
- package/dist/i18n/en.js +275 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/help.d.ts +3 -0
- package/dist/i18n/help.en.d.ts +149 -0
- package/dist/i18n/help.en.js +150 -0
- package/dist/i18n/help.en.js.map +1 -0
- package/dist/i18n/help.js +7 -0
- package/dist/i18n/help.js.map +1 -0
- package/dist/i18n/help.zh.d.ts +149 -0
- package/dist/i18n/help.zh.js +150 -0
- package/dist/i18n/help.zh.js.map +1 -0
- package/dist/i18n/helpFormat.d.ts +7 -0
- package/dist/i18n/helpFormat.js +51 -0
- package/dist/i18n/helpFormat.js.map +1 -0
- package/dist/i18n/helpGroups.d.ts +3 -0
- package/dist/i18n/helpGroups.js +11 -0
- package/dist/i18n/helpGroups.js.map +1 -0
- package/dist/i18n/index.d.ts +16 -0
- package/dist/i18n/index.js +46 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/peekLang.d.ts +1 -0
- package/dist/i18n/peekLang.js +16 -0
- package/dist/i18n/peekLang.js.map +1 -0
- package/dist/i18n/zh.d.ts +680 -0
- package/dist/i18n/zh.js +288 -0
- package/dist/i18n/zh.js.map +1 -0
- package/dist/parser/discover.d.ts +2 -0
- package/dist/parser/discover.js +69 -0
- package/dist/parser/discover.js.map +1 -0
- package/dist/parser/load-yaml.d.ts +11 -0
- package/dist/parser/load-yaml.js +25 -0
- package/dist/parser/load-yaml.js.map +1 -0
- package/dist/pkgVersion.d.ts +9 -0
- package/dist/pkgVersion.js +22 -0
- package/dist/pkgVersion.js.map +1 -0
- package/dist/renderer/context-md.d.ts +27 -0
- package/dist/renderer/context-md.js +444 -0
- package/dist/renderer/context-md.js.map +1 -0
- package/dist/renderer/refresh-md.d.ts +18 -0
- package/dist/renderer/refresh-md.js +93 -0
- package/dist/renderer/refresh-md.js.map +1 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/modules.d.ts +461 -0
- package/dist/schema/modules.js +184 -0
- package/dist/schema/modules.js.map +1 -0
- package/dist/schema/prd.d.ts +1018 -0
- package/dist/schema/prd.js +65 -0
- package/dist/schema/prd.js.map +1 -0
- package/dist/sync/cliRcHelpers.d.ts +25 -0
- package/dist/sync/cliRcHelpers.js +62 -0
- package/dist/sync/cliRcHelpers.js.map +1 -0
- package/dist/sync/conflicts.d.ts +7 -0
- package/dist/sync/conflicts.js +72 -0
- package/dist/sync/conflicts.js.map +1 -0
- package/dist/sync/headProbe.d.ts +1 -0
- package/dist/sync/headProbe.js +95 -0
- package/dist/sync/headProbe.js.map +1 -0
- package/dist/sync/normalize.d.ts +10 -0
- package/dist/sync/normalize.js +13 -0
- package/dist/sync/normalize.js.map +1 -0
- package/dist/sync/syncJson.d.ts +18 -0
- package/dist/sync/syncJson.js +42 -0
- package/dist/sync/syncJson.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/dist/validators/blocking.d.ts +2 -0
- package/dist/validators/blocking.js +25 -0
- package/dist/validators/blocking.js.map +1 -0
- package/dist/validators/duplicate-ids.d.ts +2 -0
- package/dist/validators/duplicate-ids.js +58 -0
- package/dist/validators/duplicate-ids.js.map +1 -0
- package/dist/validators/references.d.ts +5 -0
- package/dist/validators/references.js +165 -0
- package/dist/validators/references.js.map +1 -0
- package/dist/validators/required-modules.d.ts +8 -0
- package/dist/validators/required-modules.js +59 -0
- package/dist/validators/required-modules.js.map +1 -0
- package/dist/validators/runner.d.ts +11 -0
- package/dist/validators/runner.js +73 -0
- package/dist/validators/runner.js.map +1 -0
- package/dist/workspace.d.ts +32 -0
- package/dist/workspace.js +37 -0
- package/dist/workspace.js.map +1 -0
- package/dist/yaml-indexer.d.ts +15 -0
- package/dist/yaml-indexer.js +112 -0
- package/dist/yaml-indexer.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure function:把两份 PRD yaml AST 对比成结构化 DiffResult。
|
|
3
|
+
* 不读不写,可独立单测。
|
|
4
|
+
*
|
|
5
|
+
* 18 个 diffable 单元 = 14 个普通模块 + data_and_api 的 4 子组(DC/API/PC/SEC)。
|
|
6
|
+
* Summary 的 unchanged_modules 用 15 模块(parent)计数。
|
|
7
|
+
*/
|
|
8
|
+
// ---------- helpers ----------
|
|
9
|
+
function isEmpty(v) {
|
|
10
|
+
if (v === null || v === undefined)
|
|
11
|
+
return true;
|
|
12
|
+
if (typeof v === "string" && v === "")
|
|
13
|
+
return true;
|
|
14
|
+
if (Array.isArray(v) && v.length === 0)
|
|
15
|
+
return true;
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
function valueEqual(a, b) {
|
|
19
|
+
if (isEmpty(a) && isEmpty(b))
|
|
20
|
+
return true;
|
|
21
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
22
|
+
if (a.length !== b.length)
|
|
23
|
+
return false;
|
|
24
|
+
return a.every((v, i) => valueEqual(v, b[i]));
|
|
25
|
+
}
|
|
26
|
+
if (typeof a === "object" &&
|
|
27
|
+
a !== null &&
|
|
28
|
+
typeof b === "object" &&
|
|
29
|
+
b !== null) {
|
|
30
|
+
const ak = Object.keys(a).filter((k) => !isEmpty(a[k]));
|
|
31
|
+
const bk = Object.keys(b).filter((k) => !isEmpty(b[k]));
|
|
32
|
+
if (ak.length !== bk.length)
|
|
33
|
+
return false;
|
|
34
|
+
return ak.every((k) => valueEqual(a[k], b[k]));
|
|
35
|
+
}
|
|
36
|
+
return a === b;
|
|
37
|
+
}
|
|
38
|
+
function isMultiline(v) {
|
|
39
|
+
if (typeof v !== "string")
|
|
40
|
+
return false;
|
|
41
|
+
if (v.includes("\n"))
|
|
42
|
+
return true;
|
|
43
|
+
if (v.length > 80)
|
|
44
|
+
return true;
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function objectFieldChanges(before, after, fieldList) {
|
|
48
|
+
const changes = [];
|
|
49
|
+
for (const f of fieldList) {
|
|
50
|
+
const bv = before?.[f];
|
|
51
|
+
const av = after?.[f];
|
|
52
|
+
if (!valueEqual(bv, av)) {
|
|
53
|
+
changes.push({
|
|
54
|
+
field: f,
|
|
55
|
+
before: bv ?? null,
|
|
56
|
+
after: av ?? null,
|
|
57
|
+
is_multiline: isMultiline(bv) || isMultiline(av),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return changes;
|
|
62
|
+
}
|
|
63
|
+
function diffList(leftArr, rightArr, opts) {
|
|
64
|
+
const left = Array.isArray(leftArr) ? leftArr : [];
|
|
65
|
+
const right = Array.isArray(rightArr) ? rightArr : [];
|
|
66
|
+
const leftMap = new Map();
|
|
67
|
+
for (const item of left) {
|
|
68
|
+
const k = opts.primaryKeyOf(item);
|
|
69
|
+
if (k)
|
|
70
|
+
leftMap.set(k, item);
|
|
71
|
+
}
|
|
72
|
+
const rightMap = new Map();
|
|
73
|
+
for (const item of right) {
|
|
74
|
+
const k = opts.primaryKeyOf(item);
|
|
75
|
+
if (k)
|
|
76
|
+
rightMap.set(k, item);
|
|
77
|
+
}
|
|
78
|
+
const added = [];
|
|
79
|
+
const modified = [];
|
|
80
|
+
const removed = [];
|
|
81
|
+
for (const [k, rItem] of rightMap) {
|
|
82
|
+
if (!leftMap.has(k)) {
|
|
83
|
+
added.push({
|
|
84
|
+
primary_key: k,
|
|
85
|
+
display_label: opts.displayLabelOf?.(rItem),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const lItem = leftMap.get(k);
|
|
90
|
+
const fc = objectFieldChanges(lItem, rItem, opts.fieldList);
|
|
91
|
+
if (fc.length > 0) {
|
|
92
|
+
modified.push({
|
|
93
|
+
primary_key: k,
|
|
94
|
+
display_label: opts.displayLabelOf?.(rItem),
|
|
95
|
+
field_changes: fc,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const [k, lItem] of leftMap) {
|
|
101
|
+
if (!rightMap.has(k)) {
|
|
102
|
+
removed.push({
|
|
103
|
+
primary_key: k,
|
|
104
|
+
display_label: opts.displayLabelOf?.(lItem),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
module_key: opts.module_key,
|
|
110
|
+
module_label: opts.module_label,
|
|
111
|
+
added,
|
|
112
|
+
modified,
|
|
113
|
+
removed,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function diffObjectModule(left, right, module_key, module_label, fieldList) {
|
|
117
|
+
const fc = objectFieldChanges(left ?? {}, right ?? {}, fieldList);
|
|
118
|
+
const modified = fc.length > 0
|
|
119
|
+
? [{ primary_key: module_key, field_changes: fc }]
|
|
120
|
+
: [];
|
|
121
|
+
return {
|
|
122
|
+
module_key,
|
|
123
|
+
module_label,
|
|
124
|
+
added: [],
|
|
125
|
+
modified,
|
|
126
|
+
removed: [],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// ---------- 模块字段定义表 ----------
|
|
130
|
+
const META_FIELDS = [
|
|
131
|
+
"project",
|
|
132
|
+
"feature",
|
|
133
|
+
"title",
|
|
134
|
+
"summary",
|
|
135
|
+
"owner",
|
|
136
|
+
"tags",
|
|
137
|
+
"created_at",
|
|
138
|
+
"source_materials",
|
|
139
|
+
"lifecycle",
|
|
140
|
+
];
|
|
141
|
+
const BG_FIELDS = ["background", "goals"];
|
|
142
|
+
const ENTITY_FIELDS = ["name", "description", "fields", "relations", "lifecycle_states"];
|
|
143
|
+
const IN_SCOPE_FIELDS = ["name", "summary"];
|
|
144
|
+
const OOS_FIELDS = ["reason"];
|
|
145
|
+
const FLOW_FIELDS = ["actor", "trigger", "action", "outcome"];
|
|
146
|
+
const SP_FIELDS = ["allowed_actions", "notes"];
|
|
147
|
+
const RULE_FIELDS = ["rule", "rationale", "applies_to"];
|
|
148
|
+
const SCENARIO_FIELDS = ["condition", "expected_behavior", "input", "output", "refers_to"];
|
|
149
|
+
const EDGE_FIELDS = ["situation", "expected_behavior", "mitigation"];
|
|
150
|
+
const UI_FIELDS = [
|
|
151
|
+
"page",
|
|
152
|
+
"purpose",
|
|
153
|
+
"key_elements",
|
|
154
|
+
"user_actions",
|
|
155
|
+
"empty_state",
|
|
156
|
+
"loading_state",
|
|
157
|
+
"error_state",
|
|
158
|
+
];
|
|
159
|
+
const CONSTRAINT_FIELDS = ["text", "applies_to"];
|
|
160
|
+
const AC_FIELDS = ["criterion", "priority", "verification_method", "refers_to"];
|
|
161
|
+
const Q_FIELDS = ["question", "severity", "deferred_to", "owner", "due_date"];
|
|
162
|
+
const ROLE_FIELDS = ["description", "typical_goals"];
|
|
163
|
+
// ---------- 主入口 ----------
|
|
164
|
+
export function diffPRDs(left, right) {
|
|
165
|
+
const perModule = {};
|
|
166
|
+
perModule.meta = diffObjectModule(left?.meta, right?.meta, "meta", "版本信息", META_FIELDS);
|
|
167
|
+
perModule.background_and_goals = diffObjectModule(left?.background_and_goals, right?.background_and_goals, "background_and_goals", "背景与目标", BG_FIELDS);
|
|
168
|
+
perModule.users_and_roles = diffList(left?.users_and_roles, right?.users_and_roles, {
|
|
169
|
+
module_key: "users_and_roles",
|
|
170
|
+
module_label: "用户与角色",
|
|
171
|
+
primaryKeyOf: (u) => (typeof u?.role === "string" ? u.role : ""),
|
|
172
|
+
fieldList: ROLE_FIELDS,
|
|
173
|
+
});
|
|
174
|
+
perModule.in_scope = diffList(left?.in_scope, right?.in_scope, {
|
|
175
|
+
module_key: "in_scope",
|
|
176
|
+
module_label: "本期范围",
|
|
177
|
+
primaryKeyOf: (s) => (typeof s?.id === "string" ? s.id : ""),
|
|
178
|
+
displayLabelOf: (s) => s?.name,
|
|
179
|
+
fieldList: IN_SCOPE_FIELDS,
|
|
180
|
+
});
|
|
181
|
+
perModule.out_of_scope = diffList(left?.out_of_scope, right?.out_of_scope, {
|
|
182
|
+
module_key: "out_of_scope",
|
|
183
|
+
module_label: "明确不做",
|
|
184
|
+
primaryKeyOf: (o) => (typeof o?.item === "string" ? o.item : ""),
|
|
185
|
+
fieldList: OOS_FIELDS,
|
|
186
|
+
});
|
|
187
|
+
perModule.entities = diffList(left?.entities, right?.entities, {
|
|
188
|
+
module_key: "entities",
|
|
189
|
+
module_label: "核心实体",
|
|
190
|
+
primaryKeyOf: (e) => (typeof e?.id === "string" ? e.id : ""),
|
|
191
|
+
displayLabelOf: (e) => e?.name,
|
|
192
|
+
fieldList: ENTITY_FIELDS,
|
|
193
|
+
});
|
|
194
|
+
perModule.main_flow = diffList(left?.main_flow, right?.main_flow, {
|
|
195
|
+
module_key: "main_flow",
|
|
196
|
+
module_label: "主流程",
|
|
197
|
+
primaryKeyOf: (s) => (typeof s?.step === "number" ? `step-${s.step}` : ""),
|
|
198
|
+
fieldList: FLOW_FIELDS,
|
|
199
|
+
});
|
|
200
|
+
perModule.state_permissions = diffList(left?.state_permissions, right?.state_permissions, {
|
|
201
|
+
module_key: "state_permissions",
|
|
202
|
+
module_label: "状态与操作权限",
|
|
203
|
+
primaryKeyOf: (sp) => typeof sp?.entity_id === "string" && typeof sp?.state === "string"
|
|
204
|
+
? `${sp.entity_id} · ${sp.state}`
|
|
205
|
+
: "",
|
|
206
|
+
fieldList: SP_FIELDS,
|
|
207
|
+
});
|
|
208
|
+
perModule.business_rules = diffList(left?.business_rules, right?.business_rules, {
|
|
209
|
+
module_key: "business_rules",
|
|
210
|
+
module_label: "业务规则",
|
|
211
|
+
primaryKeyOf: (r) => (typeof r?.id === "string" ? r.id : ""),
|
|
212
|
+
fieldList: RULE_FIELDS,
|
|
213
|
+
});
|
|
214
|
+
perModule.scenarios = diffList(left?.scenarios, right?.scenarios, {
|
|
215
|
+
module_key: "scenarios",
|
|
216
|
+
module_label: "场景矩阵",
|
|
217
|
+
primaryKeyOf: (s) => (typeof s?.id === "string" ? s.id : ""),
|
|
218
|
+
fieldList: SCENARIO_FIELDS,
|
|
219
|
+
});
|
|
220
|
+
perModule.edge_cases = diffList(left?.edge_cases, right?.edge_cases, {
|
|
221
|
+
module_key: "edge_cases",
|
|
222
|
+
module_label: "异常与边界",
|
|
223
|
+
primaryKeyOf: (e) => (typeof e?.id === "string" ? e.id : ""),
|
|
224
|
+
displayLabelOf: (e) => e?.situation,
|
|
225
|
+
fieldList: EDGE_FIELDS,
|
|
226
|
+
});
|
|
227
|
+
perModule.ui_interaction = diffList(left?.ui_interaction, right?.ui_interaction, {
|
|
228
|
+
module_key: "ui_interaction",
|
|
229
|
+
module_label: "页面与交互",
|
|
230
|
+
primaryKeyOf: (u) => (typeof u?.id === "string" ? u.id : ""),
|
|
231
|
+
displayLabelOf: (u) => u?.page,
|
|
232
|
+
fieldList: UI_FIELDS,
|
|
233
|
+
});
|
|
234
|
+
// data_and_api: 4 subgroups merged into one ModuleDiff
|
|
235
|
+
const dArr = [
|
|
236
|
+
diffList(left?.data_and_api?.data_constraints, right?.data_and_api?.data_constraints, {
|
|
237
|
+
module_key: "data_and_api",
|
|
238
|
+
module_label: "数据与接口约束",
|
|
239
|
+
primaryKeyOf: (c) => (typeof c?.id === "string" ? c.id : ""),
|
|
240
|
+
fieldList: CONSTRAINT_FIELDS,
|
|
241
|
+
}),
|
|
242
|
+
diffList(left?.data_and_api?.api_constraints, right?.data_and_api?.api_constraints, {
|
|
243
|
+
module_key: "data_and_api",
|
|
244
|
+
module_label: "数据与接口约束",
|
|
245
|
+
primaryKeyOf: (c) => (typeof c?.id === "string" ? c.id : ""),
|
|
246
|
+
fieldList: CONSTRAINT_FIELDS,
|
|
247
|
+
}),
|
|
248
|
+
diffList(left?.data_and_api?.performance_constraints, right?.data_and_api?.performance_constraints, {
|
|
249
|
+
module_key: "data_and_api",
|
|
250
|
+
module_label: "数据与接口约束",
|
|
251
|
+
primaryKeyOf: (c) => (typeof c?.id === "string" ? c.id : ""),
|
|
252
|
+
fieldList: CONSTRAINT_FIELDS,
|
|
253
|
+
}),
|
|
254
|
+
diffList(left?.data_and_api?.security_constraints, right?.data_and_api?.security_constraints, {
|
|
255
|
+
module_key: "data_and_api",
|
|
256
|
+
module_label: "数据与接口约束",
|
|
257
|
+
primaryKeyOf: (c) => (typeof c?.id === "string" ? c.id : ""),
|
|
258
|
+
fieldList: CONSTRAINT_FIELDS,
|
|
259
|
+
}),
|
|
260
|
+
];
|
|
261
|
+
perModule.data_and_api = {
|
|
262
|
+
module_key: "data_and_api",
|
|
263
|
+
module_label: "数据与接口约束",
|
|
264
|
+
added: dArr.flatMap((m) => m.added),
|
|
265
|
+
modified: dArr.flatMap((m) => m.modified),
|
|
266
|
+
removed: dArr.flatMap((m) => m.removed),
|
|
267
|
+
};
|
|
268
|
+
perModule.acceptance_criteria = diffList(left?.acceptance_criteria, right?.acceptance_criteria, {
|
|
269
|
+
module_key: "acceptance_criteria",
|
|
270
|
+
module_label: "验收标准",
|
|
271
|
+
primaryKeyOf: (a) => (typeof a?.id === "string" ? a.id : ""),
|
|
272
|
+
displayLabelOf: (a) => a?.criterion,
|
|
273
|
+
fieldList: AC_FIELDS,
|
|
274
|
+
});
|
|
275
|
+
perModule.open_questions = diffList(left?.open_questions, right?.open_questions, {
|
|
276
|
+
module_key: "open_questions",
|
|
277
|
+
module_label: "待确认问题",
|
|
278
|
+
primaryKeyOf: (q) => (typeof q?.id === "string" ? q.id : ""),
|
|
279
|
+
displayLabelOf: (q) => q?.question,
|
|
280
|
+
fieldList: Q_FIELDS,
|
|
281
|
+
});
|
|
282
|
+
// totals
|
|
283
|
+
let added = 0;
|
|
284
|
+
let modified = 0;
|
|
285
|
+
let removed = 0;
|
|
286
|
+
let changed_module_count = 0;
|
|
287
|
+
for (const md of Object.values(perModule)) {
|
|
288
|
+
added += md.added.length;
|
|
289
|
+
modified += md.modified.length;
|
|
290
|
+
removed += md.removed.length;
|
|
291
|
+
if (md.added.length + md.modified.length + md.removed.length > 0) {
|
|
292
|
+
changed_module_count++;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
perModule,
|
|
297
|
+
totals: {
|
|
298
|
+
added,
|
|
299
|
+
modified,
|
|
300
|
+
removed,
|
|
301
|
+
unchanged_modules: 15 - changed_module_count,
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/diff/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DiffResult } from "./engine.js";
|
|
2
|
+
import { type Locale } from "../i18n/index.js";
|
|
3
|
+
export interface DiffMeta {
|
|
4
|
+
feature: string;
|
|
5
|
+
from: {
|
|
6
|
+
ref: string;
|
|
7
|
+
frozen_at?: string;
|
|
8
|
+
};
|
|
9
|
+
to: {
|
|
10
|
+
ref: string;
|
|
11
|
+
frozen_at?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface RenderOptions {
|
|
15
|
+
color: boolean;
|
|
16
|
+
locale: Locale;
|
|
17
|
+
}
|
|
18
|
+
export declare function renderDiff(result: DiffResult, meta: DiffMeta, opts: RenderOptions): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure function:把 DiffResult 渲染成 plain text(可选 ANSI 上色)。
|
|
3
|
+
* 不读不写,可独立单测。
|
|
4
|
+
*/
|
|
5
|
+
import { Chalk } from "chalk";
|
|
6
|
+
import { getMessages } from "../i18n/index.js";
|
|
7
|
+
const MODULE_ORDER = [
|
|
8
|
+
"meta",
|
|
9
|
+
"background_and_goals",
|
|
10
|
+
"users_and_roles",
|
|
11
|
+
"in_scope",
|
|
12
|
+
"out_of_scope",
|
|
13
|
+
"entities",
|
|
14
|
+
"main_flow",
|
|
15
|
+
"state_permissions",
|
|
16
|
+
"business_rules",
|
|
17
|
+
"scenarios",
|
|
18
|
+
"edge_cases",
|
|
19
|
+
"ui_interaction",
|
|
20
|
+
"data_and_api",
|
|
21
|
+
"acceptance_criteria",
|
|
22
|
+
"open_questions",
|
|
23
|
+
];
|
|
24
|
+
// Forced-color chalk instance (level 3 = truecolor); used when color=true
|
|
25
|
+
const colorChalk = new Chalk({ level: 3 });
|
|
26
|
+
function refLabel(r) {
|
|
27
|
+
if (r.ref === "working")
|
|
28
|
+
return "working";
|
|
29
|
+
if (r.frozen_at)
|
|
30
|
+
return `${r.ref} (frozen ${r.frozen_at.slice(0, 10)})`;
|
|
31
|
+
return r.ref;
|
|
32
|
+
}
|
|
33
|
+
function colorize(s, fn, on) {
|
|
34
|
+
return on ? fn(s) : s;
|
|
35
|
+
}
|
|
36
|
+
function stringifyValue(v) {
|
|
37
|
+
if (v === null || v === undefined)
|
|
38
|
+
return "(空)";
|
|
39
|
+
if (Array.isArray(v))
|
|
40
|
+
return "[" + v.map((x) => String(x)).join(", ") + "]";
|
|
41
|
+
if (typeof v === "object")
|
|
42
|
+
return JSON.stringify(v);
|
|
43
|
+
return String(v);
|
|
44
|
+
}
|
|
45
|
+
function renderFieldChange(fc, beforeLabel, afterLabel, color) {
|
|
46
|
+
if (!fc.is_multiline) {
|
|
47
|
+
const before = colorize(stringifyValue(fc.before), colorChalk.red.bind(colorChalk), color);
|
|
48
|
+
const after = colorize(stringifyValue(fc.after), colorChalk.green.bind(colorChalk), color);
|
|
49
|
+
return ` - ${fc.field}: ${before} → ${after}`;
|
|
50
|
+
}
|
|
51
|
+
const before = stringifyValue(fc.before);
|
|
52
|
+
const after = stringifyValue(fc.after);
|
|
53
|
+
return [
|
|
54
|
+
` - ${fc.field}:`,
|
|
55
|
+
` ${beforeLabel}:${colorize(before, colorChalk.red.bind(colorChalk), color)}`,
|
|
56
|
+
` ${afterLabel}:${colorize(after, colorChalk.green.bind(colorChalk), color)}`,
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
export function renderDiff(result, meta, opts) {
|
|
60
|
+
const m = getMessages(opts.locale);
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push(m.diff_header({ from: refLabel(meta.from), to: refLabel(meta.to) }));
|
|
63
|
+
lines.push(m.diff_summary({
|
|
64
|
+
added: result.totals.added,
|
|
65
|
+
modified: result.totals.modified,
|
|
66
|
+
removed: result.totals.removed,
|
|
67
|
+
unchanged: result.totals.unchanged_modules,
|
|
68
|
+
}));
|
|
69
|
+
lines.push("");
|
|
70
|
+
if (result.totals.added === 0 &&
|
|
71
|
+
result.totals.modified === 0 &&
|
|
72
|
+
result.totals.removed === 0) {
|
|
73
|
+
lines.push(m.diff_no_changes);
|
|
74
|
+
return lines.join("\n") + "\n";
|
|
75
|
+
}
|
|
76
|
+
if (result.totals.added > 0) {
|
|
77
|
+
lines.push(colorize(m.diff_section_added({ count: result.totals.added }), colorChalk.green.bind(colorChalk), opts.color));
|
|
78
|
+
for (const key of MODULE_ORDER) {
|
|
79
|
+
const md = result.perModule[key];
|
|
80
|
+
if (!md)
|
|
81
|
+
continue;
|
|
82
|
+
const sorted = [...md.added].sort((a, b) => a.primary_key.localeCompare(b.primary_key));
|
|
83
|
+
for (const item of sorted) {
|
|
84
|
+
const head = `[+] ${md.module_label} · ${item.primary_key}`;
|
|
85
|
+
const labeled = item.display_label && item.display_label !== item.primary_key
|
|
86
|
+
? `${head} — ${item.display_label}`
|
|
87
|
+
: head;
|
|
88
|
+
lines.push(colorize(labeled, colorChalk.green.bind(colorChalk), opts.color));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
lines.push("");
|
|
92
|
+
}
|
|
93
|
+
if (result.totals.modified > 0) {
|
|
94
|
+
lines.push(colorize(m.diff_section_modified({ count: result.totals.modified }), colorChalk.yellow.bind(colorChalk), opts.color));
|
|
95
|
+
for (const key of MODULE_ORDER) {
|
|
96
|
+
const md = result.perModule[key];
|
|
97
|
+
if (!md)
|
|
98
|
+
continue;
|
|
99
|
+
const sorted = [...md.modified].sort((a, b) => a.primary_key.localeCompare(b.primary_key));
|
|
100
|
+
for (const item of sorted) {
|
|
101
|
+
const head = `[~] ${md.module_label}${item.primary_key !== md.module_key ? ` · ${item.primary_key}` : ""}`;
|
|
102
|
+
lines.push(colorize(head, colorChalk.yellow.bind(colorChalk), opts.color));
|
|
103
|
+
for (const fc of item.field_changes ?? []) {
|
|
104
|
+
lines.push(renderFieldChange(fc, m.diff_before_label, m.diff_after_label, opts.color));
|
|
105
|
+
}
|
|
106
|
+
lines.push("");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (result.totals.removed > 0) {
|
|
111
|
+
lines.push(colorize(m.diff_section_removed({ count: result.totals.removed }), colorChalk.red.bind(colorChalk), opts.color));
|
|
112
|
+
for (const key of MODULE_ORDER) {
|
|
113
|
+
const md = result.perModule[key];
|
|
114
|
+
if (!md)
|
|
115
|
+
continue;
|
|
116
|
+
const sorted = [...md.removed].sort((a, b) => a.primary_key.localeCompare(b.primary_key));
|
|
117
|
+
for (const item of sorted) {
|
|
118
|
+
const head = `[-] ${md.module_label} · ${item.primary_key}`;
|
|
119
|
+
const labeled = item.display_label && item.display_label !== item.primary_key
|
|
120
|
+
? `${head} — ${item.display_label}`
|
|
121
|
+
: head;
|
|
122
|
+
lines.push(colorize(labeled, colorChalk.red.bind(colorChalk), opts.color));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
lines.push("");
|
|
126
|
+
}
|
|
127
|
+
return lines.join("\n").trimEnd() + "\n";
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/diff/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 是否启用颜色:
|
|
3
|
+
* - NO_COLOR=1 → 禁用
|
|
4
|
+
* - 非 TTY → 禁用
|
|
5
|
+
* - 否则启用
|
|
6
|
+
*/
|
|
7
|
+
export declare function colorEnabled(): boolean;
|
|
8
|
+
export declare function pass(s: string): string;
|
|
9
|
+
export declare function fail(s: string): string;
|
|
10
|
+
export declare function skip(s: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Semantic alias for `skip` — yellow text used to flag warnings (e.g. sync
|
|
13
|
+
* drift, backend unreachable) that don't change exit code. Aliased rather
|
|
14
|
+
* than duplicated so the existing "[SKIP] = yellow" convention stays intact.
|
|
15
|
+
*/
|
|
16
|
+
export declare function warn(s: string): string;
|
|
17
|
+
export declare function dim(s: string): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
/**
|
|
3
|
+
* 是否启用颜色:
|
|
4
|
+
* - NO_COLOR=1 → 禁用
|
|
5
|
+
* - 非 TTY → 禁用
|
|
6
|
+
* - 否则启用
|
|
7
|
+
*/
|
|
8
|
+
export function colorEnabled() {
|
|
9
|
+
if (process.env.NO_COLOR)
|
|
10
|
+
return false;
|
|
11
|
+
if (!process.stdout.isTTY)
|
|
12
|
+
return false;
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
export function pass(s) {
|
|
16
|
+
return colorEnabled() ? chalk.green(s) : s;
|
|
17
|
+
}
|
|
18
|
+
export function fail(s) {
|
|
19
|
+
return colorEnabled() ? chalk.red(s) : s;
|
|
20
|
+
}
|
|
21
|
+
export function skip(s) {
|
|
22
|
+
return colorEnabled() ? chalk.yellow(s) : s;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Semantic alias for `skip` — yellow text used to flag warnings (e.g. sync
|
|
26
|
+
* drift, backend unreachable) that don't change exit code. Aliased rather
|
|
27
|
+
* than duplicated so the existing "[SKIP] = yellow" convention stays intact.
|
|
28
|
+
*/
|
|
29
|
+
export function warn(s) {
|
|
30
|
+
return colorEnabled() ? chalk.yellow(s) : s;
|
|
31
|
+
}
|
|
32
|
+
export function dim(s) {
|
|
33
|
+
return colorEnabled() ? chalk.dim(s) : s;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/formatter/colors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,CAAS;IAC3B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Locale } from "../i18n/index.js";
|
|
2
|
+
import type { ValidationResult } from "../types.js";
|
|
3
|
+
interface FormatOptions {
|
|
4
|
+
pattern: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function formatHuman(result: ValidationResult, locale: Locale, opts: FormatOptions): string;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getMessages } from "../i18n/index.js";
|
|
2
|
+
import * as c from "./colors.js";
|
|
3
|
+
export function formatHuman(result, locale, opts) {
|
|
4
|
+
const m = getMessages(locale);
|
|
5
|
+
const lines = [];
|
|
6
|
+
// header
|
|
7
|
+
lines.push(m.validating({ pattern: opts.pattern }));
|
|
8
|
+
lines.push("");
|
|
9
|
+
for (const r of result.results) {
|
|
10
|
+
lines.push(...renderFeature(r, m));
|
|
11
|
+
lines.push("");
|
|
12
|
+
}
|
|
13
|
+
lines.push(m.summary_line({
|
|
14
|
+
passed: result.summary.passed,
|
|
15
|
+
failed: result.summary.failed,
|
|
16
|
+
skipped: result.summary.skipped,
|
|
17
|
+
}));
|
|
18
|
+
lines.push(m.exit_code_line({ code: result.exitCode }));
|
|
19
|
+
return lines.join("\n");
|
|
20
|
+
}
|
|
21
|
+
function renderIssueText(issue, m) {
|
|
22
|
+
// Dynamic lookup by issue code — escape hatch for string-keyed dispatch
|
|
23
|
+
const renderer = m[issue.code];
|
|
24
|
+
if (typeof renderer === "function")
|
|
25
|
+
return renderer(issue.details);
|
|
26
|
+
if (typeof renderer === "string")
|
|
27
|
+
return renderer;
|
|
28
|
+
return `[${issue.code}] ${JSON.stringify(issue.details)}`;
|
|
29
|
+
}
|
|
30
|
+
function renderFeature(r, m) {
|
|
31
|
+
const lines = [];
|
|
32
|
+
const warnings = r.issues.filter((i) => i.severity === "warning");
|
|
33
|
+
if (r.status === "pass") {
|
|
34
|
+
lines.push(`${c.pass(m.status_pass)} ${r.feature}`);
|
|
35
|
+
lines.push(" " +
|
|
36
|
+
m.feature_pass_summary({
|
|
37
|
+
complete: r.modulesComplete,
|
|
38
|
+
total: r.modulesTotal,
|
|
39
|
+
schema_version: r.schemaVersion || "?",
|
|
40
|
+
}));
|
|
41
|
+
for (const w of warnings) {
|
|
42
|
+
lines.push(" ! " + renderIssueText(w, m));
|
|
43
|
+
}
|
|
44
|
+
return lines;
|
|
45
|
+
}
|
|
46
|
+
if (r.status === "skip") {
|
|
47
|
+
lines.push(`${c.skip(m.status_skip)} ${r.feature}`);
|
|
48
|
+
lines.push(" " + m.feature_skip_reason_no_yaml);
|
|
49
|
+
return lines;
|
|
50
|
+
}
|
|
51
|
+
// fail
|
|
52
|
+
const refs = r.issues.filter((i) => i.code === "reference_not_found" || i.code === "reference_wrong_type").length;
|
|
53
|
+
const blocks = r.issues.filter((i) => i.code === "blocking_question").length;
|
|
54
|
+
lines.push(`${c.fail(m.status_fail)} ${r.feature}`);
|
|
55
|
+
lines.push(" " +
|
|
56
|
+
m.feature_fail_summary({
|
|
57
|
+
complete: r.modulesComplete,
|
|
58
|
+
total: r.modulesTotal,
|
|
59
|
+
refs,
|
|
60
|
+
blocks,
|
|
61
|
+
}));
|
|
62
|
+
for (const issue of r.issues) {
|
|
63
|
+
if (issue.severity === "info")
|
|
64
|
+
continue;
|
|
65
|
+
const prefix = issue.severity === "warning" ? "! " : "- ";
|
|
66
|
+
lines.push(" " + prefix + renderIssueText(issue, m));
|
|
67
|
+
}
|
|
68
|
+
return lines;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=human.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"human.js","sourceRoot":"","sources":["../../src/formatter/human.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface AtomicWriteOptions {
|
|
2
|
+
/** Posix permission mode applied via chmod after write. Optional. */
|
|
3
|
+
mode?: number;
|
|
4
|
+
/** Text encoding. Defaults to utf8. */
|
|
5
|
+
encoding?: BufferEncoding;
|
|
6
|
+
}
|
|
7
|
+
export declare function writeFileAtomic(path: string, data: string, opts?: AtomicWriteOptions): void;
|