@isaacriehm/cairn-core 0.9.8 → 0.10.1
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.d.ts +33 -4
- package/dist/hooks/runners/context-threshold.js +90 -25
- package/dist/hooks/runners/context-threshold.js.map +1 -1
- package/dist/hooks/runners/index.d.ts +1 -0
- package/dist/hooks/runners/index.js +1 -0
- package/dist/hooks/runners/index.js.map +1 -1
- package/dist/hooks/runners/session-start.js +36 -2
- package/dist/hooks/runners/session-start.js.map +1 -1
- package/dist/hooks/runners/stop.js +105 -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/resume.js +40 -4
- package/dist/mcp/tools/resume.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,48 @@
|
|
|
1
|
+
import { appendMissionJournal, archiveMission, locateMission, readMissionState, writeMissionState, } from "@isaacriehm/cairn-state";
|
|
2
|
+
import { requireBootstrap } from "../bootstrap-guard.js";
|
|
3
|
+
import { mcpError } from "../errors.js";
|
|
4
|
+
import { missionCloseInput } from "../schemas.js";
|
|
5
|
+
async function handler(ctx, input) {
|
|
6
|
+
const block = requireBootstrap(ctx.repoRoot);
|
|
7
|
+
if (block !== null)
|
|
8
|
+
return block;
|
|
9
|
+
const scope = locateMission(ctx.repoRoot, input.mission_id);
|
|
10
|
+
if (scope !== "active") {
|
|
11
|
+
return mcpError("MISSION_NOT_FOUND", `Mission ${input.mission_id} not active (scope=${scope ?? "missing"})`);
|
|
12
|
+
}
|
|
13
|
+
const state = readMissionState(ctx.repoRoot, input.mission_id);
|
|
14
|
+
if (state === null) {
|
|
15
|
+
return mcpError("MISSION_NOT_FOUND", `state.json missing for ${input.mission_id}`);
|
|
16
|
+
}
|
|
17
|
+
const closedAt = new Date().toISOString();
|
|
18
|
+
state.outcome = input.outcome;
|
|
19
|
+
state.cursor.active_phase = null;
|
|
20
|
+
state.cursor.active_phase_started_at = null;
|
|
21
|
+
state.closed_at = closedAt;
|
|
22
|
+
if (input.outcome === "aborted" && input.reason !== undefined) {
|
|
23
|
+
state.abort_reason = input.reason;
|
|
24
|
+
}
|
|
25
|
+
writeMissionState(ctx.repoRoot, input.mission_id, state);
|
|
26
|
+
appendMissionJournal(ctx.repoRoot, input.mission_id, {
|
|
27
|
+
ts: closedAt,
|
|
28
|
+
kind: "closed",
|
|
29
|
+
detail: input.outcome === "aborted"
|
|
30
|
+
? `aborted${input.reason !== undefined ? `: ${input.reason}` : ""}`
|
|
31
|
+
: "manual close",
|
|
32
|
+
});
|
|
33
|
+
archiveMission(ctx.repoRoot, input.mission_id);
|
|
34
|
+
return {
|
|
35
|
+
ok: true,
|
|
36
|
+
mission_id: input.mission_id,
|
|
37
|
+
outcome: input.outcome,
|
|
38
|
+
closed_at: closedAt,
|
|
39
|
+
archived_to: `.cairn/ground/missions/_done/${input.mission_id}/`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export const missionCloseTool = {
|
|
43
|
+
name: "cairn_mission_close",
|
|
44
|
+
description: "Close a mission and archive its dirs. `outcome=done` is the manual analogue of auto-close on last phase complete; `outcome=aborted` is the operator-driven cancel path (with optional `reason`). Roadmap moves to `.cairn/ground/missions/_done/<id>/`; per-clone runtime moves to `.cairn/missions/_done/<id>/`. Reversible via cairn_mission_reopen.",
|
|
45
|
+
inputSchema: missionCloseInput,
|
|
46
|
+
handler,
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=mission-close.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-close.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-close.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AASlD,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,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5D,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,QAAQ,CACb,mBAAmB,EACnB,WAAW,KAAK,CAAC,UAAU,sBAAsB,KAAK,IAAI,SAAS,GAAG,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,QAAQ,CAAC,mBAAmB,EAAE,0BAA0B,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,KAAK,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,MAAM,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9D,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;IACpC,CAAC;IACD,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAEzD,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE;QACnD,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,MAAM,EACJ,KAAK,CAAC,OAAO,KAAK,SAAS;YACzB,CAAC,CAAC,UAAU,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;YACnE,CAAC,CAAC,cAAc;KACrB,CAAC,CAAC;IAEH,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAE/C,OAAO;QACL,EAAE,EAAE,IAAI;QACR,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,QAAQ;QACnB,WAAW,EAAE,gCAAgC,KAAK,CAAC,UAAU,GAAG;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACT,wVAAwV;IAC1V,WAAW,EAAE,iBAAiB;IAC9B,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { countDonePhases, detectRoadmapDrift, findActiveMission, locateMission, readMissionState, readRoadmap, } from "@isaacriehm/cairn-state";
|
|
2
|
+
import { requireBootstrap } from "../bootstrap-guard.js";
|
|
3
|
+
import { mcpError } from "../errors.js";
|
|
4
|
+
import { missionGetInput } from "../schemas.js";
|
|
5
|
+
async function handler(ctx, input) {
|
|
6
|
+
const block = requireBootstrap(ctx.repoRoot);
|
|
7
|
+
if (block !== null)
|
|
8
|
+
return block;
|
|
9
|
+
const missionId = input.mission_id ?? findActiveMission(ctx.repoRoot);
|
|
10
|
+
if (missionId === null) {
|
|
11
|
+
return { ok: true, active: false };
|
|
12
|
+
}
|
|
13
|
+
const scope = locateMission(ctx.repoRoot, missionId);
|
|
14
|
+
if (scope === null) {
|
|
15
|
+
return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} not found in active or done sets`);
|
|
16
|
+
}
|
|
17
|
+
// Reading roadmap from `_done/` happens via `locateMission` returning
|
|
18
|
+
// "done"; the schema-validated reader looks at the live roadmap path
|
|
19
|
+
// for active missions only. For now `mission_get` is scoped to active
|
|
20
|
+
// missions; closed-mission inspection is a separate `cairn timeline`
|
|
21
|
+
// surface.
|
|
22
|
+
if (scope === "done") {
|
|
23
|
+
return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} is archived (use cairn_mission_reopen to inspect)`);
|
|
24
|
+
}
|
|
25
|
+
const roadmap = readRoadmap(ctx.repoRoot, missionId);
|
|
26
|
+
const state = readMissionState(ctx.repoRoot, missionId);
|
|
27
|
+
if (roadmap === null || state === null) {
|
|
28
|
+
return mcpError("MISSION_NOT_FOUND", `Mission ${missionId} state or roadmap unreadable`);
|
|
29
|
+
}
|
|
30
|
+
const drift = detectRoadmapDrift(roadmap.frontmatter, state);
|
|
31
|
+
const cursorPhaseId = state.cursor.active_phase;
|
|
32
|
+
const cursorPhase = cursorPhaseId === null
|
|
33
|
+
? null
|
|
34
|
+
: roadmap.frontmatter.phases.find((p) => p.id === cursorPhaseId) ?? null;
|
|
35
|
+
return {
|
|
36
|
+
ok: true,
|
|
37
|
+
active: true,
|
|
38
|
+
mission_id: missionId,
|
|
39
|
+
title: roadmap.frontmatter.title,
|
|
40
|
+
spec_path: roadmap.frontmatter.spec_path,
|
|
41
|
+
exit_gate: roadmap.frontmatter.exit_gate,
|
|
42
|
+
cursor: {
|
|
43
|
+
active_phase: cursorPhaseId,
|
|
44
|
+
active_phase_started_at: state.cursor.active_phase_started_at,
|
|
45
|
+
active_phase_title: cursorPhase?.title ?? null,
|
|
46
|
+
active_phase_exit_criteria: cursorPhase?.exit_criteria ?? null,
|
|
47
|
+
active_phase_exit_gate: cursorPhase?.exit_gate ?? roadmap.frontmatter.exit_gate,
|
|
48
|
+
},
|
|
49
|
+
progress: {
|
|
50
|
+
done: countDonePhases(state),
|
|
51
|
+
total: roadmap.frontmatter.phases.length,
|
|
52
|
+
},
|
|
53
|
+
drift_phase_ids: drift,
|
|
54
|
+
phase_progress: state.phase_progress,
|
|
55
|
+
phases: roadmap.frontmatter.phases,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export const missionGetTool = {
|
|
59
|
+
name: "cairn_mission_get",
|
|
60
|
+
description: "Return the active mission's state — title, spec_path, exit_gate, cursor (active_phase + exit_criteria), N/M phase progress, full phase_progress map, the ordered phase array, and any drift_phase_ids that no longer appear in roadmap.md (operator removed them mid-mission). Returns `{ active: false }` when no active mission exists.",
|
|
61
|
+
inputSchema: missionGetInput,
|
|
62
|
+
handler,
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=mission-get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-get.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-get.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cairn_mission_reopen` — un-archive a closed mission. Moves the
|
|
3
|
+
* `_done/<id>/` dirs back to live locations and clears the
|
|
4
|
+
* `outcome: done|aborted` stamp so the cursor (whatever it was at
|
|
5
|
+
* close) drives the next session. Does NOT re-execute graduated
|
|
6
|
+
* phase tasks.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDef } from "./types.js";
|
|
9
|
+
interface Input {
|
|
10
|
+
mission_id: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const missionReopenTool: ToolDef<Input>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cairn_mission_reopen` — un-archive a closed mission. Moves the
|
|
3
|
+
* `_done/<id>/` dirs back to live locations and clears the
|
|
4
|
+
* `outcome: done|aborted` stamp so the cursor (whatever it was at
|
|
5
|
+
* close) drives the next session. Does NOT re-execute graduated
|
|
6
|
+
* phase tasks.
|
|
7
|
+
*/
|
|
8
|
+
import { appendMissionJournal, findActiveMission, locateMission, readMissionState, restoreMission, writeMissionState, } from "@isaacriehm/cairn-state";
|
|
9
|
+
import { requireBootstrap } from "../bootstrap-guard.js";
|
|
10
|
+
import { mcpError } from "../errors.js";
|
|
11
|
+
import { missionReopenInput } from "../schemas.js";
|
|
12
|
+
async function handler(ctx, input) {
|
|
13
|
+
const block = requireBootstrap(ctx.repoRoot);
|
|
14
|
+
if (block !== null)
|
|
15
|
+
return block;
|
|
16
|
+
const scope = locateMission(ctx.repoRoot, input.mission_id);
|
|
17
|
+
if (scope === null) {
|
|
18
|
+
return mcpError("MISSION_NOT_FOUND", `Mission ${input.mission_id} not found`);
|
|
19
|
+
}
|
|
20
|
+
if (scope === "active") {
|
|
21
|
+
return mcpError("VALIDATION_FAILED", `Mission ${input.mission_id} is already active (no reopen needed)`);
|
|
22
|
+
}
|
|
23
|
+
if (findActiveMission(ctx.repoRoot) !== null) {
|
|
24
|
+
return mcpError("MISSION_ALREADY_ACTIVE", "Another mission is already active; close it before reopening this one (one active mission per repo).");
|
|
25
|
+
}
|
|
26
|
+
const moved = restoreMission(ctx.repoRoot, input.mission_id);
|
|
27
|
+
if (!moved) {
|
|
28
|
+
return mcpError("MISSION_NOT_FOUND", `Could not move archived dirs for ${input.mission_id}`);
|
|
29
|
+
}
|
|
30
|
+
const state = readMissionState(ctx.repoRoot, input.mission_id);
|
|
31
|
+
if (state !== null) {
|
|
32
|
+
state.outcome = "active";
|
|
33
|
+
delete state.closed_at;
|
|
34
|
+
delete state.abort_reason;
|
|
35
|
+
writeMissionState(ctx.repoRoot, input.mission_id, state);
|
|
36
|
+
}
|
|
37
|
+
const reopenedAt = new Date().toISOString();
|
|
38
|
+
appendMissionJournal(ctx.repoRoot, input.mission_id, {
|
|
39
|
+
ts: reopenedAt,
|
|
40
|
+
kind: "reopened",
|
|
41
|
+
detail: `cursor: ${state?.cursor.active_phase ?? "(none)"}`,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
ok: true,
|
|
45
|
+
mission_id: input.mission_id,
|
|
46
|
+
cursor: state?.cursor ?? null,
|
|
47
|
+
reopened_at: reopenedAt,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export const missionReopenTool = {
|
|
51
|
+
name: "cairn_mission_reopen",
|
|
52
|
+
description: "Un-archive a closed mission. Moves `.cairn/ground/missions/_done/<id>/` and `.cairn/missions/_done/<id>/` back to their live locations, resets `outcome` to active, and preserves the cursor at close-time. Refuses when another mission is already active. Does NOT re-execute graduated phase tasks.",
|
|
53
|
+
inputSchema: missionReopenInput,
|
|
54
|
+
handler,
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=mission-reopen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-reopen.js","sourceRoot":"","sources":["../../../src/mcp/tools/mission-reopen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,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;AAOnD,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,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,QAAQ,CAAC,mBAAmB,EAAE,WAAW,KAAK,CAAC,UAAU,YAAY,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,QAAQ,CACb,mBAAmB,EACnB,WAAW,KAAK,CAAC,UAAU,uCAAuC,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,QAAQ,CACb,wBAAwB,EACxB,sGAAsG,CACvG,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,QAAQ,CAAC,mBAAmB,EAAE,oCAAoC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC;QACzB,OAAO,KAAK,CAAC,SAAS,CAAC;QACvB,OAAO,KAAK,CAAC,YAAY,CAAC;QAC1B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE;QACnD,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,WAAW,KAAK,EAAE,MAAM,CAAC,YAAY,IAAI,QAAQ,EAAE;KAC5D,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,IAAI;QACR,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,IAAI;QAC7B,WAAW,EAAE,UAAU;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,wSAAwS;IAC1S,WAAW,EAAE,kBAAkB;IAC/B,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
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 type { ToolDef } from "./types.js";
|
|
11
|
+
interface Input {
|
|
12
|
+
mission_id?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const missionResumeTool: ToolDef<Input>;
|
|
15
|
+
export {};
|
|
@@ -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 {};
|