context-mode 1.0.161 → 1.0.163
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +142 -28
- package/bin/statusline.mjs +24 -4
- package/build/adapters/antigravity/index.d.ts +1 -1
- package/build/adapters/antigravity-cli/index.d.ts +51 -0
- package/build/adapters/antigravity-cli/index.js +341 -0
- package/build/adapters/claude-code/hooks.d.ts +1 -0
- package/build/adapters/claude-code/hooks.js +3 -0
- package/build/adapters/claude-code/index.js +24 -5
- package/build/adapters/client-map.js +5 -0
- package/build/adapters/codex/hooks.d.ts +5 -1
- package/build/adapters/codex/hooks.js +5 -1
- package/build/adapters/codex/index.d.ts +9 -1
- package/build/adapters/codex/index.js +87 -5
- package/build/adapters/copilot-cli/hooks.d.ts +33 -0
- package/build/adapters/copilot-cli/hooks.js +64 -0
- package/build/adapters/copilot-cli/index.d.ts +48 -0
- package/build/adapters/copilot-cli/index.js +341 -0
- package/build/adapters/detect.d.ts +1 -1
- package/build/adapters/detect.js +71 -3
- package/build/adapters/openclaw/mcp-tools.js +1 -1
- package/build/adapters/opencode/index.js +31 -17
- package/build/adapters/opencode/zod3tov4.js +27 -6
- package/build/adapters/pi/extension.d.ts +2 -12
- package/build/adapters/pi/extension.js +114 -96
- package/build/adapters/types.d.ts +5 -4
- package/build/adapters/types.js +4 -3
- package/build/cache-heal.d.ts +48 -0
- package/build/cache-heal.js +150 -0
- package/build/cli.js +37 -97
- package/build/executor.d.ts +25 -0
- package/build/executor.js +143 -22
- package/build/opencode-plugin.js +5 -2
- package/build/routing-block.d.ts +8 -0
- package/build/routing-block.js +86 -0
- package/build/runtime.d.ts +0 -36
- package/build/runtime.js +107 -27
- package/build/search/flood-guard.d.ts +57 -0
- package/build/search/flood-guard.js +80 -0
- package/build/security.d.ts +8 -3
- package/build/security.js +155 -29
- package/build/server.d.ts +14 -0
- package/build/server.js +368 -350
- package/build/session/analytics.d.ts +8 -8
- package/build/session/analytics.js +18 -13
- package/build/session/db.d.ts +1 -0
- package/build/session/db.js +37 -4
- package/build/session/extract.d.ts +46 -0
- package/build/session/extract.js +764 -13
- package/build/session/project-attribution.js +14 -0
- package/build/store.d.ts +1 -1
- package/build/store.js +139 -25
- package/build/tool-naming.d.ts +4 -0
- package/build/tool-naming.js +24 -0
- package/build/util/jsonc.d.ts +14 -0
- package/build/util/jsonc.js +104 -0
- package/cli.bundle.mjs +260 -254
- package/configs/antigravity/GEMINI.md +2 -2
- package/configs/antigravity-cli/hooks/hooks.json +37 -0
- package/configs/antigravity-cli/hooks.json +37 -0
- package/configs/antigravity-cli/mcp_config.json +10 -0
- package/configs/antigravity-cli/plugin.json +14 -0
- package/configs/antigravity-cli/rules/context-mode.md +77 -0
- package/configs/antigravity-cli/skills/context-mode/SKILL.md +77 -0
- package/configs/claude-code/CLAUDE.md +2 -2
- package/configs/codex/AGENTS.md +2 -2
- package/configs/copilot-cli/.github/plugin/plugin.json +23 -0
- package/configs/copilot-cli/.mcp.json +12 -0
- package/configs/copilot-cli/README.md +47 -0
- package/configs/copilot-cli/hooks.json +41 -0
- package/configs/copilot-cli/skills/context-mode/SKILL.md +38 -0
- package/configs/gemini-cli/GEMINI.md +2 -2
- package/configs/jetbrains-copilot/copilot-instructions.md +2 -2
- package/configs/kilo/AGENTS.md +2 -2
- package/configs/kiro/KIRO.md +2 -2
- package/configs/omp/SYSTEM.md +2 -2
- package/configs/openclaw/AGENTS.md +2 -2
- package/configs/opencode/AGENTS.md +2 -2
- package/configs/qwen-code/QWEN.md +2 -2
- package/configs/vscode-copilot/copilot-instructions.md +2 -2
- package/configs/zed/AGENTS.md +2 -2
- package/hooks/antigravity-cli/payload.mjs +98 -0
- package/hooks/antigravity-cli/posttooluse.mjs +138 -0
- package/hooks/antigravity-cli/pretooluse.mjs +78 -0
- package/hooks/antigravity-cli/stop.mjs +58 -0
- package/hooks/codex/pretooluse.mjs +14 -4
- package/hooks/codex/stop.mjs +12 -4
- package/hooks/copilot-cli/posttooluse.mjs +79 -0
- package/hooks/copilot-cli/precompact.mjs +66 -0
- package/hooks/copilot-cli/pretooluse.mjs +41 -0
- package/hooks/copilot-cli/sessionstart.mjs +121 -0
- package/hooks/copilot-cli/stop.mjs +59 -0
- package/hooks/copilot-cli/userpromptsubmit.mjs +77 -0
- package/hooks/core/codex-caps.mjs +112 -0
- package/hooks/core/formatters.mjs +158 -7
- package/hooks/core/mcp-ready.mjs +37 -8
- package/hooks/core/routing.mjs +94 -8
- package/hooks/core/tool-naming.mjs +3 -0
- package/hooks/hooks.json +12 -1
- package/hooks/pretooluse.mjs +6 -2
- package/hooks/routing-block.mjs +2 -2
- package/hooks/security.bundle.mjs +2 -1
- package/hooks/session-db.bundle.mjs +11 -7
- package/hooks/session-directive.mjs +88 -20
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-helpers.mjs +21 -0
- package/hooks/session-loaders.mjs +8 -5
- package/hooks/sessionstart.mjs +53 -7
- package/hooks/stop.mjs +49 -0
- package/hooks/userpromptsubmit.mjs +9 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -10
- package/scripts/install-antigravity-cli-plugin.mjs +141 -0
- package/server.bundle.mjs +214 -205
- package/skills/ctx-insight/SKILL.md +12 -17
- package/build/util/db-lock.d.ts +0 -65
- package/build/util/db-lock.js +0 -166
- package/insight/index.html +0 -13
- package/insight/package.json +0 -55
- package/insight/server.mjs +0 -1265
- package/insight/src/components/analytics.tsx +0 -112
- package/insight/src/components/ui/badge.tsx +0 -52
- package/insight/src/components/ui/button.tsx +0 -58
- package/insight/src/components/ui/card.tsx +0 -103
- package/insight/src/components/ui/chart.tsx +0 -371
- package/insight/src/components/ui/collapsible.tsx +0 -19
- package/insight/src/components/ui/input.tsx +0 -20
- package/insight/src/components/ui/progress.tsx +0 -83
- package/insight/src/components/ui/scroll-area.tsx +0 -55
- package/insight/src/components/ui/separator.tsx +0 -23
- package/insight/src/components/ui/table.tsx +0 -114
- package/insight/src/components/ui/tabs.tsx +0 -82
- package/insight/src/components/ui/tooltip.tsx +0 -64
- package/insight/src/lib/api.ts +0 -144
- package/insight/src/lib/utils.ts +0 -6
- package/insight/src/main.tsx +0 -22
- package/insight/src/routeTree.gen.ts +0 -189
- package/insight/src/router.tsx +0 -19
- package/insight/src/routes/__root.tsx +0 -55
- package/insight/src/routes/enterprise.tsx +0 -316
- package/insight/src/routes/index.tsx +0 -1482
- package/insight/src/routes/knowledge.tsx +0 -221
- package/insight/src/routes/knowledge_.$dbHash.$sourceId.tsx +0 -137
- package/insight/src/routes/search.tsx +0 -97
- package/insight/src/routes/sessions.tsx +0 -179
- package/insight/src/routes/sessions_.$dbHash.$sessionId.tsx +0 -181
- package/insight/src/styles.css +0 -104
- package/insight/tsconfig.json +0 -29
- package/insight/vite.config.ts +0 -19
|
@@ -7,10 +7,54 @@
|
|
|
7
7
|
|
|
8
8
|
import { writeFileSync } from "node:fs";
|
|
9
9
|
|
|
10
|
+
// ── Leg-boundary helpers (#780) ──
|
|
11
|
+
// The current Claude Code session_id persists across `--continue` legs, so the
|
|
12
|
+
// events array can carry rows written in a PRIOR leg. The last `session_start`
|
|
13
|
+
// lifecycle event (emitted by the prior leg's SessionStart, before this leg's
|
|
14
|
+
// directive is built — sessionstart.mjs:206/258, 277/293) is the boundary that
|
|
15
|
+
// opened the current leg. Rows with created_at < boundary are prior-leg.
|
|
16
|
+
function computeLegBoundary(events) {
|
|
17
|
+
let boundary = null;
|
|
18
|
+
for (const ev of events) {
|
|
19
|
+
if (ev.category === "session_start" && ev.created_at) boundary = ev.created_at;
|
|
20
|
+
}
|
|
21
|
+
return boundary;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// True when an event was written in a leg strictly before the current one.
|
|
25
|
+
// No boundary (first leg) → nothing is prior-leg, so everything stays current.
|
|
26
|
+
function isPriorLeg(ev, boundary) {
|
|
27
|
+
return boundary != null && ev.created_at != null && ev.created_at < boundary;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Data References sizing (#840) ──
|
|
31
|
+
// Inlining every captured tool-output verbatim defeats context-mode's own
|
|
32
|
+
// raw-bytes-stay-out principle. Inline only a small recent window; reference
|
|
33
|
+
// large blobs with a one-line pointer. The full payloads stay queryable in
|
|
34
|
+
// FTS5 via ctx_search(source: "session-events").
|
|
35
|
+
const DATA_REF_INLINE_MAX = 8; // most-recent captures rendered inline
|
|
36
|
+
const DATA_REF_ENTRY_MAX = 150; // per-entry char cap before it is referenced
|
|
37
|
+
|
|
38
|
+
function renderDataReferences(entries, push, searchHint) {
|
|
39
|
+
const recent = entries.slice(-DATA_REF_INLINE_MAX);
|
|
40
|
+
for (const ev of recent) {
|
|
41
|
+
const raw = ev.data ?? "";
|
|
42
|
+
const text = raw.length > DATA_REF_ENTRY_MAX
|
|
43
|
+
? `${raw.substring(0, DATA_REF_ENTRY_MAX - 3)}… (${raw.length} bytes — query ${searchHint})`
|
|
44
|
+
: raw;
|
|
45
|
+
push(`- ${text}`);
|
|
46
|
+
}
|
|
47
|
+
const older = entries.length - recent.length;
|
|
48
|
+
if (older > 0) {
|
|
49
|
+
push(`- … ${older} older captures kept in the sandbox — query ${searchHint}.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
10
53
|
// ── Group events by category and extract metadata ──
|
|
11
54
|
export function groupEvents(events) {
|
|
12
55
|
const grouped = {};
|
|
13
56
|
let lastPrompt = "";
|
|
57
|
+
const legBoundary = computeLegBoundary(events);
|
|
14
58
|
for (const ev of events) {
|
|
15
59
|
if (ev.category === "prompt") {
|
|
16
60
|
lastPrompt = ev.data;
|
|
@@ -25,13 +69,13 @@ export function groupEvents(events) {
|
|
|
25
69
|
const base = path?.split(/[/\\]/).pop()?.trim();
|
|
26
70
|
if (base && !base.includes("*")) fileNames.add(base);
|
|
27
71
|
}
|
|
28
|
-
return { grouped, lastPrompt, fileNames };
|
|
72
|
+
return { grouped, lastPrompt, fileNames, legBoundary };
|
|
29
73
|
}
|
|
30
74
|
|
|
31
75
|
// ── Write session events as markdown for FTS5 auto-indexing ──
|
|
32
76
|
// Structured with H2 headings per category — optimal for FTS5 chunking.
|
|
33
77
|
export function writeSessionEventsFile(events, eventsPath) {
|
|
34
|
-
const { grouped, lastPrompt, fileNames } = groupEvents(events);
|
|
78
|
+
const { grouped, lastPrompt, fileNames, legBoundary } = groupEvents(events);
|
|
35
79
|
|
|
36
80
|
const lines = [];
|
|
37
81
|
lines.push("# Session Resume");
|
|
@@ -149,10 +193,23 @@ export function writeSessionEventsFile(events, eventsPath) {
|
|
|
149
193
|
}
|
|
150
194
|
|
|
151
195
|
if (grouped.subagent?.length > 0) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
196
|
+
// #780 — only current-leg subagent events are "current". Prior-leg ones
|
|
197
|
+
// are reframed as history so stale [completed]/[launched] labels are not
|
|
198
|
+
// re-injected as if the agent ran in this conversation.
|
|
199
|
+
const currentSub = grouped.subagent.filter(ev => !isPriorLeg(ev, legBoundary));
|
|
200
|
+
const priorSub = grouped.subagent.filter(ev => isPriorLeg(ev, legBoundary));
|
|
201
|
+
if (currentSub.length > 0) {
|
|
202
|
+
lines.push("## Subagent Tasks");
|
|
203
|
+
lines.push("");
|
|
204
|
+
for (const ev of currentSub) lines.push(`- ${ev.data}`);
|
|
205
|
+
lines.push("");
|
|
206
|
+
}
|
|
207
|
+
if (priorSub.length > 0) {
|
|
208
|
+
lines.push("## Subagent Tasks (earlier session — not current)");
|
|
209
|
+
lines.push("");
|
|
210
|
+
for (const ev of priorSub) lines.push(`- ${ev.data}`);
|
|
211
|
+
lines.push("");
|
|
212
|
+
}
|
|
156
213
|
}
|
|
157
214
|
|
|
158
215
|
if (grouped.skill?.length > 0) {
|
|
@@ -180,7 +237,11 @@ export function writeSessionEventsFile(events, eventsPath) {
|
|
|
180
237
|
if (grouped.data?.length > 0) {
|
|
181
238
|
lines.push("## Data References");
|
|
182
239
|
lines.push("");
|
|
183
|
-
|
|
240
|
+
renderDataReferences(
|
|
241
|
+
grouped.data,
|
|
242
|
+
(l) => lines.push(l),
|
|
243
|
+
'ctx_search(source: "session-events")',
|
|
244
|
+
);
|
|
184
245
|
lines.push("");
|
|
185
246
|
}
|
|
186
247
|
|
|
@@ -212,8 +273,10 @@ export function writeSessionEventsFile(events, eventsPath) {
|
|
|
212
273
|
|
|
213
274
|
// ── Build session guide — actionable narrative for LLM to continue from ──
|
|
214
275
|
export function buildSessionDirective(source, eventMeta, toolNamer) {
|
|
215
|
-
const { grouped, lastPrompt, fileNames } = eventMeta;
|
|
276
|
+
const { grouped, lastPrompt, fileNames, legBoundary } = eventMeta;
|
|
216
277
|
const isCompact = source === "compact";
|
|
278
|
+
const searchTool = toolNamer ? toolNamer("ctx_search") : "ctx_search";
|
|
279
|
+
const dataSearchHint = `${searchTool}(source: "session-events")`;
|
|
217
280
|
|
|
218
281
|
let block = `\n<session_knowledge source="${isCompact ? "compact" : "continue"}">`;
|
|
219
282
|
block += `\n<session_guide>`;
|
|
@@ -333,14 +396,23 @@ export function buildSessionDirective(source, eventMeta, toolNamer) {
|
|
|
333
396
|
block += `\n`;
|
|
334
397
|
}
|
|
335
398
|
|
|
336
|
-
// 9. Subagent tasks
|
|
399
|
+
// 9. Subagent tasks — #780: prior-leg events are NOT current work. Render
|
|
400
|
+
// only current-leg subagents under "Subagent Tasks"; reframe prior-leg
|
|
401
|
+
// ones so stale [completed]/[launched] labels don't read as this leg's.
|
|
337
402
|
if (grouped.subagent?.length > 0) {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
403
|
+
const fmt = (ev) => ev.data.length > 120 ? ev.data.substring(0, 117) + "..." : ev.data;
|
|
404
|
+
const currentSub = grouped.subagent.filter(ev => !isPriorLeg(ev, legBoundary));
|
|
405
|
+
const priorSub = grouped.subagent.filter(ev => isPriorLeg(ev, legBoundary));
|
|
406
|
+
if (currentSub.length > 0) {
|
|
407
|
+
block += `\n## Subagent Tasks`;
|
|
408
|
+
for (const ev of currentSub) block += `\n- ${fmt(ev)}`;
|
|
409
|
+
block += `\n`;
|
|
410
|
+
}
|
|
411
|
+
if (priorSub.length > 0) {
|
|
412
|
+
block += `\n## Subagent Tasks (earlier session — not current)`;
|
|
413
|
+
for (const ev of priorSub) block += `\n- ${fmt(ev)}`;
|
|
414
|
+
block += `\n`;
|
|
342
415
|
}
|
|
343
|
-
block += `\n`;
|
|
344
416
|
}
|
|
345
417
|
|
|
346
418
|
// 10. Skills invoked
|
|
@@ -363,13 +435,10 @@ export function buildSessionDirective(source, eventMeta, toolNamer) {
|
|
|
363
435
|
block += `\n`;
|
|
364
436
|
}
|
|
365
437
|
|
|
366
|
-
// 12. Data references
|
|
438
|
+
// 12. Data references — #840: reference (don't inline) large tool-outputs.
|
|
367
439
|
if (grouped.data?.length > 0) {
|
|
368
440
|
block += `\n## Data References`;
|
|
369
|
-
|
|
370
|
-
const text = ev.data.length > 150 ? ev.data.substring(0, 147) + "..." : ev.data;
|
|
371
|
-
block += `\n- ${text}`;
|
|
372
|
-
}
|
|
441
|
+
renderDataReferences(grouped.data, (l) => { block += `\n${l}`; }, dataSearchHint);
|
|
373
442
|
block += `\n`;
|
|
374
443
|
}
|
|
375
444
|
|
|
@@ -417,7 +486,6 @@ export function buildSessionDirective(source, eventMeta, toolNamer) {
|
|
|
417
486
|
// Search on demand — detailed data lives in FTS5
|
|
418
487
|
block += `\n<session_search>`;
|
|
419
488
|
block += `\nDetailed session data is indexed in context-mode FTS5 (source: "session-events").`;
|
|
420
|
-
const searchTool = toolNamer ? toolNamer("ctx_search") : "ctx_search";
|
|
421
489
|
block += `\nUse ${searchTool}(queries: [...], source: "session-events") when you need specifics.`;
|
|
422
490
|
block += `\nDo NOT call ctx_index() — data is already indexed.`;
|
|
423
491
|
block += `\n</session_search>`;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function i(t){return t==null?"":String(t)}function
|
|
2
|
-
response: ${i(r)}`:"";return[{type:"mcp",category:"mcp",data:i(`${s}${u}${c}`),priority:3}]}var M=2048;function B(t,e){if(Buffer.byteLength(t,"utf8")<=e)return{value:t,truncated:!1};let n=Buffer.from(t,"utf8"),r=e;for(;r>0&&(n[r]&192)===128;)r--;return{value:n.subarray(0,r).toString("utf8"),truncated:!0}}var W=/(authorization|auth_token|access_token|refresh_token|bearer|token|secret|password|passwd|pwd|api[-_]?key|apikey|cookie|set-cookie|signature|private[-_]?key|client[-_]?secret|x[-_]?api[-_]?key)/i,j="[REDACTED]";function y(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))return"[CIRCULAR]";e.add(t);let n;if(Array.isArray(t))n=t.map(r=>y(r,e));else{let r={};for(let[o,s]of Object.entries(t))W.test(o)?r[o]=j:r[o]=y(s,e);n=r}return e.delete(t),n}function D(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let r=y(n??{}),o;try{o=JSON.stringify(r)}catch{o="{}"}let{value:s,truncated:a}=B(o,M),u=a?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(s)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${s}}`;return[{type:"mcp_tool_call",category:"mcp_tool_call",data:i(u),priority:4}]}function F(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,n=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",r=String(t.tool_response??""),o="";try{let c=JSON.parse(r)?.answers;if(c&&typeof c=="object"){let g=f=>typeof f=="string"?f:Array.isArray(f)?f.filter(h=>typeof h=="string").join(" | "):"",m=n?g(c[n]):"";m?o=m:o=Object.values(c).map(g).filter(h=>h.length>0).join(" | ")}}catch{}let s=i(o),a=n?`Q: ${i(n)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:i(a),priority:2}]}function U(t){if(t.tool_name!=="Agent")return[];if(!t.tool_response||t.tool_response.length===0)return[];let e=t.tool_response.length>500?t.tool_response.slice(0,500):t.tool_response;return[{type:"agent_finding",category:"agent-finding",data:i(e),priority:2}]}function G(t){let e=[E(t.tool_input),i(t.tool_response)].join(" ");if(e.length===0)return[];let n=new Set,r=e.match(/https?:\/\/[^\s)]+/g);if(r)for(let c of r)c=c.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(c)||n.add(c);let o=e.match(/(?<!\w)#(\d+)/g);if(o)for(let c of o)n.add(c);if(n.size===0)return[];let s,a=i(t.tool_response).match(/Fetched and indexed[^\(]*\(([\d.]+)\s*KB\)/i);if(a){let c=Number(a[1]);Number.isFinite(c)&&c>0&&(s=Math.round(c*1024))}let u={type:"external_ref",category:"external-ref",data:i(Array.from(n).join(", ")),priority:3};return s!==void 0&&(u.bytes_avoided=s),[u]}function K(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:i(`entered worktree: ${e}`),priority:2}]}var v=/[,;,;、،]/u,J=15,q=500;function z(t){if(_.test(t)||!b.test(t)||!v.test(t))return!1;let e=[...t].length;return e>=J&&e<=q}function Q(t){let e=t.trim();return z(e)?[{type:"decision",category:"decision",data:i(t),priority:2}]:[]}var V=8,X=120,Y=new RegExp("\\p{L}+\\s+\\p{L}+","u"),Z=new RegExp("\\p{L}{6,}","u");function tt(t){let e=t.split(/[.!\n。!]/u)[0].trim();if(_.test(e)||v.test(e)||!b.test(e))return!1;let n=[...e].length;return n<V||n>X?!1:Y.test(e)||Z.test(e)}function et(t){let e=t.trim();return tt(e)?[{type:"role",category:"role",data:i(t),priority:3}]:[]}var _=/[??؟¿]/u,b=new RegExp("\\p{L}","u"),nt=60;function rt(t){if(_.test(t)||!b.test(t))return!1;let e=[...t].length;return e>0&&e<nt}function ot(t){let e=t.trim();if(!e)return[];let n;return _.test(e)?n="investigate":rt(e)&&(n="implement"),n?[{type:"intent",category:"intent",data:i(n),priority:4}]:[]}var st=/^(?:\/goal\s+|(?:goal|objective)\s*:\s*)(.+)$/is;function it(t){let e=t.trim();if(!e)return[];let n=e.match(st);if(!n)return[];let r=n[1].trim();return r?[{type:"goal",category:"goal",data:i(r),priority:4}]:[]}var at=/(?:\bError\s*:|\bException\s*:|\bTraceback\b|\bat\s+\S+\s*\([^)]*:\d+:\d+\))/u,ct=/[✓✔✅☑🎉]/u,lt=/^\s*(?:fixed|resolved)\s*:/iu;function pt(t){let e=[];return ct.test(t)||lt.test(t)?(e.push({type:"blocker_resolved",category:"blocked-on",data:i(t),priority:2}),e):(at.test(t)&&e.push({type:"blocker",category:"blocked-on",data:i(t),priority:2}),e)}function ut(t){return t.length<=1024?[]:[{type:"data",category:"data",data:i(t),priority:4}]}var l=null;function ft(t){let{tool_name:e,tool_response:n}=t,r=String(n??"");if(d(t))return l={tool:e,error:r.slice(0,200),callsSince:0},[];if(!l)return[];if(l.callsSince++,l.callsSince>10)return l=null,[];if(!!d(t))return[];let s=e===l.tool,a=l.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(s||a){let u={type:"error_resolved",category:"error-resolution",data:i(`Error in ${l.tool}: ${l.error} \u2192 Fixed`),priority:2};return l=null,[u]}return[]}function yt(){l=null}var p=[];function dt(t){return`${t.length}:${t.slice(0,20)}`}function gt(t){let{tool_name:e,tool_input:n}=t,r=dt(JSON.stringify(n).slice(0,200));if(p.push({tool:e,inputHash:r}),p.length>50&&p.splice(0,p.length-50),p.length<3)return[];let o=0;for(let s=p.length-1;s>=0&&(p[s].tool===e&&p[s].inputHash===r);s--)o++;return o>=3?(p.splice(p.length-o),[{type:"retry_detected",category:"iteration-loop",data:i(`${e} called ${o} times with similar input`),priority:2}]):[]}function bt(){p.length=0}var _t={run_shell_command:"Bash",read_file:"Read",read_many_files:"Read",grep_search:"Grep",search_file_content:"Grep",web_fetch:"WebFetch",write_file:"Write",edit:"Edit",glob:"Glob",todo_write:"TodoWrite",ask_user_question:"AskUserQuestion",list_directory:"LS",save_memory:"Memory",skill:"Skill",exit_plan_mode:"ExitPlanMode",agent:"Agent",bash:"Bash",view:"Read",grep:"Grep",fetch:"WebFetch",shell:"Bash",shell_command:"Bash",exec_command:"Bash","container.exec":"Bash",local_shell:"Bash",grep_files:"Grep"};function ht(t){let e=_t[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function mt(t){try{let e=ht(t),n=[];return n.push(...A(e)),n.push(...R(e)),n.push(...T(e)),n.push(...w(e)),n.push(...L(e)),n.push(...I(e)),n.push(...N(e)),n.push(...$(e)),n.push(...O(e)),n.push(...P(e)),n.push(...D(e)),n.push(...F(e)),n.push(...H(e)),n.push(...K(e)),n.push(...U(e)),n.push(...G(e)),n.push(...ft(e)),n.push(...gt(e)),n}catch{return[]}}function St(t){try{let e=[];return e.push(...Q(t)),e.push(...et(t)),e.push(...ot(t)),e.push(...it(t)),e.push(...pt(t)),e.push(...ut(t)),e}catch{return[]}}export{mt as extractEvents,St as extractUserEvents,yt as resetErrorResolutionState,bt as resetIterationLoopState};
|
|
1
|
+
function i(t){return t==null?"":String(t)}function v(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function _(t){let e=String(t.tool_response??""),n=String(t.tool_input?.command??"");if(e.startsWith("context-mode:")||n.startsWith('echo "context-mode:')||n.startsWith("echo 'context-mode:"))return!1;let r=t.tool_output?.isError===!0||t.tool_output?.is_error===!0;return t.tool_name==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(e)||r}function R(t){if(!t)return[];let e=[];for(let r of t.split(/\r?\n/)){if(r.startsWith("*** Add File: ")){e.push({path:r.slice(14).trim(),type:"file_write"});continue}if(r.startsWith("*** Update File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}if(r.startsWith("*** Delete File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}r.startsWith("*** Move to: ")&&e.push({path:r.slice(13).trim(),type:"file_edit"})}let n=new Set;return e.filter(r=>{if(!r.path)return!1;let o=`${r.type}:${r.path}`;return n.has(o)?!1:(n.add(o),!0)})}function S(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function $(t){let{tool_name:e,tool_input:n,tool_response:r}=t,o=[];if(e==="Read"){let s=String(n.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(s)||/\/copilot-instructions\.md$/i.test(s)||/\/context-mode\.mdc$/i.test(s)||/\.claude[\\/]/i.test(s)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(s))&&(o.push({type:"rule",category:"rule",data:i(s),priority:1}),r&&r.length>0&&o.push({type:"rule_content",category:"rule",data:i(r),priority:1})),o.push({type:"file_read",category:"file",data:i(s),priority:1}),o}if(e==="Edit"){let s=String(n.file_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="NotebookEdit"){let s=String(n.notebook_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="Write"){let s=String(n.file_path??"");return o.push({type:"file_write",category:"file",data:i(s),priority:1}),o}if(e==="apply_patch"){if(_(t))return[];let s=R(String(n.command??n.patch??""));for(let a of s)o.push({type:a.type,category:"file",data:i(a.path),priority:1});return o}if(e==="Glob"){let s=String(n.pattern??"");return o.push({type:"file_glob",category:"file",data:i(s),priority:3}),o}if(e==="Grep"){let s=String(n.pattern??""),a=String(n.path??"");return o.push({type:"file_search",category:"file",data:i(`${s} in ${a}`),priority:3}),o}return o}function I(t){if(t.tool_name!=="Bash")return[];let n=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!n)return[];let r=n[2]??n[3]??n[4]??"";return[{type:"cwd",category:"cwd",data:i(r),priority:2}]}function C(t){let{tool_response:e}=t,n=String(e??"");return _(t)?[{type:"error_tool",category:"error",data:i(n),priority:2}]:[]}var E=[{pattern:/\bgit\s+checkout\b/,operation:"branch"},{pattern:/\bgit\s+commit\b/,operation:"commit"},{pattern:/\bgit\s+merge\s+\S+/,operation:"merge"},{pattern:/\bgit\s+rebase\b/,operation:"rebase"},{pattern:/\bgit\s+stash\b/,operation:"stash"},{pattern:/\bgit\s+push\b/,operation:"push"},{pattern:/\bgit\s+pull\b/,operation:"pull"},{pattern:/\bgit\s+log\b/,operation:"log"},{pattern:/\bgit\s+diff\b/,operation:"diff"},{pattern:/\bgit\s+status\b/,operation:"status"},{pattern:/\bgit\s+branch\b/,operation:"branch"},{pattern:/\bgit\s+reset\b/,operation:"reset"},{pattern:/\bgit\s+add\b/,operation:"add"},{pattern:/\bgit\s+cherry-pick\b/,operation:"cherry-pick"},{pattern:/\bgit\s+tag\b/,operation:"tag"},{pattern:/\bgit\s+fetch\b/,operation:"fetch"},{pattern:/\bgit\s+clone\b/,operation:"clone"},{pattern:/\bgit\s+worktree\b/,operation:"worktree"}];function H(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),n=P(e),r;if(n&&n.operation&&(r=E.find(s=>s.operation===n.operation)),r||(r=E.find(s=>s.pattern.test(e))),!r)return[];let o=[];if(n?.scopedDir&&o.push({type:"cwd",category:"cwd",data:i(n.scopedDir),priority:2}),r.operation==="commit"){let s=N(e);if(s)return o.push({type:"git_commit",category:"git",data:i(s),priority:2}),o}return o.push({type:"git",category:"git",data:i(r.operation),priority:2}),o}function O(t){return typeof t!="string"||t.length===0?t:t==="~"?w():t.startsWith("~/")?w()+t.slice(1):t}function w(){try{return process.env.HOME||process.env.USERPROFILE||(process.env.HOMEDRIVE&&process.env.HOMEPATH?process.env.HOMEDRIVE+process.env.HOMEPATH:"")||"~"}catch{return"~"}}function P(t){let e=x(t),n=0;for(;n<e.length&&M(e[n]);)n++;for(;n<e.length&&e[n]!=="git"&&!e[n].endsWith("/git")&&L(e[n]);)n++;if(n>=e.length||e[n]!=="git"&&!e[n].endsWith("/git"))return null;n++;let r=null,o=null;for(;n<e.length;){let s=e[n];if(s==="-C"||s==="--directory"){r=e[n+1]??null,n+=2;continue}if(s.startsWith("--directory=")){r=s.slice(12),n++;continue}if(s.length>0&&s[0]==="-"){n++;continue}o=s;break}return r&&(r=O(r)),{scopedDir:r,operation:o}}function M(t){if(t.length===0)return!1;let e=!1;for(let n=0;n<t.length;n++){let r=t.charCodeAt(n);if(n===0){if(!(r>=65&&r<=90||r===95))return!1}else if(r===61){e=!0;break}else if(!(r>=65&&r<=90||r>=48&&r<=57||r===95))return!1}return e}function L(t){switch(t){case"sudo":case"doas":case"env":case"exec":case"time":return!0;default:return!1}}function x(t){let e=[],n=t.length,r=0;for(;r<n;){for(;r<n&&(t[r]===" "||t[r]===" ");)r++;if(r>=n)break;let o="";for(;r<n&&t[r]!==" "&&t[r]!==" ";){let s=t[r];if(s==='"'||s==="'"){let a=s;for(r++;r<n&&t[r]!==a;)t[r]==="\\"&&r+1<n?(o+=t[r+1],r+=2):(o+=t[r],r++);r<n&&r++}else s==="\\"&&r+1<n?(o+=t[r+1],r+=2):(o+=s,r++)}e.push(o)}return e}function N(t){let e=x(t),n="--message=";for(let r=0;r<e.length;r++){let o=e[r];if(o.length>n.length&&o.startsWith(n)){let s=o.slice(n.length);return s.length>0?s:null}if(o==="--message"){let s=e[r+1];return s&&s.length>0?s:null}if(o.length>=2&&o[0]==="-"&&o[1]!=="-"&&o[o.length-1]==="m"&&j(o,1)){let s=e[r+1];return s&&s.length>0?s:null}}return null}function j(t,e){if(e>=t.length)return!1;for(let n=e;n<t.length;n++){let r=t.charCodeAt(n);if(r<97||r>122)return!1}return!0}function W(t){return new Set(["TodoWrite","TaskCreate","TaskUpdate"]).has(t.tool_name)?[{type:t.tool_name==="TaskUpdate"?"task_update":t.tool_name==="TaskCreate"?"task_create":"task",category:"task",data:i(JSON.stringify(t.tool_input)),priority:1}]:[]}function D(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619);return(e>>>0).toString(16).padStart(8,"0")}function B(t){let e=t.tool_input.plan;if(typeof e=="string"&&e.length>0)return e;let n=t.tool_response;if(typeof n=="string"&&n.length>0)try{let r=JSON.parse(n);if(r&&typeof r=="object"&&typeof r.plan=="string")return r.plan}catch{}return null}function F(t){if(t.tool_name==="EnterPlanMode")return[{type:"plan_enter",category:"plan",data:"entered plan mode",priority:2}];if(t.tool_name==="ExitPlanMode"){let e=[],n=t.tool_input.allowedPrompts,r=Array.isArray(n)&&n.length>0?`exited plan mode (allowed: ${v(n.map(a=>typeof a=="object"&&a!==null&&"prompt"in a?String(a.prompt):String(a)).join(", "))})`:"exited plan mode",o=B(t);typeof o=="string"&&o.length>0&&(r+=` plan_bytes:${o.length} plan_hash:${D(o)}`),e.push({type:"plan_exit",category:"plan",data:i(r),priority:2});let s=String(t.tool_response??"").toLowerCase();return s.includes("approved")||s.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(s.includes("rejected")||s.includes("decline")||s.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:i(`plan rejected: ${t.tool_response??""}`),priority:2}),e}if(t.tool_name==="Write"||t.tool_name==="Edit"){let e=String(t.tool_input.file_path??"");if(S(e))return[{type:"plan_file_write",category:"plan",data:i(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return t.tool_name==="apply_patch"?_(t)?[]:R(String(t.tool_input.command??t.tool_input.patch??"")).filter(n=>S(n.path)).map(n=>({type:"plan_file_write",category:"plan",data:i(`plan file: ${n.path.split(/[/\\]/).pop()??n.path}`),priority:2})):[]}var U=[/\bsource\s+\S*activate\b/,/\bexport\s+\w+=/,/\bnvm\s+use\b/,/\bpyenv\s+(shell|local|global)\b/,/\bconda\s+activate\b/,/\brbenv\s+(shell|local|global)\b/,/\bnpm\s+install\b/,/\bnpm\s+ci\b/,/\bpip\s+install\b/,/\bbun\s+install\b/,/\byarn\s+(add|install)\b/,/\bpnpm\s+(add|install)\b/,/\bcargo\s+(install|add)\b/,/\bgo\s+(install|get)\b/,/\brustup\b/,/\basdf\b/,/\bvolta\b/,/\bdeno\s+install\b/];function G(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!U.some(o=>o.test(e)))return[];let r=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:i(r),priority:2}]}function K(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:i(e),priority:2}]}function J(t){if(!t.tool_response?.includes("Error")&&!t.tool_output?.isError)return[];let e=String(t.tool_response||""),n=[/not supported/i,/cannot/i,/does not support/i,/FAIL/i,/refused/i,/permission denied/i,/incompatible/i];for(let r of n){let o=e.match(r);if(o){let s=e.toLowerCase().indexOf(o[0].toLowerCase()),a=e.slice(Math.max(0,s-50),Math.min(e.length,s+200)).trim();return[{type:"constraint_discovered",category:"constraint",data:i(a),priority:2}]}}return[]}function q(t){if(t.tool_name!=="Agent")return[];let e=i(String(t.tool_input.prompt??t.tool_input.description??"")),n=t.tool_response?i(String(t.tool_response)):"",r=n.length>0;return[{type:r?"subagent_completed":"subagent_launched",category:"subagent",data:i(r?`[completed] ${e} \u2192 ${n}`:`[launched] ${e}`),priority:r?2:3}]}function z(t){let{tool_name:e,tool_input:n,tool_response:r}=t;if(!e.startsWith("mcp__"))return[];let o=e.split("__"),s=o[o.length-1]||e,a=Object.values(n).find(l=>typeof l=="string"),p=a?`: ${i(String(a))}`:"",c=r&&r.length>0?`
|
|
2
|
+
response: ${i(r)}`:"";return[{type:"mcp",category:"mcp",data:i(`${s}${p}${c}`),priority:3}]}var V=2048;function Q(t,e){if(Buffer.byteLength(t,"utf8")<=e)return{value:t,truncated:!1};let n=Buffer.from(t,"utf8"),r=e;for(;r>0&&(n[r]&192)===128;)r--;return{value:n.subarray(0,r).toString("utf8"),truncated:!0}}var X=/(authorization|auth_token|access_token|refresh_token|bearer|token|secret|password|passwd|pwd|api[-_]?key|apikey|cookie|set-cookie|signature|private[-_]?key|client[-_]?secret|x[-_]?api[-_]?key)/i,Y="[REDACTED]";function b(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))return"[CIRCULAR]";e.add(t);let n;if(Array.isArray(t))n=t.map(r=>b(r,e));else{let r={};for(let[o,s]of Object.entries(t))X.test(o)?r[o]=Y:r[o]=b(s,e);n=r}return e.delete(t),n}function Z(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let r=b(n??{}),o;try{o=JSON.stringify(r)}catch{o="{}"}let{value:s,truncated:a}=Q(o,V),p=a?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(s)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${s}}`;return[{type:"mcp_tool_call",category:"mcp_tool_call",data:i(p),priority:4}]}function tt(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,n=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",r=String(t.tool_response??""),o="";try{let c=JSON.parse(r)?.answers;if(c&&typeof c=="object"){let l=g=>typeof g=="string"?g:Array.isArray(g)?g.filter(h=>typeof h=="string").join(" | "):"",u=n?l(c[n]):"";u?o=u:o=Object.values(c).map(l).filter(h=>h.length>0).join(" | ")}}catch{}let s=i(o),a=n?`Q: ${i(n)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:i(a),priority:2}]}function et(t){if(t.tool_name!=="Agent")return[];if(!t.tool_response||t.tool_response.length===0)return[];let e=t.tool_response.length>500?t.tool_response.slice(0,500):t.tool_response;return[{type:"agent_finding",category:"agent-finding",data:i(e),priority:2}]}function nt(t){let e=[v(t.tool_input),i(t.tool_response)].join(" ");if(e.length===0)return[];let n=new Set,r=e.match(/https?:\/\/[^\s)]+/g);if(r)for(let c of r)c=c.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(c)||n.add(c);let o=e.match(/(?<!\w)#(\d+)/g);if(o)for(let c of o)n.add(c);if(n.size===0)return[];let s,a=i(t.tool_response).match(/Fetched and indexed[^\(]*\(([\d.]+)\s*KB\)/i);if(a){let c=Number(a[1]);Number.isFinite(c)&&c>0&&(s=Math.round(c*1024))}let p={type:"external_ref",category:"external-ref",data:i(Array.from(n).join(", ")),priority:3};return s!==void 0&&(p.bytes_avoided=s),[p]}function rt(t){if(t.tool_name==="EnterWorktree"){let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:i(`entered worktree: ${e}`),priority:2}]}if(t.tool_name==="ExitWorktree"){let e=!!t.tool_input.discard_changes;return[{type:"worktree_exit",category:"env",data:i(`exited worktree (discard_changes:${e})`),priority:2}]}return[]}function ot(t){if(typeof t!="string"||t.length===0)return null;let e=t.indexOf("://");if(e<0)return null;let n=e+3;if(n>=t.length)return null;let r=t.length;for(let s=n;s<t.length;s++){let a=t.charCodeAt(s);if(a===47||a===63||a===35){r=s;break}}let o=t.slice(n,r);return o.length>0?o:null}function st(t){if(t.tool_name!=="WebFetch")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let n;try{n=JSON.parse(e)}catch{return[]}if(!n||typeof n!="object")return[];let r=n,o=[];if(typeof r.code=="number"&&o.push(`code:${r.code}`),typeof r.bytes=="number"&&o.push(`bytes:${r.bytes}`),typeof r.durationMs=="number"&&o.push(`durMs:${r.durationMs}`),typeof r.url=="string"){let s=ot(r.url);s&&o.push(`host:${s}`)}return o.length===0?[]:[{type:"webfetch_metadata",category:"data",data:i(o.join(" ")),priority:3}]}function it(t){if(t.tool_name!=="Bash")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let n;try{n=JSON.parse(e)}catch{return[]}if(!n||typeof n!="object")return[];let r=n;if(!(typeof r.interrupted=="boolean"||typeof r.stderr=="string"||typeof r.returnCodeInterpretation=="string"))return[];let s=[];return typeof r.interrupted=="boolean"&&s.push(`interrupted:${r.interrupted}`),typeof r.returnCodeInterpretation=="string"&&s.push(`rcInterp:${r.returnCodeInterpretation.slice(0,80)}`),typeof r.stderr=="string"&&s.push(`stderrBytes:${r.stderr.length}`),[{type:"bash_outcome",category:"data",data:i(s.join(" ")),priority:3}]}function at(t){if(t.tool_name!=="Read")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let n;try{n=JSON.parse(e)}catch{return[]}if(!n||typeof n!="object")return[];let r=n,o=r.type;if(o!=="text"&&o!=="image")return[];let s=[`type:${o}`];if(o==="text")typeof r.numLines=="number"&&s.push(`lines:${r.numLines}`),typeof r.totalLines=="number"&&s.push(`totalLines:${r.totalLines}`),typeof r.startLine=="number"&&s.push(`start:${r.startLine}`);else{typeof r.originalSize=="number"&&s.push(`origSize:${r.originalSize}`);let a=r.dimensions;if(a&&typeof a=="object"){let p=a;typeof p.width=="number"&&typeof p.height=="number"&&s.push(`dims:${p.width}x${p.height}`)}}return[{type:"file_read_metadata",category:"data",data:i(s.join(" ")),priority:3}]}var y={"claude-opus-4-8":{input:5,output:25,cache_write:6.25,cache_read:.5},"claude-opus-4-7":{input:5,output:25,cache_write:6.25,cache_read:.5},"claude-sonnet-4-6":{input:3,output:15,cache_write:3.75,cache_read:.3},"claude-haiku-4-5":{input:1,output:5,cache_write:1.25,cache_read:.1},default:{input:3,output:15,cache_write:3.75,cache_read:.3}};function ct(t,e){let n=[t.tool_input?.model,t.model,e.model],r=Object.keys(y).filter(o=>o!=="default");for(let o of n)if(!(typeof o!="string"||o.length===0)){if(o in y)return o;for(let s of r)if(o.startsWith(s))return s}return"default"}function pt(t,e,n,r,o){let s=y[t]??y.default;return(e*s.input+n*s.output+r*s.cache_write+o*s.cache_read)/1e6}function lt(t){if(t.tool_name!=="Task")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let n;try{n=JSON.parse(e)}catch{return[]}if(!n||typeof n!="object")return[];let r=n,o=r.usage&&typeof r.usage=="object"?r.usage:{};if(!(typeof r.totalTokens=="number"||typeof r.totalDurationMs=="number"||typeof o.input_tokens=="number"||typeof o.output_tokens=="number"||typeof o.service_tier=="string"))return[];let a=[];typeof r.totalTokens=="number"&&a.push(`totalTokens:${r.totalTokens}`),typeof r.totalDurationMs=="number"&&a.push(`totalDurMs:${r.totalDurationMs}`),typeof o.input_tokens=="number"&&a.push(`tokens_in:${o.input_tokens}`),typeof o.output_tokens=="number"&&a.push(`tokens_out:${o.output_tokens}`),typeof o.cache_creation_input_tokens=="number"&&a.push(`cache_create:${o.cache_creation_input_tokens}`),typeof o.cache_read_input_tokens=="number"&&a.push(`cache_read:${o.cache_read_input_tokens}`),typeof o.service_tier=="string"&&a.push(`tier:${o.service_tier.slice(0,32)}`);let p=typeof o.input_tokens=="number"?o.input_tokens:0,c=typeof o.output_tokens=="number"?o.output_tokens:0,l=typeof o.cache_creation_input_tokens=="number"?o.cache_creation_input_tokens:0,u=typeof o.cache_read_input_tokens=="number"?o.cache_read_input_tokens:0;if(p>0||c>0||l>0||u>0){let h=ct(t,r),A=pt(h,p,c,l,u);a.push(`cost_usd:${A.toFixed(6).replace(/0+$/,"").replace(/\.$/,".0")}`)}return[{type:"agent_usage",category:"cost",data:i(a.join(" ")),priority:2}]}var T=/[,;,;、،]/u,ut=15,ft=500;function dt(t){if(m.test(t)||!k.test(t)||!T.test(t))return!1;let e=[...t].length;return e>=ut&&e<=ft}function gt(t){let e=t.trim();return dt(e)?[{type:"decision",category:"decision",data:i(t),priority:2}]:[]}var ht=8,_t=120,yt=new RegExp("\\p{L}+\\s+\\p{L}+","u"),mt=new RegExp("\\p{L}{6,}","u");function bt(t){let e=t.split(/[.!\n。!]/u)[0].trim();if(m.test(e)||T.test(e)||!k.test(e))return!1;let n=[...e].length;return n<ht||n>_t?!1:yt.test(e)||mt.test(e)}function kt(t){let e=t.trim();return bt(e)?[{type:"role",category:"role",data:i(t),priority:3}]:[]}var m=/[??؟¿]/u,k=new RegExp("\\p{L}","u"),St=60;function Et(t){if(m.test(t)||!k.test(t))return!1;let e=[...t].length;return e>0&&e<St}function wt(t){let e=t.trim();if(!e)return[];let n;return m.test(e)?n="investigate":Et(e)&&(n="implement"),n?[{type:"intent",category:"intent",data:i(n),priority:4}]:[]}var vt=/^(?:\/goal\s+|(?:goal|objective)\s*:\s*)(.+)$/is;function Rt(t){let e=t.trim();if(!e)return[];let n=e.match(vt);if(!n)return[];let r=n[1].trim();return r?[{type:"goal",category:"goal",data:i(r),priority:4}]:[]}var xt=/(?:\bError\s*:|\bException\s*:|\bTraceback\b|\bat\s+\S+\s*\([^)]*:\d+:\d+\))/u,Tt=/[✓✔✅☑🎉]/u,At=/^\s*(?:fixed|resolved)\s*:/iu;function $t(t){let e=[];return Tt.test(t)||At.test(t)?(e.push({type:"blocker_resolved",category:"blocked-on",data:i(t),priority:2}),e):(xt.test(t)&&e.push({type:"blocker",category:"blocked-on",data:i(t),priority:2}),e)}function It(t){return t.length<=1024?[]:[{type:"data",category:"data",data:i(t),priority:4}]}var f=null;function Ct(t){let{tool_name:e,tool_response:n}=t,r=String(n??"");if(_(t))return f={tool:e,error:r.slice(0,200),callsSince:0},[];if(!f)return[];if(f.callsSince++,f.callsSince>10)return f=null,[];if(!!_(t))return[];let s=e===f.tool,a=f.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(s||a){let p={type:"error_resolved",category:"error-resolution",data:i(`Error in ${f.tool}: ${f.error} \u2192 Fixed`),priority:2};return f=null,[p]}return[]}function Wt(){f=null}var d=[];function Ht(t){return`${t.length}:${t.slice(0,20)}`}function Ot(t){let{tool_name:e,tool_input:n}=t,r=Ht(JSON.stringify(n).slice(0,200));if(d.push({tool:e,inputHash:r}),d.length>50&&d.splice(0,d.length-50),d.length<3)return[];let o=0;for(let s=d.length-1;s>=0&&(d[s].tool===e&&d[s].inputHash===r);s--)o++;return o>=3?(d.splice(d.length-o),[{type:"retry_detected",category:"iteration-loop",data:i(`${e} called ${o} times with similar input`),priority:2}]):[]}function Dt(){d.length=0}var Pt={run_shell_command:"Bash",read_file:"Read",read_many_files:"Read",grep_search:"Grep",search_file_content:"Grep",web_fetch:"WebFetch",write_file:"Write",edit:"Edit",glob:"Glob",todo_write:"TodoWrite",ask_user_question:"AskUserQuestion",list_directory:"LS",save_memory:"Memory",skill:"Skill",exit_plan_mode:"ExitPlanMode",agent:"Agent",bash:"Bash",view:"Read",grep:"Grep",fetch:"WebFetch",shell:"Bash",shell_command:"Bash",exec_command:"Bash","container.exec":"Bash",local_shell:"Bash",grep_files:"Grep",run_command:"Bash",view_file:"Read",read_url_content:"WebFetch",list_dir:"LS",search_web:"WebSearch"};function Mt(t){let e=Pt[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function Bt(t){try{let e=Mt(t),n=[];return n.push(...$(e)),n.push(...I(e)),n.push(...C(e)),n.push(...H(e)),n.push(...G(e)),n.push(...W(e)),n.push(...F(e)),n.push(...K(e)),n.push(...q(e)),n.push(...z(e)),n.push(...Z(e)),n.push(...tt(e)),n.push(...J(e)),n.push(...rt(e)),n.push(...st(e)),n.push(...it(e)),n.push(...at(e)),n.push(...lt(e)),n.push(...et(e)),n.push(...nt(e)),n.push(...Ct(e)),n.push(...Ot(e)),n}catch{return[]}}function Ft(t){try{let e=[];return e.push(...jt(t)),e.push(...gt(t)),e.push(...kt(t)),e.push(...wt(t)),e.push(...Rt(t)),e.push(...$t(t)),e.push(...It(t)),e}catch{return[]}}function Ut(t){if(!t||typeof t!="object")return[];let e=t,n=[],r=e.mcp_servers,o=null;return r&&typeof r=="object"&&!Array.isArray(r)&&(o=Object.keys(r),n.push(`mcp_count:${o.length}`),o.length>0&&n.push(`mcp_servers:${o.slice(0,8).join(",")}`)),typeof e.model=="string"&&n.push(`model:${e.model.slice(0,64)}`),typeof e.permission_mode=="string"&&n.push(`permission_mode:${e.permission_mode.slice(0,32)}`),n.length===0?[]:[{type:"session_settings_snapshot",category:"env",data:i(n.join(" ")),priority:2}]}var Lt=["Latin","Cyrillic","Arabic","Han","Hangul","Hiragana","Katakana","Devanagari","Hebrew","Thai","Greek"],Nt={prompt_length:0,prompt_word_count:0,prompt_uppercase_ratio:0,prompt_file_ref_count:0,prompt_path_ref_count:0,prompt_script_primary:null,prompt_script_count:0,prompt_question_glyph_count:0,prompt_code_block_count:0,prompt_url_count:0,prompt_word_tokens:[]};function Gt(t){if(typeof t!="string"||t.length===0)return{...Nt,prompt_word_tokens:[]};let e=t.match(new RegExp("\\p{L}+","gu"))??[],n=(t.match(new RegExp("\\p{Lu}","gu"))??[]).length,r=e.join("").length,o=(t.match(/```/g)??[]).length,s={};for(let l of Lt){let u=new RegExp(`\\p{Script=${l}}`,"gu"),g=(t.match(u)??[]).length;g>0&&(s[l]=g)}let a=Object.entries(s).sort((l,u)=>u[1]-l[1])[0]?.[0]??null,p=new Set,c=[];for(let l of e){if(l.length<3)continue;let u=l.toLowerCase();p.has(u)||(p.add(u),c.push(u))}return{prompt_length:t.length,prompt_word_count:e.length,prompt_uppercase_ratio:r===0?0:n/r,prompt_file_ref_count:(t.match(/(\w+\/)+\w+\.\w+/g)??[]).length,prompt_path_ref_count:(t.match(/\.{0,2}\/[\w\/.-]+/g)??[]).length,prompt_script_primary:a,prompt_script_count:Object.keys(s).length,prompt_question_glyph_count:(t.match(/[??؟]/gu)??[]).length,prompt_code_block_count:Math.floor(o/2),prompt_url_count:(t.match(/https?:\/\/[^\s]+/gu)??[]).length,prompt_word_tokens:c}}function jt(t){if(typeof t!="string"||t.length===0)return[];let e=0;for(;e<t.length;){let o=t.charCodeAt(e);if(o!==32&&o!==9)break;e++}if(e+5>t.length)return[];if(t.slice(e,e+5)!=="/plan")return[];if(e+5<t.length){let o=t.charCodeAt(e+5);if(!(o===32||o===9||o===10||o===13))return[]}let n=t.slice(e+5).trim(),r=n.length>0?`plan via /plan slash: ${n.slice(0,120)}`:"plan via /plan slash";return[{type:"plan_enter",category:"plan",data:i(r),priority:2}]}export{Bt as extractEvents,Ut as extractSessionSettings,Ft as extractUserEvents,Gt as extractUserPromptFeatures,Wt as resetErrorResolutionState,Dt as resetIterationLoopState};
|
|
@@ -143,6 +143,19 @@ export const GEMINI_OPTS = {
|
|
|
143
143
|
sessionIdEnv: undefined,
|
|
144
144
|
};
|
|
145
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Antigravity CLI (`agy`) platform options. Shares the Gemini-family session
|
|
148
|
+
* root (~/.gemini/context-mode/sessions). agy supplies the conversation id and
|
|
149
|
+
* workspace path inside the hook payload (mapped to session_id/cwd before these
|
|
150
|
+
* opts are consulted), so no env-var fallbacks are needed.
|
|
151
|
+
*/
|
|
152
|
+
export const ANTIGRAVITY_CLI_OPTS = {
|
|
153
|
+
configDir: ".gemini",
|
|
154
|
+
configDirEnv: undefined,
|
|
155
|
+
projectDirEnv: undefined,
|
|
156
|
+
sessionIdEnv: undefined,
|
|
157
|
+
};
|
|
158
|
+
|
|
146
159
|
/** VS Code Copilot platform options. */
|
|
147
160
|
export const VSCODE_OPTS = {
|
|
148
161
|
configDir: ".vscode",
|
|
@@ -151,6 +164,14 @@ export const VSCODE_OPTS = {
|
|
|
151
164
|
sessionIdEnv: undefined,
|
|
152
165
|
};
|
|
153
166
|
|
|
167
|
+
/** GitHub Copilot CLI platform options. */
|
|
168
|
+
export const COPILOT_OPTS = {
|
|
169
|
+
configDir: ".copilot",
|
|
170
|
+
configDirEnv: "COPILOT_HOME",
|
|
171
|
+
projectDirEnv: undefined,
|
|
172
|
+
sessionIdEnv: undefined,
|
|
173
|
+
};
|
|
174
|
+
|
|
154
175
|
/** Cursor platform options. */
|
|
155
176
|
export const CURSOR_OPTS = {
|
|
156
177
|
configDir: ".cursor",
|
|
@@ -195,11 +195,14 @@ function enrichEventForPlatform(event, attribution) {
|
|
|
195
195
|
if (event?.type === "blocker") enriched.blocker_status = "open";
|
|
196
196
|
else if (event?.type === "blocker_resolved") enriched.blocker_status = "resolved";
|
|
197
197
|
|
|
198
|
-
//
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
|
|
198
|
+
// v1.0.161 (Bug 2): gate per-event commit_message + has_commit on
|
|
199
|
+
// type='git_commit', NOT category='git'. Non-commit git operations
|
|
200
|
+
// (push/diff/status) used to inflate commit_message with the operation
|
|
201
|
+
// name and falsely raise has_commit on rows that should have remained
|
|
202
|
+
// commit-neutral. The rollup spread now stamps both fields symmetrically
|
|
203
|
+
// from the session's latest actual commit — see SessionDB.getSessionRollup
|
|
204
|
+
// and src/session/extract.ts:extractGit type discriminator.
|
|
205
|
+
if (event?.type === "git_commit" && dataStr.length > 0) {
|
|
203
206
|
enriched.commit_message = dataStr.slice(0, 500);
|
|
204
207
|
enriched.has_commit = 1;
|
|
205
208
|
}
|
package/hooks/sessionstart.mjs
CHANGED
|
@@ -42,7 +42,7 @@ await runHook(async () => {
|
|
|
42
42
|
const { createSessionLoaders, attributeAndInsertEvents } = await import("./session-loaders.mjs");
|
|
43
43
|
const { join, dirname } = await import("node:path");
|
|
44
44
|
const { fileURLToPath } = await import("node:url");
|
|
45
|
-
const { readFileSync, unlinkSync, readdirSync, rmSync, lstatSync } = await import("node:fs");
|
|
45
|
+
const { readFileSync, unlinkSync, readdirSync, rmSync, lstatSync, realpathSync, symlinkSync } = await import("node:fs");
|
|
46
46
|
|
|
47
47
|
const detectedPlatform = detectPlatformFromEnv();
|
|
48
48
|
const toolNamer = createToolNamer(detectedPlatform);
|
|
@@ -50,7 +50,7 @@ await runHook(async () => {
|
|
|
50
50
|
|
|
51
51
|
// Resolve absolute path for imports (fileURLToPath for Windows compat)
|
|
52
52
|
const HOOK_DIR = dirname(fileURLToPath(import.meta.url));
|
|
53
|
-
const { loadSessionDB, loadProjectAttribution } = createSessionLoaders(HOOK_DIR);
|
|
53
|
+
const { loadSessionDB, loadProjectAttribution, loadExtract } = createSessionLoaders(HOOK_DIR);
|
|
54
54
|
|
|
55
55
|
// Emit a `session_start` canonical event at the boundary of each session
|
|
56
56
|
// lifecycle transition (startup / resume / compact). The platform's insight
|
|
@@ -71,10 +71,24 @@ await runHook(async () => {
|
|
|
71
71
|
}),
|
|
72
72
|
priority: 1,
|
|
73
73
|
};
|
|
74
|
+
|
|
75
|
+
// PRD #4 — emit session_settings_snapshot alongside lifecycle when
|
|
76
|
+
// the SessionStart envelope carries any of mcp_servers / model /
|
|
77
|
+
// permission_mode. Best-effort: missing fields → no snapshot.
|
|
78
|
+
const eventsToEmit = [lifecycleEvent];
|
|
79
|
+
try {
|
|
80
|
+
const extract = await loadExtract();
|
|
81
|
+
if (typeof extract.extractSessionSettings === "function") {
|
|
82
|
+
eventsToEmit.push(...extract.extractSessionSettings(input));
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
// settings snapshot is opportunistic — never block lifecycle on it
|
|
86
|
+
}
|
|
87
|
+
|
|
74
88
|
attributeAndInsertEvents(
|
|
75
89
|
db,
|
|
76
90
|
sessionId,
|
|
77
|
-
|
|
91
|
+
eventsToEmit,
|
|
78
92
|
input,
|
|
79
93
|
projectDir,
|
|
80
94
|
"SessionStart",
|
|
@@ -384,12 +398,44 @@ await runHook(async () => {
|
|
|
384
398
|
const now = Date.now();
|
|
385
399
|
for (const d of readdirSync(cacheParent)) {
|
|
386
400
|
if (d === myDir) continue;
|
|
401
|
+
const oldDir = join(cacheParent, d);
|
|
387
402
|
try {
|
|
388
|
-
const st = lstatSync(
|
|
389
|
-
|
|
390
|
-
|
|
403
|
+
const st = lstatSync(oldDir);
|
|
404
|
+
let danglingBreadcrumb = false;
|
|
405
|
+
if (st.isSymbolicLink()) {
|
|
406
|
+
try {
|
|
407
|
+
realpathSync(oldDir);
|
|
408
|
+
} catch {
|
|
409
|
+
danglingBreadcrumb = true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (danglingBreadcrumb || now - st.mtimeMs > ONE_HOUR) {
|
|
413
|
+
rmSync(oldDir, { recursive: true, force: true });
|
|
414
|
+
// Leave a breadcrumb symlink (junction on Windows) in the
|
|
415
|
+
// removed version's place so sessions that loaded hooks
|
|
416
|
+
// from it before an auto-update keep resolving their
|
|
417
|
+
// scripts instead of erroring on every hook call until
|
|
418
|
+
// restart (#814, #807). Also fires when the entry was
|
|
419
|
+
// itself a stale breadcrumb, re-pointing it at the live
|
|
420
|
+
// root (a chain of updates would otherwise leave links
|
|
421
|
+
// targeting intermediate versions that no longer exist).
|
|
422
|
+
// The fresh mtime makes #644's lstat age gate protect it
|
|
423
|
+
// for the next hour, and the next sweep refreshes it
|
|
424
|
+
// again. Same pattern as healCacheMidSession (server.ts)
|
|
425
|
+
// and postinstall.mjs.
|
|
426
|
+
try {
|
|
427
|
+
symlinkSync(pluginRoot, oldDir, process.platform === "win32" ? "junction" : undefined);
|
|
428
|
+
} catch { /* best effort — plain delete is the pre-#814 behaviour */ }
|
|
391
429
|
}
|
|
392
|
-
} catch {
|
|
430
|
+
} catch {
|
|
431
|
+
// On Windows, a dangling junction can fail before we can read
|
|
432
|
+
// its own mtime. Treat that as a stale breadcrumb and try to
|
|
433
|
+
// repoint it at the live root; failures remain best-effort.
|
|
434
|
+
try {
|
|
435
|
+
rmSync(oldDir, { recursive: true, force: true });
|
|
436
|
+
symlinkSync(pluginRoot, oldDir, process.platform === "win32" ? "junction" : undefined);
|
|
437
|
+
} catch { /* skip */ }
|
|
438
|
+
}
|
|
393
439
|
}
|
|
394
440
|
}
|
|
395
441
|
}
|
package/hooks/stop.mjs
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./suppress-stderr.mjs";
|
|
3
|
+
import "./ensure-deps.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Claude Code Stop hook — record turn-end state for continuity.
|
|
6
|
+
*
|
|
7
|
+
* Stop fires when Claude is about to finish the current assistant turn. This is
|
|
8
|
+
* not a true session shutdown event, so record a turn_end marker and never ask
|
|
9
|
+
* Claude to continue.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { readStdin, parseStdin, getSessionId, getSessionDBPath, getInputProjectDir } from "./session-helpers.mjs";
|
|
13
|
+
import { createSessionLoaders } from "./session-loaders.mjs";
|
|
14
|
+
import { dirname } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const HOOK_DIR = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const { loadSessionDB } = createSessionLoaders(HOOK_DIR);
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const raw = await readStdin();
|
|
22
|
+
const input = parseStdin(raw);
|
|
23
|
+
const projectDir = getInputProjectDir(input);
|
|
24
|
+
|
|
25
|
+
const { SessionDB } = await loadSessionDB();
|
|
26
|
+
const dbPath = getSessionDBPath(undefined, projectDir);
|
|
27
|
+
const db = new SessionDB({ dbPath });
|
|
28
|
+
const sessionId = getSessionId(input);
|
|
29
|
+
|
|
30
|
+
db.ensureSession(sessionId, projectDir);
|
|
31
|
+
const payload = {
|
|
32
|
+
stop_hook_active: input.stop_hook_active ?? false,
|
|
33
|
+
last_assistant_message: typeof input.last_assistant_message === "string"
|
|
34
|
+
? input.last_assistant_message.slice(0, 2000)
|
|
35
|
+
: null,
|
|
36
|
+
};
|
|
37
|
+
db.insertEvent(sessionId, {
|
|
38
|
+
type: "turn_end",
|
|
39
|
+
category: "session",
|
|
40
|
+
data: JSON.stringify(payload),
|
|
41
|
+
priority: 1,
|
|
42
|
+
}, "Stop");
|
|
43
|
+
|
|
44
|
+
db.close();
|
|
45
|
+
} catch {
|
|
46
|
+
// Claude Code hooks must not block the session.
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
process.stdout.write("{}\n");
|
|
@@ -44,7 +44,7 @@ await runHook(async () => {
|
|
|
44
44
|
|
|
45
45
|
if (trimmed.length > 0 && !isSystemMessage) {
|
|
46
46
|
const { SessionDB } = await loadSessionDB();
|
|
47
|
-
const { extractUserEvents } = await loadExtract();
|
|
47
|
+
const { extractUserEvents, extractUserPromptFeatures } = await loadExtract();
|
|
48
48
|
const { resolveProjectAttributions } = await loadProjectAttribution();
|
|
49
49
|
const dbPath = getSessionDBPath();
|
|
50
50
|
const db = new SessionDB({ dbPath });
|
|
@@ -52,12 +52,19 @@ await runHook(async () => {
|
|
|
52
52
|
|
|
53
53
|
db.ensureSession(sessionId, projectDir);
|
|
54
54
|
|
|
55
|
-
// 1. Always save the raw prompt
|
|
55
|
+
// 1. Always save the raw prompt with F1 §2 features attached.
|
|
56
|
+
// Features attach to the existing user_prompt event payload alongside
|
|
57
|
+
// the raw `data` field (do NOT remove `data`). Platform Zod envelope
|
|
58
|
+
// is forward-compatible; new fields persist as typed columns.
|
|
59
|
+
const promptFeatures = typeof extractUserPromptFeatures === "function"
|
|
60
|
+
? extractUserPromptFeatures(trimmed)
|
|
61
|
+
: {};
|
|
56
62
|
const promptEvent = {
|
|
57
63
|
type: "user_prompt",
|
|
58
64
|
category: "user-prompt",
|
|
59
65
|
data: prompt,
|
|
60
66
|
priority: 1,
|
|
67
|
+
...promptFeatures,
|
|
61
68
|
};
|
|
62
69
|
const promptAttributions = attributeAndInsertEvents(
|
|
63
70
|
db, sessionId, [promptEvent], input, projectDir, "UserPromptSubmit", resolveProjectAttributions,
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "Context Mode",
|
|
4
4
|
"kind": "tool",
|
|
5
5
|
"description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.163",
|
|
7
7
|
"sandbox": {
|
|
8
8
|
"mode": "permissive",
|
|
9
9
|
"filesystem_access": "full",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.163",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP plugin that saves 98% of your context window. Works with Claude Code, Gemini CLI, VS Code Copilot, OpenCode, and Codex CLI. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.",
|
|
6
6
|
"author": "Mert Koseoğlu",
|
|
@@ -62,14 +62,6 @@
|
|
|
62
62
|
"build",
|
|
63
63
|
"hooks",
|
|
64
64
|
"configs",
|
|
65
|
-
"insight/server.mjs",
|
|
66
|
-
"insight/package.json",
|
|
67
|
-
"insight/tsconfig.json",
|
|
68
|
-
"insight/vite.config.ts",
|
|
69
|
-
"insight/tailwind.config.ts",
|
|
70
|
-
"insight/postcss.config.js",
|
|
71
|
-
"insight/index.html",
|
|
72
|
-
"insight/src",
|
|
73
65
|
"server.bundle.mjs",
|
|
74
66
|
"cli.bundle.mjs",
|
|
75
67
|
"bin",
|
|
@@ -80,6 +72,7 @@
|
|
|
80
72
|
"openclaw.plugin.json",
|
|
81
73
|
"start.mjs",
|
|
82
74
|
"scripts/postinstall.mjs",
|
|
75
|
+
"scripts/install-antigravity-cli-plugin.mjs",
|
|
83
76
|
"scripts/heal-better-sqlite3.mjs",
|
|
84
77
|
"scripts/heal-installed-plugins.mjs",
|
|
85
78
|
"scripts/plugin-cache-integrity.mjs",
|
|
@@ -92,7 +85,7 @@
|
|
|
92
85
|
"assert-asymmetric-drift": "node scripts/assert-asymmetric-drift.mjs",
|
|
93
86
|
"bundle": "esbuild src/server.ts --bundle --platform=node --target=node18 --format=esm --outfile=server.bundle.mjs --external:better-sqlite3 --external:turndown --external:turndown-plugin-gfm --external:@mixmark-io/domino --minify && esbuild src/cli.ts --bundle --platform=node --target=node18 --format=esm --outfile=cli.bundle.mjs --external:better-sqlite3 --minify && esbuild src/session/extract.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-extract.bundle.mjs --minify && esbuild src/session/snapshot.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-snapshot.bundle.mjs --minify && esbuild src/session/db.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-db.bundle.mjs --external:better-sqlite3 --minify && esbuild src/security.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/security.bundle.mjs --minify",
|
|
94
87
|
"version-sync": "node scripts/version-sync.mjs",
|
|
95
|
-
"version": "node scripts/version-sync.mjs && git add package.json .claude-plugin/plugin.json .claude-plugin/marketplace.json .cursor-plugin/plugin.json .codex-plugin/plugin.json .openclaw-plugin/openclaw.plugin.json .openclaw-plugin/package.json openclaw.plugin.json .pi/extensions/context-mode/package.json",
|
|
88
|
+
"version": "node scripts/version-sync.mjs && git add package.json .claude-plugin/plugin.json .claude-plugin/marketplace.json .cursor-plugin/plugin.json .codex-plugin/plugin.json .openclaw-plugin/openclaw.plugin.json .openclaw-plugin/package.json openclaw.plugin.json .pi/extensions/context-mode/package.json configs/antigravity-cli/plugin.json configs/copilot-cli/.github/plugin/plugin.json",
|
|
96
89
|
"prepublishOnly": "npm run build",
|
|
97
90
|
"dev": "npx tsx src/server.ts",
|
|
98
91
|
"setup": "npx tsx src/cli.ts setup",
|
|
@@ -106,6 +99,7 @@
|
|
|
106
99
|
"test:compare": "npx tsx tests/context-comparison.ts",
|
|
107
100
|
"test:ecosystem": "npx tsx tests/ecosystem-benchmark.ts",
|
|
108
101
|
"install:openclaw": "node -e \"if(process.platform==='win32'){console.error('OpenClaw install requires bash (Git Bash or WSL)');process.exit(1)}else{require('child_process').execSync('bash scripts/install-openclaw-plugin.sh',{stdio:'inherit'})}\"",
|
|
102
|
+
"install:agy": "node scripts/install-antigravity-cli-plugin.mjs",
|
|
109
103
|
"postinstall": "node scripts/postinstall.mjs"
|
|
110
104
|
},
|
|
111
105
|
"dependencies": {
|