claudelink 1.4.3 → 1.5.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/README.md +34 -1
- package/dist/arm-compact.d.ts +2 -0
- package/dist/arm-compact.js +182 -0
- package/dist/arm-compact.js.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -1
- package/dist/compact-analyzer.d.ts +67 -0
- package/dist/compact-analyzer.js +309 -0
- package/dist/compact-analyzer.js.map +1 -0
- package/dist/compact-decision.d.ts +19 -0
- package/dist/compact-decision.js +47 -0
- package/dist/compact-decision.js.map +1 -0
- package/dist/compact-executor.d.ts +27 -0
- package/dist/compact-executor.js +160 -0
- package/dist/compact-executor.js.map +1 -0
- package/dist/context-watcher-settings.d.ts +21 -0
- package/dist/context-watcher-settings.js +176 -0
- package/dist/context-watcher-settings.js.map +1 -0
- package/dist/context-watcher.d.ts +70 -0
- package/dist/context-watcher.js +1005 -0
- package/dist/context-watcher.js.map +1 -0
- package/dist/db.d.ts +22 -1
- package/dist/db.js +184 -5
- package/dist/db.js.map +1 -1
- package/dist/hooks/stop-hook.js +30 -1
- package/dist/hooks/stop-hook.js.map +1 -1
- package/dist/index.js +144 -12
- package/dist/index.js.map +1 -1
- package/dist/manual-decision.d.ts +23 -0
- package/dist/manual-decision.js +67 -0
- package/dist/manual-decision.js.map +1 -0
- package/dist/prompt-clear.d.ts +8 -0
- package/dist/prompt-clear.js +33 -0
- package/dist/prompt-clear.js.map +1 -0
- package/dist/recovery-watcher.d.ts +6 -0
- package/dist/recovery-watcher.js +20 -0
- package/dist/recovery-watcher.js.map +1 -1
- package/dist/role-collision.d.ts +6 -0
- package/dist/role-collision.js +51 -0
- package/dist/role-collision.js.map +1 -0
- package/dist/ui-server.d.ts +4 -0
- package/dist/ui-server.js +899 -20
- package/dist/ui-server.js.map +1 -1
- package/dist/usage-reader.d.ts +79 -0
- package/dist/usage-reader.js +553 -0
- package/dist/usage-reader.js.map +1 -0
- package/package.json +8 -2
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Compact-loss analyzer (read-only) — the calibration engine for intelligent
|
|
3
|
+
// auto-compact. Scans the fleet's existing transcripts for compact events and,
|
|
4
|
+
// for each, records the ground-truth effect + four intelligence-LOSS signals
|
|
5
|
+
// in the surrounding turns. Run on NATURALLY-OCCURRING compacts (the founder's
|
|
6
|
+
// manual /compact discipline + Claude Code's built-in auto-compact), so we
|
|
7
|
+
// build a labeled loss dataset and validate the heuristics BEFORE the watcher
|
|
8
|
+
// ever auto-triggers one. No injection, no terminal contact.
|
|
9
|
+
//
|
|
10
|
+
// Ground truth is exact: Claude Code records each compact as a transcript line
|
|
11
|
+
// { type:"system", subtype:"compact_boundary",
|
|
12
|
+
// compactMetadata:{ trigger:"auto"|"manual", preTokens, postTokens, durationMs } }
|
|
13
|
+
// so we know the real context size before/after — no estimation.
|
|
14
|
+
//
|
|
15
|
+
// CAVEAT (carried into the case study): manual compacts fire at task
|
|
16
|
+
// boundaries; the auto-trigger fires at an economic threshold (mid-task). These
|
|
17
|
+
// are different populations. This analyzer validates the loss-signal DETECTION
|
|
18
|
+
// MECHANICS on real events; the loss RATES it reports for manual compacts are
|
|
19
|
+
// NOT extrapolatable to auto-trigger rates — the armed soak measures those.
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.pathALossBaseline = pathALossBaseline;
|
|
25
|
+
exports.analyzeCompactEvents = analyzeCompactEvents;
|
|
26
|
+
const fs_1 = __importDefault(require("fs"));
|
|
27
|
+
const path_1 = __importDefault(require("path"));
|
|
28
|
+
const readline_1 = __importDefault(require("readline"));
|
|
29
|
+
const usage_reader_js_1 = require("./usage-reader.js");
|
|
30
|
+
// Window sizes (in real user/assistant turns) for signal computation, kept
|
|
31
|
+
// tight so legitimate repeats far from a compact don't register as loss.
|
|
32
|
+
const PRE_WINDOW = 12;
|
|
33
|
+
const POST_WINDOW = 12;
|
|
34
|
+
const REEXPLAIN_CHARS = 1500; // a human user message longer than this = re-explain
|
|
35
|
+
// Primary distinguishing argument per tool, so a signature captures "same
|
|
36
|
+
// action" without being so loose it matches everything.
|
|
37
|
+
function toolSignature(name, input) {
|
|
38
|
+
const i = input || {};
|
|
39
|
+
if (name === "Bash")
|
|
40
|
+
return "Bash:" + String(i.command || "").slice(0, 80);
|
|
41
|
+
if (["Read", "Edit", "Write", "NotebookEdit"].includes(name))
|
|
42
|
+
return name + ":" + (i.file_path || "");
|
|
43
|
+
if (["Grep", "Glob"].includes(name))
|
|
44
|
+
return name + ":" + (i.pattern || i.glob || "");
|
|
45
|
+
// generic: name + a short stable slice of the args
|
|
46
|
+
try {
|
|
47
|
+
return name + ":" + JSON.stringify(i).slice(0, 80);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return name;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const READ_TOOLS = new Set(["Read", "Grep", "Glob"]);
|
|
54
|
+
function parseTurn(o, prevWasBoundary) {
|
|
55
|
+
const t = o?.type;
|
|
56
|
+
if (t !== "user" && t !== "assistant")
|
|
57
|
+
return null;
|
|
58
|
+
const m = o?.message;
|
|
59
|
+
if (!m)
|
|
60
|
+
return null;
|
|
61
|
+
const toolSigs = [];
|
|
62
|
+
const readSigs = [];
|
|
63
|
+
let text = "";
|
|
64
|
+
let isToolResult = false;
|
|
65
|
+
if (Array.isArray(m.content)) {
|
|
66
|
+
for (const b of m.content) {
|
|
67
|
+
if (!b || typeof b !== "object")
|
|
68
|
+
continue;
|
|
69
|
+
if (b.type === "tool_use") {
|
|
70
|
+
const sig = toolSignature(b.name, b.input);
|
|
71
|
+
toolSigs.push(sig);
|
|
72
|
+
if (READ_TOOLS.has(b.name))
|
|
73
|
+
readSigs.push(sig);
|
|
74
|
+
}
|
|
75
|
+
else if (b.type === "text") {
|
|
76
|
+
text += b.text || "";
|
|
77
|
+
}
|
|
78
|
+
else if (b.type === "tool_result") {
|
|
79
|
+
isToolResult = true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (typeof m.content === "string") {
|
|
84
|
+
text = m.content;
|
|
85
|
+
}
|
|
86
|
+
// A user line that is purely a tool_result is not a human turn; skip for
|
|
87
|
+
// re-explain purposes but it's still a turn for recovery counting.
|
|
88
|
+
return {
|
|
89
|
+
role: t,
|
|
90
|
+
text,
|
|
91
|
+
textLen: text.length,
|
|
92
|
+
toolSigs,
|
|
93
|
+
readSigs,
|
|
94
|
+
// The compact summary is the large user message immediately after the
|
|
95
|
+
// boundary (and is flagged by the harness as a compact summary in content).
|
|
96
|
+
isCompactSummary: t === "user" && prevWasBoundary && !isToolResult && text.length > 0,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async function analyzeFile(file, seenBoundaries, out, projectLabel, roles) {
|
|
100
|
+
const seq = [];
|
|
101
|
+
let prevWasBoundary = false;
|
|
102
|
+
const rl = readline_1.default.createInterface({ input: fs_1.default.createReadStream(file, { encoding: "utf-8" }), crlfDelay: Infinity });
|
|
103
|
+
for await (const line of rl) {
|
|
104
|
+
let o;
|
|
105
|
+
try {
|
|
106
|
+
o = JSON.parse(line);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (o?.type === "system" && o?.subtype === "compact_boundary") {
|
|
112
|
+
seq.push({ kind: "boundary", meta: o.compactMetadata || {}, uuid: o.uuid || `${file}:${seq.length}` });
|
|
113
|
+
prevWasBoundary = true;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const turn = parseTurn(o, prevWasBoundary);
|
|
117
|
+
if (turn) {
|
|
118
|
+
seq.push({ kind: "turn", turn });
|
|
119
|
+
prevWasBoundary = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Index the turn positions for windowing.
|
|
123
|
+
for (let i = 0; i < seq.length; i++) {
|
|
124
|
+
const it = seq[i];
|
|
125
|
+
if (it.kind !== "boundary")
|
|
126
|
+
continue;
|
|
127
|
+
if (seenBoundaries.has(it.uuid))
|
|
128
|
+
continue; // dedupe forked re-emits
|
|
129
|
+
seenBoundaries.add(it.uuid);
|
|
130
|
+
const meta = it.meta;
|
|
131
|
+
const pre = meta.preTokens ?? null;
|
|
132
|
+
const post = meta.postTokens ?? null;
|
|
133
|
+
// Gather pre/post turns (real turns only) within the windows.
|
|
134
|
+
const preTurns = [];
|
|
135
|
+
for (let j = i - 1; j >= 0 && preTurns.length < PRE_WINDOW; j--) {
|
|
136
|
+
if (seq[j].kind === "turn")
|
|
137
|
+
preTurns.push(seq[j].turn);
|
|
138
|
+
}
|
|
139
|
+
const postTurns = [];
|
|
140
|
+
for (let j = i + 1; j < seq.length && postTurns.length < POST_WINDOW; j++) {
|
|
141
|
+
if (seq[j].kind === "turn")
|
|
142
|
+
postTurns.push(seq[j].turn);
|
|
143
|
+
if (seq[j].kind === "boundary")
|
|
144
|
+
break; // stop at the next compact
|
|
145
|
+
}
|
|
146
|
+
const preToolSigs = new Set();
|
|
147
|
+
const preReadSigs = new Set();
|
|
148
|
+
for (const t of preTurns) {
|
|
149
|
+
t.toolSigs.forEach((s) => preToolSigs.add(s));
|
|
150
|
+
t.readSigs.forEach((s) => preReadSigs.add(s));
|
|
151
|
+
}
|
|
152
|
+
let reworkHits = 0;
|
|
153
|
+
let refetchHits = 0;
|
|
154
|
+
let turnsToRecover = null;
|
|
155
|
+
let userReexplain = false;
|
|
156
|
+
let recoverCount = 0;
|
|
157
|
+
for (const t of postTurns) {
|
|
158
|
+
recoverCount++;
|
|
159
|
+
// rework: a post-compact tool action whose signature appeared pre-compact
|
|
160
|
+
for (const s of t.toolSigs)
|
|
161
|
+
if (preToolSigs.has(s))
|
|
162
|
+
reworkHits++;
|
|
163
|
+
// refetch (re-ask proxy): a post-compact read of something read pre-compact
|
|
164
|
+
for (const s of t.readSigs)
|
|
165
|
+
if (preReadSigs.has(s))
|
|
166
|
+
refetchHits++;
|
|
167
|
+
// recovery: first post-compact assistant turn issuing a NEW tool action
|
|
168
|
+
if (turnsToRecover === null && t.role === "assistant") {
|
|
169
|
+
const hasNew = t.toolSigs.some((s) => !preToolSigs.has(s));
|
|
170
|
+
if (hasNew)
|
|
171
|
+
turnsToRecover = recoverCount;
|
|
172
|
+
}
|
|
173
|
+
// re-explain: a human user message (not the summary, not a tool_result)
|
|
174
|
+
// longer than the threshold
|
|
175
|
+
if (!t.isCompactSummary && t.role === "user" && t.toolSigs.length === 0 && t.textLen > REEXPLAIN_CHARS) {
|
|
176
|
+
userReexplain = true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
out.push({
|
|
180
|
+
project: projectLabel,
|
|
181
|
+
roles,
|
|
182
|
+
trigger: meta.trigger ?? null,
|
|
183
|
+
preTokens: pre,
|
|
184
|
+
postTokens: post,
|
|
185
|
+
reductionPct: pre && post && pre > 0 ? Math.round((100 * (pre - post)) / pre) : null,
|
|
186
|
+
durationMs: meta.durationMs ?? null,
|
|
187
|
+
reworkHits,
|
|
188
|
+
refetchHits,
|
|
189
|
+
turnsToRecover,
|
|
190
|
+
userReexplain,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function median(nums) {
|
|
195
|
+
if (nums.length === 0)
|
|
196
|
+
return 0;
|
|
197
|
+
const s = [...nums].sort((a, b) => a - b);
|
|
198
|
+
return s[Math.floor(s.length / 2)];
|
|
199
|
+
}
|
|
200
|
+
const BUCKETS = [
|
|
201
|
+
["<100K", 0, 100000],
|
|
202
|
+
["100-250K", 100000, 250000],
|
|
203
|
+
["250-500K", 250000, 500000],
|
|
204
|
+
["500K-1M", 500000, 1000000],
|
|
205
|
+
[">=1M", 1000000, Infinity],
|
|
206
|
+
];
|
|
207
|
+
function pathALossBaseline(events) {
|
|
208
|
+
const rate = (es, pred) => es.length ? es.filter(pred).length / es.length : 0;
|
|
209
|
+
const byPreTokenBucket = BUCKETS.map(([label, lo, hi]) => {
|
|
210
|
+
const es = events.filter((e) => (e.preTokens ?? 0) >= lo && (e.preTokens ?? 0) < hi);
|
|
211
|
+
const recov = es.map((e) => e.turnsToRecover).filter((n) => n !== null);
|
|
212
|
+
return {
|
|
213
|
+
bucket: label,
|
|
214
|
+
count: es.length,
|
|
215
|
+
reworkRate: rate(es, (e) => e.reworkHits > 0),
|
|
216
|
+
reexplainRate: rate(es, (e) => e.userReexplain),
|
|
217
|
+
medianTurnsToRecover: recov.length ? median(recov) : null,
|
|
218
|
+
};
|
|
219
|
+
}).filter((b) => b.count > 0);
|
|
220
|
+
const worstCases = [...events]
|
|
221
|
+
.sort((a, b) => b.reworkHits - a.reworkHits || (b.turnsToRecover ?? 0) - (a.turnsToRecover ?? 0))
|
|
222
|
+
.slice(0, 5)
|
|
223
|
+
.map((e) => ({
|
|
224
|
+
project: e.project,
|
|
225
|
+
preTokens: e.preTokens,
|
|
226
|
+
reworkHits: e.reworkHits,
|
|
227
|
+
turnsToRecover: e.turnsToRecover,
|
|
228
|
+
userReexplain: e.userReexplain,
|
|
229
|
+
}));
|
|
230
|
+
const recovAll = events.map((e) => e.turnsToRecover).filter((n) => n !== null);
|
|
231
|
+
return {
|
|
232
|
+
source: "historical Path-A (Claude Code /compact); HEURISTIC signals; NON-representative of auto-trigger rates (manual = task-boundary timing). Validates detection mechanics, not arming-phase loss rates.",
|
|
233
|
+
totalEvents: events.length,
|
|
234
|
+
byPreTokenBucket,
|
|
235
|
+
worstCases,
|
|
236
|
+
comparison: {
|
|
237
|
+
pathA: {
|
|
238
|
+
source: "historical /compact (this dataset)",
|
|
239
|
+
events: events.length,
|
|
240
|
+
reworkRate: rate(events, (e) => e.reworkHits > 0),
|
|
241
|
+
reexplainRate: rate(events, (e) => e.userReexplain),
|
|
242
|
+
medianTurnsToRecover: recovAll.length ? median(recovAll) : null,
|
|
243
|
+
},
|
|
244
|
+
pathB: null,
|
|
245
|
+
defaultSoakPath: "A",
|
|
246
|
+
note: "Path B (CLEAR+reinject) has no historical data and cannot be measured read-only — its loss signals only exist if the path is executed in the founder-gated soak. A is the conservative-soak default; B is tested against A's measured baseline.",
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
async function analyzeCompactEvents(agents, windowDays = 30) {
|
|
251
|
+
const windowStartMs = Date.now() - windowDays * 24 * 60 * 60 * 1000;
|
|
252
|
+
const byProject = new Map();
|
|
253
|
+
for (const a of agents) {
|
|
254
|
+
const cwd = (0, usage_reader_js_1.cwdForPid)(a.pid);
|
|
255
|
+
if (!cwd)
|
|
256
|
+
continue;
|
|
257
|
+
const id = (0, usage_reader_js_1.projectIdFromCwd)(cwd);
|
|
258
|
+
const e = byProject.get(id) || { roles: [], cwd };
|
|
259
|
+
e.roles.push(a.role);
|
|
260
|
+
byProject.set(id, e);
|
|
261
|
+
}
|
|
262
|
+
const events = [];
|
|
263
|
+
const seen = new Set();
|
|
264
|
+
for (const [id, { roles, cwd }] of byProject) {
|
|
265
|
+
const dir = path_1.default.join(usage_reader_js_1.PROJECTS_DIR, id);
|
|
266
|
+
const label = roles.length === 1 ? roles[0] : `${path_1.default.basename(cwd)} (${roles.length} agents)`;
|
|
267
|
+
let files = [];
|
|
268
|
+
try {
|
|
269
|
+
files = fs_1.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) => path_1.default.join(dir, f));
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
for (const file of files) {
|
|
275
|
+
try {
|
|
276
|
+
if (fs_1.default.statSync(file).mtimeMs < windowStartMs)
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
await analyzeFile(file, seen, events, label, roles);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Roll up by trigger type.
|
|
286
|
+
const byTrigger = {};
|
|
287
|
+
for (const trig of new Set(events.map((e) => e.trigger || "unknown"))) {
|
|
288
|
+
const es = events.filter((e) => (e.trigger || "unknown") === trig);
|
|
289
|
+
const recov = es.map((e) => e.turnsToRecover).filter((n) => n !== null);
|
|
290
|
+
byTrigger[trig] = {
|
|
291
|
+
count: es.length,
|
|
292
|
+
medianPreTokens: median(es.map((e) => e.preTokens || 0)),
|
|
293
|
+
medianPostTokens: median(es.map((e) => e.postTokens || 0)),
|
|
294
|
+
medianReductionPct: median(es.map((e) => e.reductionPct || 0)),
|
|
295
|
+
reworkRate: es.length ? es.filter((e) => e.reworkHits > 0).length / es.length : 0,
|
|
296
|
+
refetchRate: es.length ? es.filter((e) => e.refetchHits > 0).length / es.length : 0,
|
|
297
|
+
userReexplainRate: es.length ? es.filter((e) => e.userReexplain).length / es.length : 0,
|
|
298
|
+
medianTurnsToRecover: recov.length ? median(recov) : null,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
generatedAt: new Date().toISOString(),
|
|
303
|
+
windowDays,
|
|
304
|
+
totalEvents: events.length,
|
|
305
|
+
byTrigger,
|
|
306
|
+
events,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=compact-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-analyzer.js","sourceRoot":"","sources":["../src/compact-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type CompactAction = {
|
|
2
|
+
kind: "fire";
|
|
3
|
+
} | {
|
|
4
|
+
kind: "ask";
|
|
5
|
+
} | {
|
|
6
|
+
kind: "skip";
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
export interface CompactDecisionInput {
|
|
10
|
+
idle: boolean;
|
|
11
|
+
ambiguous: boolean;
|
|
12
|
+
safeToClear: boolean;
|
|
13
|
+
consentAgeMs: number | null;
|
|
14
|
+
consentFreshMs: number;
|
|
15
|
+
economicGreen: boolean;
|
|
16
|
+
msSinceLastAsk: number | null;
|
|
17
|
+
askCooldownMs: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function decideCompactAction(i: CompactDecisionInput): CompactAction;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// T1 consent handshake — pure decision core for the armed /compact path.
|
|
3
|
+
//
|
|
4
|
+
// Background: before this, the watcher auto-fired /compact the moment an
|
|
5
|
+
// allowlisted agent was idle at a turn boundary (the Stop hook touches
|
|
6
|
+
// checkpoint_ts every turn, so the old "fresh_consent" gate was satisfied
|
|
7
|
+
// automatically — the agent never actually said yes). This module replaces
|
|
8
|
+
// that silent fire with a two-phase handshake:
|
|
9
|
+
//
|
|
10
|
+
// ASK — when occupancy is high + the agent is idle + compacting is
|
|
11
|
+
// economically worth a turn, type a prompt asking the agent to flush
|
|
12
|
+
// its handoff and CONSENT via signal_checkpoint(safe_to_clear=true).
|
|
13
|
+
// FIRE — only once a GENUINE consent is on record (checkpoint_safe_to_clear
|
|
14
|
+
// === 1, set solely by the explicit signal_checkpoint MCP call and
|
|
15
|
+
// unforgeable by the per-turn hook touch) AND that consent is fresh
|
|
16
|
+
// AND the agent is idle right now, type /compact.
|
|
17
|
+
//
|
|
18
|
+
// The function is pure so the gate ordering + freshness + cooldown logic can be
|
|
19
|
+
// pinned by tests independently of the watcher's transcript/DB plumbing.
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.decideCompactAction = decideCompactAction;
|
|
22
|
+
// Precedence: ambiguous → FIRE (durable consent) → ASK (throttled) → skip.
|
|
23
|
+
// FIRE is evaluated BEFORE the ask-cooldown so a yes is never starved by the
|
|
24
|
+
// throttle that exists only to stop us re-asking every tick. A fresh consent
|
|
25
|
+
// with no prior ask still fires — an agent that volunteered safe_to_clear=true
|
|
26
|
+
// on its own is just as valid as one answering our prompt.
|
|
27
|
+
function decideCompactAction(i) {
|
|
28
|
+
if (i.ambiguous)
|
|
29
|
+
return { kind: "skip", reason: "ambiguous-session" };
|
|
30
|
+
const consentFresh = i.safeToClear && i.consentAgeMs !== null && i.consentAgeMs < i.consentFreshMs;
|
|
31
|
+
if (consentFresh) {
|
|
32
|
+
// Consent is necessary, not sufficient — re-check idle at FIRE time.
|
|
33
|
+
if (!i.idle)
|
|
34
|
+
return { kind: "skip", reason: "consented-but-not-idle" };
|
|
35
|
+
return { kind: "fire" };
|
|
36
|
+
}
|
|
37
|
+
// No fire-eligible consent → consider asking. Asking costs the agent a turn,
|
|
38
|
+
// so only when idle (won't interrupt) and economically worth it.
|
|
39
|
+
if (!i.idle)
|
|
40
|
+
return { kind: "skip", reason: "not-idle" };
|
|
41
|
+
if (!i.economicGreen)
|
|
42
|
+
return { kind: "skip", reason: "economics-below-overhead" };
|
|
43
|
+
if (i.msSinceLastAsk !== null && i.msSinceLastAsk < i.askCooldownMs)
|
|
44
|
+
return { kind: "skip", reason: "ask-cooldown" };
|
|
45
|
+
return { kind: "ask" };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=compact-decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-decision.js","sourceRoot":"","sources":["../src/compact-decision.ts"],"names":[],"mappings":";AAAA,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,0EAA0E;AAC1E,2EAA2E;AAC3E,+CAA+C;AAC/C,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,2DAA2D;AAC3D,EAAE;AACF,gFAAgF;AAChF,yEAAyE;;AAuCzE,kDAkBC;AAvBD,2EAA2E;AAC3E,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,2DAA2D;AAC3D,SAAgB,mBAAmB,CAAC,CAAuB;IACzD,IAAI,CAAC,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAEtE,MAAM,YAAY,GAChB,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,KAAK,IAAI,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,cAAc,CAAC;IAChF,IAAI,YAAY,EAAE,CAAC;QACjB,qEAAqE;QACrE,IAAI,CAAC,CAAC,CAAC,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACvE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,6EAA6E;IAC7E,iEAAiE;IACjE,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACzD,IAAI,CAAC,CAAC,CAAC,aAAa;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC;IAClF,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,aAAa;QACjE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAClD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type CompactPath = "A" | "B";
|
|
2
|
+
export declare const DEFAULT_PATH: CompactPath;
|
|
3
|
+
export declare const HANDOFF_DIR: string;
|
|
4
|
+
export declare function isHandoffPathSafe(p: string): boolean;
|
|
5
|
+
export declare const HANDOFF_TEMPLATE = "# ClaudeLink handoff \u2014 <role>\n\n## Current task & progress\n<what you are doing right now and how far along>\n\n## Key decisions / context you must NOT lose\n<constraints, choices already made, facts that won't be re-derivable>\n\n## Exact next step\n<the very next action to take on resume>\n\n## Open threads\n<anything in flight, awaited, or deferred>\n";
|
|
6
|
+
export declare function handoffPathFor(agentId: string): string;
|
|
7
|
+
export declare function preparePrompt(perTurnCostUsd: number, handoffFile: string): string;
|
|
8
|
+
export declare function postCompactPrompt(p: CompactPath, handoffFile: string): string;
|
|
9
|
+
export declare function verifyHandoff(file: string): {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
bytes: number;
|
|
12
|
+
};
|
|
13
|
+
export interface CompactStep {
|
|
14
|
+
action: "send-prepare-prompt" | "await-ready" | "verify-handoff" | "inject-compact" | "inject-clear" | "reinject-handoff" | "send-postcompact-prompt";
|
|
15
|
+
detail: string;
|
|
16
|
+
injects: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function planCompact(p: CompactPath, perTurnCostUsd: number, handoffFile: string): CompactStep[];
|
|
19
|
+
export type ExecMode = "dry" | "armed";
|
|
20
|
+
export interface ExecResult {
|
|
21
|
+
path: CompactPath;
|
|
22
|
+
mode: ExecMode;
|
|
23
|
+
steps: CompactStep[];
|
|
24
|
+
executed: boolean;
|
|
25
|
+
note: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function executeCompact(agentId: string, p: CompactPath, perTurnCostUsd: number, mode?: ExecMode): ExecResult;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Compact executor — the prepare-then-compact handshake and the two
|
|
3
|
+
// state-preservation paths (§C of the auto-compact design), built in DRY mode:
|
|
4
|
+
// every flow is a PLANNER that logs the ordered steps it WOULD take. The actual
|
|
5
|
+
// terminal-injection points are guarded stubs — nothing types into a terminal
|
|
6
|
+
// here. Arming (real injection) is founder-gated and happens in the supervised
|
|
7
|
+
// soak, where the A-vs-B winner is MEASURED (it cannot be measured read-only:
|
|
8
|
+
// a path's loss-signals only exist if that path is executed).
|
|
9
|
+
//
|
|
10
|
+
// HYPOTHESIS (explicitly a hypothesis, not a measurement) — informs the soak's
|
|
11
|
+
// starting posture, does NOT decide it:
|
|
12
|
+
// Path A (/compact + handoff-file) = belt-and-suspenders. Claude Code's own
|
|
13
|
+
// summary PLUS the agent's structured handoff. If the handoff misses
|
|
14
|
+
// something, the model summary is a safety net. Lower risk FLOOR.
|
|
15
|
+
// Path B (CLEAR + handoff-reinject) = total control. Skip /compact entirely;
|
|
16
|
+
// the handoff IS the new context. No dependency on /compact's opaque
|
|
17
|
+
// summarization — potentially a higher ceiling — but if the handoff misses
|
|
18
|
+
// something it is GONE, no safety net. Higher risk floor.
|
|
19
|
+
// => Start the soak with A as the CONSERVATIVE DEFAULT; test B as the
|
|
20
|
+
// optimization against A's measured baseline. (Per senior review + pushback #4.)
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.HANDOFF_TEMPLATE = exports.HANDOFF_DIR = exports.DEFAULT_PATH = void 0;
|
|
26
|
+
exports.isHandoffPathSafe = isHandoffPathSafe;
|
|
27
|
+
exports.handoffPathFor = handoffPathFor;
|
|
28
|
+
exports.preparePrompt = preparePrompt;
|
|
29
|
+
exports.postCompactPrompt = postCompactPrompt;
|
|
30
|
+
exports.verifyHandoff = verifyHandoff;
|
|
31
|
+
exports.planCompact = planCompact;
|
|
32
|
+
exports.executeCompact = executeCompact;
|
|
33
|
+
const fs_1 = __importDefault(require("fs"));
|
|
34
|
+
const path_1 = __importDefault(require("path"));
|
|
35
|
+
const os_1 = __importDefault(require("os"));
|
|
36
|
+
exports.DEFAULT_PATH = "A"; // conservative-soak default
|
|
37
|
+
exports.HANDOFF_DIR = path_1.default.join(os_1.default.homedir(), ".claudelink", "handoffs");
|
|
38
|
+
// Marker substrings from HANDOFF_TEMPLATE — used by verifyHandoff to detect a
|
|
39
|
+
// "filled in nothing, just kept the stub" handoff. The template itself is
|
|
40
|
+
// ~270 bytes which sails over the >200-byte size gate, so a byte-count check
|
|
41
|
+
// alone is bypassable. Updated together with HANDOFF_TEMPLATE.
|
|
42
|
+
const HANDOFF_PLACEHOLDERS = [
|
|
43
|
+
"<role>",
|
|
44
|
+
"<what you are doing right now",
|
|
45
|
+
"<constraints, choices already made",
|
|
46
|
+
"<the very next action to take on resume>",
|
|
47
|
+
"<anything in flight, awaited, or deferred>",
|
|
48
|
+
];
|
|
49
|
+
// True iff `p` resolves under ~/.claudelink/handoffs/. Used at the
|
|
50
|
+
// signal_checkpoint ingress to reject agent-supplied paths that would let a
|
|
51
|
+
// confused agent satisfy the handoff gate with any large file on disk
|
|
52
|
+
// (e.g. /etc/passwd, a node_modules tarball). Returns false for any path that
|
|
53
|
+
// can't be resolved.
|
|
54
|
+
function isHandoffPathSafe(p) {
|
|
55
|
+
try {
|
|
56
|
+
const resolved = path_1.default.resolve(p);
|
|
57
|
+
const root = path_1.default.resolve(exports.HANDOFF_DIR);
|
|
58
|
+
return resolved === root || resolved.startsWith(root + path_1.default.sep);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// The structured essence the agent preserves across a compact. The 780K it
|
|
65
|
+
// re-reads every turn is mostly dead weight; this is the few-KB that matters.
|
|
66
|
+
exports.HANDOFF_TEMPLATE = `# ClaudeLink handoff — <role>
|
|
67
|
+
|
|
68
|
+
## Current task & progress
|
|
69
|
+
<what you are doing right now and how far along>
|
|
70
|
+
|
|
71
|
+
## Key decisions / context you must NOT lose
|
|
72
|
+
<constraints, choices already made, facts that won't be re-derivable>
|
|
73
|
+
|
|
74
|
+
## Exact next step
|
|
75
|
+
<the very next action to take on resume>
|
|
76
|
+
|
|
77
|
+
## Open threads
|
|
78
|
+
<anything in flight, awaited, or deferred>
|
|
79
|
+
`;
|
|
80
|
+
function handoffPathFor(agentId) {
|
|
81
|
+
return path_1.default.join(exports.HANDOFF_DIR, `${agentId}.md`);
|
|
82
|
+
}
|
|
83
|
+
// Step 2 of the handshake: the prepare-for-compact prompt (NOT a blind /compact).
|
|
84
|
+
function preparePrompt(perTurnCostUsd, handoffFile) {
|
|
85
|
+
return (`Your context is now costing ~$${perTurnCostUsd.toFixed(2)}/turn to re-read. ` +
|
|
86
|
+
`Before I compact it, write a handoff to ${handoffFile} capturing: current task + progress; ` +
|
|
87
|
+
`key decisions/context you must not lose; the exact next step; open threads. ` +
|
|
88
|
+
`Reply READY when the file is written.`);
|
|
89
|
+
}
|
|
90
|
+
// Step 6: the post-compact re-orient prompt, points the agent at its essence.
|
|
91
|
+
function postCompactPrompt(p, handoffFile) {
|
|
92
|
+
if (p === "A") {
|
|
93
|
+
return `Context compacted. Resume from your handoff at ${handoffFile} (plus the compact summary above).`;
|
|
94
|
+
}
|
|
95
|
+
return `Fresh context. Your handoff is at ${handoffFile} — resume from it; that is your full working state.`;
|
|
96
|
+
}
|
|
97
|
+
// Verify the agent actually wrote a non-trivial handoff before compacting.
|
|
98
|
+
// Two checks, both required: file must be >200 bytes AND must NOT contain any
|
|
99
|
+
// of the HANDOFF_TEMPLATE placeholders unfilled. A byte-count alone is
|
|
100
|
+
// bypassable because the template itself is ~270 bytes — an agent that wrote
|
|
101
|
+
// the template verbatim with nothing else would satisfy size but have zero
|
|
102
|
+
// real content. The placeholder scan catches that.
|
|
103
|
+
function verifyHandoff(file) {
|
|
104
|
+
try {
|
|
105
|
+
const st = fs_1.default.statSync(file);
|
|
106
|
+
if (st.size <= 200)
|
|
107
|
+
return { ok: false, bytes: st.size };
|
|
108
|
+
const body = fs_1.default.readFileSync(file, "utf-8");
|
|
109
|
+
for (const ph of HANDOFF_PLACEHOLDERS) {
|
|
110
|
+
if (body.includes(ph))
|
|
111
|
+
return { ok: false, bytes: st.size };
|
|
112
|
+
}
|
|
113
|
+
return { ok: true, bytes: st.size };
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { ok: false, bytes: 0 };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// The ordered plan for a given path. This is what the soak would execute; in dry
|
|
120
|
+
// mode we only LOG it. The `injects` flags mark exactly which steps touch the
|
|
121
|
+
// terminal — all of them stay stubbed until founder-armed.
|
|
122
|
+
function planCompact(p, perTurnCostUsd, handoffFile) {
|
|
123
|
+
const common = [
|
|
124
|
+
{ action: "send-prepare-prompt", detail: preparePrompt(perTurnCostUsd, handoffFile), injects: true },
|
|
125
|
+
{ action: "await-ready", detail: "wait for the agent to reply READY (bounded timeout)", injects: false },
|
|
126
|
+
{ action: "verify-handoff", detail: `verify ${handoffFile} exists and is non-trivial`, injects: false },
|
|
127
|
+
];
|
|
128
|
+
if (p === "A") {
|
|
129
|
+
return [
|
|
130
|
+
...common,
|
|
131
|
+
{ action: "inject-compact", detail: "type /compact (Claude Code summarizes)", injects: true },
|
|
132
|
+
{ action: "send-postcompact-prompt", detail: postCompactPrompt("A", handoffFile), injects: true },
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
return [
|
|
136
|
+
...common,
|
|
137
|
+
{ action: "inject-clear", detail: "type /clear (fresh context, no model summary)", injects: true },
|
|
138
|
+
{ action: "reinject-handoff", detail: "inject the handoff file contents as the new starting message", injects: true },
|
|
139
|
+
{ action: "send-postcompact-prompt", detail: postCompactPrompt("B", handoffFile), injects: true },
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
// Execute (or, in dry mode, PLAN) a compact via the chosen path. In dry mode it
|
|
143
|
+
// returns the plan without touching anything. "armed" mode is NOT reachable yet:
|
|
144
|
+
// it throws, because real injection is founder-gated and must be wired with the
|
|
145
|
+
// idle-prompt safety detector under supervision — not enabled from here.
|
|
146
|
+
function executeCompact(agentId, p, perTurnCostUsd, mode = "dry") {
|
|
147
|
+
const handoffFile = handoffPathFor(agentId);
|
|
148
|
+
const steps = planCompact(p, perTurnCostUsd, handoffFile);
|
|
149
|
+
if (mode === "armed") {
|
|
150
|
+
throw new Error("compact-executor: armed injection is not enabled — founder-gated, requires the idle-prompt safety detector and a supervised soak.");
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
path: p,
|
|
154
|
+
mode: "dry",
|
|
155
|
+
steps,
|
|
156
|
+
executed: false,
|
|
157
|
+
note: "dry plan only — no terminal contact; injection steps marked injects:true are stubbed pending founder-armed soak",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=compact-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact-executor.js","sourceRoot":"","sources":["../src/compact-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type WatcherMode = "observe" | "inject";
|
|
2
|
+
export interface ContextWatcherSettings {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
mode: WatcherMode;
|
|
5
|
+
intervalSec: number;
|
|
6
|
+
contextOccupancyThreshold: number;
|
|
7
|
+
dollarPerTurnThreshold: number;
|
|
8
|
+
handshakeOverheadTokens: number;
|
|
9
|
+
activeWindowMin: number;
|
|
10
|
+
thresholdTokens: number;
|
|
11
|
+
compactBaselineTokens: number;
|
|
12
|
+
cooldownMin: number;
|
|
13
|
+
message: string;
|
|
14
|
+
askMessage: string;
|
|
15
|
+
consentFreshMin: number;
|
|
16
|
+
injectAllowlist: string[];
|
|
17
|
+
oneShot: boolean;
|
|
18
|
+
activeSince: string | null;
|
|
19
|
+
}
|
|
20
|
+
export declare function readContextWatcherSettings(): ContextWatcherSettings;
|
|
21
|
+
export declare function writeContextWatcherSettings(partial: Partial<ContextWatcherSettings>): ContextWatcherSettings;
|