@isaacriehm/cairn-core 0.9.7 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/hooks/runners/context-threshold.js +37 -1
- package/dist/hooks/runners/context-threshold.js.map +1 -1
- package/dist/hooks/runners/stop.js +109 -0
- package/dist/hooks/runners/stop.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/errors.d.ts +1 -1
- package/dist/mcp/errors.js.map +1 -1
- package/dist/mcp/schemas.d.ts +101 -0
- package/dist/mcp/schemas.js +92 -0
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/tools/index.js +19 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/mission-accept-draft.d.ts +16 -0
- package/dist/mcp/tools/mission-accept-draft.js +102 -0
- package/dist/mcp/tools/mission-accept-draft.js.map +1 -0
- package/dist/mcp/tools/mission-advance.d.ts +8 -0
- package/dist/mcp/tools/mission-advance.js +124 -0
- package/dist/mcp/tools/mission-advance.js.map +1 -0
- package/dist/mcp/tools/mission-close.d.ts +8 -0
- package/dist/mcp/tools/mission-close.js +48 -0
- package/dist/mcp/tools/mission-close.js.map +1 -0
- package/dist/mcp/tools/mission-get.d.ts +6 -0
- package/dist/mcp/tools/mission-get.js +64 -0
- package/dist/mcp/tools/mission-get.js.map +1 -0
- package/dist/mcp/tools/mission-reopen.d.ts +13 -0
- package/dist/mcp/tools/mission-reopen.js +56 -0
- package/dist/mcp/tools/mission-reopen.js.map +1 -0
- package/dist/mcp/tools/mission-resume.d.ts +15 -0
- package/dist/mcp/tools/mission-resume.js +219 -0
- package/dist/mcp/tools/mission-resume.js.map +1 -0
- package/dist/mcp/tools/mission-resync-accept.d.ts +19 -0
- package/dist/mcp/tools/mission-resync-accept.js +192 -0
- package/dist/mcp/tools/mission-resync-accept.js.map +1 -0
- package/dist/mcp/tools/mission-resync.d.ts +20 -0
- package/dist/mcp/tools/mission-resync.js +113 -0
- package/dist/mcp/tools/mission-resync.js.map +1 -0
- package/dist/mcp/tools/mission-start.d.ts +8 -0
- package/dist/mcp/tools/mission-start.js +76 -0
- package/dist/mcp/tools/mission-start.js.map +1 -0
- package/dist/mcp/tools/resolve-attention.js +62 -1
- package/dist/mcp/tools/resolve-attention.js.map +1 -1
- package/dist/mcp/tools/task-create.d.ts +2 -0
- package/dist/mcp/tools/task-create.js +40 -2
- package/dist/mcp/tools/task-create.js.map +1 -1
- package/dist/missions/cli.d.ts +106 -0
- package/dist/missions/cli.js +279 -0
- package/dist/missions/cli.js.map +1 -0
- package/dist/missions/cursor.d.ts +40 -0
- package/dist/missions/cursor.js +99 -0
- package/dist/missions/cursor.js.map +1 -0
- package/dist/missions/draft.d.ts +28 -0
- package/dist/missions/draft.js +112 -0
- package/dist/missions/draft.js.map +1 -0
- package/dist/missions/index.d.ts +9 -0
- package/dist/missions/index.js +10 -0
- package/dist/missions/index.js.map +1 -0
- package/dist/missions/task-link.d.ts +51 -0
- package/dist/missions/task-link.js +155 -0
- package/dist/missions/task-link.js.map +1 -0
- package/dist/session-start/build.d.ts +1 -1
- package/dist/session-start/build.js +58 -1
- package/dist/session-start/build.js.map +1 -1
- package/dist/status-line/format.d.ts +15 -1
- package/dist/status-line/format.js +12 -1
- package/dist/status-line/format.js.map +1 -1
- package/dist/status-line/index.d.ts +1 -1
- package/dist/status-line/index.js +1 -1
- package/dist/status-line/index.js.map +1 -1
- package/dist/status-line/reader.js +33 -2
- package/dist/status-line/reader.js.map +1 -1
- package/dist/tasks/lifecycle.js +11 -0
- package/dist/tasks/lifecycle.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI wrappers around the mission MCP tools — `cairn mission ...`
|
|
3
|
+
* subcommands. Reuses the helper modules (cursor, draft, task-link)
|
|
4
|
+
* directly so the CLI stays in lock-step with the MCP surface.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { isAbsolute, resolve as pathResolve } from "node:path";
|
|
8
|
+
import { appendMissionJournal, archiveMission, countDonePhases, deriveMissionId, detectRoadmapDrift, findActiveMission, initialPhaseProgress, listActiveMissionIds, listDoneMissionIds, locateMission, nextPendingPhase, readMissionState, readRoadmap, restoreMission, writeMissionSpec, writeMissionState, writeRoadmap, } from "@isaacriehm/cairn-state";
|
|
9
|
+
import { advancePhase } from "./cursor.js";
|
|
10
|
+
import { draftRoadmapFromSpec, stubRoadmap } from "./draft.js";
|
|
11
|
+
export async function runMissionStart(args) {
|
|
12
|
+
if (findActiveMission(args.repoRoot) !== null) {
|
|
13
|
+
throw new Error("An active mission already exists; close or abort it before starting another.");
|
|
14
|
+
}
|
|
15
|
+
const abs = isAbsolute(args.specPath) ? args.specPath : pathResolve(args.repoRoot, args.specPath);
|
|
16
|
+
if (!abs.startsWith(args.repoRoot)) {
|
|
17
|
+
throw new Error(`${args.specPath} resolves outside the repo`);
|
|
18
|
+
}
|
|
19
|
+
if (!existsSync(abs)) {
|
|
20
|
+
throw new Error(`Spec doc not found: ${args.specPath}`);
|
|
21
|
+
}
|
|
22
|
+
const source = readFileSync(abs, "utf8");
|
|
23
|
+
const proposedTitle = deriveTitleFromSpec(source, args.specPath);
|
|
24
|
+
if (args.noLlm === true) {
|
|
25
|
+
return {
|
|
26
|
+
proposed_title: proposedTitle,
|
|
27
|
+
spec_path: args.specPath,
|
|
28
|
+
exit_gate: args.exitGate,
|
|
29
|
+
phases: stubRoadmap(),
|
|
30
|
+
llm_used: false,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const draft = await draftRoadmapFromSpec({
|
|
34
|
+
repoRoot: args.repoRoot,
|
|
35
|
+
spec: source,
|
|
36
|
+
specPath: args.specPath,
|
|
37
|
+
});
|
|
38
|
+
if (draft === null) {
|
|
39
|
+
throw new Error("Haiku failed to parse the spec doc; retry or pass --no-llm");
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
proposed_title: proposedTitle,
|
|
43
|
+
spec_path: args.specPath,
|
|
44
|
+
exit_gate: args.exitGate,
|
|
45
|
+
phases: draft.phases,
|
|
46
|
+
llm_used: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function runMissionAccept(args) {
|
|
50
|
+
if (findActiveMission(args.repoRoot) !== null) {
|
|
51
|
+
throw new Error("An active mission already exists; close or abort it before starting another.");
|
|
52
|
+
}
|
|
53
|
+
const abs = isAbsolute(args.specPath) ? args.specPath : pathResolve(args.repoRoot, args.specPath);
|
|
54
|
+
if (!existsSync(abs)) {
|
|
55
|
+
throw new Error(`Spec doc not found: ${args.specPath}`);
|
|
56
|
+
}
|
|
57
|
+
const startedAt = new Date().toISOString();
|
|
58
|
+
const missionId = deriveMissionId({ title: args.title, spec_path: args.specPath, started_at: startedAt });
|
|
59
|
+
const frontmatter = {
|
|
60
|
+
mission_id: missionId,
|
|
61
|
+
title: args.title,
|
|
62
|
+
spec_path: args.specPath,
|
|
63
|
+
created_at: startedAt,
|
|
64
|
+
exit_gate: args.exitGate,
|
|
65
|
+
phases: args.phases,
|
|
66
|
+
};
|
|
67
|
+
writeRoadmap(args.repoRoot, missionId, frontmatter, `# Mission — ${args.title}\n\nSpec: \`${args.specPath}\`.\n`);
|
|
68
|
+
writeMissionSpec(args.repoRoot, missionId, readFileSync(abs, "utf8"));
|
|
69
|
+
const phaseProgress = initialPhaseProgress(frontmatter);
|
|
70
|
+
const firstPhase = nextPendingPhase(frontmatter, {
|
|
71
|
+
mission_id: missionId,
|
|
72
|
+
started_at: startedAt,
|
|
73
|
+
cursor: { active_phase: null, active_phase_started_at: null },
|
|
74
|
+
phase_progress: phaseProgress,
|
|
75
|
+
outcome: "active",
|
|
76
|
+
});
|
|
77
|
+
if (firstPhase !== null) {
|
|
78
|
+
phaseProgress[firstPhase.id] = { state: "in_progress", task_ids: [] };
|
|
79
|
+
}
|
|
80
|
+
writeMissionState(args.repoRoot, missionId, {
|
|
81
|
+
mission_id: missionId,
|
|
82
|
+
started_at: startedAt,
|
|
83
|
+
cursor: {
|
|
84
|
+
active_phase: firstPhase?.id ?? null,
|
|
85
|
+
active_phase_started_at: firstPhase !== null ? startedAt : null,
|
|
86
|
+
},
|
|
87
|
+
phase_progress: phaseProgress,
|
|
88
|
+
outcome: "active",
|
|
89
|
+
});
|
|
90
|
+
appendMissionJournal(args.repoRoot, missionId, {
|
|
91
|
+
ts: startedAt,
|
|
92
|
+
kind: "started",
|
|
93
|
+
detail: `${args.phases.length} phases, exit_gate=${args.exitGate}`,
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
mission_id: missionId,
|
|
97
|
+
cursor: { active_phase: firstPhase?.id ?? null },
|
|
98
|
+
total_phases: args.phases.length,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export function runMissionGet(repoRoot) {
|
|
102
|
+
const id = findActiveMission(repoRoot);
|
|
103
|
+
if (id === null)
|
|
104
|
+
return { active: false };
|
|
105
|
+
const roadmap = readRoadmap(repoRoot, id);
|
|
106
|
+
const state = readMissionState(repoRoot, id);
|
|
107
|
+
if (roadmap === null || state === null)
|
|
108
|
+
return { active: false };
|
|
109
|
+
return {
|
|
110
|
+
active: true,
|
|
111
|
+
mission_id: id,
|
|
112
|
+
title: roadmap.frontmatter.title,
|
|
113
|
+
cursor: { active_phase: state.cursor.active_phase },
|
|
114
|
+
progress: { done: countDonePhases(state), total: roadmap.frontmatter.phases.length },
|
|
115
|
+
drift_phase_ids: detectRoadmapDrift(roadmap.frontmatter, state),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function runMissionAdvance(args) {
|
|
119
|
+
const missionId = findActiveMission(args.repoRoot);
|
|
120
|
+
if (missionId === null)
|
|
121
|
+
throw new Error("No active mission");
|
|
122
|
+
const state = readMissionState(args.repoRoot, missionId);
|
|
123
|
+
if (state === null)
|
|
124
|
+
throw new Error(`state.json missing for ${missionId}`);
|
|
125
|
+
const roadmap = readRoadmap(args.repoRoot, missionId);
|
|
126
|
+
if (roadmap === null)
|
|
127
|
+
throw new Error(`roadmap.md missing for ${missionId}`);
|
|
128
|
+
if (args.drop === true) {
|
|
129
|
+
if (roadmap.frontmatter.phases.some((p) => p.id === args.phaseId)) {
|
|
130
|
+
throw new Error(`phase ${args.phaseId} is still in roadmap.md; --drop only resolves drifted ids`);
|
|
131
|
+
}
|
|
132
|
+
const progress = state.phase_progress[args.phaseId];
|
|
133
|
+
if (progress === undefined) {
|
|
134
|
+
throw new Error(`phase ${args.phaseId} not present in phase_progress`);
|
|
135
|
+
}
|
|
136
|
+
const taskIds = progress.task_ids;
|
|
137
|
+
delete state.phase_progress[args.phaseId];
|
|
138
|
+
writeMissionState(args.repoRoot, missionId, state);
|
|
139
|
+
appendMissionJournal(args.repoRoot, missionId, {
|
|
140
|
+
ts: new Date().toISOString(),
|
|
141
|
+
kind: "drift-detected",
|
|
142
|
+
phase_id: args.phaseId,
|
|
143
|
+
detail: `dropped — ${taskIds.length} graduated task(s) orphaned`,
|
|
144
|
+
});
|
|
145
|
+
return { kind: "dropped", phase_id: args.phaseId, orphaned_task_ids: taskIds };
|
|
146
|
+
}
|
|
147
|
+
if (args.force !== true) {
|
|
148
|
+
const progress = state.phase_progress[args.phaseId];
|
|
149
|
+
if (progress === undefined || progress.task_ids.length === 0) {
|
|
150
|
+
throw new Error(`phase ${args.phaseId} has no linked tasks; pass --force to advance`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const r = advancePhase(args.repoRoot, missionId, args.phaseId);
|
|
154
|
+
if (!r.ok)
|
|
155
|
+
throw new Error(r.message);
|
|
156
|
+
return {
|
|
157
|
+
kind: "advanced",
|
|
158
|
+
phase_advanced: r.phase_advanced,
|
|
159
|
+
next_phase: r.next_phase?.id ?? null,
|
|
160
|
+
closed: r.closed,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export function runMissionClose(repoRoot, missionId, outcome, reason) {
|
|
164
|
+
if (locateMission(repoRoot, missionId) !== "active") {
|
|
165
|
+
throw new Error(`Mission ${missionId} is not active`);
|
|
166
|
+
}
|
|
167
|
+
const state = readMissionState(repoRoot, missionId);
|
|
168
|
+
if (state === null)
|
|
169
|
+
throw new Error(`state.json missing for ${missionId}`);
|
|
170
|
+
const closedAt = new Date().toISOString();
|
|
171
|
+
state.outcome = outcome;
|
|
172
|
+
state.cursor.active_phase = null;
|
|
173
|
+
state.cursor.active_phase_started_at = null;
|
|
174
|
+
state.closed_at = closedAt;
|
|
175
|
+
if (outcome === "aborted" && reason !== undefined)
|
|
176
|
+
state.abort_reason = reason;
|
|
177
|
+
writeMissionState(repoRoot, missionId, state);
|
|
178
|
+
appendMissionJournal(repoRoot, missionId, {
|
|
179
|
+
ts: closedAt,
|
|
180
|
+
kind: "closed",
|
|
181
|
+
detail: outcome === "aborted" ? `aborted${reason !== undefined ? `: ${reason}` : ""}` : "manual close",
|
|
182
|
+
});
|
|
183
|
+
archiveMission(repoRoot, missionId);
|
|
184
|
+
return { mission_id: missionId, outcome, closed_at: closedAt };
|
|
185
|
+
}
|
|
186
|
+
export function runMissionReopen(repoRoot, missionId) {
|
|
187
|
+
if (locateMission(repoRoot, missionId) !== "done") {
|
|
188
|
+
throw new Error(`Mission ${missionId} is not archived`);
|
|
189
|
+
}
|
|
190
|
+
if (findActiveMission(repoRoot) !== null) {
|
|
191
|
+
throw new Error("Another mission is already active");
|
|
192
|
+
}
|
|
193
|
+
if (!restoreMission(repoRoot, missionId)) {
|
|
194
|
+
throw new Error(`Could not restore archived dirs for ${missionId}`);
|
|
195
|
+
}
|
|
196
|
+
const state = readMissionState(repoRoot, missionId);
|
|
197
|
+
const reopenedAt = new Date().toISOString();
|
|
198
|
+
if (state !== null) {
|
|
199
|
+
state.outcome = "active";
|
|
200
|
+
delete state.closed_at;
|
|
201
|
+
delete state.abort_reason;
|
|
202
|
+
writeMissionState(repoRoot, missionId, state);
|
|
203
|
+
}
|
|
204
|
+
appendMissionJournal(repoRoot, missionId, {
|
|
205
|
+
ts: reopenedAt,
|
|
206
|
+
kind: "reopened",
|
|
207
|
+
detail: `cursor: ${state?.cursor.active_phase ?? "(none)"}`,
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
mission_id: missionId,
|
|
211
|
+
cursor: state?.cursor ?? null,
|
|
212
|
+
reopened_at: reopenedAt,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export function listMissions(repoRoot) {
|
|
216
|
+
return {
|
|
217
|
+
active: listActiveMissionIds(repoRoot),
|
|
218
|
+
done: listDoneMissionIds(repoRoot),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function deriveTitleFromSpec(source, fallback) {
|
|
222
|
+
const m = source.match(/^#\s+(.+?)\s*$/m);
|
|
223
|
+
const raw = m?.[1] ?? fallback.replace(/^.*\//, "").replace(/\.[a-z]+$/i, "");
|
|
224
|
+
return raw.slice(0, 60);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Pretty-print a roadmap to a string for `cairn mission start --print`
|
|
228
|
+
* preview output. Matches the YAML-frontmatter shape Cairn writes to
|
|
229
|
+
* disk so the operator can copy + edit it before approval.
|
|
230
|
+
*/
|
|
231
|
+
export function previewRoadmap(args) {
|
|
232
|
+
const lines = [];
|
|
233
|
+
lines.push(`# Mission preview — ${args.title}`);
|
|
234
|
+
lines.push("");
|
|
235
|
+
lines.push(`spec_path: ${args.specPath}`);
|
|
236
|
+
lines.push(`exit_gate: ${args.exitGate}`);
|
|
237
|
+
lines.push("");
|
|
238
|
+
lines.push("Phases:");
|
|
239
|
+
for (const p of args.phases) {
|
|
240
|
+
lines.push(` - ${p.id}: ${p.title}`);
|
|
241
|
+
if (p.depends_on.length > 0)
|
|
242
|
+
lines.push(` depends_on: ${p.depends_on.join(", ")}`);
|
|
243
|
+
lines.push(` exit_criteria: ${p.exit_criteria}`);
|
|
244
|
+
}
|
|
245
|
+
return lines.join("\n");
|
|
246
|
+
}
|
|
247
|
+
/** Used by `cairn mission accept --from <file>` to load a hand-edited roadmap draft. */
|
|
248
|
+
export function loadDraftFromFile(path) {
|
|
249
|
+
if (!existsSync(path))
|
|
250
|
+
throw new Error(`Draft file not found: ${path}`);
|
|
251
|
+
const raw = readFileSync(path, "utf8");
|
|
252
|
+
const parsed = JSON.parse(raw);
|
|
253
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
254
|
+
throw new Error("Draft file must be a JSON object");
|
|
255
|
+
const obj = parsed;
|
|
256
|
+
if (typeof obj["title"] !== "string")
|
|
257
|
+
throw new Error("Draft missing title");
|
|
258
|
+
if (typeof obj["spec_path"] !== "string")
|
|
259
|
+
throw new Error("Draft missing spec_path");
|
|
260
|
+
if (typeof obj["exit_gate"] !== "string")
|
|
261
|
+
throw new Error("Draft missing exit_gate");
|
|
262
|
+
if (!Array.isArray(obj["phases"]))
|
|
263
|
+
throw new Error("Draft missing phases array");
|
|
264
|
+
const exitGate = obj["exit_gate"];
|
|
265
|
+
if (exitGate !== "prompt" && exitGate !== "auto" && exitGate !== "manual") {
|
|
266
|
+
throw new Error(`Invalid exit_gate: ${exitGate}`);
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
title: obj["title"],
|
|
270
|
+
spec_path: obj["spec_path"],
|
|
271
|
+
exit_gate: exitGate,
|
|
272
|
+
phases: obj["phases"],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/** Persist the proposed roadmap draft to a temp JSON file for hand-editing. */
|
|
276
|
+
export function writeDraftToFile(path, draft) {
|
|
277
|
+
writeFileSync(path, JSON.stringify(draft, null, 2) + "\n", "utf8");
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/missions/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission cursor advance helpers — shared logic between the explicit
|
|
3
|
+
* `cairn_mission_advance` MCP tool, the Stop hook auto-advance path
|
|
4
|
+
* (exit_gate=auto), and the Stop hook prompt path (exit_gate=prompt
|
|
5
|
+
* after operator picks `a`).
|
|
6
|
+
*/
|
|
7
|
+
import { type MissionPhase, type MissionRoadmapFrontmatter, type MissionState } from "@isaacriehm/cairn-state";
|
|
8
|
+
export interface AdvanceResult {
|
|
9
|
+
ok: true;
|
|
10
|
+
phase_advanced: string;
|
|
11
|
+
next_phase: MissionPhase | null;
|
|
12
|
+
/** True when this advance closed the mission. */
|
|
13
|
+
closed: boolean;
|
|
14
|
+
donePhases: number;
|
|
15
|
+
totalPhases: number;
|
|
16
|
+
}
|
|
17
|
+
export interface AdvanceError {
|
|
18
|
+
ok: false;
|
|
19
|
+
code: "MISSION_NOT_FOUND" | "PHASE_NOT_FOUND" | "PHASE_ALREADY_DONE" | "ROADMAP_MISSING" | "STATE_MISSING";
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Mark `phaseId` as done in `phase_progress` and pick the next pending
|
|
24
|
+
* phase whose `depends_on` set is satisfied. When no eligible phase
|
|
25
|
+
* remains, set `cursor.active_phase = null`, mark `outcome: done`, and
|
|
26
|
+
* archive the mission dirs.
|
|
27
|
+
*/
|
|
28
|
+
export declare function advancePhase(repoRoot: string, missionId: string, phaseId: string, now?: Date): AdvanceResult | AdvanceError;
|
|
29
|
+
/**
|
|
30
|
+
* Determine whether every linked task on a phase has graduated.
|
|
31
|
+
* Returns `false` when the phase has zero tasks (the operator has to
|
|
32
|
+
* `mission_advance --force` for empty phases — never auto-advance an
|
|
33
|
+
* empty phase silently).
|
|
34
|
+
*/
|
|
35
|
+
export declare function allPhaseTasksDone(state: MissionState, phaseId: string, taskIsDone: (taskId: string) => boolean): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a roadmap phase by id from a mission's roadmap. Returns null
|
|
38
|
+
* when the id was deleted in a mid-mission roadmap edit (drift case).
|
|
39
|
+
*/
|
|
40
|
+
export declare function lookupPhase(roadmap: MissionRoadmapFrontmatter, phaseId: string): MissionPhase | null;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission cursor advance helpers — shared logic between the explicit
|
|
3
|
+
* `cairn_mission_advance` MCP tool, the Stop hook auto-advance path
|
|
4
|
+
* (exit_gate=auto), and the Stop hook prompt path (exit_gate=prompt
|
|
5
|
+
* after operator picks `a`).
|
|
6
|
+
*/
|
|
7
|
+
import { appendMissionJournal, archiveMission, countDonePhases, nextPendingPhase, readMissionState, readRoadmap, writeMissionState, } from "@isaacriehm/cairn-state";
|
|
8
|
+
/**
|
|
9
|
+
* Mark `phaseId` as done in `phase_progress` and pick the next pending
|
|
10
|
+
* phase whose `depends_on` set is satisfied. When no eligible phase
|
|
11
|
+
* remains, set `cursor.active_phase = null`, mark `outcome: done`, and
|
|
12
|
+
* archive the mission dirs.
|
|
13
|
+
*/
|
|
14
|
+
export function advancePhase(repoRoot, missionId, phaseId, now = new Date()) {
|
|
15
|
+
const roadmap = readRoadmap(repoRoot, missionId);
|
|
16
|
+
if (roadmap === null) {
|
|
17
|
+
return { ok: false, code: "ROADMAP_MISSING", message: `roadmap.md missing for ${missionId}` };
|
|
18
|
+
}
|
|
19
|
+
const state = readMissionState(repoRoot, missionId);
|
|
20
|
+
if (state === null) {
|
|
21
|
+
return { ok: false, code: "STATE_MISSING", message: `state.json missing for ${missionId}` };
|
|
22
|
+
}
|
|
23
|
+
const phaseDef = roadmap.frontmatter.phases.find((p) => p.id === phaseId);
|
|
24
|
+
if (phaseDef === undefined) {
|
|
25
|
+
return { ok: false, code: "PHASE_NOT_FOUND", message: `phase ${phaseId} not in roadmap` };
|
|
26
|
+
}
|
|
27
|
+
const progress = state.phase_progress[phaseId];
|
|
28
|
+
if (progress?.state === "done") {
|
|
29
|
+
return { ok: false, code: "PHASE_ALREADY_DONE", message: `phase ${phaseId} already done` };
|
|
30
|
+
}
|
|
31
|
+
const ts = now.toISOString();
|
|
32
|
+
state.phase_progress[phaseId] = {
|
|
33
|
+
state: "done",
|
|
34
|
+
task_ids: progress?.task_ids ?? [],
|
|
35
|
+
graduated_at: ts,
|
|
36
|
+
};
|
|
37
|
+
const next = nextPendingPhase(roadmap.frontmatter, state);
|
|
38
|
+
if (next !== null) {
|
|
39
|
+
state.cursor.active_phase = next.id;
|
|
40
|
+
state.cursor.active_phase_started_at = ts;
|
|
41
|
+
state.phase_progress[next.id] = {
|
|
42
|
+
state: "in_progress",
|
|
43
|
+
task_ids: state.phase_progress[next.id]?.task_ids ?? [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
state.cursor.active_phase = null;
|
|
48
|
+
state.cursor.active_phase_started_at = null;
|
|
49
|
+
state.outcome = "done";
|
|
50
|
+
state.closed_at = ts;
|
|
51
|
+
}
|
|
52
|
+
writeMissionState(repoRoot, missionId, state);
|
|
53
|
+
appendMissionJournal(repoRoot, missionId, {
|
|
54
|
+
ts,
|
|
55
|
+
kind: "phase-advanced",
|
|
56
|
+
phase_id: phaseId,
|
|
57
|
+
detail: next !== null ? `next: ${next.id}` : "mission complete",
|
|
58
|
+
});
|
|
59
|
+
let closed = false;
|
|
60
|
+
if (next === null) {
|
|
61
|
+
appendMissionJournal(repoRoot, missionId, {
|
|
62
|
+
ts,
|
|
63
|
+
kind: "closed",
|
|
64
|
+
detail: "auto-close on last phase complete",
|
|
65
|
+
});
|
|
66
|
+
archiveMission(repoRoot, missionId);
|
|
67
|
+
closed = true;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
ok: true,
|
|
71
|
+
phase_advanced: phaseId,
|
|
72
|
+
next_phase: next,
|
|
73
|
+
closed,
|
|
74
|
+
donePhases: countDonePhases(state),
|
|
75
|
+
totalPhases: roadmap.frontmatter.phases.length,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Determine whether every linked task on a phase has graduated.
|
|
80
|
+
* Returns `false` when the phase has zero tasks (the operator has to
|
|
81
|
+
* `mission_advance --force` for empty phases — never auto-advance an
|
|
82
|
+
* empty phase silently).
|
|
83
|
+
*/
|
|
84
|
+
export function allPhaseTasksDone(state, phaseId, taskIsDone) {
|
|
85
|
+
const progress = state.phase_progress[phaseId];
|
|
86
|
+
if (progress === undefined)
|
|
87
|
+
return false;
|
|
88
|
+
if (progress.task_ids.length === 0)
|
|
89
|
+
return false;
|
|
90
|
+
return progress.task_ids.every(taskIsDone);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Resolve a roadmap phase by id from a mission's roadmap. Returns null
|
|
94
|
+
* when the id was deleted in a mid-mission roadmap edit (drift case).
|
|
95
|
+
*/
|
|
96
|
+
export function lookupPhase(roadmap, phaseId) {
|
|
97
|
+
return roadmap.phases.find((p) => p.id === phaseId) ?? null;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/missions/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission roadmap drafting — Haiku call that turns a planning doc into
|
|
3
|
+
* an ordered phase array. One LLM-cost touchpoint per mission
|
|
4
|
+
* lifecycle. All subsequent phase advance / linking is deterministic.
|
|
5
|
+
*
|
|
6
|
+
* The model receives ONLY the spec doc + a tight system prompt; no
|
|
7
|
+
* project ground state, no MCP tools, no ambient CLAUDE.md hierarchy.
|
|
8
|
+
* `isolateAmbientContext: true` enforces that.
|
|
9
|
+
*/
|
|
10
|
+
import type { MissionPhase } from "@isaacriehm/cairn-state";
|
|
11
|
+
export interface DraftRoadmapArgs {
|
|
12
|
+
repoRoot: string;
|
|
13
|
+
spec: string;
|
|
14
|
+
specPath: string;
|
|
15
|
+
}
|
|
16
|
+
export interface DraftRoadmapResult {
|
|
17
|
+
phases: MissionPhase[];
|
|
18
|
+
/** Char count of the spec slice actually fed to Haiku. */
|
|
19
|
+
spec_chars_used: number;
|
|
20
|
+
/** True when the spec was truncated to fit MAX_SPEC_CHARS. */
|
|
21
|
+
truncated: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function draftRoadmapFromSpec(args: DraftRoadmapArgs): Promise<DraftRoadmapResult | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Single-phase fallback used when `no_llm: true` or Haiku is offline.
|
|
26
|
+
* Lets the operator hand-edit roadmap.md before approving.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stubRoadmap(): MissionPhase[];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission roadmap drafting — Haiku call that turns a planning doc into
|
|
3
|
+
* an ordered phase array. One LLM-cost touchpoint per mission
|
|
4
|
+
* lifecycle. All subsequent phase advance / linking is deterministic.
|
|
5
|
+
*
|
|
6
|
+
* The model receives ONLY the spec doc + a tight system prompt; no
|
|
7
|
+
* project ground state, no MCP tools, no ambient CLAUDE.md hierarchy.
|
|
8
|
+
* `isolateAmbientContext: true` enforces that.
|
|
9
|
+
*/
|
|
10
|
+
import { runClaude } from "../claude/index.js";
|
|
11
|
+
import { logger } from "../logger.js";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
const log = logger("mission.draft");
|
|
14
|
+
const TIMEOUT_MS = 180_000;
|
|
15
|
+
const MAX_SPEC_CHARS = 60_000;
|
|
16
|
+
const MAX_PHASES = 24;
|
|
17
|
+
const SYSTEM_PROMPT = `You parse a software-project planning document into an ordered list of implementation phases.
|
|
18
|
+
|
|
19
|
+
Return STRICT JSON matching the schema. No prose, no markdown.
|
|
20
|
+
|
|
21
|
+
Phase rules:
|
|
22
|
+
- Each phase id is kebab-case, prefixed by an ordinal (e.g. "phase-1-schema", "phase-2-jwt"). Lowercase ASCII letters, digits, hyphens only.
|
|
23
|
+
- title is a tight noun-phrase summarizing the phase's deliverable (≤60 chars).
|
|
24
|
+
- depends_on lists prior phase ids that must complete before this phase starts. Empty array for the first phase.
|
|
25
|
+
- exit_criteria is one tight sentence describing the operator-verifiable end state of this phase. Cite concrete artifacts ("migration applied", "smoke green") not vague verbs ("works", "done").
|
|
26
|
+
- Maximum ${MAX_PHASES} phases. If the spec describes finer-grained sub-tasks, group them into phases.
|
|
27
|
+
- Linear or DAG, never cyclic. Every depends_on entry must be an earlier phase id.
|
|
28
|
+
|
|
29
|
+
Keep phase count tight — one phase per coherent deliverable, not one per file. The roadmap is the operator's mental map; pad it and you waste their attention.`;
|
|
30
|
+
const OUTPUT_SCHEMA = {
|
|
31
|
+
type: "object",
|
|
32
|
+
required: ["phases"],
|
|
33
|
+
properties: {
|
|
34
|
+
phases: {
|
|
35
|
+
type: "array",
|
|
36
|
+
minItems: 1,
|
|
37
|
+
maxItems: MAX_PHASES,
|
|
38
|
+
items: {
|
|
39
|
+
type: "object",
|
|
40
|
+
required: ["id", "title", "depends_on", "exit_criteria"],
|
|
41
|
+
properties: {
|
|
42
|
+
id: { type: "string", pattern: "^phase-[0-9]+-[a-z0-9-]+$" },
|
|
43
|
+
title: { type: "string", minLength: 1, maxLength: 80 },
|
|
44
|
+
depends_on: { type: "array", items: { type: "string" } },
|
|
45
|
+
exit_criteria: { type: "string", minLength: 1, maxLength: 200 },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const DraftResponseSchema = z.object({
|
|
52
|
+
phases: z.array(z.object({
|
|
53
|
+
id: z.string(),
|
|
54
|
+
title: z.string(),
|
|
55
|
+
depends_on: z.array(z.string()),
|
|
56
|
+
exit_criteria: z.string(),
|
|
57
|
+
})),
|
|
58
|
+
});
|
|
59
|
+
export async function draftRoadmapFromSpec(args) {
|
|
60
|
+
const truncated = args.spec.length > MAX_SPEC_CHARS;
|
|
61
|
+
const slice = truncated ? args.spec.slice(0, MAX_SPEC_CHARS) : args.spec;
|
|
62
|
+
const prompt = `Source planning document (${args.specPath}):\n\n${slice}\n\nReturn the phase array.`;
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = await runClaude({
|
|
66
|
+
tier: "haiku",
|
|
67
|
+
prompt,
|
|
68
|
+
system: SYSTEM_PROMPT,
|
|
69
|
+
jsonSchema: OUTPUT_SCHEMA,
|
|
70
|
+
timeoutMs: TIMEOUT_MS,
|
|
71
|
+
repoRoot: args.repoRoot,
|
|
72
|
+
cacheable: false,
|
|
73
|
+
isolateAmbientContext: true,
|
|
74
|
+
purpose: "mission.draft",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
log.warn({ error: err instanceof Error ? err.message : String(err) }, "mission draft Haiku call failed");
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const parsed = DraftResponseSchema.safeParse(result.parsed);
|
|
82
|
+
if (!parsed.success) {
|
|
83
|
+
log.warn({ error: parsed.error.message }, "mission draft response failed schema");
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const phases = parsed.data.phases.map((p) => ({
|
|
87
|
+
id: p.id,
|
|
88
|
+
title: p.title,
|
|
89
|
+
depends_on: p.depends_on,
|
|
90
|
+
exit_criteria: p.exit_criteria,
|
|
91
|
+
}));
|
|
92
|
+
return {
|
|
93
|
+
phases,
|
|
94
|
+
spec_chars_used: slice.length,
|
|
95
|
+
truncated,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Single-phase fallback used when `no_llm: true` or Haiku is offline.
|
|
100
|
+
* Lets the operator hand-edit roadmap.md before approving.
|
|
101
|
+
*/
|
|
102
|
+
export function stubRoadmap() {
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
id: "phase-1-todo",
|
|
106
|
+
title: "Implement (single-phase stub)",
|
|
107
|
+
depends_on: [],
|
|
108
|
+
exit_criteria: "Operator hand-edits this phase list before accepting the draft.",
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/missions/draft.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission orchestration — helpers for the `cairn_mission_*` MCP tools.
|
|
3
|
+
* State + I/O lives in `@isaacriehm/cairn-state`; this module holds
|
|
4
|
+
* the LLM call (Haiku doc-parse), cursor advance, and task linkage.
|
|
5
|
+
*/
|
|
6
|
+
export { draftRoadmapFromSpec, stubRoadmap, type DraftRoadmapArgs, type DraftRoadmapResult, } from "./draft.js";
|
|
7
|
+
export { advancePhase as advanceMissionPhase, allPhaseTasksDone, lookupPhase, type AdvanceResult, type AdvanceError, } from "./cursor.js";
|
|
8
|
+
export { onTaskCompleted, readTaskMissionAnchor, linkTaskToPhase, type TaskMissionAnchor, type TaskCompletionLink, } from "./task-link.js";
|
|
9
|
+
export { listMissions, loadDraftFromFile, previewRoadmap, runMissionAccept, runMissionAdvance, runMissionClose, runMissionGet, runMissionReopen, runMissionStart, writeDraftToFile, } from "./cli.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission orchestration — helpers for the `cairn_mission_*` MCP tools.
|
|
3
|
+
* State + I/O lives in `@isaacriehm/cairn-state`; this module holds
|
|
4
|
+
* the LLM call (Haiku doc-parse), cursor advance, and task linkage.
|
|
5
|
+
*/
|
|
6
|
+
export { draftRoadmapFromSpec, stubRoadmap, } from "./draft.js";
|
|
7
|
+
export { advancePhase as advanceMissionPhase, allPhaseTasksDone, lookupPhase, } from "./cursor.js";
|
|
8
|
+
export { onTaskCompleted, readTaskMissionAnchor, linkTaskToPhase, } from "./task-link.js";
|
|
9
|
+
export { listMissions, loadDraftFromFile, previewRoadmap, runMissionAccept, runMissionAdvance, runMissionClose, runMissionGet, runMissionReopen, runMissionStart, writeDraftToFile, } from "./cli.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/missions/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,EACpB,WAAW,GAGZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,IAAI,mBAAmB,EACnC,iBAAiB,EACjB,WAAW,GAGZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,GAGhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,UAAU,CAAC"}
|