context-mode 0.9.21 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/hooks/hooks.json +46 -4
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +4 -4
- package/README.md +377 -191
- package/build/adapters/claude-code/config.d.ts +8 -0
- package/build/adapters/claude-code/config.js +8 -0
- package/build/adapters/claude-code/hooks.d.ts +53 -0
- package/build/adapters/claude-code/hooks.js +88 -0
- package/build/adapters/claude-code/index.d.ts +50 -0
- package/build/adapters/claude-code/index.js +523 -0
- package/build/adapters/codex/config.d.ts +8 -0
- package/build/adapters/codex/config.js +8 -0
- package/build/adapters/codex/hooks.d.ts +21 -0
- package/build/adapters/codex/hooks.js +27 -0
- package/build/adapters/codex/index.d.ts +44 -0
- package/build/adapters/codex/index.js +223 -0
- package/build/adapters/detect.d.ts +26 -0
- package/build/adapters/detect.js +131 -0
- package/build/adapters/gemini-cli/config.d.ts +8 -0
- package/build/adapters/gemini-cli/config.js +8 -0
- package/build/adapters/gemini-cli/hooks.d.ts +44 -0
- package/build/adapters/gemini-cli/hooks.js +64 -0
- package/build/adapters/gemini-cli/index.d.ts +57 -0
- package/build/adapters/gemini-cli/index.js +468 -0
- package/build/adapters/opencode/config.d.ts +8 -0
- package/build/adapters/opencode/config.js +8 -0
- package/build/adapters/opencode/hooks.d.ts +38 -0
- package/build/adapters/opencode/hooks.js +50 -0
- package/build/adapters/opencode/index.d.ts +52 -0
- package/build/adapters/opencode/index.js +386 -0
- package/build/adapters/types.d.ts +218 -0
- package/build/adapters/types.js +13 -0
- package/build/adapters/vscode-copilot/config.d.ts +8 -0
- package/build/adapters/vscode-copilot/config.js +8 -0
- package/build/adapters/vscode-copilot/hooks.d.ts +49 -0
- package/build/adapters/vscode-copilot/hooks.js +76 -0
- package/build/adapters/vscode-copilot/index.d.ts +58 -0
- package/build/adapters/vscode-copilot/index.js +512 -0
- package/build/cli.d.ts +9 -6
- package/build/cli.js +133 -423
- package/build/db-base.d.ts +84 -0
- package/build/db-base.js +128 -0
- package/build/executor.d.ts +6 -7
- package/build/executor.js +111 -51
- package/build/opencode-plugin.d.ts +37 -0
- package/build/opencode-plugin.js +118 -0
- package/build/runtime.js +1 -1
- package/build/server.js +436 -117
- package/build/session/db.d.ts +110 -0
- package/build/session/db.js +285 -0
- package/build/session/extract.d.ts +51 -0
- package/build/session/extract.js +407 -0
- package/build/session/snapshot.d.ts +70 -0
- package/build/session/snapshot.js +309 -0
- package/build/store.d.ts +4 -22
- package/build/store.js +67 -55
- package/build/truncate.d.ts +59 -0
- package/build/truncate.js +157 -0
- package/build/types.d.ts +101 -0
- package/build/types.js +20 -0
- package/configs/claude-code/CLAUDE.md +62 -0
- package/configs/codex/AGENTS.md +58 -0
- package/configs/codex/config.toml +5 -0
- package/configs/gemini-cli/GEMINI.md +58 -0
- package/configs/gemini-cli/mcp.json +7 -0
- package/configs/gemini-cli/settings.json +49 -0
- package/configs/opencode/AGENTS.md +58 -0
- package/configs/opencode/opencode.json +10 -0
- package/configs/vscode-copilot/copilot-instructions.md +58 -0
- package/configs/vscode-copilot/hooks.json +16 -0
- package/configs/vscode-copilot/mcp.json +8 -0
- package/hooks/core/formatters.mjs +86 -0
- package/hooks/core/routing.mjs +262 -0
- package/hooks/core/stdin.mjs +19 -0
- package/hooks/formatters/claude-code.mjs +57 -0
- package/hooks/formatters/gemini-cli.mjs +55 -0
- package/hooks/formatters/vscode-copilot.mjs +55 -0
- package/hooks/gemini-cli/aftertool.mjs +58 -0
- package/hooks/gemini-cli/beforetool.mjs +25 -0
- package/hooks/gemini-cli/precompress.mjs +51 -0
- package/hooks/gemini-cli/sessionstart.mjs +117 -0
- package/hooks/hooks.json +46 -4
- package/hooks/posttooluse.mjs +53 -0
- package/hooks/precompact.mjs +55 -0
- package/hooks/pretooluse.mjs +23 -266
- package/hooks/routing-block.mjs +19 -6
- package/hooks/session-directive.mjs +353 -0
- package/hooks/session-helpers.mjs +112 -0
- package/hooks/sessionstart.mjs +123 -16
- package/hooks/userpromptsubmit.mjs +58 -0
- package/hooks/vscode-copilot/posttooluse.mjs +58 -0
- package/hooks/vscode-copilot/precompact.mjs +51 -0
- package/hooks/vscode-copilot/pretooluse.mjs +25 -0
- package/hooks/vscode-copilot/sessionstart.mjs +115 -0
- package/package.json +20 -17
- package/skills/context-mode/SKILL.md +49 -49
- package/skills/{doctor → ctx-doctor}/SKILL.md +3 -3
- package/skills/{stats → ctx-stats}/SKILL.md +3 -3
- package/skills/{upgrade → ctx-upgrade}/SKILL.md +3 -3
- package/start.mjs +47 -0
- package/hooks/pretooluse.sh +0 -147
- package/server.bundle.mjs +0 -341
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* truncate — Pure string and output truncation utilities for context-mode.
|
|
3
|
+
*
|
|
4
|
+
* These helpers are used by both the core ContentStore (chunking) and the
|
|
5
|
+
* PolyglotExecutor (smart output truncation). They are extracted here so
|
|
6
|
+
* SessionDB and any other future consumer can import them without pulling
|
|
7
|
+
* in the full store or executor.
|
|
8
|
+
*/
|
|
9
|
+
// ─────────────────────────────────────────────────────────
|
|
10
|
+
// String truncation
|
|
11
|
+
// ─────────────────────────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Truncate a string to at most `maxChars` characters, appending an ellipsis
|
|
14
|
+
* when truncation occurs.
|
|
15
|
+
*
|
|
16
|
+
* @param str - Input string.
|
|
17
|
+
* @param maxChars - Maximum character count (inclusive). Must be >= 3.
|
|
18
|
+
* @returns The original string if short enough, otherwise a truncated string
|
|
19
|
+
* ending with "...".
|
|
20
|
+
*/
|
|
21
|
+
export function truncateString(str, maxChars) {
|
|
22
|
+
if (str.length <= maxChars)
|
|
23
|
+
return str;
|
|
24
|
+
return str.slice(0, Math.max(0, maxChars - 3)) + "...";
|
|
25
|
+
}
|
|
26
|
+
// ─────────────────────────────────────────────────────────
|
|
27
|
+
// Byte-aware smart truncation (head + tail)
|
|
28
|
+
// ─────────────────────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Smart truncation that keeps the head (60%) and tail (40%) of output,
|
|
31
|
+
* preserving both initial context and final error messages.
|
|
32
|
+
* Snaps to line boundaries and handles UTF-8 safely via `Buffer.byteLength`.
|
|
33
|
+
*
|
|
34
|
+
* Used by PolyglotExecutor to cap stdout/stderr before returning to context.
|
|
35
|
+
*
|
|
36
|
+
* @param raw - Raw output string.
|
|
37
|
+
* @param maxBytes - Soft cap in bytes. Output below this threshold is returned as-is.
|
|
38
|
+
* @returns The original string if within budget, otherwise head + separator + tail.
|
|
39
|
+
*/
|
|
40
|
+
export function smartTruncate(raw, maxBytes) {
|
|
41
|
+
if (Buffer.byteLength(raw) <= maxBytes)
|
|
42
|
+
return raw;
|
|
43
|
+
const lines = raw.split("\n");
|
|
44
|
+
// Budget: 60% head, 40% tail (errors/results are usually at the end)
|
|
45
|
+
const headBudget = Math.floor(maxBytes * 0.6);
|
|
46
|
+
const tailBudget = maxBytes - headBudget;
|
|
47
|
+
// Collect head lines
|
|
48
|
+
const headLines = [];
|
|
49
|
+
let headBytes = 0;
|
|
50
|
+
for (const line of lines) {
|
|
51
|
+
const lineBytes = Buffer.byteLength(line) + 1; // +1 for \n
|
|
52
|
+
if (headBytes + lineBytes > headBudget)
|
|
53
|
+
break;
|
|
54
|
+
headLines.push(line);
|
|
55
|
+
headBytes += lineBytes;
|
|
56
|
+
}
|
|
57
|
+
// Collect tail lines (from end)
|
|
58
|
+
const tailLines = [];
|
|
59
|
+
let tailBytes = 0;
|
|
60
|
+
for (let i = lines.length - 1; i >= headLines.length; i--) {
|
|
61
|
+
const lineBytes = Buffer.byteLength(lines[i]) + 1;
|
|
62
|
+
if (tailBytes + lineBytes > tailBudget)
|
|
63
|
+
break;
|
|
64
|
+
tailLines.unshift(lines[i]);
|
|
65
|
+
tailBytes += lineBytes;
|
|
66
|
+
}
|
|
67
|
+
const skippedLines = lines.length - headLines.length - tailLines.length;
|
|
68
|
+
const skippedBytes = Buffer.byteLength(raw) - headBytes - tailBytes;
|
|
69
|
+
const separator = `\n\n... [${skippedLines} lines / ${(skippedBytes / 1024).toFixed(1)}KB truncated` +
|
|
70
|
+
` — showing first ${headLines.length} + last ${tailLines.length} lines] ...\n\n`;
|
|
71
|
+
return headLines.join("\n") + separator + tailLines.join("\n");
|
|
72
|
+
}
|
|
73
|
+
// ─────────────────────────────────────────────────────────
|
|
74
|
+
// JSON truncation
|
|
75
|
+
// ─────────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Serialize a value to JSON, then truncate the result to `maxBytes` bytes.
|
|
78
|
+
* If truncation occurs, the string is cut at a UTF-8-safe boundary and
|
|
79
|
+
* "... [truncated]" is appended. The result is NOT guaranteed to be valid
|
|
80
|
+
* JSON after truncation — it is suitable only for display/logging.
|
|
81
|
+
*
|
|
82
|
+
* @param value - Any JSON-serializable value.
|
|
83
|
+
* @param maxBytes - Maximum byte length of the returned string.
|
|
84
|
+
* @param indent - JSON indentation spaces (default 2). Pass 0 for compact.
|
|
85
|
+
*/
|
|
86
|
+
export function truncateJSON(value, maxBytes, indent = 2) {
|
|
87
|
+
const serialized = JSON.stringify(value, null, indent) ?? "null";
|
|
88
|
+
if (Buffer.byteLength(serialized) <= maxBytes)
|
|
89
|
+
return serialized;
|
|
90
|
+
// Find the largest character slice that stays within maxBytes once encoded.
|
|
91
|
+
// Buffer.byteLength is O(n) but we only call it once per truncation.
|
|
92
|
+
const marker = "... [truncated]";
|
|
93
|
+
const markerBytes = Buffer.byteLength(marker);
|
|
94
|
+
const budget = maxBytes - markerBytes;
|
|
95
|
+
// Binary-search for the right character count — avoids O(n²) scanning.
|
|
96
|
+
let lo = 0;
|
|
97
|
+
let hi = serialized.length;
|
|
98
|
+
while (lo < hi) {
|
|
99
|
+
const mid = (lo + hi + 1) >> 1;
|
|
100
|
+
if (Buffer.byteLength(serialized.slice(0, mid)) <= budget) {
|
|
101
|
+
lo = mid;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
hi = mid - 1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return serialized.slice(0, lo) + marker;
|
|
108
|
+
}
|
|
109
|
+
// ─────────────────────────────────────────────────────────
|
|
110
|
+
// XML / HTML escaping
|
|
111
|
+
// ─────────────────────────────────────────────────────────
|
|
112
|
+
/**
|
|
113
|
+
* Escape a string for safe embedding in an XML or HTML attribute or text node.
|
|
114
|
+
* Replaces the five XML-reserved characters: `&`, `<`, `>`, `"`, `'`.
|
|
115
|
+
*
|
|
116
|
+
* Used by the resume snapshot template builder to embed user content in
|
|
117
|
+
* `<tool_response>` and `<user_message>` XML tags without breaking the
|
|
118
|
+
* structured prompt format.
|
|
119
|
+
*/
|
|
120
|
+
export function escapeXML(str) {
|
|
121
|
+
return str
|
|
122
|
+
.replace(/&/g, "&")
|
|
123
|
+
.replace(/</g, "<")
|
|
124
|
+
.replace(/>/g, ">")
|
|
125
|
+
.replace(/"/g, """)
|
|
126
|
+
.replace(/'/g, "'");
|
|
127
|
+
}
|
|
128
|
+
// ─────────────────────────────────────────────────────────
|
|
129
|
+
// maxBytes guard
|
|
130
|
+
// ─────────────────────────────────────────────────────────
|
|
131
|
+
/**
|
|
132
|
+
* Return `str` unchanged if it fits within `maxBytes`, otherwise return a
|
|
133
|
+
* byte-safe slice with an ellipsis appended. Useful for single-value fields
|
|
134
|
+
* (e.g., tool response strings) where head+tail splitting is not needed.
|
|
135
|
+
*
|
|
136
|
+
* @param str - Input string.
|
|
137
|
+
* @param maxBytes - Hard byte cap.
|
|
138
|
+
*/
|
|
139
|
+
export function capBytes(str, maxBytes) {
|
|
140
|
+
if (Buffer.byteLength(str) <= maxBytes)
|
|
141
|
+
return str;
|
|
142
|
+
const marker = "...";
|
|
143
|
+
const markerBytes = Buffer.byteLength(marker);
|
|
144
|
+
const budget = maxBytes - markerBytes;
|
|
145
|
+
let lo = 0;
|
|
146
|
+
let hi = str.length;
|
|
147
|
+
while (lo < hi) {
|
|
148
|
+
const mid = (lo + hi + 1) >> 1;
|
|
149
|
+
if (Buffer.byteLength(str.slice(0, mid)) <= budget) {
|
|
150
|
+
lo = mid;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
hi = mid - 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return str.slice(0, lo) + marker;
|
|
157
|
+
}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* types — Shared type definitions for context-mode packages.
|
|
3
|
+
*
|
|
4
|
+
* Contains interfaces that are genuinely shared between the core (ContentStore,
|
|
5
|
+
* PolyglotExecutor) and the session domain (SessionDB, event extraction).
|
|
6
|
+
* Import from "./types.js".
|
|
7
|
+
*/
|
|
8
|
+
/** Tool call representation used during event extraction from Claude messages. */
|
|
9
|
+
export interface ToolCall {
|
|
10
|
+
toolName: string;
|
|
11
|
+
toolInput: Record<string, unknown>;
|
|
12
|
+
toolResponse?: string;
|
|
13
|
+
isError?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** User message representation used during event extraction. */
|
|
16
|
+
export interface UserMessage {
|
|
17
|
+
content: string;
|
|
18
|
+
timestamp?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Session event as stored in SessionDB.
|
|
22
|
+
* Each event captures a discrete unit of session activity (tool use, user
|
|
23
|
+
* message, assistant response summary, etc.) for later resume-snapshot
|
|
24
|
+
* reconstruction.
|
|
25
|
+
*/
|
|
26
|
+
export interface SessionEvent {
|
|
27
|
+
type: string;
|
|
28
|
+
category: string;
|
|
29
|
+
data: string;
|
|
30
|
+
priority: number;
|
|
31
|
+
data_hash: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Result returned by PolyglotExecutor after running a code snippet.
|
|
35
|
+
* Shared here so SessionDB can record execution outcomes without importing
|
|
36
|
+
* the full executor module.
|
|
37
|
+
*/
|
|
38
|
+
export interface ExecResult {
|
|
39
|
+
stdout: string;
|
|
40
|
+
stderr: string;
|
|
41
|
+
exitCode: number;
|
|
42
|
+
timedOut: boolean;
|
|
43
|
+
/** Process was detached and continues running in the background. */
|
|
44
|
+
backgrounded?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Result returned after indexing content into the knowledge base.
|
|
48
|
+
* Shared so session tooling can record what was indexed without importing
|
|
49
|
+
* ContentStore.
|
|
50
|
+
*/
|
|
51
|
+
export interface IndexResult {
|
|
52
|
+
sourceId: number;
|
|
53
|
+
label: string;
|
|
54
|
+
totalChunks: number;
|
|
55
|
+
codeChunks: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A single search result returned from FTS5 BM25-ranked lookup.
|
|
59
|
+
* Shared for consumers that display or log results outside of ContentStore.
|
|
60
|
+
*/
|
|
61
|
+
export interface SearchResult {
|
|
62
|
+
title: string;
|
|
63
|
+
content: string;
|
|
64
|
+
source: string;
|
|
65
|
+
rank: number;
|
|
66
|
+
contentType: "code" | "prose";
|
|
67
|
+
matchLayer?: "porter" | "trigram" | "fuzzy";
|
|
68
|
+
highlighted?: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Aggregate statistics for a ContentStore instance.
|
|
72
|
+
*/
|
|
73
|
+
export interface StoreStats {
|
|
74
|
+
sources: number;
|
|
75
|
+
chunks: number;
|
|
76
|
+
codeChunks: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Structured representation of a session resume snapshot, suitable for
|
|
80
|
+
* injecting into a new conversation as context. Generated from stored
|
|
81
|
+
* SessionEvents by the snapshot builder.
|
|
82
|
+
*/
|
|
83
|
+
export interface ResumeSnapshot {
|
|
84
|
+
/** ISO-8601 timestamp of when the snapshot was generated. */
|
|
85
|
+
generatedAt: string;
|
|
86
|
+
/** Human-readable summary of the session to this point. */
|
|
87
|
+
summary: string;
|
|
88
|
+
/** Ordered list of events selected for the snapshot (priority-filtered). */
|
|
89
|
+
events: SessionEvent[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Priority levels for SessionEvent records. Higher numbers are more important
|
|
93
|
+
* and are retained when the snapshot budget is tight.
|
|
94
|
+
*/
|
|
95
|
+
export declare const EventPriority: {
|
|
96
|
+
readonly LOW: 1;
|
|
97
|
+
readonly NORMAL: 2;
|
|
98
|
+
readonly HIGH: 3;
|
|
99
|
+
readonly CRITICAL: 4;
|
|
100
|
+
};
|
|
101
|
+
export type EventPriorityLevel = (typeof EventPriority)[keyof typeof EventPriority];
|
package/build/types.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* types — Shared type definitions for context-mode packages.
|
|
3
|
+
*
|
|
4
|
+
* Contains interfaces that are genuinely shared between the core (ContentStore,
|
|
5
|
+
* PolyglotExecutor) and the session domain (SessionDB, event extraction).
|
|
6
|
+
* Import from "./types.js".
|
|
7
|
+
*/
|
|
8
|
+
// ─────────────────────────────────────────────────────────
|
|
9
|
+
// Priority constants
|
|
10
|
+
// ─────────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Priority levels for SessionEvent records. Higher numbers are more important
|
|
13
|
+
* and are retained when the snapshot budget is tight.
|
|
14
|
+
*/
|
|
15
|
+
export const EventPriority = {
|
|
16
|
+
LOW: 1,
|
|
17
|
+
NORMAL: 2,
|
|
18
|
+
HIGH: 3,
|
|
19
|
+
CRITICAL: 4,
|
|
20
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
|
+
|
|
3
|
+
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session.
|
|
4
|
+
|
|
5
|
+
## BLOCKED commands — do NOT attempt these
|
|
6
|
+
|
|
7
|
+
### curl / wget — BLOCKED
|
|
8
|
+
Any Bash command containing `curl` or `wget` is intercepted and replaced with an error message. Do NOT retry.
|
|
9
|
+
Instead use:
|
|
10
|
+
- `ctx_fetch_and_index(url, source)` to fetch and index web pages
|
|
11
|
+
- `ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
|
12
|
+
|
|
13
|
+
### Inline HTTP — BLOCKED
|
|
14
|
+
Any Bash command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` is intercepted and replaced with an error message. Do NOT retry with Bash.
|
|
15
|
+
Instead use:
|
|
16
|
+
- `ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
|
17
|
+
|
|
18
|
+
### WebFetch — BLOCKED
|
|
19
|
+
WebFetch calls are denied entirely. The URL is extracted and you are told to use `ctx_fetch_and_index` instead.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content
|
|
22
|
+
|
|
23
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
24
|
+
|
|
25
|
+
### Bash (>20 lines output)
|
|
26
|
+
Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
27
|
+
For everything else, use:
|
|
28
|
+
- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
29
|
+
- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
30
|
+
|
|
31
|
+
### Read (for analysis)
|
|
32
|
+
If you are reading a file to **Edit** it → Read is correct (Edit needs content in context).
|
|
33
|
+
If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file content stays in the sandbox.
|
|
34
|
+
|
|
35
|
+
### Grep (large results)
|
|
36
|
+
Grep results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
|
37
|
+
|
|
38
|
+
## Tool selection hierarchy
|
|
39
|
+
|
|
40
|
+
1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
41
|
+
2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
42
|
+
3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
43
|
+
4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
44
|
+
5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
45
|
+
|
|
46
|
+
## Subagent routing
|
|
47
|
+
|
|
48
|
+
When spawning subagents (Agent/Task tool), the routing block is automatically injected into their prompt. Bash-type subagents are upgraded to general-purpose so they have access to MCP tools. You do NOT need to manually instruct subagents about context-mode.
|
|
49
|
+
|
|
50
|
+
## Output constraints
|
|
51
|
+
|
|
52
|
+
- Keep responses under 500 words.
|
|
53
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
54
|
+
- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later.
|
|
55
|
+
|
|
56
|
+
## ctx commands
|
|
57
|
+
|
|
58
|
+
| Command | Action |
|
|
59
|
+
|---------|--------|
|
|
60
|
+
| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim |
|
|
61
|
+
| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist |
|
|
62
|
+
| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
|
+
|
|
3
|
+
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session. Codex CLI does NOT have hooks, so these instructions are your ONLY enforcement mechanism. Follow them strictly.
|
|
4
|
+
|
|
5
|
+
## BLOCKED commands — do NOT use these
|
|
6
|
+
|
|
7
|
+
### curl / wget — FORBIDDEN
|
|
8
|
+
Do NOT use `curl` or `wget` in any shell command. They dump raw HTTP responses directly into your context window.
|
|
9
|
+
Instead use:
|
|
10
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` to fetch and index web pages
|
|
11
|
+
- `mcp__context-mode__ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
|
12
|
+
|
|
13
|
+
### Inline HTTP — FORBIDDEN
|
|
14
|
+
Do NOT run inline HTTP calls via `node -e "fetch(..."`, `python -c "requests.get(..."`, or similar patterns. They bypass the sandbox and flood context.
|
|
15
|
+
Instead use:
|
|
16
|
+
- `mcp__context-mode__ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
|
17
|
+
|
|
18
|
+
### Direct web fetching — FORBIDDEN
|
|
19
|
+
Do NOT use any direct URL fetching tool. Raw HTML can exceed 100 KB.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` to query the indexed content
|
|
22
|
+
|
|
23
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
24
|
+
|
|
25
|
+
### Shell (>20 lines output)
|
|
26
|
+
Shell is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
27
|
+
For everything else, use:
|
|
28
|
+
- `mcp__context-mode__ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
29
|
+
- `mcp__context-mode__ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
30
|
+
|
|
31
|
+
### File reading (for analysis)
|
|
32
|
+
If you are reading a file to **edit** it → reading is correct (edit needs content in context).
|
|
33
|
+
If you are reading to **analyze, explore, or summarize** → use `mcp__context-mode__ctx_execute_file(path, language, code)` instead. Only your printed summary enters context. The raw file stays in the sandbox.
|
|
34
|
+
|
|
35
|
+
### grep / search (large results)
|
|
36
|
+
Search results can flood context. Use `mcp__context-mode__ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
|
37
|
+
|
|
38
|
+
## Tool selection hierarchy
|
|
39
|
+
|
|
40
|
+
1. **GATHER**: `mcp__context-mode__ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
41
|
+
2. **FOLLOW-UP**: `mcp__context-mode__ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
42
|
+
3. **PROCESSING**: `mcp__context-mode__ctx_execute(language, code)` | `mcp__context-mode__ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
43
|
+
4. **WEB**: `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
44
|
+
5. **INDEX**: `mcp__context-mode__ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
45
|
+
|
|
46
|
+
## Output constraints
|
|
47
|
+
|
|
48
|
+
- Keep responses under 500 words.
|
|
49
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
50
|
+
- When indexing content, use descriptive source labels so others can `search(source: "label")` later.
|
|
51
|
+
|
|
52
|
+
## ctx commands
|
|
53
|
+
|
|
54
|
+
| Command | Action |
|
|
55
|
+
|---------|--------|
|
|
56
|
+
| `ctx stats` | Call the `stats` MCP tool and display the full output verbatim |
|
|
57
|
+
| `ctx doctor` | Call the `doctor` MCP tool, run the returned shell command, display as checklist |
|
|
58
|
+
| `ctx upgrade` | Call the `upgrade` MCP tool, run the returned shell command, display as checklist |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
|
+
|
|
3
|
+
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session.
|
|
4
|
+
|
|
5
|
+
## BLOCKED commands — do NOT attempt these
|
|
6
|
+
|
|
7
|
+
### curl / wget — BLOCKED
|
|
8
|
+
Any shell command containing `curl` or `wget` will be intercepted and blocked. Do NOT retry.
|
|
9
|
+
Instead use:
|
|
10
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` to fetch and index web pages
|
|
11
|
+
- `mcp__context-mode__ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
|
12
|
+
|
|
13
|
+
### Inline HTTP — BLOCKED
|
|
14
|
+
Any shell command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` will be intercepted and blocked. Do NOT retry with shell.
|
|
15
|
+
Instead use:
|
|
16
|
+
- `mcp__context-mode__ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
|
17
|
+
|
|
18
|
+
### WebFetch / web browsing — BLOCKED
|
|
19
|
+
Direct web fetching is blocked. Use the sandbox equivalent.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` to query the indexed content
|
|
22
|
+
|
|
23
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
24
|
+
|
|
25
|
+
### Shell (>20 lines output)
|
|
26
|
+
Shell is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
27
|
+
For everything else, use:
|
|
28
|
+
- `mcp__context-mode__ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
29
|
+
- `mcp__context-mode__ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
30
|
+
|
|
31
|
+
### read_file (for analysis)
|
|
32
|
+
If you are reading a file to **edit** it → read_file is correct (edit needs content in context).
|
|
33
|
+
If you are reading to **analyze, explore, or summarize** → use `mcp__context-mode__ctx_execute_file(path, language, code)` instead. Only your printed summary enters context.
|
|
34
|
+
|
|
35
|
+
### grep / search (large results)
|
|
36
|
+
Search results can flood context. Use `mcp__context-mode__ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
|
37
|
+
|
|
38
|
+
## Tool selection hierarchy
|
|
39
|
+
|
|
40
|
+
1. **GATHER**: `mcp__context-mode__ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
41
|
+
2. **FOLLOW-UP**: `mcp__context-mode__ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
42
|
+
3. **PROCESSING**: `mcp__context-mode__ctx_execute(language, code)` | `mcp__context-mode__ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
43
|
+
4. **WEB**: `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
44
|
+
5. **INDEX**: `mcp__context-mode__ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
45
|
+
|
|
46
|
+
## Output constraints
|
|
47
|
+
|
|
48
|
+
- Keep responses under 500 words.
|
|
49
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
50
|
+
- When indexing content, use descriptive source labels so others can `search(source: "label")` later.
|
|
51
|
+
|
|
52
|
+
## ctx commands
|
|
53
|
+
|
|
54
|
+
| Command | Action |
|
|
55
|
+
|---------|--------|
|
|
56
|
+
| `ctx stats` | Call the `stats` MCP tool and display the full output verbatim |
|
|
57
|
+
| `ctx doctor` | Call the `doctor` MCP tool, run the returned shell command, display as checklist |
|
|
58
|
+
| `ctx upgrade` | Call the `upgrade` MCP tool, run the returned shell command, display as checklist |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/google-gemini/gemini-cli/main/packages/core/src/schema/settings-schema.json",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"BeforeTool": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "context-mode hook gemini-cli beforetool"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"AfterTool": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "context-mode hook gemini-cli aftertool"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"PreCompress": [
|
|
27
|
+
{
|
|
28
|
+
"matcher": "",
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "context-mode hook gemini-cli precompress"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"SessionStart": [
|
|
38
|
+
{
|
|
39
|
+
"matcher": "",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "context-mode hook gemini-cli sessionstart"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
|
+
|
|
3
|
+
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session.
|
|
4
|
+
|
|
5
|
+
## BLOCKED commands — do NOT attempt these
|
|
6
|
+
|
|
7
|
+
### curl / wget — BLOCKED
|
|
8
|
+
Any shell command containing `curl` or `wget` will be intercepted and blocked by the context-mode plugin. Do NOT retry.
|
|
9
|
+
Instead use:
|
|
10
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` to fetch and index web pages
|
|
11
|
+
- `mcp__context-mode__ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
|
12
|
+
|
|
13
|
+
### Inline HTTP — BLOCKED
|
|
14
|
+
Any shell command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` will be intercepted and blocked. Do NOT retry with shell.
|
|
15
|
+
Instead use:
|
|
16
|
+
- `mcp__context-mode__ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
|
17
|
+
|
|
18
|
+
### Direct web fetching — BLOCKED
|
|
19
|
+
Do NOT use any direct URL fetching tool. Use the sandbox equivalent.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` to query the indexed content
|
|
22
|
+
|
|
23
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
24
|
+
|
|
25
|
+
### Shell (>20 lines output)
|
|
26
|
+
Shell is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
27
|
+
For everything else, use:
|
|
28
|
+
- `mcp__context-mode__ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
29
|
+
- `mcp__context-mode__ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
30
|
+
|
|
31
|
+
### File reading (for analysis)
|
|
32
|
+
If you are reading a file to **edit** it → reading is correct (edit needs content in context).
|
|
33
|
+
If you are reading to **analyze, explore, or summarize** → use `mcp__context-mode__ctx_execute_file(path, language, code)` instead. Only your printed summary enters context.
|
|
34
|
+
|
|
35
|
+
### grep / search (large results)
|
|
36
|
+
Search results can flood context. Use `mcp__context-mode__ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
|
37
|
+
|
|
38
|
+
## Tool selection hierarchy
|
|
39
|
+
|
|
40
|
+
1. **GATHER**: `mcp__context-mode__ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
41
|
+
2. **FOLLOW-UP**: `mcp__context-mode__ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
42
|
+
3. **PROCESSING**: `mcp__context-mode__ctx_execute(language, code)` | `mcp__context-mode__ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
43
|
+
4. **WEB**: `mcp__context-mode__ctx_fetch_and_index(url, source)` then `mcp__context-mode__ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
44
|
+
5. **INDEX**: `mcp__context-mode__ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
45
|
+
|
|
46
|
+
## Output constraints
|
|
47
|
+
|
|
48
|
+
- Keep responses under 500 words.
|
|
49
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
50
|
+
- When indexing content, use descriptive source labels so others can `search(source: "label")` later.
|
|
51
|
+
|
|
52
|
+
## ctx commands
|
|
53
|
+
|
|
54
|
+
| Command | Action |
|
|
55
|
+
|---------|--------|
|
|
56
|
+
| `ctx stats` | Call the `stats` MCP tool and display the full output verbatim |
|
|
57
|
+
| `ctx doctor` | Call the `doctor` MCP tool, run the returned shell command, display as checklist |
|
|
58
|
+
| `ctx upgrade` | Call the `upgrade` MCP tool, run the returned shell command, display as checklist |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
|
+
|
|
3
|
+
You have context-mode MCP tools available. These rules are NOT optional — they protect your context window from flooding. A single unrouted command can dump 56 KB into context and waste the entire session.
|
|
4
|
+
|
|
5
|
+
## BLOCKED commands — do NOT attempt these
|
|
6
|
+
|
|
7
|
+
### curl / wget — BLOCKED
|
|
8
|
+
Any terminal command containing `curl` or `wget` will be intercepted and blocked. Do NOT retry.
|
|
9
|
+
Instead use:
|
|
10
|
+
- `ctx_fetch_and_index(url, source)` to fetch and index web pages
|
|
11
|
+
- `ctx_execute(language: "javascript", code: "const r = await fetch(...)")` to run HTTP calls in sandbox
|
|
12
|
+
|
|
13
|
+
### Inline HTTP — BLOCKED
|
|
14
|
+
Any terminal command containing `fetch('http`, `requests.get(`, `requests.post(`, `http.get(`, or `http.request(` will be intercepted and blocked. Do NOT retry with terminal.
|
|
15
|
+
Instead use:
|
|
16
|
+
- `ctx_execute(language, code)` to run HTTP calls in sandbox — only stdout enters context
|
|
17
|
+
|
|
18
|
+
### WebFetch / fetch — BLOCKED
|
|
19
|
+
Direct web fetching tools are blocked. Use the sandbox equivalent.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content
|
|
22
|
+
|
|
23
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
24
|
+
|
|
25
|
+
### Terminal / run_in_terminal (>20 lines output)
|
|
26
|
+
Terminal is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
27
|
+
For everything else, use:
|
|
28
|
+
- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
29
|
+
- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
30
|
+
|
|
31
|
+
### read_file (for analysis)
|
|
32
|
+
If you are reading a file to **edit** it → read_file is correct (edit needs content in context).
|
|
33
|
+
If you are reading to **analyze, explore, or summarize** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context.
|
|
34
|
+
|
|
35
|
+
### grep / search (large results)
|
|
36
|
+
Search results can flood context. Use `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox. Only your printed summary enters context.
|
|
37
|
+
|
|
38
|
+
## Tool selection hierarchy
|
|
39
|
+
|
|
40
|
+
1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
41
|
+
2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
42
|
+
3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
43
|
+
4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
44
|
+
5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
45
|
+
|
|
46
|
+
## Output constraints
|
|
47
|
+
|
|
48
|
+
- Keep responses under 500 words.
|
|
49
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
50
|
+
- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later.
|
|
51
|
+
|
|
52
|
+
## ctx commands
|
|
53
|
+
|
|
54
|
+
| Command | Action |
|
|
55
|
+
|---------|--------|
|
|
56
|
+
| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim |
|
|
57
|
+
| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist |
|
|
58
|
+
| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist |
|