@isaacriehm/cairn-core 0.23.0 → 0.24.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/context/index.d.ts +2 -0
- package/dist/context/index.js +1 -0
- package/dist/context/index.js.map +1 -1
- package/dist/context/task-summary.d.ts +18 -0
- package/dist/context/task-summary.js +94 -23
- package/dist/context/task-summary.js.map +1 -1
- package/dist/context/working-header.d.ts +29 -0
- package/dist/context/working-header.js +125 -0
- package/dist/context/working-header.js.map +1 -0
- package/dist/hooks/post-tool-use/post-write.js +16 -0
- package/dist/hooks/post-tool-use/post-write.js.map +1 -1
- package/dist/hooks/post-tool-use/read-enricher.js +96 -4
- package/dist/hooks/post-tool-use/read-enricher.js.map +1 -1
- package/dist/hooks/runners/annotate-surface.d.ts +41 -0
- package/dist/hooks/runners/annotate-surface.js +152 -0
- package/dist/hooks/runners/annotate-surface.js.map +1 -0
- package/dist/hooks/runners/stop.js +26 -0
- package/dist/hooks/runners/stop.js.map +1 -1
- package/dist/hooks/runners/user-prompt-submit.js +59 -9
- package/dist/hooks/runners/user-prompt-submit.js.map +1 -1
- package/dist/mcp/schemas.d.ts +27 -1
- package/dist/mcp/schemas.js +22 -0
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/tools/component-annotate.d.ts +33 -0
- package/dist/mcp/tools/component-annotate.js +189 -0
- package/dist/mcp/tools/component-annotate.js.map +1 -0
- package/dist/mcp/tools/index.js +3 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/resume.js +10 -34
- package/dist/mcp/tools/resume.js.map +1 -1
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/index.js.map +1 -1
- package/dist/session/seen.d.ts +37 -0
- package/dist/session/seen.js +110 -0
- package/dist/session/seen.js.map +1 -0
- package/dist/session/touched.d.ts +17 -0
- package/dist/session/touched.js +57 -0
- package/dist/session/touched.js.map +1 -0
- package/dist/tasks/spec-reader.d.ts +27 -0
- package/dist/tasks/spec-reader.js +60 -0
- package/dist/tasks/spec-reader.js.map +1 -0
- package/package.json +2 -2
package/dist/context/index.d.ts
CHANGED
|
@@ -9,3 +9,5 @@ export { buildSpecDelta } from "./spec-delta.js";
|
|
|
9
9
|
export type { SpecDelta } from "./spec-delta.js";
|
|
10
10
|
export { readActiveTaskSummary } from "./task-summary.js";
|
|
11
11
|
export type { ActiveTaskSummary } from "./task-summary.js";
|
|
12
|
+
export { buildWorkingHeader } from "./working-header.js";
|
|
13
|
+
export type { WorkingHeader } from "./working-header.js";
|
package/dist/context/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -16,3 +16,21 @@ export interface ActiveTaskSummary {
|
|
|
16
16
|
taskModule: string;
|
|
17
17
|
}
|
|
18
18
|
export declare function readActiveTaskSummary(repoRoot: string): ActiveTaskSummary | null;
|
|
19
|
+
/**
|
|
20
|
+
* Summary for one specific active task id, or null when it is not
|
|
21
|
+
* in-flight. Used by the working-context header to render the task this
|
|
22
|
+
* session is actually on (resolved by session affinity) rather than the
|
|
23
|
+
* first/arbitrary active task.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readTaskSummaryById(repoRoot: string, taskId: string): ActiveTaskSummary | null;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve which active task THIS session is on, for multi-task /
|
|
28
|
+
* multi-window correctness. Among in-flight tasks, prefer one this
|
|
29
|
+
* session created or last journaled (`created_by_session` /
|
|
30
|
+
* `last_journal_session` on status.yaml); fall back to the most-recently
|
|
31
|
+
* touched active task. Returns null when nothing is in flight.
|
|
32
|
+
*
|
|
33
|
+
* Without this, two Claude windows on one checkout would both surface
|
|
34
|
+
* whichever task was globally first/most-recent — wrong frame.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveSessionTaskId(repoRoot: string, sessionId: string | null): string | null;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* unrecognized values collapse to `idle` so the surface stays quiet
|
|
9
9
|
* when nothing is actually in flight.
|
|
10
10
|
*/
|
|
11
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
11
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { parse as parseYaml } from "yaml";
|
|
14
14
|
import { cairnDir, parseFrontmatter } from "@isaacriehm/cairn-state";
|
|
@@ -52,8 +52,48 @@ export function readActiveTaskSummary(repoRoot) {
|
|
|
52
52
|
for (const e of dirents) {
|
|
53
53
|
if (!e.isDirectory())
|
|
54
54
|
continue;
|
|
55
|
-
const
|
|
56
|
-
|
|
55
|
+
const summary = summarizeActiveTask(join(activeDir, e.name), e.name);
|
|
56
|
+
if (summary !== null)
|
|
57
|
+
return summary;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Summary for one specific active task id, or null when it is not
|
|
63
|
+
* in-flight. Used by the working-context header to render the task this
|
|
64
|
+
* session is actually on (resolved by session affinity) rather than the
|
|
65
|
+
* first/arbitrary active task.
|
|
66
|
+
*/
|
|
67
|
+
export function readTaskSummaryById(repoRoot, taskId) {
|
|
68
|
+
return summarizeActiveTask(cairnDir(repoRoot, "tasks", "active", taskId), taskId);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve which active task THIS session is on, for multi-task /
|
|
72
|
+
* multi-window correctness. Among in-flight tasks, prefer one this
|
|
73
|
+
* session created or last journaled (`created_by_session` /
|
|
74
|
+
* `last_journal_session` on status.yaml); fall back to the most-recently
|
|
75
|
+
* touched active task. Returns null when nothing is in flight.
|
|
76
|
+
*
|
|
77
|
+
* Without this, two Claude windows on one checkout would both surface
|
|
78
|
+
* whichever task was globally first/most-recent — wrong frame.
|
|
79
|
+
*/
|
|
80
|
+
export function resolveSessionTaskId(repoRoot, sessionId) {
|
|
81
|
+
const activeDir = cairnDir(repoRoot, "tasks", "active");
|
|
82
|
+
if (!existsSync(activeDir))
|
|
83
|
+
return null;
|
|
84
|
+
let dirents;
|
|
85
|
+
try {
|
|
86
|
+
dirents = readdirSync(activeDir, { withFileTypes: true, encoding: "utf8" });
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const sid = sessionId !== null && sessionId.length > 0 ? sessionId : null;
|
|
92
|
+
const candidates = [];
|
|
93
|
+
for (const e of dirents) {
|
|
94
|
+
if (!e.isDirectory())
|
|
95
|
+
continue;
|
|
96
|
+
const statusPath = join(activeDir, e.name, "status.yaml");
|
|
57
97
|
if (!existsSync(statusPath))
|
|
58
98
|
continue;
|
|
59
99
|
let parsed;
|
|
@@ -65,29 +105,60 @@ export function readActiveTaskSummary(repoRoot) {
|
|
|
65
105
|
}
|
|
66
106
|
if (typeof parsed !== "object" || parsed === null)
|
|
67
107
|
continue;
|
|
68
|
-
const
|
|
108
|
+
const o = parsed;
|
|
109
|
+
const phase = o["phase"];
|
|
69
110
|
if (typeof phase !== "string" || !ACTIVE_PHASES.has(phase))
|
|
70
111
|
continue;
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
const specText = readFileSync(specPath, "utf8");
|
|
76
|
-
const body = parseFrontmatter(specText).body;
|
|
77
|
-
const m = body.match(/^#\s+(.+)$/m);
|
|
78
|
-
if (m && m[1])
|
|
79
|
-
title = m[1].trim();
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
// fall through to taskId
|
|
83
|
-
}
|
|
112
|
+
let mtimeMs = 0;
|
|
113
|
+
try {
|
|
114
|
+
mtimeMs = statSync(statusPath).mtimeMs;
|
|
84
115
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
116
|
+
catch {
|
|
117
|
+
// keep 0 — undated tasks sort last
|
|
118
|
+
}
|
|
119
|
+
const owned = sid !== null &&
|
|
120
|
+
(o["last_journal_session"] === sid || o["created_by_session"] === sid);
|
|
121
|
+
candidates.push({ taskId: e.name, mtimeMs, owned });
|
|
90
122
|
}
|
|
91
|
-
|
|
123
|
+
if (candidates.length === 0)
|
|
124
|
+
return null;
|
|
125
|
+
const byRecent = (a, b) => b.mtimeMs - a.mtimeMs;
|
|
126
|
+
const owned = candidates.filter((c) => c.owned).sort(byRecent);
|
|
127
|
+
if (owned.length > 0)
|
|
128
|
+
return owned[0].taskId;
|
|
129
|
+
return candidates.sort(byRecent)[0].taskId;
|
|
130
|
+
}
|
|
131
|
+
/** Read one active task dir into a summary, or null when not in-flight. */
|
|
132
|
+
function summarizeActiveTask(taskDir, taskId) {
|
|
133
|
+
const statusPath = join(taskDir, "status.yaml");
|
|
134
|
+
if (!existsSync(statusPath))
|
|
135
|
+
return null;
|
|
136
|
+
let parsed;
|
|
137
|
+
try {
|
|
138
|
+
parsed = parseYaml(readFileSync(statusPath, "utf8"));
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
144
|
+
return null;
|
|
145
|
+
const phase = parsed.phase;
|
|
146
|
+
if (typeof phase !== "string" || !ACTIVE_PHASES.has(phase))
|
|
147
|
+
return null;
|
|
148
|
+
let title = taskId;
|
|
149
|
+
const specPath = join(taskDir, "spec.tightened.md");
|
|
150
|
+
if (existsSync(specPath)) {
|
|
151
|
+
try {
|
|
152
|
+
const specText = readFileSync(specPath, "utf8");
|
|
153
|
+
const body = parseFrontmatter(specText).body;
|
|
154
|
+
const m = body.match(/^#\s+(.+)$/m);
|
|
155
|
+
if (m && m[1])
|
|
156
|
+
title = m[1].trim();
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// fall through to taskId
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { taskId, taskState: mapPhase(phase), taskModule: title };
|
|
92
163
|
}
|
|
93
164
|
//# sourceMappingURL=task-summary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-summary.js","sourceRoot":"","sources":["../../src/context/task-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAe,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"task-summary.js","sourceRoot":"","sources":["../../src/context/task-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working-context header — the context engine's stage-1 surface.
|
|
3
|
+
*
|
|
4
|
+
* Per prompt (UserPromptSubmit), the server injects a compact "what am
|
|
5
|
+
* I working on" frame so the agent never has to call `cairn_in_scope` /
|
|
6
|
+
* `cairn_mission_get` to know its frame. This module builds that text +
|
|
7
|
+
* a fingerprint; the runner injects it only when the fingerprint
|
|
8
|
+
* changed (per-session dedup via session/seen.ts).
|
|
9
|
+
*
|
|
10
|
+
* The header is the PERSISTENT in-scope id INDEX (every prompt) — ids
|
|
11
|
+
* only, no bodies. The stage-2 read-enricher shows each DEC/INV/
|
|
12
|
+
* component BODY once per session. So the agent always knows WHAT is in
|
|
13
|
+
* scope (this header) even after a body scrolled off (D13).
|
|
14
|
+
*
|
|
15
|
+
* Pure-FS, zero LLM — safe to run on every prompt inside a hook.
|
|
16
|
+
*
|
|
17
|
+
* Spec: docs/CONTEXT_ENGINE.md (stage 1), CAIRN_REBUILD §6 / D11–D13.
|
|
18
|
+
*/
|
|
19
|
+
export interface WorkingHeader {
|
|
20
|
+
text: string;
|
|
21
|
+
fingerprint: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the working-context header for the repo's current frame, or
|
|
25
|
+
* null when there is no active task AND no active mission (D11 — inject
|
|
26
|
+
* nothing extra). When a task is active but has no in-scope ids, the
|
|
27
|
+
* "In scope" line is omitted (active-task line only).
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildWorkingHeader(repoRoot: string, sessionId: string | null): WorkingHeader | null;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working-context header — the context engine's stage-1 surface.
|
|
3
|
+
*
|
|
4
|
+
* Per prompt (UserPromptSubmit), the server injects a compact "what am
|
|
5
|
+
* I working on" frame so the agent never has to call `cairn_in_scope` /
|
|
6
|
+
* `cairn_mission_get` to know its frame. This module builds that text +
|
|
7
|
+
* a fingerprint; the runner injects it only when the fingerprint
|
|
8
|
+
* changed (per-session dedup via session/seen.ts).
|
|
9
|
+
*
|
|
10
|
+
* The header is the PERSISTENT in-scope id INDEX (every prompt) — ids
|
|
11
|
+
* only, no bodies. The stage-2 read-enricher shows each DEC/INV/
|
|
12
|
+
* component BODY once per session. So the agent always knows WHAT is in
|
|
13
|
+
* scope (this header) even after a body scrolled off (D13).
|
|
14
|
+
*
|
|
15
|
+
* Pure-FS, zero LLM — safe to run on every prompt inside a hook.
|
|
16
|
+
*
|
|
17
|
+
* Spec: docs/CONTEXT_ENGINE.md (stage 1), CAIRN_REBUILD §6 / D11–D13.
|
|
18
|
+
*/
|
|
19
|
+
import { cairnDir, findActiveMission, readMissionState, readRoadmap, } from "@isaacriehm/cairn-state";
|
|
20
|
+
import { resolveSessionTaskId, readTaskSummaryById } from "./task-summary.js";
|
|
21
|
+
import { readTaskMissionAnchor } from "../missions/index.js";
|
|
22
|
+
import { readTaskSpec } from "../tasks/spec-reader.js";
|
|
23
|
+
import { fingerprintText } from "../session/seen.js";
|
|
24
|
+
const GOAL_MAX = 120;
|
|
25
|
+
const ID_LIST_CAP = 12;
|
|
26
|
+
/** Truncate at a word boundary, appending `…` when cut. */
|
|
27
|
+
function truncateAtWord(s, max) {
|
|
28
|
+
const flat = s.replace(/\s+/g, " ").trim();
|
|
29
|
+
if (flat.length <= max)
|
|
30
|
+
return flat;
|
|
31
|
+
const slice = flat.slice(0, max);
|
|
32
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
33
|
+
const cut = lastSpace > max * 0.6 ? slice.slice(0, lastSpace) : slice;
|
|
34
|
+
return `${cut.trimEnd()}…`;
|
|
35
|
+
}
|
|
36
|
+
/** Render up to `cap` ids, then `(+N more)`. Empty → "". */
|
|
37
|
+
function renderIdList(ids, cap) {
|
|
38
|
+
if (ids.length === 0)
|
|
39
|
+
return "";
|
|
40
|
+
const head = ids.slice(0, cap);
|
|
41
|
+
const extra = ids.length - head.length;
|
|
42
|
+
const base = head.join(", ");
|
|
43
|
+
return extra > 0 ? `${base} (+${extra} more)` : base;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build the working-context header for the repo's current frame, or
|
|
47
|
+
* null when there is no active task AND no active mission (D11 — inject
|
|
48
|
+
* nothing extra). When a task is active but has no in-scope ids, the
|
|
49
|
+
* "In scope" line is omitted (active-task line only).
|
|
50
|
+
*/
|
|
51
|
+
export function buildWorkingHeader(repoRoot, sessionId) {
|
|
52
|
+
// Resolve the task THIS session is on (affinity), not a global pick —
|
|
53
|
+
// correct when multiple tasks are active across windows.
|
|
54
|
+
const taskId = resolveSessionTaskId(repoRoot, sessionId);
|
|
55
|
+
const active = taskId !== null ? readTaskSummaryById(repoRoot, taskId) : null;
|
|
56
|
+
// Mission: prefer the resolved task's own anchor (the mission + phase
|
|
57
|
+
// this session is working) over a global scan — correct when several
|
|
58
|
+
// missions are active. Fall back to the single active mission only
|
|
59
|
+
// when there's no task to anchor on.
|
|
60
|
+
const anchor = active !== null ? readTaskMissionAnchor(repoRoot, active.taskId) : null;
|
|
61
|
+
const missionId = anchor?.mission_id ?? findActiveMission(repoRoot);
|
|
62
|
+
const preferredPhaseId = anchor?.phase_id ?? null;
|
|
63
|
+
if (active === null && missionId === null)
|
|
64
|
+
return null;
|
|
65
|
+
const lines = ["## Cairn — working context"];
|
|
66
|
+
let hasInScope = false;
|
|
67
|
+
if (active !== null) {
|
|
68
|
+
const spec = readTaskSpec(cairnDir(repoRoot, "tasks", "active", active.taskId));
|
|
69
|
+
const goal = spec !== null && spec.goal.length > 0 ? spec.goal : "";
|
|
70
|
+
const parts = [`Active: ${active.taskId} (${active.taskState})`];
|
|
71
|
+
if (goal.length > 0)
|
|
72
|
+
parts.push(`— ${truncateAtWord(goal, GOAL_MAX)}`);
|
|
73
|
+
if (active.taskModule.length > 0 && active.taskModule !== active.taskId) {
|
|
74
|
+
parts.push(`· module ${active.taskModule}`);
|
|
75
|
+
}
|
|
76
|
+
lines.push(parts.join(" "));
|
|
77
|
+
const decs = spec?.inScopeDecisions ?? [];
|
|
78
|
+
const invs = spec?.inScopeInvariants ?? [];
|
|
79
|
+
if (decs.length > 0 || invs.length > 0) {
|
|
80
|
+
hasInScope = true;
|
|
81
|
+
const segs = [];
|
|
82
|
+
if (decs.length > 0)
|
|
83
|
+
segs.push(renderIdList(decs, ID_LIST_CAP));
|
|
84
|
+
if (invs.length > 0)
|
|
85
|
+
segs.push(renderIdList(invs, ID_LIST_CAP));
|
|
86
|
+
lines.push(`In scope: ${segs.join(" · ")}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (missionId !== null) {
|
|
90
|
+
const missionLine = renderMissionLine(repoRoot, missionId, preferredPhaseId);
|
|
91
|
+
if (missionLine !== null)
|
|
92
|
+
lines.push(missionLine);
|
|
93
|
+
}
|
|
94
|
+
if (hasInScope) {
|
|
95
|
+
lines.push("Bodies on demand: cairn_decision_get / cairn_invariant_get.");
|
|
96
|
+
}
|
|
97
|
+
const text = lines.join("\n");
|
|
98
|
+
return { text, fingerprint: fingerprintText(text) };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* `Mission: <title> — phase <i>/<n> "<phase title>"`. Degrades to a
|
|
102
|
+
* title-only line when the cursor phase can't be located, and to null
|
|
103
|
+
* when the mission state/roadmap is unreadable (D-graceful: never throw).
|
|
104
|
+
*/
|
|
105
|
+
function renderMissionLine(repoRoot, missionId, preferredPhaseId) {
|
|
106
|
+
const roadmap = readRoadmap(repoRoot, missionId);
|
|
107
|
+
const state = readMissionState(repoRoot, missionId);
|
|
108
|
+
if (roadmap === null)
|
|
109
|
+
return null;
|
|
110
|
+
const title = roadmap.frontmatter.title;
|
|
111
|
+
const phases = roadmap.frontmatter.phases;
|
|
112
|
+
// The task anchor's phase wins (the phase THIS session is working);
|
|
113
|
+
// fall back to the mission cursor when there's no task anchor.
|
|
114
|
+
const activePhase = preferredPhaseId ?? state?.cursor.active_phase ?? null;
|
|
115
|
+
if (activePhase !== null) {
|
|
116
|
+
const idx = phases.findIndex((p) => p.id === activePhase);
|
|
117
|
+
if (idx >= 0) {
|
|
118
|
+
const phase = phases[idx];
|
|
119
|
+
const phaseTitle = phase !== undefined ? phase.title : activePhase;
|
|
120
|
+
return `Mission: ${title} — phase ${idx + 1}/${phases.length} "${phaseTitle}"`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return `Mission: ${title}`;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=working-header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"working-header.js","sourceRoot":"","sources":["../../src/context/working-header.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { relative, resolve } from "node:path";
|
|
10
10
|
import { resolveRepoRoot } from "../../session-start/index.js";
|
|
11
|
+
import { appendTouched } from "../../session/index.js";
|
|
11
12
|
import { readHookStdin } from "../runners/payload.js";
|
|
12
13
|
import { executeSotAlign } from "./sot-align.js";
|
|
13
14
|
import { executeWriteGuardian } from "./write-guardian.js";
|
|
@@ -93,6 +94,21 @@ export async function runPostWriteHook() {
|
|
|
93
94
|
// gitignore / glob / scope-index lookups all expect a repo-relative
|
|
94
95
|
// path, so normalize here before handing it over.
|
|
95
96
|
const relPath = relative(repoRoot, resolve(cwd, filePath));
|
|
97
|
+
// Stage-3 (D6): record the touched path so the Stop capture-gate can
|
|
98
|
+
// later filter to component-dir files missing a @cairn header. Best-
|
|
99
|
+
// effort, before the guard block — PostToolUse fires after the write
|
|
100
|
+
// landed, so the file is on disk regardless of the guard hint.
|
|
101
|
+
const sessionId = typeof payload.session_id === "string" && payload.session_id.length > 0
|
|
102
|
+
? payload.session_id
|
|
103
|
+
: null;
|
|
104
|
+
if (sessionId !== null) {
|
|
105
|
+
try {
|
|
106
|
+
appendTouched(repoRoot, sessionId, relPath);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// best-effort — never affect the write
|
|
110
|
+
}
|
|
111
|
+
}
|
|
96
112
|
const guard = executeWriteGuardian({
|
|
97
113
|
repoRoot,
|
|
98
114
|
relPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-write.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/post-write.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,GAAG,GAAG,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAErD,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,mBAAmB;QACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,mBAAmB;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC/B,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC3B,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC;QACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9B,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC,WAAW,EAAE,CAAC;AAkBjB,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,8BAA8B,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,iBAAyB;IAC3C,MAAM,GAAG,GAA4B;QACnC,QAAQ,EAAE,IAAI;QACd,kBAAkB,EAAE;YAClB,aAAa,EAAE,aAAa;YAC5B,iBAAiB;SAClB;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,GAAG,GAA2B;QAClC,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,OAAO;QACjB,MAAM;KACP,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAElC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;QAC/B,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACxC,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpD,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,8BAA8B;QAC9B,6CAA6C;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,MAAM,IAAI,EAAE,CAAC;QACrH,gEAAgE;QAChE,oEAAoE;QACpE,kDAAkD;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"post-write.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/post-write.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { resolve, relative } from "node:path";
|
|
16
16
|
import { z } from "zod";
|
|
17
|
-
import { getDecisionsLedger, getInvariantsLedger, getScopeIndexEntry, } from "@isaacriehm/cairn-state";
|
|
17
|
+
import { componentsInScope, getDecisionsLedger, getInvariantsLedger, getScopeIndexEntry, hasComponentConfig, loadComponentsConfig, } from "@isaacriehm/cairn-state";
|
|
18
18
|
import { readHookStdin, emitShapeB, appendTelemetry, } from "../runners/payload.js";
|
|
19
19
|
import { resolveRepoRoot } from "../../session-start/index.js";
|
|
20
20
|
import { scanCitations } from "./citation-scanner.js";
|
|
21
21
|
import { buildLegend } from "./legend-builder.js";
|
|
22
|
+
import { filterUnshownIds, hasShownId, markShownIds } from "../../session/index.js";
|
|
22
23
|
import { logger } from "../../logger.js";
|
|
23
24
|
const MAX_CONTENT_BYTES = 512_000;
|
|
24
25
|
const BINARY_SAMPLE_BYTES = 1024;
|
|
@@ -86,21 +87,88 @@ export async function runReadEnricher() {
|
|
|
86
87
|
emitShapeB("", "PostToolUse");
|
|
87
88
|
return;
|
|
88
89
|
}
|
|
90
|
+
const sessionId = typeof payload.session_id === "string" && payload.session_id.length > 0
|
|
91
|
+
? payload.session_id
|
|
92
|
+
: null;
|
|
89
93
|
const citations = scanCitations(content);
|
|
90
94
|
const scopeEntry = getScopeIndexEntry(repoRoot, relPath);
|
|
91
95
|
const decisionsLedger = getDecisionsLedger(repoRoot);
|
|
92
96
|
const invariantsLedger = getInvariantsLedger(repoRoot);
|
|
93
|
-
|
|
97
|
+
// Stage-2 dedup (D13): the stage-1 working header carries the
|
|
98
|
+
// persistent in-scope id INDEX, so the enricher renders each cited
|
|
99
|
+
// DEC/INV BODY at most once per session. Re-reads of the same file
|
|
100
|
+
// no longer re-inject the (bulky) title lines.
|
|
101
|
+
const citedIds = [
|
|
102
|
+
...citations.decisions.map((d) => d.id),
|
|
103
|
+
...citations.invariants.map((i) => i.id),
|
|
104
|
+
];
|
|
105
|
+
const freshIds = sessionId !== null
|
|
106
|
+
? new Set(filterUnshownIds(repoRoot, sessionId, citedIds))
|
|
107
|
+
: new Set(citedIds);
|
|
108
|
+
const freshCitations = {
|
|
109
|
+
decisions: citations.decisions.filter((d) => freshIds.has(d.id)),
|
|
110
|
+
invariants: citations.invariants.filter((i) => freshIds.has(i.id)),
|
|
111
|
+
};
|
|
112
|
+
// The stage-1 working header is the persistent in-scope id index, so
|
|
113
|
+
// the enricher's file-scope box ("Decisions/Invariants in scope")
|
|
114
|
+
// renders at most once per file per session. Without this, every
|
|
115
|
+
// re-read of a scoped file re-injects the box — the over-injection
|
|
116
|
+
// the engine exists to avoid (D13).
|
|
117
|
+
const scopeKey = `scope:${relPath}`;
|
|
118
|
+
const showScope = scopeEntry !== null &&
|
|
119
|
+
(sessionId === null || !hasShownId(repoRoot, sessionId, scopeKey));
|
|
120
|
+
const legend = buildLegend(freshCitations, invariantsLedger, decisionsLedger, showScope ? scopeEntry : null);
|
|
121
|
+
// Stage-2 component slice (D17): when the agent reads a file under a
|
|
122
|
+
// component dir, attach the entitled inventory (name · category ·
|
|
123
|
+
// purpose · [S]) once per component per session — replacing the
|
|
124
|
+
// agent's need to classify "UI work" and call components_in_scope.
|
|
125
|
+
let componentSlice = "";
|
|
126
|
+
const shownComponentKeys = [];
|
|
127
|
+
try {
|
|
128
|
+
const config = loadComponentsConfig(repoRoot);
|
|
129
|
+
if (hasComponentConfig(config) && fileInComponentDir(config, relPath)) {
|
|
130
|
+
const scope = componentsInScope(repoRoot, [relPath]);
|
|
131
|
+
const keys = scope.components.map((c) => `comp:${c.name}`);
|
|
132
|
+
const freshCompKeys = sessionId !== null
|
|
133
|
+
? new Set(filterUnshownIds(repoRoot, sessionId, keys))
|
|
134
|
+
: new Set(keys);
|
|
135
|
+
const freshComponents = scope.components.filter((c) => freshCompKeys.has(`comp:${c.name}`));
|
|
136
|
+
if (freshComponents.length > 0) {
|
|
137
|
+
componentSlice = renderComponentSlice(freshComponents);
|
|
138
|
+
for (const c of freshComponents)
|
|
139
|
+
shownComponentKeys.push(`comp:${c.name}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// component config is optional — never block the read on it
|
|
145
|
+
}
|
|
146
|
+
// Mark shown AFTER building so a crash before this point leaves the
|
|
147
|
+
// ids un-shown (they surface on the next read instead of vanishing).
|
|
148
|
+
if (sessionId !== null) {
|
|
149
|
+
const toMark = [
|
|
150
|
+
...freshIds,
|
|
151
|
+
...shownComponentKeys,
|
|
152
|
+
...(showScope ? [scopeKey] : []),
|
|
153
|
+
];
|
|
154
|
+
if (toMark.length > 0)
|
|
155
|
+
markShownIds(repoRoot, sessionId, toMark);
|
|
156
|
+
}
|
|
157
|
+
const combined = [legend ?? "", componentSlice]
|
|
158
|
+
.filter((s) => s.length > 0)
|
|
159
|
+
.join("\n\n");
|
|
94
160
|
outcome = {
|
|
95
161
|
ok: true,
|
|
96
162
|
path: relPath,
|
|
97
163
|
citations: {
|
|
98
164
|
invariants: citations.invariants.length,
|
|
99
165
|
decisions: citations.decisions.length,
|
|
166
|
+
fresh: freshCitations.invariants.length + freshCitations.decisions.length,
|
|
100
167
|
},
|
|
101
|
-
|
|
168
|
+
components_shown: shownComponentKeys.length,
|
|
169
|
+
legend_chars: combined.length,
|
|
102
170
|
};
|
|
103
|
-
emitShapeB(
|
|
171
|
+
emitShapeB(combined, "PostToolUse");
|
|
104
172
|
}
|
|
105
173
|
catch (err) {
|
|
106
174
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -164,4 +232,28 @@ function isBinary(content) {
|
|
|
164
232
|
}
|
|
165
233
|
return nullCount / sampleLen > BINARY_THRESHOLD;
|
|
166
234
|
}
|
|
235
|
+
/** True when `relPath` sits inside any workspace's component dir. */
|
|
236
|
+
function fileInComponentDir(config, relPath) {
|
|
237
|
+
const p = relPath.replace(/\\/g, "/");
|
|
238
|
+
for (const ws of config.workspaces) {
|
|
239
|
+
for (const dir of ws.componentDirs) {
|
|
240
|
+
if (p === dir || p.startsWith(`${dir}/`))
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
/** Render the deduped component slice (D17): name · category · purpose · [S]. */
|
|
247
|
+
function renderComponentSlice(components) {
|
|
248
|
+
const lines = [
|
|
249
|
+
"## Cairn — components in scope (USE > EXTEND > CREATE)",
|
|
250
|
+
];
|
|
251
|
+
for (const c of components) {
|
|
252
|
+
const flag = c.singleton ? " [S]" : "";
|
|
253
|
+
const purpose = c.purpose.length > 0 ? ` · ${c.purpose}` : "";
|
|
254
|
+
lines.push(`- ${c.name} · ${c.category}${purpose}${flag}`);
|
|
255
|
+
}
|
|
256
|
+
lines.push("`[S]` = singleton: extend in place, never fork or rebuild.");
|
|
257
|
+
return lines.join("\n");
|
|
258
|
+
}
|
|
167
259
|
//# sourceMappingURL=read-enricher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-enricher.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/read-enricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"read-enricher.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/read-enricher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component-annotate capture-gate surface (context engine, stage 3).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors phase-ready-surface: the Stop hook detects components the
|
|
5
|
+
* session touched that still lack a `@cairn` header, pre-derives their
|
|
6
|
+
* mechanical fields (export symbol, allowed categories), and stashes a
|
|
7
|
+
* fully-specified ask to `.cairn/sessions/<id>/annotate-pending.json`.
|
|
8
|
+
* The next UserPromptSubmit injects it as `additionalContext` — inject-
|
|
9
|
+
* only, no Stop block. The pre-commit component check is the hard
|
|
10
|
+
* backstop; this is the deferred nudge.
|
|
11
|
+
*
|
|
12
|
+
* The agent supplies only judgment (category, purpose, aliases); the
|
|
13
|
+
* server holds the grammar + validation in `cairn_component_annotate`.
|
|
14
|
+
*
|
|
15
|
+
* Spec: docs/CONTEXT_ENGINE.md (stage 3), CAIRN_REBUILD §8 / D5–D9.
|
|
16
|
+
*/
|
|
17
|
+
export interface AnnotateAsk {
|
|
18
|
+
/** Repo-relative POSIX path of the component file missing a header. */
|
|
19
|
+
file: string;
|
|
20
|
+
/** Best-effort detected export symbol, or null when undetectable. */
|
|
21
|
+
export_name: string | null;
|
|
22
|
+
/** The owning workspace's allowed `@category` taxonomy. */
|
|
23
|
+
categories: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Collect the component-dir files this session touched that still lack a
|
|
27
|
+
* `@cairn` header, skipping any already surfaced (`annotate:<file>` in
|
|
28
|
+
* seen.shownIds — the once-per-component debounce, D5). Pure read; the
|
|
29
|
+
* caller marks shown after stashing. Returns [] for non-component repos.
|
|
30
|
+
*/
|
|
31
|
+
export declare function collectAnnotateAsks(repoRoot: string, sessionId: string): AnnotateAsk[];
|
|
32
|
+
/** Persist the asks for the next UPS to inject. Latest set wins. */
|
|
33
|
+
export declare function writeAnnotatePending(repoRoot: string, sessionId: string, asks: AnnotateAsk[]): void;
|
|
34
|
+
/** Read + delete the pending file (show-once). Null when absent/malformed. */
|
|
35
|
+
export declare function readAndConsumeAnnotatePending(repoRoot: string, sessionId: string): AnnotateAsk[] | null;
|
|
36
|
+
/**
|
|
37
|
+
* Render the fully-specified annotate ask. The agent supplies only
|
|
38
|
+
* judgment; the `cairn_component_annotate` call template carries the
|
|
39
|
+
* mechanical fields the server already derived.
|
|
40
|
+
*/
|
|
41
|
+
export declare function renderAnnotateHint(asks: AnnotateAsk[]): string;
|