supipowers 0.7.1 → 0.7.3
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/bin/install.mjs +49 -0
- package/package.json +1 -1
- package/skills/context-mode/SKILL.md +64 -25
- package/src/context-mode/detector.ts +20 -8
- package/src/context-mode/hooks.ts +2 -1
package/bin/install.mjs
CHANGED
|
@@ -196,6 +196,55 @@ async function main() {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
// ── Step 2b: Register context-mode MCP server (if installed) ──
|
|
200
|
+
|
|
201
|
+
const ctxSpinner = spinner();
|
|
202
|
+
ctxSpinner.start("Checking for context-mode...");
|
|
203
|
+
|
|
204
|
+
// Find context-mode installation (Claude Code plugin cache)
|
|
205
|
+
const ctxCacheBase = join(homedir(), ".claude", "plugins", "cache", "context-mode", "context-mode");
|
|
206
|
+
let ctxInstallPath = null;
|
|
207
|
+
if (existsSync(ctxCacheBase)) {
|
|
208
|
+
// Find the latest version directory
|
|
209
|
+
const versions = readdirSync(ctxCacheBase, { withFileTypes: true })
|
|
210
|
+
.filter((d) => d.isDirectory())
|
|
211
|
+
.map((d) => d.name)
|
|
212
|
+
.sort()
|
|
213
|
+
.reverse();
|
|
214
|
+
if (versions.length > 0) {
|
|
215
|
+
const candidate = join(ctxCacheBase, versions[0], "start.mjs");
|
|
216
|
+
if (existsSync(candidate)) {
|
|
217
|
+
ctxInstallPath = join(ctxCacheBase, versions[0]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (ctxInstallPath) {
|
|
223
|
+
// Register as MCP server in ~/.omp/agent/mcp.json
|
|
224
|
+
const mcpConfigPath = join(homedir(), ".omp", "agent", "mcp.json");
|
|
225
|
+
let mcpConfig = { mcpServers: {} };
|
|
226
|
+
if (existsSync(mcpConfigPath)) {
|
|
227
|
+
try {
|
|
228
|
+
mcpConfig = JSON.parse(readFileSync(mcpConfigPath, "utf8"));
|
|
229
|
+
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
230
|
+
} catch {
|
|
231
|
+
mcpConfig = { mcpServers: {} };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const startMjs = join(ctxInstallPath, "start.mjs");
|
|
236
|
+
mcpConfig.mcpServers["context-mode"] = {
|
|
237
|
+
command: "node",
|
|
238
|
+
args: [startMjs],
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const { writeFileSync: writeFs } = await import("node:fs");
|
|
242
|
+
writeFs(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
243
|
+
ctxSpinner.stop(`context-mode registered as MCP server (${ctxInstallPath})`);
|
|
244
|
+
} else {
|
|
245
|
+
ctxSpinner.stop("context-mode not found (install it as a Claude Code plugin for context window protection)");
|
|
246
|
+
}
|
|
247
|
+
|
|
199
248
|
// ── Step 3: LSP setup (optional, skipped with --skip-lsp) ──
|
|
200
249
|
|
|
201
250
|
if (skipLsp) {
|
package/package.json
CHANGED
|
@@ -1,38 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# context-mode — MANDATORY routing rules
|
|
2
2
|
|
|
3
|
-
|
|
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
4
|
|
|
5
|
-
##
|
|
5
|
+
## BLOCKED commands — do NOT attempt these
|
|
6
6
|
|
|
7
|
-
|
|
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
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
### WebFetch / Fetch — BLOCKED
|
|
19
|
+
WebFetch and Fetch calls are denied entirely.
|
|
20
|
+
Instead use:
|
|
21
|
+
- `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` to query the indexed content
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
### Grep — BLOCKED
|
|
24
|
+
Grep calls are intercepted and blocked. Do NOT retry with Grep.
|
|
25
|
+
Instead use:
|
|
26
|
+
- `ctx_search(queries: ["<pattern>"])` to search indexed content
|
|
27
|
+
- `ctx_batch_execute(commands, queries)` to run searches and return compressed results
|
|
28
|
+
- `ctx_execute(language: "shell", code: "grep ...")` to run searches in sandbox
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
### Find / Glob — BLOCKED
|
|
31
|
+
Find/Glob calls are intercepted and blocked. Do NOT retry with Find/Glob.
|
|
32
|
+
Instead use:
|
|
33
|
+
- `ctx_execute(language: "shell", code: "find ...")` to run in sandbox
|
|
34
|
+
- `ctx_batch_execute(commands, queries)` for multiple searches
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
### Read (full-file, no limit) — BLOCKED
|
|
37
|
+
Reading an entire file without a `limit` parameter is blocked.
|
|
38
|
+
- If you need to **Edit** the file → re-call Read with `limit` parameter (e.g., `limit: 200`)
|
|
39
|
+
- If you need to **analyze or explore** → use `ctx_execute_file(path, language, code)` instead. Only your printed summary enters context.
|
|
25
40
|
|
|
26
|
-
|
|
27
|
-
- Do NOT use Read for analyzing large files (>100 lines) — use `ctx_execute_file` to process and summarize
|
|
28
|
-
- Do NOT use Bash for directory listings with >20 expected files — use `ctx_execute`
|
|
41
|
+
## REDIRECTED tools — use sandbox equivalents
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
### Bash (>20 lines output)
|
|
44
|
+
Bash is ONLY for: `git`, `mkdir`, `rm`, `mv`, `cd`, `ls`, `npm install`, `pip install`, and other short-output commands.
|
|
45
|
+
For everything else, use:
|
|
46
|
+
- `ctx_batch_execute(commands, queries)` — run multiple commands + search in ONE call
|
|
47
|
+
- `ctx_execute(language: "shell", code: "...")` — run in sandbox, only stdout enters context
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
### Read (for analysis)
|
|
50
|
+
If you are reading a file to **Edit** it → Read with `limit` is correct (Edit needs content in context).
|
|
51
|
+
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.
|
|
35
52
|
|
|
36
|
-
##
|
|
53
|
+
## Tool selection hierarchy
|
|
37
54
|
|
|
38
|
-
|
|
55
|
+
1. **GATHER**: `ctx_batch_execute(commands, queries)` — Primary tool. Runs all commands, auto-indexes output, returns search results. ONE call replaces 30+ individual calls.
|
|
56
|
+
2. **FOLLOW-UP**: `ctx_search(queries: ["q1", "q2", ...])` — Query indexed content. Pass ALL questions as array in ONE call.
|
|
57
|
+
3. **PROCESSING**: `ctx_execute(language, code)` | `ctx_execute_file(path, language, code)` — Sandbox execution. Only stdout enters context.
|
|
58
|
+
4. **WEB**: `ctx_fetch_and_index(url, source)` then `ctx_search(queries)` — Fetch, chunk, index, query. Raw HTML never enters context.
|
|
59
|
+
5. **INDEX**: `ctx_index(content, source)` — Store content in FTS5 knowledge base for later search.
|
|
60
|
+
|
|
61
|
+
## Subagent routing
|
|
62
|
+
|
|
63
|
+
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.
|
|
64
|
+
|
|
65
|
+
## Output constraints
|
|
66
|
+
|
|
67
|
+
- Keep responses under 500 words.
|
|
68
|
+
- Write artifacts (code, configs, PRDs) to FILES — never return them as inline text. Return only: file path + 1-line description.
|
|
69
|
+
- When indexing content, use descriptive source labels so others can `ctx_search(source: "label")` later.
|
|
70
|
+
|
|
71
|
+
## ctx commands
|
|
72
|
+
|
|
73
|
+
| Command | Action |
|
|
74
|
+
|---------|--------|
|
|
75
|
+
| `ctx stats` | Call the `ctx_stats` MCP tool and display the full output verbatim |
|
|
76
|
+
| `ctx doctor` | Call the `ctx_doctor` MCP tool, run the returned shell command, display as checklist |
|
|
77
|
+
| `ctx upgrade` | Call the `ctx_upgrade` MCP tool, run the returned shell command, display as checklist |
|
|
@@ -24,13 +24,26 @@ const TOOL_SUFFIXES: Array<[string, keyof ContextModeStatus["tools"]]> = [
|
|
|
24
24
|
];
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Check if a tool name matches a context-mode tool suffix.
|
|
28
|
+
* Handles multiple naming conventions:
|
|
29
|
+
* - Bare names: "ctx_execute"
|
|
30
|
+
* - Claude Code MCP: "mcp__plugin_context-mode_context-mode__ctx_execute"
|
|
31
|
+
* - OMP MCP: "mcp_context_mode_ctx_execute"
|
|
32
|
+
*
|
|
33
|
+
* We match by checking if the tool contains a known context-mode server
|
|
34
|
+
* prefix followed by the suffix, or is the bare suffix itself.
|
|
30
35
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
const CONTEXT_MODE_PREFIXES = [
|
|
37
|
+
"mcp__plugin_context-mode_context-mode__", // Claude Code
|
|
38
|
+
"mcp_context_mode_", // OMP
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
function matchesSuffix(tool: string, suffix: string): boolean {
|
|
42
|
+
if (tool === suffix) return true;
|
|
43
|
+
for (const prefix of CONTEXT_MODE_PREFIXES) {
|
|
44
|
+
if (tool === prefix + suffix) return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
34
47
|
}
|
|
35
48
|
|
|
36
49
|
/** Detect context-mode MCP tool availability from the active tools list */
|
|
@@ -45,9 +58,8 @@ export function detectContextMode(activeTools: string[]): ContextModeStatus {
|
|
|
45
58
|
};
|
|
46
59
|
|
|
47
60
|
for (const tool of activeTools) {
|
|
48
|
-
const shortName = getShortName(tool);
|
|
49
61
|
for (const [suffix, key] of TOOL_SUFFIXES) {
|
|
50
|
-
if (
|
|
62
|
+
if (matchesSuffix(tool, suffix)) {
|
|
51
63
|
tools[key] = true;
|
|
52
64
|
break;
|
|
53
65
|
}
|
|
@@ -94,7 +94,8 @@ export function registerContextModeHooks(pi: ExtensionAPI, config: SupipowersCon
|
|
|
94
94
|
|
|
95
95
|
// Phase 1: routing instructions
|
|
96
96
|
if (!config.contextMode.routingInstructions) return;
|
|
97
|
-
|
|
97
|
+
// Always re-detect: MCP tools may load after extension init
|
|
98
|
+
cachedStatus = detectContextMode(pi.getActiveTools());
|
|
98
99
|
if (!cachedStatus.available) return;
|
|
99
100
|
|
|
100
101
|
const skill = loadRoutingSkill();
|