@riotprompt/riotplan 1.0.4 β 1.0.5
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.
- package/MCP-ELICITATION-NOTES.md +211 -0
- package/MCP-FIXES.md +50 -0
- package/MCP-PROMPT-FIXES.md +207 -0
- package/README.md +70 -2
- package/dist/cli-BAr1IsMF.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/mcp/prompts/create_plan.md +127 -0
- package/dist/mcp/prompts/develop_plan.md +667 -0
- package/dist/mcp/prompts/execute_plan.md +456 -0
- package/dist/mcp/prompts/execute_step.md +142 -0
- package/dist/mcp/prompts/explore_idea.md +187 -0
- package/dist/mcp/prompts/shape_approach.md +187 -0
- package/dist/mcp/prompts/track_progress.md +145 -0
- package/dist/mcp-server.js +3553 -0
- package/idea-plan-conceptual-model/.history/timeline.jsonl +1 -0
- package/idea-plan-conceptual-model/IDEA.md +39 -0
- package/idea-plan-conceptual-model/LIFECYCLE.md +21 -0
- package/package.json +16 -6
- package/scripts/build-mcp.js +88 -0
|
@@ -0,0 +1,3553 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer as Se } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport as ve } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z as c } from "zod";
|
|
5
|
+
import { resolve as T, join as u, basename as J, dirname as be } from "node:path";
|
|
6
|
+
import { writeFile as w, mkdir as $, stat as j, readFile as y, readdir as b, rename as ke, access as I, appendFile as _e } from "node:fs/promises";
|
|
7
|
+
import { existsSync as $e, readFileSync as Y } from "node:fs";
|
|
8
|
+
import { fileURLToPath as Pe } from "node:url";
|
|
9
|
+
function S() {
|
|
10
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
11
|
+
}
|
|
12
|
+
function A(e, n) {
|
|
13
|
+
return e.path ? T(e.path) : n.workingDirectory ? n.workingDirectory : process.cwd();
|
|
14
|
+
}
|
|
15
|
+
function x(e) {
|
|
16
|
+
return {
|
|
17
|
+
success: !1,
|
|
18
|
+
error: e instanceof Error ? e.message : String(e)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function C(e, n) {
|
|
22
|
+
return {
|
|
23
|
+
success: !0,
|
|
24
|
+
data: e,
|
|
25
|
+
message: n
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const h = {
|
|
29
|
+
/** Meta-prompt file patterns */
|
|
30
|
+
metaPromptPatterns: [
|
|
31
|
+
"{code}-prompt.md",
|
|
32
|
+
"prompt-of-prompts.md",
|
|
33
|
+
"{code}.md"
|
|
34
|
+
],
|
|
35
|
+
/** Step file pattern (e.g., "01-step-name.md") */
|
|
36
|
+
stepPattern: /^(\d{2})-(.+)\.md$/,
|
|
37
|
+
/** Feedback file pattern (e.g., "001-initial-review.md") */
|
|
38
|
+
feedbackPattern: /^(\d{3})-(.+)\.md$/,
|
|
39
|
+
/** Evidence file patterns */
|
|
40
|
+
evidencePatterns: [
|
|
41
|
+
/^what-happened-in-(.+)\.md$/,
|
|
42
|
+
/^research-(.+)\.md$/,
|
|
43
|
+
/^analysis-(.+)\.md$/,
|
|
44
|
+
/^example-(.+)\.md$/
|
|
45
|
+
],
|
|
46
|
+
/** Standard files */
|
|
47
|
+
standardFiles: {
|
|
48
|
+
summary: "SUMMARY.md",
|
|
49
|
+
status: "STATUS.md",
|
|
50
|
+
executionPlan: "EXECUTION_PLAN.md",
|
|
51
|
+
readme: "README.md",
|
|
52
|
+
changelog: "CHANGELOG.md"
|
|
53
|
+
},
|
|
54
|
+
/** Standard directories */
|
|
55
|
+
standardDirs: {
|
|
56
|
+
plan: "plan",
|
|
57
|
+
analysis: "analysis",
|
|
58
|
+
architecture: "architecture",
|
|
59
|
+
implementation: "implementation",
|
|
60
|
+
testing: "testing",
|
|
61
|
+
feedback: "feedback",
|
|
62
|
+
evidence: "evidence",
|
|
63
|
+
history: ".history"
|
|
64
|
+
},
|
|
65
|
+
/** Status emoji mapping */
|
|
66
|
+
statusEmoji: {
|
|
67
|
+
pending: "β¬",
|
|
68
|
+
in_progress: "π",
|
|
69
|
+
completed: "β
",
|
|
70
|
+
failed: "β",
|
|
71
|
+
blocked: "βΈοΈ",
|
|
72
|
+
skipped: "βοΈ"
|
|
73
|
+
},
|
|
74
|
+
/** Emoji to status mapping (reverse lookup) */
|
|
75
|
+
emojiToStatus: {
|
|
76
|
+
"β¬": "pending",
|
|
77
|
+
"π": "in_progress",
|
|
78
|
+
"β
": "completed",
|
|
79
|
+
"β": "failed",
|
|
80
|
+
"βΈοΈ": "blocked",
|
|
81
|
+
"βοΈ": "skipped"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
async function xe(e) {
|
|
85
|
+
if (!/^[a-z0-9-]+$/.test(e.code))
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Invalid plan code: "${e.code}". Use lowercase letters, numbers, and hyphens only.`
|
|
88
|
+
);
|
|
89
|
+
const n = T(u(e.basePath, e.code)), t = [], s = e.createFeedbackDir ?? !0, r = e.createEvidenceDir ?? !0;
|
|
90
|
+
await Ce(n, {
|
|
91
|
+
feedback: s,
|
|
92
|
+
evidence: r
|
|
93
|
+
});
|
|
94
|
+
const a = u(n, h.standardFiles.summary);
|
|
95
|
+
await w(a, Ae(e)), t.push(a);
|
|
96
|
+
const i = u(
|
|
97
|
+
n,
|
|
98
|
+
h.standardFiles.executionPlan
|
|
99
|
+
);
|
|
100
|
+
await w(i, Ee(e)), t.push(i);
|
|
101
|
+
const o = u(n, h.standardFiles.status);
|
|
102
|
+
await w(o, De(e)), t.push(o);
|
|
103
|
+
const p = M(), d = [];
|
|
104
|
+
for (let m = 0; m < p.length; m++) {
|
|
105
|
+
const g = p[m], v = m + 1, k = Ne(g.title), E = `${String(v).padStart(2, "0")}-${k}.md`, D = u(
|
|
106
|
+
n,
|
|
107
|
+
h.standardDirs.plan,
|
|
108
|
+
E
|
|
109
|
+
);
|
|
110
|
+
await w(
|
|
111
|
+
D,
|
|
112
|
+
Ie(v, g.title, g.description)
|
|
113
|
+
), t.push(D), d.push({
|
|
114
|
+
number: v,
|
|
115
|
+
code: k,
|
|
116
|
+
filename: E,
|
|
117
|
+
title: g.title,
|
|
118
|
+
description: g.description,
|
|
119
|
+
status: "pending",
|
|
120
|
+
filePath: D
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const l = [h.standardDirs.plan];
|
|
124
|
+
return s && l.push(h.standardDirs.feedback), r && l.push(h.standardDirs.evidence), { plan: {
|
|
125
|
+
metadata: {
|
|
126
|
+
code: e.code,
|
|
127
|
+
name: e.name,
|
|
128
|
+
description: e.description,
|
|
129
|
+
author: e.author,
|
|
130
|
+
path: n,
|
|
131
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
132
|
+
},
|
|
133
|
+
files: {
|
|
134
|
+
summary: h.standardFiles.summary,
|
|
135
|
+
status: h.standardFiles.status,
|
|
136
|
+
executionPlan: h.standardFiles.executionPlan,
|
|
137
|
+
steps: d.map((m) => m.filename),
|
|
138
|
+
subdirectories: l,
|
|
139
|
+
feedbackDir: s ? h.standardDirs.feedback : void 0,
|
|
140
|
+
evidenceDir: r ? h.standardDirs.evidence : void 0
|
|
141
|
+
},
|
|
142
|
+
steps: d,
|
|
143
|
+
state: {
|
|
144
|
+
status: "pending",
|
|
145
|
+
lastUpdatedAt: /* @__PURE__ */ new Date(),
|
|
146
|
+
blockers: [],
|
|
147
|
+
issues: [],
|
|
148
|
+
progress: 0
|
|
149
|
+
},
|
|
150
|
+
context: e.context
|
|
151
|
+
}, path: n, filesCreated: t };
|
|
152
|
+
}
|
|
153
|
+
async function Ce(e, n) {
|
|
154
|
+
await $(e, { recursive: !0 });
|
|
155
|
+
const t = u(e, h.standardDirs.plan);
|
|
156
|
+
if (await $(t, { recursive: !0 }), n.feedback) {
|
|
157
|
+
const s = u(
|
|
158
|
+
e,
|
|
159
|
+
h.standardDirs.feedback
|
|
160
|
+
);
|
|
161
|
+
await $(s, { recursive: !0 });
|
|
162
|
+
}
|
|
163
|
+
if (n.evidence) {
|
|
164
|
+
const s = u(
|
|
165
|
+
e,
|
|
166
|
+
h.standardDirs.evidence
|
|
167
|
+
);
|
|
168
|
+
await $(s, { recursive: !0 });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function Ae(e) {
|
|
172
|
+
const n = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], t = e.author ? `
|
|
173
|
+
*Author: ${e.author}*` : "";
|
|
174
|
+
return `# ${e.name}
|
|
175
|
+
|
|
176
|
+
## Overview
|
|
177
|
+
|
|
178
|
+
${e.description || "Description of this plan."}
|
|
179
|
+
|
|
180
|
+
## Goals
|
|
181
|
+
|
|
182
|
+
1. Goal 1
|
|
183
|
+
2. Goal 2
|
|
184
|
+
3. Goal 3
|
|
185
|
+
|
|
186
|
+
## Scope
|
|
187
|
+
|
|
188
|
+
### In Scope
|
|
189
|
+
|
|
190
|
+
- Item 1
|
|
191
|
+
- Item 2
|
|
192
|
+
|
|
193
|
+
### Out of Scope
|
|
194
|
+
|
|
195
|
+
- Item 1
|
|
196
|
+
|
|
197
|
+
## Success Criteria
|
|
198
|
+
|
|
199
|
+
- [ ] Criterion 1
|
|
200
|
+
- [ ] Criterion 2
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
*Plan created: ${n}*${t}
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
207
|
+
function Ee(e) {
|
|
208
|
+
const n = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], t = M();
|
|
209
|
+
let s = "";
|
|
210
|
+
return t.forEach((r, a) => {
|
|
211
|
+
const i = String(a + 1).padStart(2, "0");
|
|
212
|
+
s += `| ${i} | ${r.title} | ${r.description || ""} |
|
|
213
|
+
`;
|
|
214
|
+
}), `# Execution Plan: ${e.name}
|
|
215
|
+
|
|
216
|
+
## Strategy
|
|
217
|
+
|
|
218
|
+
Describe the overall approach and strategy for this plan.
|
|
219
|
+
|
|
220
|
+
## Prerequisites
|
|
221
|
+
|
|
222
|
+
- [ ] Prerequisite 1
|
|
223
|
+
- [ ] Prerequisite 2
|
|
224
|
+
|
|
225
|
+
## Steps
|
|
226
|
+
|
|
227
|
+
| Step | Name | Description |
|
|
228
|
+
|------|------|-------------|
|
|
229
|
+
${s}
|
|
230
|
+
## Quality Gates
|
|
231
|
+
|
|
232
|
+
After each step:
|
|
233
|
+
- [ ] Tests pass
|
|
234
|
+
- [ ] Lint passes
|
|
235
|
+
- [ ] Code review complete
|
|
236
|
+
|
|
237
|
+
## Notes
|
|
238
|
+
|
|
239
|
+
Additional notes about the execution approach.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
*Last updated: ${n}*
|
|
244
|
+
`;
|
|
245
|
+
}
|
|
246
|
+
function De(e) {
|
|
247
|
+
const n = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], t = M();
|
|
248
|
+
let s = "";
|
|
249
|
+
return t.forEach((r, a) => {
|
|
250
|
+
const i = String(a + 1).padStart(2, "0");
|
|
251
|
+
s += `| ${i} | ${r.title} | β¬ | - | - | |
|
|
252
|
+
`;
|
|
253
|
+
}), `# ${e.name} Status
|
|
254
|
+
|
|
255
|
+
## Current State
|
|
256
|
+
|
|
257
|
+
| Field | Value |
|
|
258
|
+
|-------|-------|
|
|
259
|
+
| **Status** | β¬ PLANNING |
|
|
260
|
+
| **Current Step** | - |
|
|
261
|
+
| **Last Completed** | - |
|
|
262
|
+
| **Started** | - |
|
|
263
|
+
| **Last Updated** | ${n} |
|
|
264
|
+
| **Progress** | 0% (0/${t.length} steps) |
|
|
265
|
+
|
|
266
|
+
## Step Progress
|
|
267
|
+
|
|
268
|
+
| Step | Name | Status | Started | Completed | Notes |
|
|
269
|
+
|------|------|--------|---------|-----------|-------|
|
|
270
|
+
${s}
|
|
271
|
+
## Blockers
|
|
272
|
+
|
|
273
|
+
None currently.
|
|
274
|
+
|
|
275
|
+
## Issues
|
|
276
|
+
|
|
277
|
+
None currently.
|
|
278
|
+
|
|
279
|
+
## Notes
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
*Last updated: ${n}*
|
|
284
|
+
`;
|
|
285
|
+
}
|
|
286
|
+
function Ie(e, n, t) {
|
|
287
|
+
return `# Step ${String(e).padStart(2, "0")}: ${n}
|
|
288
|
+
|
|
289
|
+
## Objective
|
|
290
|
+
|
|
291
|
+
${t || "Describe the objective of this step."}
|
|
292
|
+
|
|
293
|
+
## Background
|
|
294
|
+
|
|
295
|
+
Provide context and rationale for this step.
|
|
296
|
+
|
|
297
|
+
## Tasks
|
|
298
|
+
|
|
299
|
+
### 1. Task 1
|
|
300
|
+
|
|
301
|
+
Description of task 1.
|
|
302
|
+
|
|
303
|
+
### 2. Task 2
|
|
304
|
+
|
|
305
|
+
Description of task 2.
|
|
306
|
+
|
|
307
|
+
## Acceptance Criteria
|
|
308
|
+
|
|
309
|
+
- [ ] Criterion 1
|
|
310
|
+
- [ ] Criterion 2
|
|
311
|
+
|
|
312
|
+
## Testing
|
|
313
|
+
|
|
314
|
+
Describe how to verify this step is complete.
|
|
315
|
+
|
|
316
|
+
## Files Changed
|
|
317
|
+
|
|
318
|
+
- File 1
|
|
319
|
+
- File 2
|
|
320
|
+
|
|
321
|
+
## Notes
|
|
322
|
+
|
|
323
|
+
Additional notes for this step.
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
function M() {
|
|
327
|
+
return [
|
|
328
|
+
{ title: "Setup", description: "Initial setup and prerequisites" },
|
|
329
|
+
{ title: "Implementation", description: "Core implementation work" },
|
|
330
|
+
{ title: "Testing", description: "Verify everything works" }
|
|
331
|
+
];
|
|
332
|
+
}
|
|
333
|
+
function Ne(e) {
|
|
334
|
+
return e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
335
|
+
}
|
|
336
|
+
async function Te(e, n) {
|
|
337
|
+
try {
|
|
338
|
+
const t = e.directory ? e.directory : A(e, n), r = {
|
|
339
|
+
code: e.code,
|
|
340
|
+
name: e.name || e.code,
|
|
341
|
+
basePath: t,
|
|
342
|
+
description: e.description,
|
|
343
|
+
steps: void 0
|
|
344
|
+
}, a = await xe(r);
|
|
345
|
+
return C(
|
|
346
|
+
{
|
|
347
|
+
planPath: a.path,
|
|
348
|
+
code: e.code,
|
|
349
|
+
stepsCreated: a.plan.steps?.length || 0,
|
|
350
|
+
filesCreated: a.filesCreated || []
|
|
351
|
+
},
|
|
352
|
+
`Plan "${e.code}" created successfully at ${a.path}`
|
|
353
|
+
);
|
|
354
|
+
} catch (t) {
|
|
355
|
+
return x(t);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
function Fe(e) {
|
|
359
|
+
const n = /* @__PURE__ */ new Set(), t = e.indexOf("---", 4);
|
|
360
|
+
if (e.startsWith(`---
|
|
361
|
+
`) && t > 0) {
|
|
362
|
+
const d = e.substring(4, t).match(/depends-on:\s*([^\n]+)/);
|
|
363
|
+
if (d) {
|
|
364
|
+
const l = d[1].match(/\d+/g);
|
|
365
|
+
l && l.forEach((f) => n.add(parseInt(f)));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const s = e.split(`
|
|
369
|
+
`), r = [];
|
|
370
|
+
let a = !1;
|
|
371
|
+
for (const p of s) {
|
|
372
|
+
if (/^##\s+Dependencies$/i.test(p)) {
|
|
373
|
+
a = !0;
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
if (a && /^#/.test(p))
|
|
377
|
+
break;
|
|
378
|
+
a && r.push(p);
|
|
379
|
+
}
|
|
380
|
+
if (r.length > 0) {
|
|
381
|
+
const p = r.join(`
|
|
382
|
+
`), d = p.matchAll(
|
|
383
|
+
/[-*]\s*(?:Step\s*)?(\d+)/gi
|
|
384
|
+
);
|
|
385
|
+
for (const f of d)
|
|
386
|
+
n.add(parseInt(f[1]));
|
|
387
|
+
const l = p.matchAll(/Step\s+(\d+)/gi);
|
|
388
|
+
for (const f of l)
|
|
389
|
+
n.add(parseInt(f[1]));
|
|
390
|
+
}
|
|
391
|
+
const i = e.matchAll(
|
|
392
|
+
/\(depends\s+on\s+(?:Step\s*)?(\d+(?:\s*,\s*\d+)*)\)/gi
|
|
393
|
+
);
|
|
394
|
+
for (const p of i) {
|
|
395
|
+
const d = p[1].match(/\d+/g);
|
|
396
|
+
d && d.forEach((l) => n.add(parseInt(l)));
|
|
397
|
+
}
|
|
398
|
+
const o = e.matchAll(
|
|
399
|
+
/Requires:\s*(.+?)(?:\n|$)/gi
|
|
400
|
+
);
|
|
401
|
+
for (const p of o) {
|
|
402
|
+
const l = p[1].match(/\d+/g);
|
|
403
|
+
l && l.forEach((f) => n.add(parseInt(f)));
|
|
404
|
+
}
|
|
405
|
+
return Array.from(n).sort((p, d) => p - d);
|
|
406
|
+
}
|
|
407
|
+
async function P(e, n = {}) {
|
|
408
|
+
const {
|
|
409
|
+
includeFeedback: t = !0,
|
|
410
|
+
includeEvidence: s = !0,
|
|
411
|
+
parseStatus: r = !0
|
|
412
|
+
} = n, a = T(e);
|
|
413
|
+
let i;
|
|
414
|
+
try {
|
|
415
|
+
i = await j(a);
|
|
416
|
+
} catch {
|
|
417
|
+
throw new Error(`Plan path does not exist: ${a}`);
|
|
418
|
+
}
|
|
419
|
+
if (!i.isDirectory())
|
|
420
|
+
throw new Error(`Plan path is not a directory: ${a}`);
|
|
421
|
+
const o = await Oe(a), p = await qe(a, o), d = o.steps.length > 0 ? await Me(a, o) : [];
|
|
422
|
+
let l = {
|
|
423
|
+
status: "pending",
|
|
424
|
+
lastUpdatedAt: /* @__PURE__ */ new Date(),
|
|
425
|
+
blockers: [],
|
|
426
|
+
issues: [],
|
|
427
|
+
progress: 0
|
|
428
|
+
};
|
|
429
|
+
if (r && o.status) {
|
|
430
|
+
const g = await y(
|
|
431
|
+
u(a, o.status),
|
|
432
|
+
"utf-8"
|
|
433
|
+
);
|
|
434
|
+
l = We(g, d);
|
|
435
|
+
}
|
|
436
|
+
const f = t && o.feedbackDir ? await Be(u(a, o.feedbackDir)) : void 0, m = s && o.evidenceDir ? await Je(u(a, o.evidenceDir)) : void 0;
|
|
437
|
+
return {
|
|
438
|
+
metadata: p,
|
|
439
|
+
files: o,
|
|
440
|
+
steps: d,
|
|
441
|
+
state: l,
|
|
442
|
+
feedback: f,
|
|
443
|
+
evidence: m
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
async function Oe(e) {
|
|
447
|
+
const n = {
|
|
448
|
+
steps: [],
|
|
449
|
+
subdirectories: []
|
|
450
|
+
}, t = await b(e, { withFileTypes: !0 });
|
|
451
|
+
for (const s of t)
|
|
452
|
+
if (s.isDirectory())
|
|
453
|
+
n.subdirectories.push(s.name), s.name === h.standardDirs.plan ? n.steps = await B(
|
|
454
|
+
u(e, s.name)
|
|
455
|
+
) : s.name === h.standardDirs.feedback ? (n.feedbackDir = s.name, n.feedbackFiles = await Re(
|
|
456
|
+
u(e, s.name)
|
|
457
|
+
)) : s.name === h.standardDirs.evidence ? (n.evidenceDir = s.name, n.evidenceFiles = await Le(
|
|
458
|
+
u(e, s.name)
|
|
459
|
+
)) : s.name === h.standardDirs.analysis ? n.analysisDir = s.name : s.name === h.standardDirs.history && (n.historyDir = s.name);
|
|
460
|
+
else if (s.isFile()) {
|
|
461
|
+
const r = s.name;
|
|
462
|
+
r === h.standardFiles.summary ? n.summary = r : r === h.standardFiles.status ? n.status = r : r === h.standardFiles.executionPlan ? n.executionPlan = r : r === h.standardFiles.readme ? n.readme = r : r === h.standardFiles.changelog ? n.changelog = r : je(r, J(e)) && (n.metaPrompt = r);
|
|
463
|
+
}
|
|
464
|
+
if (n.steps.length === 0) {
|
|
465
|
+
const s = await B(e);
|
|
466
|
+
s.length > 0 && (n.steps = s);
|
|
467
|
+
}
|
|
468
|
+
return n;
|
|
469
|
+
}
|
|
470
|
+
function je(e, n) {
|
|
471
|
+
for (const t of h.metaPromptPatterns) {
|
|
472
|
+
const s = t.replace("{code}", n);
|
|
473
|
+
if (e === s)
|
|
474
|
+
return !0;
|
|
475
|
+
}
|
|
476
|
+
return !1;
|
|
477
|
+
}
|
|
478
|
+
async function B(e) {
|
|
479
|
+
let n;
|
|
480
|
+
try {
|
|
481
|
+
n = await b(e);
|
|
482
|
+
} catch {
|
|
483
|
+
return [];
|
|
484
|
+
}
|
|
485
|
+
const t = [];
|
|
486
|
+
for (const s of n)
|
|
487
|
+
h.stepPattern.test(s) && t.push(s);
|
|
488
|
+
return t.sort((s, r) => {
|
|
489
|
+
const a = s.match(h.stepPattern), i = r.match(h.stepPattern);
|
|
490
|
+
if (!a || !i) return 0;
|
|
491
|
+
const o = parseInt(a[1]), p = parseInt(i[1]);
|
|
492
|
+
return o - p;
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
async function Re(e) {
|
|
496
|
+
let n;
|
|
497
|
+
try {
|
|
498
|
+
n = await b(e);
|
|
499
|
+
} catch {
|
|
500
|
+
return [];
|
|
501
|
+
}
|
|
502
|
+
const t = [];
|
|
503
|
+
for (const s of n)
|
|
504
|
+
h.feedbackPattern.test(s) && t.push(s);
|
|
505
|
+
return t.sort((s, r) => {
|
|
506
|
+
const a = s.match(h.feedbackPattern), i = r.match(h.feedbackPattern);
|
|
507
|
+
return !a || !i ? 0 : a[1].localeCompare(i[1]);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
async function Le(e) {
|
|
511
|
+
let n;
|
|
512
|
+
try {
|
|
513
|
+
n = await b(e);
|
|
514
|
+
} catch {
|
|
515
|
+
return [];
|
|
516
|
+
}
|
|
517
|
+
const t = [];
|
|
518
|
+
for (const s of n)
|
|
519
|
+
for (const r of h.evidencePatterns)
|
|
520
|
+
if (r.test(s)) {
|
|
521
|
+
t.push(s);
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
return t.sort();
|
|
525
|
+
}
|
|
526
|
+
async function Me(e, n) {
|
|
527
|
+
const t = [], s = n.subdirectories.includes(
|
|
528
|
+
h.standardDirs.plan
|
|
529
|
+
) ? u(e, h.standardDirs.plan) : e;
|
|
530
|
+
for (const r of n.steps) {
|
|
531
|
+
const a = r.match(h.stepPattern);
|
|
532
|
+
if (!a) continue;
|
|
533
|
+
const [, i, o] = a, p = parseInt(i), d = u(s, r);
|
|
534
|
+
let l;
|
|
535
|
+
try {
|
|
536
|
+
l = await y(d, "utf-8");
|
|
537
|
+
} catch {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
const f = Fe(l);
|
|
541
|
+
t.push({
|
|
542
|
+
number: p,
|
|
543
|
+
code: o,
|
|
544
|
+
filename: r,
|
|
545
|
+
title: q(l) || R(o),
|
|
546
|
+
description: Ue(l),
|
|
547
|
+
status: "pending",
|
|
548
|
+
// Default, may be overridden by STATUS.md
|
|
549
|
+
dependencies: f.length > 0 ? f : void 0,
|
|
550
|
+
filePath: d
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return t;
|
|
554
|
+
}
|
|
555
|
+
async function qe(e, n) {
|
|
556
|
+
const t = J(e);
|
|
557
|
+
let s = R(t), r;
|
|
558
|
+
if (n.summary)
|
|
559
|
+
try {
|
|
560
|
+
const a = await y(
|
|
561
|
+
u(e, n.summary),
|
|
562
|
+
"utf-8"
|
|
563
|
+
), i = q(a);
|
|
564
|
+
i && (s = i), r = U(a);
|
|
565
|
+
} catch {
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
code: t,
|
|
569
|
+
name: s,
|
|
570
|
+
description: r,
|
|
571
|
+
path: e
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function q(e) {
|
|
575
|
+
const n = e.match(/^#\s+(.+)$/m);
|
|
576
|
+
return n ? n[1].trim() : null;
|
|
577
|
+
}
|
|
578
|
+
function Ue(e) {
|
|
579
|
+
return U(e);
|
|
580
|
+
}
|
|
581
|
+
function U(e) {
|
|
582
|
+
const n = e.split(`
|
|
583
|
+
`);
|
|
584
|
+
let t = !1, s = "";
|
|
585
|
+
for (const a of n) {
|
|
586
|
+
if (a.startsWith("#")) {
|
|
587
|
+
if (t && s)
|
|
588
|
+
break;
|
|
589
|
+
t = !0;
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
if (t && a.trim()) {
|
|
593
|
+
if (a.startsWith("-") || a.startsWith("|") || a.startsWith(">") || a.startsWith("```")) {
|
|
594
|
+
if (s) break;
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
s += a.trim() + " ";
|
|
598
|
+
} else if (t && s && !a.trim())
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
return s.trim() || void 0;
|
|
602
|
+
}
|
|
603
|
+
function R(e) {
|
|
604
|
+
return e.replace(/-/g, " ").replace(/_/g, " ").replace(/\b\w/g, (n) => n.toUpperCase());
|
|
605
|
+
}
|
|
606
|
+
const Ge = ["β¬", "π", "β
", "β", "βΈοΈ", "βοΈ"];
|
|
607
|
+
function H(e) {
|
|
608
|
+
for (const n of Ge)
|
|
609
|
+
if (e.includes(n))
|
|
610
|
+
return n;
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
function We(e, n) {
|
|
614
|
+
const t = {
|
|
615
|
+
status: "pending",
|
|
616
|
+
lastUpdatedAt: /* @__PURE__ */ new Date(),
|
|
617
|
+
blockers: [],
|
|
618
|
+
issues: [],
|
|
619
|
+
progress: 0
|
|
620
|
+
}, s = e.match(/\*\*Status\*\*\s*\|\s*([^|]+)/i);
|
|
621
|
+
if (s) {
|
|
622
|
+
const p = H(s[1]);
|
|
623
|
+
if (p) {
|
|
624
|
+
const d = h.emojiToStatus[p];
|
|
625
|
+
d && (t.status = d);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
const r = e.split(`
|
|
629
|
+
`);
|
|
630
|
+
for (const p of r) {
|
|
631
|
+
const d = p.match(/^\|\s*(\d{2})\s*\|[^|]+\|([^|]+)\|/);
|
|
632
|
+
if (d) {
|
|
633
|
+
const l = parseInt(d[1]), f = d[2], m = H(f);
|
|
634
|
+
if (m) {
|
|
635
|
+
const g = h.emojiToStatus[m];
|
|
636
|
+
if (g) {
|
|
637
|
+
const v = n.find((k) => k.number === l);
|
|
638
|
+
v && (v.status = g);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const a = n.filter((p) => p.status === "completed").length;
|
|
644
|
+
t.progress = n.length > 0 ? Math.round(a / n.length * 100) : 0;
|
|
645
|
+
const i = n.find((p) => p.status === "in_progress");
|
|
646
|
+
i && (t.currentStep = i.number);
|
|
647
|
+
const o = n.filter((p) => p.status === "completed").map((p) => p.number);
|
|
648
|
+
return o.length > 0 && (t.lastCompletedStep = Math.max(...o)), t;
|
|
649
|
+
}
|
|
650
|
+
async function Be(e) {
|
|
651
|
+
let n;
|
|
652
|
+
try {
|
|
653
|
+
n = await b(e);
|
|
654
|
+
} catch {
|
|
655
|
+
return [];
|
|
656
|
+
}
|
|
657
|
+
const t = [];
|
|
658
|
+
for (const s of n)
|
|
659
|
+
if (h.feedbackPattern.test(s))
|
|
660
|
+
try {
|
|
661
|
+
const r = await y(u(e, s), "utf-8"), a = He(s, r);
|
|
662
|
+
a && t.push(a);
|
|
663
|
+
} catch {
|
|
664
|
+
}
|
|
665
|
+
return t.sort((s, r) => s.id.localeCompare(r.id));
|
|
666
|
+
}
|
|
667
|
+
function He(e, n) {
|
|
668
|
+
const t = e.match(h.feedbackPattern);
|
|
669
|
+
if (!t) return null;
|
|
670
|
+
const [, s, r] = t, { frontmatter: a, body: i } = K(n), o = [];
|
|
671
|
+
if (Array.isArray(a.participants)) {
|
|
672
|
+
for (const d of a.participants)
|
|
673
|
+
if (typeof d == "string")
|
|
674
|
+
o.push({ name: d, type: "human" });
|
|
675
|
+
else if (d && typeof d == "object") {
|
|
676
|
+
const l = d;
|
|
677
|
+
o.push({
|
|
678
|
+
name: (typeof l.name == "string" ? l.name : void 0) || "Unknown",
|
|
679
|
+
type: l.type === "human" || l.type === "ai" ? l.type : "human",
|
|
680
|
+
model: typeof l.model == "string" ? l.model : void 0
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
let p = "other";
|
|
685
|
+
return typeof a.platform == "string" && [
|
|
686
|
+
"cursor",
|
|
687
|
+
"chatgpt",
|
|
688
|
+
"slack",
|
|
689
|
+
"email",
|
|
690
|
+
"meeting",
|
|
691
|
+
"voice",
|
|
692
|
+
"document",
|
|
693
|
+
"other"
|
|
694
|
+
].includes(a.platform) && (p = a.platform), {
|
|
695
|
+
id: s,
|
|
696
|
+
title: (typeof a.title == "string" ? a.title : void 0) || R(r),
|
|
697
|
+
createdAt: typeof a.date == "string" || typeof a.date == "number" ? new Date(a.date) : /* @__PURE__ */ new Date(),
|
|
698
|
+
participants: o.length > 0 ? o : [{ name: "Unknown", type: "human" }],
|
|
699
|
+
platform: p,
|
|
700
|
+
planVersion: typeof a.planVersion == "string" ? a.planVersion : void 0,
|
|
701
|
+
feedback: i.trim(),
|
|
702
|
+
resolution: typeof a.resolution == "string" ? a.resolution : void 0,
|
|
703
|
+
changes: Array.isArray(a.changes) ? a.changes.filter((d) => typeof d == "string") : void 0,
|
|
704
|
+
openQuestions: Array.isArray(a.openQuestions) ? a.openQuestions.filter((d) => typeof d == "string") : void 0,
|
|
705
|
+
filename: e
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
async function Je(e) {
|
|
709
|
+
let n;
|
|
710
|
+
try {
|
|
711
|
+
n = await b(e);
|
|
712
|
+
} catch {
|
|
713
|
+
return [];
|
|
714
|
+
}
|
|
715
|
+
const t = [];
|
|
716
|
+
for (const s of n) {
|
|
717
|
+
let r = !1;
|
|
718
|
+
for (const a of h.evidencePatterns)
|
|
719
|
+
if (a.test(s)) {
|
|
720
|
+
r = !0;
|
|
721
|
+
break;
|
|
722
|
+
}
|
|
723
|
+
if (r)
|
|
724
|
+
try {
|
|
725
|
+
const a = await y(u(e, s), "utf-8"), i = Ye(s, a);
|
|
726
|
+
i && t.push(i);
|
|
727
|
+
} catch {
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return t.sort((s, r) => s.id.localeCompare(r.id));
|
|
731
|
+
}
|
|
732
|
+
function Ye(e, n) {
|
|
733
|
+
let t = "reference", s = null;
|
|
734
|
+
for (let p = 0; p < h.evidencePatterns.length; p++) {
|
|
735
|
+
const d = h.evidencePatterns[p], l = e.match(d);
|
|
736
|
+
if (l) {
|
|
737
|
+
s = l, t = [
|
|
738
|
+
"case-study",
|
|
739
|
+
"research",
|
|
740
|
+
"analysis",
|
|
741
|
+
"example"
|
|
742
|
+
][p] || "reference";
|
|
743
|
+
break;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (!s) return null;
|
|
747
|
+
const { frontmatter: r, body: a } = K(n), i = r.title || q(a) || R(s[1] || e);
|
|
748
|
+
return {
|
|
749
|
+
id: e.replace(/\.md$/, ""),
|
|
750
|
+
type: t,
|
|
751
|
+
title: typeof i == "string" ? i : "",
|
|
752
|
+
createdAt: typeof r.date == "string" || typeof r.date == "number" ? new Date(r.date) : /* @__PURE__ */ new Date(),
|
|
753
|
+
source: typeof r.source == "string" ? r.source : void 0,
|
|
754
|
+
filename: e,
|
|
755
|
+
summary: (typeof r.summary == "string" ? r.summary : void 0) || U(a),
|
|
756
|
+
tags: Array.isArray(r.tags) ? r.tags.filter((p) => typeof p == "string") : void 0
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
function K(e) {
|
|
760
|
+
if (!e.startsWith(`---
|
|
761
|
+
`))
|
|
762
|
+
return { frontmatter: {}, body: e };
|
|
763
|
+
const n = e.indexOf(`
|
|
764
|
+
---
|
|
765
|
+
`, 4);
|
|
766
|
+
if (n === -1)
|
|
767
|
+
return { frontmatter: {}, body: e };
|
|
768
|
+
const t = e.substring(4, n), s = e.substring(n + 5), r = {}, a = t.split(`
|
|
769
|
+
`);
|
|
770
|
+
let i = null, o = null;
|
|
771
|
+
for (const p of a) {
|
|
772
|
+
const d = p.trim();
|
|
773
|
+
if (d.startsWith("- ") && i) {
|
|
774
|
+
o || (o = [], r[i] = o);
|
|
775
|
+
const f = d.slice(2).trim();
|
|
776
|
+
if (f.includes(":")) {
|
|
777
|
+
const m = {}, g = f.split(",").map((v) => v.trim());
|
|
778
|
+
for (const v of g) {
|
|
779
|
+
const [k, E] = v.split(":").map((D) => D.trim());
|
|
780
|
+
k && E && (m[k] = E.replace(/^["']|["']$/g, ""));
|
|
781
|
+
}
|
|
782
|
+
o.push(m);
|
|
783
|
+
} else
|
|
784
|
+
o.push(f.replace(/^["']|["']$/g, ""));
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
const l = p.match(/^(\w+):\s*(.*)$/);
|
|
788
|
+
if (l) {
|
|
789
|
+
const [, f, m] = l;
|
|
790
|
+
i = f, o = null, m.trim() && (r[f] = m.trim().replace(/^["']|["']$/g, ""));
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return { frontmatter: r, body: s };
|
|
794
|
+
}
|
|
795
|
+
const Ke = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
796
|
+
__proto__: null,
|
|
797
|
+
loadPlan: P
|
|
798
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
799
|
+
async function Ve(e, n) {
|
|
800
|
+
try {
|
|
801
|
+
const t = e.path ? e.path : A(e, n), s = await P(t), r = s.steps.filter((p) => p.status === "completed").length, a = s.steps.length, i = a > 0 ? Math.round(r / a * 100) : 0, o = {
|
|
802
|
+
planPath: s.metadata.path,
|
|
803
|
+
code: s.metadata.code,
|
|
804
|
+
name: s.metadata.name,
|
|
805
|
+
status: s.state.status,
|
|
806
|
+
currentStep: s.state.currentStep,
|
|
807
|
+
lastCompleted: s.state.lastCompletedStep,
|
|
808
|
+
progress: {
|
|
809
|
+
completed: r,
|
|
810
|
+
total: a,
|
|
811
|
+
percentage: i
|
|
812
|
+
},
|
|
813
|
+
blockers: s.state.blockers || [],
|
|
814
|
+
issues: s.state.issues || [],
|
|
815
|
+
startedAt: s.state.startedAt,
|
|
816
|
+
lastUpdated: s.state.lastUpdatedAt
|
|
817
|
+
};
|
|
818
|
+
return e.verbose && (o.steps = s.steps.map((p) => ({
|
|
819
|
+
number: p.number,
|
|
820
|
+
title: p.title,
|
|
821
|
+
status: p.status,
|
|
822
|
+
startedAt: p.startedAt,
|
|
823
|
+
completedAt: p.completedAt
|
|
824
|
+
}))), C(o);
|
|
825
|
+
} catch (t) {
|
|
826
|
+
return x(t);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
async function Qe(e) {
|
|
830
|
+
let n = u(e, h.standardDirs.plan), t;
|
|
831
|
+
try {
|
|
832
|
+
t = await b(n);
|
|
833
|
+
} catch {
|
|
834
|
+
n = e, t = await b(n);
|
|
835
|
+
}
|
|
836
|
+
const s = [];
|
|
837
|
+
for (const r of t) {
|
|
838
|
+
const a = r.match(h.stepPattern);
|
|
839
|
+
a && s.push({
|
|
840
|
+
number: parseInt(a[1]),
|
|
841
|
+
code: a[2],
|
|
842
|
+
filename: r,
|
|
843
|
+
path: u(n, r)
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
return s.sort((r, a) => r.number - a.number);
|
|
847
|
+
}
|
|
848
|
+
async function V(e) {
|
|
849
|
+
const n = u(e, h.standardDirs.plan);
|
|
850
|
+
try {
|
|
851
|
+
return await b(n), n;
|
|
852
|
+
} catch {
|
|
853
|
+
return e;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function Q(e, n) {
|
|
857
|
+
return `${String(e).padStart(2, "0")}-${n}.md`;
|
|
858
|
+
}
|
|
859
|
+
function ze(e) {
|
|
860
|
+
return e.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
861
|
+
}
|
|
862
|
+
async function Xe(e, n, t) {
|
|
863
|
+
const s = await V(e), r = await Qe(e), a = [], i = r.filter((o) => o.number >= n).reverse();
|
|
864
|
+
for (const o of i) {
|
|
865
|
+
const p = o.number + t, d = Q(p, o.code), l = u(s, d);
|
|
866
|
+
if (o.filename !== d) {
|
|
867
|
+
await ke(o.path, l), a.push({ from: o.filename, to: d });
|
|
868
|
+
const f = await y(l, "utf-8"), m = f.replace(
|
|
869
|
+
/^#\s+Step\s+\d+:/m,
|
|
870
|
+
`# Step ${String(p).padStart(2, "0")}:`
|
|
871
|
+
);
|
|
872
|
+
m !== f && await w(l, m);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
return a;
|
|
876
|
+
}
|
|
877
|
+
function Ze(e, n, t) {
|
|
878
|
+
return `# Step ${String(e).padStart(2, "0")}: ${n}
|
|
879
|
+
|
|
880
|
+
## Objective
|
|
881
|
+
|
|
882
|
+
${t || "Describe the objective of this step."}
|
|
883
|
+
|
|
884
|
+
## Background
|
|
885
|
+
|
|
886
|
+
Provide context and rationale for this step.
|
|
887
|
+
|
|
888
|
+
## Tasks
|
|
889
|
+
|
|
890
|
+
### 1. Task 1
|
|
891
|
+
|
|
892
|
+
Description of task 1.
|
|
893
|
+
|
|
894
|
+
## Acceptance Criteria
|
|
895
|
+
|
|
896
|
+
- [ ] Criterion 1
|
|
897
|
+
- [ ] Criterion 2
|
|
898
|
+
|
|
899
|
+
## Testing
|
|
900
|
+
|
|
901
|
+
Describe how to verify this step is complete.
|
|
902
|
+
|
|
903
|
+
## Files Changed
|
|
904
|
+
|
|
905
|
+
- File 1
|
|
906
|
+
|
|
907
|
+
## Notes
|
|
908
|
+
|
|
909
|
+
`;
|
|
910
|
+
}
|
|
911
|
+
async function et(e, n) {
|
|
912
|
+
const t = await V(e.metadata.path);
|
|
913
|
+
let s;
|
|
914
|
+
if (n.position !== void 0 ? s = n.position : n.after !== void 0 ? s = n.after + 1 : s = e.steps.length + 1, s < 1 || s > e.steps.length + 1)
|
|
915
|
+
throw new Error(
|
|
916
|
+
`Invalid position ${s}. Must be between 1 and ${e.steps.length + 1}`
|
|
917
|
+
);
|
|
918
|
+
let r = [];
|
|
919
|
+
s <= e.steps.length && (r = await Xe(e.metadata.path, s, 1));
|
|
920
|
+
const a = ze(n.title), i = Q(s, a), o = u(t, i), p = Ze(
|
|
921
|
+
s,
|
|
922
|
+
n.title,
|
|
923
|
+
n.description
|
|
924
|
+
);
|
|
925
|
+
return await w(o, p), {
|
|
926
|
+
step: {
|
|
927
|
+
number: s,
|
|
928
|
+
code: a,
|
|
929
|
+
filename: i,
|
|
930
|
+
title: n.title,
|
|
931
|
+
description: n.description,
|
|
932
|
+
status: n.status || "pending",
|
|
933
|
+
filePath: o
|
|
934
|
+
},
|
|
935
|
+
renamedFiles: r,
|
|
936
|
+
createdFile: o
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
function tt(e, n, t) {
|
|
940
|
+
const s = e.steps.find((r) => r.number === n);
|
|
941
|
+
if (!s)
|
|
942
|
+
throw new Error(`Step ${n} not found`);
|
|
943
|
+
return {
|
|
944
|
+
...s,
|
|
945
|
+
status: "completed",
|
|
946
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
947
|
+
notes: t
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
function nt(e, n) {
|
|
951
|
+
const t = e.steps.find((s) => s.number === n);
|
|
952
|
+
if (!t)
|
|
953
|
+
throw new Error(`Step ${n} not found`);
|
|
954
|
+
return {
|
|
955
|
+
...t,
|
|
956
|
+
status: "in_progress",
|
|
957
|
+
startedAt: /* @__PURE__ */ new Date()
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
function N(e, n) {
|
|
961
|
+
if (!e) return "-";
|
|
962
|
+
switch (n) {
|
|
963
|
+
case "iso":
|
|
964
|
+
return e.toISOString().split("T")[0];
|
|
965
|
+
case "long":
|
|
966
|
+
return e.toLocaleDateString("en-US", {
|
|
967
|
+
year: "numeric",
|
|
968
|
+
month: "long",
|
|
969
|
+
day: "numeric"
|
|
970
|
+
});
|
|
971
|
+
default:
|
|
972
|
+
return e.toISOString().split("T")[0];
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
function G(e) {
|
|
976
|
+
return h.statusEmoji[e] || "β¬";
|
|
977
|
+
}
|
|
978
|
+
function st(e) {
|
|
979
|
+
const n = G(e), t = e.toUpperCase().replace("_", " ");
|
|
980
|
+
return `${n} ${t}`;
|
|
981
|
+
}
|
|
982
|
+
function at(e, n) {
|
|
983
|
+
const { state: t, steps: s } = e, r = s.filter((l) => l.status === "completed").length, a = s.length > 0 ? Math.round(r / s.length * 100) : 0, i = t.currentStep ? s.find((l) => l.number === t.currentStep) : void 0, o = t.lastCompletedStep ? s.find((l) => l.number === t.lastCompletedStep) : void 0, p = i ? `${String(i.number).padStart(2, "0")} - ${i.title}` : "-", d = o ? `${String(o.number).padStart(2, "0")} - ${o.title}` : "-";
|
|
984
|
+
return `## Current State
|
|
985
|
+
|
|
986
|
+
| Field | Value |
|
|
987
|
+
|-------|-------|
|
|
988
|
+
| **Status** | ${st(t.status)} |
|
|
989
|
+
| **Current Step** | ${p} |
|
|
990
|
+
| **Last Completed** | ${d} |
|
|
991
|
+
| **Started** | ${N(t.startedAt, n)} |
|
|
992
|
+
| **Last Updated** | ${N(t.lastUpdatedAt, n)} |
|
|
993
|
+
| **Progress** | ${a}% (${r}/${s.length} steps) |
|
|
994
|
+
`;
|
|
995
|
+
}
|
|
996
|
+
function rt(e) {
|
|
997
|
+
if (!e.phases || e.phases.length === 0) return "";
|
|
998
|
+
let n = `## Phase Progress
|
|
999
|
+
|
|
1000
|
+
| Phase | Steps | Status | Progress |
|
|
1001
|
+
|-------|-------|--------|----------|
|
|
1002
|
+
`;
|
|
1003
|
+
for (const t of e.phases) {
|
|
1004
|
+
const s = e.steps.filter(
|
|
1005
|
+
(p) => t.steps.includes(p.number)
|
|
1006
|
+
), a = `${s.filter(
|
|
1007
|
+
(p) => p.status === "completed"
|
|
1008
|
+
).length}/${s.length}`, i = `${String(t.steps[0]).padStart(2, "0")}-${String(t.steps[t.steps.length - 1]).padStart(2, "0")}`, o = t.status.charAt(0).toUpperCase() + t.status.slice(1).replace("_", " ");
|
|
1009
|
+
n += `| **${t.name}** | ${i} | ${G(t.status)} ${o} | ${a} |
|
|
1010
|
+
`;
|
|
1011
|
+
}
|
|
1012
|
+
return n + `
|
|
1013
|
+
`;
|
|
1014
|
+
}
|
|
1015
|
+
function it(e, n) {
|
|
1016
|
+
let t = `## Step Progress
|
|
1017
|
+
|
|
1018
|
+
| Step | Name | Status | Started | Completed | Notes |
|
|
1019
|
+
|------|------|--------|---------|-----------|-------|
|
|
1020
|
+
`;
|
|
1021
|
+
for (const s of e) {
|
|
1022
|
+
const r = String(s.number).padStart(2, "0"), a = N(s.startedAt, n), i = N(s.completedAt, n), o = s.notes || "";
|
|
1023
|
+
t += `| ${r} | ${s.title} | ${G(s.status)} | ${a} | ${i} | ${o} |
|
|
1024
|
+
`;
|
|
1025
|
+
}
|
|
1026
|
+
return t + `
|
|
1027
|
+
`;
|
|
1028
|
+
}
|
|
1029
|
+
function ot(e) {
|
|
1030
|
+
if (e.length === 0)
|
|
1031
|
+
return `## Blockers
|
|
1032
|
+
|
|
1033
|
+
None currently.
|
|
1034
|
+
|
|
1035
|
+
`;
|
|
1036
|
+
let n = `## Blockers
|
|
1037
|
+
|
|
1038
|
+
`;
|
|
1039
|
+
for (const t of e)
|
|
1040
|
+
n += `- ${t.description}`, t.affectedSteps && t.affectedSteps.length > 0 && (n += ` (affects steps: ${t.affectedSteps.join(", ")})`), n += `
|
|
1041
|
+
`;
|
|
1042
|
+
return n + `
|
|
1043
|
+
`;
|
|
1044
|
+
}
|
|
1045
|
+
function ct(e) {
|
|
1046
|
+
if (e.length === 0)
|
|
1047
|
+
return `## Issues
|
|
1048
|
+
|
|
1049
|
+
None currently.
|
|
1050
|
+
|
|
1051
|
+
`;
|
|
1052
|
+
let n = `## Issues
|
|
1053
|
+
|
|
1054
|
+
`;
|
|
1055
|
+
for (const t of e)
|
|
1056
|
+
n += `- **${t.title}**: ${t.description}
|
|
1057
|
+
`;
|
|
1058
|
+
return n + `
|
|
1059
|
+
`;
|
|
1060
|
+
}
|
|
1061
|
+
function pt(e) {
|
|
1062
|
+
return `## Notes
|
|
1063
|
+
|
|
1064
|
+
${e || ""}
|
|
1065
|
+
|
|
1066
|
+
`;
|
|
1067
|
+
}
|
|
1068
|
+
function dt(e) {
|
|
1069
|
+
return `---
|
|
1070
|
+
|
|
1071
|
+
**Status Legend**:
|
|
1072
|
+
- ${h.statusEmoji.pending} Pending
|
|
1073
|
+
- ${h.statusEmoji.in_progress} In Progress
|
|
1074
|
+
- ${h.statusEmoji.completed} Completed
|
|
1075
|
+
- ${h.statusEmoji.failed} Failed
|
|
1076
|
+
- ${h.statusEmoji.blocked} Blocked
|
|
1077
|
+
- ${h.statusEmoji.skipped} Skipped
|
|
1078
|
+
|
|
1079
|
+
*Last updated: ${N(/* @__PURE__ */ new Date(), e)}*
|
|
1080
|
+
`;
|
|
1081
|
+
}
|
|
1082
|
+
function z(e, n = {}) {
|
|
1083
|
+
const {
|
|
1084
|
+
preserveNotes: t = !0,
|
|
1085
|
+
existingContent: s,
|
|
1086
|
+
includePhases: r = !0,
|
|
1087
|
+
dateFormat: a = "short"
|
|
1088
|
+
} = n;
|
|
1089
|
+
let i;
|
|
1090
|
+
if (t && s) {
|
|
1091
|
+
const p = s.split(`
|
|
1092
|
+
`), d = [];
|
|
1093
|
+
let l = !1;
|
|
1094
|
+
for (const f of p) {
|
|
1095
|
+
if (/^## Notes$/i.test(f)) {
|
|
1096
|
+
l = !0;
|
|
1097
|
+
continue;
|
|
1098
|
+
}
|
|
1099
|
+
if (l && (/^##/.test(f) || /^---/.test(f)))
|
|
1100
|
+
break;
|
|
1101
|
+
l && d.push(f);
|
|
1102
|
+
}
|
|
1103
|
+
d.length > 0 && (i = d.join(`
|
|
1104
|
+
`).trim());
|
|
1105
|
+
}
|
|
1106
|
+
let o = `# ${e.metadata.name} Status
|
|
1107
|
+
|
|
1108
|
+
`;
|
|
1109
|
+
return o += at(e, a), o += `
|
|
1110
|
+
`, r && e.phases && e.phases.length > 0 && (o += rt(e)), o += it(e.steps, a), o += ot(e.state.blockers), o += ct(e.state.issues), o += pt(i), o += dt(a), o;
|
|
1111
|
+
}
|
|
1112
|
+
async function lt(e, n) {
|
|
1113
|
+
try {
|
|
1114
|
+
const t = e.path ? e.path : A(e, n), s = await P(t);
|
|
1115
|
+
let r = s.steps;
|
|
1116
|
+
return e.pending ? r = r.filter((a) => a.status === "pending") : e.all || (r = r.filter((a) => a.status !== "completed")), C({
|
|
1117
|
+
planPath: s.metadata.path,
|
|
1118
|
+
steps: r.map((a) => ({
|
|
1119
|
+
number: a.number,
|
|
1120
|
+
title: a.title,
|
|
1121
|
+
status: a.status,
|
|
1122
|
+
file: a.filename,
|
|
1123
|
+
startedAt: a.startedAt,
|
|
1124
|
+
completedAt: a.completedAt
|
|
1125
|
+
}))
|
|
1126
|
+
});
|
|
1127
|
+
} catch (t) {
|
|
1128
|
+
return x(t);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
async function ut(e, n) {
|
|
1132
|
+
try {
|
|
1133
|
+
const t = e.path ? e.path : A(e, n), s = await P(t), r = nt(s, e.step), a = s.steps.findIndex((o) => o.number === e.step);
|
|
1134
|
+
a >= 0 && (s.steps[a] = r), s.state.currentStep = e.step, s.state.status = "in_progress", s.state.lastUpdatedAt = /* @__PURE__ */ new Date();
|
|
1135
|
+
const i = z(s);
|
|
1136
|
+
return await w(u(t, "STATUS.md"), i, "utf-8"), C(
|
|
1137
|
+
{ planPath: t, step: e.step },
|
|
1138
|
+
`Step ${e.step} marked as started`
|
|
1139
|
+
);
|
|
1140
|
+
} catch (t) {
|
|
1141
|
+
return x(t);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
async function ht(e, n) {
|
|
1145
|
+
try {
|
|
1146
|
+
const t = e.path ? e.path : A(e, n), s = await P(t), r = tt(s, e.step), a = s.steps.findIndex((p) => p.number === e.step);
|
|
1147
|
+
a >= 0 && (s.steps[a] = r), s.state.lastCompletedStep = e.step, s.state.lastUpdatedAt = /* @__PURE__ */ new Date();
|
|
1148
|
+
const i = s.steps.find((p) => p.status === "pending");
|
|
1149
|
+
i ? (s.state.currentStep = i.number, s.state.status = "in_progress") : (s.state.status = "completed", s.state.currentStep = void 0);
|
|
1150
|
+
const o = z(s);
|
|
1151
|
+
return await w(u(t, "STATUS.md"), o, "utf-8"), C(
|
|
1152
|
+
{ planPath: t, step: e.step },
|
|
1153
|
+
`Step ${e.step} marked as completed`
|
|
1154
|
+
);
|
|
1155
|
+
} catch (t) {
|
|
1156
|
+
return x(t);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
async function mt(e, n) {
|
|
1160
|
+
try {
|
|
1161
|
+
const t = e.path ? e.path : A(e, n), s = await P(t), r = await et(s, {
|
|
1162
|
+
title: e.title,
|
|
1163
|
+
position: e.number,
|
|
1164
|
+
after: e.after,
|
|
1165
|
+
status: "pending"
|
|
1166
|
+
});
|
|
1167
|
+
return C(
|
|
1168
|
+
{
|
|
1169
|
+
planPath: t,
|
|
1170
|
+
step: r.step.number,
|
|
1171
|
+
file: r.createdFile,
|
|
1172
|
+
renamedFiles: r.renamedFiles
|
|
1173
|
+
},
|
|
1174
|
+
`Step "${e.title}" added as step ${r.step.number}`
|
|
1175
|
+
);
|
|
1176
|
+
} catch (t) {
|
|
1177
|
+
return x(t);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
async function ft(e) {
|
|
1181
|
+
const n = [], t = [];
|
|
1182
|
+
try {
|
|
1183
|
+
await I(e);
|
|
1184
|
+
} catch {
|
|
1185
|
+
return n.push({
|
|
1186
|
+
code: "DIR_NOT_FOUND",
|
|
1187
|
+
message: `Plan directory not found: ${e}`,
|
|
1188
|
+
path: e
|
|
1189
|
+
}), { errors: n, warnings: t };
|
|
1190
|
+
}
|
|
1191
|
+
const s = u(e, h.standardFiles.summary);
|
|
1192
|
+
try {
|
|
1193
|
+
await I(s);
|
|
1194
|
+
} catch {
|
|
1195
|
+
t.push({
|
|
1196
|
+
code: "MISSING_SUMMARY",
|
|
1197
|
+
message: "SUMMARY.md not found",
|
|
1198
|
+
path: s
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
const r = u(e, h.standardFiles.status);
|
|
1202
|
+
try {
|
|
1203
|
+
await I(r);
|
|
1204
|
+
} catch {
|
|
1205
|
+
t.push({
|
|
1206
|
+
code: "MISSING_STATUS",
|
|
1207
|
+
message: "STATUS.md not found",
|
|
1208
|
+
path: r
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
const a = u(
|
|
1212
|
+
e,
|
|
1213
|
+
h.standardFiles.executionPlan
|
|
1214
|
+
);
|
|
1215
|
+
try {
|
|
1216
|
+
await I(a);
|
|
1217
|
+
} catch {
|
|
1218
|
+
t.push({
|
|
1219
|
+
code: "MISSING_EXEC_PLAN",
|
|
1220
|
+
message: "EXECUTION_PLAN.md not found",
|
|
1221
|
+
path: a
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
const i = u(e, h.standardDirs.plan);
|
|
1225
|
+
try {
|
|
1226
|
+
await I(i), (await b(i)).filter(
|
|
1227
|
+
(d) => h.stepPattern.test(d)
|
|
1228
|
+
).length === 0 && t.push({
|
|
1229
|
+
code: "NO_STEPS",
|
|
1230
|
+
message: "No step files found in plan/ directory"
|
|
1231
|
+
});
|
|
1232
|
+
} catch {
|
|
1233
|
+
try {
|
|
1234
|
+
(await b(e)).filter(
|
|
1235
|
+
(d) => h.stepPattern.test(d)
|
|
1236
|
+
).length === 0 && t.push({
|
|
1237
|
+
code: "NO_STEPS",
|
|
1238
|
+
message: "No step files found"
|
|
1239
|
+
});
|
|
1240
|
+
} catch {
|
|
1241
|
+
t.push({
|
|
1242
|
+
code: "NO_STEPS",
|
|
1243
|
+
message: "Unable to read plan directory for step files"
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return { errors: n, warnings: t };
|
|
1248
|
+
}
|
|
1249
|
+
async function gt(e) {
|
|
1250
|
+
const n = [], t = [], s = [], r = u(e, h.standardDirs.plan);
|
|
1251
|
+
let a = [], i = r;
|
|
1252
|
+
try {
|
|
1253
|
+
a = (await b(r)).filter((l) => h.stepPattern.test(l));
|
|
1254
|
+
} catch {
|
|
1255
|
+
try {
|
|
1256
|
+
a = (await b(e)).filter(
|
|
1257
|
+
(l) => h.stepPattern.test(l)
|
|
1258
|
+
), i = e;
|
|
1259
|
+
} catch {
|
|
1260
|
+
return { errors: n, warnings: t, fixable: s };
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
if (a.length === 0) return { errors: n, warnings: t, fixable: s };
|
|
1264
|
+
const o = [];
|
|
1265
|
+
for (const d of a) {
|
|
1266
|
+
const l = d.match(h.stepPattern);
|
|
1267
|
+
l && o.push(parseInt(l[1]));
|
|
1268
|
+
}
|
|
1269
|
+
o.sort((d, l) => d - l);
|
|
1270
|
+
for (let d = 0; d < o.length; d++) {
|
|
1271
|
+
const l = d + 1;
|
|
1272
|
+
if (o[d] !== l && o[d] > l) {
|
|
1273
|
+
t.push({
|
|
1274
|
+
code: "STEP_GAP",
|
|
1275
|
+
message: `Gap in step numbering: expected ${l}, found ${o[d]}`,
|
|
1276
|
+
step: o[d]
|
|
1277
|
+
});
|
|
1278
|
+
const f = l;
|
|
1279
|
+
s.push({
|
|
1280
|
+
code: "FIX_STEP_GAP",
|
|
1281
|
+
description: `Renumber steps to close gap at ${f}`,
|
|
1282
|
+
fix: async () => {
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
const p = /* @__PURE__ */ new Set();
|
|
1288
|
+
for (const d of o)
|
|
1289
|
+
p.has(d) && n.push({
|
|
1290
|
+
code: "DUPLICATE_STEP",
|
|
1291
|
+
message: `Duplicate step number: ${d}`,
|
|
1292
|
+
step: d
|
|
1293
|
+
}), p.add(d);
|
|
1294
|
+
return o[0] === 0 && t.push({
|
|
1295
|
+
code: "STEP_ZERO",
|
|
1296
|
+
message: "Step numbering should start at 01, not 00"
|
|
1297
|
+
}), { errors: n, warnings: t, fixable: s };
|
|
1298
|
+
}
|
|
1299
|
+
async function yt(e) {
|
|
1300
|
+
const n = [], t = [];
|
|
1301
|
+
try {
|
|
1302
|
+
const s = await y(e.filePath, "utf-8");
|
|
1303
|
+
s.match(/^#\s+/m) || t.push({
|
|
1304
|
+
code: "MISSING_TITLE",
|
|
1305
|
+
message: `Step ${e.number} missing title heading`,
|
|
1306
|
+
step: e.number,
|
|
1307
|
+
path: e.filePath
|
|
1308
|
+
}), s.match(/##\s+Objective/i) || t.push({
|
|
1309
|
+
code: "MISSING_OBJECTIVE",
|
|
1310
|
+
message: `Step ${e.number} missing Objective section`,
|
|
1311
|
+
step: e.number
|
|
1312
|
+
}), s.match(/##\s+Acceptance Criteria/i) || t.push({
|
|
1313
|
+
code: "MISSING_ACCEPTANCE",
|
|
1314
|
+
message: `Step ${e.number} missing Acceptance Criteria section`,
|
|
1315
|
+
step: e.number
|
|
1316
|
+
});
|
|
1317
|
+
const r = s.match(/^#\s+Step\s+(\d+)/m);
|
|
1318
|
+
if (r) {
|
|
1319
|
+
const a = parseInt(r[1]);
|
|
1320
|
+
a !== e.number && n.push({
|
|
1321
|
+
code: "STEP_NUMBER_MISMATCH",
|
|
1322
|
+
message: `Step ${e.number} has title "Step ${a}" - mismatch`,
|
|
1323
|
+
step: e.number
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
} catch {
|
|
1327
|
+
n.push({
|
|
1328
|
+
code: "STEP_UNREADABLE",
|
|
1329
|
+
message: `Cannot read step file: ${e.filePath}`,
|
|
1330
|
+
step: e.number
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
return { errors: n, warnings: t };
|
|
1334
|
+
}
|
|
1335
|
+
function wt(e) {
|
|
1336
|
+
const n = [], t = [], s = new Set(e.map((a) => a.number));
|
|
1337
|
+
for (const a of e)
|
|
1338
|
+
if (a.dependencies)
|
|
1339
|
+
for (const i of a.dependencies)
|
|
1340
|
+
s.has(i) || n.push({
|
|
1341
|
+
code: "INVALID_DEPENDENCY",
|
|
1342
|
+
message: `Step ${a.number} depends on non-existent step ${i}`,
|
|
1343
|
+
step: a.number
|
|
1344
|
+
}), i === a.number && n.push({
|
|
1345
|
+
code: "SELF_DEPENDENCY",
|
|
1346
|
+
message: `Step ${a.number} depends on itself`,
|
|
1347
|
+
step: a.number
|
|
1348
|
+
}), i > a.number && t.push({
|
|
1349
|
+
code: "FORWARD_DEPENDENCY",
|
|
1350
|
+
message: `Step ${a.number} depends on later step ${i}`,
|
|
1351
|
+
step: a.number
|
|
1352
|
+
});
|
|
1353
|
+
const r = St(e);
|
|
1354
|
+
for (const a of r)
|
|
1355
|
+
n.push({
|
|
1356
|
+
code: "CIRCULAR_DEPENDENCY",
|
|
1357
|
+
message: `Circular dependency detected: ${a.join(" β ")}`
|
|
1358
|
+
});
|
|
1359
|
+
return { errors: n, warnings: t };
|
|
1360
|
+
}
|
|
1361
|
+
function St(e) {
|
|
1362
|
+
const n = [], t = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), r = [], a = new Map(e.map((o) => [o.number, o]));
|
|
1363
|
+
function i(o) {
|
|
1364
|
+
if (s.has(o)) {
|
|
1365
|
+
const d = r.indexOf(o);
|
|
1366
|
+
n.push([...r.slice(d), o]);
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
if (t.has(o)) return;
|
|
1370
|
+
t.add(o), s.add(o), r.push(o);
|
|
1371
|
+
const p = a.get(o);
|
|
1372
|
+
if (p?.dependencies)
|
|
1373
|
+
for (const d of p.dependencies)
|
|
1374
|
+
i(d);
|
|
1375
|
+
r.pop(), s.delete(o);
|
|
1376
|
+
}
|
|
1377
|
+
for (const o of e)
|
|
1378
|
+
i(o.number);
|
|
1379
|
+
return n;
|
|
1380
|
+
}
|
|
1381
|
+
async function vt(e, n = {}) {
|
|
1382
|
+
const {
|
|
1383
|
+
validateContent: t = !0,
|
|
1384
|
+
validateDependencies: s = !0,
|
|
1385
|
+
validateStatus: r = !0,
|
|
1386
|
+
strict: a = !1
|
|
1387
|
+
} = n, i = {
|
|
1388
|
+
valid: !0,
|
|
1389
|
+
errors: [],
|
|
1390
|
+
warnings: [],
|
|
1391
|
+
info: [],
|
|
1392
|
+
fixable: []
|
|
1393
|
+
}, o = await ft(e);
|
|
1394
|
+
if (i.errors.push(...o.errors), i.warnings.push(...o.warnings), o.errors.some((d) => d.code === "DIR_NOT_FOUND"))
|
|
1395
|
+
return i.valid = !1, i;
|
|
1396
|
+
const p = await gt(e);
|
|
1397
|
+
i.errors.push(...p.errors), i.warnings.push(...p.warnings), i.fixable.push(...p.fixable);
|
|
1398
|
+
try {
|
|
1399
|
+
const { loadPlan: d } = await Promise.resolve().then(() => Ke), l = await d(e, {
|
|
1400
|
+
parseStatus: r
|
|
1401
|
+
});
|
|
1402
|
+
if (t)
|
|
1403
|
+
for (const f of l.steps) {
|
|
1404
|
+
const m = await yt(f);
|
|
1405
|
+
i.errors.push(...m.errors), i.warnings.push(...m.warnings);
|
|
1406
|
+
}
|
|
1407
|
+
if (s) {
|
|
1408
|
+
const f = wt(l.steps);
|
|
1409
|
+
i.errors.push(...f.errors), i.warnings.push(...f.warnings);
|
|
1410
|
+
}
|
|
1411
|
+
i.info.push({
|
|
1412
|
+
code: "PLAN_LOADED",
|
|
1413
|
+
message: `Plan "${l.metadata.name}" loaded with ${l.steps.length} steps`
|
|
1414
|
+
});
|
|
1415
|
+
} catch (d) {
|
|
1416
|
+
i.errors.push({
|
|
1417
|
+
code: "LOAD_FAILED",
|
|
1418
|
+
message: `Failed to load plan: ${d.message}`
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
return a ? i.valid = i.errors.length === 0 && i.warnings.length === 0 : i.valid = i.errors.length === 0, i;
|
|
1422
|
+
}
|
|
1423
|
+
async function bt(e, n) {
|
|
1424
|
+
try {
|
|
1425
|
+
const t = e.path ? e.path : A(e, n), s = await vt(t);
|
|
1426
|
+
return C(
|
|
1427
|
+
{
|
|
1428
|
+
planPath: t,
|
|
1429
|
+
valid: s.valid,
|
|
1430
|
+
errors: s.errors || [],
|
|
1431
|
+
warnings: s.warnings || [],
|
|
1432
|
+
fixable: s.fixable || []
|
|
1433
|
+
},
|
|
1434
|
+
s.valid ? "Plan validation passed" : `Plan validation failed with ${s.errors.length} error(s)`
|
|
1435
|
+
);
|
|
1436
|
+
} catch (t) {
|
|
1437
|
+
return x(t);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
async function kt(e, n, t = {}) {
|
|
1441
|
+
const s = $t(e), r = {
|
|
1442
|
+
model: t.model || "claude-sonnet-4-5",
|
|
1443
|
+
messages: [
|
|
1444
|
+
{
|
|
1445
|
+
role: "system",
|
|
1446
|
+
content: _t
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
role: "user",
|
|
1450
|
+
content: s
|
|
1451
|
+
}
|
|
1452
|
+
],
|
|
1453
|
+
responseFormat: {
|
|
1454
|
+
type: "json_schema",
|
|
1455
|
+
json_schema: {
|
|
1456
|
+
name: "plan_generation",
|
|
1457
|
+
description: "Generate a detailed execution plan",
|
|
1458
|
+
schema: {
|
|
1459
|
+
type: "object",
|
|
1460
|
+
properties: {
|
|
1461
|
+
summary: { type: "string" },
|
|
1462
|
+
approach: { type: "string" },
|
|
1463
|
+
successCriteria: { type: "string" },
|
|
1464
|
+
steps: {
|
|
1465
|
+
type: "array",
|
|
1466
|
+
items: {
|
|
1467
|
+
type: "object",
|
|
1468
|
+
properties: {
|
|
1469
|
+
number: { type: "number" },
|
|
1470
|
+
title: { type: "string" },
|
|
1471
|
+
objective: { type: "string" },
|
|
1472
|
+
background: { type: "string" },
|
|
1473
|
+
tasks: {
|
|
1474
|
+
type: "array",
|
|
1475
|
+
items: {
|
|
1476
|
+
type: "object",
|
|
1477
|
+
properties: {
|
|
1478
|
+
id: { type: "string" },
|
|
1479
|
+
description: { type: "string" }
|
|
1480
|
+
},
|
|
1481
|
+
required: ["id", "description"]
|
|
1482
|
+
}
|
|
1483
|
+
},
|
|
1484
|
+
acceptanceCriteria: {
|
|
1485
|
+
type: "array",
|
|
1486
|
+
items: { type: "string" }
|
|
1487
|
+
},
|
|
1488
|
+
testing: { type: "string" },
|
|
1489
|
+
filesChanged: {
|
|
1490
|
+
type: "array",
|
|
1491
|
+
items: { type: "string" }
|
|
1492
|
+
},
|
|
1493
|
+
notes: { type: "string" }
|
|
1494
|
+
},
|
|
1495
|
+
required: ["number", "title", "objective", "background", "tasks", "acceptanceCriteria", "testing", "filesChanged", "notes"]
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
},
|
|
1499
|
+
required: ["summary", "approach", "successCriteria", "steps"]
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1503
|
+
addMessage: function(i) {
|
|
1504
|
+
this.messages.push(i);
|
|
1505
|
+
}
|
|
1506
|
+
}, a = await n.execute(r, t);
|
|
1507
|
+
return Pt(a.content);
|
|
1508
|
+
}
|
|
1509
|
+
const _t = `You are an expert project planner and software architect. Your role is to analyze project requirements and create detailed, actionable execution plans.
|
|
1510
|
+
|
|
1511
|
+
When creating a plan:
|
|
1512
|
+
1. Break down the work into clear, sequential steps
|
|
1513
|
+
2. Provide specific, actionable tasks for each step
|
|
1514
|
+
3. Define measurable acceptance criteria
|
|
1515
|
+
4. Consider dependencies and ordering
|
|
1516
|
+
5. Be concrete and specific, not vague or generic
|
|
1517
|
+
6. Think about testing and verification at each stage
|
|
1518
|
+
|
|
1519
|
+
CRITICAL: You must output ONLY valid JSON. Do not include any text before or after the JSON object. Ensure all strings are properly escaped.`;
|
|
1520
|
+
function $t(e) {
|
|
1521
|
+
let n = `Create a detailed execution plan for the following project:
|
|
1522
|
+
|
|
1523
|
+
**Project Name**: ${e.planName}
|
|
1524
|
+
|
|
1525
|
+
**Description**:
|
|
1526
|
+
${e.description}
|
|
1527
|
+
`;
|
|
1528
|
+
return e.elaborations && e.elaborations.length > 0 && (n += `
|
|
1529
|
+
**Additional Context**:
|
|
1530
|
+
`, e.elaborations.forEach((t, s) => {
|
|
1531
|
+
n += `
|
|
1532
|
+
${s + 1}. ${t}
|
|
1533
|
+
`;
|
|
1534
|
+
})), n += `
|
|
1535
|
+
**Requirements**:
|
|
1536
|
+
- Generate ${e.stepCount || 5} steps
|
|
1537
|
+
- Each step should be focused and achievable
|
|
1538
|
+
- Provide specific tasks, not generic placeholders
|
|
1539
|
+
- Include concrete acceptance criteria
|
|
1540
|
+
- Consider what files or components will be affected
|
|
1541
|
+
|
|
1542
|
+
Please provide:
|
|
1543
|
+
1. Executive Summary (2-3 paragraphs explaining what this plan accomplishes)
|
|
1544
|
+
2. Approach (how you'll tackle this work, key decisions)
|
|
1545
|
+
3. Success Criteria (how we'll know the project is complete)
|
|
1546
|
+
4. Detailed steps with:
|
|
1547
|
+
- Step title
|
|
1548
|
+
- Objective (what this step accomplishes)
|
|
1549
|
+
- Background (context needed)
|
|
1550
|
+
- Tasks (specific actions to take)
|
|
1551
|
+
- Acceptance criteria (how to verify completion)
|
|
1552
|
+
- Testing approach
|
|
1553
|
+
- Files that will be changed
|
|
1554
|
+
- Any notes or considerations
|
|
1555
|
+
|
|
1556
|
+
IMPORTANT: Output ONLY the JSON object below, with no markdown formatting, no code blocks, no additional text. Ensure all strings use proper JSON escaping for quotes and newlines.
|
|
1557
|
+
|
|
1558
|
+
JSON structure:
|
|
1559
|
+
{
|
|
1560
|
+
"summary": "executive summary text",
|
|
1561
|
+
"approach": "approach description",
|
|
1562
|
+
"successCriteria": "success criteria description",
|
|
1563
|
+
"steps": [
|
|
1564
|
+
{
|
|
1565
|
+
"number": 1,
|
|
1566
|
+
"title": "Step Title",
|
|
1567
|
+
"objective": "what this step accomplishes",
|
|
1568
|
+
"background": "context and prerequisites",
|
|
1569
|
+
"tasks": [
|
|
1570
|
+
{"id": "01.1", "description": "specific task"},
|
|
1571
|
+
{"id": "01.2", "description": "another task"}
|
|
1572
|
+
],
|
|
1573
|
+
"acceptanceCriteria": ["criterion 1", "criterion 2"],
|
|
1574
|
+
"testing": "how to verify this step",
|
|
1575
|
+
"filesChanged": ["file1.ts", "file2.ts"],
|
|
1576
|
+
"notes": "additional notes"
|
|
1577
|
+
}
|
|
1578
|
+
]
|
|
1579
|
+
}`, n;
|
|
1580
|
+
}
|
|
1581
|
+
function Pt(e, n) {
|
|
1582
|
+
try {
|
|
1583
|
+
let t = e.trim();
|
|
1584
|
+
const s = t.indexOf("```");
|
|
1585
|
+
if (s !== -1) {
|
|
1586
|
+
const o = t.indexOf("```", s + 3);
|
|
1587
|
+
o !== -1 && (t = t.substring(s + 3, o).trim(), t.startsWith("json") && (t = t.substring(4).trim()));
|
|
1588
|
+
}
|
|
1589
|
+
const r = t.indexOf("{"), a = t.lastIndexOf("}");
|
|
1590
|
+
r !== -1 && a !== -1 && a > r && (t = t.substring(r, a + 1));
|
|
1591
|
+
let i;
|
|
1592
|
+
try {
|
|
1593
|
+
i = JSON.parse(t);
|
|
1594
|
+
} catch {
|
|
1595
|
+
t = t.replace(/\n/g, "\\n").replace(/\t/g, "\\t").replace(/\r/g, "\\r"), i = JSON.parse(t);
|
|
1596
|
+
}
|
|
1597
|
+
if (!i.summary || !i.approach || !i.successCriteria || !i.steps)
|
|
1598
|
+
throw new Error("Invalid plan structure: missing required fields");
|
|
1599
|
+
return i;
|
|
1600
|
+
} catch (t) {
|
|
1601
|
+
throw new Error(`Failed to parse plan response: ${t instanceof Error ? t.message : "Unknown error"}`);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
async function xt(e) {
|
|
1605
|
+
const { name: n, apiKey: t } = e;
|
|
1606
|
+
try {
|
|
1607
|
+
switch (n.toLowerCase()) {
|
|
1608
|
+
case "anthropic":
|
|
1609
|
+
case "claude":
|
|
1610
|
+
return await Ct(t);
|
|
1611
|
+
case "openai":
|
|
1612
|
+
case "gpt":
|
|
1613
|
+
return await At(t);
|
|
1614
|
+
case "gemini":
|
|
1615
|
+
case "google":
|
|
1616
|
+
return await Et(t);
|
|
1617
|
+
default:
|
|
1618
|
+
throw new Error(`Unknown provider: ${n}`);
|
|
1619
|
+
}
|
|
1620
|
+
} catch (s) {
|
|
1621
|
+
throw s instanceof Error && s.message.includes("Cannot find package") ? new Error(
|
|
1622
|
+
`Provider '${n}' is not installed. Install it with:
|
|
1623
|
+
npm install @riotprompt/execution-${n}`
|
|
1624
|
+
) : s;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
async function Ct(e) {
|
|
1628
|
+
const { createAnthropicProvider: n } = await import("@riotprompt/execution-anthropic");
|
|
1629
|
+
return n();
|
|
1630
|
+
}
|
|
1631
|
+
async function At(e) {
|
|
1632
|
+
const { createOpenAIProvider: n } = await import("@riotprompt/execution-openai");
|
|
1633
|
+
return n();
|
|
1634
|
+
}
|
|
1635
|
+
async function Et(e) {
|
|
1636
|
+
const { createGeminiProvider: n } = await import("@riotprompt/execution-gemini");
|
|
1637
|
+
return n();
|
|
1638
|
+
}
|
|
1639
|
+
async function Dt(e, n) {
|
|
1640
|
+
try {
|
|
1641
|
+
const t = e.provider || "anthropic", s = await xt({
|
|
1642
|
+
name: t,
|
|
1643
|
+
apiKey: process.env[`${t.toUpperCase()}_API_KEY`]
|
|
1644
|
+
}), r = {
|
|
1645
|
+
planName: "Generated Plan",
|
|
1646
|
+
description: e.description,
|
|
1647
|
+
stepCount: e.steps
|
|
1648
|
+
}, a = await kt(r, s, {
|
|
1649
|
+
model: e.model
|
|
1650
|
+
});
|
|
1651
|
+
return C(
|
|
1652
|
+
{
|
|
1653
|
+
summary: a.summary,
|
|
1654
|
+
approach: a.approach,
|
|
1655
|
+
stepsGenerated: a.steps.length,
|
|
1656
|
+
steps: a.steps.map((i) => ({
|
|
1657
|
+
number: i.number,
|
|
1658
|
+
title: i.title,
|
|
1659
|
+
objective: i.objective
|
|
1660
|
+
}))
|
|
1661
|
+
},
|
|
1662
|
+
`Plan generated successfully with ${a.steps.length} steps`
|
|
1663
|
+
);
|
|
1664
|
+
} catch (t) {
|
|
1665
|
+
return x(t);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
const X = c.object({
|
|
1669
|
+
path: c.string().optional().describe("Path to plan directory"),
|
|
1670
|
+
name: c.string().describe("Checkpoint name (kebab-case)"),
|
|
1671
|
+
message: c.string().describe("Description of why checkpoint created"),
|
|
1672
|
+
capturePrompt: c.boolean().optional().default(!0).describe("Capture conversation context")
|
|
1673
|
+
}), Z = c.object({
|
|
1674
|
+
path: c.string().optional().describe("Path to plan directory")
|
|
1675
|
+
}), ee = c.object({
|
|
1676
|
+
path: c.string().optional().describe("Path to plan directory"),
|
|
1677
|
+
checkpoint: c.string().describe("Checkpoint name")
|
|
1678
|
+
}), te = c.object({
|
|
1679
|
+
path: c.string().optional().describe("Path to plan directory"),
|
|
1680
|
+
checkpoint: c.string().describe("Checkpoint name")
|
|
1681
|
+
}), ne = c.object({
|
|
1682
|
+
path: c.string().optional().describe("Path to plan directory"),
|
|
1683
|
+
since: c.string().optional().describe("Show events since this ISO timestamp"),
|
|
1684
|
+
eventType: c.string().optional().describe("Filter by event type"),
|
|
1685
|
+
limit: c.number().optional().describe("Maximum number of events to show")
|
|
1686
|
+
});
|
|
1687
|
+
async function _(e, n) {
|
|
1688
|
+
const t = u(e, ".history");
|
|
1689
|
+
await $(t, { recursive: !0 });
|
|
1690
|
+
const s = u(t, "timeline.jsonl"), r = JSON.stringify(n) + `
|
|
1691
|
+
`;
|
|
1692
|
+
await _e(s, r);
|
|
1693
|
+
}
|
|
1694
|
+
async function W(e) {
|
|
1695
|
+
const n = u(e, ".history", "timeline.jsonl");
|
|
1696
|
+
try {
|
|
1697
|
+
return (await y(n, "utf-8")).split(`
|
|
1698
|
+
`).filter((s) => s.trim()).map((s) => JSON.parse(s));
|
|
1699
|
+
} catch (t) {
|
|
1700
|
+
if (t.code === "ENOENT")
|
|
1701
|
+
return [];
|
|
1702
|
+
throw t;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
async function It(e) {
|
|
1706
|
+
const n = {
|
|
1707
|
+
timestamp: S(),
|
|
1708
|
+
stage: "unknown",
|
|
1709
|
+
idea: void 0,
|
|
1710
|
+
shaping: void 0,
|
|
1711
|
+
lifecycle: void 0
|
|
1712
|
+
};
|
|
1713
|
+
try {
|
|
1714
|
+
const t = await y(u(e, "IDEA.md"), "utf-8");
|
|
1715
|
+
n.idea = {
|
|
1716
|
+
content: t,
|
|
1717
|
+
exists: !0
|
|
1718
|
+
};
|
|
1719
|
+
} catch {
|
|
1720
|
+
n.idea = { exists: !1 };
|
|
1721
|
+
}
|
|
1722
|
+
try {
|
|
1723
|
+
const t = await y(u(e, "SHAPING.md"), "utf-8");
|
|
1724
|
+
n.shaping = {
|
|
1725
|
+
content: t,
|
|
1726
|
+
exists: !0
|
|
1727
|
+
};
|
|
1728
|
+
} catch {
|
|
1729
|
+
n.shaping = { exists: !1 };
|
|
1730
|
+
}
|
|
1731
|
+
try {
|
|
1732
|
+
const t = await y(u(e, "LIFECYCLE.md"), "utf-8");
|
|
1733
|
+
n.lifecycle = {
|
|
1734
|
+
content: t,
|
|
1735
|
+
exists: !0
|
|
1736
|
+
};
|
|
1737
|
+
const s = t.match(/\*\*Stage\*\*:\s*`(\w+)`/);
|
|
1738
|
+
s && (n.stage = s[1]);
|
|
1739
|
+
} catch {
|
|
1740
|
+
n.lifecycle = { exists: !1 };
|
|
1741
|
+
}
|
|
1742
|
+
return n;
|
|
1743
|
+
}
|
|
1744
|
+
async function Nt(e) {
|
|
1745
|
+
const n = await W(e);
|
|
1746
|
+
let t = -1;
|
|
1747
|
+
for (let s = n.length - 1; s >= 0; s--)
|
|
1748
|
+
if (n[s].type === "checkpoint_created") {
|
|
1749
|
+
t = s;
|
|
1750
|
+
break;
|
|
1751
|
+
}
|
|
1752
|
+
return t === -1 ? n.length : n.length - t - 1;
|
|
1753
|
+
}
|
|
1754
|
+
async function se(e) {
|
|
1755
|
+
try {
|
|
1756
|
+
return (await b(e)).filter((t) => t.endsWith(".md"));
|
|
1757
|
+
} catch {
|
|
1758
|
+
return [];
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
async function Tt(e, n) {
|
|
1762
|
+
return (await W(e)).slice(-10).map((r) => `- ${new Date(r.timestamp).toLocaleString()}: ${r.type} - ${JSON.stringify(r.data)}`).join(`
|
|
1763
|
+
`);
|
|
1764
|
+
}
|
|
1765
|
+
function ae(e) {
|
|
1766
|
+
let n = "";
|
|
1767
|
+
return e.stage && (n += `**Current Stage**: ${e.stage}
|
|
1768
|
+
|
|
1769
|
+
`), e.idea?.exists && (n += `### IDEA.md
|
|
1770
|
+
|
|
1771
|
+
${e.idea.content}
|
|
1772
|
+
|
|
1773
|
+
`), e.shaping?.exists && (n += `### SHAPING.md
|
|
1774
|
+
|
|
1775
|
+
${e.shaping.content}
|
|
1776
|
+
|
|
1777
|
+
`), n;
|
|
1778
|
+
}
|
|
1779
|
+
async function Ft(e, n, t, s) {
|
|
1780
|
+
const r = u(e, ".history", "prompts");
|
|
1781
|
+
await $(r, { recursive: !0 });
|
|
1782
|
+
const a = `# Checkpoint: ${n}
|
|
1783
|
+
|
|
1784
|
+
**Timestamp**: ${t.timestamp}
|
|
1785
|
+
**Stage**: ${t.stage || "unknown"}
|
|
1786
|
+
**Message**: ${s}
|
|
1787
|
+
|
|
1788
|
+
## Current State
|
|
1789
|
+
|
|
1790
|
+
${ae(t)}
|
|
1791
|
+
|
|
1792
|
+
## Files at This Point
|
|
1793
|
+
|
|
1794
|
+
${(await se(e)).map((i) => `- ${i}`).join(`
|
|
1795
|
+
`)}
|
|
1796
|
+
|
|
1797
|
+
## Recent Timeline
|
|
1798
|
+
|
|
1799
|
+
${await Tt(e)}
|
|
1800
|
+
|
|
1801
|
+
---
|
|
1802
|
+
|
|
1803
|
+
This checkpoint captures the state of the plan at this moment in time.
|
|
1804
|
+
You can restore to this checkpoint using: \`riotplan_checkpoint_restore({ checkpoint: "${n}" })\`
|
|
1805
|
+
`;
|
|
1806
|
+
await w(
|
|
1807
|
+
u(r, `${n}.md`),
|
|
1808
|
+
a
|
|
1809
|
+
);
|
|
1810
|
+
}
|
|
1811
|
+
async function Ot(e) {
|
|
1812
|
+
const n = e.path || process.cwd(), { name: t, message: s, capturePrompt: r } = e, a = u(n, ".history", "checkpoints");
|
|
1813
|
+
await $(a, { recursive: !0 });
|
|
1814
|
+
const i = await It(n), o = {
|
|
1815
|
+
name: t,
|
|
1816
|
+
timestamp: i.timestamp,
|
|
1817
|
+
message: s,
|
|
1818
|
+
stage: i.stage,
|
|
1819
|
+
snapshot: {
|
|
1820
|
+
timestamp: i.timestamp,
|
|
1821
|
+
idea: i.idea,
|
|
1822
|
+
shaping: i.shaping,
|
|
1823
|
+
lifecycle: i.lifecycle
|
|
1824
|
+
},
|
|
1825
|
+
context: {
|
|
1826
|
+
filesChanged: await se(n),
|
|
1827
|
+
eventsSinceLastCheckpoint: await Nt(n)
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
await w(
|
|
1831
|
+
u(a, `${t}.json`),
|
|
1832
|
+
JSON.stringify(o, null, 2)
|
|
1833
|
+
), r && await Ft(n, t, i, s);
|
|
1834
|
+
const p = {
|
|
1835
|
+
timestamp: i.timestamp,
|
|
1836
|
+
type: "checkpoint_created",
|
|
1837
|
+
data: {
|
|
1838
|
+
name: t,
|
|
1839
|
+
message: s,
|
|
1840
|
+
snapshotPath: `.history/checkpoints/${t}.json`,
|
|
1841
|
+
promptPath: `.history/prompts/${t}.md`
|
|
1842
|
+
}
|
|
1843
|
+
};
|
|
1844
|
+
return await _(n, p), `β
Checkpoint created: ${t}
|
|
1845
|
+
|
|
1846
|
+
Location: ${n}/.history/checkpoints/${t}.json
|
|
1847
|
+
Prompt: ${n}/.history/prompts/${t}.md
|
|
1848
|
+
|
|
1849
|
+
You can restore this checkpoint later with:
|
|
1850
|
+
riotplan_checkpoint_restore({ checkpoint: "${t}" })`;
|
|
1851
|
+
}
|
|
1852
|
+
async function jt(e) {
|
|
1853
|
+
const n = e.path || process.cwd(), t = u(n, ".history", "checkpoints");
|
|
1854
|
+
try {
|
|
1855
|
+
const r = (await b(t)).filter((i) => i.endsWith(".json"));
|
|
1856
|
+
if (r.length === 0)
|
|
1857
|
+
return "No checkpoints found.";
|
|
1858
|
+
let a = `Found ${r.length} checkpoint(s):
|
|
1859
|
+
|
|
1860
|
+
`;
|
|
1861
|
+
for (const i of r) {
|
|
1862
|
+
const o = await y(u(t, i), "utf-8"), p = JSON.parse(o), d = new Date(p.timestamp).toLocaleString();
|
|
1863
|
+
a += `- **${p.name}** (${d})
|
|
1864
|
+
`, a += ` Stage: ${p.stage}
|
|
1865
|
+
`, a += ` Message: ${p.message}
|
|
1866
|
+
`, a += ` Events since last: ${p.context.eventsSinceLastCheckpoint}
|
|
1867
|
+
|
|
1868
|
+
`;
|
|
1869
|
+
}
|
|
1870
|
+
return a;
|
|
1871
|
+
} catch (s) {
|
|
1872
|
+
if (s.code === "ENOENT")
|
|
1873
|
+
return "No checkpoints found.";
|
|
1874
|
+
throw s;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
async function Rt(e) {
|
|
1878
|
+
const n = e.path || process.cwd(), t = u(n, ".history", "checkpoints", `${e.checkpoint}.json`), s = await y(t, "utf-8"), r = JSON.parse(s), a = new Date(r.timestamp).toLocaleString();
|
|
1879
|
+
let i = `# Checkpoint: ${r.name}
|
|
1880
|
+
|
|
1881
|
+
`;
|
|
1882
|
+
return i += `**Created**: ${a}
|
|
1883
|
+
`, i += `**Stage**: ${r.stage}
|
|
1884
|
+
`, i += `**Message**: ${r.message}
|
|
1885
|
+
|
|
1886
|
+
`, i += `## Context
|
|
1887
|
+
|
|
1888
|
+
`, i += `- Files changed: ${r.context.filesChanged.join(", ")}
|
|
1889
|
+
`, i += `- Events since last checkpoint: ${r.context.eventsSinceLastCheckpoint}
|
|
1890
|
+
|
|
1891
|
+
`, i += `## Snapshot
|
|
1892
|
+
|
|
1893
|
+
`, i += `${ae(r.snapshot)}
|
|
1894
|
+
`, i += `
|
|
1895
|
+
---
|
|
1896
|
+
|
|
1897
|
+
`, i += `View full prompt context: ${n}/.history/prompts/${e.checkpoint}.md
|
|
1898
|
+
`, i += `Restore: riotplan_checkpoint_restore({ checkpoint: "${e.checkpoint}" })`, i;
|
|
1899
|
+
}
|
|
1900
|
+
async function Lt(e) {
|
|
1901
|
+
const n = e.path || process.cwd(), t = u(n, ".history", "checkpoints", `${e.checkpoint}.json`), s = await y(t, "utf-8"), r = JSON.parse(s);
|
|
1902
|
+
r.snapshot.idea?.exists && r.snapshot.idea.content && await w(u(n, "IDEA.md"), r.snapshot.idea.content), r.snapshot.shaping?.exists && r.snapshot.shaping.content && await w(u(n, "SHAPING.md"), r.snapshot.shaping.content), r.snapshot.lifecycle?.exists && r.snapshot.lifecycle.content && await w(u(n, "LIFECYCLE.md"), r.snapshot.lifecycle.content);
|
|
1903
|
+
const a = {
|
|
1904
|
+
timestamp: S(),
|
|
1905
|
+
type: "checkpoint_restored",
|
|
1906
|
+
data: {
|
|
1907
|
+
checkpoint: e.checkpoint,
|
|
1908
|
+
restoredFrom: r.timestamp
|
|
1909
|
+
}
|
|
1910
|
+
};
|
|
1911
|
+
return await _(n, a), `β
Restored to checkpoint: ${e.checkpoint}
|
|
1912
|
+
|
|
1913
|
+
Restored from: ${r.timestamp}
|
|
1914
|
+
Stage: ${r.stage}
|
|
1915
|
+
|
|
1916
|
+
Files restored:
|
|
1917
|
+
${r.context.filesChanged.map((i) => ` - ${i}`).join(`
|
|
1918
|
+
`)}`;
|
|
1919
|
+
}
|
|
1920
|
+
async function Mt(e) {
|
|
1921
|
+
const n = e.path || process.cwd();
|
|
1922
|
+
let t = await W(n);
|
|
1923
|
+
if (t.length === 0)
|
|
1924
|
+
return "No history events found.";
|
|
1925
|
+
if (e.since) {
|
|
1926
|
+
const r = new Date(e.since).getTime();
|
|
1927
|
+
t = t.filter((a) => new Date(a.timestamp).getTime() >= r);
|
|
1928
|
+
}
|
|
1929
|
+
e.eventType && (t = t.filter((r) => r.type === e.eventType)), e.limit && (t = t.slice(-e.limit));
|
|
1930
|
+
let s = `# Ideation History
|
|
1931
|
+
|
|
1932
|
+
`;
|
|
1933
|
+
s += `Total events: ${t.length}
|
|
1934
|
+
|
|
1935
|
+
`;
|
|
1936
|
+
for (const r of t) {
|
|
1937
|
+
const a = new Date(r.timestamp).toLocaleString();
|
|
1938
|
+
s += `## ${a} - ${r.type}
|
|
1939
|
+
|
|
1940
|
+
`, s += `\`\`\`json
|
|
1941
|
+
${JSON.stringify(r.data, null, 2)}
|
|
1942
|
+
\`\`\`
|
|
1943
|
+
|
|
1944
|
+
`;
|
|
1945
|
+
}
|
|
1946
|
+
return s;
|
|
1947
|
+
}
|
|
1948
|
+
async function qt(e, n) {
|
|
1949
|
+
try {
|
|
1950
|
+
const t = X.parse(e);
|
|
1951
|
+
return { success: !0, data: { message: await Ot(t) } };
|
|
1952
|
+
} catch (t) {
|
|
1953
|
+
return { success: !1, error: t.message };
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
async function Ut(e, n) {
|
|
1957
|
+
try {
|
|
1958
|
+
const t = Z.parse(e);
|
|
1959
|
+
return { success: !0, data: { message: await jt(t) } };
|
|
1960
|
+
} catch (t) {
|
|
1961
|
+
return { success: !1, error: t.message };
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
async function Gt(e, n) {
|
|
1965
|
+
try {
|
|
1966
|
+
const t = ee.parse(e);
|
|
1967
|
+
return { success: !0, data: { message: await Rt(t) } };
|
|
1968
|
+
} catch (t) {
|
|
1969
|
+
return { success: !1, error: t.message };
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
async function Wt(e, n) {
|
|
1973
|
+
try {
|
|
1974
|
+
const t = te.parse(e);
|
|
1975
|
+
return { success: !0, data: { message: await Lt(t) } };
|
|
1976
|
+
} catch (t) {
|
|
1977
|
+
return { success: !1, error: t.message };
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
async function Bt(e, n) {
|
|
1981
|
+
try {
|
|
1982
|
+
const t = ne.parse(e);
|
|
1983
|
+
return { success: !0, data: { message: await Mt(t) } };
|
|
1984
|
+
} catch (t) {
|
|
1985
|
+
return { success: !1, error: t.message };
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
X.shape;
|
|
1989
|
+
Z.shape;
|
|
1990
|
+
ee.shape;
|
|
1991
|
+
te.shape;
|
|
1992
|
+
ne.shape;
|
|
1993
|
+
const re = c.object({
|
|
1994
|
+
code: c.string().describe("Plan identifier (kebab-case)"),
|
|
1995
|
+
description: c.string().describe("Initial idea description"),
|
|
1996
|
+
directory: c.string().optional().describe("Parent directory for the idea")
|
|
1997
|
+
}), ie = c.object({
|
|
1998
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
1999
|
+
note: c.string().describe("Note to add to the idea")
|
|
2000
|
+
}), oe = c.object({
|
|
2001
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
2002
|
+
constraint: c.string().describe("Constraint to add")
|
|
2003
|
+
}), ce = c.object({
|
|
2004
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
2005
|
+
question: c.string().describe("Question to add")
|
|
2006
|
+
}), pe = c.object({
|
|
2007
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
2008
|
+
evidencePath: c.string().optional().describe("Path to evidence file, or 'inline' for pasted text"),
|
|
2009
|
+
description: c.string().describe("Description of the evidence and its relevance"),
|
|
2010
|
+
content: c.string().optional().describe("Inline content if evidencePath is 'inline' (for pasted text/transcripts)"),
|
|
2011
|
+
source: c.string().optional().describe("Where evidence came from (e.g., 'web search', 'user paste', 'file analysis')"),
|
|
2012
|
+
gatheringMethod: c.enum(["manual", "model-assisted"]).optional().describe("How evidence was gathered"),
|
|
2013
|
+
relevanceScore: c.number().min(0).max(1).optional().describe("Relevance score (0-1) from model if model-assisted"),
|
|
2014
|
+
summary: c.string().optional().describe("Model-generated summary of the evidence")
|
|
2015
|
+
}), de = c.object({
|
|
2016
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
2017
|
+
content: c.string().describe("Raw narrative content (thoughts, observations, context)"),
|
|
2018
|
+
source: c.enum(["typing", "voice", "paste", "import"]).optional().describe("Source of the narrative"),
|
|
2019
|
+
context: c.string().optional().describe("Context about what prompted this narrative"),
|
|
2020
|
+
speaker: c.string().optional().describe("Who is speaking (user, assistant, or name)")
|
|
2021
|
+
}), le = c.object({
|
|
2022
|
+
path: c.string().optional().describe("Path to idea directory"),
|
|
2023
|
+
reason: c.string().describe("Reason for killing the idea")
|
|
2024
|
+
});
|
|
2025
|
+
async function Ht(e) {
|
|
2026
|
+
const { code: n, description: t, directory: s } = e, r = s || process.cwd(), a = u(r, n);
|
|
2027
|
+
await $(a, { recursive: !0 });
|
|
2028
|
+
const i = `# Idea: ${n}
|
|
2029
|
+
|
|
2030
|
+
## Core Concept
|
|
2031
|
+
|
|
2032
|
+
${t}
|
|
2033
|
+
|
|
2034
|
+
## Why This Matters
|
|
2035
|
+
|
|
2036
|
+
_Why pursue this idea?_
|
|
2037
|
+
|
|
2038
|
+
## Initial Thoughts
|
|
2039
|
+
|
|
2040
|
+
- _Add your thoughts..._
|
|
2041
|
+
|
|
2042
|
+
## Constraints
|
|
2043
|
+
|
|
2044
|
+
- _Add constraints..._
|
|
2045
|
+
|
|
2046
|
+
## Questions
|
|
2047
|
+
|
|
2048
|
+
- _Add questions..._
|
|
2049
|
+
|
|
2050
|
+
## Evidence
|
|
2051
|
+
|
|
2052
|
+
_Attach relevant documents, images, or files_
|
|
2053
|
+
|
|
2054
|
+
## Related Ideas
|
|
2055
|
+
|
|
2056
|
+
- _Link to related ideas..._
|
|
2057
|
+
|
|
2058
|
+
## Status
|
|
2059
|
+
|
|
2060
|
+
**Stage**: idea
|
|
2061
|
+
**Created**: ${S()}
|
|
2062
|
+
**Next**: Decide if worth shaping
|
|
2063
|
+
|
|
2064
|
+
## Notes
|
|
2065
|
+
|
|
2066
|
+
_Add notes as you think about this..._
|
|
2067
|
+
`;
|
|
2068
|
+
await w(u(a, "IDEA.md"), i, "utf-8");
|
|
2069
|
+
const o = `# Lifecycle
|
|
2070
|
+
|
|
2071
|
+
## Current Stage
|
|
2072
|
+
|
|
2073
|
+
**Stage**: \`idea\`
|
|
2074
|
+
**Since**: ${S()}
|
|
2075
|
+
|
|
2076
|
+
## State History
|
|
2077
|
+
|
|
2078
|
+
| From | To | When | Reason |
|
|
2079
|
+
|------|-----|------|--------|
|
|
2080
|
+
| - | idea | ${S()} | Initial creation |
|
|
2081
|
+
|
|
2082
|
+
## Stage-Specific Data
|
|
2083
|
+
|
|
2084
|
+
### Idea
|
|
2085
|
+
- Core concept: ${t}
|
|
2086
|
+
- Notes: []
|
|
2087
|
+
- Constraints: []
|
|
2088
|
+
- Questions: []
|
|
2089
|
+
- Evidence: []
|
|
2090
|
+
`;
|
|
2091
|
+
return await w(u(a, "LIFECYCLE.md"), o, "utf-8"), await _(a, {
|
|
2092
|
+
timestamp: S(),
|
|
2093
|
+
type: "idea_created",
|
|
2094
|
+
data: { code: n, description: t }
|
|
2095
|
+
}), `β
Idea created: ${a}
|
|
2096
|
+
|
|
2097
|
+
Next steps:
|
|
2098
|
+
- Add notes: riotplan_idea_add_note
|
|
2099
|
+
- Add constraints: riotplan_idea_add_constraint
|
|
2100
|
+
- Add questions: riotplan_idea_add_question
|
|
2101
|
+
- Add evidence: riotplan_idea_add_evidence
|
|
2102
|
+
- When ready: riotplan_transition to 'shaping'`;
|
|
2103
|
+
}
|
|
2104
|
+
async function Jt(e) {
|
|
2105
|
+
const n = e.path || process.cwd(), t = u(n, "IDEA.md");
|
|
2106
|
+
let s = await y(t, "utf-8");
|
|
2107
|
+
const r = "## Initial Thoughts", a = s.indexOf(r);
|
|
2108
|
+
if (a === -1)
|
|
2109
|
+
throw new Error("Could not find Initial Thoughts section in IDEA.md");
|
|
2110
|
+
const i = s.indexOf(`
|
|
2111
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `- ${e.note}
|
|
2112
|
+
`;
|
|
2113
|
+
return s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2114
|
+
timestamp: S(),
|
|
2115
|
+
type: "note_added",
|
|
2116
|
+
data: { note: e.note }
|
|
2117
|
+
}), "β
Note added to idea";
|
|
2118
|
+
}
|
|
2119
|
+
async function Yt(e) {
|
|
2120
|
+
const n = e.path || process.cwd(), t = u(n, "IDEA.md");
|
|
2121
|
+
let s = await y(t, "utf-8");
|
|
2122
|
+
const r = "## Constraints", a = s.indexOf(r);
|
|
2123
|
+
if (a === -1)
|
|
2124
|
+
throw new Error("Could not find Constraints section in IDEA.md");
|
|
2125
|
+
const i = s.indexOf(`
|
|
2126
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `- ${e.constraint}
|
|
2127
|
+
`;
|
|
2128
|
+
return s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2129
|
+
timestamp: S(),
|
|
2130
|
+
type: "constraint_added",
|
|
2131
|
+
data: { constraint: e.constraint }
|
|
2132
|
+
}), "β
Constraint added to idea";
|
|
2133
|
+
}
|
|
2134
|
+
async function Kt(e) {
|
|
2135
|
+
const n = e.path || process.cwd(), t = u(n, "IDEA.md");
|
|
2136
|
+
let s = await y(t, "utf-8");
|
|
2137
|
+
const r = "## Questions", a = s.indexOf(r);
|
|
2138
|
+
if (a === -1)
|
|
2139
|
+
throw new Error("Could not find Questions section in IDEA.md");
|
|
2140
|
+
const i = s.indexOf(`
|
|
2141
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `- ${e.question}
|
|
2142
|
+
`;
|
|
2143
|
+
return s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2144
|
+
timestamp: S(),
|
|
2145
|
+
type: "question_added",
|
|
2146
|
+
data: { question: e.question }
|
|
2147
|
+
}), "β
Question added to idea";
|
|
2148
|
+
}
|
|
2149
|
+
async function Vt(e) {
|
|
2150
|
+
const n = e.path || process.cwd(), t = u(n, "IDEA.md");
|
|
2151
|
+
let s = e.evidencePath, r;
|
|
2152
|
+
if (s === "inline" || e.content) {
|
|
2153
|
+
if (!e.content)
|
|
2154
|
+
throw new Error("Content is required when evidencePath is 'inline'");
|
|
2155
|
+
const f = u(n, "evidence");
|
|
2156
|
+
await $(f, { recursive: !0 }), r = `evidence-${Date.now()}`;
|
|
2157
|
+
const m = u(f, `${r}.md`), g = `# Evidence: ${e.description}
|
|
2158
|
+
|
|
2159
|
+
**Source**: ${e.source || "user paste"}
|
|
2160
|
+
**Added**: ${S()}
|
|
2161
|
+
` + (e.gatheringMethod ? `**Gathering Method**: ${e.gatheringMethod}
|
|
2162
|
+
` : "") + (e.relevanceScore !== void 0 ? `**Relevance Score**: ${e.relevanceScore}
|
|
2163
|
+
` : "") + `
|
|
2164
|
+
---
|
|
2165
|
+
|
|
2166
|
+
${e.content}`;
|
|
2167
|
+
await w(m, g), s = `evidence/${r}.md`;
|
|
2168
|
+
}
|
|
2169
|
+
let a = await y(t, "utf-8");
|
|
2170
|
+
const i = "## Evidence", o = a.indexOf(i);
|
|
2171
|
+
if (o === -1)
|
|
2172
|
+
throw new Error("Could not find Evidence section in IDEA.md");
|
|
2173
|
+
const p = a.indexOf(`
|
|
2174
|
+
## `, o + i.length), d = p === -1 ? a.length : p, l = `- [${e.description}](${s})${e.source ? ` (${e.source})` : ""}
|
|
2175
|
+
`;
|
|
2176
|
+
return a = a.slice(0, d) + l + a.slice(d), await w(t, a, "utf-8"), await _(n, {
|
|
2177
|
+
timestamp: S(),
|
|
2178
|
+
type: "evidence_added",
|
|
2179
|
+
data: {
|
|
2180
|
+
evidencePath: s,
|
|
2181
|
+
description: e.description,
|
|
2182
|
+
source: e.source,
|
|
2183
|
+
gatheringMethod: e.gatheringMethod,
|
|
2184
|
+
relevanceScore: e.relevanceScore,
|
|
2185
|
+
summary: e.summary,
|
|
2186
|
+
evidenceId: r
|
|
2187
|
+
}
|
|
2188
|
+
}), `β
Evidence added: ${e.description}${r ? ` (ID: ${r})` : ""}`;
|
|
2189
|
+
}
|
|
2190
|
+
async function Qt(e) {
|
|
2191
|
+
const n = e.path || process.cwd(), t = S();
|
|
2192
|
+
await _(n, {
|
|
2193
|
+
timestamp: t,
|
|
2194
|
+
type: "narrative_chunk",
|
|
2195
|
+
data: {
|
|
2196
|
+
content: e.content,
|
|
2197
|
+
source: e.source,
|
|
2198
|
+
context: e.context,
|
|
2199
|
+
speaker: e.speaker || "user"
|
|
2200
|
+
}
|
|
2201
|
+
});
|
|
2202
|
+
const s = u(n, ".history"), r = u(s, "prompts");
|
|
2203
|
+
await $(r, { recursive: !0 });
|
|
2204
|
+
let a = [];
|
|
2205
|
+
try {
|
|
2206
|
+
a = await b(r);
|
|
2207
|
+
} catch {
|
|
2208
|
+
a = [];
|
|
2209
|
+
}
|
|
2210
|
+
const i = a.filter((m) => /^\d{3}-.*\.md$/.test(m)).sort(), o = i.length > 0 ? parseInt(i[i.length - 1].substring(0, 3)) + 1 : 1, p = e.context ? e.context.toLowerCase().replace(/[^a-z0-9]+/g, "-").substring(0, 50) : "narrative", d = `${String(o).padStart(3, "0")}-${p}.md`, l = u(r, d), f = `# Narrative: ${e.context || "User Input"}
|
|
2211
|
+
|
|
2212
|
+
**Date**: ${t}
|
|
2213
|
+
**Source**: ${e.source || "unknown"}
|
|
2214
|
+
**Speaker**: ${e.speaker || "user"}
|
|
2215
|
+
|
|
2216
|
+
---
|
|
2217
|
+
|
|
2218
|
+
${e.content}
|
|
2219
|
+
`;
|
|
2220
|
+
return await w(l, f, "utf-8"), `β
Narrative saved to timeline and ${d} (${e.content.length} characters)`;
|
|
2221
|
+
}
|
|
2222
|
+
async function zt(e) {
|
|
2223
|
+
const n = e.path || process.cwd(), t = u(n, "IDEA.md");
|
|
2224
|
+
let s = await y(t, "utf-8");
|
|
2225
|
+
const r = "## Status", a = s.indexOf(r);
|
|
2226
|
+
if (a !== -1) {
|
|
2227
|
+
const i = s.indexOf(`
|
|
2228
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `
|
|
2229
|
+
**Killed**: ${S()}
|
|
2230
|
+
**Reason**: ${e.reason}
|
|
2231
|
+
`;
|
|
2232
|
+
s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8");
|
|
2233
|
+
}
|
|
2234
|
+
return await _(n, {
|
|
2235
|
+
timestamp: S(),
|
|
2236
|
+
type: "idea_killed",
|
|
2237
|
+
data: { reason: e.reason }
|
|
2238
|
+
}), `β
Idea killed: ${e.reason}`;
|
|
2239
|
+
}
|
|
2240
|
+
async function Xt(e, n) {
|
|
2241
|
+
try {
|
|
2242
|
+
const t = re.parse(e);
|
|
2243
|
+
return { success: !0, data: { message: await Ht(t) } };
|
|
2244
|
+
} catch (t) {
|
|
2245
|
+
return { success: !1, error: t.message };
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
async function Zt(e, n) {
|
|
2249
|
+
try {
|
|
2250
|
+
const t = ie.parse(e);
|
|
2251
|
+
return { success: !0, data: { message: await Jt(t) } };
|
|
2252
|
+
} catch (t) {
|
|
2253
|
+
return { success: !1, error: t.message };
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
async function en(e, n) {
|
|
2257
|
+
try {
|
|
2258
|
+
const t = oe.parse(e);
|
|
2259
|
+
return { success: !0, data: { message: await Yt(t) } };
|
|
2260
|
+
} catch (t) {
|
|
2261
|
+
return { success: !1, error: t.message };
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
async function tn(e, n) {
|
|
2265
|
+
try {
|
|
2266
|
+
const t = ce.parse(e);
|
|
2267
|
+
return { success: !0, data: { message: await Kt(t) } };
|
|
2268
|
+
} catch (t) {
|
|
2269
|
+
return { success: !1, error: t.message };
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
async function nn(e, n) {
|
|
2273
|
+
try {
|
|
2274
|
+
const t = pe.parse(e);
|
|
2275
|
+
return { success: !0, data: { message: await Vt(t) } };
|
|
2276
|
+
} catch (t) {
|
|
2277
|
+
return { success: !1, error: t.message };
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
async function sn(e, n) {
|
|
2281
|
+
try {
|
|
2282
|
+
const t = de.parse(e);
|
|
2283
|
+
return { success: !0, data: { message: await Qt(t) } };
|
|
2284
|
+
} catch (t) {
|
|
2285
|
+
return { success: !1, error: t.message };
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
async function an(e, n) {
|
|
2289
|
+
try {
|
|
2290
|
+
const t = le.parse(e);
|
|
2291
|
+
return { success: !0, data: { message: await zt(t) } };
|
|
2292
|
+
} catch (t) {
|
|
2293
|
+
return { success: !1, error: t.message };
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
re.shape;
|
|
2297
|
+
ie.shape;
|
|
2298
|
+
oe.shape;
|
|
2299
|
+
ce.shape;
|
|
2300
|
+
pe.shape;
|
|
2301
|
+
de.shape;
|
|
2302
|
+
le.shape;
|
|
2303
|
+
const ue = c.object({
|
|
2304
|
+
path: c.string().optional().describe("Path to idea directory")
|
|
2305
|
+
}), he = c.object({
|
|
2306
|
+
path: c.string().optional().describe("Path to shaping directory"),
|
|
2307
|
+
name: c.string().describe("Name of the approach"),
|
|
2308
|
+
description: c.string().describe("Description of the approach"),
|
|
2309
|
+
tradeoffs: c.array(c.string()).optional().describe("List of tradeoffs (pros/cons)"),
|
|
2310
|
+
assumptions: c.array(c.string()).optional().describe("Key assumptions")
|
|
2311
|
+
}), me = c.object({
|
|
2312
|
+
path: c.string().optional().describe("Path to shaping directory"),
|
|
2313
|
+
feedback: c.string().describe("Feedback about the current shaping")
|
|
2314
|
+
}), fe = c.object({
|
|
2315
|
+
path: c.string().optional().describe("Path to shaping directory"),
|
|
2316
|
+
evidencePath: c.string().describe("Path to evidence file"),
|
|
2317
|
+
description: c.string().optional().describe("Description of the evidence"),
|
|
2318
|
+
relatedTo: c.string().optional().describe("Which approach this evidence relates to")
|
|
2319
|
+
}), ge = c.object({
|
|
2320
|
+
path: c.string().optional().describe("Path to shaping directory")
|
|
2321
|
+
}), ye = c.object({
|
|
2322
|
+
path: c.string().optional().describe("Path to shaping directory"),
|
|
2323
|
+
approach: c.string().describe("Name of the selected approach"),
|
|
2324
|
+
reason: c.string().describe("Reason for selecting this approach")
|
|
2325
|
+
});
|
|
2326
|
+
async function rn(e) {
|
|
2327
|
+
const n = e.path || process.cwd(), t = `# Shaping: [Name]
|
|
2328
|
+
|
|
2329
|
+
## Problem Statement
|
|
2330
|
+
|
|
2331
|
+
_What problem are we solving? What are we trying to achieve?_
|
|
2332
|
+
|
|
2333
|
+
## Approaches Considered
|
|
2334
|
+
|
|
2335
|
+
_Add approaches using riotplan_shaping_add_approach_
|
|
2336
|
+
|
|
2337
|
+
## Feedback
|
|
2338
|
+
|
|
2339
|
+
_Feedback will be added here as you provide it_
|
|
2340
|
+
|
|
2341
|
+
## Evidence
|
|
2342
|
+
|
|
2343
|
+
_Evidence will be added here to support decision-making_
|
|
2344
|
+
|
|
2345
|
+
## Key Decisions
|
|
2346
|
+
|
|
2347
|
+
_Decisions will be tracked here_
|
|
2348
|
+
|
|
2349
|
+
## Open Questions
|
|
2350
|
+
|
|
2351
|
+
- _What questions need answering?_
|
|
2352
|
+
|
|
2353
|
+
## Status
|
|
2354
|
+
|
|
2355
|
+
**Stage**: shaping
|
|
2356
|
+
**Started**: ${S()}
|
|
2357
|
+
**Next**: Select an approach and transition to 'built'
|
|
2358
|
+
`;
|
|
2359
|
+
await w(u(n, "SHAPING.md"), t, "utf-8");
|
|
2360
|
+
const s = u(n, "LIFECYCLE.md");
|
|
2361
|
+
let r = await y(s, "utf-8");
|
|
2362
|
+
r = r.replace(
|
|
2363
|
+
/\*\*Stage\*\*: `\w+`/,
|
|
2364
|
+
"**Stage**: `shaping`"
|
|
2365
|
+
), r = r.replace(
|
|
2366
|
+
/\*\*Since\*\*: .+/,
|
|
2367
|
+
`**Since**: ${S()}`
|
|
2368
|
+
);
|
|
2369
|
+
const a = r.indexOf("| From | To | When | Reason |");
|
|
2370
|
+
if (a !== -1) {
|
|
2371
|
+
const i = r.indexOf(`
|
|
2372
|
+
`, a + 50), o = `| idea | shaping | ${S()} | Ready to explore approaches |
|
|
2373
|
+
`;
|
|
2374
|
+
r = r.slice(0, i + 1) + o + r.slice(i + 1);
|
|
2375
|
+
}
|
|
2376
|
+
return await w(s, r, "utf-8"), await _(n, {
|
|
2377
|
+
timestamp: S(),
|
|
2378
|
+
type: "shaping_started",
|
|
2379
|
+
data: {}
|
|
2380
|
+
}), `β
Shaping started
|
|
2381
|
+
|
|
2382
|
+
Next steps:
|
|
2383
|
+
- Add approaches: riotplan_shaping_add_approach
|
|
2384
|
+
- Provide feedback: riotplan_shaping_add_feedback
|
|
2385
|
+
- Add evidence: riotplan_shaping_add_evidence
|
|
2386
|
+
- Compare approaches: riotplan_shaping_compare
|
|
2387
|
+
- When ready: riotplan_shaping_select`;
|
|
2388
|
+
}
|
|
2389
|
+
async function on(e) {
|
|
2390
|
+
const n = e.path || process.cwd(), t = u(n, "SHAPING.md");
|
|
2391
|
+
let s = await y(t, "utf-8");
|
|
2392
|
+
const r = "## Approaches Considered", a = s.indexOf(r);
|
|
2393
|
+
if (a === -1)
|
|
2394
|
+
throw new Error("Could not find Approaches Considered section in SHAPING.md");
|
|
2395
|
+
const i = s.indexOf(`
|
|
2396
|
+
## `, a + r.length), o = i === -1 ? s.length : i;
|
|
2397
|
+
let p = `
|
|
2398
|
+
### Approach: ${e.name}
|
|
2399
|
+
|
|
2400
|
+
`;
|
|
2401
|
+
return p += `**Description**: ${e.description}
|
|
2402
|
+
|
|
2403
|
+
`, e.tradeoffs && e.tradeoffs.length > 0 && (p += `**Tradeoffs**:
|
|
2404
|
+
`, e.tradeoffs.forEach((d) => {
|
|
2405
|
+
p += `- ${d}
|
|
2406
|
+
`;
|
|
2407
|
+
}), p += `
|
|
2408
|
+
`), e.assumptions && e.assumptions.length > 0 && (p += `**Assumptions**:
|
|
2409
|
+
`, e.assumptions.forEach((d) => {
|
|
2410
|
+
p += `- ${d}
|
|
2411
|
+
`;
|
|
2412
|
+
}), p += `
|
|
2413
|
+
`), s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2414
|
+
timestamp: S(),
|
|
2415
|
+
type: "approach_added",
|
|
2416
|
+
data: {
|
|
2417
|
+
name: e.name,
|
|
2418
|
+
description: e.description,
|
|
2419
|
+
tradeoffs: e.tradeoffs,
|
|
2420
|
+
assumptions: e.assumptions
|
|
2421
|
+
}
|
|
2422
|
+
}), `β
Approach added: ${e.name}`;
|
|
2423
|
+
}
|
|
2424
|
+
async function cn(e) {
|
|
2425
|
+
const n = e.path || process.cwd(), t = u(n, "SHAPING.md");
|
|
2426
|
+
let s = await y(t, "utf-8");
|
|
2427
|
+
const r = "## Feedback", a = s.indexOf(r);
|
|
2428
|
+
if (a === -1)
|
|
2429
|
+
throw new Error("Could not find Feedback section in SHAPING.md");
|
|
2430
|
+
const i = s.indexOf(`
|
|
2431
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `
|
|
2432
|
+
### ${S()}
|
|
2433
|
+
|
|
2434
|
+
${e.feedback}
|
|
2435
|
+
`;
|
|
2436
|
+
return s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2437
|
+
timestamp: S(),
|
|
2438
|
+
type: "feedback_added",
|
|
2439
|
+
data: { feedback: e.feedback }
|
|
2440
|
+
}), "β
Feedback added";
|
|
2441
|
+
}
|
|
2442
|
+
async function pn(e) {
|
|
2443
|
+
const n = e.path || process.cwd(), t = u(n, "SHAPING.md");
|
|
2444
|
+
let s = await y(t, "utf-8");
|
|
2445
|
+
const r = "## Evidence", a = s.indexOf(r);
|
|
2446
|
+
if (a === -1)
|
|
2447
|
+
throw new Error("Could not find Evidence section in SHAPING.md");
|
|
2448
|
+
const i = s.indexOf(`
|
|
2449
|
+
## `, a + r.length), o = i === -1 ? s.length : i;
|
|
2450
|
+
let p = `
|
|
2451
|
+
- [${e.evidencePath}](${e.evidencePath})`;
|
|
2452
|
+
return e.description && (p += ` - ${e.description}`), e.relatedTo && (p += ` (relates to: ${e.relatedTo})`), p += `
|
|
2453
|
+
`, s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8"), await _(n, {
|
|
2454
|
+
timestamp: S(),
|
|
2455
|
+
type: "evidence_added",
|
|
2456
|
+
data: {
|
|
2457
|
+
evidencePath: e.evidencePath,
|
|
2458
|
+
description: e.description,
|
|
2459
|
+
relatedTo: e.relatedTo
|
|
2460
|
+
}
|
|
2461
|
+
}), "β
Evidence added";
|
|
2462
|
+
}
|
|
2463
|
+
async function dn(e) {
|
|
2464
|
+
const n = e.path || process.cwd(), t = u(n, "SHAPING.md"), s = await y(t, "utf-8"), r = s.indexOf("## Approaches Considered"), a = s.indexOf(`
|
|
2465
|
+
## `, r + 25), i = s.slice(r, a !== -1 ? a : void 0), o = i.match(/### Approach: (.+)/g) || [];
|
|
2466
|
+
if (o.length === 0)
|
|
2467
|
+
return "No approaches found. Add approaches first using riotplan_shaping_add_approach";
|
|
2468
|
+
let p = `## Approach Comparison
|
|
2469
|
+
|
|
2470
|
+
`;
|
|
2471
|
+
return o.forEach((d) => {
|
|
2472
|
+
const l = d.replace("### Approach: ", "");
|
|
2473
|
+
p += `**${l}**
|
|
2474
|
+
`;
|
|
2475
|
+
const f = i.indexOf(d), m = i.indexOf("### Approach:", f + 1), v = i.slice(
|
|
2476
|
+
f,
|
|
2477
|
+
m !== -1 ? m : void 0
|
|
2478
|
+
).match(/\*\*Tradeoffs\*\*:\n((?:- .+\n)+)/);
|
|
2479
|
+
v && (p += v[1]), p += `
|
|
2480
|
+
`;
|
|
2481
|
+
}), await _(n, {
|
|
2482
|
+
timestamp: S(),
|
|
2483
|
+
type: "approach_compared",
|
|
2484
|
+
data: { approachCount: o.length }
|
|
2485
|
+
}), p;
|
|
2486
|
+
}
|
|
2487
|
+
async function ln(e) {
|
|
2488
|
+
const n = e.path || process.cwd(), t = u(n, "SHAPING.md");
|
|
2489
|
+
let s = await y(t, "utf-8");
|
|
2490
|
+
const r = "## Key Decisions", a = s.indexOf(r);
|
|
2491
|
+
if (a !== -1) {
|
|
2492
|
+
const i = s.indexOf(`
|
|
2493
|
+
## `, a + r.length), o = i === -1 ? s.length : i, p = `
|
|
2494
|
+
**Selected Approach**: ${e.approach}
|
|
2495
|
+
|
|
2496
|
+
**Reasoning**: ${e.reason}
|
|
2497
|
+
|
|
2498
|
+
**Selected At**: ${S()}
|
|
2499
|
+
`;
|
|
2500
|
+
s = s.slice(0, o) + p + s.slice(o), await w(t, s, "utf-8");
|
|
2501
|
+
}
|
|
2502
|
+
return await _(n, {
|
|
2503
|
+
timestamp: S(),
|
|
2504
|
+
type: "approach_selected",
|
|
2505
|
+
data: {
|
|
2506
|
+
approach: e.approach,
|
|
2507
|
+
reason: e.reason
|
|
2508
|
+
}
|
|
2509
|
+
}), `β
Approach selected: ${e.approach}
|
|
2510
|
+
|
|
2511
|
+
Next: Transition to 'built' stage to generate detailed plan:
|
|
2512
|
+
riotplan_transition({ stage: "built", reason: "Approach selected: ${e.approach}" })`;
|
|
2513
|
+
}
|
|
2514
|
+
async function un(e, n) {
|
|
2515
|
+
try {
|
|
2516
|
+
const t = ue.parse(e);
|
|
2517
|
+
return { success: !0, data: { message: await rn(t) } };
|
|
2518
|
+
} catch (t) {
|
|
2519
|
+
return { success: !1, error: t.message };
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
async function hn(e, n) {
|
|
2523
|
+
try {
|
|
2524
|
+
const t = he.parse(e);
|
|
2525
|
+
return { success: !0, data: { message: await on(t) } };
|
|
2526
|
+
} catch (t) {
|
|
2527
|
+
return { success: !1, error: t.message };
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
async function mn(e, n) {
|
|
2531
|
+
try {
|
|
2532
|
+
const t = me.parse(e);
|
|
2533
|
+
return { success: !0, data: { message: await cn(t) } };
|
|
2534
|
+
} catch (t) {
|
|
2535
|
+
return { success: !1, error: t.message };
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
async function fn(e, n) {
|
|
2539
|
+
try {
|
|
2540
|
+
const t = fe.parse(e);
|
|
2541
|
+
return { success: !0, data: { message: await pn(t) } };
|
|
2542
|
+
} catch (t) {
|
|
2543
|
+
return { success: !1, error: t.message };
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
async function gn(e, n) {
|
|
2547
|
+
try {
|
|
2548
|
+
const t = ge.parse(e);
|
|
2549
|
+
return { success: !0, data: { message: await dn(t) } };
|
|
2550
|
+
} catch (t) {
|
|
2551
|
+
return { success: !1, error: t.message };
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
async function yn(e, n) {
|
|
2555
|
+
try {
|
|
2556
|
+
const t = ye.parse(e);
|
|
2557
|
+
return { success: !0, data: { message: await ln(t) } };
|
|
2558
|
+
} catch (t) {
|
|
2559
|
+
return { success: !1, error: t.message };
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
ue.shape;
|
|
2563
|
+
he.shape;
|
|
2564
|
+
me.shape;
|
|
2565
|
+
fe.shape;
|
|
2566
|
+
ge.shape;
|
|
2567
|
+
ye.shape;
|
|
2568
|
+
async function wn(e, n, t) {
|
|
2569
|
+
try {
|
|
2570
|
+
switch (e) {
|
|
2571
|
+
case "riotplan_create":
|
|
2572
|
+
return await Te(n, t);
|
|
2573
|
+
case "riotplan_status":
|
|
2574
|
+
return await Ve(n, t);
|
|
2575
|
+
case "riotplan_step_list":
|
|
2576
|
+
return await lt(n, t);
|
|
2577
|
+
case "riotplan_step_start":
|
|
2578
|
+
return await ut(n, t);
|
|
2579
|
+
case "riotplan_step_complete":
|
|
2580
|
+
return await ht(n, t);
|
|
2581
|
+
case "riotplan_step_add":
|
|
2582
|
+
return await mt(n, t);
|
|
2583
|
+
case "riotplan_validate":
|
|
2584
|
+
return await bt(n, t);
|
|
2585
|
+
case "riotplan_generate":
|
|
2586
|
+
return await Dt(n, t);
|
|
2587
|
+
// Idea tools
|
|
2588
|
+
case "riotplan_idea_create":
|
|
2589
|
+
return await Xt(n, t);
|
|
2590
|
+
case "riotplan_idea_add_note":
|
|
2591
|
+
return await Zt(n, t);
|
|
2592
|
+
case "riotplan_idea_add_constraint":
|
|
2593
|
+
return await en(n, t);
|
|
2594
|
+
case "riotplan_idea_add_question":
|
|
2595
|
+
return await tn(n, t);
|
|
2596
|
+
case "riotplan_idea_add_evidence":
|
|
2597
|
+
return await nn(n, t);
|
|
2598
|
+
case "riotplan_idea_add_narrative":
|
|
2599
|
+
return await sn(n, t);
|
|
2600
|
+
case "riotplan_idea_kill":
|
|
2601
|
+
return await an(n, t);
|
|
2602
|
+
// Shaping tools
|
|
2603
|
+
case "riotplan_shaping_start":
|
|
2604
|
+
return await un(n, t);
|
|
2605
|
+
case "riotplan_shaping_add_approach":
|
|
2606
|
+
return await hn(n, t);
|
|
2607
|
+
case "riotplan_shaping_add_feedback":
|
|
2608
|
+
return await mn(n, t);
|
|
2609
|
+
case "riotplan_shaping_add_evidence":
|
|
2610
|
+
return await fn(n, t);
|
|
2611
|
+
case "riotplan_shaping_compare":
|
|
2612
|
+
return await gn(n, t);
|
|
2613
|
+
case "riotplan_shaping_select":
|
|
2614
|
+
return await yn(n, t);
|
|
2615
|
+
// History and checkpoint tools
|
|
2616
|
+
case "riotplan_checkpoint_create":
|
|
2617
|
+
return await qt(n, t);
|
|
2618
|
+
case "riotplan_checkpoint_list":
|
|
2619
|
+
return await Ut(n, t);
|
|
2620
|
+
case "riotplan_checkpoint_show":
|
|
2621
|
+
return await Gt(n, t);
|
|
2622
|
+
case "riotplan_checkpoint_restore":
|
|
2623
|
+
return await Wt(n, t);
|
|
2624
|
+
case "riotplan_history_show":
|
|
2625
|
+
return await Bt(n, t);
|
|
2626
|
+
default:
|
|
2627
|
+
return {
|
|
2628
|
+
success: !1,
|
|
2629
|
+
error: `Unknown tool: ${e}`
|
|
2630
|
+
};
|
|
2631
|
+
}
|
|
2632
|
+
} catch (s) {
|
|
2633
|
+
return {
|
|
2634
|
+
success: !1,
|
|
2635
|
+
error: s instanceof Error ? s.message : String(s),
|
|
2636
|
+
context: {
|
|
2637
|
+
errorType: s?.constructor?.name || "Error"
|
|
2638
|
+
}
|
|
2639
|
+
};
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
async function Sn(e) {
|
|
2643
|
+
if (!$e(e))
|
|
2644
|
+
return {
|
|
2645
|
+
path: e,
|
|
2646
|
+
code: "",
|
|
2647
|
+
name: "",
|
|
2648
|
+
exists: !1
|
|
2649
|
+
};
|
|
2650
|
+
try {
|
|
2651
|
+
const t = await P(e);
|
|
2652
|
+
return {
|
|
2653
|
+
path: t.metadata.path,
|
|
2654
|
+
code: t.metadata.code,
|
|
2655
|
+
name: t.metadata.name,
|
|
2656
|
+
exists: !0,
|
|
2657
|
+
metadata: {
|
|
2658
|
+
code: t.metadata.code,
|
|
2659
|
+
name: t.metadata.name,
|
|
2660
|
+
description: t.metadata.description,
|
|
2661
|
+
created: t.metadata.createdAt
|
|
2662
|
+
},
|
|
2663
|
+
state: {
|
|
2664
|
+
status: t.state.status,
|
|
2665
|
+
currentStep: t.state.currentStep,
|
|
2666
|
+
lastCompleted: t.state.lastCompletedStep,
|
|
2667
|
+
startedAt: t.state.startedAt,
|
|
2668
|
+
lastUpdated: t.state.lastUpdatedAt
|
|
2669
|
+
}
|
|
2670
|
+
};
|
|
2671
|
+
} catch (t) {
|
|
2672
|
+
throw new Error(`Failed to read plan at ${e}: ${t}`);
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
async function vn(e) {
|
|
2676
|
+
try {
|
|
2677
|
+
const n = await P(e), t = n.steps.filter((a) => a.status === "completed").length, s = n.steps.length, r = s > 0 ? Math.round(t / s * 100) : 0;
|
|
2678
|
+
return {
|
|
2679
|
+
planPath: n.metadata.path,
|
|
2680
|
+
status: n.state.status,
|
|
2681
|
+
currentStep: n.state.currentStep,
|
|
2682
|
+
lastCompleted: n.state.lastCompletedStep,
|
|
2683
|
+
progress: {
|
|
2684
|
+
completed: t,
|
|
2685
|
+
total: s,
|
|
2686
|
+
percentage: r
|
|
2687
|
+
},
|
|
2688
|
+
blockers: (n.state.blockers || []).map(
|
|
2689
|
+
(a) => typeof a == "string" ? a : `${a.severity}: ${a.description}`
|
|
2690
|
+
),
|
|
2691
|
+
issues: (n.state.issues || []).map(
|
|
2692
|
+
(a) => typeof a == "string" ? a : `${a.severity}: ${a.description}`
|
|
2693
|
+
)
|
|
2694
|
+
};
|
|
2695
|
+
} catch (n) {
|
|
2696
|
+
throw new Error(`Failed to read status at ${e}: ${n}`);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
async function bn(e) {
|
|
2700
|
+
try {
|
|
2701
|
+
const n = await P(e);
|
|
2702
|
+
return {
|
|
2703
|
+
planPath: n.metadata.path,
|
|
2704
|
+
steps: n.steps.map((t) => ({
|
|
2705
|
+
number: t.number,
|
|
2706
|
+
title: t.title,
|
|
2707
|
+
status: t.status,
|
|
2708
|
+
file: t.filename
|
|
2709
|
+
}))
|
|
2710
|
+
};
|
|
2711
|
+
} catch (n) {
|
|
2712
|
+
throw new Error(`Failed to read steps at ${e}: ${n}`);
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
async function kn(e, n) {
|
|
2716
|
+
try {
|
|
2717
|
+
const t = await P(e), s = t.steps.find((i) => i.number === n);
|
|
2718
|
+
if (!s)
|
|
2719
|
+
throw new Error(`Step ${n} not found in plan`);
|
|
2720
|
+
const r = u(t.metadata.path, "plan", s.filename), a = Y(r, "utf-8");
|
|
2721
|
+
return {
|
|
2722
|
+
planPath: t.metadata.path,
|
|
2723
|
+
number: s.number,
|
|
2724
|
+
title: s.title,
|
|
2725
|
+
status: s.status,
|
|
2726
|
+
file: s.filename,
|
|
2727
|
+
content: a
|
|
2728
|
+
};
|
|
2729
|
+
} catch (t) {
|
|
2730
|
+
throw new Error(`Failed to read step ${n} at ${e}: ${t}`);
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
async function _n(e) {
|
|
2734
|
+
const n = u(e, "IDEA.md");
|
|
2735
|
+
try {
|
|
2736
|
+
const t = await y(n, "utf-8");
|
|
2737
|
+
return {
|
|
2738
|
+
path: n,
|
|
2739
|
+
content: t,
|
|
2740
|
+
type: "idea"
|
|
2741
|
+
};
|
|
2742
|
+
} catch (t) {
|
|
2743
|
+
throw t.code === "ENOENT" ? new Error(`IDEA.md not found at ${n}. This may not be an idea/plan directory.`) : t;
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
async function $n(e) {
|
|
2747
|
+
const n = u(e, ".history", "timeline.jsonl");
|
|
2748
|
+
try {
|
|
2749
|
+
const s = (await y(n, "utf-8")).trim().split(`
|
|
2750
|
+
`).filter((r) => r.trim()).map((r) => JSON.parse(r));
|
|
2751
|
+
return {
|
|
2752
|
+
path: n,
|
|
2753
|
+
events: s,
|
|
2754
|
+
count: s.length,
|
|
2755
|
+
type: "timeline"
|
|
2756
|
+
};
|
|
2757
|
+
} catch (t) {
|
|
2758
|
+
throw t.code === "ENOENT" ? new Error(`Timeline not found at ${n}. This may not have history tracking enabled.`) : t;
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
async function Pn(e) {
|
|
2762
|
+
const n = u(e, ".history", "prompts");
|
|
2763
|
+
try {
|
|
2764
|
+
const s = (await b(n)).filter((r) => r.endsWith(".md")).sort();
|
|
2765
|
+
return {
|
|
2766
|
+
path: n,
|
|
2767
|
+
prompts: s,
|
|
2768
|
+
count: s.length,
|
|
2769
|
+
type: "prompts_list"
|
|
2770
|
+
};
|
|
2771
|
+
} catch (t) {
|
|
2772
|
+
if (t.code === "ENOENT")
|
|
2773
|
+
return {
|
|
2774
|
+
path: n,
|
|
2775
|
+
prompts: [],
|
|
2776
|
+
count: 0,
|
|
2777
|
+
type: "prompts_list",
|
|
2778
|
+
note: "No prompts directory found"
|
|
2779
|
+
};
|
|
2780
|
+
throw t;
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
async function xn(e, n) {
|
|
2784
|
+
const t = u(e, ".history", "prompts", n);
|
|
2785
|
+
try {
|
|
2786
|
+
const s = await y(t, "utf-8");
|
|
2787
|
+
return {
|
|
2788
|
+
path: t,
|
|
2789
|
+
file: n,
|
|
2790
|
+
content: s,
|
|
2791
|
+
type: "prompt"
|
|
2792
|
+
};
|
|
2793
|
+
} catch (s) {
|
|
2794
|
+
throw s.code === "ENOENT" ? new Error(`Prompt file not found: ${n}`) : s;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
async function Cn(e) {
|
|
2798
|
+
const n = u(e, "evidence");
|
|
2799
|
+
try {
|
|
2800
|
+
const t = await b(n), s = await Promise.all(
|
|
2801
|
+
t.map(async (r) => {
|
|
2802
|
+
const a = u(n, r), i = await j(a);
|
|
2803
|
+
return {
|
|
2804
|
+
name: r,
|
|
2805
|
+
size: i.size,
|
|
2806
|
+
modified: i.mtime
|
|
2807
|
+
};
|
|
2808
|
+
})
|
|
2809
|
+
);
|
|
2810
|
+
return {
|
|
2811
|
+
path: n,
|
|
2812
|
+
evidence: s,
|
|
2813
|
+
count: s.length,
|
|
2814
|
+
type: "evidence_list"
|
|
2815
|
+
};
|
|
2816
|
+
} catch (t) {
|
|
2817
|
+
if (t.code === "ENOENT")
|
|
2818
|
+
return {
|
|
2819
|
+
path: n,
|
|
2820
|
+
evidence: [],
|
|
2821
|
+
count: 0,
|
|
2822
|
+
type: "evidence_list",
|
|
2823
|
+
note: "No evidence directory found"
|
|
2824
|
+
};
|
|
2825
|
+
throw t;
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
async function An(e, n) {
|
|
2829
|
+
const t = u(e, "evidence", n);
|
|
2830
|
+
try {
|
|
2831
|
+
const s = await y(t, "utf-8"), r = await j(t);
|
|
2832
|
+
return {
|
|
2833
|
+
path: t,
|
|
2834
|
+
file: n,
|
|
2835
|
+
content: s,
|
|
2836
|
+
size: r.size,
|
|
2837
|
+
modified: r.mtime,
|
|
2838
|
+
type: "evidence"
|
|
2839
|
+
};
|
|
2840
|
+
} catch (s) {
|
|
2841
|
+
throw s.code === "ENOENT" ? new Error(`Evidence file not found: ${n}`) : s;
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
async function En(e) {
|
|
2845
|
+
const n = u(e, "SHAPING.md");
|
|
2846
|
+
try {
|
|
2847
|
+
const t = await y(n, "utf-8");
|
|
2848
|
+
return {
|
|
2849
|
+
path: n,
|
|
2850
|
+
content: t,
|
|
2851
|
+
type: "shaping"
|
|
2852
|
+
};
|
|
2853
|
+
} catch (t) {
|
|
2854
|
+
if (t.code === "ENOENT")
|
|
2855
|
+
return {
|
|
2856
|
+
path: n,
|
|
2857
|
+
content: null,
|
|
2858
|
+
type: "shaping",
|
|
2859
|
+
note: "No shaping file found - idea may not have been shaped yet"
|
|
2860
|
+
};
|
|
2861
|
+
throw t;
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
async function Dn(e) {
|
|
2865
|
+
const n = u(e, ".history", "checkpoints");
|
|
2866
|
+
try {
|
|
2867
|
+
const t = await b(n), s = await Promise.all(
|
|
2868
|
+
t.filter((r) => r.endsWith(".json")).map(async (r) => {
|
|
2869
|
+
const a = u(n, r), i = await j(a);
|
|
2870
|
+
return {
|
|
2871
|
+
name: r.replace(".json", ""),
|
|
2872
|
+
file: r,
|
|
2873
|
+
created: i.mtime
|
|
2874
|
+
};
|
|
2875
|
+
})
|
|
2876
|
+
);
|
|
2877
|
+
return s.sort((r, a) => a.created.getTime() - r.created.getTime()), {
|
|
2878
|
+
path: n,
|
|
2879
|
+
checkpoints: s,
|
|
2880
|
+
count: s.length,
|
|
2881
|
+
type: "checkpoints_list"
|
|
2882
|
+
};
|
|
2883
|
+
} catch (t) {
|
|
2884
|
+
if (t.code === "ENOENT")
|
|
2885
|
+
return {
|
|
2886
|
+
path: n,
|
|
2887
|
+
checkpoints: [],
|
|
2888
|
+
count: 0,
|
|
2889
|
+
type: "checkpoints_list",
|
|
2890
|
+
note: "No checkpoints directory found"
|
|
2891
|
+
};
|
|
2892
|
+
throw t;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
async function In(e, n) {
|
|
2896
|
+
const t = u(e, ".history", "checkpoints", `${n}.json`), s = u(e, ".history", "prompts", `${n}.md`);
|
|
2897
|
+
try {
|
|
2898
|
+
const r = await y(t, "utf-8"), a = JSON.parse(r);
|
|
2899
|
+
let i = null;
|
|
2900
|
+
try {
|
|
2901
|
+
i = await y(s, "utf-8");
|
|
2902
|
+
} catch {
|
|
2903
|
+
}
|
|
2904
|
+
return {
|
|
2905
|
+
path: t,
|
|
2906
|
+
name: n,
|
|
2907
|
+
checkpoint: a,
|
|
2908
|
+
prompt: i,
|
|
2909
|
+
type: "checkpoint"
|
|
2910
|
+
};
|
|
2911
|
+
} catch (r) {
|
|
2912
|
+
throw r.code === "ENOENT" ? new Error(`Checkpoint not found: ${n}`) : r;
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
function Nn(e) {
|
|
2916
|
+
if (!e.startsWith("riotplan://"))
|
|
2917
|
+
throw new Error(`Invalid riotplan URI: ${e}`);
|
|
2918
|
+
const n = e.slice(11), [t, s] = n.split("?"), r = t.split("/"), a = r[0], i = r.slice(1).join("/") || void 0, o = {};
|
|
2919
|
+
if (s) {
|
|
2920
|
+
const p = new URLSearchParams(s);
|
|
2921
|
+
for (const [d, l] of p.entries())
|
|
2922
|
+
o[d] = l;
|
|
2923
|
+
}
|
|
2924
|
+
return {
|
|
2925
|
+
scheme: "riotplan",
|
|
2926
|
+
type: a,
|
|
2927
|
+
path: i,
|
|
2928
|
+
query: Object.keys(o).length > 0 ? o : void 0
|
|
2929
|
+
};
|
|
2930
|
+
}
|
|
2931
|
+
function Tn() {
|
|
2932
|
+
return [
|
|
2933
|
+
// Plan execution resources
|
|
2934
|
+
{
|
|
2935
|
+
uri: "riotplan://plan/{path}",
|
|
2936
|
+
name: "Plan",
|
|
2937
|
+
description: "Read plan metadata and structure",
|
|
2938
|
+
mimeType: "application/json"
|
|
2939
|
+
},
|
|
2940
|
+
{
|
|
2941
|
+
uri: "riotplan://status/{path}",
|
|
2942
|
+
name: "Status",
|
|
2943
|
+
description: "Read plan status and progress",
|
|
2944
|
+
mimeType: "application/json"
|
|
2945
|
+
},
|
|
2946
|
+
{
|
|
2947
|
+
uri: "riotplan://steps/{path}",
|
|
2948
|
+
name: "Steps",
|
|
2949
|
+
description: "List all steps in a plan",
|
|
2950
|
+
mimeType: "application/json"
|
|
2951
|
+
},
|
|
2952
|
+
{
|
|
2953
|
+
uri: "riotplan://step/{path}/{number}",
|
|
2954
|
+
name: "Step",
|
|
2955
|
+
description: "Read a specific step with full content",
|
|
2956
|
+
mimeType: "application/json"
|
|
2957
|
+
},
|
|
2958
|
+
// Ideation context resources
|
|
2959
|
+
{
|
|
2960
|
+
uri: "riotplan://idea/{path}",
|
|
2961
|
+
name: "Idea",
|
|
2962
|
+
description: "Read IDEA.md file with core concept, constraints, questions, and evidence",
|
|
2963
|
+
mimeType: "application/json"
|
|
2964
|
+
},
|
|
2965
|
+
{
|
|
2966
|
+
uri: "riotplan://timeline/{path}",
|
|
2967
|
+
name: "Timeline",
|
|
2968
|
+
description: "Read .history/timeline.jsonl with full evolution of thinking (notes, narratives, decisions)",
|
|
2969
|
+
mimeType: "application/json"
|
|
2970
|
+
},
|
|
2971
|
+
{
|
|
2972
|
+
uri: "riotplan://prompts/{path}",
|
|
2973
|
+
name: "Prompts List",
|
|
2974
|
+
description: "List all prompt files in .history/prompts/ directory",
|
|
2975
|
+
mimeType: "application/json"
|
|
2976
|
+
},
|
|
2977
|
+
{
|
|
2978
|
+
uri: "riotplan://prompt/{path}/{file}",
|
|
2979
|
+
name: "Prompt",
|
|
2980
|
+
description: "Read a specific prompt file with conversational context",
|
|
2981
|
+
mimeType: "application/json"
|
|
2982
|
+
},
|
|
2983
|
+
{
|
|
2984
|
+
uri: "riotplan://evidence/{path}",
|
|
2985
|
+
name: "Evidence List",
|
|
2986
|
+
description: "List all evidence files in evidence/ directory",
|
|
2987
|
+
mimeType: "application/json"
|
|
2988
|
+
},
|
|
2989
|
+
{
|
|
2990
|
+
uri: "riotplan://evidence-file/{path}/{file}",
|
|
2991
|
+
name: "Evidence File",
|
|
2992
|
+
description: "Read a specific evidence file",
|
|
2993
|
+
mimeType: "application/json"
|
|
2994
|
+
},
|
|
2995
|
+
{
|
|
2996
|
+
uri: "riotplan://shaping/{path}",
|
|
2997
|
+
name: "Shaping",
|
|
2998
|
+
description: "Read SHAPING.md with approaches, tradeoffs, and selected approach",
|
|
2999
|
+
mimeType: "application/json"
|
|
3000
|
+
},
|
|
3001
|
+
{
|
|
3002
|
+
uri: "riotplan://checkpoints/{path}",
|
|
3003
|
+
name: "Checkpoints List",
|
|
3004
|
+
description: "List all checkpoints in .history/checkpoints/ directory",
|
|
3005
|
+
mimeType: "application/json"
|
|
3006
|
+
},
|
|
3007
|
+
{
|
|
3008
|
+
uri: "riotplan://checkpoint/{path}/{name}",
|
|
3009
|
+
name: "Checkpoint",
|
|
3010
|
+
description: "Read a specific checkpoint with snapshot and prompt context",
|
|
3011
|
+
mimeType: "application/json"
|
|
3012
|
+
}
|
|
3013
|
+
];
|
|
3014
|
+
}
|
|
3015
|
+
async function Fn(e) {
|
|
3016
|
+
const n = Nn(e);
|
|
3017
|
+
switch (n.type) {
|
|
3018
|
+
// Plan execution resources
|
|
3019
|
+
case "plan":
|
|
3020
|
+
return await Sn(n.path || ".");
|
|
3021
|
+
case "status":
|
|
3022
|
+
return await vn(n.path || ".");
|
|
3023
|
+
case "steps":
|
|
3024
|
+
return await bn(n.path || ".");
|
|
3025
|
+
case "step": {
|
|
3026
|
+
const t = n.query?.number ? parseInt(n.query.number) : void 0;
|
|
3027
|
+
if (!t)
|
|
3028
|
+
throw new Error("Step number is required for step resource");
|
|
3029
|
+
return await kn(n.path || ".", t);
|
|
3030
|
+
}
|
|
3031
|
+
// Ideation context resources
|
|
3032
|
+
case "idea":
|
|
3033
|
+
return await _n(n.path || ".");
|
|
3034
|
+
case "timeline":
|
|
3035
|
+
return await $n(n.path || ".");
|
|
3036
|
+
case "prompts":
|
|
3037
|
+
return await Pn(n.path || ".");
|
|
3038
|
+
case "prompt": {
|
|
3039
|
+
const t = n.query?.file;
|
|
3040
|
+
if (!t)
|
|
3041
|
+
throw new Error("File name is required for prompt resource");
|
|
3042
|
+
return await xn(n.path || ".", t);
|
|
3043
|
+
}
|
|
3044
|
+
case "evidence":
|
|
3045
|
+
return await Cn(n.path || ".");
|
|
3046
|
+
case "evidence-file": {
|
|
3047
|
+
const t = n.query?.file;
|
|
3048
|
+
if (!t)
|
|
3049
|
+
throw new Error("File name is required for evidence resource");
|
|
3050
|
+
return await An(n.path || ".", t);
|
|
3051
|
+
}
|
|
3052
|
+
case "shaping":
|
|
3053
|
+
return await En(n.path || ".");
|
|
3054
|
+
case "checkpoints":
|
|
3055
|
+
return await Dn(n.path || ".");
|
|
3056
|
+
case "checkpoint": {
|
|
3057
|
+
const t = n.query?.name;
|
|
3058
|
+
if (!t)
|
|
3059
|
+
throw new Error("Checkpoint name is required for checkpoint resource");
|
|
3060
|
+
return await In(n.path || ".", t);
|
|
3061
|
+
}
|
|
3062
|
+
default:
|
|
3063
|
+
throw new Error(`Unknown resource type: ${n.type}`);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
const L = Pe(import.meta.url), F = be(L);
|
|
3067
|
+
function On() {
|
|
3068
|
+
return F.includes("/dist") || F.endsWith("dist") || L.includes("dist/mcp-server.js") || L.includes("dist\\mcp-server.js") ? T(F, "mcp/prompts") : F;
|
|
3069
|
+
}
|
|
3070
|
+
function jn(e) {
|
|
3071
|
+
const n = On(), t = T(n, `${e}.md`);
|
|
3072
|
+
try {
|
|
3073
|
+
return Y(t, "utf-8").trim();
|
|
3074
|
+
} catch (s) {
|
|
3075
|
+
throw new Error(`Failed to load prompt template "${e}" from ${t}: ${s}`);
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
function Rn(e, n) {
|
|
3079
|
+
return e.replace(/\${(\w+)}/g, (t, s) => n[s] || `[${s}]`);
|
|
3080
|
+
}
|
|
3081
|
+
function we() {
|
|
3082
|
+
return [
|
|
3083
|
+
{
|
|
3084
|
+
name: "explore_idea",
|
|
3085
|
+
description: "Explore a new idea collaboratively without premature commitment. Capture thoughts, constraints, questions, and evidence.",
|
|
3086
|
+
arguments: [
|
|
3087
|
+
{
|
|
3088
|
+
name: "code",
|
|
3089
|
+
description: 'Idea identifier (kebab-case, e.g., "real-time-notifications")',
|
|
3090
|
+
required: !1
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
name: "description",
|
|
3094
|
+
description: "Initial concept description",
|
|
3095
|
+
required: !1
|
|
3096
|
+
}
|
|
3097
|
+
]
|
|
3098
|
+
},
|
|
3099
|
+
{
|
|
3100
|
+
name: "shape_approach",
|
|
3101
|
+
description: "Compare different approaches and make decisions before building detailed plans. Surface tradeoffs and gather evidence.",
|
|
3102
|
+
arguments: [
|
|
3103
|
+
{
|
|
3104
|
+
name: "path",
|
|
3105
|
+
description: "Path to idea or shaping directory",
|
|
3106
|
+
required: !1
|
|
3107
|
+
}
|
|
3108
|
+
]
|
|
3109
|
+
},
|
|
3110
|
+
{
|
|
3111
|
+
name: "create_plan",
|
|
3112
|
+
description: "Create a new plan with AI-generated steps for a complex task (use after shaping)",
|
|
3113
|
+
arguments: [
|
|
3114
|
+
{
|
|
3115
|
+
name: "code",
|
|
3116
|
+
description: 'Plan code/identifier (e.g., "auth-system", "dark-mode")',
|
|
3117
|
+
required: !1
|
|
3118
|
+
},
|
|
3119
|
+
{
|
|
3120
|
+
name: "description",
|
|
3121
|
+
description: "Detailed description of what you want to accomplish",
|
|
3122
|
+
required: !1
|
|
3123
|
+
},
|
|
3124
|
+
{
|
|
3125
|
+
name: "directory",
|
|
3126
|
+
description: 'Parent directory where the plan should be created (e.g., "./plans")',
|
|
3127
|
+
required: !1
|
|
3128
|
+
},
|
|
3129
|
+
{
|
|
3130
|
+
name: "steps",
|
|
3131
|
+
description: "Number of steps to generate (optional, AI will determine if not specified)",
|
|
3132
|
+
required: !1
|
|
3133
|
+
}
|
|
3134
|
+
]
|
|
3135
|
+
},
|
|
3136
|
+
{
|
|
3137
|
+
name: "develop_plan",
|
|
3138
|
+
description: "Refine a generated plan through conversational feedback. Captures full narrative of plan evolution with checkpoints.",
|
|
3139
|
+
arguments: [
|
|
3140
|
+
{
|
|
3141
|
+
name: "path",
|
|
3142
|
+
description: "Path to the plan directory to develop",
|
|
3143
|
+
required: !1
|
|
3144
|
+
}
|
|
3145
|
+
]
|
|
3146
|
+
},
|
|
3147
|
+
{
|
|
3148
|
+
name: "execute_plan",
|
|
3149
|
+
description: "Execute a plan with intelligent state management. Automatically determines next step, guides through tasks, and manages execution state.",
|
|
3150
|
+
arguments: [
|
|
3151
|
+
{
|
|
3152
|
+
name: "path",
|
|
3153
|
+
description: "Path to the plan directory to execute",
|
|
3154
|
+
required: !1
|
|
3155
|
+
}
|
|
3156
|
+
]
|
|
3157
|
+
},
|
|
3158
|
+
{
|
|
3159
|
+
name: "execute_step",
|
|
3160
|
+
description: "Execute a single step from a plan with proper status tracking",
|
|
3161
|
+
arguments: [
|
|
3162
|
+
{
|
|
3163
|
+
name: "path",
|
|
3164
|
+
description: "Plan directory path",
|
|
3165
|
+
required: !1
|
|
3166
|
+
}
|
|
3167
|
+
]
|
|
3168
|
+
},
|
|
3169
|
+
{
|
|
3170
|
+
name: "track_progress",
|
|
3171
|
+
description: "Monitor plan progress and maintain status tracking",
|
|
3172
|
+
arguments: [
|
|
3173
|
+
{
|
|
3174
|
+
name: "path",
|
|
3175
|
+
description: "Plan directory path",
|
|
3176
|
+
required: !1
|
|
3177
|
+
}
|
|
3178
|
+
]
|
|
3179
|
+
}
|
|
3180
|
+
];
|
|
3181
|
+
}
|
|
3182
|
+
async function Ln(e, n) {
|
|
3183
|
+
if (!we().find((o) => o.name === e))
|
|
3184
|
+
throw new Error(`Unknown prompt: ${e}`);
|
|
3185
|
+
const r = jn(e), a = { ...n };
|
|
3186
|
+
return e === "explore_idea" && (a.code || (a.code = "[idea-code]"), a.description || (a.description = "[initial concept]")), e === "create_plan" && (a.code || (a.code = "[code]"), a.description || (a.description = "[description]"), a.directory || (a.directory = "[directory]"), a.steps || (a.steps = "[steps]")), a.path || (a.path = "current directory"), [
|
|
3187
|
+
{
|
|
3188
|
+
role: "user",
|
|
3189
|
+
content: {
|
|
3190
|
+
type: "text",
|
|
3191
|
+
text: Rn(r, a)
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
];
|
|
3195
|
+
}
|
|
3196
|
+
function O(e) {
|
|
3197
|
+
if (e !== void 0) {
|
|
3198
|
+
if (e === null)
|
|
3199
|
+
return null;
|
|
3200
|
+
if (Array.isArray(e))
|
|
3201
|
+
return e.map(O).filter((n) => n !== void 0);
|
|
3202
|
+
if (typeof e == "object") {
|
|
3203
|
+
const n = {};
|
|
3204
|
+
for (const [t, s] of Object.entries(e)) {
|
|
3205
|
+
const r = O(s);
|
|
3206
|
+
r !== void 0 && (n[t] = r);
|
|
3207
|
+
}
|
|
3208
|
+
return n;
|
|
3209
|
+
}
|
|
3210
|
+
return e;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
async function Mn() {
|
|
3214
|
+
process.env.RIOTPLAN_MCP_SERVER = "true";
|
|
3215
|
+
const e = new Se(
|
|
3216
|
+
{
|
|
3217
|
+
name: "riotplan",
|
|
3218
|
+
version: "1.0.0"
|
|
3219
|
+
},
|
|
3220
|
+
{
|
|
3221
|
+
capabilities: {
|
|
3222
|
+
tools: {},
|
|
3223
|
+
resources: {
|
|
3224
|
+
subscribe: !1,
|
|
3225
|
+
listChanged: !1
|
|
3226
|
+
},
|
|
3227
|
+
prompts: {
|
|
3228
|
+
listChanged: !1
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
);
|
|
3233
|
+
function n(a, i, o) {
|
|
3234
|
+
e.tool(
|
|
3235
|
+
a,
|
|
3236
|
+
i,
|
|
3237
|
+
o,
|
|
3238
|
+
async (p, { sendNotification: d, _meta: l }) => {
|
|
3239
|
+
const f = {
|
|
3240
|
+
workingDirectory: process.cwd(),
|
|
3241
|
+
config: void 0,
|
|
3242
|
+
logger: void 0,
|
|
3243
|
+
sendNotification: async (g) => {
|
|
3244
|
+
if (g.method === "notifications/progress" && l?.progressToken) {
|
|
3245
|
+
const v = {
|
|
3246
|
+
progressToken: l.progressToken,
|
|
3247
|
+
progress: g.params.progress
|
|
3248
|
+
};
|
|
3249
|
+
g.params.total !== void 0 && (v.total = g.params.total), g.params.message !== void 0 && (v.message = g.params.message), await d({
|
|
3250
|
+
method: "notifications/progress",
|
|
3251
|
+
params: O(v)
|
|
3252
|
+
});
|
|
3253
|
+
}
|
|
3254
|
+
},
|
|
3255
|
+
progressToken: l?.progressToken
|
|
3256
|
+
}, m = await wn(a, p, f);
|
|
3257
|
+
if (m.success) {
|
|
3258
|
+
const g = [];
|
|
3259
|
+
m.logs && m.logs.length > 0 && g.push({
|
|
3260
|
+
type: "text",
|
|
3261
|
+
text: `=== Command Output ===
|
|
3262
|
+
` + m.logs.join(`
|
|
3263
|
+
`) + `
|
|
3264
|
+
|
|
3265
|
+
=== Result ===`
|
|
3266
|
+
});
|
|
3267
|
+
const v = O(m.data), k = v !== void 0 ? JSON.stringify(v, null, 2) : m.message || "Success";
|
|
3268
|
+
return g.push({
|
|
3269
|
+
type: "text",
|
|
3270
|
+
text: k
|
|
3271
|
+
}), { content: g };
|
|
3272
|
+
} else {
|
|
3273
|
+
const g = [];
|
|
3274
|
+
if (m.logs && m.logs.length > 0 && (g.push("=== Command Output ==="), g.push(m.logs.join(`
|
|
3275
|
+
`)), g.push(`
|
|
3276
|
+
=== Error ===`)), g.push(m.error || "Unknown error"), m.context && typeof m.context == "object") {
|
|
3277
|
+
g.push(`
|
|
3278
|
+
=== Context ===`);
|
|
3279
|
+
for (const [v, k] of Object.entries(m.context))
|
|
3280
|
+
k != null && g.push(`${v}: ${String(k)}`);
|
|
3281
|
+
}
|
|
3282
|
+
return m.details && (m.details.stderr && m.details.stderr.trim() && (g.push(`
|
|
3283
|
+
=== STDERR ===`), g.push(m.details.stderr)), m.details.stdout && m.details.stdout.trim() && (g.push(`
|
|
3284
|
+
=== STDOUT ===`), g.push(m.details.stdout))), m.recovery && m.recovery.length > 0 && (g.push(`
|
|
3285
|
+
=== Recovery Steps ===`), g.push(...m.recovery.map((v, k) => `${k + 1}. ${v}`))), {
|
|
3286
|
+
content: [{
|
|
3287
|
+
type: "text",
|
|
3288
|
+
text: g.join(`
|
|
3289
|
+
`)
|
|
3290
|
+
}],
|
|
3291
|
+
isError: !0
|
|
3292
|
+
};
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
);
|
|
3296
|
+
}
|
|
3297
|
+
n(
|
|
3298
|
+
"riotplan_create",
|
|
3299
|
+
"Create a new plan with AI generation. Generates detailed, actionable plans from descriptions.",
|
|
3300
|
+
{
|
|
3301
|
+
code: c.string(),
|
|
3302
|
+
name: c.string().optional(),
|
|
3303
|
+
description: c.string(),
|
|
3304
|
+
directory: c.string().optional(),
|
|
3305
|
+
steps: c.number().optional(),
|
|
3306
|
+
direct: c.boolean().optional(),
|
|
3307
|
+
provider: c.string().optional(),
|
|
3308
|
+
model: c.string().optional(),
|
|
3309
|
+
noAi: c.boolean().optional()
|
|
3310
|
+
}
|
|
3311
|
+
), n(
|
|
3312
|
+
"riotplan_status",
|
|
3313
|
+
"Show current plan status including progress, current step, blockers, and issues.",
|
|
3314
|
+
{
|
|
3315
|
+
path: c.string().optional(),
|
|
3316
|
+
verbose: c.boolean().optional()
|
|
3317
|
+
}
|
|
3318
|
+
), n(
|
|
3319
|
+
"riotplan_step_list",
|
|
3320
|
+
"List all steps in a plan with their status. Can filter to show only pending or all steps.",
|
|
3321
|
+
{
|
|
3322
|
+
path: c.string().optional(),
|
|
3323
|
+
pending: c.boolean().optional(),
|
|
3324
|
+
all: c.boolean().optional()
|
|
3325
|
+
}
|
|
3326
|
+
), n(
|
|
3327
|
+
"riotplan_step_start",
|
|
3328
|
+
"Mark a step as started. Updates STATUS.md to reflect the step is in progress.",
|
|
3329
|
+
{
|
|
3330
|
+
path: c.string().optional(),
|
|
3331
|
+
step: c.number()
|
|
3332
|
+
}
|
|
3333
|
+
), n(
|
|
3334
|
+
"riotplan_step_complete",
|
|
3335
|
+
"Mark a step as completed. Updates STATUS.md to reflect the step is done.",
|
|
3336
|
+
{
|
|
3337
|
+
path: c.string().optional(),
|
|
3338
|
+
step: c.number()
|
|
3339
|
+
}
|
|
3340
|
+
), n(
|
|
3341
|
+
"riotplan_step_add",
|
|
3342
|
+
"Add a new step to the plan. Can specify position or add after a specific step.",
|
|
3343
|
+
{
|
|
3344
|
+
path: c.string().optional(),
|
|
3345
|
+
title: c.string(),
|
|
3346
|
+
number: c.number().optional(),
|
|
3347
|
+
after: c.number().optional()
|
|
3348
|
+
}
|
|
3349
|
+
), n(
|
|
3350
|
+
"riotplan_validate",
|
|
3351
|
+
"Validate plan structure and files. Checks for required files, valid STATUS.md, step numbering, and dependencies.",
|
|
3352
|
+
{
|
|
3353
|
+
path: c.string().optional(),
|
|
3354
|
+
fix: c.boolean().optional()
|
|
3355
|
+
}
|
|
3356
|
+
), n(
|
|
3357
|
+
"riotplan_generate",
|
|
3358
|
+
"Generate plan content from an existing prompt file. Useful for regenerating plan files.",
|
|
3359
|
+
{
|
|
3360
|
+
path: c.string().optional(),
|
|
3361
|
+
steps: c.number().optional(),
|
|
3362
|
+
provider: c.string().optional(),
|
|
3363
|
+
model: c.string().optional()
|
|
3364
|
+
}
|
|
3365
|
+
), n(
|
|
3366
|
+
"riotplan_idea_create",
|
|
3367
|
+
"Create a new idea without commitment. Start exploring a concept in the Idea stage.",
|
|
3368
|
+
{
|
|
3369
|
+
code: c.string(),
|
|
3370
|
+
description: c.string(),
|
|
3371
|
+
directory: c.string().optional()
|
|
3372
|
+
}
|
|
3373
|
+
), n(
|
|
3374
|
+
"riotplan_idea_add_note",
|
|
3375
|
+
"Add a note to an idea. Capture thoughts and observations during exploration.",
|
|
3376
|
+
{
|
|
3377
|
+
note: c.string(),
|
|
3378
|
+
path: c.string().optional()
|
|
3379
|
+
}
|
|
3380
|
+
), n(
|
|
3381
|
+
"riotplan_idea_add_constraint",
|
|
3382
|
+
"Add a constraint to an idea. Document limitations and requirements.",
|
|
3383
|
+
{
|
|
3384
|
+
constraint: c.string(),
|
|
3385
|
+
path: c.string().optional()
|
|
3386
|
+
}
|
|
3387
|
+
), n(
|
|
3388
|
+
"riotplan_idea_add_question",
|
|
3389
|
+
"Add a question to an idea. Raise uncertainties that need resolution.",
|
|
3390
|
+
{
|
|
3391
|
+
question: c.string(),
|
|
3392
|
+
path: c.string().optional()
|
|
3393
|
+
}
|
|
3394
|
+
), n(
|
|
3395
|
+
"riotplan_idea_add_evidence",
|
|
3396
|
+
"Add evidence to an idea. Attach supporting materials like diagrams, documents, or examples.",
|
|
3397
|
+
{
|
|
3398
|
+
evidencePath: c.string(),
|
|
3399
|
+
description: c.string(),
|
|
3400
|
+
path: c.string().optional()
|
|
3401
|
+
}
|
|
3402
|
+
), n(
|
|
3403
|
+
"riotplan_idea_add_narrative",
|
|
3404
|
+
"Add raw narrative content to the timeline. Use this to capture conversational context, thinking-out-loud, or any free-form input that doesn't fit structured categories. Narrative chunks preserve full-fidelity context.",
|
|
3405
|
+
{
|
|
3406
|
+
content: c.string(),
|
|
3407
|
+
path: c.string().optional(),
|
|
3408
|
+
source: c.enum(["typing", "voice", "paste", "import"]).optional(),
|
|
3409
|
+
context: c.string().optional(),
|
|
3410
|
+
speaker: c.string().optional()
|
|
3411
|
+
}
|
|
3412
|
+
), n(
|
|
3413
|
+
"riotplan_idea_kill",
|
|
3414
|
+
"Kill an idea. Abandon the idea with a reason, preserving the learning.",
|
|
3415
|
+
{
|
|
3416
|
+
reason: c.string(),
|
|
3417
|
+
path: c.string().optional()
|
|
3418
|
+
}
|
|
3419
|
+
), n(
|
|
3420
|
+
"riotplan_shaping_start",
|
|
3421
|
+
"Start shaping an idea. Move from Idea to Shaping stage to explore approaches.",
|
|
3422
|
+
{
|
|
3423
|
+
path: c.string().optional()
|
|
3424
|
+
}
|
|
3425
|
+
), n(
|
|
3426
|
+
"riotplan_shaping_add_approach",
|
|
3427
|
+
"Add an approach to consider. Propose a way to solve the problem with explicit tradeoffs.",
|
|
3428
|
+
{
|
|
3429
|
+
name: c.string(),
|
|
3430
|
+
description: c.string(),
|
|
3431
|
+
tradeoffs: c.array(c.string()),
|
|
3432
|
+
assumptions: c.array(c.string()).optional(),
|
|
3433
|
+
path: c.string().optional()
|
|
3434
|
+
}
|
|
3435
|
+
), n(
|
|
3436
|
+
"riotplan_shaping_add_feedback",
|
|
3437
|
+
"Add feedback on an approach. Provide observations, concerns, or suggestions.",
|
|
3438
|
+
{
|
|
3439
|
+
approach: c.string(),
|
|
3440
|
+
feedback: c.string(),
|
|
3441
|
+
path: c.string().optional()
|
|
3442
|
+
}
|
|
3443
|
+
), n(
|
|
3444
|
+
"riotplan_shaping_add_evidence",
|
|
3445
|
+
"Add evidence for an approach. Attach supporting materials that inform the decision.",
|
|
3446
|
+
{
|
|
3447
|
+
approach: c.string(),
|
|
3448
|
+
evidencePath: c.string(),
|
|
3449
|
+
description: c.string(),
|
|
3450
|
+
path: c.string().optional()
|
|
3451
|
+
}
|
|
3452
|
+
), n(
|
|
3453
|
+
"riotplan_shaping_compare",
|
|
3454
|
+
"Compare all approaches. Generate a side-by-side comparison of tradeoffs.",
|
|
3455
|
+
{
|
|
3456
|
+
path: c.string().optional()
|
|
3457
|
+
}
|
|
3458
|
+
), n(
|
|
3459
|
+
"riotplan_shaping_select",
|
|
3460
|
+
"Select an approach. Choose the best approach and move to Built stage.",
|
|
3461
|
+
{
|
|
3462
|
+
approach: c.string(),
|
|
3463
|
+
reason: c.string(),
|
|
3464
|
+
path: c.string().optional()
|
|
3465
|
+
}
|
|
3466
|
+
), n(
|
|
3467
|
+
"riotplan_checkpoint_create",
|
|
3468
|
+
"Create a checkpoint. Save a snapshot of the current state with prompt context.",
|
|
3469
|
+
{
|
|
3470
|
+
name: c.string(),
|
|
3471
|
+
message: c.string(),
|
|
3472
|
+
path: c.string().optional()
|
|
3473
|
+
}
|
|
3474
|
+
), n(
|
|
3475
|
+
"riotplan_checkpoint_list",
|
|
3476
|
+
"List all checkpoints. Show all saved checkpoints with timestamps.",
|
|
3477
|
+
{
|
|
3478
|
+
path: c.string().optional()
|
|
3479
|
+
}
|
|
3480
|
+
), n(
|
|
3481
|
+
"riotplan_checkpoint_show",
|
|
3482
|
+
"Show checkpoint details. Display the full checkpoint snapshot and prompt context.",
|
|
3483
|
+
{
|
|
3484
|
+
checkpoint: c.string(),
|
|
3485
|
+
path: c.string().optional()
|
|
3486
|
+
}
|
|
3487
|
+
), n(
|
|
3488
|
+
"riotplan_checkpoint_restore",
|
|
3489
|
+
"Restore a checkpoint. Revert to a previous state.",
|
|
3490
|
+
{
|
|
3491
|
+
checkpoint: c.string(),
|
|
3492
|
+
path: c.string().optional()
|
|
3493
|
+
}
|
|
3494
|
+
), n(
|
|
3495
|
+
"riotplan_history_show",
|
|
3496
|
+
"Show ideation history. Display the complete timeline of events.",
|
|
3497
|
+
{
|
|
3498
|
+
path: c.string().optional(),
|
|
3499
|
+
limit: c.number().optional(),
|
|
3500
|
+
sinceCheckpoint: c.string().optional()
|
|
3501
|
+
}
|
|
3502
|
+
);
|
|
3503
|
+
const t = Tn();
|
|
3504
|
+
for (const a of t)
|
|
3505
|
+
e.resource(
|
|
3506
|
+
a.name,
|
|
3507
|
+
a.uri,
|
|
3508
|
+
{
|
|
3509
|
+
description: a.description || ""
|
|
3510
|
+
},
|
|
3511
|
+
async () => {
|
|
3512
|
+
const i = await Fn(a.uri);
|
|
3513
|
+
return {
|
|
3514
|
+
contents: [{
|
|
3515
|
+
uri: a.uri,
|
|
3516
|
+
mimeType: a.mimeType || "application/json",
|
|
3517
|
+
text: JSON.stringify(i, null, 2)
|
|
3518
|
+
}]
|
|
3519
|
+
};
|
|
3520
|
+
}
|
|
3521
|
+
);
|
|
3522
|
+
const s = we();
|
|
3523
|
+
for (const a of s) {
|
|
3524
|
+
const i = {};
|
|
3525
|
+
if (a.arguments)
|
|
3526
|
+
for (const o of a.arguments)
|
|
3527
|
+
i[o.name] = o.required ? c.string() : c.string().optional();
|
|
3528
|
+
e.prompt(
|
|
3529
|
+
a.name,
|
|
3530
|
+
a.description,
|
|
3531
|
+
i,
|
|
3532
|
+
async (o, p) => {
|
|
3533
|
+
const d = {};
|
|
3534
|
+
for (const [f, m] of Object.entries(o))
|
|
3535
|
+
typeof m == "string" && (d[f] = m);
|
|
3536
|
+
return {
|
|
3537
|
+
messages: (await Ln(a.name, d)).map((f) => f.content.type === "text" ? {
|
|
3538
|
+
role: f.role,
|
|
3539
|
+
content: {
|
|
3540
|
+
type: "text",
|
|
3541
|
+
text: f.content.text || ""
|
|
3542
|
+
}
|
|
3543
|
+
} : f)
|
|
3544
|
+
};
|
|
3545
|
+
}
|
|
3546
|
+
);
|
|
3547
|
+
}
|
|
3548
|
+
const r = new ve();
|
|
3549
|
+
await e.connect(r);
|
|
3550
|
+
}
|
|
3551
|
+
Mn().catch((e) => {
|
|
3552
|
+
process.exit(1);
|
|
3553
|
+
});
|