@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.
Files changed (76) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/hooks/runners/context-threshold.js +37 -1
  3. package/dist/hooks/runners/context-threshold.js.map +1 -1
  4. package/dist/hooks/runners/stop.js +109 -0
  5. package/dist/hooks/runners/stop.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp/errors.d.ts +1 -1
  10. package/dist/mcp/errors.js.map +1 -1
  11. package/dist/mcp/schemas.d.ts +101 -0
  12. package/dist/mcp/schemas.js +92 -0
  13. package/dist/mcp/schemas.js.map +1 -1
  14. package/dist/mcp/tools/index.js +19 -0
  15. package/dist/mcp/tools/index.js.map +1 -1
  16. package/dist/mcp/tools/mission-accept-draft.d.ts +16 -0
  17. package/dist/mcp/tools/mission-accept-draft.js +102 -0
  18. package/dist/mcp/tools/mission-accept-draft.js.map +1 -0
  19. package/dist/mcp/tools/mission-advance.d.ts +8 -0
  20. package/dist/mcp/tools/mission-advance.js +124 -0
  21. package/dist/mcp/tools/mission-advance.js.map +1 -0
  22. package/dist/mcp/tools/mission-close.d.ts +8 -0
  23. package/dist/mcp/tools/mission-close.js +48 -0
  24. package/dist/mcp/tools/mission-close.js.map +1 -0
  25. package/dist/mcp/tools/mission-get.d.ts +6 -0
  26. package/dist/mcp/tools/mission-get.js +64 -0
  27. package/dist/mcp/tools/mission-get.js.map +1 -0
  28. package/dist/mcp/tools/mission-reopen.d.ts +13 -0
  29. package/dist/mcp/tools/mission-reopen.js +56 -0
  30. package/dist/mcp/tools/mission-reopen.js.map +1 -0
  31. package/dist/mcp/tools/mission-resume.d.ts +15 -0
  32. package/dist/mcp/tools/mission-resume.js +219 -0
  33. package/dist/mcp/tools/mission-resume.js.map +1 -0
  34. package/dist/mcp/tools/mission-resync-accept.d.ts +19 -0
  35. package/dist/mcp/tools/mission-resync-accept.js +192 -0
  36. package/dist/mcp/tools/mission-resync-accept.js.map +1 -0
  37. package/dist/mcp/tools/mission-resync.d.ts +20 -0
  38. package/dist/mcp/tools/mission-resync.js +113 -0
  39. package/dist/mcp/tools/mission-resync.js.map +1 -0
  40. package/dist/mcp/tools/mission-start.d.ts +8 -0
  41. package/dist/mcp/tools/mission-start.js +76 -0
  42. package/dist/mcp/tools/mission-start.js.map +1 -0
  43. package/dist/mcp/tools/resolve-attention.js +62 -1
  44. package/dist/mcp/tools/resolve-attention.js.map +1 -1
  45. package/dist/mcp/tools/task-create.d.ts +2 -0
  46. package/dist/mcp/tools/task-create.js +40 -2
  47. package/dist/mcp/tools/task-create.js.map +1 -1
  48. package/dist/missions/cli.d.ts +106 -0
  49. package/dist/missions/cli.js +279 -0
  50. package/dist/missions/cli.js.map +1 -0
  51. package/dist/missions/cursor.d.ts +40 -0
  52. package/dist/missions/cursor.js +99 -0
  53. package/dist/missions/cursor.js.map +1 -0
  54. package/dist/missions/draft.d.ts +28 -0
  55. package/dist/missions/draft.js +112 -0
  56. package/dist/missions/draft.js.map +1 -0
  57. package/dist/missions/index.d.ts +9 -0
  58. package/dist/missions/index.js +10 -0
  59. package/dist/missions/index.js.map +1 -0
  60. package/dist/missions/task-link.d.ts +51 -0
  61. package/dist/missions/task-link.js +155 -0
  62. package/dist/missions/task-link.js.map +1 -0
  63. package/dist/session-start/build.d.ts +1 -1
  64. package/dist/session-start/build.js +58 -1
  65. package/dist/session-start/build.js.map +1 -1
  66. package/dist/status-line/format.d.ts +15 -1
  67. package/dist/status-line/format.js +12 -1
  68. package/dist/status-line/format.js.map +1 -1
  69. package/dist/status-line/index.d.ts +1 -1
  70. package/dist/status-line/index.js +1 -1
  71. package/dist/status-line/index.js.map +1 -1
  72. package/dist/status-line/reader.js +33 -2
  73. package/dist/status-line/reader.js.map +1 -1
  74. package/dist/tasks/lifecycle.js +11 -0
  75. package/dist/tasks/lifecycle.js.map +1 -1
  76. package/package.json +2 -2
@@ -0,0 +1,219 @@
1
+ /**
2
+ * `cairn_mission_resume` — return the mission-frame priming body the
3
+ * `cairn-resume` skill chains in front of the existing task journal
4
+ * frame after `/clear`.
5
+ *
6
+ * Budget: ≤ 2500 tokens total (~10000 chars, conservative). Phase
7
+ * spec slice hard-capped at 1500 tokens (~6000 chars); falls back to
8
+ * title + exit_criteria + first paragraph when over.
9
+ */
10
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { parse as parseYaml } from "yaml";
13
+ import { countDonePhases, findActiveMission, locateMission, readMissionSpec, readMissionState, readRoadmap, slicePhaseSection, } from "@isaacriehm/cairn-state";
14
+ import { requireBootstrap } from "../bootstrap-guard.js";
15
+ import { mcpError } from "../errors.js";
16
+ import { missionResumeInput } from "../schemas.js";
17
+ const MAX_PHASE_SLICE_CHARS = 6_000;
18
+ const MAX_GRADUATED_TASKS = 3;
19
+ const MAX_IN_FLIGHT_TASKS = 5;
20
+ async function handler(ctx, input) {
21
+ const block = requireBootstrap(ctx.repoRoot);
22
+ if (block !== null)
23
+ return block;
24
+ const missionId = input.mission_id ?? findActiveMission(ctx.repoRoot);
25
+ if (missionId === null) {
26
+ return { ok: true, active: false };
27
+ }
28
+ if (locateMission(ctx.repoRoot, missionId) !== "active") {
29
+ return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} is not active on this clone`);
30
+ }
31
+ const roadmap = readRoadmap(ctx.repoRoot, missionId);
32
+ const state = readMissionState(ctx.repoRoot, missionId);
33
+ if (roadmap === null || state === null) {
34
+ return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} state or roadmap unreadable`);
35
+ }
36
+ const cursorPhaseId = state.cursor.active_phase;
37
+ const cursorPhase = cursorPhaseId === null
38
+ ? null
39
+ : roadmap.frontmatter.phases.find((p) => p.id === cursorPhaseId) ?? null;
40
+ const spec = readMissionSpec(ctx.repoRoot, missionId) ?? "";
41
+ let phaseSlice = null;
42
+ if (cursorPhase !== null) {
43
+ phaseSlice = slicePhaseSection(spec, cursorPhase);
44
+ if (phaseSlice !== null && phaseSlice.length > MAX_PHASE_SLICE_CHARS) {
45
+ const firstParagraph = phaseSlice.split(/\n\n/, 2)[0]?.slice(0, MAX_PHASE_SLICE_CHARS) ?? "";
46
+ phaseSlice = `${firstParagraph}\n\n…(truncated; full section in .cairn/missions/${missionId}/spec.md)`;
47
+ }
48
+ }
49
+ const recentGraduated = collectRecentGraduatedTasks(ctx.repoRoot, missionId, MAX_GRADUATED_TASKS);
50
+ const inFlight = collectInFlightTasks(ctx.repoRoot, missionId);
51
+ const upcoming = roadmap.frontmatter.phases
52
+ .filter((p) => {
53
+ const progress = state.phase_progress[p.id];
54
+ return (progress?.state ?? "pending") === "pending" && p.id !== cursorPhaseId;
55
+ })
56
+ .slice(0, 2);
57
+ const donePhases = countDonePhases(state);
58
+ const totalPhases = roadmap.frontmatter.phases.length;
59
+ const lines = [];
60
+ lines.push(`# Mission frame — ${roadmap.frontmatter.title}`);
61
+ lines.push("");
62
+ lines.push(`- mission: \`${missionId}\``);
63
+ lines.push(`- spec: \`${roadmap.frontmatter.spec_path}\``);
64
+ lines.push(`- progress: ${donePhases}/${totalPhases} phases`);
65
+ lines.push(`- exit_gate: ${roadmap.frontmatter.exit_gate}`);
66
+ if (cursorPhase !== null) {
67
+ lines.push(`- cursor: \`${cursorPhase.id}\` — ${cursorPhase.title}`);
68
+ lines.push(` - exit_criteria: ${cursorPhase.exit_criteria}`);
69
+ }
70
+ else {
71
+ lines.push(`- cursor: (no active phase — mission may be near close)`);
72
+ }
73
+ lines.push("");
74
+ if (recentGraduated.length > 0) {
75
+ lines.push("## Recent graduated tasks");
76
+ for (const t of recentGraduated) {
77
+ lines.push(`- \`${t.task_id}\` — ${t.title} (${t.outcome})`);
78
+ }
79
+ lines.push("");
80
+ }
81
+ if (inFlight.length > 0) {
82
+ lines.push("## In-flight tasks (current phase)");
83
+ for (const t of inFlight) {
84
+ lines.push(`- \`${t.task_id}\` — ${t.title} (phase=${t.phase})`);
85
+ }
86
+ lines.push("");
87
+ }
88
+ if (cursorPhase !== null && phaseSlice !== null) {
89
+ lines.push(`## Spec section — ${cursorPhase.title}`);
90
+ lines.push("");
91
+ lines.push(phaseSlice);
92
+ lines.push("");
93
+ }
94
+ else if (cursorPhase !== null) {
95
+ lines.push(`## Spec section — ${cursorPhase.title}`);
96
+ lines.push("");
97
+ lines.push(cursorPhase.exit_criteria);
98
+ lines.push("");
99
+ }
100
+ if (upcoming.length > 0) {
101
+ lines.push("## Upcoming phases");
102
+ for (const p of upcoming) {
103
+ lines.push(`- \`${p.id}\` — ${p.title}`);
104
+ }
105
+ lines.push("");
106
+ }
107
+ return {
108
+ ok: true,
109
+ active: true,
110
+ mission_id: missionId,
111
+ title: roadmap.frontmatter.title,
112
+ cursor_phase: cursorPhase?.id ?? null,
113
+ progress: { done: donePhases, total: totalPhases },
114
+ body: lines.join("\n").trim(),
115
+ };
116
+ }
117
+ function parseStatusYaml(path) {
118
+ if (!existsSync(path))
119
+ return null;
120
+ let raw;
121
+ try {
122
+ raw = readFileSync(path, "utf8");
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ let parsed;
128
+ try {
129
+ parsed = parseYaml(raw);
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ if (parsed === null || typeof parsed !== "object")
135
+ return null;
136
+ const obj = parsed;
137
+ return {
138
+ mission_id: typeof obj["mission_id"] === "string" ? obj["mission_id"] : null,
139
+ phase_id: typeof obj["phase_id"] === "string" ? obj["phase_id"] : null,
140
+ title: typeof obj["title"] === "string" ? obj["title"] : null,
141
+ phase: typeof obj["phase"] === "string" ? obj["phase"] : null,
142
+ };
143
+ }
144
+ function collectRecentGraduatedTasks(repoRoot, missionId, cap) {
145
+ const doneDir = join(repoRoot, ".cairn", "tasks", "done");
146
+ if (!existsSync(doneDir))
147
+ return [];
148
+ let entries;
149
+ try {
150
+ entries = readdirSync(doneDir, { withFileTypes: true, encoding: "utf8" });
151
+ }
152
+ catch {
153
+ return [];
154
+ }
155
+ const matches = [];
156
+ for (const entry of entries) {
157
+ if (!entry.isDirectory())
158
+ continue;
159
+ const statusPath = join(doneDir, entry.name, "status.yaml");
160
+ const status = parseStatusYaml(statusPath);
161
+ if (status === null || status.mission_id !== missionId)
162
+ continue;
163
+ let mtime = 0;
164
+ try {
165
+ mtime = statSync(statusPath).mtimeMs;
166
+ }
167
+ catch {
168
+ continue;
169
+ }
170
+ matches.push({
171
+ task_id: entry.name,
172
+ title: status.title ?? entry.name,
173
+ outcome: status.phase ?? "succeeded",
174
+ mtime,
175
+ });
176
+ }
177
+ matches.sort((a, b) => b.mtime - a.mtime);
178
+ return matches.slice(0, cap).map((m) => ({
179
+ task_id: m.task_id,
180
+ title: m.title,
181
+ outcome: m.outcome,
182
+ }));
183
+ }
184
+ function collectInFlightTasks(repoRoot, missionId) {
185
+ const activeDir = join(repoRoot, ".cairn", "tasks", "active");
186
+ if (!existsSync(activeDir))
187
+ return [];
188
+ let entries;
189
+ try {
190
+ entries = readdirSync(activeDir, { withFileTypes: true, encoding: "utf8" });
191
+ }
192
+ catch {
193
+ return [];
194
+ }
195
+ const out = [];
196
+ for (const entry of entries) {
197
+ if (!entry.isDirectory())
198
+ continue;
199
+ const statusPath = join(activeDir, entry.name, "status.yaml");
200
+ const status = parseStatusYaml(statusPath);
201
+ if (status === null || status.mission_id !== missionId)
202
+ continue;
203
+ out.push({
204
+ task_id: entry.name,
205
+ title: status.title ?? entry.name,
206
+ phase: status.phase ?? "unknown",
207
+ });
208
+ if (out.length >= MAX_IN_FLIGHT_TASKS)
209
+ break;
210
+ }
211
+ return out;
212
+ }
213
+ export const missionResumeTool = {
214
+ name: "cairn_mission_resume",
215
+ description: "Return the mission-frame priming body the cairn-resume skill chains before the existing task journal frame after `/clear`. Includes mission id + title, cursor phase + exit_criteria, last 3 graduated tasks (mission-anchored), in-flight tasks under the cursor phase, the spec.md section sliced by phase heading (≤6000 chars), and the next 1-2 upcoming phases. Returns `{ active: false }` when no active mission exists.",
216
+ inputSchema: missionResumeInput,
217
+ handler,
218
+ };
219
+ //# sourceMappingURL=mission-resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mission-resume.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-resume.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `cairn_mission_resync_accept` — apply or reject the pending resync
3
+ * marker (`.cairn/missions/<id>/_resync.json`) written by
4
+ * `cairn_mission_resync`. On accept: rewrite roadmap.md with the
5
+ * proposed phases (preserving mission_id, title, exit_gate,
6
+ * created_at), refresh spec.md from the live spec doc, reconcile
7
+ * `phase_progress` (added phases → pending entries; removed phases →
8
+ * dropped with journal note), and reposition the cursor when the
9
+ * active phase was deleted.
10
+ *
11
+ * Reject just deletes the marker; roadmap.md and state.json stay
12
+ * untouched.
13
+ */
14
+ import type { ToolDef } from "./types.js";
15
+ interface Input {
16
+ outcome: "accept" | "reject";
17
+ }
18
+ export declare const missionResyncAcceptTool: ToolDef<Input>;
19
+ export {};
@@ -0,0 +1,192 @@
1
+ /**
2
+ * `cairn_mission_resync_accept` — apply or reject the pending resync
3
+ * marker (`.cairn/missions/<id>/_resync.json`) written by
4
+ * `cairn_mission_resync`. On accept: rewrite roadmap.md with the
5
+ * proposed phases (preserving mission_id, title, exit_gate,
6
+ * created_at), refresh spec.md from the live spec doc, reconcile
7
+ * `phase_progress` (added phases → pending entries; removed phases →
8
+ * dropped with journal note), and reposition the cursor when the
9
+ * active phase was deleted.
10
+ *
11
+ * Reject just deletes the marker; roadmap.md and state.json stay
12
+ * untouched.
13
+ */
14
+ import { existsSync, readFileSync, rmSync } from "node:fs";
15
+ import { isAbsolute, join, resolve as pathResolve } from "node:path";
16
+ import { z } from "zod";
17
+ import { appendMissionJournal, findActiveMission, missionRuntimeDir, nextPendingPhase, readMissionState, readRoadmap, writeMissionSpec, writeMissionState, writeRoadmap, } from "@isaacriehm/cairn-state";
18
+ import { requireBootstrap } from "../bootstrap-guard.js";
19
+ import { mcpError } from "../errors.js";
20
+ import { missionResyncAcceptInput } from "../schemas.js";
21
+ const ResyncMarkerSchema = z.object({
22
+ generated_at: z.string(),
23
+ spec_path: z.string(),
24
+ proposed_phases: z.array(z.object({
25
+ id: z.string(),
26
+ title: z.string(),
27
+ depends_on: z.array(z.string()).default([]),
28
+ exit_criteria: z.string(),
29
+ exit_gate: z.enum(["prompt", "auto", "manual"]).optional(),
30
+ })),
31
+ diff: z
32
+ .object({
33
+ added: z.array(z.string()),
34
+ removed: z.array(z.string()),
35
+ renamed: z.array(z.object({ from: z.string(), to: z.string() })),
36
+ exit_criteria_changed: z.array(z.object({ id: z.string(), before: z.string(), after: z.string() })),
37
+ })
38
+ .passthrough(),
39
+ });
40
+ async function handler(ctx, input) {
41
+ const block = requireBootstrap(ctx.repoRoot);
42
+ if (block !== null)
43
+ return block;
44
+ const missionId = findActiveMission(ctx.repoRoot);
45
+ if (missionId === null) {
46
+ return mcpError("MISSION_NOT_FOUND", "No active mission");
47
+ }
48
+ const markerPath = join(missionRuntimeDir(ctx.repoRoot, missionId), "_resync.json");
49
+ if (!existsSync(markerPath)) {
50
+ return mcpError("FILE_NOT_FOUND", `No pending resync for ${missionId} (_resync.json not present)`);
51
+ }
52
+ let raw;
53
+ try {
54
+ raw = readFileSync(markerPath, "utf8");
55
+ }
56
+ catch (err) {
57
+ return mcpError("INTERNAL_ERROR", `Failed to read resync marker: ${err instanceof Error ? err.message : String(err)}`);
58
+ }
59
+ let parsed;
60
+ try {
61
+ parsed = JSON.parse(raw);
62
+ }
63
+ catch (err) {
64
+ return mcpError("INTERNAL_ERROR", `Resync marker malformed: ${err instanceof Error ? err.message : String(err)}`);
65
+ }
66
+ const markerResult = ResyncMarkerSchema.safeParse(parsed);
67
+ if (!markerResult.success) {
68
+ return mcpError("VALIDATION_FAILED", `Resync marker invalid: ${markerResult.error.message}`);
69
+ }
70
+ const marker = markerResult.data;
71
+ const ts = new Date().toISOString();
72
+ if (input.outcome === "reject") {
73
+ rmSync(markerPath, { force: true });
74
+ appendMissionJournal(ctx.repoRoot, missionId, {
75
+ ts,
76
+ kind: "resync-applied",
77
+ detail: "rejected by operator",
78
+ });
79
+ return {
80
+ ok: true,
81
+ mission_id: missionId,
82
+ outcome: "rejected",
83
+ };
84
+ }
85
+ // outcome === "accept"
86
+ const roadmap = readRoadmap(ctx.repoRoot, missionId);
87
+ const state = readMissionState(ctx.repoRoot, missionId);
88
+ if (roadmap === null || state === null) {
89
+ return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} state or roadmap unreadable`);
90
+ }
91
+ // Build new roadmap frontmatter — preserve mission_id, title,
92
+ // exit_gate, created_at, spec_path. Replace phases with the
93
+ // operator-approved proposed_phases.
94
+ const newPhases = marker.proposed_phases.map((p) => ({
95
+ id: p.id,
96
+ title: p.title,
97
+ depends_on: p.depends_on,
98
+ exit_criteria: p.exit_criteria,
99
+ ...(p.exit_gate !== undefined ? { exit_gate: p.exit_gate } : {}),
100
+ }));
101
+ const newFrontmatter = {
102
+ mission_id: roadmap.frontmatter.mission_id,
103
+ title: roadmap.frontmatter.title,
104
+ spec_path: marker.spec_path,
105
+ created_at: roadmap.frontmatter.created_at,
106
+ exit_gate: roadmap.frontmatter.exit_gate,
107
+ phases: newPhases,
108
+ };
109
+ writeRoadmap(ctx.repoRoot, missionId, newFrontmatter, roadmap.prose);
110
+ // Refresh spec.md from the live spec doc.
111
+ const absSpec = isAbsolute(marker.spec_path)
112
+ ? marker.spec_path
113
+ : pathResolve(ctx.repoRoot, marker.spec_path);
114
+ if (existsSync(absSpec)) {
115
+ try {
116
+ const liveSpec = readFileSync(absSpec, "utf8");
117
+ writeMissionSpec(ctx.repoRoot, missionId, liveSpec);
118
+ }
119
+ catch {
120
+ // best-effort spec refresh; resync still applies even if spec read fails
121
+ }
122
+ }
123
+ // Reconcile phase_progress.
124
+ // - Added phases: insert a `pending` entry with no task_ids.
125
+ // - Removed phases (in marker.diff.removed): drop from phase_progress;
126
+ // journal each drop with the orphaned task ids.
127
+ // - Surviving phases keep their state + task_ids.
128
+ const orphanedByPhase = {};
129
+ for (const removed of marker.diff.removed) {
130
+ const taskIds = state.phase_progress[removed]?.task_ids ?? [];
131
+ if (taskIds.length > 0)
132
+ orphanedByPhase[removed] = taskIds;
133
+ delete state.phase_progress[removed];
134
+ }
135
+ for (const added of marker.diff.added) {
136
+ if (!(added in state.phase_progress)) {
137
+ state.phase_progress[added] = { state: "pending", task_ids: [] };
138
+ }
139
+ }
140
+ // Cursor: if the current active phase was removed, recompute via
141
+ // nextPendingPhase against the new roadmap. If no phase remains
142
+ // pending, leave cursor null (mission may auto-close on next
143
+ // advance).
144
+ const cursorPhaseId = state.cursor.active_phase;
145
+ if (cursorPhaseId !== null && !newPhases.some((p) => p.id === cursorPhaseId)) {
146
+ const nextPhase = nextPendingPhase(newFrontmatter, state);
147
+ if (nextPhase !== null) {
148
+ state.cursor.active_phase = nextPhase.id;
149
+ state.cursor.active_phase_started_at = ts;
150
+ const existing = state.phase_progress[nextPhase.id];
151
+ state.phase_progress[nextPhase.id] = {
152
+ state: "in_progress",
153
+ task_ids: existing?.task_ids ?? [],
154
+ };
155
+ }
156
+ else {
157
+ state.cursor.active_phase = null;
158
+ state.cursor.active_phase_started_at = null;
159
+ }
160
+ }
161
+ writeMissionState(ctx.repoRoot, missionId, state);
162
+ appendMissionJournal(ctx.repoRoot, missionId, {
163
+ ts,
164
+ kind: "resync-applied",
165
+ detail: `+${marker.diff.added.length} −${marker.diff.removed.length} ↻${marker.diff.renamed.length} criteria${marker.diff.exit_criteria_changed.length}`,
166
+ });
167
+ for (const [phaseId, ids] of Object.entries(orphanedByPhase)) {
168
+ appendMissionJournal(ctx.repoRoot, missionId, {
169
+ ts,
170
+ kind: "drift-detected",
171
+ phase_id: phaseId,
172
+ detail: `dropped via resync — ${ids.length} graduated task(s) orphaned`,
173
+ });
174
+ }
175
+ rmSync(markerPath, { force: true });
176
+ return {
177
+ ok: true,
178
+ mission_id: missionId,
179
+ outcome: "applied",
180
+ diff: marker.diff,
181
+ new_phase_count: newPhases.length,
182
+ cursor_phase: state.cursor.active_phase,
183
+ orphaned_tasks_by_phase: orphanedByPhase,
184
+ };
185
+ }
186
+ export const missionResyncAcceptTool = {
187
+ name: "cairn_mission_resync_accept",
188
+ description: "Apply or reject the pending resync marker written by cairn_mission_resync. `outcome=accept` rewrites roadmap.md with the proposed phases, refreshes spec.md from the live spec, reconciles phase_progress (adds/drops), and repositions the cursor when the active phase was deleted. `outcome=reject` deletes the marker without touching anything else. Idempotent — once applied, the marker is gone.",
189
+ inputSchema: missionResyncAcceptInput,
190
+ handler,
191
+ };
192
+ //# sourceMappingURL=mission-resync-accept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mission-resync-accept.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-resync-accept.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `cairn_mission_resync` — operator amended the source spec doc and
3
+ * wants Cairn to pick up the changes.
4
+ *
5
+ * Re-parses the spec via Haiku (or `no_llm: true` stub fallback),
6
+ * diffs against the current roadmap.md, and writes a `mission_resync_pending`
7
+ * marker file under `.cairn/missions/<id>/_resync.json`. The operator
8
+ * resolves via `cairn-attention` — accepting the diff overwrites the
9
+ * roadmap and refreshes `spec.md`; rejecting drops the marker.
10
+ *
11
+ * No mutation of `roadmap.md` or `phase_progress` happens here — the
12
+ * operator gates the apply step via `cairn_mission_resync_accept`.
13
+ */
14
+ import type { ToolDef } from "./types.js";
15
+ interface Input {
16
+ spec_path?: string;
17
+ no_llm?: boolean;
18
+ }
19
+ export declare const missionResyncTool: ToolDef<Input>;
20
+ export {};
@@ -0,0 +1,113 @@
1
+ /**
2
+ * `cairn_mission_resync` — operator amended the source spec doc and
3
+ * wants Cairn to pick up the changes.
4
+ *
5
+ * Re-parses the spec via Haiku (or `no_llm: true` stub fallback),
6
+ * diffs against the current roadmap.md, and writes a `mission_resync_pending`
7
+ * marker file under `.cairn/missions/<id>/_resync.json`. The operator
8
+ * resolves via `cairn-attention` — accepting the diff overwrites the
9
+ * roadmap and refreshes `spec.md`; rejecting drops the marker.
10
+ *
11
+ * No mutation of `roadmap.md` or `phase_progress` happens here — the
12
+ * operator gates the apply step via `cairn_mission_resync_accept`.
13
+ */
14
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
15
+ import { isAbsolute, join, resolve as pathResolve } from "node:path";
16
+ import { appendMissionJournal, findActiveMission, missionRuntimeDir, readRoadmap, } from "@isaacriehm/cairn-state";
17
+ import { requireBootstrap } from "../bootstrap-guard.js";
18
+ import { mcpError } from "../errors.js";
19
+ import { missionResyncInput } from "../schemas.js";
20
+ import { draftRoadmapFromSpec, stubRoadmap } from "../../missions/index.js";
21
+ async function handler(ctx, input) {
22
+ const block = requireBootstrap(ctx.repoRoot);
23
+ if (block !== null)
24
+ return block;
25
+ const missionId = findActiveMission(ctx.repoRoot);
26
+ if (missionId === null) {
27
+ return mcpError("MISSION_NOT_FOUND", "No active mission to resync");
28
+ }
29
+ const roadmap = readRoadmap(ctx.repoRoot, missionId);
30
+ if (roadmap === null) {
31
+ return mcpError("MISSION_NOT_FOUND", `Roadmap missing for ${missionId}`);
32
+ }
33
+ const specPath = input.spec_path ?? roadmap.frontmatter.spec_path;
34
+ const absSpec = isAbsolute(specPath) ? specPath : pathResolve(ctx.repoRoot, specPath);
35
+ if (!absSpec.startsWith(ctx.repoRoot)) {
36
+ return mcpError("PATH_OUTSIDE_REPO", `${specPath} resolves outside the repo`);
37
+ }
38
+ if (!existsSync(absSpec)) {
39
+ return mcpError("FILE_NOT_FOUND", `Spec doc not found: ${specPath}`);
40
+ }
41
+ let source;
42
+ try {
43
+ source = readFileSync(absSpec, "utf8");
44
+ }
45
+ catch (err) {
46
+ return mcpError("INTERNAL_ERROR", `Failed to read spec doc: ${err instanceof Error ? err.message : String(err)}`);
47
+ }
48
+ let newPhases;
49
+ if (input.no_llm === true) {
50
+ newPhases = stubRoadmap();
51
+ }
52
+ else {
53
+ const draft = await draftRoadmapFromSpec({
54
+ repoRoot: ctx.repoRoot,
55
+ spec: source,
56
+ specPath,
57
+ });
58
+ if (draft === null) {
59
+ return mcpError("MISSION_DRAFT_FAILED", "Haiku failed to re-parse the spec. Retry, or pass `no_llm: true` for a stub fallback.");
60
+ }
61
+ newPhases = draft.phases;
62
+ }
63
+ const oldIds = new Set(roadmap.frontmatter.phases.map((p) => p.id));
64
+ const newIds = new Set(newPhases.map((p) => p.id));
65
+ const added = [...newIds].filter((id) => !oldIds.has(id));
66
+ const removed = [...oldIds].filter((id) => !newIds.has(id));
67
+ const renamed = [];
68
+ // crude rename detection — same title at different ids
69
+ for (const op of roadmap.frontmatter.phases) {
70
+ for (const np of newPhases) {
71
+ if (op.id !== np.id && op.title === np.title) {
72
+ renamed.push({ from: op.id, to: np.id });
73
+ }
74
+ }
75
+ }
76
+ const exit_criteria_changed = [];
77
+ for (const op of roadmap.frontmatter.phases) {
78
+ const np = newPhases.find((n) => n.id === op.id);
79
+ if (np !== undefined && np.exit_criteria !== op.exit_criteria) {
80
+ exit_criteria_changed.push({ id: op.id, before: op.exit_criteria, after: np.exit_criteria });
81
+ }
82
+ }
83
+ const ts = new Date().toISOString();
84
+ const resyncPath = join(missionRuntimeDir(ctx.repoRoot, missionId), "_resync.json");
85
+ mkdirSync(missionRuntimeDir(ctx.repoRoot, missionId), { recursive: true });
86
+ writeFileSync(resyncPath, JSON.stringify({
87
+ generated_at: ts,
88
+ spec_path: specPath,
89
+ proposed_phases: newPhases,
90
+ diff: { added, removed, renamed, exit_criteria_changed },
91
+ }, null, 2), "utf8");
92
+ appendMissionJournal(ctx.repoRoot, missionId, {
93
+ ts,
94
+ kind: "resync-pending",
95
+ detail: `+${added.length} −${removed.length} ↻${renamed.length} criteria${exit_criteria_changed.length}`,
96
+ });
97
+ return {
98
+ ok: true,
99
+ mission_id: missionId,
100
+ spec_path: specPath,
101
+ diff: { added, removed, renamed, exit_criteria_changed },
102
+ proposed_phases: newPhases,
103
+ resync_marker_path: `.cairn/missions/${missionId}/_resync.json`,
104
+ note: "Operator reviews via cairn-attention (kind: mission_resync_pending). Apply or reject via cairn_mission_resync_accept.",
105
+ };
106
+ }
107
+ export const missionResyncTool = {
108
+ name: "cairn_mission_resync",
109
+ description: "Re-parse the source spec doc, diff against the current roadmap.md, and write a `mission_resync_pending` marker. Does NOT mutate roadmap.md or phase_progress — the operator must accept the diff via cairn-attention. Use when the operator amended the live spec doc; the frozen `spec.md` snapshot stays untouched until the resync is accepted.",
110
+ inputSchema: missionResyncInput,
111
+ handler,
112
+ };
113
+ //# sourceMappingURL=mission-resync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mission-resync.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-resync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQ5E,KAAK,UAAU,OAAO,CAAC,GAAe,EAAE,KAAY;IAClD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAEjC,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC,mBAAmB,EAAE,6BAA6B,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAC,mBAAmB,EAAE,uBAAuB,SAAS,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC;IAClE,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtF,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,QAAQ,CAAC,mBAAmB,EAAE,GAAG,QAAQ,4BAA4B,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,QAAQ,CACb,gBAAgB,EAChB,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/E,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC;IACd,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1B,SAAS,GAAG,WAAW,EAAE,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC;YACvC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,MAAM;YACZ,QAAQ;SACT,CAAC,CAAC;QACH,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CACb,sBAAsB,EACtB,uFAAuF,CACxF,CAAC;QACJ,CAAC;QACD,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAmC,EAAE,CAAC;IACnD,uDAAuD;IACvD,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC5C,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC;gBAC7C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,qBAAqB,GAAoD,EAAE,CAAC;IAClF,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,CAAC,aAAa,KAAK,EAAE,CAAC,aAAa,EAAE,CAAC;YAC9D,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,cAAc,CAAC,CAAC;IACpF,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,aAAa,CACX,UAAU,EACV,IAAI,CAAC,SAAS,CACZ;QACE,YAAY,EAAE,EAAE;QAChB,SAAS,EAAE,QAAQ;QACnB,eAAe,EAAE,SAAS;QAC1B,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE;KACzD,EACD,IAAI,EACJ,CAAC,CACF,EACD,MAAM,CACP,CAAC;IAEF,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE;QAC5C,EAAE;QACF,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,YAAY,qBAAqB,CAAC,MAAM,EAAE;KACzG,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,IAAI;QACR,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,QAAQ;QACnB,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE;QACxD,eAAe,EAAE,SAAS;QAC1B,kBAAkB,EAAE,mBAAmB,SAAS,eAAe;QAC/D,IAAI,EAAE,uHAAuH;KAC9H,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,oVAAoV;IACtV,WAAW,EAAE,kBAAkB;IAC/B,OAAO;CACR,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ToolDef } from "./types.js";
2
+ interface Input {
3
+ spec_path: string;
4
+ exit_gate: "prompt" | "auto" | "manual";
5
+ no_llm?: boolean;
6
+ }
7
+ export declare const missionStartTool: ToolDef<Input>;
8
+ export {};