context-mode 1.0.67 → 1.0.68

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.
@@ -8,7 +8,8 @@ import "../ensure-deps.mjs";
8
8
  import { createRoutingBlock } from "../routing-block.mjs";
9
9
  import { createToolNamer } from "../core/tool-naming.mjs";
10
10
 
11
- const ROUTING_BLOCK = createRoutingBlock(createToolNamer("codex"));
11
+ const toolNamer = createToolNamer("codex");
12
+ const ROUTING_BLOCK = createRoutingBlock(toolNamer);
12
13
  import {
13
14
  writeSessionEventsFile,
14
15
  buildSessionDirective,
@@ -25,7 +26,7 @@ import {
25
26
  CODEX_OPTS,
26
27
  } from "../session-helpers.mjs";
27
28
  import { join } from "node:path";
28
- import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
29
+ import { unlinkSync } from "node:fs";
29
30
  import { fileURLToPath, pathToFileURL } from "node:url";
30
31
 
31
32
  const HOOK_DIR = fileURLToPath(new URL(".", import.meta.url));
@@ -60,7 +61,7 @@ try {
60
61
  : getLatestSessionEvents(db);
61
62
  if (events.length > 0) {
62
63
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
63
- additionalContext += buildSessionDirective(source, eventMeta);
64
+ additionalContext += buildSessionDirective(source, eventMeta, toolNamer);
64
65
  }
65
66
 
66
67
  db.close();
@@ -70,17 +71,8 @@ try {
70
71
  const db = new SessionDB({ dbPath });
71
72
  try { unlinkSync(getSessionEventsPath(OPTS)); } catch { /* no stale file */ }
72
73
 
73
- const cleanupFlag = getCleanupFlagPath(OPTS);
74
- let previousWasFresh = false;
75
- try { readFileSync(cleanupFlag); previousWasFresh = true; } catch { /* no flag */ }
76
-
77
- if (previousWasFresh) {
78
- db.cleanupOldSessions(0);
79
- } else {
80
- db.cleanupOldSessions(7);
81
- }
74
+ db.cleanupOldSessions(7);
82
75
  db.db.exec(`DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)`);
83
- writeFileSync(cleanupFlag, new Date().toISOString(), "utf-8");
84
76
 
85
77
  const sessionId = getSessionId(input, OPTS);
86
78
  db.ensureSession(sessionId, projectDir);
@@ -8,7 +8,8 @@ import "../ensure-deps.mjs";
8
8
  import { createRoutingBlock } from "../routing-block.mjs";
9
9
  import { createToolNamer } from "../core/tool-naming.mjs";
10
10
 
11
- const ROUTING_BLOCK = createRoutingBlock(createToolNamer("cursor"));
11
+ const toolNamer = createToolNamer("cursor");
12
+ const ROUTING_BLOCK = createRoutingBlock(toolNamer);
12
13
  import {
13
14
  writeSessionEventsFile,
14
15
  buildSessionDirective,
@@ -25,7 +26,7 @@ import {
25
26
  CURSOR_OPTS,
26
27
  } from "../session-helpers.mjs";
27
28
  import { join } from "node:path";
28
- import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
29
+ import { unlinkSync } from "node:fs";
29
30
  import { fileURLToPath, pathToFileURL } from "node:url";
30
31
 
31
32
  const HOOK_DIR = fileURLToPath(new URL(".", import.meta.url));
@@ -64,7 +65,7 @@ try {
64
65
  : getLatestSessionEvents(db);
65
66
  if (events.length > 0) {
66
67
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
67
- additionalContext += buildSessionDirective(source, eventMeta);
68
+ additionalContext += buildSessionDirective(source, eventMeta, toolNamer);
68
69
  }
69
70
 
70
71
  db.close();
@@ -74,17 +75,8 @@ try {
74
75
  const db = new SessionDB({ dbPath });
75
76
  try { unlinkSync(getSessionEventsPath(OPTS)); } catch { /* no stale file */ }
76
77
 
77
- const cleanupFlag = getCleanupFlagPath(OPTS);
78
- let previousWasFresh = false;
79
- try { readFileSync(cleanupFlag); previousWasFresh = true; } catch { /* no flag */ }
80
-
81
- if (previousWasFresh) {
82
- db.cleanupOldSessions(0);
83
- } else {
84
- db.cleanupOldSessions(7);
85
- }
78
+ db.cleanupOldSessions(7);
86
79
  db.db.exec(`DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)`);
87
- writeFileSync(cleanupFlag, new Date().toISOString(), "utf-8");
88
80
 
89
81
  const sessionId = getSessionId(input, OPTS);
90
82
  db.ensureSession(sessionId, projectDir);
@@ -14,14 +14,15 @@ import "../ensure-deps.mjs";
14
14
  import { createRoutingBlock } from "../routing-block.mjs";
15
15
  import { createToolNamer } from "../core/tool-naming.mjs";
16
16
 
17
- const ROUTING_BLOCK = createRoutingBlock(createToolNamer("gemini-cli"));
17
+ const toolNamer = createToolNamer("gemini-cli");
18
+ const ROUTING_BLOCK = createRoutingBlock(toolNamer);
18
19
  import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "../session-directive.mjs";
19
20
  import {
20
21
  readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath,
21
22
  getProjectDir, GEMINI_OPTS,
22
23
  } from "../session-helpers.mjs";
23
24
  import { join, dirname } from "node:path";
24
- import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
25
+ import { readFileSync, unlinkSync } from "node:fs";
25
26
  import { homedir } from "node:os";
26
27
  import { fileURLToPath, pathToFileURL } from "node:url";
27
28
 
@@ -50,7 +51,7 @@ try {
50
51
  const events = getSessionEvents(db, sessionId);
51
52
  if (events.length > 0) {
52
53
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
53
- additionalContext += buildSessionDirective("compact", eventMeta);
54
+ additionalContext += buildSessionDirective("compact", eventMeta, toolNamer);
54
55
  }
55
56
 
56
57
  db.close();
@@ -64,7 +65,7 @@ try {
64
65
  const events = getLatestSessionEvents(db);
65
66
  if (events.length > 0) {
66
67
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
67
- additionalContext += buildSessionDirective("resume", eventMeta);
68
+ additionalContext += buildSessionDirective("resume", eventMeta, toolNamer);
68
69
  }
69
70
 
70
71
  db.close();
@@ -74,17 +75,8 @@ try {
74
75
  const db = new SessionDB({ dbPath });
75
76
  try { unlinkSync(getSessionEventsPath(OPTS)); } catch { /* no stale file */ }
76
77
 
77
- const cleanupFlag = getCleanupFlagPath(OPTS);
78
- let previousWasFresh = false;
79
- try { readFileSync(cleanupFlag); previousWasFresh = true; } catch { /* no flag */ }
80
-
81
- if (previousWasFresh) {
82
- db.cleanupOldSessions(0);
83
- } else {
84
- db.cleanupOldSessions(7);
85
- }
78
+ db.cleanupOldSessions(7);
86
79
  db.db.exec(`DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)`);
87
- writeFileSync(cleanupFlag, new Date().toISOString(), "utf-8");
88
80
 
89
81
  const sessionId = getSessionId(input, OPTS);
90
82
  const projectDir = getProjectDir(OPTS);
@@ -211,7 +211,7 @@ export function writeSessionEventsFile(events, eventsPath) {
211
211
  }
212
212
 
213
213
  // ── Build session guide — actionable narrative for LLM to continue from ──
214
- export function buildSessionDirective(source, eventMeta) {
214
+ export function buildSessionDirective(source, eventMeta, toolNamer) {
215
215
  const { grouped, lastPrompt, fileNames } = eventMeta;
216
216
  const isCompact = source === "compact";
217
217
 
@@ -417,7 +417,8 @@ export function buildSessionDirective(source, eventMeta) {
417
417
  // Search on demand — detailed data lives in FTS5
418
418
  block += `\n<session_search>`;
419
419
  block += `\nDetailed session data is indexed in context-mode FTS5 (source: "session-events").`;
420
- block += `\nUse mcp__plugin_context-mode_context-mode__ctx_search(queries: [...], source: "session-events") when you need specifics.`;
420
+ const searchTool = toolNamer ? toolNamer("ctx_search") : "ctx_search";
421
+ block += `\nUse ${searchTool}(queries: [...], source: "session-events") when you need specifics.`;
421
422
  block += `\nDo NOT call ctx_index() — data is already indexed.`;
422
423
  block += `\n</session_search>`;
423
424
 
@@ -1 +1 @@
1
- function o(t,e=300){return t==null?"":t.length<=e?t:t.slice(0,e)}function c(t,e=300){if(t==null)return"";let n=typeof t=="string"?t:JSON.stringify(t);return o(n,e)}function l(t){let{tool_name:e,tool_input:n,tool_response:s}=t,r=[];if(e==="Read"){let i=String(n.file_path??"");return/CLAUDE\.md$|\.claude[\\/]/i.test(i)&&(r.push({type:"rule",category:"rule",data:o(i),priority:1}),s&&s.length>0&&r.push({type:"rule_content",category:"rule",data:o(s,5e3),priority:1})),r.push({type:"file_read",category:"file",data:o(i),priority:1}),r}if(e==="Edit"){let i=String(n.file_path??"");return r.push({type:"file_edit",category:"file",data:o(i),priority:1}),r}if(e==="NotebookEdit"){let i=String(n.notebook_path??"");return r.push({type:"file_edit",category:"file",data:o(i),priority:1}),r}if(e==="Write"){let i=String(n.file_path??"");return r.push({type:"file_write",category:"file",data:o(i),priority:1}),r}if(e==="Glob"){let i=String(n.pattern??"");return r.push({type:"file_glob",category:"file",data:o(i),priority:3}),r}if(e==="Grep"){let i=String(n.pattern??""),a=String(n.path??"");return r.push({type:"file_search",category:"file",data:o(`${i} in ${a}`),priority:3}),r}return r}function u(t){if(t.tool_name!=="Bash")return[];let n=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!n)return[];let s=n[2]??n[3]??n[4]??"";return[{type:"cwd",category:"cwd",data:o(s),priority:2}]}function d(t){let{tool_name:e,tool_input:n,tool_response:s,tool_output:r}=t,i=String(s??""),a=r?.isError===!0;return!(e==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(i))&&!a?[]:[{type:"error_tool",category:"error",data:o(i,300),priority:2}]}var g=[{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 b(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),n=g.find(s=>s.pattern.test(e));return n?[{type:"git",category:"git",data:o(n.operation),priority:2}]:[]}function y(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:o(JSON.stringify(t.tool_input),300),priority:1}]:[]}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,s=Array.isArray(n)&&n.length>0?`exited plan mode (allowed: ${c(n.map(i=>typeof i=="object"&&i!==null&&"prompt"in i?String(i.prompt):String(i)).join(", "),200)})`:"exited plan mode";e.push({type:"plan_exit",category:"plan",data:o(s),priority:2});let r=String(t.tool_response??"").toLowerCase();return r.includes("approved")||r.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(r.includes("rejected")||r.includes("decline")||r.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:o(`plan rejected: ${t.tool_response??""}`,300),priority:2}),e}if(t.tool_name==="Write"||t.tool_name==="Edit"){let e=String(t.tool_input.file_path??"");if(/[/\\]\.claude[/\\]plans[/\\]/.test(e))return[{type:"plan_file_write",category:"plan",data:o(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return[]}var h=[/\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 _(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!h.some(r=>r.test(e)))return[];let s=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:o(s),priority:2}]}function m(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:o(e),priority:3}]}function S(t){if(t.tool_name!=="Agent")return[];let e=o(String(t.tool_input.prompt??t.tool_input.description??""),200),n=t.tool_response?o(String(t.tool_response),300):"",s=n.length>0;return[{type:s?"subagent_completed":"subagent_launched",category:"subagent",data:o(s?`[completed] ${e} \u2192 ${n}`:`[launched] ${e}`,300),priority:s?2:3}]}function k(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let s=e.split("__"),r=s[s.length-1]||e,i=Object.values(n).find(p=>typeof p=="string"),a=i?`: ${o(String(i),100)}`:"";return[{type:"mcp",category:"mcp",data:o(`${r}${a}`),priority:3}]}function E(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,n=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",s=o(String(t.tool_response??""),150),r=n?`Q: ${o(n,120)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:o(r),priority:2}]}function v(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:o(`entered worktree: ${e}`),priority:2}]}var x=[/\b(don'?t|do not|never|always|instead|rather|prefer)\b/i,/\b(use|switch to|go with|pick|choose)\s+\w+\s+(instead|over|not)\b/i,/\b(no,?\s+(use|do|try|make))\b/i,/\b(hayır|hayir|evet|böyle|boyle|degil|değil|yerine|kullan)\b/i];function w(t){return x.some(n=>n.test(t))?[{type:"decision",category:"decision",data:o(t,300),priority:2}]:[]}var T=[/\b(act as|you are|behave like|pretend|role of|persona)\b/i,/\b(senior|staff|principal|lead)\s+(engineer|developer|architect)\b/i,/\b(gibi davran|rolünde|olarak çalış)\b/i];function R(t){return T.some(n=>n.test(t))?[{type:"role",category:"role",data:o(t,300),priority:3}]:[]}var A=[{mode:"investigate",pattern:/\b(why|how does|explain|understand|what is|analyze|debug|look into)\b/i},{mode:"implement",pattern:/\b(create|add|build|implement|write|make|develop|fix)\b/i},{mode:"discuss",pattern:/\b(think about|consider|should we|what if|pros and cons|opinion)\b/i},{mode:"review",pattern:/\b(review|check|audit|verify|test|validate)\b/i}];function I(t){let e=A.find(({pattern:n})=>n.test(t));return e?[{type:"intent",category:"intent",data:o(e.mode),priority:4}]:[]}function $(t){return t.length<=1024?[]:[{type:"data",category:"data",data:o(t,200),priority:4}]}function P(t){try{let e=[];return e.push(...l(t)),e.push(...u(t)),e.push(...d(t)),e.push(...b(t)),e.push(..._(t)),e.push(...y(t)),e.push(...f(t)),e.push(...m(t)),e.push(...S(t)),e.push(...k(t)),e.push(...E(t)),e.push(...v(t)),e}catch{return[]}}function H(t){try{let e=[];return e.push(...w(t)),e.push(...R(t)),e.push(...I(t)),e.push(...$(t)),e}catch{return[]}}export{P as extractEvents,H as extractUserEvents};
1
+ function o(t){return t==null?"":String(t)}function l(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function c(t){let{tool_name:e,tool_input:n,tool_response:s}=t,r=[];if(e==="Read"){let i=String(n.file_path??"");return/CLAUDE\.md$|\.claude[\\/]/i.test(i)&&(r.push({type:"rule",category:"rule",data:o(i),priority:1}),s&&s.length>0&&r.push({type:"rule_content",category:"rule",data:o(s),priority:1})),r.push({type:"file_read",category:"file",data:o(i),priority:1}),r}if(e==="Edit"){let i=String(n.file_path??"");return r.push({type:"file_edit",category:"file",data:o(i),priority:1}),r}if(e==="NotebookEdit"){let i=String(n.notebook_path??"");return r.push({type:"file_edit",category:"file",data:o(i),priority:1}),r}if(e==="Write"){let i=String(n.file_path??"");return r.push({type:"file_write",category:"file",data:o(i),priority:1}),r}if(e==="Glob"){let i=String(n.pattern??"");return r.push({type:"file_glob",category:"file",data:o(i),priority:3}),r}if(e==="Grep"){let i=String(n.pattern??""),a=String(n.path??"");return r.push({type:"file_search",category:"file",data:o(`${i} in ${a}`),priority:3}),r}return r}function u(t){if(t.tool_name!=="Bash")return[];let n=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!n)return[];let s=n[2]??n[3]??n[4]??"";return[{type:"cwd",category:"cwd",data:o(s),priority:2}]}function d(t){let{tool_name:e,tool_input:n,tool_response:s,tool_output:r}=t,i=String(s??""),a=r?.isError===!0;return!(e==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(i))&&!a?[]:[{type:"error_tool",category:"error",data:o(i),priority:2}]}var g=[{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 b(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),n=g.find(s=>s.pattern.test(e));return n?[{type:"git",category:"git",data:o(n.operation),priority:2}]:[]}function y(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:o(JSON.stringify(t.tool_input)),priority:1}]:[]}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,s=Array.isArray(n)&&n.length>0?`exited plan mode (allowed: ${l(n.map(i=>typeof i=="object"&&i!==null&&"prompt"in i?String(i.prompt):String(i)).join(", "))})`:"exited plan mode";e.push({type:"plan_exit",category:"plan",data:o(s),priority:2});let r=String(t.tool_response??"").toLowerCase();return r.includes("approved")||r.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(r.includes("rejected")||r.includes("decline")||r.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:o(`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(/[/\\]\.claude[/\\]plans[/\\]/.test(e))return[{type:"plan_file_write",category:"plan",data:o(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return[]}var h=[/\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 _(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!h.some(r=>r.test(e)))return[];let s=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:o(s),priority:2}]}function m(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:o(e),priority:3}]}function S(t){if(t.tool_name!=="Agent")return[];let e=o(String(t.tool_input.prompt??t.tool_input.description??"")),n=t.tool_response?o(String(t.tool_response)):"",s=n.length>0;return[{type:s?"subagent_completed":"subagent_launched",category:"subagent",data:o(s?`[completed] ${e} \u2192 ${n}`:`[launched] ${e}`),priority:s?2:3}]}function k(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let s=e.split("__"),r=s[s.length-1]||e,i=Object.values(n).find(p=>typeof p=="string"),a=i?`: ${o(String(i))}`:"";return[{type:"mcp",category:"mcp",data:o(`${r}${a}`),priority:3}]}function E(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,n=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",s=o(String(t.tool_response??"")),r=n?`Q: ${o(n)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:o(r),priority:2}]}function v(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:o(`entered worktree: ${e}`),priority:2}]}var x=[/\b(don'?t|do not|never|always|instead|rather|prefer)\b/i,/\b(use|switch to|go with|pick|choose)\s+\w+\s+(instead|over|not)\b/i,/\b(no,?\s+(use|do|try|make))\b/i,/\b(hayır|hayir|evet|böyle|boyle|degil|değil|yerine|kullan)\b/i];function w(t){return x.some(n=>n.test(t))?[{type:"decision",category:"decision",data:o(t),priority:2}]:[]}var T=[/\b(act as|you are|behave like|pretend|role of|persona)\b/i,/\b(senior|staff|principal|lead)\s+(engineer|developer|architect)\b/i,/\b(gibi davran|rolünde|olarak çalış)\b/i];function R(t){return T.some(n=>n.test(t))?[{type:"role",category:"role",data:o(t),priority:3}]:[]}var A=[{mode:"investigate",pattern:/\b(why|how does|explain|understand|what is|analyze|debug|look into)\b/i},{mode:"implement",pattern:/\b(create|add|build|implement|write|make|develop|fix)\b/i},{mode:"discuss",pattern:/\b(think about|consider|should we|what if|pros and cons|opinion)\b/i},{mode:"review",pattern:/\b(review|check|audit|verify|test|validate)\b/i}];function I(t){let e=A.find(({pattern:n})=>n.test(t));return e?[{type:"intent",category:"intent",data:o(e.mode),priority:4}]:[]}function $(t){return t.length<=1024?[]:[{type:"data",category:"data",data:o(t),priority:4}]}function P(t){try{let e=[];return e.push(...c(t)),e.push(...u(t)),e.push(...d(t)),e.push(...b(t)),e.push(..._(t)),e.push(...y(t)),e.push(...f(t)),e.push(...m(t)),e.push(...S(t)),e.push(...k(t)),e.push(...E(t)),e.push(...v(t)),e}catch{return[]}}function H(t){try{let e=[];return e.push(...w(t)),e.push(...R(t)),e.push(...I(t)),e.push(...$(t)),e}catch{return[]}}export{P as extractEvents,H as extractUserEvents};
@@ -1,14 +1,29 @@
1
- function l(t,e){return t.length<=e?t:t.slice(0,Math.max(0,e-3))+"..."}function a(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}var G=2048,J=10;function q(t){if(t.length===0)return"";let e=new Map;for(let u of t){let p=u.data,i=e.get(p);i||(i={ops:new Map,last:""},e.set(p,i));let r;u.type==="file_write"?r="write":u.type==="file_read"?r="read":u.type==="file_edit"?r="edit":r=u.type,i.ops.set(r,(i.ops.get(r)??0)+1),i.last=r}let s=Array.from(e.entries()).slice(-J),c=[" <active_files>"];for(let[u,{ops:p,last:i}]of s){let r=Array.from(p.entries()).map(([f,g])=>`${f}:${g}`).join(",");c.push(` <file path="${a(u)}" ops="${a(r)}" last="${a(i)}" />`)}return c.push(" </active_files>"),c.join(`
2
- `)}function z(t){if(t.length===0)return"";let e=[],n={};for(let i of t)try{let r=JSON.parse(i.data);typeof r.subject=="string"?e.push(r.subject):typeof r.taskId=="string"&&typeof r.status=="string"&&(n[r.taskId]=r.status)}catch{}if(e.length===0)return"";let s=new Set(["completed","deleted","failed"]),c=Object.keys(n).sort((i,r)=>Number(i)-Number(r)),u=[];for(let i=0;i<e.length;i++){let r=c[i],f=r?n[r]??"pending":"pending";s.has(f)||u.push(e[i])}if(u.length===0)return"";let p=[" <task_state>"];for(let i of u)p.push(` - ${a(l(i,100))}`);return p.push(" </task_state>"),p.join(`
3
- `)}function U(t){if(t.length===0)return"";let e=new Set,n=[" <rules>"];for(let s of t){let c=s.data;e.has(c)||(e.add(c),s.type==="rule_content"?n.push(` <rule_content>${a(l(s.data,400))}</rule_content>`):n.push(` - ${a(l(s.data,200))}`))}return n.push(" </rules>"),n.join(`
4
- `)}function V(t){if(t.length===0)return"";let e=new Set,n=[" <decisions>"];for(let s of t){let c=s.data;e.has(c)||(e.add(c),n.push(` - ${a(l(s.data,200))}`))}return n.push(" </decisions>"),n.join(`
5
- `)}function Y(t,e,n){let s=[];if(!t&&e.length===0&&!n)return"";s.push(" <environment>"),t&&s.push(` <cwd>${a(t.data)}</cwd>`),n&&s.push(` <git op="${a(n.data)}" />`);for(let c of e)s.push(` <env>${a(l(c.data,150))}</env>`);return s.push(" </environment>"),s.join(`
6
- `)}function H(t){if(t.length===0)return"";let e=[" <errors_encountered>"];for(let n of t)e.push(` - ${a(l(n.data,150))}`);return e.push(" </errors_encountered>"),e.join(`
7
- `)}function K(t){return` <intent mode="${a(t.data)}">${a(l(t.data,100))}</intent>`}function P(t){if(t.length===0)return"";let e=[" <subagents>"];for(let n of t){let s=n.type==="subagent_completed"?"completed":n.type==="subagent_launched"?"launched":"unknown";e.push(` <agent status="${s}">${a(l(n.data,200))}</agent>`)}return e.push(" </subagents>"),e.join(`
8
- `)}function Q(t){if(t.length===0)return"";let e=new Map;for(let s of t){let c=s.data.split(":")[0].trim();e.set(c,(e.get(c)??0)+1)}let n=[" <mcp_tools>"];for(let[s,c]of e)n.push(` <tool name="${a(s)}" calls="${c}" />`);return n.push(" </mcp_tools>"),n.join(`
9
- `)}function et(t,e){let n=e?.maxBytes??G,s=e?.compactCount??1,c=new Date().toISOString(),u=[],p=[],i=[],r=[],f=[],g=[],$=[],h=[],E=[],S=[],w=[],m=[];for(let o of t)switch(o.category){case"file":u.push(o);break;case"task":p.push(o);break;case"rule":i.push(o);break;case"decision":r.push(o);break;case"cwd":f.push(o);break;case"error":g.push(o);break;case"env":$.push(o);break;case"git":h.push(o);break;case"subagent":E.push(o);break;case"intent":S.push(o);break;case"mcp":w.push(o);break;case"plan":m.push(o);break}let b=[],x=q(u);x&&b.push(x);let B=z(p);B&&b.push(B);let j=U(i);j&&b.push(j);let d=[],I=V(r);I&&d.push(I);let R=f.length>0?f[f.length-1]:void 0,F=h.length>0?h[h.length-1]:void 0,L=Y(R,$,F);L&&d.push(L);let M=H(g);M&&d.push(M);let D=E.filter(o=>o.type==="subagent_completed"),O=P(D);O&&d.push(O),m.length>0&&m[m.length-1].type==="plan_enter"&&d.push(' <plan_mode status="active" />');let v=[];if(S.length>0){let o=S[S.length-1];v.push(K(o))}let T=Q(w);T&&v.push(T);let X=E.filter(o=>o.type==="subagent_launched"),A=P(X);A&&v.push(A);let _=`<session_resume compact_count="${s}" events_captured="${t.length}" generated_at="${c}">`,k="</session_resume>",C=[b,d,v];for(let o=C.length;o>=0;o--){let N=C.slice(0,o).flat().join(`
10
- `),y;if(N?y=`${_}
11
- ${N}
12
- ${k}`:y=`${_}
13
- ${k}`,Buffer.byteLength(y)<=n)return y}return`${_}
14
- ${k}`}export{et as buildResumeSnapshot,q as renderActiveFiles,V as renderDecisions,Y as renderEnvironment,H as renderErrors,K as renderIntent,Q as renderMcpTools,U as renderRules,P as renderSubagents,z as renderTaskState};
1
+ function a(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}var N=10;function h(t,r=4){return[...new Set(t.filter(o=>o.length>0))].slice(0,r).map(o=>o.length>80?o.slice(0,80):o)}function m(t,r){if(r.length===0)return"";let s=r.map(n=>`"${a(n)}"`).join(", ");return`
2
+ For full details:
3
+ ${a(t)}(
4
+ queries: [${s}],
5
+ source: "session-events"
6
+ )`}function x(t,r){if(t.length===0)return"";let s=new Map;for(let l of t){let b=l.data,p=s.get(b);p||(p={ops:new Map},s.set(b,p));let g;l.type==="file_write"?g="write":l.type==="file_read"?g="read":l.type==="file_edit"?g="edit":g=l.type,p.ops.set(g,(p.ops.get(g)??0)+1)}let o=Array.from(s.entries()).slice(-N),u=[],i=[];for(let[l,{ops:b}]of o){let p=Array.from(b.entries()).map(([S,y])=>`${S}\xD7${y}`).join(", "),g=l.split("/").pop()??l;u.push(` ${a(g)} (${a(p)})`),i.push(`${g} ${Array.from(b.keys()).join(" ")}`)}let e=h(i);return[` <files count="${s.size}">`,...u,m(r,e)," </files>"].join(`
7
+ `)}function M(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t)s.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <errors count="${t.length}">`,...s,m(r,o)," </errors>"].join(`
8
+ `)}function A(t,r){if(t.length===0)return"";let s=new Set,n=[],o=[];for(let e of t)s.has(e.data)||(s.add(e.data),n.push(` ${a(e.data)}`),o.push(e.data));if(n.length===0)return"";let u=h(o);return[` <decisions count="${n.length}">`,...n,m(r,u)," </decisions>"].join(`
9
+ `)}function D(t,r){if(t.length===0)return"";let s=new Set,n=[],o=[];for(let e of t)s.has(e.data)||(s.add(e.data),e.type==="rule_content"?n.push(` ${a(e.data)}`):n.push(` ${a(e.data)}`),o.push(e.data));if(n.length===0)return"";let u=h(o);return[` <rules count="${n.length}">`,...n,m(r,u)," </rules>"].join(`
10
+ `)}function F(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t)s.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <git count="${t.length}">`,...s,m(r,o)," </git>"].join(`
11
+ `)}function R(t){if(t.length===0)return"";let r=[],s={};for(let e of t)try{let c=JSON.parse(e.data);typeof c.subject=="string"?r.push(c.subject):typeof c.taskId=="string"&&typeof c.status=="string"&&(s[c.taskId]=c.status)}catch{}if(r.length===0)return"";let n=new Set(["completed","deleted","failed"]),o=Object.keys(s).sort((e,c)=>Number(e)-Number(c)),u=[];for(let e=0;e<r.length;e++){let c=o[e],l=c?s[c]??"pending":"pending";n.has(l)||u.push(r[e])}if(u.length===0)return"";let i=[];for(let e of u)i.push(` [pending] ${a(e)}`);return i.join(`
12
+ `)}function J(t,r){let s=R(t);if(!s)return"";let n=[];for(let e of t)try{let c=JSON.parse(e.data);typeof c.subject=="string"&&n.push(c.subject)}catch{}let o=h(n);return[` <task_state count="${s.split(`
13
+ `).length}">`,s,m(r,o)," </task_state>"].join(`
14
+ `)}function X(t,r,s){if(t.length===0&&r.length===0)return"";let n=[],o=[];if(t.length>0){let e=t[t.length-1];n.push(` cwd: ${a(e.data)}`),o.push("working directory")}for(let e of r)n.push(` ${a(e.data)}`),o.push(e.data);let u=h(o);return[" <environment>",...n,m(s,u)," </environment>"].join(`
15
+ `)}function z(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t){let e=i.type==="subagent_completed"?"completed":i.type==="subagent_launched"?"launched":"unknown";s.push(` [${e}] ${a(i.data)}`),n.push(`subagent ${i.data}`)}let o=h(n);return[` <subagents count="${t.length}">`,...s,m(r,o)," </subagents>"].join(`
16
+ `)}function G(t,r){if(t.length===0)return"";let s=new Map;for(let e of t){let c=e.data.split(":")[0].trim();s.set(c,(s.get(c)??0)+1)}let n=[],o=[];for(let[e,c]of s)n.push(` ${a(e)} (${c}\xD7)`),o.push(`skill ${e} invocation`);let u=h(o);return[` <skills count="${t.length}">`,...n,m(r,u)," </skills>"].join(`
17
+ `)}function Q(t){if(t.length===0)return"";let r=t[t.length-1];return` <intent mode="${a(r.data)}"/>`}function H(t,r){let s=r?.compactCount??1,n=r?.searchTool??"ctx_search",o=new Date().toISOString(),u=[],i=[],e=[],c=[],l=[],b=[],p=[],g=[],S=[],y=[],k=[];for(let d of t)switch(d.category){case"file":u.push(d);break;case"task":i.push(d);break;case"rule":e.push(d);break;case"decision":c.push(d);break;case"cwd":l.push(d);break;case"error":b.push(d);break;case"env":p.push(d);break;case"git":g.push(d);break;case"subagent":S.push(d);break;case"intent":y.push(d);break;case"skill":k.push(d);break}let f=[];f.push(` <how_to_search>
18
+ Each section below contains a summary of prior work.
19
+ For FULL DETAILS, run the exact tool call shown under each section.
20
+ Do NOT ask the user to re-explain prior work. Search first.
21
+ Do NOT invent your own queries \u2014 use the ones provided.
22
+ </how_to_search>`);let $=x(u,n);$&&f.push($);let v=M(b,n);v&&f.push(v);let w=A(c,n);w&&f.push(w);let E=D(e,n);E&&f.push(E);let q=F(g,n);q&&f.push(q);let L=J(i,n);L&&f.push(L);let _=X(l,p,n);_&&f.push(_);let j=z(S,n);j&&f.push(j);let T=G(k,n);T&&f.push(T);let O=Q(y);O&&f.push(O);let B=`<session_resume events="${t.length}" compact_count="${s}" generated_at="${o}">`,C="</session_resume>",I=f.join(`
23
+
24
+ `);return I?`${B}
25
+
26
+ ${I}
27
+
28
+ ${C}`:`${B}
29
+ ${C}`}export{H as buildResumeSnapshot,R as renderTaskState};
@@ -18,13 +18,14 @@ import "./ensure-deps.mjs";
18
18
  import { createRoutingBlock } from "./routing-block.mjs";
19
19
  import { createToolNamer } from "./core/tool-naming.mjs";
20
20
 
21
- const ROUTING_BLOCK = createRoutingBlock(createToolNamer("claude-code"));
21
+ const toolNamer = createToolNamer("claude-code");
22
+ const ROUTING_BLOCK = createRoutingBlock(toolNamer);
22
23
  import { readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath } from "./session-helpers.mjs";
23
24
  import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "./session-directive.mjs";
24
25
  import { createSessionLoaders } from "./session-loaders.mjs";
25
26
  import { join, dirname } from "node:path";
26
27
  import { fileURLToPath } from "node:url";
27
- import { readFileSync, writeFileSync, unlinkSync, readdirSync, rmSync, statSync } from "node:fs";
28
+ import { readFileSync, unlinkSync, readdirSync, rmSync, statSync } from "node:fs";
28
29
  import { homedir } from "node:os";
29
30
 
30
31
  // Resolve absolute path for imports (fileURLToPath for Windows compat)
@@ -53,7 +54,7 @@ try {
53
54
  const events = getSessionEvents(db, sessionId);
54
55
  if (events.length > 0) {
55
56
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath());
56
- additionalContext += buildSessionDirective("compact", eventMeta);
57
+ additionalContext += buildSessionDirective("compact", eventMeta, toolNamer);
57
58
  }
58
59
 
59
60
  db.close();
@@ -68,7 +69,7 @@ try {
68
69
  const events = getLatestSessionEvents(db);
69
70
  if (events.length > 0) {
70
71
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath());
71
- additionalContext += buildSessionDirective("resume", eventMeta);
72
+ additionalContext += buildSessionDirective("resume", eventMeta, toolNamer);
72
73
  }
73
74
 
74
75
  db.close();
@@ -82,22 +83,9 @@ try {
82
83
  // Detect true fresh start vs --continue (which fires startup→resume).
83
84
  // If cleanup flag exists from a PREVIOUS startup that was never followed by
84
85
  // resume, that was a true fresh start — aggressively wipe all data.
85
- const cleanupFlag = getCleanupFlagPath();
86
- let previousWasFresh = false;
87
- try { readFileSync(cleanupFlag); previousWasFresh = true; } catch { /* no flag */ }
88
-
89
- if (previousWasFresh) {
90
- // Previous session was a true fresh start (no --continue) — clean slate
91
- db.cleanupOldSessions(0);
92
- } else {
93
- // First startup or --continue will follow — only clean old sessions
94
- db.cleanupOldSessions(7);
95
- }
86
+ db.cleanupOldSessions(7);
96
87
  db.db.exec(`DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)`);
97
88
 
98
- // Write cleanup flag — resume will delete it if --continue follows
99
- writeFileSync(cleanupFlag, new Date().toISOString(), "utf-8");
100
-
101
89
  // Proactively capture CLAUDE.md files — Claude Code loads them as system
102
90
  // context at startup, invisible to PostToolUse hooks. We read them from
103
91
  // disk so they survive compact/resume via the session events pipeline.
@@ -15,14 +15,15 @@ import { createSessionLoaders } from "../session-loaders.mjs";
15
15
  import { createRoutingBlock } from "../routing-block.mjs";
16
16
  import { createToolNamer } from "../core/tool-naming.mjs";
17
17
 
18
- const ROUTING_BLOCK = createRoutingBlock(createToolNamer("vscode-copilot"));
18
+ const toolNamer = createToolNamer("vscode-copilot");
19
+ const ROUTING_BLOCK = createRoutingBlock(toolNamer);
19
20
  import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "../session-directive.mjs";
20
21
  import {
21
22
  readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath,
22
23
  getProjectDir, VSCODE_OPTS,
23
24
  } from "../session-helpers.mjs";
24
25
  import { join } from "node:path";
25
- import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
26
+ import { readFileSync, unlinkSync } from "node:fs";
26
27
  import { fileURLToPath, pathToFileURL } from "node:url";
27
28
  import { homedir } from "node:os";
28
29
 
@@ -51,7 +52,7 @@ try {
51
52
  const events = getSessionEvents(db, sessionId);
52
53
  if (events.length > 0) {
53
54
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
54
- additionalContext += buildSessionDirective("compact", eventMeta);
55
+ additionalContext += buildSessionDirective("compact", eventMeta, toolNamer);
55
56
  }
56
57
 
57
58
  db.close();
@@ -65,7 +66,7 @@ try {
65
66
  const events = getLatestSessionEvents(db);
66
67
  if (events.length > 0) {
67
68
  const eventMeta = writeSessionEventsFile(events, getSessionEventsPath(OPTS));
68
- additionalContext += buildSessionDirective("resume", eventMeta);
69
+ additionalContext += buildSessionDirective("resume", eventMeta, toolNamer);
69
70
  }
70
71
 
71
72
  db.close();
@@ -75,17 +76,8 @@ try {
75
76
  const db = new SessionDB({ dbPath });
76
77
  try { unlinkSync(getSessionEventsPath(OPTS)); } catch { /* no stale file */ }
77
78
 
78
- const cleanupFlag = getCleanupFlagPath(OPTS);
79
- let previousWasFresh = false;
80
- try { readFileSync(cleanupFlag); previousWasFresh = true; } catch { /* no flag */ }
81
-
82
- if (previousWasFresh) {
83
- db.cleanupOldSessions(0);
84
- } else {
85
- db.cleanupOldSessions(7);
86
- }
79
+ db.cleanupOldSessions(7);
87
80
  db.db.exec(`DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)`);
88
- writeFileSync(cleanupFlag, new Date().toISOString(), "utf-8");
89
81
 
90
82
  const sessionId = getSessionId(input, OPTS);
91
83
  const projectDir = getProjectDir(OPTS);
@@ -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.67",
6
+ "version": "1.0.68",
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.67",
3
+ "version": "1.0.68",
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",