@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
@@ -0,0 +1,212 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { loadTemplate } from "../spec.js";
4
+ import { loadAiwsPackage } from "../aiws-package.js";
5
+ import { resolveWorkspaceRoot } from "../workspace.js";
6
+ import { readText, pathExists } from "../fs.js";
7
+ import { UserError } from "../errors.js";
8
+ import { normalizeNewlines } from "../hash.js";
9
+ import { findManagedBlock } from "../managed-blocks.js";
10
+ import { BackupSession } from "../backup.js";
11
+ import { normalizeRel, joinRel } from "../path-utils.js";
12
+ import { copyTemplateFileToWorkspace, applyManagedBlocksFromTemplate } from "../template.js";
13
+ import { detectLegacyWorkspaceTemplateId, writeWorkspaceManifest } from "../manifest.js";
14
+ import { deployClaudeHooks } from "../hooks/deploy-claude.js";
15
+ import { DIR_MIGRATION_MAP, FILE_MIGRATION_MAP } from "../aiws-paths.js";
16
+ /**
17
+ * Rename a file or directory, falling back to copy+delete when renaming
18
+ * across different filesystems (EXDEV).
19
+ */
20
+ async function renameOrCopy(src, dst) {
21
+ try {
22
+ await fs.rename(src, dst);
23
+ }
24
+ catch (err) {
25
+ if (err.code === "EXDEV") {
26
+ await fs.cp(src, dst, { recursive: true, force: true });
27
+ await fs.rm(src, { recursive: true, force: true });
28
+ }
29
+ else {
30
+ throw err;
31
+ }
32
+ }
33
+ }
34
+ /**
35
+ * Move old root-level AIWS artifacts into `.aiws/`.
36
+ * Skips if source doesn't exist or target already exists.
37
+ * Returns the number of items moved.
38
+ */
39
+ async function migrateOldLayout(workspaceRoot, backup) {
40
+ let count = 0;
41
+ for (const [srcRel, dstRel] of Object.entries(DIR_MIGRATION_MAP)) {
42
+ const src = path.join(workspaceRoot, srcRel);
43
+ const dst = path.join(workspaceRoot, dstRel);
44
+ if (!(await pathExists(src)))
45
+ continue;
46
+ if (await pathExists(dst)) {
47
+ console.log(` skip ${srcRel} → ${dstRel} (target already exists)`);
48
+ continue;
49
+ }
50
+ await backup.recordFile(srcRel, { recordMissing: true });
51
+ await fs.mkdir(path.dirname(dst), { recursive: true });
52
+ await renameOrCopy(src, dst);
53
+ count++;
54
+ }
55
+ for (const [srcRel, dstRel] of Object.entries(FILE_MIGRATION_MAP)) {
56
+ const src = path.join(workspaceRoot, srcRel);
57
+ const dst = path.join(workspaceRoot, dstRel);
58
+ if (!(await pathExists(src)))
59
+ continue;
60
+ if (await pathExists(dst)) {
61
+ console.log(` skip ${srcRel} → ${dstRel} (target already exists)`);
62
+ continue;
63
+ }
64
+ await backup.recordFile(srcRel, { recordMissing: true });
65
+ await fs.mkdir(path.dirname(dst), { recursive: true });
66
+ await renameOrCopy(src, dst);
67
+ count++;
68
+ }
69
+ return count;
70
+ }
71
+ /**
72
+ * @param {{ targetPath: string }} options
73
+ */
74
+ export async function updateCommand(options) {
75
+ const workspaceRoot = await resolveWorkspaceRoot(options.targetPath, { create: false });
76
+ const aiws = await loadAiwsPackage();
77
+ const manifestPath = path.join(workspaceRoot, ".aiws", "manifest.json");
78
+ const hasManifest = await pathExists(manifestPath);
79
+ const legacyTemplateId = !hasManifest ? await detectLegacyWorkspaceTemplateId(workspaceRoot) : null;
80
+ const legacyMigration = !hasManifest && Boolean(legacyTemplateId);
81
+ if (!hasManifest && !legacyTemplateId) {
82
+ throw new UserError("Missing .aiws/manifest.json. Run `aiws init` first.");
83
+ }
84
+ const stored = hasManifest
85
+ ? JSON.parse(await readText(manifestPath))
86
+ : { template_id: legacyTemplateId, installed_at: "", tools: [], managed: [] };
87
+ const templateId = String(stored.template_id || legacyTemplateId || "workspace");
88
+ const tpl = await loadTemplate(templateId);
89
+ const storedManagedByPath = new Map((Array.isArray(stored.managed) ? stored.managed : [])
90
+ .filter((entry) => entry && typeof entry === "object")
91
+ .map((entry) => [normalizeRel(String(entry.path || "")), entry]));
92
+ const defaults = tpl.manifest.defaults || {};
93
+ const defaultTools = Array.isArray(defaults.tools) ? defaults.tools.map(String) : ["claude", "opencode", "codex"];
94
+ const allowedTools = new Set(defaultTools);
95
+ const update = tpl.manifest.update || {};
96
+ const replaceFiles = (update.replace_file || []).map(normalizeRel);
97
+ const managedBlocks = update.managed_blocks && typeof update.managed_blocks === "object" ? update.managed_blocks : {};
98
+ // Preflight: existing managed-block files must be intact.
99
+ // Missing files that were not previously managed are treated as newly introduced
100
+ // template surfaces and will be created during applyManagedBlocksFromTemplate.
101
+ for (const [fileRelRaw, blockIdsRaw] of Object.entries(managedBlocks)) {
102
+ const fileRel = normalizeRel(fileRelRaw);
103
+ const abs = joinRel(workspaceRoot, fileRel);
104
+ const hadManagedBefore = storedManagedByPath.has(fileRel);
105
+ if (!(await pathExists(abs))) {
106
+ if (hadManagedBefore) {
107
+ throw new UserError("Managed block file missing; run `aiws init` or restore the file.", { details: `Missing: ${fileRel}` });
108
+ }
109
+ continue;
110
+ }
111
+ const text = normalizeNewlines(await readText(abs));
112
+ const ids = Array.isArray(blockIdsRaw) ? blockIdsRaw.map(String) : [];
113
+ for (const id of ids) {
114
+ if (!findManagedBlock(text, id)) {
115
+ if (legacyMigration) {
116
+ continue;
117
+ }
118
+ throw new UserError("Managed block markers are missing or broken; refusing to update.", {
119
+ details: `File: ${fileRel}\nBlock: ${id}\nHint: re-run \`aiws init\` or repair markers manually.`,
120
+ });
121
+ }
122
+ }
123
+ }
124
+ const removeFiles = (update.remove || []).map(normalizeRel);
125
+ const backup = new BackupSession({ workspaceRoot, operation: "update" });
126
+ // Backup every file we might touch (including missing, for rollback deletions).
127
+ await backup.recordFile(".aiws/manifest.json", { recordMissing: true });
128
+ for (const f of replaceFiles)
129
+ await backup.recordFile(f, { recordMissing: true });
130
+ for (const f of Object.keys(managedBlocks))
131
+ await backup.recordFile(f, { recordMissing: true });
132
+ for (const f of removeFiles)
133
+ await backup.recordFile(f, undefined);
134
+ await backup.finalize({ extra: { template_id: tpl.templateId } });
135
+ const migratedCount = await migrateOldLayout(workspaceRoot, backup);
136
+ if (migratedCount > 0) {
137
+ console.log(` migrated ${migratedCount} old AIWS artifact(s) into .aiws/`);
138
+ }
139
+ // Remove deprecated files (backed up above; restorable via `aiws rollback`).
140
+ let removedCount = 0;
141
+ for (const rel of removeFiles) {
142
+ if (!rel)
143
+ continue;
144
+ const abs = joinRel(workspaceRoot, rel);
145
+ if (await pathExists(abs)) {
146
+ await fs.rm(abs, { force: true });
147
+ removedCount++;
148
+ // Remove empty parent directory (safe: rmdir fails on non-empty).
149
+ try {
150
+ await fs.rmdir(path.dirname(abs));
151
+ }
152
+ catch { /* non-empty or gone */ }
153
+ }
154
+ }
155
+ if (removedCount > 0) {
156
+ console.log(` removed ${removedCount} deprecated file(s)`);
157
+ }
158
+ // Replace files (except manifest, generated later).
159
+ for (const rel of replaceFiles) {
160
+ if (!rel || rel === ".aiws/manifest.json")
161
+ continue;
162
+ await copyTemplateFileToWorkspace({
163
+ templateDir: tpl.templateDir,
164
+ workspaceRoot,
165
+ relPosix: rel,
166
+ chmod: rel.startsWith(".githooks/") ? 0o755 : undefined,
167
+ });
168
+ }
169
+ // Update managed blocks only (do not insert missing blocks).
170
+ for (const [fileRelRaw, blockIdsRaw] of Object.entries(managedBlocks)) {
171
+ const fileRel = normalizeRel(fileRelRaw);
172
+ const ids = Array.isArray(blockIdsRaw) ? blockIdsRaw.map(String) : [];
173
+ await applyManagedBlocksFromTemplate({
174
+ templateDir: tpl.templateDir,
175
+ workspaceRoot,
176
+ fileRel,
177
+ blockIds: ids,
178
+ insertIfMissing: legacyMigration,
179
+ });
180
+ }
181
+ const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
182
+ const installedAt = String(stored.installed_at || now);
183
+ const storedTools = Array.isArray(stored.tools) ? stored.tools.map(String).filter((tool) => allowedTools.has(tool)) : [];
184
+ const tools = storedTools.length > 0 ? storedTools : defaultTools;
185
+ await writeWorkspaceManifest({
186
+ workspaceRoot,
187
+ templateId: tpl.templateId,
188
+ specVersion: tpl.specVersion,
189
+ aiwsVersion: aiws.version,
190
+ installedAt,
191
+ updatedAt: now,
192
+ tools,
193
+ templateManifest: tpl.manifest,
194
+ });
195
+ const pluginEntries = (tpl.manifest.required || [])
196
+ .filter((rel) => rel.startsWith(".opencode/plugins/") && rel.endsWith(".js"));
197
+ for (const rel of pluginEntries) {
198
+ await copyTemplateFileToWorkspace({
199
+ templateDir: tpl.templateDir,
200
+ workspaceRoot,
201
+ relPosix: rel,
202
+ });
203
+ }
204
+ if (tools.includes("claude")) {
205
+ await deployClaudeHooks({ force: true });
206
+ }
207
+ if (legacyMigration) {
208
+ console.log(` migrated legacy AIWS workspace: generated .aiws/manifest.json for template=${legacyTemplateId}`);
209
+ }
210
+ console.log(`✓ aiws update: ${workspaceRoot}`);
211
+ }
212
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @param {{ targetPath: string, stamp?: boolean }} options
3
+ */
4
+ export declare function validateCommand(options: any): Promise<void>;
@@ -0,0 +1,222 @@
1
+ import path from "node:path";
2
+ import { loadTemplate } from "../spec.js";
3
+ import { resolveWorkspaceRoot } from "../workspace.js";
4
+ import { ensureDir, pathExists, readText, writeText } from "../fs.js";
5
+ import { UserError } from "../errors.js";
6
+ import { detectLegacyWorkspaceTemplateId, validateDrift } from "../manifest.js";
7
+ import { runCommand } from "../exec.js";
8
+ import { expandManifestEntries } from "../template.js";
9
+ import { loadAiwsPackage } from "../aiws-package.js";
10
+ /**
11
+ * Enforce deterministic submodule branch policy:
12
+ * - If `.gitmodules` exists and declares submodules, each submodule must declare `submodule.<name>.branch`.
13
+ * - This avoids guessing which branch to attach/push for workflows like ws-pull/ws-finish.
14
+ *
15
+ * @param {string} workspaceRoot
16
+ */
17
+ async function validateSubmoduleBranchPolicy(workspaceRoot) {
18
+ const gitmodules = path.join(workspaceRoot, ".gitmodules");
19
+ if (!(await pathExists(gitmodules)))
20
+ return;
21
+ const list = await runCommand("git", ["config", "--file", ".gitmodules", "--get-regexp", "^submodule\\..*\\.path$"], {
22
+ cwd: workspaceRoot,
23
+ });
24
+ if (list.code !== 0) {
25
+ // `.gitmodules` exists but no submodule path entries: treat as ok.
26
+ return;
27
+ }
28
+ /** @type {Array<{ name: string, path: string }>} */
29
+ const subs = [];
30
+ for (const line of String(list.stdout || "").split("\n")) {
31
+ const t = line.trim();
32
+ if (!t)
33
+ continue;
34
+ const idx = t.indexOf(" ");
35
+ if (idx <= 0)
36
+ continue;
37
+ const key = t.slice(0, idx).trim();
38
+ const subPath = t.slice(idx + 1).trim();
39
+ const m = key.match(/^submodule\.(.+)\.path$/);
40
+ if (!m)
41
+ continue;
42
+ const name = m[1] || "";
43
+ if (!name || !subPath)
44
+ continue;
45
+ subs.push({ name, path: subPath });
46
+ }
47
+ if (subs.length === 0)
48
+ return;
49
+ /** @type {Array<{ name: string, path: string }>} */
50
+ const missing = [];
51
+ for (const s of subs) {
52
+ const br = await runCommand("git", ["config", "--file", ".gitmodules", "--get", `submodule.${s.name}.branch`], {
53
+ cwd: workspaceRoot,
54
+ });
55
+ if (br.code !== 0 || !String(br.stdout || "").trim()) {
56
+ missing.push(s);
57
+ }
58
+ }
59
+ if (missing.length > 0) {
60
+ const lines = missing.map((m) => `- ${m.name} (${m.path}): missing submodule.${m.name}.branch`);
61
+ const hints = missing
62
+ .slice(0, 8)
63
+ .map((m) => `git submodule set-branch --branch main ${m.path}`)
64
+ .join("\n");
65
+ throw new UserError("Submodule branch policy failed: missing `.gitmodules` branch config.", {
66
+ details: `${lines.join("\n")}\n\n` +
67
+ "Fix:\n" +
68
+ "- Run `ws-submodule-setup` (recommended), or set per submodule:\n" +
69
+ `${hints}\n\n` +
70
+ "Then commit `.gitmodules` in the superproject.",
71
+ });
72
+ }
73
+ }
74
+ /**
75
+ * @param {string | undefined} v
76
+ */
77
+ function envFlag(v) {
78
+ const s = String(v || "")
79
+ .trim()
80
+ .toLowerCase();
81
+ return s === "1" || s === "true" || s === "yes" || s === "y" || s === "on";
82
+ }
83
+ /**
84
+ * @returns {string} e.g. 20260204-140026Z
85
+ */
86
+ function nowStampUtc() {
87
+ const d = new Date();
88
+ const y = String(d.getUTCFullYear());
89
+ const m = String(d.getUTCMonth() + 1).padStart(2, "0");
90
+ const day = String(d.getUTCDate()).padStart(2, "0");
91
+ const hh = String(d.getUTCHours()).padStart(2, "0");
92
+ const mm = String(d.getUTCMinutes()).padStart(2, "0");
93
+ const ss = String(d.getUTCSeconds()).padStart(2, "0");
94
+ const ms = String(d.getUTCMilliseconds()).padStart(3, "0");
95
+ return `${y}${m}${day}-${hh}${mm}${ss}${ms}Z`;
96
+ }
97
+ /**
98
+ * @returns {string} e.g. 2026-01-28T14:00:26Z
99
+ */
100
+ function nowIsoUtc() {
101
+ return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
102
+ }
103
+ /**
104
+ * @param {any} error
105
+ * @returns {{ name: string, message: string, details?: string } | null}
106
+ */
107
+ function serializeError(error) {
108
+ if (!error)
109
+ return null;
110
+ if (error instanceof UserError) {
111
+ return { name: error.name, message: error.message, details: error.details };
112
+ }
113
+ if (error instanceof Error) {
114
+ return { name: error.name, message: error.message };
115
+ }
116
+ return { name: "Error", message: String(error) };
117
+ }
118
+ /**
119
+ * @param {{ targetPath: string, stamp?: boolean }} options
120
+ */
121
+ export async function validateCommand(options) {
122
+ const stampEnabled = options.stamp === true || envFlag(process.env.AIWS_VALIDATE_STAMP);
123
+ const startedAt = nowIsoUtc();
124
+ const startedTs = Math.floor(Date.now() / 1000);
125
+ let workspaceRoot = "";
126
+ let templateId = "";
127
+ let specVersion = "";
128
+ let aiwsVersion = "";
129
+ let status = /** @type {"ok" | "error"} */ ("ok");
130
+ let exitCode = 0;
131
+ let err = null;
132
+ let stampPath = "";
133
+ try {
134
+ workspaceRoot = await resolveWorkspaceRoot(options.targetPath, { create: false });
135
+ const aiws = await loadAiwsPackage();
136
+ aiwsVersion = aiws.version;
137
+ const manifestPath = path.join(workspaceRoot, ".aiws", "manifest.json");
138
+ if (!(await pathExists(manifestPath))) {
139
+ const legacyTemplateId = await detectLegacyWorkspaceTemplateId(workspaceRoot);
140
+ if (legacyTemplateId) {
141
+ throw new UserError("Missing .aiws/manifest.json in a legacy AIWS workspace.", {
142
+ details: "This workspace looks like an older AIWS install. Run `aiws update .` once to generate the manifest, then rerun `aiws validate`.",
143
+ });
144
+ }
145
+ throw new UserError("Missing .aiws/manifest.json. Run `aiws init` first.");
146
+ }
147
+ const stored = JSON.parse(await readText(manifestPath));
148
+ templateId = String(stored.template_id || "workspace");
149
+ const tpl = await loadTemplate(templateId);
150
+ specVersion = tpl.specVersion;
151
+ // Required files/dirs.
152
+ const required = await expandManifestEntries(tpl.templateDir, tpl.manifest.required || []);
153
+ /** @type {string[]} */
154
+ const missing = [];
155
+ for (const rel of required) {
156
+ const abs = path.join(workspaceRoot, ...String(rel).split("/"));
157
+ if (!(await pathExists(abs)))
158
+ missing.push(rel);
159
+ }
160
+ if (missing.length > 0) {
161
+ throw new UserError("Missing required files.", { details: missing.join("\n") });
162
+ }
163
+ // Drift detection.
164
+ await validateDrift({ workspaceRoot, storedManifest: stored, templateManifest: tpl.manifest });
165
+ // Submodule branch policy (deterministic workflow; avoids guessing target branches).
166
+ await validateSubmoduleBranchPolicy(workspaceRoot);
167
+ // python3 gate.
168
+ const py = await runCommand("python3", ["--version"], { cwd: workspaceRoot });
169
+ if (py.code !== 0) {
170
+ throw new UserError("python3 is required for validate.", { details: py.stderr || py.stdout });
171
+ }
172
+ // Required gate scripts.
173
+ const wsCheck = await runCommand("python3", [".aiws/tools/ws_change_check.py", "--strict"], { cwd: workspaceRoot });
174
+ if (wsCheck.code !== 0) {
175
+ throw new UserError("change gate failed.", { details: wsCheck.stderr || wsCheck.stdout });
176
+ }
177
+ const reqCheck = await runCommand("python3", [".aiws/tools/requirements_contract.py", "validate"], { cwd: workspaceRoot });
178
+ if (reqCheck.code !== 0) {
179
+ throw new UserError("requirements contract gate failed.", { details: reqCheck.stderr || reqCheck.stdout });
180
+ }
181
+ console.log(`✓ aiws validate: ${workspaceRoot}`);
182
+ }
183
+ catch (error) {
184
+ status = "error";
185
+ err = serializeError(error);
186
+ if (error instanceof UserError) {
187
+ exitCode = error.exitCode;
188
+ }
189
+ else {
190
+ exitCode = 1;
191
+ }
192
+ throw error;
193
+ }
194
+ finally {
195
+ if (stampEnabled && workspaceRoot) {
196
+ try {
197
+ const stampDir = path.join(workspaceRoot, ".aiws", "tmp", "aiws-validate");
198
+ await ensureDir(stampDir);
199
+ stampPath = path.join(stampDir, `${nowStampUtc()}.json`);
200
+ const stamp = {
201
+ timestamp: startedTs,
202
+ ws_root: workspaceRoot,
203
+ template_id: templateId || null,
204
+ aiws_version: aiwsVersion || null,
205
+ spec_version: specVersion || null,
206
+ started_at: startedAt,
207
+ finished_at: nowIsoUtc(),
208
+ status,
209
+ exit_code: status === "ok" ? 0 : exitCode || 1,
210
+ error: err,
211
+ note: "aiws validate stamp; does not include full stdout/stderr; do not put secrets in validation output.",
212
+ };
213
+ await writeText(stampPath, JSON.stringify(stamp, null, 2) + "\n");
214
+ console.log(`stamp: ${path.relative(workspaceRoot, stampPath)}`);
215
+ }
216
+ catch (e) {
217
+ console.error(`warn: failed to write validate stamp: ${e instanceof Error ? e.message : String(e)}`);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws commit — validate + commit
3
+ * @param {{ cwd?: string, message?: string }} opts
4
+ */
5
+ export declare function wsCommitCommand({ cwd, message }?: any): Promise<void>;
@@ -0,0 +1,39 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws commit — validate + commit
6
+ * @param {{ cwd?: string, message?: string }} opts
7
+ */
8
+ export async function wsCommitCommand({ cwd = ".", message } = {}) {
9
+ checkClean(cwd);
10
+ // Check review artifacts
11
+ const reviewsExist = existsSync(`${cwd}/.aiws/changes/*/review/spec-review.md`) ||
12
+ existsSync(`${cwd}/.aiws/changes/*/review/quality-review.md`);
13
+ if (!reviewsExist) {
14
+ console.log("warn: no spec-review or quality-review found");
15
+ }
16
+ // Run validate
17
+ try {
18
+ execSync("npx -y @aipper/aiws validate . 2>/dev/null || aiws validate . 2>/dev/null || true", { cwd, stdio: "inherit" });
19
+ }
20
+ catch { /* validate is advisory, not blocking */ }
21
+ // Get staged changes
22
+ const staged = execSync("git diff --cached --name-only", { cwd, encoding: "utf8" }).trim();
23
+ if (!staged) {
24
+ console.log("info: nothing staged. Use git add first.");
25
+ }
26
+ // Commit
27
+ if (!message) {
28
+ throw new UserError("commit requires --message (use -m or --message)", { exitCode: 2 });
29
+ }
30
+ execSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd, stdio: "inherit" });
31
+ console.log("ok: commit created");
32
+ }
33
+ function checkClean(cwd) {
34
+ const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
35
+ if (!out) {
36
+ throw new UserError("Nothing to commit. Working tree clean.", { exitCode: 2 });
37
+ }
38
+ }
39
+ //# sourceMappingURL=ws-commit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-commit.js","sourceRoot":"","sources":["../../src/commands/ws-commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,OAAO,KAAK,EAAS;IACtE,UAAU,CAAC,GAAG,CAAC,CAAC;IAEhB,yBAAyB;IACzB,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,GAAG,wCAAwC,CAAC;QAC7E,UAAU,CAAC,GAAG,GAAG,2CAA2C,CAAC,CAAC;IAChE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC9D,CAAC;IAED,eAAe;IACf,IAAI,CAAC;QACH,QAAQ,CAAC,mFAAmF,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3H,CAAC;IAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;IAEpD,qBAAqB;IACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED,SAAS;IACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CAAC,iDAAiD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,QAAQ,CAAC,kBAAkB,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,SAAS,CAAC,wCAAwC,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws deliver — submodule + superproject commit, then finish
3
+ * @param {{ cwd?: string, message?: string, changeId?: string }} opts
4
+ */
5
+ export declare function wsDeliverCommand({ cwd, message, changeId }?: any): Promise<void>;
@@ -0,0 +1,59 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws deliver — submodule + superproject commit, then finish
6
+ * @param {{ cwd?: string, message?: string, changeId?: string }} opts
7
+ */
8
+ export async function wsDeliverCommand({ cwd = ".", message, changeId } = {}) {
9
+ if (!changeId) {
10
+ changeId = detectChangeBranch(cwd);
11
+ }
12
+ if (!changeId) {
13
+ throw new UserError("Could not detect change ID.", { exitCode: 2 });
14
+ }
15
+ if (!message) {
16
+ throw new UserError("deliver requires --message for the superproject commit", { exitCode: 2 });
17
+ }
18
+ console.log("info: starting delivery...");
19
+ // Commit submodules first
20
+ if (existsSync(`${cwd}/.gitmodules`)) {
21
+ const out = execSync("git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$'", {
22
+ cwd, encoding: "utf8",
23
+ }).trim();
24
+ for (const line of out.split("\n")) {
25
+ const parts = line.trim().split(/\s+/);
26
+ if (parts.length < 2)
27
+ continue;
28
+ const subPath = parts[1];
29
+ const status = execSync(`git -C "${subPath}" status --porcelain`, { cwd, encoding: "utf8" }).trim();
30
+ if (status) {
31
+ console.log(`info: submodule ${subPath} has changes. Committing...`);
32
+ execSync(`git -C "${subPath}" add -A`, { cwd, stdio: "inherit" });
33
+ execSync(`git -C "${subPath}" commit -m "${message}"`, { cwd, stdio: "inherit" });
34
+ }
35
+ else {
36
+ console.log(`info: submodule ${subPath} has no changes, skipping`);
37
+ }
38
+ }
39
+ }
40
+ // Commit superproject
41
+ const superStatus = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
42
+ if (superStatus) {
43
+ console.log("info: committing superproject...");
44
+ execSync("git add -A", { cwd, stdio: "inherit" });
45
+ execSync(`git commit -m "${message}"`, { cwd, stdio: "inherit" });
46
+ }
47
+ else {
48
+ console.log("info: superproject has no changes");
49
+ }
50
+ // Finish
51
+ await import("./ws-finish.js").then((m) => m.wsFinishCommand({ cwd, changeId, push: true }));
52
+ console.log("ok: deliver complete");
53
+ }
54
+ function detectChangeBranch(cwd) {
55
+ const branch = execSync("git branch --show-current", { cwd, encoding: "utf8" }).trim();
56
+ const match = branch.match(/^(?:change|changes|ws|ws-change)\/(.+)$/);
57
+ return match ? match[1] : null;
58
+ }
59
+ //# sourceMappingURL=ws-deliver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-deliver.js","sourceRoot":"","sources":["../../src/commands/ws-deliver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws finish — ff-merge + push + archive
3
+ * @param {{ cwd?: string, changeId?: string, into?: string, push?: boolean, remote?: string }} opts
4
+ */
5
+ export declare function wsFinishCommand({ cwd, changeId, into, push, remote }?: any): Promise<void>;