@aipper/aiws 0.0.28 → 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 (267) hide show
  1. package/README.md +18 -2
  2. package/bin/aiws.js +2 -2
  3. package/dist/aiws-package.d.ts +4 -0
  4. package/dist/aiws-package.js +11 -0
  5. package/dist/aiws-package.js.map +1 -0
  6. package/dist/aiws-paths.d.ts +48 -0
  7. package/dist/aiws-paths.js +129 -0
  8. package/dist/aiws-paths.js.map +1 -0
  9. package/dist/backup.d.ts +27 -0
  10. package/dist/backup.js +125 -0
  11. package/dist/backup.js.map +1 -0
  12. package/dist/cli.d.ts +1 -0
  13. package/dist/cli.js +773 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codex-prompts.d.ts +17 -0
  16. package/dist/codex-prompts.js +49 -0
  17. package/dist/codex-prompts.js.map +1 -0
  18. package/dist/codex-skills.d.ts +17 -0
  19. package/dist/codex-skills.js +75 -0
  20. package/dist/codex-skills.js.map +1 -0
  21. package/dist/commands/change-advice.d.ts +25 -0
  22. package/dist/commands/change-advice.js +197 -0
  23. package/dist/commands/change-advice.js.map +1 -0
  24. package/dist/commands/change-evidence-command.d.ts +29 -0
  25. package/dist/commands/change-evidence-command.js +213 -0
  26. package/dist/commands/change-evidence-command.js.map +1 -0
  27. package/dist/commands/change-evidence-entry.d.ts +16 -0
  28. package/dist/commands/change-evidence-entry.js +35 -0
  29. package/dist/commands/change-evidence-entry.js.map +1 -0
  30. package/dist/commands/change-evidence.d.ts +108 -0
  31. package/dist/commands/change-evidence.js +341 -0
  32. package/dist/commands/change-evidence.js.map +1 -0
  33. package/dist/commands/change-finish.d.ts +71 -0
  34. package/dist/commands/change-finish.js +387 -0
  35. package/dist/commands/change-finish.js.map +1 -0
  36. package/dist/commands/change-git-status.d.ts +22 -0
  37. package/dist/commands/change-git-status.js +50 -0
  38. package/dist/commands/change-git-status.js.map +1 -0
  39. package/dist/commands/change-lifecycle-entry.d.ts +29 -0
  40. package/{src → dist}/commands/change-lifecycle-entry.js +21 -28
  41. package/dist/commands/change-lifecycle-entry.js.map +1 -0
  42. package/dist/commands/change-lifecycle.d.ts +56 -0
  43. package/dist/commands/change-lifecycle.js +211 -0
  44. package/dist/commands/change-lifecycle.js.map +1 -0
  45. package/dist/commands/change-metrics-command.d.ts +12 -0
  46. package/dist/commands/change-metrics-command.js +110 -0
  47. package/dist/commands/change-metrics-command.js.map +1 -0
  48. package/dist/commands/change-next-command.d.ts +18 -0
  49. package/dist/commands/change-next-command.js +138 -0
  50. package/dist/commands/change-next-command.js.map +1 -0
  51. package/dist/commands/change-review-gates.d.ts +107 -0
  52. package/dist/commands/change-review-gates.js +329 -0
  53. package/dist/commands/change-review-gates.js.map +1 -0
  54. package/dist/commands/change-scope-gate.d.ts +21 -0
  55. package/dist/commands/change-scope-gate.js +32 -0
  56. package/dist/commands/change-scope-gate.js.map +1 -0
  57. package/dist/commands/change-start.d.ts +30 -0
  58. package/dist/commands/change-start.js +91 -0
  59. package/dist/commands/change-start.js.map +1 -0
  60. package/dist/commands/change-state-command.d.ts +3 -0
  61. package/dist/commands/change-state-command.js +32 -0
  62. package/dist/commands/change-state-command.js.map +1 -0
  63. package/dist/commands/change-status-command.d.ts +13 -0
  64. package/dist/commands/change-status-command.js +126 -0
  65. package/dist/commands/change-status-command.js.map +1 -0
  66. package/dist/commands/change-status-context.d.ts +58 -0
  67. package/dist/commands/change-status-context.js +166 -0
  68. package/dist/commands/change-status-context.js.map +1 -0
  69. package/dist/commands/change-task-stats.d.ts +24 -0
  70. package/dist/commands/change-task-stats.js +66 -0
  71. package/dist/commands/change-task-stats.js.map +1 -0
  72. package/dist/commands/change-validate-entry.d.ts +17 -0
  73. package/dist/commands/change-validate-entry.js +44 -0
  74. package/dist/commands/change-validate-entry.js.map +1 -0
  75. package/dist/commands/change-validate.d.ts +32 -0
  76. package/dist/commands/change-validate.js +128 -0
  77. package/dist/commands/change-validate.js.map +1 -0
  78. package/dist/commands/change.d.ts +322 -0
  79. package/dist/commands/change.js +1731 -0
  80. package/dist/commands/change.js.map +1 -0
  81. package/dist/commands/codex-install-prompts.d.ts +4 -0
  82. package/dist/commands/codex-install-prompts.js +68 -0
  83. package/dist/commands/codex-install-prompts.js.map +1 -0
  84. package/dist/commands/codex-install-skills.d.ts +4 -0
  85. package/dist/commands/codex-install-skills.js +74 -0
  86. package/dist/commands/codex-install-skills.js.map +1 -0
  87. package/dist/commands/codex-status-prompts.d.ts +4 -0
  88. package/dist/commands/codex-status-prompts.js +44 -0
  89. package/dist/commands/codex-status-prompts.js.map +1 -0
  90. package/dist/commands/codex-status-skills.d.ts +4 -0
  91. package/dist/commands/codex-status-skills.js +54 -0
  92. package/dist/commands/codex-status-skills.js.map +1 -0
  93. package/dist/commands/codex-uninstall-prompts.d.ts +4 -0
  94. package/dist/commands/codex-uninstall-prompts.js +51 -0
  95. package/dist/commands/codex-uninstall-prompts.js.map +1 -0
  96. package/dist/commands/codex-uninstall-skills.d.ts +4 -0
  97. package/dist/commands/codex-uninstall-skills.js +59 -0
  98. package/dist/commands/codex-uninstall-skills.js.map +1 -0
  99. package/dist/commands/dashboard.d.ts +222 -0
  100. package/dist/commands/dashboard.js +193 -0
  101. package/dist/commands/dashboard.js.map +1 -0
  102. package/dist/commands/hooks-install.d.ts +4 -0
  103. package/dist/commands/hooks-install.js +90 -0
  104. package/dist/commands/hooks-install.js.map +1 -0
  105. package/dist/commands/hooks-status.d.ts +4 -0
  106. package/dist/commands/hooks-status.js +89 -0
  107. package/dist/commands/hooks-status.js.map +1 -0
  108. package/dist/commands/init.d.ts +4 -0
  109. package/dist/commands/init.js +100 -0
  110. package/dist/commands/init.js.map +1 -0
  111. package/dist/commands/opencode-auto.d.ts +11 -0
  112. package/dist/commands/opencode-auto.js +158 -0
  113. package/dist/commands/opencode-auto.js.map +1 -0
  114. package/dist/commands/opencode-status.d.ts +4 -0
  115. package/dist/commands/opencode-status.js +75 -0
  116. package/dist/commands/opencode-status.js.map +1 -0
  117. package/dist/commands/opencode-supervise.d.ts +24 -0
  118. package/dist/commands/opencode-supervise.js +188 -0
  119. package/dist/commands/opencode-supervise.js.map +1 -0
  120. package/dist/commands/rollback.d.ts +4 -0
  121. package/dist/commands/rollback.js +12 -0
  122. package/dist/commands/rollback.js.map +1 -0
  123. package/dist/commands/update.d.ts +4 -0
  124. package/dist/commands/update.js +212 -0
  125. package/dist/commands/update.js.map +1 -0
  126. package/dist/commands/validate.d.ts +4 -0
  127. package/dist/commands/validate.js +222 -0
  128. package/dist/commands/validate.js.map +1 -0
  129. package/dist/commands/ws-commit.d.ts +5 -0
  130. package/dist/commands/ws-commit.js +39 -0
  131. package/dist/commands/ws-commit.js.map +1 -0
  132. package/dist/commands/ws-deliver.d.ts +5 -0
  133. package/dist/commands/ws-deliver.js +59 -0
  134. package/dist/commands/ws-deliver.js.map +1 -0
  135. package/dist/commands/ws-finish.d.ts +5 -0
  136. package/dist/commands/ws-finish.js +142 -0
  137. package/dist/commands/ws-finish.js.map +1 -0
  138. package/dist/commands/ws-handoff.d.ts +5 -0
  139. package/dist/commands/ws-handoff.js +35 -0
  140. package/dist/commands/ws-handoff.js.map +1 -0
  141. package/dist/commands/ws-migrate.d.ts +5 -0
  142. package/dist/commands/ws-migrate.js +41 -0
  143. package/dist/commands/ws-migrate.js.map +1 -0
  144. package/dist/commands/ws-plan-verify.d.ts +5 -0
  145. package/dist/commands/ws-plan-verify.js +38 -0
  146. package/dist/commands/ws-plan-verify.js.map +1 -0
  147. package/dist/commands/ws-pull.d.ts +5 -0
  148. package/dist/commands/ws-pull.js +26 -0
  149. package/dist/commands/ws-pull.js.map +1 -0
  150. package/dist/commands/ws-push.d.ts +5 -0
  151. package/dist/commands/ws-push.js +68 -0
  152. package/dist/commands/ws-push.js.map +1 -0
  153. package/dist/commands/ws-submodule-setup.d.ts +5 -0
  154. package/dist/commands/ws-submodule-setup.js +55 -0
  155. package/dist/commands/ws-submodule-setup.js.map +1 -0
  156. package/dist/commands/ws-verify-before-complete.d.ts +5 -0
  157. package/dist/commands/ws-verify-before-complete.js +35 -0
  158. package/dist/commands/ws-verify-before-complete.js.map +1 -0
  159. package/dist/dashboard/app.d.ts +1 -0
  160. package/dist/dashboard/app.js +370 -0
  161. package/dist/dashboard/app.js.map +1 -0
  162. package/dist/delegation/cli.d.ts +6 -0
  163. package/dist/delegation/cli.js +14 -0
  164. package/dist/delegation/cli.js.map +1 -0
  165. package/dist/delegation/index.d.ts +35 -0
  166. package/dist/delegation/index.js +118 -0
  167. package/dist/delegation/index.js.map +1 -0
  168. package/dist/errors.d.ts +8 -0
  169. package/dist/errors.js +11 -0
  170. package/dist/errors.js.map +1 -0
  171. package/dist/exec.d.ts +9 -0
  172. package/dist/exec.js +22 -0
  173. package/dist/exec.js.map +1 -0
  174. package/dist/fs.d.ts +9 -0
  175. package/dist/fs.js +62 -0
  176. package/dist/fs.js.map +1 -0
  177. package/dist/governance.d.ts +10 -0
  178. package/dist/governance.js +135 -0
  179. package/dist/governance.js.map +1 -0
  180. package/dist/hash.d.ts +3 -0
  181. package/dist/hash.js +13 -0
  182. package/dist/hash.js.map +1 -0
  183. package/dist/hooks/deploy-claude.d.ts +13 -0
  184. package/dist/hooks/deploy-claude.js +67 -0
  185. package/dist/hooks/deploy-claude.js.map +1 -0
  186. package/dist/journal.d.ts +22 -0
  187. package/dist/journal.js +112 -0
  188. package/dist/journal.js.map +1 -0
  189. package/dist/json-schema-lite.d.ts +22 -0
  190. package/dist/json-schema-lite.js +148 -0
  191. package/dist/json-schema-lite.js.map +1 -0
  192. package/dist/managed-blocks.d.ts +24 -0
  193. package/dist/managed-blocks.js +84 -0
  194. package/dist/managed-blocks.js.map +1 -0
  195. package/dist/manifest.d.ts +24 -0
  196. package/dist/manifest.js +145 -0
  197. package/dist/manifest.js.map +1 -0
  198. package/dist/opencode-env.d.ts +62 -0
  199. package/dist/opencode-env.js +178 -0
  200. package/dist/opencode-env.js.map +1 -0
  201. package/dist/path-utils.d.ts +2 -0
  202. package/dist/path-utils.js +8 -0
  203. package/dist/path-utils.js.map +1 -0
  204. package/dist/spec.d.ts +17 -0
  205. package/dist/spec.js +174 -0
  206. package/dist/spec.js.map +1 -0
  207. package/dist/template.d.ts +20 -0
  208. package/dist/template.js +123 -0
  209. package/dist/template.js.map +1 -0
  210. package/dist/workspace.d.ts +4 -0
  211. package/dist/workspace.js +19 -0
  212. package/dist/workspace.js.map +1 -0
  213. package/package.json +11 -3
  214. package/src/aiws-package.js +0 -15
  215. package/src/backup.js +0 -149
  216. package/src/cli.js +0 -647
  217. package/src/codex-prompts.js +0 -74
  218. package/src/codex-skills.js +0 -111
  219. package/src/commands/change-advice.js +0 -200
  220. package/src/commands/change-evidence-command.js +0 -242
  221. package/src/commands/change-evidence-entry.js +0 -40
  222. package/src/commands/change-evidence.js +0 -340
  223. package/src/commands/change-finish.js +0 -484
  224. package/src/commands/change-git-status.js +0 -53
  225. package/src/commands/change-lifecycle.js +0 -236
  226. package/src/commands/change-metrics-command.js +0 -110
  227. package/src/commands/change-next-command.js +0 -129
  228. package/src/commands/change-review-gates.js +0 -315
  229. package/src/commands/change-scope-gate.js +0 -34
  230. package/src/commands/change-start.js +0 -120
  231. package/src/commands/change-state-command.js +0 -40
  232. package/src/commands/change-status-command.js +0 -134
  233. package/src/commands/change-status-context.js +0 -202
  234. package/src/commands/change-task-stats.js +0 -64
  235. package/src/commands/change-validate-entry.js +0 -45
  236. package/src/commands/change-validate.js +0 -127
  237. package/src/commands/change.js +0 -2087
  238. package/src/commands/codex-install-prompts.js +0 -68
  239. package/src/commands/codex-install-skills.js +0 -74
  240. package/src/commands/codex-status-prompts.js +0 -55
  241. package/src/commands/codex-status-skills.js +0 -63
  242. package/src/commands/codex-uninstall-prompts.js +0 -55
  243. package/src/commands/codex-uninstall-skills.js +0 -62
  244. package/src/commands/dashboard.js +0 -205
  245. package/src/commands/hooks-install.js +0 -92
  246. package/src/commands/hooks-status.js +0 -95
  247. package/src/commands/init.js +0 -93
  248. package/src/commands/opencode-status.js +0 -61
  249. package/src/commands/rollback.js +0 -13
  250. package/src/commands/update.js +0 -133
  251. package/src/commands/validate.js +0 -222
  252. package/src/dashboard/app.js +0 -371
  253. package/src/errors.js +0 -15
  254. package/src/exec.js +0 -34
  255. package/src/fs.js +0 -91
  256. package/src/governance.js +0 -159
  257. package/src/hash.js +0 -25
  258. package/src/json-schema-lite.js +0 -164
  259. package/src/managed-blocks.js +0 -131
  260. package/src/manifest.js +0 -153
  261. package/src/opencode-env.js +0 -76
  262. package/src/path-utils.js +0 -20
  263. package/src/spec.js +0 -195
  264. package/src/template.js +0 -187
  265. package/src/workspace.js +0 -23
  266. /package/{src → dist}/dashboard/index.html +0 -0
  267. /package/{src → dist}/dashboard/style.css +0 -0
@@ -0,0 +1,142 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { UserError } from "../errors.js";
5
+ /**
6
+ * aiws finish — ff-merge + push + archive
7
+ * @param {{ cwd?: string, changeId?: string, into?: string, push?: boolean, remote?: string }} opts
8
+ */
9
+ export async function wsFinishCommand({ cwd = ".", changeId, into, push = false, remote = "origin" } = {}) {
10
+ checkClean(cwd);
11
+ if (!changeId) {
12
+ changeId = detectChangeBranch(cwd);
13
+ }
14
+ if (!changeId) {
15
+ throw new UserError("Could not detect change ID. Provide as argument or be on a change branch.", { exitCode: 2 });
16
+ }
17
+ const targetBranch = into || "main";
18
+ // Validate before complete
19
+ try {
20
+ execSync(`npx -y @aipper/aiws change validate ${changeId} --strict 2>/dev/null`, { cwd, stdio: "inherit" });
21
+ }
22
+ catch {
23
+ throw new UserError(`Validation failed for ${changeId}. Fix issues first.`, { exitCode: 1 });
24
+ }
25
+ // FF merge
26
+ const changeBranch = `change/${changeId}`;
27
+ const branchExists = execSync(`git branch --list '${changeBranch}'`, { cwd, encoding: "utf8" }).trim();
28
+ if (branchExists) {
29
+ console.log(`info: ff-merging ${changeBranch} → ${targetBranch}...`);
30
+ execSync(`git checkout ${targetBranch}`, { cwd, stdio: "inherit" });
31
+ execSync(`git merge --ff-only ${changeBranch}`, { cwd, stdio: "inherit" });
32
+ }
33
+ else {
34
+ console.log("info: no change branch found, using current branch");
35
+ }
36
+ // Push
37
+ if (push) {
38
+ const currentBranch = execSync("git branch --show-current", { cwd, encoding: "utf8" }).trim();
39
+ // Push submodules first
40
+ if (existsSync(`${cwd}/.gitmodules`)) {
41
+ const targetsFile = `.aiws/changes/${changeId}/submodules.targets`;
42
+ if (existsSync(targetsFile)) {
43
+ const content = execSync(`cat "${targetsFile}"`, { cwd, encoding: "utf8" });
44
+ for (const line of content.split("\n")) {
45
+ const t = line.trim();
46
+ if (!t || t.startsWith("#"))
47
+ continue;
48
+ const [subPath, targetBranch] = t.split(/\s+/);
49
+ if (subPath && targetBranch) {
50
+ console.log(`info: pushing submodule ${subPath}...`);
51
+ execSync(`git push ${remote} ${targetBranch}`, { cwd: `${cwd}/${subPath}`, stdio: "inherit" });
52
+ }
53
+ }
54
+ }
55
+ }
56
+ execSync(`git push ${remote} ${currentBranch}`, { cwd, stdio: "inherit" });
57
+ }
58
+ const promotionCandidates = collectSpecPromotionCandidates(cwd, changeId);
59
+ // Archive
60
+ try {
61
+ execSync(`npx -y @aipper/aiws change archive ${changeId} --force 2>/dev/null || aiws change archive ${changeId} --force 2>/dev/null || true`, { cwd, stdio: "inherit" });
62
+ }
63
+ catch { /* ignore archive failure — main flow done */ }
64
+ // Session journal write
65
+ try {
66
+ const journalDir = join(cwd, ".aiws", "journal");
67
+ mkdirSync(journalDir, { recursive: true });
68
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
69
+ const journalEntry = [
70
+ "---",
71
+ `timestamp: ${new Date().toISOString()}`,
72
+ `changeId: ${changeId}`,
73
+ `phase: finished`,
74
+ `action: finish`,
75
+ `targetBranch: ${targetBranch}`,
76
+ `pushed: ${push}`,
77
+ "---",
78
+ "",
79
+ `## Finish Summary`,
80
+ "",
81
+ `Change **${changeId}** completed via \`aiws ws-finish\`.`,
82
+ `- Merged: change/${changeId} → ${targetBranch}`,
83
+ push ? `- Pushed: yes` : `- Pushed: no`,
84
+ `- Archived: yes`,
85
+ "",
86
+ `### Spec Promotion Candidates`,
87
+ "",
88
+ ].join("\n");
89
+ writeFileSync(join(journalDir, `${timestamp}-finish-${changeId}.md`), journalEntry, "utf8");
90
+ console.log(`info: journal written to .aiws/journal/${timestamp}-finish-${changeId}.md`);
91
+ }
92
+ catch (e) {
93
+ console.log(`warn: journal write failed (non-blocking): ${e instanceof Error ? e.message : String(e)}`);
94
+ }
95
+ // Spec promotion: scan change artifacts for candidate updates
96
+ try {
97
+ if (promotionCandidates.length > 0) {
98
+ console.log("\n---");
99
+ console.log("info: Spec promotion candidates detected:");
100
+ for (const c of promotionCandidates) {
101
+ console.log(` - ${c.file} (${c.source})`);
102
+ }
103
+ console.log("info: Review and manually run aiws update if managed block updates are needed.");
104
+ console.log("---\n");
105
+ }
106
+ }
107
+ catch {
108
+ // spec promotion scan is non-blocking
109
+ }
110
+ console.log(`ok: finish complete. ${push ? "Pushed and " : ""}Archived.`);
111
+ }
112
+ function checkClean(cwd) {
113
+ const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
114
+ if (out) {
115
+ throw new UserError("Working tree is not clean. Commit or stash first.", { exitCode: 2 });
116
+ }
117
+ }
118
+ function detectChangeBranch(cwd) {
119
+ const branch = execSync("git branch --show-current", { cwd, encoding: "utf8" }).trim();
120
+ const match = branch.match(/^(?:change|changes|ws|ws-change)\/(.+)$/);
121
+ return match ? match[1] : null;
122
+ }
123
+ function collectSpecPromotionCandidates(cwd, changeId) {
124
+ const candidates = [];
125
+ const changeDir = join(cwd, ".aiws", "changes", changeId);
126
+ const proposalPath = join(changeDir, "proposal.md");
127
+ if (existsSync(proposalPath)) {
128
+ const proposal = readFileSync(proposalPath, "utf8");
129
+ if (proposal.includes("Update:") || proposal.includes("Spec:") || proposal.includes("managed block")) {
130
+ candidates.push({ file: "proposal.md", source: "proposal.md markers" });
131
+ }
132
+ }
133
+ const tasksPath = join(changeDir, "tasks.md");
134
+ if (existsSync(tasksPath)) {
135
+ const tasks = readFileSync(tasksPath, "utf8");
136
+ if (tasks.includes("AGENTS.md") || tasks.includes("AI_PROJECT.md") || tasks.includes("REQUIREMENTS.md") || tasks.includes("AI_WORKSPACE.md")) {
137
+ candidates.push({ file: "tasks.md", source: "task spec references" });
138
+ }
139
+ }
140
+ return candidates;
141
+ }
142
+ //# sourceMappingURL=ws-finish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-finish.js","sourceRoot":"","sources":["../../src/commands/ws-finish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws handoff — read/display handoff documents
3
+ * @param {{ cwd?: string }} opts
4
+ */
5
+ export declare function wsHandoffCommand({ cwd }?: any): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ /**
3
+ * aiws handoff — read/display handoff documents
4
+ * @param {{ cwd?: string }} opts
5
+ */
6
+ export async function wsHandoffCommand({ cwd = "." } = {}) {
7
+ const changesDir = `${cwd}/.aiws/changes`;
8
+ if (!existsSync(changesDir)) {
9
+ console.log("info: no .aiws/changes/ directory found");
10
+ return;
11
+ }
12
+ // Check archive handoffs first
13
+ const archiveDir = `${changesDir}/archive`;
14
+ if (existsSync(archiveDir)) {
15
+ const archives = readdirSync(archiveDir).filter(f => f !== ".DS_Store");
16
+ for (const a of archives) {
17
+ const hf = `${archiveDir}/${a}/handoff.md`;
18
+ if (existsSync(hf)) {
19
+ console.log(`=== ${a} ===`);
20
+ console.log(readFileSync(hf, "utf8"));
21
+ }
22
+ }
23
+ }
24
+ // Check active change handoffs
25
+ const changes = readdirSync(changesDir).filter(f => !f.startsWith(".") && f !== "templates" && f !== "archive" && f !== "README.md");
26
+ for (const c of changes) {
27
+ const hf = `${changesDir}/${c}/handoff.md`;
28
+ if (existsSync(hf)) {
29
+ console.log(`=== ${c} (active) ===`);
30
+ console.log(readFileSync(hf, "utf8"));
31
+ }
32
+ }
33
+ console.log("info: handoffs are generated by aiws change finish --push");
34
+ }
35
+ //# sourceMappingURL=ws-handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-handoff.js","sourceRoot":"","sources":["../../src/commands/ws-handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAE,GAAG,GAAG,GAAG,KAAK,EAAS;IAC9D,MAAM,UAAU,GAAG,GAAG,GAAG,gBAAgB,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,+BAA+B;IAC/B,MAAM,UAAU,GAAG,GAAG,UAAU,UAAU,CAAC;IAC3C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,GAAG,UAAU,IAAI,CAAC,aAAa,CAAC;YAC3C,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACjD,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,WAAW,CAChF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,GAAG,UAAU,IAAI,CAAC,aAAa,CAAC;QAC3C,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws migrate — workspace migration (init or update)
3
+ * @param {{ cwd?: string }} opts
4
+ */
5
+ export declare function wsMigrateCommand({ cwd }?: any): Promise<void>;
@@ -0,0 +1,41 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ /**
4
+ * aiws migrate — workspace migration (init or update)
5
+ * @param {{ cwd?: string }} opts
6
+ */
7
+ export async function wsMigrateCommand({ cwd = "." } = {}) {
8
+ const localAiws = `${cwd}/node_modules/.bin/aiws`;
9
+ if (existsSync(`${cwd}/.aiws/manifest.json`)) {
10
+ console.log("info: workspace detected, running update...");
11
+ runAiws(localAiws, `update ${cwd}`);
12
+ }
13
+ else {
14
+ console.log("info: no workspace detected, running init...");
15
+ runAiws(localAiws, `init ${cwd}`);
16
+ }
17
+ // Enable hooks
18
+ try {
19
+ execSync("git config core.hooksPath .githooks", { cwd, stdio: "inherit" });
20
+ console.log("info: hooks enabled (core.hooksPath=.githooks)");
21
+ }
22
+ catch {
23
+ console.log("warn: could not set hooks (not a git repo?)");
24
+ }
25
+ console.log("ok: migrate complete");
26
+ }
27
+ function runAiws(localAiws, args) {
28
+ try {
29
+ if (existsSync(localAiws)) {
30
+ execSync(`${localAiws} ${args}`, { stdio: "inherit" });
31
+ }
32
+ else {
33
+ execSync(`npx -y @aipper/aiws ${args}`, { stdio: "inherit" });
34
+ }
35
+ }
36
+ catch (e) {
37
+ console.error(`error: aiws ${args} failed`);
38
+ throw e;
39
+ }
40
+ }
41
+ //# sourceMappingURL=ws-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-migrate.js","sourceRoot":"","sources":["../../src/commands/ws-migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAE,GAAG,GAAG,GAAG,KAAK,EAAS;IAC9D,MAAM,SAAS,GAAG,GAAG,GAAG,yBAAyB,CAAC;IAElD,IAAI,UAAU,CAAC,GAAG,GAAG,sBAAsB,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,CAAC,SAAS,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,eAAe;IACf,IAAI,CAAC;QACH,QAAQ,CAAC,qCAAqC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,OAAO,CAAC,SAAc,EAAE,IAAS;IACxC,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,GAAG,SAAS,IAAI,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,uBAAuB,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC,CAAC;QAC5C,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws plan-verify — check plan completeness
3
+ * @param {{ cwd?: string }} opts
4
+ */
5
+ export declare function wsPlanVerifyCommand({ cwd }?: any): Promise<void>;
@@ -0,0 +1,38 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { UserError } from "../errors.js";
3
+ /**
4
+ * aiws plan-verify — check plan completeness
5
+ * @param {{ cwd?: string }} opts
6
+ */
7
+ export async function wsPlanVerifyCommand({ cwd = "." } = {}) {
8
+ const planDir = `${cwd}/plan`;
9
+ if (!existsSync(planDir)) {
10
+ throw new UserError("No plan/ directory found", { exitCode: 2 });
11
+ }
12
+ const plans = readdirSync(planDir).filter(f => f.endsWith(".md"));
13
+ if (plans.length === 0) {
14
+ throw new UserError("No plan files found in plan/", { exitCode: 2 });
15
+ }
16
+ const failures = [];
17
+ for (const planFile of plans) {
18
+ const content = readFileSync(`${planDir}/${planFile}`, "utf8");
19
+ const checks = [];
20
+ checks.push({ name: "Goal", pass: /^##?\s*Goal/im.test(content) });
21
+ checks.push({ name: "Non-goals", pass: /^##?\s*Non-goals/im.test(content) });
22
+ checks.push({ name: "Scope", pass: /^##?\s*(Scope|In Scope)/im.test(content) });
23
+ checks.push({ name: "Verify", pass: /^##?\s*Verify/im.test(content) });
24
+ checks.push({ name: "Risks", pass: /^##?\s*Risks/im.test(content) });
25
+ const failed = checks.filter(c => !c.pass);
26
+ if (failed.length > 0) {
27
+ failures.push({ file: planFile, missing: failed.map(c => c.name) });
28
+ }
29
+ }
30
+ if (failures.length > 0) {
31
+ for (const f of failures) {
32
+ console.error(`error: ${f.file} missing sections: ${f.missing.join(", ")}`);
33
+ }
34
+ throw new UserError("Plan verification failed. Fix missing sections.", { exitCode: 1 });
35
+ }
36
+ console.log("ok: plan verification passed");
37
+ }
38
+ //# sourceMappingURL=ws-plan-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-plan-verify.js","sourceRoot":"","sources":["../../src/commands/ws-plan-verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAE,GAAG,GAAG,GAAG,KAAK,EAAS;IACjE,MAAM,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC;IAC9B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,SAAS,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,OAAO,IAAI,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,EAAE,CAAC;QAElB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAErE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,iDAAiD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws pull — git pull --ff-only + submodule sync
3
+ * @param {{ cwd?: string }} opts
4
+ */
5
+ export declare function wsPullCommand({ cwd }?: any): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws pull — git pull --ff-only + submodule sync
6
+ * @param {{ cwd?: string }} opts
7
+ */
8
+ export async function wsPullCommand({ cwd = "." } = {}) {
9
+ checkClean(cwd);
10
+ // git pull --ff-only
11
+ execSync("git pull --ff-only", { cwd, stdio: "inherit" });
12
+ // submodule sync if .gitmodules exists
13
+ if (existsSync(`${cwd}/.gitmodules`)) {
14
+ console.log("info: submodules detected, syncing...");
15
+ execSync("git submodule sync --recursive", { cwd, stdio: "inherit" });
16
+ execSync("git submodule update --init --recursive", { cwd, stdio: "inherit" });
17
+ }
18
+ console.log("ok: pull complete");
19
+ }
20
+ function checkClean(cwd) {
21
+ const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
22
+ if (out) {
23
+ throw new UserError("Working tree is not clean. Commit or stash first.", { exitCode: 2 });
24
+ }
25
+ }
26
+ //# sourceMappingURL=ws-pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-pull.js","sourceRoot":"","sources":["../../src/commands/ws-pull.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,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,KAAK,EAAS;IAC3D,UAAU,CAAC,GAAG,CAAC,CAAC;IAEhB,qBAAqB;IACrB,QAAQ,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE1D,uCAAuC;IACvC,IAAI,UAAU,CAAC,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,QAAQ,CAAC,gCAAgC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACtE,QAAQ,CAAC,yCAAyC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACnC,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,GAAG,EAAE,CAAC;QACR,MAAM,IAAI,SAAS,CAAC,mDAAmD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws push — submodule-aware push (submodules first, then superproject)
3
+ * @param {{ cwd?: string, remote?: string }} opts
4
+ */
5
+ export declare function wsPushCommand({ cwd, remote }?: any): Promise<void>;
@@ -0,0 +1,68 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws push — submodule-aware push (submodules first, then superproject)
6
+ * @param {{ cwd?: string, remote?: string }} opts
7
+ */
8
+ export async function wsPushCommand({ cwd = ".", remote = "origin" } = {}) {
9
+ checkClean(cwd);
10
+ if (existsSync(`${cwd}/.gitmodules`)) {
11
+ pushSubmodules(cwd, remote);
12
+ }
13
+ const branch = execSync("git branch --show-current", { cwd, encoding: "utf8" }).trim();
14
+ console.log(`info: pushing ${branch} to ${remote}...`);
15
+ try {
16
+ execSync(`git push ${remote} ${branch}`, { cwd, stdio: "inherit" });
17
+ }
18
+ catch {
19
+ throw new UserError("Push failed. Check for diverged branch.", { exitCode: 1 });
20
+ }
21
+ console.log("ok: push complete");
22
+ }
23
+ function pushSubmodules(cwd, remote) {
24
+ const targetFile = findSubmodulesTargets(cwd);
25
+ if (!targetFile) {
26
+ console.log("info: no submodules.targets found, skipping submodule push");
27
+ return;
28
+ }
29
+ const content = readFileSync(targetFile, "utf8");
30
+ for (const line of content.split("\n")) {
31
+ const trimmed = line.trim();
32
+ if (!trimmed || trimmed.startsWith("#"))
33
+ continue;
34
+ const [subPath, targetBranch, rmt = remote] = trimmed.split(/\s+/);
35
+ if (!subPath || !targetBranch)
36
+ continue;
37
+ console.log(`info: pushing submodule ${subPath} (${targetBranch})...`);
38
+ try {
39
+ execSync(`git push ${rmt} ${targetBranch}`, { cwd: `${cwd}/${subPath}`, stdio: "inherit" });
40
+ }
41
+ catch {
42
+ throw new UserError(`Failed to push submodule ${subPath}`, { exitCode: 1 });
43
+ }
44
+ }
45
+ }
46
+ function findSubmodulesTargets(cwd) {
47
+ const paths = [
48
+ `${cwd}/.aiws/changes/*/submodules.targets`,
49
+ ];
50
+ // Find first match using shell expansion
51
+ try {
52
+ const out = execSync("ls .aiws/changes/*/submodules.targets 2>/dev/null || true", { cwd, encoding: "utf8" }).trim();
53
+ if (out) {
54
+ const first = out.split("\n")[0];
55
+ if (first)
56
+ return `${cwd}/${first}`;
57
+ }
58
+ }
59
+ catch { /* ignore */ }
60
+ return null;
61
+ }
62
+ function checkClean(cwd) {
63
+ const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
64
+ if (out) {
65
+ throw new UserError("Working tree is not clean. Commit or stash first.", { exitCode: 2 });
66
+ }
67
+ }
68
+ //# sourceMappingURL=ws-push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-push.js","sourceRoot":"","sources":["../../src/commands/ws-push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws submodule-setup — set .gitmodules branch for each submodule
3
+ * @param {{ cwd?: string, branch?: string }} opts
4
+ */
5
+ export declare function wsSubmoduleSetupCommand({ cwd, branch }?: any): Promise<void>;
@@ -0,0 +1,55 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws submodule-setup — set .gitmodules branch for each submodule
6
+ * @param {{ cwd?: string, branch?: string }} opts
7
+ */
8
+ export async function wsSubmoduleSetupCommand({ cwd = ".", branch = "main" } = {}) {
9
+ checkClean(cwd);
10
+ if (!existsSync(`${cwd}/.gitmodules`)) {
11
+ console.log("info: no .gitmodules found, nothing to configure");
12
+ return;
13
+ }
14
+ // List submodules
15
+ const out = execSync("git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$'", {
16
+ cwd, encoding: "utf8",
17
+ }).trim();
18
+ if (!out) {
19
+ console.log("info: no submodules in .gitmodules");
20
+ return;
21
+ }
22
+ const lines = out.split("\n");
23
+ for (const line of lines) {
24
+ const parts = line.trim().split(/\s+/);
25
+ if (parts.length < 2)
26
+ continue;
27
+ const key = parts[0]; // submodule.<name>.path
28
+ const subPath = parts[1];
29
+ const name = key.replace(/^submodule\./, "").replace(/\.path$/, "");
30
+ // Check if branch already set
31
+ const existing = execSync(`git config --file .gitmodules --get submodule.${name}.branch 2>/dev/null || true`, { cwd, encoding: "utf8" }).trim();
32
+ if (existing) {
33
+ console.log(`info: ${subPath} branch already set: ${existing}`);
34
+ continue;
35
+ }
36
+ // Detect current branch
37
+ let detected = branch;
38
+ try {
39
+ const current = execSync(`git -C "${subPath}" branch --show-current 2>/dev/null || true`, { cwd, encoding: "utf8" }).trim();
40
+ if (current)
41
+ detected = current;
42
+ }
43
+ catch { /* use default */ }
44
+ console.log(`info: setting ${subPath} branch → ${detected}`);
45
+ execSync(`git submodule set-branch --branch ${detected} ${name}`, { cwd, stdio: "inherit" });
46
+ }
47
+ console.log("ok: submodule branches configured. Review .gitmodules changes before committing.");
48
+ }
49
+ function checkClean(cwd) {
50
+ const out = execSync("git status --porcelain", { cwd, encoding: "utf8" }).trim();
51
+ if (out) {
52
+ throw new UserError("Working tree is not clean. Commit or stash first.", { exitCode: 2 });
53
+ }
54
+ }
55
+ //# sourceMappingURL=ws-submodule-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-submodule-setup.js","sourceRoot":"","sources":["../../src/commands/ws-submodule-setup.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,uBAAuB,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,EAAS;IACtF,UAAU,CAAC,GAAG,CAAC,CAAC;IAEhB,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,kBAAkB;IAClB,MAAM,GAAG,GAAG,QAAQ,CAAC,sEAAsE,EAAE;QAC3F,GAAG,EAAE,QAAQ,EAAE,MAAM;KACtB,CAAC,CAAC,IAAI,EAAE,CAAC;IAEV,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,wBAAwB;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEpE,8BAA8B;QAC9B,MAAM,QAAQ,GAAG,QAAQ,CACvB,iDAAiD,IAAI,6BAA6B,EAClF,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAC1B,CAAC,IAAI,EAAE,CAAC;QAET,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,wBAAwB,QAAQ,EAAE,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,IAAI,QAAQ,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,OAAO,6CAA6C,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5H,IAAI,OAAO;gBAAE,QAAQ,GAAG,OAAO,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE7B,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,aAAa,QAAQ,EAAE,CAAC,CAAC;QAC7D,QAAQ,CAAC,qCAAqC,QAAQ,IAAI,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC;AAClG,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,GAAG,EAAE,CAAC;QACR,MAAM,IAAI,SAAS,CAAC,mDAAmD,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * aiws verify-bc — verify before complete (check review + validate)
3
+ * @param {{ cwd?: string }} opts
4
+ */
5
+ export declare function wsVerifyBeforeCompleteCommand({ cwd }?: any): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import { existsSync, readdirSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { UserError } from "../errors.js";
4
+ /**
5
+ * aiws verify-bc — verify before complete (check review + validate)
6
+ * @param {{ cwd?: string }} opts
7
+ */
8
+ export async function wsVerifyBeforeCompleteCommand({ cwd = "." } = {}) {
9
+ const missing = [];
10
+ // Check spec-review
11
+ const changesDir = path.join(cwd, ".aiws", "changes");
12
+ if (existsSync(changesDir)) {
13
+ const changes = readdirSync(changesDir).filter(f => !f.startsWith(".") && f !== "templates" && f !== "archive");
14
+ const hasSpecReview = changes.some(c => existsSync(path.join(changesDir, c, "review", "spec-review.md")));
15
+ const hasQualityReview = changes.some(c => existsSync(path.join(changesDir, c, "review", "quality-review.md")));
16
+ if (!hasSpecReview)
17
+ missing.push("spec-review.md");
18
+ if (!hasQualityReview)
19
+ missing.push("quality-review.md");
20
+ }
21
+ else {
22
+ missing.push(".aiws/changes/ directory not found");
23
+ }
24
+ // Check validate stamp
25
+ const stampDir = path.join(cwd, ".aiws", "tmp", "aiws-validate");
26
+ const hasStamp = existsSync(stampDir) && readdirSync(stampDir).some(f => f.endsWith(".json"));
27
+ if (!hasStamp) {
28
+ console.log("warn: no validate stamp found. Run aiws validate . --stamp");
29
+ }
30
+ if (missing.length > 0) {
31
+ throw new UserError(`Missing gates: ${missing.join(", ")}`, { exitCode: 1 });
32
+ }
33
+ console.log("ok: all gates passed");
34
+ }
35
+ //# sourceMappingURL=ws-verify-before-complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-verify-before-complete.js","sourceRoot":"","sources":["../../src/commands/ws-verify-before-complete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,EAAE,GAAG,GAAG,GAAG,KAAK,EAAS;IAC3E,MAAM,OAAO,GAAG,EAAE,CAAC;IAEnB,oBAAoB;IACpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;QAChH,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACrC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CACjE,CAAC;QACF,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACxC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CACpE,CAAC;QACF,IAAI,CAAC,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,CAAC,gBAAgB;YAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACrD,CAAC;IAED,uBAAuB;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CAAC,kBAAkB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};