@specship/specship-win32-arm64 0.25.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/bin/specship.cmd +31 -1
  2. package/lib/dist/activation/cheatsheet.d.ts +17 -1
  3. package/lib/dist/activation/cheatsheet.d.ts.map +1 -1
  4. package/lib/dist/activation/cheatsheet.js +47 -3
  5. package/lib/dist/activation/cheatsheet.js.map +1 -1
  6. package/lib/dist/activation/hook-output.d.ts +80 -0
  7. package/lib/dist/activation/hook-output.d.ts.map +1 -0
  8. package/lib/dist/activation/hook-output.js +103 -0
  9. package/lib/dist/activation/hook-output.js.map +1 -0
  10. package/lib/dist/activation/search-intercept.d.ts +60 -29
  11. package/lib/dist/activation/search-intercept.d.ts.map +1 -1
  12. package/lib/dist/activation/search-intercept.js +159 -55
  13. package/lib/dist/activation/search-intercept.js.map +1 -1
  14. package/lib/dist/activation/steering.d.ts +8 -10
  15. package/lib/dist/activation/steering.d.ts.map +1 -1
  16. package/lib/dist/activation/steering.js +21 -6
  17. package/lib/dist/activation/steering.js.map +1 -1
  18. package/lib/dist/behaviour/behaviour-surface.d.ts +47 -0
  19. package/lib/dist/behaviour/behaviour-surface.d.ts.map +1 -1
  20. package/lib/dist/behaviour/behaviour-surface.js +108 -2
  21. package/lib/dist/behaviour/behaviour-surface.js.map +1 -1
  22. package/lib/dist/bin/node-version-check.d.ts +22 -7
  23. package/lib/dist/bin/node-version-check.d.ts.map +1 -1
  24. package/lib/dist/bin/node-version-check.js +39 -9
  25. package/lib/dist/bin/node-version-check.js.map +1 -1
  26. package/lib/dist/bin/specship.js +762 -81
  27. package/lib/dist/bin/specship.js.map +1 -1
  28. package/lib/dist/commands/specship/learn.md +22 -0
  29. package/lib/dist/commands/specship/spec.md +12 -0
  30. package/lib/dist/db/sqlite-adapter.d.ts +7 -5
  31. package/lib/dist/db/sqlite-adapter.d.ts.map +1 -1
  32. package/lib/dist/db/sqlite-adapter.js +11 -9
  33. package/lib/dist/db/sqlite-adapter.js.map +1 -1
  34. package/lib/dist/enforce/changed-files.d.ts +11 -0
  35. package/lib/dist/enforce/changed-files.d.ts.map +1 -1
  36. package/lib/dist/enforce/changed-files.js +42 -0
  37. package/lib/dist/enforce/changed-files.js.map +1 -1
  38. package/lib/dist/enforce/enforce.d.ts +25 -1
  39. package/lib/dist/enforce/enforce.d.ts.map +1 -1
  40. package/lib/dist/enforce/enforce.js +58 -3
  41. package/lib/dist/enforce/enforce.js.map +1 -1
  42. package/lib/dist/enforce/mutation.d.ts +46 -0
  43. package/lib/dist/enforce/mutation.d.ts.map +1 -0
  44. package/lib/dist/enforce/mutation.js +104 -0
  45. package/lib/dist/enforce/mutation.js.map +1 -0
  46. package/lib/dist/enforce/suppressions.d.ts +33 -0
  47. package/lib/dist/enforce/suppressions.d.ts.map +1 -0
  48. package/lib/dist/enforce/suppressions.js +159 -0
  49. package/lib/dist/enforce/suppressions.js.map +1 -0
  50. package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
  51. package/lib/dist/extraction/specs/markdown-spec-extractor.js +16 -2
  52. package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
  53. package/lib/dist/graph/spec-coverage.d.ts +57 -1
  54. package/lib/dist/graph/spec-coverage.d.ts.map +1 -1
  55. package/lib/dist/graph/spec-coverage.js +129 -5
  56. package/lib/dist/graph/spec-coverage.js.map +1 -1
  57. package/lib/dist/health/smoke-check.js +2 -2
  58. package/lib/dist/health/smoke-check.js.map +1 -1
  59. package/lib/dist/index.d.ts +8 -3
  60. package/lib/dist/index.d.ts.map +1 -1
  61. package/lib/dist/index.js +65 -9
  62. package/lib/dist/index.js.map +1 -1
  63. package/lib/dist/installer/gemini-commands.d.ts +107 -0
  64. package/lib/dist/installer/gemini-commands.d.ts.map +1 -0
  65. package/lib/dist/installer/gemini-commands.js +264 -0
  66. package/lib/dist/installer/gemini-commands.js.map +1 -0
  67. package/lib/dist/installer/index.d.ts +23 -1
  68. package/lib/dist/installer/index.d.ts.map +1 -1
  69. package/lib/dist/installer/index.js +22 -3
  70. package/lib/dist/installer/index.js.map +1 -1
  71. package/lib/dist/installer/install-defaults.d.ts +19 -0
  72. package/lib/dist/installer/install-defaults.d.ts.map +1 -1
  73. package/lib/dist/installer/install-defaults.js +28 -0
  74. package/lib/dist/installer/install-defaults.js.map +1 -1
  75. package/lib/dist/installer/instructions-template.d.ts +22 -0
  76. package/lib/dist/installer/instructions-template.d.ts.map +1 -1
  77. package/lib/dist/installer/instructions-template.js +37 -1
  78. package/lib/dist/installer/instructions-template.js.map +1 -1
  79. package/lib/dist/installer/targets/claude.d.ts +4 -0
  80. package/lib/dist/installer/targets/claude.d.ts.map +1 -1
  81. package/lib/dist/installer/targets/claude.js +8 -25
  82. package/lib/dist/installer/targets/claude.js.map +1 -1
  83. package/lib/dist/installer/targets/gemini.d.ts +85 -12
  84. package/lib/dist/installer/targets/gemini.d.ts.map +1 -1
  85. package/lib/dist/installer/targets/gemini.js +527 -30
  86. package/lib/dist/installer/targets/gemini.js.map +1 -1
  87. package/lib/dist/installer/targets/shared.d.ts +13 -0
  88. package/lib/dist/installer/targets/shared.d.ts.map +1 -1
  89. package/lib/dist/installer/targets/shared.js +18 -0
  90. package/lib/dist/installer/targets/shared.js.map +1 -1
  91. package/lib/dist/installer/targets/types.d.ts +12 -0
  92. package/lib/dist/installer/targets/types.d.ts.map +1 -1
  93. package/lib/dist/jira/auto-publish.d.ts +71 -4
  94. package/lib/dist/jira/auto-publish.d.ts.map +1 -1
  95. package/lib/dist/jira/auto-publish.js +186 -17
  96. package/lib/dist/jira/auto-publish.js.map +1 -1
  97. package/lib/dist/jira/reconcile.d.ts +24 -1
  98. package/lib/dist/jira/reconcile.d.ts.map +1 -1
  99. package/lib/dist/jira/reconcile.js +46 -2
  100. package/lib/dist/jira/reconcile.js.map +1 -1
  101. package/lib/dist/jira/repo-config.d.ts +9 -0
  102. package/lib/dist/jira/repo-config.d.ts.map +1 -1
  103. package/lib/dist/jira/repo-config.js +11 -0
  104. package/lib/dist/jira/repo-config.js.map +1 -1
  105. package/lib/dist/jira/types.d.ts +7 -0
  106. package/lib/dist/jira/types.d.ts.map +1 -1
  107. package/lib/dist/jira/types.js.map +1 -1
  108. package/lib/dist/knowledge/enforce.d.ts +75 -0
  109. package/lib/dist/knowledge/enforce.d.ts.map +1 -0
  110. package/lib/dist/knowledge/enforce.js +250 -0
  111. package/lib/dist/knowledge/enforce.js.map +1 -0
  112. package/lib/dist/knowledge/facts.d.ts +33 -0
  113. package/lib/dist/knowledge/facts.d.ts.map +1 -0
  114. package/lib/dist/knowledge/facts.js +117 -0
  115. package/lib/dist/knowledge/facts.js.map +1 -0
  116. package/lib/dist/knowledge/proposals.d.ts +88 -0
  117. package/lib/dist/knowledge/proposals.d.ts.map +1 -0
  118. package/lib/dist/knowledge/proposals.js +360 -0
  119. package/lib/dist/knowledge/proposals.js.map +1 -0
  120. package/lib/dist/knowledge/stale.d.ts +64 -0
  121. package/lib/dist/knowledge/stale.d.ts.map +1 -0
  122. package/lib/dist/knowledge/stale.js +174 -0
  123. package/lib/dist/knowledge/stale.js.map +1 -0
  124. package/lib/dist/mcp/gemini-session.d.ts +50 -0
  125. package/lib/dist/mcp/gemini-session.d.ts.map +1 -0
  126. package/lib/dist/mcp/gemini-session.js +159 -0
  127. package/lib/dist/mcp/gemini-session.js.map +1 -0
  128. package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
  129. package/lib/dist/mcp/jira-tools.js +25 -0
  130. package/lib/dist/mcp/jira-tools.js.map +1 -1
  131. package/lib/dist/mcp/model-context.d.ts +22 -9
  132. package/lib/dist/mcp/model-context.d.ts.map +1 -1
  133. package/lib/dist/mcp/model-context.js +35 -13
  134. package/lib/dist/mcp/model-context.js.map +1 -1
  135. package/lib/dist/mcp/proxy.js +1 -1
  136. package/lib/dist/mcp/proxy.js.map +1 -1
  137. package/lib/dist/mcp/server-instructions.d.ts +16 -15
  138. package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
  139. package/lib/dist/mcp/server-instructions.js +67 -1
  140. package/lib/dist/mcp/server-instructions.js.map +1 -1
  141. package/lib/dist/mcp/session.js +1 -1
  142. package/lib/dist/mcp/session.js.map +1 -1
  143. package/lib/dist/mcp/spec-tools.d.ts +9 -1
  144. package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
  145. package/lib/dist/mcp/spec-tools.js +69 -21
  146. package/lib/dist/mcp/spec-tools.js.map +1 -1
  147. package/lib/dist/mcp/tools.d.ts +37 -1
  148. package/lib/dist/mcp/tools.d.ts.map +1 -1
  149. package/lib/dist/mcp/tools.js +120 -9
  150. package/lib/dist/mcp/tools.js.map +1 -1
  151. package/lib/dist/pulse/pulse.d.ts +93 -0
  152. package/lib/dist/pulse/pulse.d.ts.map +1 -0
  153. package/lib/dist/pulse/pulse.js +401 -0
  154. package/lib/dist/pulse/pulse.js.map +1 -0
  155. package/lib/dist/reflect/apply.d.ts.map +1 -1
  156. package/lib/dist/reflect/apply.js +38 -3
  157. package/lib/dist/reflect/apply.js.map +1 -1
  158. package/lib/dist/reflect/auto-sweep.d.ts +26 -0
  159. package/lib/dist/reflect/auto-sweep.d.ts.map +1 -0
  160. package/lib/dist/reflect/auto-sweep.js +90 -0
  161. package/lib/dist/reflect/auto-sweep.js.map +1 -0
  162. package/lib/dist/reflect/cli.d.ts +62 -0
  163. package/lib/dist/reflect/cli.d.ts.map +1 -0
  164. package/lib/dist/reflect/cli.js +163 -0
  165. package/lib/dist/reflect/cli.js.map +1 -0
  166. package/lib/dist/reflect/miner.d.ts.map +1 -1
  167. package/lib/dist/reflect/miner.js +119 -0
  168. package/lib/dist/reflect/miner.js.map +1 -1
  169. package/lib/dist/reflect/sweep.d.ts +1 -0
  170. package/lib/dist/reflect/sweep.d.ts.map +1 -1
  171. package/lib/dist/reflect/sweep.js +62 -13
  172. package/lib/dist/reflect/sweep.js.map +1 -1
  173. package/lib/dist/reflect/targets.d.ts +2 -0
  174. package/lib/dist/reflect/targets.d.ts.map +1 -1
  175. package/lib/dist/reflect/targets.js +33 -0
  176. package/lib/dist/reflect/targets.js.map +1 -1
  177. package/lib/dist/reflect/types.d.ts +19 -2
  178. package/lib/dist/reflect/types.d.ts.map +1 -1
  179. package/lib/dist/resolution/test-title-links.d.ts.map +1 -1
  180. package/lib/dist/resolution/test-title-links.js +3 -14
  181. package/lib/dist/resolution/test-title-links.js.map +1 -1
  182. package/lib/dist/server/routes/claude.js +15 -7
  183. package/lib/dist/server/routes/knowledge.js +118 -0
  184. package/lib/dist/server/server.js +2 -0
  185. package/lib/dist/spec-lint/lint.d.ts +1 -1
  186. package/lib/dist/spec-lint/lint.d.ts.map +1 -1
  187. package/lib/dist/spec-lint/lint.js +63 -2
  188. package/lib/dist/spec-lint/lint.js.map +1 -1
  189. package/lib/dist/spec-quality/criterion-ids.d.ts +13 -0
  190. package/lib/dist/spec-quality/criterion-ids.d.ts.map +1 -0
  191. package/lib/dist/spec-quality/criterion-ids.js +38 -0
  192. package/lib/dist/spec-quality/criterion-ids.js.map +1 -0
  193. package/lib/dist/spec-quality/evidence-kind.d.ts +54 -0
  194. package/lib/dist/spec-quality/evidence-kind.d.ts.map +1 -0
  195. package/lib/dist/spec-quality/evidence-kind.js +183 -0
  196. package/lib/dist/spec-quality/evidence-kind.js.map +1 -0
  197. package/lib/dist/spec-quality/link-persist.d.ts +65 -0
  198. package/lib/dist/spec-quality/link-persist.d.ts.map +1 -0
  199. package/lib/dist/spec-quality/link-persist.js +249 -0
  200. package/lib/dist/spec-quality/link-persist.js.map +1 -0
  201. package/lib/dist/spec-quality/plan-scope.d.ts +38 -0
  202. package/lib/dist/spec-quality/plan-scope.d.ts.map +1 -0
  203. package/lib/dist/spec-quality/plan-scope.js +129 -0
  204. package/lib/dist/spec-quality/plan-scope.js.map +1 -0
  205. package/lib/dist/spec-quality/postcheck.d.ts +85 -0
  206. package/lib/dist/spec-quality/postcheck.d.ts.map +1 -0
  207. package/lib/dist/spec-quality/postcheck.js +390 -0
  208. package/lib/dist/spec-quality/postcheck.js.map +1 -0
  209. package/lib/dist/spec-quality/readiness.d.ts +72 -0
  210. package/lib/dist/spec-quality/readiness.d.ts.map +1 -0
  211. package/lib/dist/spec-quality/readiness.js +226 -0
  212. package/lib/dist/spec-quality/readiness.js.map +1 -0
  213. package/lib/dist/workflows/agents/claude.d.ts +16 -0
  214. package/lib/dist/workflows/agents/claude.d.ts.map +1 -0
  215. package/lib/dist/workflows/agents/claude.js +82 -0
  216. package/lib/dist/workflows/agents/claude.js.map +1 -0
  217. package/lib/dist/workflows/agents/gemini.d.ts +21 -0
  218. package/lib/dist/workflows/agents/gemini.d.ts.map +1 -0
  219. package/lib/dist/workflows/agents/gemini.js +124 -0
  220. package/lib/dist/workflows/agents/gemini.js.map +1 -0
  221. package/lib/dist/workflows/agents/index.d.ts +28 -0
  222. package/lib/dist/workflows/agents/index.d.ts.map +1 -0
  223. package/lib/dist/workflows/agents/index.js +104 -0
  224. package/lib/dist/workflows/agents/index.js.map +1 -0
  225. package/lib/dist/workflows/agents/types.d.ts +55 -0
  226. package/lib/dist/workflows/agents/types.d.ts.map +1 -0
  227. package/lib/dist/workflows/agents/types.js +46 -0
  228. package/lib/dist/workflows/agents/types.js.map +1 -0
  229. package/lib/dist/workflows/batch.d.ts +63 -0
  230. package/lib/dist/workflows/batch.d.ts.map +1 -0
  231. package/lib/dist/workflows/batch.js +151 -0
  232. package/lib/dist/workflows/batch.js.map +1 -0
  233. package/lib/dist/workflows/defaults/claude-design-implement.yaml +3 -4
  234. package/lib/dist/workflows/defaults/spec-author.yaml +11 -9
  235. package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +21 -436
  236. package/lib/dist/workflows/defaults/spec-implement.yaml +465 -46
  237. package/lib/dist/workflows/discovery.d.ts +13 -0
  238. package/lib/dist/workflows/discovery.d.ts.map +1 -1
  239. package/lib/dist/workflows/discovery.js +79 -17
  240. package/lib/dist/workflows/discovery.js.map +1 -1
  241. package/lib/dist/workflows/executor.d.ts +18 -0
  242. package/lib/dist/workflows/executor.d.ts.map +1 -1
  243. package/lib/dist/workflows/executor.js +130 -33
  244. package/lib/dist/workflows/executor.js.map +1 -1
  245. package/lib/dist/workflows/gc.d.ts +50 -0
  246. package/lib/dist/workflows/gc.d.ts.map +1 -0
  247. package/lib/dist/workflows/gc.js +120 -0
  248. package/lib/dist/workflows/gc.js.map +1 -0
  249. package/lib/dist/workflows/merge-queue.d.ts +64 -0
  250. package/lib/dist/workflows/merge-queue.d.ts.map +1 -0
  251. package/lib/dist/workflows/merge-queue.js +162 -0
  252. package/lib/dist/workflows/merge-queue.js.map +1 -0
  253. package/lib/dist/workflows/runners/approval.d.ts +1 -1
  254. package/lib/dist/workflows/runners/approval.d.ts.map +1 -1
  255. package/lib/dist/workflows/runners/approval.js +11 -2
  256. package/lib/dist/workflows/runners/approval.js.map +1 -1
  257. package/lib/dist/workflows/runners/bash.d.ts +15 -0
  258. package/lib/dist/workflows/runners/bash.d.ts.map +1 -1
  259. package/lib/dist/workflows/runners/bash.js +50 -1
  260. package/lib/dist/workflows/runners/bash.js.map +1 -1
  261. package/lib/dist/workflows/runners/prompt.d.ts +16 -41
  262. package/lib/dist/workflows/runners/prompt.d.ts.map +1 -1
  263. package/lib/dist/workflows/runners/prompt.js +55 -120
  264. package/lib/dist/workflows/runners/prompt.js.map +1 -1
  265. package/lib/dist/workflows/runners/types.d.ts +12 -0
  266. package/lib/dist/workflows/runners/types.d.ts.map +1 -1
  267. package/lib/dist/workflows/schemas/workflow.d.ts +17 -0
  268. package/lib/dist/workflows/schemas/workflow.d.ts.map +1 -1
  269. package/lib/dist/workflows/schemas/workflow.js +27 -0
  270. package/lib/dist/workflows/schemas/workflow.js.map +1 -1
  271. package/lib/node_modules/.package-lock.json +1 -1
  272. package/lib/package.json +2 -2
  273. package/package.json +5 -3
  274. package/node.exe +0 -4
@@ -0,0 +1,50 @@
1
+ /**
2
+ * REQ-THRU-007 — collect the worktrees of merged runs.
3
+ *
4
+ * `specship workflow gc` purges the worktree of every run whose branch is
5
+ * merged into the default branch — the same way `specship workflow purge`
6
+ * does, so run records and artifacts are kept — and leaves unmerged runs
7
+ * untouched. `--dry-run` lists the candidates and removes nothing.
8
+ */
9
+ import { type GitFn } from './merge-queue';
10
+ export interface GcRun {
11
+ id: string;
12
+ status: string;
13
+ /** The run's branch (from its isolation env). */
14
+ branch?: string;
15
+ /** The run's worktree path (from its isolation env). */
16
+ workingPath?: string;
17
+ }
18
+ export interface GcCandidate {
19
+ runId: string;
20
+ branch: string;
21
+ workingPath: string;
22
+ }
23
+ export interface CollectMergedRunsOptions {
24
+ projectRoot: string;
25
+ dryRun?: boolean;
26
+ /** Runs that own (or owned) a worktree. */
27
+ listRuns: () => GcRun[];
28
+ /** Purge one run's worktree, keeping its record and artifacts (`workflow purge`). */
29
+ purge: (runId: string) => void;
30
+ git?: GitFn;
31
+ /** Override default-branch detection. */
32
+ defaultBranch?: string;
33
+ }
34
+ export interface CollectMergedRunsResult {
35
+ defaultBranch: string | null;
36
+ /** Merged runs whose worktree is (or, on a dry run, would be) removed. */
37
+ candidates: GcCandidate[];
38
+ /** Run ids actually purged (empty on a dry run). */
39
+ purged: string[];
40
+ /** Merged runs left alone, with why. */
41
+ skipped: Array<{
42
+ runId: string;
43
+ reason: string;
44
+ }>;
45
+ dryRun: boolean;
46
+ }
47
+ /** The default branch: origin's HEAD, else a local `main`, else `master`. */
48
+ export declare function detectDefaultBranch(projectRoot: string, git?: GitFn): string | null;
49
+ export declare function collectMergedRuns(opts: CollectMergedRunsOptions): CollectMergedRunsResult;
50
+ //# sourceMappingURL=gc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../src/workflows/gc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAc,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,qFAAqF;IACrF,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0EAA0E;IAC1E,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,oDAAoD;IACpD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wCAAwC;IACxC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,KAAkB,GAAG,MAAM,GAAG,IAAI,CAW/F;AAaD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,uBAAuB,CAwCzF"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ /**
3
+ * REQ-THRU-007 — collect the worktrees of merged runs.
4
+ *
5
+ * `specship workflow gc` purges the worktree of every run whose branch is
6
+ * merged into the default branch — the same way `specship workflow purge`
7
+ * does, so run records and artifacts are kept — and leaves unmerged runs
8
+ * untouched. `--dry-run` lists the candidates and removes nothing.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.detectDefaultBranch = detectDefaultBranch;
45
+ exports.collectMergedRuns = collectMergedRuns;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const pulse_1 = require("../pulse/pulse");
49
+ const merge_queue_1 = require("./merge-queue");
50
+ /** The default branch: origin's HEAD, else a local `main`, else `master`. */
51
+ function detectDefaultBranch(projectRoot, git = merge_queue_1.defaultGit) {
52
+ const sym = git(['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'], projectRoot);
53
+ if (sym.ok && sym.stdout.trim()) {
54
+ const name = sym.stdout.trim().replace(/^origin\//, '');
55
+ if (git(['rev-parse', '--verify', '--quiet', `refs/heads/${name}`], projectRoot).ok)
56
+ return name;
57
+ return `origin/${name}`;
58
+ }
59
+ for (const name of ['main', 'master']) {
60
+ if (git(['rev-parse', '--verify', '--quiet', `refs/heads/${name}`], projectRoot).ok)
61
+ return name;
62
+ }
63
+ return null;
64
+ }
65
+ function samePath(a, b) {
66
+ const norm = (p) => {
67
+ try {
68
+ return fs.realpathSync(p);
69
+ }
70
+ catch {
71
+ return path.resolve(p);
72
+ }
73
+ };
74
+ return norm(a) === norm(b);
75
+ }
76
+ function collectMergedRuns(opts) {
77
+ const git = opts.git ?? merge_queue_1.defaultGit;
78
+ const dryRun = opts.dryRun === true;
79
+ const base = opts.defaultBranch ?? detectDefaultBranch(opts.projectRoot, git);
80
+ const result = { defaultBranch: base, candidates: [], purged: [], skipped: [], dryRun };
81
+ if (!base)
82
+ return result;
83
+ const mergedOut = git(['branch', '--merged', base, '--format=%(refname:short)'], opts.projectRoot);
84
+ if (!mergedOut.ok)
85
+ throw new Error(`git branch --merged ${base} failed: ${mergedOut.stderr.trim()}`);
86
+ const merged = new Set(mergedOut.stdout.split(/\r?\n/).map((s) => s.trim()).filter(Boolean));
87
+ // Only worktrees still registered with git are on disk to collect.
88
+ const list = git(['worktree', 'list', '--porcelain'], opts.projectRoot);
89
+ const live = list.ok ? (0, pulse_1.parseWorktreePorcelain)(list.stdout).slice(1).filter((e) => !e.prunable) : [];
90
+ for (const run of opts.listRuns()) {
91
+ if (!run.branch || !run.workingPath)
92
+ continue;
93
+ if (!merged.has(run.branch))
94
+ continue; // A2 — unmerged runs are untouched
95
+ if (run.branch === base)
96
+ continue;
97
+ const onDisk = live.find((e) => samePath(e.path, run.workingPath));
98
+ if (!onDisk)
99
+ continue;
100
+ if (run.status === 'running' || run.status === 'paused') {
101
+ result.skipped.push({ runId: run.id, reason: `run is ${run.status}` });
102
+ continue;
103
+ }
104
+ // Never discard uncommitted work sitting in a worktree.
105
+ const dirty = git(['status', '--porcelain'], run.workingPath);
106
+ if (!dirty.ok || dirty.stdout.trim() !== '') {
107
+ result.skipped.push({ runId: run.id, reason: 'worktree has uncommitted changes' });
108
+ continue;
109
+ }
110
+ result.candidates.push({ runId: run.id, branch: run.branch, workingPath: run.workingPath });
111
+ }
112
+ if (dryRun)
113
+ return result; // A3 — list only
114
+ for (const c of result.candidates) {
115
+ opts.purge(c.runId); // A1 — worktree removed, record + artifacts kept
116
+ result.purged.push(c.runId);
117
+ }
118
+ return result;
119
+ }
120
+ //# sourceMappingURL=gc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc.js","sourceRoot":"","sources":["../../src/workflows/gc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * REQ-THRU-002 — merge completed runs through a queue that re-checks each merge.
3
+ *
4
+ * `specship workflow merge-queue <runId…>` merges each completed run's branch
5
+ * into the current branch in the given order, re-running the project's quality
6
+ * command after each merge. It stops at the first merge conflict (aborting the
7
+ * merge so no conflict markers remain) or the first failing check (resetting
8
+ * to the pre-merge HEAD), leaving the tree at the last good merge and naming
9
+ * the run that stopped it. Runs that are not completed are refused before any
10
+ * merge happens.
11
+ */
12
+ export interface GitResult {
13
+ ok: boolean;
14
+ stdout: string;
15
+ stderr: string;
16
+ }
17
+ export type GitFn = (args: string[], cwd: string) => GitResult;
18
+ export declare const defaultGit: GitFn;
19
+ /**
20
+ * The project's quality command — the same detection the implement
21
+ * workflows' quality gate uses: `npm run lint --if-present` when package.json
22
+ * has a lint script, else `npx --no-install tsc --noEmit` when tsconfig.json
23
+ * exists, else none.
24
+ */
25
+ export declare function detectQualityCommand(projectRoot: string): string | null;
26
+ export interface QualityResult {
27
+ ok: boolean;
28
+ /** The command that ran; undefined when the project has none. */
29
+ command?: string;
30
+ output?: string;
31
+ }
32
+ /** Run the detected quality command in `projectRoot`; no command = ok (skipped). */
33
+ export declare function defaultRunQuality(projectRoot: string): QualityResult;
34
+ export interface MergeQueueRun {
35
+ id: string;
36
+ status: string;
37
+ /** The run's branch (from its isolation env). */
38
+ branch?: string;
39
+ }
40
+ export type MergeQueueStopReason = 'not-found' | 'not-completed' | 'no-branch' | 'dirty-tree' | 'conflict' | 'quality-failed' | 'git-error';
41
+ export interface MergeQueueOptions {
42
+ projectRoot: string;
43
+ runIds: string[];
44
+ getRun: (runId: string) => MergeQueueRun | null;
45
+ runQuality?: (projectRoot: string) => QualityResult;
46
+ git?: GitFn;
47
+ }
48
+ export interface MergeQueueResult {
49
+ /** Run ids merged (and checked), in order. */
50
+ merged: string[];
51
+ /** The run that stopped the queue. */
52
+ stoppedAt?: string;
53
+ reason?: MergeQueueStopReason;
54
+ /** Human-readable explanation of the stop. */
55
+ detail?: string;
56
+ /** Runs refused up front (not found / not completed / no branch). */
57
+ refused?: Array<{
58
+ runId: string;
59
+ reason: MergeQueueStopReason;
60
+ detail: string;
61
+ }>;
62
+ }
63
+ export declare function runMergeQueue(opts: MergeQueueOptions): MergeQueueResult;
64
+ //# sourceMappingURL=merge-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-queue.d.ts","sourceRoot":"","sources":["../../src/workflows/merge-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;AAE/D,eAAO,MAAM,UAAU,EAAE,KAGxB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYvE;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAKpE;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,eAAe,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAE5I,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;IAChD,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,aAAa,CAAC;IACpD,GAAG,CAAC,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAyEvE"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * REQ-THRU-002 — merge completed runs through a queue that re-checks each merge.
4
+ *
5
+ * `specship workflow merge-queue <runId…>` merges each completed run's branch
6
+ * into the current branch in the given order, re-running the project's quality
7
+ * command after each merge. It stops at the first merge conflict (aborting the
8
+ * merge so no conflict markers remain) or the first failing check (resetting
9
+ * to the pre-merge HEAD), leaving the tree at the last good merge and naming
10
+ * the run that stopped it. Runs that are not completed are refused before any
11
+ * merge happens.
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.defaultGit = void 0;
48
+ exports.detectQualityCommand = detectQualityCommand;
49
+ exports.defaultRunQuality = defaultRunQuality;
50
+ exports.runMergeQueue = runMergeQueue;
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ const child_process_1 = require("child_process");
54
+ const defaultGit = (args, cwd) => {
55
+ const r = (0, child_process_1.spawnSync)('git', args, { cwd, encoding: 'utf-8', windowsHide: true });
56
+ return { ok: r.status === 0, stdout: r.stdout ?? '', stderr: r.stderr ?? (r.error ? r.error.message : '') };
57
+ };
58
+ exports.defaultGit = defaultGit;
59
+ /**
60
+ * The project's quality command — the same detection the implement
61
+ * workflows' quality gate uses: `npm run lint --if-present` when package.json
62
+ * has a lint script, else `npx --no-install tsc --noEmit` when tsconfig.json
63
+ * exists, else none.
64
+ */
65
+ function detectQualityCommand(projectRoot) {
66
+ const pkgPath = path.join(projectRoot, 'package.json');
67
+ if (fs.existsSync(pkgPath)) {
68
+ try {
69
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
70
+ if (pkg.scripts && typeof pkg.scripts.lint === 'string')
71
+ return 'npm run lint --if-present';
72
+ }
73
+ catch {
74
+ // unreadable package.json — fall through to the tsconfig check
75
+ }
76
+ }
77
+ if (fs.existsSync(path.join(projectRoot, 'tsconfig.json')))
78
+ return 'npx --no-install tsc --noEmit';
79
+ return null;
80
+ }
81
+ /** Run the detected quality command in `projectRoot`; no command = ok (skipped). */
82
+ function defaultRunQuality(projectRoot) {
83
+ const command = detectQualityCommand(projectRoot);
84
+ if (!command)
85
+ return { ok: true };
86
+ const r = (0, child_process_1.spawnSync)(command, { cwd: projectRoot, shell: true, encoding: 'utf-8', windowsHide: true });
87
+ return { ok: r.status === 0, command, output: `${r.stdout ?? ''}${r.stderr ?? ''}` };
88
+ }
89
+ function runMergeQueue(opts) {
90
+ const git = opts.git ?? exports.defaultGit;
91
+ const runQuality = opts.runQuality ?? defaultRunQuality;
92
+ const cwd = opts.projectRoot;
93
+ // A4 — refuse incomplete runs before any merge happens.
94
+ const runs = [];
95
+ const refused = [];
96
+ for (const id of opts.runIds) {
97
+ const run = opts.getRun(id);
98
+ if (!run) {
99
+ refused.push({ runId: id, reason: 'not-found', detail: `Run ${id} not found` });
100
+ }
101
+ else if (run.status !== 'completed') {
102
+ refused.push({ runId: id, reason: 'not-completed', detail: `Run ${id} is ${run.status}, not completed` });
103
+ }
104
+ else if (!run.branch) {
105
+ refused.push({ runId: id, reason: 'no-branch', detail: `Run ${id} has no branch to merge` });
106
+ }
107
+ else {
108
+ runs.push({ id, branch: run.branch });
109
+ }
110
+ }
111
+ if (refused.length > 0) {
112
+ const first = refused[0];
113
+ return { merged: [], stoppedAt: first.runId, reason: first.reason, detail: refused.map((r) => r.detail).join('; '), refused };
114
+ }
115
+ // A failed check is undone with `git reset --hard`; never let that discard
116
+ // the user's own uncommitted work.
117
+ const status = git(['status', '--porcelain', '--untracked-files=no'], cwd);
118
+ if (!status.ok || status.stdout.trim() !== '') {
119
+ return {
120
+ merged: [],
121
+ stoppedAt: runs[0]?.id,
122
+ reason: 'dirty-tree',
123
+ detail: status.ok ? 'Working tree has uncommitted changes — commit or stash them first' : status.stderr.trim(),
124
+ };
125
+ }
126
+ const merged = [];
127
+ for (const run of runs) {
128
+ const head = git(['rev-parse', 'HEAD'], cwd);
129
+ if (!head.ok)
130
+ return { merged, stoppedAt: run.id, reason: 'git-error', detail: head.stderr.trim() };
131
+ const preMerge = head.stdout.trim();
132
+ const merge = git(['merge', '--no-ff', '--no-edit', run.branch], cwd);
133
+ if (!merge.ok) {
134
+ // A2 — leave no conflict markers: abort back to the last good merge.
135
+ const conflicted = git(['diff', '--name-only', '--diff-filter=U'], cwd).stdout.trim();
136
+ git(['merge', '--abort'], cwd);
137
+ git(['reset', '--hard', preMerge], cwd);
138
+ return {
139
+ merged,
140
+ stoppedAt: run.id,
141
+ reason: conflicted ? 'conflict' : 'git-error',
142
+ detail: conflicted
143
+ ? `Merging ${run.branch} conflicts in: ${conflicted.split(/\r?\n/).join(', ')}`
144
+ : `git merge ${run.branch} failed: ${(merge.stderr || merge.stdout).trim()}`,
145
+ };
146
+ }
147
+ // A1/A3 — re-run the quality command after each merge; undo on failure.
148
+ const q = runQuality(cwd);
149
+ if (!q.ok) {
150
+ git(['reset', '--hard', preMerge], cwd);
151
+ return {
152
+ merged,
153
+ stoppedAt: run.id,
154
+ reason: 'quality-failed',
155
+ detail: `Quality command${q.command ? ` (${q.command})` : ''} failed after merging ${run.branch}; merge undone`,
156
+ };
157
+ }
158
+ merged.push(run.id);
159
+ }
160
+ return { merged };
161
+ }
162
+ //# sourceMappingURL=merge-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-queue.js","sourceRoot":"","sources":["../../src/workflows/merge-queue.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,6 @@ import { DagNode } from '../schemas/workflow';
13
13
  import { NodeRunner, NodeRunResult, RunnerContext } from './types';
14
14
  export declare class ApprovalRunner implements NodeRunner {
15
15
  readonly kind: "approval";
16
- run(rawNode: DagNode, _ctx: RunnerContext): Promise<NodeRunResult>;
16
+ run(rawNode: DagNode, ctx: RunnerContext): Promise<NodeRunResult>;
17
17
  }
18
18
  //# sourceMappingURL=approval.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../../src/workflows/runners/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGnE,qBAAa,cAAe,YAAW,UAAU;IAC/C,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IAG9B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAgBzE"}
1
+ {"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../../src/workflows/runners/approval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGnE,qBAAa,cAAe,YAAW,UAAU;IAC/C,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IAE9B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CA0BxE"}
@@ -14,12 +14,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.ApprovalRunner = void 0;
15
15
  class ApprovalRunner {
16
16
  kind = 'approval';
17
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
- async run(rawNode, _ctx) {
17
+ async run(rawNode, ctx) {
19
18
  if (rawNode.kind !== 'approval') {
20
19
  return { status: 'failed', error: `ApprovalRunner received ${rawNode.kind} node` };
21
20
  }
22
21
  const node = rawNode;
22
+ // REQ-THRU-003 — a deterministic upstream check may approve this gate.
23
+ if (node.auto_approve) {
24
+ const upstream = ctx.outputs?.get(node.auto_approve.from)?.text ?? '';
25
+ if (upstream.includes(node.auto_approve.marker)) {
26
+ return {
27
+ status: 'completed',
28
+ output: { text: `auto-approved: ${node.auto_approve.from} reported ${node.auto_approve.marker}` },
29
+ };
30
+ }
31
+ }
23
32
  const approval = {
24
33
  type: 'approval',
25
34
  nodeId: node.id,
@@ -1 +1 @@
1
- {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/workflows/runners/approval.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAMH,MAAa,cAAc;IAChB,IAAI,GAAG,UAAmB,CAAC;IAEpC,6DAA6D;IAC7D,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAE,IAAmB;QAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,2BAA2B,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC;QACrF,CAAC;QACD,MAAM,IAAI,GAAG,OAAuB,CAAC;QAErC,MAAM,QAAQ,GAAoB;YAChC,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,gBAAgB;YACtC,QAAQ,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC;QAEF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;CACF;AApBD,wCAoBC"}
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/workflows/runners/approval.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAMH,MAAa,cAAc;IAChB,IAAI,GAAG,UAAmB,CAAC;IAEpC,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAE,GAAkB;QAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,2BAA2B,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC;QACrF,CAAC;QACD,MAAM,IAAI,GAAG,OAAuB,CAAC;QACrC,uEAAuE;QACvE,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;YACtE,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChD,OAAO;oBACL,MAAM,EAAE,WAAW;oBACnB,MAAM,EAAE,EAAE,IAAI,EAAE,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,aAAa,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE;iBAClG,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAoB;YAChC,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,gBAAgB;YACtC,QAAQ,EAAE,IAAI,CAAC,SAAS;SACzB,CAAC;QAEF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;CACF;AA7BD,wCA6BC"}
@@ -6,6 +6,21 @@
6
6
  */
7
7
  import { DagNode } from '../schemas/workflow';
8
8
  import { NodeRunner, NodeRunResult, RunnerContext } from './types';
9
+ /**
10
+ * Keep the LAST `max` chars — test runners and compilers print their summary
11
+ * at the end, so the head is the least useful part (REQ-PIPETRUST-006.A1).
12
+ */
13
+ export declare function tailForError(text: string, max?: number): string;
14
+ /**
15
+ * The SpecShip CLI running this process — `{ node, script }` when this
16
+ * process is the CLI, else null. Exported to bash steps as
17
+ * SPECSHIP_CLI_NODE / SPECSHIP_CLI_SCRIPT (kept separate so paths with spaces
18
+ * survive) plus a display-only SPECSHIP_CLI.
19
+ */
20
+ export declare function specshipCli(argv?: string[], execPath?: string): {
21
+ node: string;
22
+ script: string;
23
+ } | null;
9
24
  export declare class BashRunner implements NodeRunner {
10
25
  readonly kind: "bash";
11
26
  run(rawNode: DagNode, ctx: RunnerContext): Promise<NodeRunResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/workflows/runners/bash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,OAAO,EAAY,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAInE,qBAAa,UAAW,YAAW,UAAU;IAC3C,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAE1B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CA6GxE"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/workflows/runners/bash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,OAAO,EAAY,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMnE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAmB,GAAG,MAAM,CAEzE;AAQD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,GAAE,MAAM,EAAiB,EAC7B,QAAQ,GAAE,MAAyB,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIzC;AAYD,qBAAa,UAAW,YAAW,UAAU;IAC3C,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAE1B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAuHxE"}
@@ -40,10 +40,49 @@ var __importStar = (this && this.__importStar) || (function () {
40
40
  })();
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.BashRunner = void 0;
43
+ exports.tailForError = tailForError;
44
+ exports.specshipCli = specshipCli;
43
45
  const child_process_1 = require("child_process");
44
46
  const fs = __importStar(require("fs"));
45
47
  const path = __importStar(require("path"));
46
48
  const DEFAULT_TIMEOUT_MS = 60_000;
49
+ /** How much of a failed step's output the one-line `error` keeps. */
50
+ const ERROR_TAIL_CHARS = 4000;
51
+ /**
52
+ * Keep the LAST `max` chars — test runners and compilers print their summary
53
+ * at the end, so the head is the least useful part (REQ-PIPETRUST-006.A1).
54
+ */
55
+ function tailForError(text, max = ERROR_TAIL_CHARS) {
56
+ return text.length > max ? `…${text.slice(text.length - max)}` : text;
57
+ }
58
+ /** Combined output of a failed step, stdout first then stderr. */
59
+ function combinedOutput(stdout, stderr) {
60
+ if (stdout && stderr)
61
+ return `${stdout}${stdout.endsWith('\n') ? '' : '\n'}${stderr}`;
62
+ return stdout || stderr;
63
+ }
64
+ /**
65
+ * The SpecShip CLI running this process — `{ node, script }` when this
66
+ * process is the CLI, else null. Exported to bash steps as
67
+ * SPECSHIP_CLI_NODE / SPECSHIP_CLI_SCRIPT (kept separate so paths with spaces
68
+ * survive) plus a display-only SPECSHIP_CLI.
69
+ */
70
+ function specshipCli(argv = process.argv, execPath = process.execPath) {
71
+ const script = argv[1] ?? '';
72
+ if (!/^specship(\.js)?$/.test(path.basename(script)))
73
+ return null;
74
+ return { node: execPath, script };
75
+ }
76
+ function cliEnv() {
77
+ const cli = specshipCli();
78
+ if (!cli)
79
+ return {};
80
+ return {
81
+ SPECSHIP_CLI_NODE: cli.node,
82
+ SPECSHIP_CLI_SCRIPT: cli.script,
83
+ SPECSHIP_CLI: `${cli.node} ${cli.script}`,
84
+ };
85
+ }
47
86
  class BashRunner {
48
87
  kind = 'bash';
49
88
  async run(rawNode, ctx) {
@@ -65,6 +104,13 @@ class BashRunner {
65
104
  // Always prepend — being merely *present* later in PATH still loses to
66
105
  // an earlier host Node.
67
106
  PATH: `${runtimeDir}${path.delimiter}${basePath}`,
107
+ // The exact CLI running this workflow (PIPETRUST-DOC, REQ-PIPETRUST-006.A4):
108
+ // steps call `$SPECSHIP_CLI` before any `specship` on PATH, so a step
109
+ // never runs an older globally installed CLI that lacks its command.
110
+ ...cliEnv(),
111
+ // Where this run keeps its artifacts, so a step can leave durable
112
+ // evidence (e.g. a JSON test report) beside the node outputs.
113
+ SPECSHIP_ARTIFACTS_DIR: ctx.artifactsDir,
68
114
  ...(node.env ?? {}),
69
115
  };
70
116
  const isWindows = process.platform === 'win32';
@@ -135,18 +181,21 @@ class BashRunner {
135
181
  });
136
182
  return;
137
183
  }
184
+ const combined = combinedOutput(stdout, stderr);
138
185
  if (signal === 'SIGTERM') {
139
186
  resolve({
140
187
  status: 'failed',
141
188
  error: `bash node timed out after ${timeout}ms`,
142
189
  transient: true,
190
+ ...(combined ? { output: { text: combined } } : {}),
143
191
  });
144
192
  return;
145
193
  }
146
- const errMsg = (stderr || stdout || '').slice(0, 4000);
194
+ const errMsg = tailForError(stderr || stdout || '');
147
195
  resolve({
148
196
  status: 'failed',
149
197
  error: `bash exited with code ${code}: ${errMsg}`,
198
+ output: { text: combined },
150
199
  });
151
200
  });
152
201
  });
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/workflows/runners/bash.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,iDAAsC;AACtC,uCAAyB;AACzB,2CAA6B;AAI7B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAa,UAAU;IACZ,IAAI,GAAG,MAAe,CAAC;IAEhC,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAE,GAAkB;QAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,uBAAuB,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC;QACjF,CAAC;QACD,MAAM,IAAI,GAAG,OAAmB,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAC;QACnD,yEAAyE;QACzE,0EAA0E;QAC1E,uEAAuE;QACvE,qEAAqE;QACrE,0CAA0C;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG;YACV,GAAG,OAAO,CAAC,GAAG;YACd,uEAAuE;YACvE,wBAAwB;YACxB,IAAI,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,SAAS,GAAG,QAAQ,EAAE;YACjD,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;SACpB,CAAC;QAEF,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;QAC/C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;QAClD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEpE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;QAE3E,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC;YACV,IAAI,CAAC;gBACH,KAAK,GAAG,IAAA,qBAAK,EAAC,KAAK,EAAE,SAAS,EAAE;oBAC9B,GAAG;oBACH,GAAG;oBACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;oBACjC,WAAW,EAAE,IAAI;iBAClB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC;oBACN,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;iBACpF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE;gBACtB,IAAI,CAAC;oBACH,OAAO,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBACvD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YACL,SAAS,EAAE,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,eAAe,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACpF,SAAS,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;YACpC,SAAS,EAAE,KAAK,CAAC,cAAc,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC;YAEhD,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,CAAC;gBACZ,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,CAAC;gBACZ,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC7B,IAAI,CAAC;oBAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC,EAAE,OAAO,CAAC,CAAC;YAEZ,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,SAAS,EAAE,GAAG,EAAE,CAAC;gBACjB,OAAO,CAAC;oBACN,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,gBAAgB,GAAG,CAAC,OAAO,EAAE;iBACrC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;gBACjC,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrB,SAAS,EAAE,GAAG,EAAE,CAAC;gBAEjB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,OAAO,CAAC;wBACN,MAAM,EAAE,WAAW;wBACnB,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;qBACzB,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,OAAO,CAAC;wBACN,MAAM,EAAE,QAAQ;wBAChB,KAAK,EAAE,6BAA6B,OAAO,IAAI;wBAC/C,SAAS,EAAE,IAAI;qBAChB,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBACvD,OAAO,CAAC;oBACN,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,yBAAyB,IAAI,KAAK,MAAM,EAAE;iBAClD,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAhHD,gCAgHC"}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/workflows/runners/bash.ts"],"names":[],"mappings":"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"}