@aipper/aiws 0.0.29 → 0.0.30

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 (278) hide show
  1. package/bin/aiws.js +2 -2
  2. package/dist/aiws-package.d.ts +4 -0
  3. package/dist/aiws-package.js +11 -0
  4. package/dist/aiws-package.js.map +1 -0
  5. package/dist/aiws-paths.d.ts +48 -0
  6. package/dist/aiws-paths.js +129 -0
  7. package/dist/aiws-paths.js.map +1 -0
  8. package/dist/backup.d.ts +27 -0
  9. package/dist/backup.js +125 -0
  10. package/dist/backup.js.map +1 -0
  11. package/dist/cli.d.ts +1 -0
  12. package/dist/cli.js +773 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/codex-prompts.d.ts +17 -0
  15. package/dist/codex-prompts.js +49 -0
  16. package/dist/codex-prompts.js.map +1 -0
  17. package/dist/codex-skills.d.ts +17 -0
  18. package/dist/codex-skills.js +75 -0
  19. package/dist/codex-skills.js.map +1 -0
  20. package/dist/commands/change-advice.d.ts +25 -0
  21. package/dist/commands/change-advice.js +197 -0
  22. package/dist/commands/change-advice.js.map +1 -0
  23. package/dist/commands/change-evidence-command.d.ts +29 -0
  24. package/dist/commands/change-evidence-command.js +213 -0
  25. package/dist/commands/change-evidence-command.js.map +1 -0
  26. package/dist/commands/change-evidence-entry.d.ts +16 -0
  27. package/dist/commands/change-evidence-entry.js +35 -0
  28. package/dist/commands/change-evidence-entry.js.map +1 -0
  29. package/dist/commands/change-evidence.d.ts +108 -0
  30. package/dist/commands/change-evidence.js +341 -0
  31. package/dist/commands/change-evidence.js.map +1 -0
  32. package/dist/commands/change-finish.d.ts +71 -0
  33. package/dist/commands/change-finish.js +387 -0
  34. package/dist/commands/change-finish.js.map +1 -0
  35. package/dist/commands/change-git-status.d.ts +22 -0
  36. package/dist/commands/change-git-status.js +50 -0
  37. package/dist/commands/change-git-status.js.map +1 -0
  38. package/dist/commands/change-lifecycle-entry.d.ts +29 -0
  39. package/{src → dist}/commands/change-lifecycle-entry.js +21 -28
  40. package/dist/commands/change-lifecycle-entry.js.map +1 -0
  41. package/dist/commands/change-lifecycle.d.ts +56 -0
  42. package/dist/commands/change-lifecycle.js +211 -0
  43. package/dist/commands/change-lifecycle.js.map +1 -0
  44. package/dist/commands/change-metrics-command.d.ts +12 -0
  45. package/dist/commands/change-metrics-command.js +110 -0
  46. package/dist/commands/change-metrics-command.js.map +1 -0
  47. package/dist/commands/change-next-command.d.ts +18 -0
  48. package/dist/commands/change-next-command.js +138 -0
  49. package/dist/commands/change-next-command.js.map +1 -0
  50. package/dist/commands/change-review-gates.d.ts +107 -0
  51. package/dist/commands/change-review-gates.js +329 -0
  52. package/dist/commands/change-review-gates.js.map +1 -0
  53. package/dist/commands/change-scope-gate.d.ts +21 -0
  54. package/dist/commands/change-scope-gate.js +32 -0
  55. package/dist/commands/change-scope-gate.js.map +1 -0
  56. package/dist/commands/change-start.d.ts +30 -0
  57. package/dist/commands/change-start.js +91 -0
  58. package/dist/commands/change-start.js.map +1 -0
  59. package/dist/commands/change-state-command.d.ts +3 -0
  60. package/dist/commands/change-state-command.js +32 -0
  61. package/dist/commands/change-state-command.js.map +1 -0
  62. package/dist/commands/change-status-command.d.ts +13 -0
  63. package/dist/commands/change-status-command.js +126 -0
  64. package/dist/commands/change-status-command.js.map +1 -0
  65. package/dist/commands/change-status-context.d.ts +58 -0
  66. package/dist/commands/change-status-context.js +166 -0
  67. package/dist/commands/change-status-context.js.map +1 -0
  68. package/dist/commands/change-task-stats.d.ts +24 -0
  69. package/dist/commands/change-task-stats.js +66 -0
  70. package/dist/commands/change-task-stats.js.map +1 -0
  71. package/dist/commands/change-validate-entry.d.ts +17 -0
  72. package/dist/commands/change-validate-entry.js +44 -0
  73. package/dist/commands/change-validate-entry.js.map +1 -0
  74. package/dist/commands/change-validate.d.ts +32 -0
  75. package/dist/commands/change-validate.js +128 -0
  76. package/dist/commands/change-validate.js.map +1 -0
  77. package/dist/commands/change.d.ts +322 -0
  78. package/dist/commands/change.js +1731 -0
  79. package/dist/commands/change.js.map +1 -0
  80. package/dist/commands/codex-install-prompts.d.ts +4 -0
  81. package/dist/commands/codex-install-prompts.js +68 -0
  82. package/dist/commands/codex-install-prompts.js.map +1 -0
  83. package/dist/commands/codex-install-skills.d.ts +4 -0
  84. package/dist/commands/codex-install-skills.js +74 -0
  85. package/dist/commands/codex-install-skills.js.map +1 -0
  86. package/dist/commands/codex-status-prompts.d.ts +4 -0
  87. package/dist/commands/codex-status-prompts.js +44 -0
  88. package/dist/commands/codex-status-prompts.js.map +1 -0
  89. package/dist/commands/codex-status-skills.d.ts +4 -0
  90. package/dist/commands/codex-status-skills.js +54 -0
  91. package/dist/commands/codex-status-skills.js.map +1 -0
  92. package/dist/commands/codex-uninstall-prompts.d.ts +4 -0
  93. package/dist/commands/codex-uninstall-prompts.js +51 -0
  94. package/dist/commands/codex-uninstall-prompts.js.map +1 -0
  95. package/dist/commands/codex-uninstall-skills.d.ts +4 -0
  96. package/dist/commands/codex-uninstall-skills.js +59 -0
  97. package/dist/commands/codex-uninstall-skills.js.map +1 -0
  98. package/dist/commands/dashboard.d.ts +222 -0
  99. package/dist/commands/dashboard.js +193 -0
  100. package/dist/commands/dashboard.js.map +1 -0
  101. package/dist/commands/hooks-install.d.ts +4 -0
  102. package/dist/commands/hooks-install.js +90 -0
  103. package/dist/commands/hooks-install.js.map +1 -0
  104. package/dist/commands/hooks-status.d.ts +4 -0
  105. package/dist/commands/hooks-status.js +89 -0
  106. package/dist/commands/hooks-status.js.map +1 -0
  107. package/dist/commands/init.d.ts +4 -0
  108. package/dist/commands/init.js +100 -0
  109. package/dist/commands/init.js.map +1 -0
  110. package/dist/commands/opencode-auto.d.ts +11 -0
  111. package/dist/commands/opencode-auto.js +158 -0
  112. package/dist/commands/opencode-auto.js.map +1 -0
  113. package/dist/commands/opencode-status.d.ts +4 -0
  114. package/dist/commands/opencode-status.js +75 -0
  115. package/dist/commands/opencode-status.js.map +1 -0
  116. package/dist/commands/opencode-supervise.d.ts +24 -0
  117. package/dist/commands/opencode-supervise.js +188 -0
  118. package/dist/commands/opencode-supervise.js.map +1 -0
  119. package/dist/commands/rollback.d.ts +4 -0
  120. package/dist/commands/rollback.js +12 -0
  121. package/dist/commands/rollback.js.map +1 -0
  122. package/dist/commands/update.d.ts +4 -0
  123. package/dist/commands/update.js +212 -0
  124. package/dist/commands/update.js.map +1 -0
  125. package/dist/commands/validate.d.ts +4 -0
  126. package/dist/commands/validate.js +222 -0
  127. package/dist/commands/validate.js.map +1 -0
  128. package/dist/commands/ws-commit.d.ts +5 -0
  129. package/dist/commands/ws-commit.js +39 -0
  130. package/dist/commands/ws-commit.js.map +1 -0
  131. package/dist/commands/ws-deliver.d.ts +5 -0
  132. package/dist/commands/ws-deliver.js +59 -0
  133. package/dist/commands/ws-deliver.js.map +1 -0
  134. package/dist/commands/ws-finish.d.ts +5 -0
  135. package/dist/commands/ws-finish.js +142 -0
  136. package/dist/commands/ws-finish.js.map +1 -0
  137. package/dist/commands/ws-handoff.d.ts +5 -0
  138. package/dist/commands/ws-handoff.js +35 -0
  139. package/dist/commands/ws-handoff.js.map +1 -0
  140. package/dist/commands/ws-migrate.d.ts +5 -0
  141. package/dist/commands/ws-migrate.js +41 -0
  142. package/dist/commands/ws-migrate.js.map +1 -0
  143. package/dist/commands/ws-plan-verify.d.ts +5 -0
  144. package/dist/commands/ws-plan-verify.js +38 -0
  145. package/dist/commands/ws-plan-verify.js.map +1 -0
  146. package/dist/commands/ws-pull.d.ts +5 -0
  147. package/dist/commands/ws-pull.js +26 -0
  148. package/dist/commands/ws-pull.js.map +1 -0
  149. package/dist/commands/ws-push.d.ts +5 -0
  150. package/dist/commands/ws-push.js +68 -0
  151. package/dist/commands/ws-push.js.map +1 -0
  152. package/dist/commands/ws-submodule-setup.d.ts +5 -0
  153. package/dist/commands/ws-submodule-setup.js +55 -0
  154. package/dist/commands/ws-submodule-setup.js.map +1 -0
  155. package/dist/commands/ws-verify-before-complete.d.ts +5 -0
  156. package/dist/commands/ws-verify-before-complete.js +35 -0
  157. package/dist/commands/ws-verify-before-complete.js.map +1 -0
  158. package/dist/dashboard/app.d.ts +1 -0
  159. package/dist/dashboard/app.js +370 -0
  160. package/dist/dashboard/app.js.map +1 -0
  161. package/dist/delegation/cli.d.ts +6 -0
  162. package/dist/delegation/cli.js +14 -0
  163. package/dist/delegation/cli.js.map +1 -0
  164. package/dist/delegation/index.d.ts +35 -0
  165. package/dist/delegation/index.js +118 -0
  166. package/dist/delegation/index.js.map +1 -0
  167. package/dist/errors.d.ts +8 -0
  168. package/dist/errors.js +11 -0
  169. package/dist/errors.js.map +1 -0
  170. package/dist/exec.d.ts +9 -0
  171. package/dist/exec.js +22 -0
  172. package/dist/exec.js.map +1 -0
  173. package/dist/fs.d.ts +9 -0
  174. package/dist/fs.js +62 -0
  175. package/dist/fs.js.map +1 -0
  176. package/dist/governance.d.ts +10 -0
  177. package/dist/governance.js +135 -0
  178. package/dist/governance.js.map +1 -0
  179. package/dist/hash.d.ts +3 -0
  180. package/dist/hash.js +13 -0
  181. package/dist/hash.js.map +1 -0
  182. package/dist/hooks/deploy-claude.d.ts +13 -0
  183. package/dist/hooks/deploy-claude.js +67 -0
  184. package/dist/hooks/deploy-claude.js.map +1 -0
  185. package/dist/journal.d.ts +22 -0
  186. package/dist/journal.js +112 -0
  187. package/dist/journal.js.map +1 -0
  188. package/dist/json-schema-lite.d.ts +22 -0
  189. package/dist/json-schema-lite.js +148 -0
  190. package/dist/json-schema-lite.js.map +1 -0
  191. package/dist/managed-blocks.d.ts +24 -0
  192. package/dist/managed-blocks.js +84 -0
  193. package/dist/managed-blocks.js.map +1 -0
  194. package/dist/manifest.d.ts +24 -0
  195. package/dist/manifest.js +145 -0
  196. package/dist/manifest.js.map +1 -0
  197. package/dist/opencode-env.d.ts +62 -0
  198. package/dist/opencode-env.js +178 -0
  199. package/dist/opencode-env.js.map +1 -0
  200. package/dist/path-utils.d.ts +2 -0
  201. package/dist/path-utils.js +8 -0
  202. package/dist/path-utils.js.map +1 -0
  203. package/dist/spec.d.ts +17 -0
  204. package/dist/spec.js +174 -0
  205. package/dist/spec.js.map +1 -0
  206. package/dist/template.d.ts +20 -0
  207. package/dist/template.js +123 -0
  208. package/dist/template.js.map +1 -0
  209. package/dist/workspace.d.ts +4 -0
  210. package/dist/workspace.js +19 -0
  211. package/dist/workspace.js.map +1 -0
  212. package/package.json +11 -3
  213. package/src/aiws-package.js +0 -15
  214. package/src/backup.js +0 -149
  215. package/src/cli.js +0 -760
  216. package/src/codex-prompts.js +0 -74
  217. package/src/codex-skills.js +0 -111
  218. package/src/commands/change-advice.js +0 -181
  219. package/src/commands/change-evidence-command.js +0 -242
  220. package/src/commands/change-evidence-entry.js +0 -40
  221. package/src/commands/change-evidence.js +0 -340
  222. package/src/commands/change-finish.js +0 -413
  223. package/src/commands/change-git-status.js +0 -53
  224. package/src/commands/change-lifecycle.js +0 -236
  225. package/src/commands/change-metrics-command.js +0 -110
  226. package/src/commands/change-next-command.js +0 -133
  227. package/src/commands/change-review-gates.js +0 -331
  228. package/src/commands/change-scope-gate.js +0 -34
  229. package/src/commands/change-start.js +0 -85
  230. package/src/commands/change-state-command.js +0 -40
  231. package/src/commands/change-status-command.js +0 -125
  232. package/src/commands/change-status-context.js +0 -173
  233. package/src/commands/change-task-stats.js +0 -64
  234. package/src/commands/change-validate-entry.js +0 -45
  235. package/src/commands/change-validate.js +0 -127
  236. package/src/commands/change.js +0 -1829
  237. package/src/commands/codex-install-prompts.js +0 -68
  238. package/src/commands/codex-install-skills.js +0 -74
  239. package/src/commands/codex-status-prompts.js +0 -55
  240. package/src/commands/codex-status-skills.js +0 -63
  241. package/src/commands/codex-uninstall-prompts.js +0 -55
  242. package/src/commands/codex-uninstall-skills.js +0 -62
  243. package/src/commands/dashboard.js +0 -205
  244. package/src/commands/hooks-install.js +0 -92
  245. package/src/commands/hooks-status.js +0 -95
  246. package/src/commands/init.js +0 -101
  247. package/src/commands/opencode-auto.js +0 -167
  248. package/src/commands/opencode-status.js +0 -103
  249. package/src/commands/opencode-supervise.js +0 -200
  250. package/src/commands/rollback.js +0 -13
  251. package/src/commands/update.js +0 -145
  252. package/src/commands/validate.js +0 -228
  253. package/src/commands/ws-commit.js +0 -44
  254. package/src/commands/ws-deliver.js +0 -67
  255. package/src/commands/ws-finish.js +0 -83
  256. package/src/commands/ws-handoff.js +0 -40
  257. package/src/commands/ws-migrate.js +0 -41
  258. package/src/commands/ws-plan-verify.js +0 -44
  259. package/src/commands/ws-pull.js +0 -30
  260. package/src/commands/ws-push.js +0 -71
  261. package/src/commands/ws-submodule-setup.js +0 -65
  262. package/src/commands/ws-verify-before-complete.js +0 -39
  263. package/src/dashboard/app.js +0 -371
  264. package/src/errors.js +0 -15
  265. package/src/exec.js +0 -34
  266. package/src/fs.js +0 -91
  267. package/src/governance.js +0 -159
  268. package/src/hash.js +0 -25
  269. package/src/json-schema-lite.js +0 -164
  270. package/src/managed-blocks.js +0 -131
  271. package/src/manifest.js +0 -177
  272. package/src/opencode-env.js +0 -208
  273. package/src/path-utils.js +0 -20
  274. package/src/spec.js +0 -195
  275. package/src/template.js +0 -187
  276. package/src/workspace.js +0 -23
  277. /package/{src → dist}/dashboard/index.html +0 -0
  278. /package/{src → dist}/dashboard/style.css +0 -0
@@ -1,340 +0,0 @@
1
- import path from "node:path";
2
- import fs from "node:fs/promises";
3
- import { pathExists } from "../fs.js";
4
-
5
- /**
6
- * @param {string} input
7
- */
8
- function normalizeSlashes(input) {
9
- return String(input || "").replaceAll("\\", "/");
10
- }
11
-
12
- /**
13
- * @param {string} gitRoot
14
- * @param {string} absPath
15
- */
16
- export function relFromRoot(gitRoot, absPath) {
17
- return normalizeSlashes(path.relative(gitRoot, absPath));
18
- }
19
-
20
- /**
21
- * @param {string} absDir
22
- * @param {{ maxDepth?: number, maxFiles?: number }} [options]
23
- * @returns {Promise<string[]>}
24
- */
25
- async function listFilesRecursive(absDir, options) {
26
- const maxDepth = Number(options?.maxDepth ?? 4);
27
- const maxFiles = Number(options?.maxFiles ?? 200);
28
- /** @type {string[]} */
29
- const out = [];
30
-
31
- /** @param {string} curAbs @param {number} depth */
32
- async function walk(curAbs, depth) {
33
- if (depth > maxDepth) return;
34
- let entries = [];
35
- try {
36
- entries = await fs.readdir(curAbs, { withFileTypes: true });
37
- } catch {
38
- return;
39
- }
40
- entries.sort((a, b) => a.name.localeCompare(b.name));
41
- for (const entry of entries) {
42
- if (out.length >= maxFiles) return;
43
- const nextAbs = path.join(curAbs, entry.name);
44
- if (entry.isDirectory()) {
45
- await walk(nextAbs, depth + 1);
46
- continue;
47
- }
48
- if (entry.isFile()) out.push(nextAbs);
49
- }
50
- }
51
-
52
- if (!(await pathExists(absDir))) return out;
53
- await walk(absDir, 0);
54
- return out;
55
- }
56
-
57
- /**
58
- * @param {string} gitRoot
59
- * @param {string} changeDir
60
- */
61
- export async function collectCollaborationArtifacts(gitRoot, changeDir) {
62
- const groups = [
63
- ["analysis", "analysis"],
64
- ["patches", "patches"],
65
- ["review", "review"],
66
- ["evidence", "evidence"],
67
- ];
68
-
69
- /** @type {Record<string, { label: string, dir: string, exists: boolean, count: number, files: string[], truncated: boolean }>} */
70
- const dirs = {};
71
- const counts = {
72
- analysis: 0,
73
- patches: 0,
74
- review: 0,
75
- evidence: 0,
76
- total: 0,
77
- };
78
-
79
- for (const [key, label] of groups) {
80
- const abs = path.join(changeDir, key);
81
- const exists = await pathExists(abs);
82
- const filesAbs = exists ? await listFilesRecursive(abs, { maxDepth: 4, maxFiles: 200 }) : [];
83
- const files = filesAbs.map((item) => relFromRoot(gitRoot, item));
84
- dirs[key] = {
85
- label,
86
- dir: relFromRoot(gitRoot, abs),
87
- exists,
88
- count: files.length,
89
- files: files.slice(0, 8),
90
- truncated: files.length > 8,
91
- };
92
- counts[key] = files.length;
93
- counts.total += files.length;
94
- }
95
-
96
- return { dirs, counts };
97
- }
98
-
99
- /**
100
- * Evidence_Path is user-declared; we treat it as best-effort hints, not hard gates.
101
- *
102
- * @param {string} gitRoot
103
- * @param {string} changeId
104
- * @param {string[]} evidencePaths
105
- * @returns {Promise<{
106
- * entries: Array<{rel: string, abs: string, exists: boolean, kind: string, isAbsolute: boolean}>,
107
- * counts: { total: number, exists: number, missing: number, tmp: number, persistent: number, other: number, absolute: number },
108
- * missing: string[]
109
- * }>}
110
- */
111
- export async function analyzeEvidencePaths(gitRoot, changeId, evidencePaths) {
112
- const changePrefix = `changes/${changeId}/`;
113
- const evidencePrefix = `changes/${changeId}/evidence/`;
114
- const reviewPrefix = `changes/${changeId}/review/`;
115
-
116
- const entries = await Promise.all(
117
- (evidencePaths || []).map(async (raw) => {
118
- const rel = String(raw || "").trim();
119
- const isAbsolute = path.isAbsolute(rel);
120
- const abs = isAbsolute ? rel : path.join(gitRoot, rel);
121
- const exists = rel ? await pathExists(abs) : false;
122
-
123
- const relNorm = normalizeSlashes(rel);
124
- let kind = "other";
125
- if (relNorm.startsWith(".agentdocs/tmp/") || relNorm.startsWith(".agentdocs/")) kind = "tmp";
126
- else if (relNorm.startsWith(evidencePrefix) || relNorm.startsWith(reviewPrefix) || relNorm.startsWith(changePrefix)) kind = "persistent";
127
-
128
- return { rel, abs: path.resolve(abs), exists, kind, isAbsolute };
129
- }),
130
- );
131
-
132
- const missing = entries.filter((entry) => entry.rel && !entry.exists).map((entry) => entry.rel);
133
- const counts = {
134
- total: entries.filter((entry) => entry.rel).length,
135
- exists: entries.filter((entry) => entry.rel && entry.exists).length,
136
- missing: missing.length,
137
- tmp: entries.filter((entry) => entry.rel && entry.kind === "tmp").length,
138
- persistent: entries.filter((entry) => entry.rel && entry.kind === "persistent").length,
139
- other: entries.filter((entry) => entry.rel && entry.kind === "other").length,
140
- absolute: entries.filter((entry) => entry.rel && entry.isAbsolute).length,
141
- };
142
-
143
- return { entries: entries.filter((entry) => entry.rel), counts, missing };
144
- }
145
-
146
- /**
147
- * @param {string[]} a
148
- * @param {string[]} b
149
- */
150
- export function mergeDeclaredValues(a, b) {
151
- const seen = new Set();
152
- /** @type {string[]} */
153
- const out = [];
154
- for (const raw of [...(a || []), ...(b || [])]) {
155
- const value = String(raw || "").trim().replace(/^`+/, "").replace(/`+$/, "").trim();
156
- if (!value) continue;
157
- if (seen.has(value)) continue;
158
- seen.add(value);
159
- out.push(value);
160
- }
161
- return out;
162
- }
163
-
164
- /**
165
- * @param {string[]} values
166
- */
167
- export function formatDeclaredValues(values) {
168
- return (values || []).join(", ");
169
- }
170
-
171
- /**
172
- * @param {string} input
173
- */
174
- function escapeRegExp(input) {
175
- return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
176
- }
177
-
178
- /**
179
- * Replace or insert a simple "ID: value" style line in Markdown.
180
- *
181
- * @param {string} text
182
- * @param {string[]} labelCandidates
183
- * @param {string} value
184
- * @param {{ insertAfterLabels?: string[] }} options
185
- */
186
- export function upsertIdLine(text, labelCandidates, value, options) {
187
- const src = String(text || "");
188
- const labels = Array.isArray(labelCandidates) ? labelCandidates : [];
189
- for (const label of labels) {
190
- const re = new RegExp(`^(.*${escapeRegExp(label)}.*?[:=][ \\t]*)(.*)$`, "m");
191
- const match = re.exec(src);
192
- if (!match) continue;
193
- const prefix = match[1] || "";
194
- const replaced = src.replace(re, `${prefix}${value}`);
195
- return { ok: true, changed: replaced !== src, text: replaced, mode: "replaced", label };
196
- }
197
-
198
- const insertAfter = Array.isArray(options?.insertAfterLabels) ? options.insertAfterLabels : [];
199
- const lines = src.split(/\r?\n/);
200
- let idx = 0;
201
- for (let i = 0; i < Math.min(lines.length, 80); i++) {
202
- const line = lines[i] || "";
203
- if (insertAfter.some((label) => line.includes(label))) idx = i + 1;
204
- }
205
- const insertedLabel = labels[0] || "Evidence_Path";
206
- lines.splice(idx, 0, `- ${insertedLabel}: ${value}`);
207
- const inserted = lines.join("\n");
208
- return { ok: true, changed: inserted !== src, text: inserted, mode: "inserted", label: labels[0] || "" };
209
- }
210
-
211
- /**
212
- * Special-case insertion for proposal.md template style.
213
- *
214
- * @param {string} proposalText
215
- * @param {string} value
216
- */
217
- export function upsertProposalEvidencePath(proposalText, value) {
218
- const src = String(proposalText || "");
219
- const re = new RegExp(`^(.*${escapeRegExp("Evidence_Path")}.*?[:=][ \\t]*)(.*)$`, "m");
220
- if (re.test(src)) {
221
- const match = re.exec(src);
222
- const prefix = match?.[1] || "";
223
- const out = src.replace(re, `${prefix}${value}`);
224
- return { changed: out !== src, text: out, mode: "replaced" };
225
- }
226
- const lines = src.split(/\r?\n/);
227
- let idx = 0;
228
- for (let i = 0; i < Math.min(lines.length, 120); i++) {
229
- if ((lines[i] || "").includes("Plan_File")) {
230
- idx = i + 1;
231
- break;
232
- }
233
- }
234
- lines.splice(idx, 0, `- \`Evidence_Path\` = ${value}`);
235
- const inserted = lines.join("\n");
236
- return { changed: inserted !== src, text: inserted, mode: "inserted" };
237
- }
238
-
239
- /**
240
- * @param {string} changeId
241
- */
242
- export function planVerifyHint(changeId) {
243
- return `执行前质量门(优先):\`aiws change validate ${changeId} --strict\`(AI 工具中等价于 \`$ws-plan-verify\`)`;
244
- }
245
-
246
- /**
247
- * @param {string} absDir
248
- * @param {(fileName: string) => boolean} predicate
249
- */
250
- export async function findLatestFileByMtime(absDir, predicate) {
251
- /** @type {Array<{ abs: string, mtimeMs: number }>} */
252
- const matches = [];
253
- if (!(await pathExists(absDir))) return "";
254
- try {
255
- const entries = await fs.readdir(absDir, { withFileTypes: true });
256
- for (const entry of entries) {
257
- if (!entry.isFile()) continue;
258
- if (!predicate(entry.name)) continue;
259
- const abs = path.join(absDir, entry.name);
260
- const st = await fs.stat(abs);
261
- matches.push({ abs, mtimeMs: st.mtimeMs });
262
- }
263
- } catch {
264
- return "";
265
- }
266
- matches.sort((a, b) => b.mtimeMs - a.mtimeMs);
267
- return matches[0]?.abs || "";
268
- }
269
-
270
- /**
271
- * @param {{
272
- * gitRoot: string,
273
- * changeId: string,
274
- * branch: string,
275
- * status: any,
276
- * collaboration: any,
277
- * created: string[],
278
- * validateRes: any,
279
- * validateFailed: boolean
280
- * }} options
281
- */
282
- export function buildDeliverySummary(options) {
283
- const { gitRoot, changeId, branch, status, collaboration, created, validateRes, validateFailed } = options;
284
- /** @type {string[]} */
285
- const lines = [];
286
- lines.push(`# Delivery Summary: ${changeId}`);
287
- lines.push("");
288
- lines.push(`Generated: ${new Date().toISOString().replace(/\.\d{3}Z$/, "Z")}`);
289
- lines.push("");
290
- lines.push("## Context");
291
- lines.push(`- Worktree: \`${gitRoot}\``);
292
- lines.push(`- Branch: \`${branch || "(detached)"}\``);
293
- lines.push("");
294
- lines.push("## Status");
295
- lines.push(`- Phase: \`${status.phase}\``);
296
- lines.push(
297
- `- Tasks: ${status.tasks.done}/${status.tasks.total} (unchecked=${status.tasks.unchecked}, optional_open=${status.tasks.optionalUnchecked || 0}, n_a=${status.tasks.naCount || 0})`,
298
- );
299
- lines.push(`- Truth drift: ${status.driftFiles.length > 0 ? status.driftFiles.join(", ") : "(none)"}`);
300
- lines.push("");
301
- lines.push("## Collaboration");
302
- lines.push(`- analysis: ${collaboration.counts.analysis}`);
303
- lines.push(`- patches: ${collaboration.counts.patches}`);
304
- lines.push(`- review: ${collaboration.counts.review}`);
305
- lines.push(`- evidence dir files: ${collaboration.counts.evidence}`);
306
- for (const key of ["analysis", "patches", "review"]) {
307
- const group = collaboration.dirs[key];
308
- if (!group || group.count === 0) continue;
309
- lines.push(`- ${group.label} files:`);
310
- for (const rel of group.files) lines.push(` - \`${rel}\``);
311
- if (group.truncated) lines.push(" - ...(truncated)");
312
- }
313
- lines.push("");
314
- lines.push("## Bindings");
315
- if (status.reqId) lines.push(`- Req_ID: \`${status.reqId}\``);
316
- if (status.probId) lines.push(`- Problem_ID: \`${status.probId}\``);
317
- if (status.bindings?.contractRow) lines.push(`- Contract_Row: \`${status.bindings.contractRow}\``);
318
- if (status.bindings?.planFile) lines.push(`- Plan_File: \`${status.bindings.planFile}\``);
319
- lines.push("");
320
- lines.push("## Evidence (Created/Collected)");
321
- if (created.length === 0) lines.push("- (none)");
322
- else for (const item of created) lines.push(`- \`${item}\``);
323
- lines.push("");
324
- lines.push("## Quality Gate");
325
- if (!validateRes) {
326
- lines.push("- Strict validation: (skipped via --no-validate)");
327
- } else {
328
- lines.push(`- Strict validation ok: \`${validateRes.ok === true}\``);
329
- lines.push(`- Errors: \`${Array.isArray(validateRes.errors) ? validateRes.errors.length : 0}\``);
330
- lines.push(`- Warnings: \`${Array.isArray(validateRes.warnings) ? validateRes.warnings.length : 0}\``);
331
- }
332
- lines.push("");
333
- lines.push("## Next");
334
- lines.push(`- ${planVerifyHint(changeId)}`);
335
- if (validateFailed) lines.push("- Fix strict validation errors, then re-run `aiws change evidence`");
336
- else lines.push(`- Verify evidence gate: \`aiws change validate ${changeId} --strict --check-evidence\``);
337
- if (collaboration.counts.patches > 0) lines.push("- Review delegated patch drafts before apply/merge; do not treat `changes/<id>/patches/` as auto-applied changes");
338
- if (collaboration.counts.analysis > 0 && collaboration.counts.review === 0) lines.push("- Summarize delegated analysis into `changes/<id>/review/` before delivery");
339
- return lines.join("\n") + "\n";
340
- }