strikethroo 3.0.1 → 3.1.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 (137) hide show
  1. package/README.md +20 -5
  2. package/dist/cli.js +19 -128
  3. package/dist/cli.js.map +1 -1
  4. package/dist/serve/archive.d.ts +43 -0
  5. package/dist/serve/archive.d.ts.map +1 -0
  6. package/dist/serve/archive.js +124 -0
  7. package/dist/serve/archive.js.map +1 -0
  8. package/dist/serve/derivation.d.ts +78 -0
  9. package/dist/serve/derivation.d.ts.map +1 -0
  10. package/dist/serve/derivation.js +237 -0
  11. package/dist/serve/derivation.js.map +1 -0
  12. package/dist/serve/events.d.ts +41 -0
  13. package/dist/serve/events.d.ts.map +1 -0
  14. package/dist/serve/events.js +91 -0
  15. package/dist/serve/events.js.map +1 -0
  16. package/dist/serve/markdown.d.ts +75 -0
  17. package/dist/serve/markdown.d.ts.map +1 -0
  18. package/dist/serve/markdown.js +221 -0
  19. package/dist/serve/markdown.js.map +1 -0
  20. package/dist/serve/root.d.ts +48 -0
  21. package/dist/serve/root.d.ts.map +1 -0
  22. package/dist/serve/root.js +110 -0
  23. package/dist/serve/root.js.map +1 -0
  24. package/dist/serve/self-review.d.ts +70 -0
  25. package/dist/serve/self-review.d.ts.map +1 -0
  26. package/dist/serve/self-review.js +164 -0
  27. package/dist/serve/self-review.js.map +1 -0
  28. package/dist/serve/server.d.ts +70 -0
  29. package/dist/serve/server.d.ts.map +1 -0
  30. package/dist/serve/server.js +368 -0
  31. package/dist/serve/server.js.map +1 -0
  32. package/dist/serve/watcher.d.ts +32 -0
  33. package/dist/serve/watcher.d.ts.map +1 -0
  34. package/dist/serve/watcher.js +99 -0
  35. package/dist/serve/watcher.js.map +1 -0
  36. package/dist/serve/workspace-model.d.ts +80 -0
  37. package/dist/serve/workspace-model.d.ts.map +1 -0
  38. package/dist/serve/workspace-model.js +176 -0
  39. package/dist/serve/workspace-model.js.map +1 -0
  40. package/dist/skill-scripts/shared/frontmatter.d.ts +2 -0
  41. package/dist/skill-scripts/shared/frontmatter.d.ts.map +1 -0
  42. package/dist/skill-scripts/shared/frontmatter.js +37 -0
  43. package/dist/skill-scripts/shared/frontmatter.js.map +1 -0
  44. package/dist/skill-scripts/shared/plan-scan.d.ts +10 -0
  45. package/dist/skill-scripts/shared/plan-scan.d.ts.map +1 -0
  46. package/dist/skill-scripts/shared/plan-scan.js +91 -0
  47. package/dist/skill-scripts/shared/plan-scan.js.map +1 -0
  48. package/dist/skill-scripts/shared/root.d.ts +2 -0
  49. package/dist/skill-scripts/shared/root.d.ts.map +1 -0
  50. package/dist/skill-scripts/shared/root.js +104 -0
  51. package/dist/skill-scripts/shared/root.js.map +1 -0
  52. package/dist-web/assets/Fraunces-Italic-VariableFont_SOFT_WONK_opsz_wght-CuXX_kIb.ttf +0 -0
  53. package/dist-web/assets/Fraunces-VariableFont_SOFT_WONK_opsz_wght-DLWfSgHL.ttf +0 -0
  54. package/dist-web/assets/Outfit-VariableFont_wght-B6lQlNBM.ttf +0 -0
  55. package/dist-web/assets/SFMonoBold-DXHgGUoo.otf +0 -0
  56. package/dist-web/assets/SFMonoBoldItalic-CdGEImHi.otf +0 -0
  57. package/dist-web/assets/SFMonoHeavy-DL92f7rT.otf +0 -0
  58. package/dist-web/assets/SFMonoHeavyItalic-DnE00LFH.otf +0 -0
  59. package/dist-web/assets/SFMonoLight-CaMC1gg-.otf +0 -0
  60. package/dist-web/assets/SFMonoLightItalic-DG3Owzn7.otf +0 -0
  61. package/dist-web/assets/SFMonoMedium-ypRDCKSo.otf +0 -0
  62. package/dist-web/assets/SFMonoMediumItalic-DkJk-c-x.otf +0 -0
  63. package/dist-web/assets/SFMonoRegular-77Uh1IPk.otf +0 -0
  64. package/dist-web/assets/SFMonoRegularItalic-Cn01bACm.otf +0 -0
  65. package/dist-web/assets/SFMonoSemibold-CvhtzcyM.otf +0 -0
  66. package/dist-web/assets/SFMonoSemiboldItalic-D75NMH13.otf +0 -0
  67. package/dist-web/assets/arc-BWWIDtzc.js +1 -0
  68. package/dist-web/assets/architectureDiagram-3BPJPVTR-DeYxmq4e.js +36 -0
  69. package/dist-web/assets/blockDiagram-GPEHLZMM-DR85OQGh.js +132 -0
  70. package/dist-web/assets/c4Diagram-AAUBKEIU-B5p4vlmU.js +10 -0
  71. package/dist-web/assets/channel-BaP08-ph.js +1 -0
  72. package/dist-web/assets/chunk-2J33WTMH-duXs_Bbu.js +1 -0
  73. package/dist-web/assets/chunk-4BX2VUAB-DR1619KE.js +1 -0
  74. package/dist-web/assets/chunk-55IACEB6-UacLKom4.js +1 -0
  75. package/dist-web/assets/chunk-727SXJPM-DW2a_NI7.js +206 -0
  76. package/dist-web/assets/chunk-AQP2D5EJ-Bu5jn-_L.js +231 -0
  77. package/dist-web/assets/chunk-FMBD7UC4-eJsExyuh.js +15 -0
  78. package/dist-web/assets/chunk-ND2GUHAM-BqKmGd94.js +1 -0
  79. package/dist-web/assets/chunk-QZHKN3VN--ynTiOCz.js +1 -0
  80. package/dist-web/assets/classDiagram-4FO5ZUOK-V5dHIfdR.js +1 -0
  81. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-V5dHIfdR.js +1 -0
  82. package/dist-web/assets/cose-bilkent-S5V4N54A-Ccz3r4S1.js +1 -0
  83. package/dist-web/assets/cytoscape.esm-BHYC38rz.js +331 -0
  84. package/dist-web/assets/dagre-BM42HDAG-BESSLbjB.js +4 -0
  85. package/dist-web/assets/defaultLocale-CrowFXzY.js +1 -0
  86. package/dist-web/assets/diagram-2AECGRRQ-BB5cYRbY.js +43 -0
  87. package/dist-web/assets/diagram-5GNKFQAL-3lmcZFDS.js +10 -0
  88. package/dist-web/assets/diagram-KO2AKTUF-DUMp202y.js +3 -0
  89. package/dist-web/assets/diagram-LMA3HP47-DCGXhLm1.js +24 -0
  90. package/dist-web/assets/diagram-OG6HWLK6-D247gj5y.js +24 -0
  91. package/dist-web/assets/erDiagram-TEJ5UH35-GI1vhsr2.js +85 -0
  92. package/dist-web/assets/flowDiagram-I6XJVG4X-iqUPWZuf.js +162 -0
  93. package/dist-web/assets/ganttDiagram-6RSMTGT7-DfG1X-Pe.js +292 -0
  94. package/dist-web/assets/gitGraphDiagram-PVQCEYII-B2MrV3y6.js +106 -0
  95. package/dist-web/assets/graph-Dqkl27Ch.js +1 -0
  96. package/dist-web/assets/index-Bm5I46eC.css +1 -0
  97. package/dist-web/assets/index-CvfrFREc.js +125 -0
  98. package/dist-web/assets/infoDiagram-5YYISTIA-DGqU5K4a.js +2 -0
  99. package/dist-web/assets/init-Gi6I4Gst.js +1 -0
  100. package/dist-web/assets/ishikawaDiagram-YF4QCWOH-DrMH3jRf.js +70 -0
  101. package/dist-web/assets/journeyDiagram-JHISSGLW-BH4wiwsd.js +139 -0
  102. package/dist-web/assets/kanban-definition-UN3LZRKU-DEV_dEgE.js +89 -0
  103. package/dist-web/assets/katex-C5jXJg4s.js +257 -0
  104. package/dist-web/assets/layout-DO9UvE1P.js +1 -0
  105. package/dist-web/assets/linear-D81nAxzR.js +1 -0
  106. package/dist-web/assets/mermaid.core-BaP7clO2.js +307 -0
  107. package/dist-web/assets/mindmap-definition-RKZ34NQL-DM4iAZ4M.js +96 -0
  108. package/dist-web/assets/ordinal-Cboi1Yqb.js +1 -0
  109. package/dist-web/assets/pieDiagram-4H26LBE5-DinO6q5i.js +30 -0
  110. package/dist-web/assets/quadrantDiagram-W4KKPZXB-CYvCm7U6.js +7 -0
  111. package/dist-web/assets/requirementDiagram-4Y6WPE33-DXfPIJ5m.js +84 -0
  112. package/dist-web/assets/sankeyDiagram-5OEKKPKP-CfovFay4.js +40 -0
  113. package/dist-web/assets/sequenceDiagram-3UESZ5HK-BboUGmEB.js +162 -0
  114. package/dist-web/assets/stateDiagram-AJRCARHV-CsB2FtnQ.js +1 -0
  115. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-D0D_KesS.js +1 -0
  116. package/dist-web/assets/timeline-definition-PNZ67QCA-Cma1yLcq.js +120 -0
  117. package/dist-web/assets/vennDiagram-CIIHVFJN-DhFGEgCQ.js +34 -0
  118. package/dist-web/assets/wardley-L42UT6IY-DYkCeynG.js +173 -0
  119. package/dist-web/assets/wardleyDiagram-YWT4CUSO-jogT61m_.js +78 -0
  120. package/dist-web/assets/xychartDiagram-2RQKCTM6-Cn3W0E3s.js +7 -0
  121. package/dist-web/favicon.svg +13 -0
  122. package/dist-web/index.html +30 -0
  123. package/package.json +28 -8
  124. package/templates/harness/skills/st-full-workflow/SKILL.md +2 -2
  125. package/templates/harness/skills/st-generate-tasks/SKILL.md +2 -2
  126. package/dist/plan-utils.d.ts +0 -35
  127. package/dist/plan-utils.d.ts.map +0 -1
  128. package/dist/plan-utils.js +0 -123
  129. package/dist/plan-utils.js.map +0 -1
  130. package/dist/plan.d.ts +0 -27
  131. package/dist/plan.d.ts.map +0 -1
  132. package/dist/plan.js +0 -279
  133. package/dist/plan.js.map +0 -1
  134. package/dist/status.d.ts +0 -73
  135. package/dist/status.d.ts.map +0 -1
  136. package/dist/status.js +0 -375
  137. package/dist/status.js.map +0 -1
package/README.md CHANGED
@@ -3,8 +3,6 @@
3
3
  [![npm version](https://img.shields.io/npm/v/strikethroo.svg)](https://www.npmjs.com/package/strikethroo)
4
4
  [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- ![Dashboard](./docs/img/dashboard.svg)
7
-
8
6
  **Strikethroo: extensible AI-powered plan and task management with customizable workflows and structured development processes.**
9
7
 
10
8
  Transform complex AI prompts into organized, executable workflows through customizable hooks, templates, and progressive refinement. Works seamlessly within your existing AI subscriptions for Claude Code, Gemini CLI, and Open Code.
@@ -25,13 +23,30 @@ The skills give your assistant the planning, decomposition, and execution workfl
25
23
 
26
24
  The CLI's `init` emits the shared workspace plus harness-specific agents (e.g., `.claude/agents/` for Claude). Other harnesses rely entirely on the installed skills.
27
25
 
26
+ ## 🌐 Serve the Workspace
27
+
28
+ Run a local web app over an initialized `.ai/strikethroo/` workspace:
29
+
30
+ ```bash
31
+ npx strikethroo serve
32
+ ```
33
+
34
+ `serve` boots a dependency-light Node server that hosts the prebuilt single-page app as static files, exposes a read-only JSON API over the workspace model, and streams a coalesced `changed` event over Server-Sent Events whenever the workspace mutates on disk. Run it from inside an initialized workspace; if none is found it prints guidance to run `init` and exits without binding.
35
+
36
+ The viewer is read-only **except for one permitted mutation: the archive action.** A plan whose tasks are all complete (derived state `done`) shows an **Archive** control; confirming it issues `POST /api/plans/:id/archive`, which moves that plan's directory from `plans/` to `archive/`. It is strictly a directory move — no files are deleted or edited, and only `done` plans are accepted. This is the manual escape hatch for plans that are done but not yet archived; it does **not** replace the automatic archival the `st-execute-blueprint` skill performs on successful completion.
37
+
38
+ Flags:
39
+
40
+ - `--port <n>` — port to bind (default `4317`).
41
+ - `--no-open` — do not open the browser on start.
42
+ - `--workspace <path>` — override workspace root discovery.
43
+
28
44
  ## ✨ Key Benefits
29
45
 
30
46
  - **🔧 Fully Customizable**: Tailor hooks, templates, and workflows to your project's specific needs
31
47
  - **🎯 Extensible Architecture**: Add custom validation gates, quality checks, and workflow patterns
32
48
  - **📋 Structured Workflows**: Three-phase progressive refinement with validation gates
33
49
  - **🔄 Plan Mode Integration**: Enhance existing AI assistant features with structured task management
34
- - **📊 Plan Inspection & Management**: View progress, archive completed work, and manage plans via CLI
35
50
  - **💰 Works Within Subscriptions**: No additional API keys or costs required
36
51
 
37
52
  ## 📖 Documentation
@@ -60,8 +75,8 @@ The `st-full-workflow` skill handles plan creation, task generation, and bluepri
60
75
  2. **🔍 Refine the plan** → "Refine plan 1" (`st-refine-plan` skill — useful when a second assistant should red-team the plan)
61
76
  3. **📋 Generate tasks** → "Generate tasks for plan 1" (`st-generate-tasks` skill)
62
77
  4. **🚀 Execute blueprint** → "Execute the blueprint for plan 1" (`st-execute-blueprint` skill)
63
- 5. **📊 Monitor progress** → `npx strikethroo status`
64
- 6. **🗂️ Manage plans** `npx strikethroo plan show 1`
78
+
79
+ Progress is driven by the Agent Skills workflow: the `st-execute-blueprint` skill runs the phases, archives the plan automatically on completion, and you can inspect plan and task files directly under `.ai/strikethroo/plans/` (completed plans move to `.ai/strikethroo/archive/`).
65
80
 
66
81
  ## 🤖 Supported Harnesses
67
82
 
package/dist/cli.js CHANGED
@@ -9,8 +9,8 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const commander_1 = require("commander");
11
11
  const index_1 = require("./index");
12
- const status_1 = require("./status");
13
- const plan_1 = require("./plan");
12
+ const root_1 = require("./serve/root");
13
+ const server_1 = require("./serve/server");
14
14
  const program = new commander_1.Command();
15
15
  program.name('strikethroo').version('0.1.0').description('AI-powered task management CLI tool');
16
16
  program
@@ -37,140 +37,31 @@ program
37
37
  }
38
38
  });
39
39
  program
40
- .command('status')
41
- .description('Display dashboard with plans and task statistics')
42
- .action(async () => {
40
+ .command('serve')
41
+ .description('Serve the workspace as a local web app (static SPA, JSON API, SSE change stream)')
42
+ .option('--port <n>', 'port to bind', '4317')
43
+ .option('--no-open', 'do not open the browser on start')
44
+ .option('--workspace <path>', 'override workspace root discovery')
45
+ .action(async (opts) => {
43
46
  try {
44
- const result = await (0, status_1.status)();
45
- if (result.success) {
46
- process.exit(0);
47
- }
48
- else {
49
- if (result.message) {
50
- console.error(result.message);
51
- }
52
- process.exit(1);
53
- }
54
- }
55
- catch (error) {
56
- console.error(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
57
- process.exit(1);
58
- }
59
- });
60
- // Create parent plan command for help organization
61
- const planCommand = program
62
- .command('plan')
63
- .description('Display and manage plans. Use `plan <id>` as shorthand for `plan show <id>`.');
64
- // Plan show subcommand
65
- planCommand
66
- .command('show <plan-id>')
67
- .description('Display plan metadata, progress, and executive summary')
68
- .action(async (planId) => {
69
- try {
70
- const planIdNum = parseInt(planId, 10);
71
- if (isNaN(planIdNum)) {
72
- console.error(`Invalid plan ID: ${planId}. Must be a number.`);
73
- process.exit(1);
74
- }
75
- const result = await (0, plan_1.showPlan)(planIdNum);
76
- if (result.success) {
77
- process.exit(0);
78
- }
79
- else {
80
- if (result.message) {
81
- console.error(result.message);
82
- }
47
+ const resolved = (0, root_1.resolveWorkspaceRoot)({ workspace: opts.workspace });
48
+ if ((0, root_1.isResolveError)(resolved)) {
49
+ console.error(resolved.error);
83
50
  process.exit(1);
84
51
  }
52
+ const handle = await (0, server_1.startServer)({
53
+ root: resolved.root,
54
+ port: Number(opts.port),
55
+ open: opts.open,
56
+ assetsDir: (0, server_1.defaultAssetsDir)(),
57
+ });
58
+ console.log(`Serving ${handle.url}`);
85
59
  }
86
60
  catch (error) {
87
- console.error(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
61
+ console.error(`Failed to start serve: ${error instanceof Error ? error.message : String(error)}`);
88
62
  process.exit(1);
89
63
  }
90
64
  });
91
- // Plan archive subcommand
92
- planCommand
93
- .command('archive <plan-id>')
94
- .description('Move a plan from active to archive directory')
95
- .action(async (planId) => {
96
- try {
97
- const planIdNum = parseInt(planId, 10);
98
- if (isNaN(planIdNum)) {
99
- console.error(`Invalid plan ID: ${planId}. Must be a number.`);
100
- process.exit(1);
101
- }
102
- const result = await (0, plan_1.archivePlan)(planIdNum);
103
- if (result.success) {
104
- process.exit(0);
105
- }
106
- else {
107
- if (result.message) {
108
- console.error(result.message);
109
- }
110
- process.exit(1);
111
- }
112
- }
113
- catch (error) {
114
- console.error(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
115
- process.exit(1);
116
- }
117
- });
118
- // Plan delete subcommand
119
- planCommand
120
- .command('delete <plan-id>')
121
- .description('Permanently delete a plan and all its tasks')
122
- .action(async (planId) => {
123
- try {
124
- const planIdNum = parseInt(planId, 10);
125
- if (isNaN(planIdNum)) {
126
- console.error(`Invalid plan ID: ${planId}. Must be a number.`);
127
- process.exit(1);
128
- }
129
- const result = await (0, plan_1.deletePlan)(planIdNum);
130
- if (result.success) {
131
- process.exit(0);
132
- }
133
- else {
134
- if (result.message) {
135
- console.error(result.message);
136
- }
137
- process.exit(1);
138
- }
139
- }
140
- catch (error) {
141
- console.error(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
142
- process.exit(1);
143
- }
144
- });
145
- // Backward compatibility: plan <id> as shorthand for plan show <id>
146
- planCommand
147
- .argument('[plan-id]', 'Plan ID to display (shorthand for show subcommand)')
148
- .action(async (planId) => {
149
- // Only handle if planId is provided and no subcommand was matched
150
- if (planId) {
151
- try {
152
- const planIdNum = parseInt(planId, 10);
153
- if (isNaN(planIdNum)) {
154
- console.error(`Invalid plan ID: ${planId}. Must be a number.`);
155
- process.exit(1);
156
- }
157
- const result = await (0, plan_1.showPlan)(planIdNum);
158
- if (result.success) {
159
- process.exit(0);
160
- }
161
- else {
162
- if (result.message) {
163
- console.error(result.message);
164
- }
165
- process.exit(1);
166
- }
167
- }
168
- catch (error) {
169
- console.error(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
170
- process.exit(1);
171
- }
172
- }
173
- });
174
65
  // Error handling for unknown commands
175
66
  program.on('command:*', async (operands) => {
176
67
  console.error(`Unknown command: ${operands[0]}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Archive operation for `npx strikethroo serve`.
3
+ *
4
+ * The serve web app is a read-only viewer over `.ai/strikethroo/` with exactly
5
+ * one sanctioned mutation: moving a plan that has reached the derived `done`
6
+ * state from `plans/NN--slug/` to `archive/NN--slug/`. This module is that
7
+ * mutation's authoritative guard — a single, HTTP-free function the route
8
+ * handler and the tests both call.
9
+ *
10
+ * It validates three preconditions, in order — the plan exists, currently lives
11
+ * under `plans/` (not already archived), and is `done` per the derived state in
12
+ * `workspace-model.ts` — then performs a single atomic `fs.rename` of the whole
13
+ * plan directory. It never deletes files, never edits file contents, and never
14
+ * falls back to a non-atomic copy-then-delete. Expected precondition failures
15
+ * are returned as a typed result, not thrown; only an unexpected filesystem
16
+ * error surfaces as the `fs-error` variant. Node built-ins only.
17
+ */
18
+ import { PlanDetail } from './workspace-model';
19
+ /**
20
+ * Outcome of an {@link archivePlan} call. A discriminated union mirroring the
21
+ * serve layer's existing result convention (see `self-review.ts`): callers map
22
+ * `reason` to HTTP status codes without re-deriving anything.
23
+ */
24
+ export type ArchiveResult = {
25
+ ok: true;
26
+ plan: PlanDetail;
27
+ } | {
28
+ ok: false;
29
+ reason: 'not-found' | 'already-archived' | 'not-done' | 'destination-exists' | 'fs-error';
30
+ message: string;
31
+ };
32
+ /**
33
+ * Validates the archive preconditions for plan `planId` under `root` (the
34
+ * absolute `.ai/strikethroo` directory) and, if they pass, atomically renames
35
+ * its directory from `plans/` into `archive/`, returning the refreshed model.
36
+ *
37
+ * On any precondition failure it performs zero filesystem changes and returns a
38
+ * typed failure with an actionable message. The only write it performs beyond
39
+ * the rename is creating the `archive/` directory if it does not yet exist,
40
+ * which is required for the rename's destination parent to resolve.
41
+ */
42
+ export declare const archivePlan: (root: string, planId: number) => Promise<ArchiveResult>;
43
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/serve/archive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAiB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC9B;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,WAAW,GAAG,kBAAkB,GAAG,UAAU,GAAG,oBAAoB,GAAG,UAAU,CAAC;IAC1F,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,aAAa,CA6DrF,CAAC"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * Archive operation for `npx strikethroo serve`.
4
+ *
5
+ * The serve web app is a read-only viewer over `.ai/strikethroo/` with exactly
6
+ * one sanctioned mutation: moving a plan that has reached the derived `done`
7
+ * state from `plans/NN--slug/` to `archive/NN--slug/`. This module is that
8
+ * mutation's authoritative guard — a single, HTTP-free function the route
9
+ * handler and the tests both call.
10
+ *
11
+ * It validates three preconditions, in order — the plan exists, currently lives
12
+ * under `plans/` (not already archived), and is `done` per the derived state in
13
+ * `workspace-model.ts` — then performs a single atomic `fs.rename` of the whole
14
+ * plan directory. It never deletes files, never edits file contents, and never
15
+ * falls back to a non-atomic copy-then-delete. Expected precondition failures
16
+ * are returned as a typed result, not thrown; only an unexpected filesystem
17
+ * error surfaces as the `fs-error` variant. Node built-ins only.
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.archivePlan = void 0;
54
+ const fs = __importStar(require("fs"));
55
+ const path = __importStar(require("path"));
56
+ const workspace_model_1 = require("./workspace-model");
57
+ /**
58
+ * Validates the archive preconditions for plan `planId` under `root` (the
59
+ * absolute `.ai/strikethroo` directory) and, if they pass, atomically renames
60
+ * its directory from `plans/` into `archive/`, returning the refreshed model.
61
+ *
62
+ * On any precondition failure it performs zero filesystem changes and returns a
63
+ * typed failure with an actionable message. The only write it performs beyond
64
+ * the rename is creating the `archive/` directory if it does not yet exist,
65
+ * which is required for the rename's destination parent to resolve.
66
+ */
67
+ const archivePlan = async (root, planId) => {
68
+ const detail = (0, workspace_model_1.getPlanDetail)(root, planId);
69
+ if (!detail) {
70
+ return {
71
+ ok: false,
72
+ reason: 'not-found',
73
+ message: `Plan ${planId} was not found.`,
74
+ };
75
+ }
76
+ if (detail.archived) {
77
+ return {
78
+ ok: false,
79
+ reason: 'already-archived',
80
+ message: `Plan ${planId} is already archived.`,
81
+ };
82
+ }
83
+ if (detail.state !== 'done') {
84
+ return {
85
+ ok: false,
86
+ reason: 'not-done',
87
+ message: `Plan ${planId} is not in the done state and cannot be archived.`,
88
+ };
89
+ }
90
+ const src = detail.dir;
91
+ const dest = path.join(root, 'archive', detail.name);
92
+ if (fs.existsSync(dest)) {
93
+ return {
94
+ ok: false,
95
+ reason: 'destination-exists',
96
+ message: `Plan ${planId} cannot be archived: a directory already exists at its archive location.`,
97
+ };
98
+ }
99
+ try {
100
+ // The destination's parent (`archive/`) must exist for the rename to land.
101
+ // Creating it is benign and never touches plan contents.
102
+ await fs.promises.mkdir(path.join(root, 'archive'), { recursive: true });
103
+ await fs.promises.rename(src, dest);
104
+ }
105
+ catch {
106
+ return {
107
+ ok: false,
108
+ reason: 'fs-error',
109
+ message: `Plan ${planId} could not be archived due to a filesystem error.`,
110
+ };
111
+ }
112
+ // Re-resolve so the returned model reflects the new archive/ location.
113
+ const moved = (0, workspace_model_1.getPlanDetail)(root, planId);
114
+ if (!moved) {
115
+ return {
116
+ ok: false,
117
+ reason: 'fs-error',
118
+ message: `Plan ${planId} was moved but could not be re-read.`,
119
+ };
120
+ }
121
+ return { ok: true, plan: moved };
122
+ };
123
+ exports.archivePlan = archivePlan;
124
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/serve/archive.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAC7B,uDAA8D;AAe9D;;;;;;;;;GASG;AACI,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAE,MAAc,EAA0B,EAAE;IACxF,MAAM,MAAM,GAAG,IAAA,+BAAa,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,QAAQ,MAAM,iBAAiB;SACzC,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,kBAAkB;YAC1B,OAAO,EAAE,QAAQ,MAAM,uBAAuB;SAC/C,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,QAAQ,MAAM,mDAAmD;SAC3E,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAErD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,oBAAoB;YAC5B,OAAO,EAAE,QAAQ,MAAM,0EAA0E;SAClG,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,2EAA2E;QAC3E,yDAAyD;QACzD,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,QAAQ,MAAM,mDAAmD;SAC3E,CAAC;IACJ,CAAC;IAED,uEAAuE;IACvE,MAAM,KAAK,GAAG,IAAA,+BAAa,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,QAAQ,MAAM,sCAAsC;SAC9D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC,CAAC;AA7DW,QAAA,WAAW,eA6DtB"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Per-plan derivation layer for the serve data layer.
3
+ *
4
+ * Scans a plan directory's `tasks/*.md` into structured task records, computes
5
+ * the derived plan lifecycle state (`drafted` -> `ready` -> `doing` -> `done`)
6
+ * with done/total counts, and resolves execution phases (from a blueprint
7
+ * document when present, otherwise inferred from task `group` + `dependencies`).
8
+ *
9
+ * Everything is synchronous and read-only: file reads only, no watches, no
10
+ * network, no writes.
11
+ */
12
+ import { type MarkdownSection } from './markdown';
13
+ /** A single task parsed from a plan's `tasks/` directory. */
14
+ export interface Task {
15
+ id: number | undefined;
16
+ /** Task title (first `# ` heading), falling back to the filename. */
17
+ name: string;
18
+ group: string | undefined;
19
+ dependencies: number[];
20
+ status: string | undefined;
21
+ skills: string[];
22
+ /** Source filename (basename). */
23
+ file: string;
24
+ /** Raw markdown body after frontmatter. */
25
+ body: string;
26
+ /** Ordered named `##` sections of the body (via `sectionBody`, mirrors
27
+ * `PlanDetail.sections`). Additive to `body`, which is retained. */
28
+ sections: MarkdownSection[];
29
+ }
30
+ /** Derived lifecycle state of a plan. */
31
+ export type PlanState = 'drafted' | 'ready' | 'doing' | 'done';
32
+ /** Derived state plus done/total counts. */
33
+ export interface DerivedState {
34
+ state: PlanState;
35
+ done: number;
36
+ total: number;
37
+ }
38
+ /** An execution phase: an ordered group of task ids that run together. */
39
+ export interface Phase {
40
+ /** 1-based phase index. */
41
+ index: number;
42
+ /** Optional descriptive name (from a blueprint doc). */
43
+ name?: string;
44
+ /** Task ids scheduled in this phase. */
45
+ taskIds: number[];
46
+ /** True when the phase holds more than one task. */
47
+ parallel: boolean;
48
+ }
49
+ /** Reads a plan directory's `tasks/*.md` into structured records. Missing dir -> []. */
50
+ export declare const scanTasks: (planDir: string) => Task[];
51
+ /**
52
+ * Computes the derived plan state and counts. Never throws on unknown statuses.
53
+ *
54
+ * - empty list -> `drafted`
55
+ * - tasks present, none started or done -> `ready`
56
+ * - all done -> `done`
57
+ * - otherwise -> `doing`
58
+ */
59
+ export declare const deriveState: (tasks: Task[]) => DerivedState;
60
+ /**
61
+ * Parses phases from an "## Execution Blueprint" section if the plan body
62
+ * contains one. Returns undefined when no blueprint section is present.
63
+ */
64
+ export declare const parseBlueprintPhases: (planBody: string) => Phase[] | undefined;
65
+ /**
66
+ * Infers phases from tasks by grouping on satisfied dependencies. Tasks whose
67
+ * dependencies are all already emitted (or absent from the task set) form a
68
+ * phase; dependents fall into later phases. Best-effort and cycle-safe: if no
69
+ * progress is made, the remaining tasks are emitted as a final phase rather
70
+ * than looping forever. Never throws.
71
+ */
72
+ export declare const inferPhases: (tasks: Task[]) => Phase[];
73
+ /**
74
+ * Resolves a plan's phases: parses a blueprint document's phase list when the
75
+ * plan body contains one, otherwise infers phases from task dependencies.
76
+ */
77
+ export declare const resolvePhases: (planBody: string, tasks: Task[]) => Phase[];
78
+ //# sourceMappingURL=derivation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../../src/serve/derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB,6DAA6D;AAC7D,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb;wEACoE;IACpE,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,yCAAyC;AACzC,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/D,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0EAA0E;AAC1E,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oDAAoD;IACpD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,wFAAwF;AACxF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAAI,EAuC/C,CAAC;AASF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,IAAI,EAAE,KAAG,YA4B3C,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,KAAG,KAAK,EAAE,GAAG,SA6CjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,IAAI,EAAE,KAAG,KAAK,EA0BhD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,EAAE,OAAO,IAAI,EAAE,KAAG,KAAK,EAIpE,CAAC"}