context-mode 1.0.101 → 1.0.104
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/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +66 -5
- package/bin/statusline.mjs +321 -0
- package/build/adapters/antigravity/index.d.ts +6 -0
- package/build/adapters/antigravity/index.js +10 -0
- package/build/adapters/base.d.ts +23 -0
- package/build/adapters/base.js +29 -0
- package/build/adapters/codex/index.d.ts +10 -0
- package/build/adapters/codex/index.js +22 -4
- package/build/adapters/cursor/index.d.ts +7 -0
- package/build/adapters/cursor/index.js +11 -0
- package/build/adapters/detect.d.ts +12 -1
- package/build/adapters/detect.js +69 -7
- package/build/adapters/gemini-cli/index.d.ts +8 -1
- package/build/adapters/gemini-cli/index.js +19 -7
- package/build/adapters/jetbrains-copilot/index.d.ts +7 -0
- package/build/adapters/jetbrains-copilot/index.js +12 -0
- package/build/adapters/kiro/index.d.ts +8 -0
- package/build/adapters/kiro/index.js +12 -0
- package/build/adapters/openclaw/index.d.ts +17 -0
- package/build/adapters/openclaw/index.js +29 -4
- package/build/adapters/opencode/index.d.ts +8 -0
- package/build/adapters/opencode/index.js +18 -6
- package/build/adapters/qwen-code/index.d.ts +1 -0
- package/build/adapters/qwen-code/index.js +3 -0
- package/build/adapters/types.d.ts +33 -0
- package/build/adapters/vscode-copilot/index.d.ts +6 -0
- package/build/adapters/vscode-copilot/index.js +10 -0
- package/build/adapters/zed/index.d.ts +1 -0
- package/build/adapters/zed/index.js +3 -0
- package/build/cli.d.ts +15 -0
- package/build/cli.js +62 -16
- package/build/concurrency/runPool.d.ts +36 -0
- package/build/concurrency/runPool.js +51 -0
- package/build/executor.d.ts +11 -1
- package/build/executor.js +59 -16
- package/build/fetch-cache.d.ts +13 -0
- package/build/fetch-cache.js +15 -0
- package/build/lifecycle.d.ts +6 -2
- package/build/lifecycle.js +29 -2
- package/build/opencode-plugin.d.ts +6 -0
- package/build/opencode-plugin.js +60 -1
- package/build/routing-block.d.ts +8 -0
- package/build/routing-block.js +86 -0
- package/build/runtime.d.ts +1 -0
- package/build/runtime.js +54 -3
- package/build/search/auto-memory.d.ts +23 -10
- package/build/search/auto-memory.js +64 -26
- package/build/search/unified.d.ts +3 -0
- package/build/search/unified.js +2 -2
- package/build/server.d.ts +42 -0
- package/build/server.js +693 -164
- package/build/session/analytics.d.ts +49 -1
- package/build/session/analytics.js +278 -16
- package/build/session/db.d.ts +39 -8
- package/build/session/db.js +170 -19
- package/build/session/extract.js +124 -2
- package/build/tool-naming.d.ts +4 -0
- package/build/tool-naming.js +24 -0
- package/cli.bundle.mjs +201 -159
- package/configs/antigravity/GEMINI.md +11 -0
- package/configs/claude-code/CLAUDE.md +11 -0
- package/configs/codex/AGENTS.md +11 -0
- package/configs/cursor/context-mode.mdc +11 -0
- package/configs/gemini-cli/GEMINI.md +11 -0
- package/configs/jetbrains-copilot/copilot-instructions.md +3 -0
- package/configs/kilo/AGENTS.md +11 -0
- package/configs/kiro/KIRO.md +11 -0
- package/configs/openclaw/AGENTS.md +11 -0
- package/configs/opencode/AGENTS.md +11 -0
- package/configs/pi/AGENTS.md +11 -0
- package/configs/qwen-code/QWEN.md +11 -0
- package/configs/vscode-copilot/copilot-instructions.md +3 -0
- package/configs/zed/AGENTS.md +11 -0
- package/hooks/auto-injection.mjs +36 -10
- package/hooks/cache-heal-utils.mjs +231 -0
- package/hooks/codex/sessionstart.mjs +7 -4
- package/hooks/core/routing.mjs +5 -0
- package/hooks/cursor/sessionstart.mjs +7 -4
- package/hooks/formatters/claude-code.mjs +20 -0
- package/hooks/gemini-cli/sessionstart.mjs +7 -2
- package/hooks/jetbrains-copilot/sessionstart.mjs +7 -2
- package/hooks/normalize-hooks.mjs +184 -0
- package/hooks/session-db.bundle.mjs +33 -14
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-helpers.mjs +68 -20
- package/hooks/session-loaders.mjs +8 -2
- package/hooks/sessionstart.mjs +8 -2
- package/hooks/vscode-copilot/sessionstart.mjs +7 -2
- package/insight/src/routes/index.tsx +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/server.bundle.mjs +164 -125
- package/skills/ctx-insight/SKILL.md +1 -1
- package/start.mjs +63 -3
package/build/runtime.d.ts
CHANGED
package/build/runtime.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { execFileSync, execSync } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
/**
|
|
4
|
+
* Allowlist for SHELL env override. Only POSIX shells + Windows shells permit
|
|
5
|
+
* arbitrary command interpretation; anything else (e.g., /usr/bin/python set
|
|
6
|
+
* as SHELL) would let an attacker redirect the executor to a non-shell binary.
|
|
7
|
+
*
|
|
8
|
+
* basename split handles BOTH `/` and `\` separators so a Windows-style path
|
|
9
|
+
* (`C:\Program Files\PowerShell\7\pwsh.exe`) classifies correctly even when
|
|
10
|
+
* the runtime is on POSIX (where node:path.basename only splits on `/`).
|
|
11
|
+
*
|
|
12
|
+
* Match is case-insensitive; `.exe` extension tolerated for Windows binaries.
|
|
13
|
+
*/
|
|
14
|
+
const ALLOWED_SHELL_BASENAMES = /^(bash|sh|zsh|dash|pwsh|powershell|cmd)(\.exe)?$/i;
|
|
15
|
+
export function isAllowlistedShell(shellPath) {
|
|
16
|
+
// Cross-OS basename: split on either separator, take the last segment.
|
|
17
|
+
const segments = shellPath.split(/[\\/]/);
|
|
18
|
+
const base = segments[segments.length - 1];
|
|
19
|
+
return ALLOWED_SHELL_BASENAMES.test(base);
|
|
20
|
+
}
|
|
3
21
|
const isWindows = process.platform === "win32";
|
|
4
22
|
function commandExists(cmd) {
|
|
5
23
|
try {
|
|
@@ -93,6 +111,19 @@ function getVersion(cmd, args = ["--version"]) {
|
|
|
93
111
|
export function detectRuntimes() {
|
|
94
112
|
const hasBun = bunExists();
|
|
95
113
|
const bun = hasBun ? bunCommand() : null;
|
|
114
|
+
// Honor SHELL env var when it points at a real binary AND the basename is
|
|
115
|
+
// an allowlisted shell. Lets users with non-standard setups (WSL, custom
|
|
116
|
+
// bash, msys2) pin context-mode to their preferred shell.
|
|
117
|
+
//
|
|
118
|
+
// Allowlist (PR #401 ops review): basename must match
|
|
119
|
+
// /^(bash|sh|zsh|dash|pwsh|cmd)(\.exe)?$/. Without this guard, an attacker
|
|
120
|
+
// who controls SHELL (e.g., supply-chain compromise of a profile script)
|
|
121
|
+
// could redirect the executor to /usr/bin/python or any arbitrary binary.
|
|
122
|
+
const userShell = process.env.SHELL;
|
|
123
|
+
const shellOverride = userShell && existsSync(userShell) && isAllowlistedShell(userShell)
|
|
124
|
+
? userShell
|
|
125
|
+
: null;
|
|
126
|
+
const isWin = process.platform === "win32";
|
|
96
127
|
return {
|
|
97
128
|
javascript: bun ?? process.execPath,
|
|
98
129
|
typescript: bun
|
|
@@ -107,9 +138,9 @@ export function detectRuntimes() {
|
|
|
107
138
|
: commandExists("python")
|
|
108
139
|
? "python"
|
|
109
140
|
: null,
|
|
110
|
-
shell:
|
|
141
|
+
shell: shellOverride ?? (isWin
|
|
111
142
|
? (resolveWindowsBash() ?? (commandExists("sh") ? "sh" : commandExists("powershell") ? "powershell" : "cmd.exe"))
|
|
112
|
-
: commandExists("bash") ? "bash" : "sh",
|
|
143
|
+
: commandExists("bash") ? "bash" : "sh"),
|
|
113
144
|
ruby: commandExists("ruby") ? "ruby" : null,
|
|
114
145
|
go: commandExists("go") ? "go" : null,
|
|
115
146
|
rust: commandExists("rustc") ? "rustc" : null,
|
|
@@ -206,8 +237,28 @@ export function buildCommand(runtimes, language, filePath) {
|
|
|
206
237
|
throw new Error("No Python runtime available. Install python3 or python.");
|
|
207
238
|
}
|
|
208
239
|
return [runtimes.python, filePath];
|
|
209
|
-
case "shell":
|
|
240
|
+
case "shell": {
|
|
241
|
+
// Re-evaluate platform per call so detection-time and command-build-time
|
|
242
|
+
// can be tested independently (and to allow tests to stub process.platform).
|
|
243
|
+
const winNow = process.platform === "win32";
|
|
244
|
+
if (winNow) {
|
|
245
|
+
const shellName = runtimes.shell.toLowerCase();
|
|
246
|
+
if (shellName.includes("bash") || shellName.endsWith("/sh") || shellName.endsWith("\\sh.exe")) {
|
|
247
|
+
// bash -c "source 'path'" — avoids MSYS2 path mangling on non-C:
|
|
248
|
+
// drives. When bash.exe receives a script as a direct argument,
|
|
249
|
+
// MSYS rewrites D:\tmp\script → D:\c\tmp\script and execution
|
|
250
|
+
// breaks. The -c flag prevents MSYS from touching the file arg.
|
|
251
|
+
// Single-quote escape: ' → '\''
|
|
252
|
+
const escaped = filePath.replace(/'/g, "'\\''");
|
|
253
|
+
return [runtimes.shell, "-c", `source '${escaped}'`];
|
|
254
|
+
}
|
|
255
|
+
if (shellName.includes("powershell") || shellName.includes("pwsh")) {
|
|
256
|
+
return [runtimes.shell, "-File", filePath];
|
|
257
|
+
}
|
|
258
|
+
// cmd.exe and others: direct file (cmd reads .cmd association safely).
|
|
259
|
+
}
|
|
210
260
|
return [runtimes.shell, filePath];
|
|
261
|
+
}
|
|
211
262
|
case "ruby":
|
|
212
263
|
if (!runtimes.ruby) {
|
|
213
264
|
throw new Error("Ruby not available. Install ruby.");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auto-memory search — searches CLAUDE.md
|
|
3
|
-
*
|
|
2
|
+
* Auto-memory search — searches CLAUDE.md / AGENTS.md / GEMINI.md / etc.
|
|
3
|
+
* and the platform's persistent memory directory for decisions,
|
|
4
|
+
* preferences, and context from prior sessions.
|
|
4
5
|
*
|
|
5
6
|
* Returns results in a format compatible with the unified search pipeline.
|
|
6
7
|
*/
|
|
@@ -12,18 +13,30 @@ export interface AutoMemoryResult {
|
|
|
12
13
|
timestamp?: string;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* Minimal adapter contract used by searchAutoMemory.
|
|
17
|
+
* Avoids depending on the full HookAdapter type to keep this module standalone.
|
|
18
|
+
*/
|
|
19
|
+
export interface AutoMemoryAdapter {
|
|
20
|
+
getConfigDir(): string;
|
|
21
|
+
getInstructionFiles(): string[];
|
|
22
|
+
getMemoryDir(): string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Search auto-memory files for content matching any of the given queries.
|
|
26
|
+
*
|
|
27
|
+
* When `adapter` is provided, the per-platform conventions are used:
|
|
28
|
+
* 1. Project-level: <projectDir>/<each instructionFile>
|
|
29
|
+
* 2. User-level: <configDir>/<each instructionFile>
|
|
30
|
+
* 3. Memory dir: <memoryDir>/*.md
|
|
17
31
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* 2. User-level: <configDir>/CLAUDE.md
|
|
21
|
-
* 3. User memory: <configDir>/memory/*.md
|
|
32
|
+
* Without an adapter (legacy callers), defaults to Claude conventions
|
|
33
|
+
* (CLAUDE.md + ~/.claude/memory) for backwards compatibility.
|
|
22
34
|
*
|
|
23
35
|
* @param queries Array of search terms
|
|
24
36
|
* @param limit Max results to return
|
|
25
37
|
* @param projectDir Project directory path
|
|
26
|
-
* @param configDir
|
|
38
|
+
* @param configDir Explicit config dir override (legacy callers)
|
|
39
|
+
* @param adapter Platform adapter — supplies instruction files + memory dir
|
|
27
40
|
* @returns Matching auto-memory results
|
|
28
41
|
*/
|
|
29
|
-
export declare function searchAutoMemory(queries: string[], limit?: number, projectDir?: string, configDir?: string): AutoMemoryResult[];
|
|
42
|
+
export declare function searchAutoMemory(queries: string[], limit?: number, projectDir?: string, configDir?: string, adapter?: AutoMemoryAdapter): AutoMemoryResult[];
|
|
@@ -1,48 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auto-memory search — searches CLAUDE.md
|
|
3
|
-
*
|
|
2
|
+
* Auto-memory search — searches CLAUDE.md / AGENTS.md / GEMINI.md / etc.
|
|
3
|
+
* and the platform's persistent memory directory for decisions,
|
|
4
|
+
* preferences, and context from prior sessions.
|
|
4
5
|
*
|
|
5
6
|
* Returns results in a format compatible with the unified search pipeline.
|
|
6
7
|
*/
|
|
7
8
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
+
import { join, isAbsolute } from "node:path";
|
|
9
10
|
import { homedir } from "node:os";
|
|
10
11
|
const DEBUG = process.env.DEBUG?.includes("context-mode");
|
|
11
12
|
/**
|
|
12
|
-
* Search auto-memory files
|
|
13
|
-
* for content matching any of the given queries.
|
|
13
|
+
* Search auto-memory files for content matching any of the given queries.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* 1. Project-level: <projectDir
|
|
17
|
-
* 2. User-level: <configDir
|
|
18
|
-
* 3.
|
|
15
|
+
* When `adapter` is provided, the per-platform conventions are used:
|
|
16
|
+
* 1. Project-level: <projectDir>/<each instructionFile>
|
|
17
|
+
* 2. User-level: <configDir>/<each instructionFile>
|
|
18
|
+
* 3. Memory dir: <memoryDir>/*.md
|
|
19
|
+
*
|
|
20
|
+
* Without an adapter (legacy callers), defaults to Claude conventions
|
|
21
|
+
* (CLAUDE.md + ~/.claude/memory) for backwards compatibility.
|
|
19
22
|
*
|
|
20
23
|
* @param queries Array of search terms
|
|
21
24
|
* @param limit Max results to return
|
|
22
25
|
* @param projectDir Project directory path
|
|
23
|
-
* @param configDir
|
|
26
|
+
* @param configDir Explicit config dir override (legacy callers)
|
|
27
|
+
* @param adapter Platform adapter — supplies instruction files + memory dir
|
|
24
28
|
* @returns Matching auto-memory results
|
|
25
29
|
*/
|
|
26
|
-
export function searchAutoMemory(queries, limit = 5, projectDir, configDir) {
|
|
30
|
+
export function searchAutoMemory(queries, limit = 5, projectDir, configDir, adapter) {
|
|
27
31
|
const results = [];
|
|
28
|
-
|
|
32
|
+
// Resolve conventions — adapter wins over explicit configDir, which wins
|
|
33
|
+
// over the historical Claude defaults.
|
|
34
|
+
const instructionFiles = adapter?.getInstructionFiles() ?? ["CLAUDE.md"];
|
|
35
|
+
const adapterConfigDir = adapter?.getConfigDir();
|
|
36
|
+
const effectiveConfigDir = adapterConfigDir
|
|
37
|
+
? resolveAgainst(projectDir, adapterConfigDir)
|
|
38
|
+
: (configDir || join(homedir(), ".claude"));
|
|
39
|
+
const adapterMemoryDir = adapter?.getMemoryDir();
|
|
40
|
+
const memoryDir = adapterMemoryDir
|
|
41
|
+
? resolveAgainst(projectDir, adapterMemoryDir)
|
|
42
|
+
: join(effectiveConfigDir, "memory");
|
|
29
43
|
// Collect candidate files
|
|
30
44
|
const candidates = [];
|
|
31
|
-
// 1. Project-level
|
|
45
|
+
// 1. Project-level instruction files
|
|
32
46
|
if (projectDir) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
for (const fileName of instructionFiles) {
|
|
48
|
+
const p = join(projectDir, fileName);
|
|
49
|
+
if (existsSync(p)) {
|
|
50
|
+
candidates.push({ path: p, label: `project/${fileName}` });
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
}
|
|
38
|
-
// 2. User-level
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
54
|
+
// 2. User-level instruction files (skip when configDir resolves to the
|
|
55
|
+
// project root — already covered by step 1, would emit dup labels).
|
|
56
|
+
if (effectiveConfigDir && effectiveConfigDir !== projectDir) {
|
|
57
|
+
for (const fileName of instructionFiles) {
|
|
58
|
+
const p = join(effectiveConfigDir, fileName);
|
|
59
|
+
if (existsSync(p)) {
|
|
60
|
+
candidates.push({ path: p, label: `user/${fileName}` });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
42
63
|
}
|
|
43
|
-
// 3.
|
|
44
|
-
|
|
45
|
-
if (existsSync(memoryDir)) {
|
|
64
|
+
// 3. Memory directory
|
|
65
|
+
if (memoryDir && existsSync(memoryDir)) {
|
|
46
66
|
try {
|
|
47
67
|
const files = readdirSync(memoryDir).filter(f => f.endsWith(".md"));
|
|
48
68
|
for (const file of files) {
|
|
@@ -62,9 +82,13 @@ export function searchAutoMemory(queries, limit = 5, projectDir, configDir) {
|
|
|
62
82
|
if (results.length >= limit)
|
|
63
83
|
break;
|
|
64
84
|
try {
|
|
65
|
-
//
|
|
85
|
+
// Single stat for both size guard and timestamp — saves one syscall
|
|
86
|
+
// per candidate file. Cross-platform: statSync semantics identical
|
|
87
|
+
// on macOS / Linux / Windows; size+mtime read in the same inode probe.
|
|
88
|
+
let stat;
|
|
66
89
|
try {
|
|
67
|
-
|
|
90
|
+
stat = statSync(candidate.path);
|
|
91
|
+
if (stat.size > 1_000_000)
|
|
68
92
|
continue;
|
|
69
93
|
}
|
|
70
94
|
catch {
|
|
@@ -106,7 +130,7 @@ export function searchAutoMemory(queries, limit = 5, projectDir, configDir) {
|
|
|
106
130
|
content: snippet,
|
|
107
131
|
source: candidate.label,
|
|
108
132
|
origin: "auto-memory",
|
|
109
|
-
timestamp:
|
|
133
|
+
timestamp: stat.mtime.toISOString(),
|
|
110
134
|
});
|
|
111
135
|
break; // one result per file per query batch
|
|
112
136
|
}
|
|
@@ -119,3 +143,17 @@ export function searchAutoMemory(queries, limit = 5, projectDir, configDir) {
|
|
|
119
143
|
}
|
|
120
144
|
return results.slice(0, limit);
|
|
121
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolve a possibly-relative path (e.g. ".github", "memory") against a
|
|
148
|
+
* project directory. Absolute paths and empty strings are returned as-is
|
|
149
|
+
* (empty == "use projectDir directly").
|
|
150
|
+
*/
|
|
151
|
+
function resolveAgainst(projectDir, p) {
|
|
152
|
+
if (!p)
|
|
153
|
+
return projectDir ?? "";
|
|
154
|
+
if (isAbsolute(p))
|
|
155
|
+
return p;
|
|
156
|
+
if (!projectDir)
|
|
157
|
+
return p;
|
|
158
|
+
return join(projectDir, p);
|
|
159
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ContentStore } from "../store.js";
|
|
9
9
|
import type { SessionDB } from "../session/db.js";
|
|
10
|
+
import { type AutoMemoryAdapter } from "./auto-memory.js";
|
|
10
11
|
export interface UnifiedSearchResult {
|
|
11
12
|
title: string;
|
|
12
13
|
content: string;
|
|
@@ -28,6 +29,8 @@ export interface SearchAllSourcesOpts {
|
|
|
28
29
|
sessionDB?: SessionDB | null;
|
|
29
30
|
projectDir?: string;
|
|
30
31
|
configDir?: string;
|
|
32
|
+
/** Detected platform adapter — used for adapter-aware auto-memory. */
|
|
33
|
+
adapter?: AutoMemoryAdapter;
|
|
31
34
|
}
|
|
32
35
|
/**
|
|
33
36
|
* Search across all available sources.
|
package/build/search/unified.js
CHANGED
|
@@ -20,7 +20,7 @@ const DEBUG = process.env.DEBUG?.includes("context-mode");
|
|
|
20
20
|
* are always returned.
|
|
21
21
|
*/
|
|
22
22
|
export function searchAllSources(opts) {
|
|
23
|
-
const { query, limit, store, sort = "relevance", source, contentType, sessionDB, projectDir, configDir, } = opts;
|
|
23
|
+
const { query, limit, store, sort = "relevance", source, contentType, sessionDB, projectDir, configDir, adapter, } = opts;
|
|
24
24
|
const results = [];
|
|
25
25
|
// Capture session start time once — used as proxy for ContentStore items
|
|
26
26
|
// (we don't know exact indexing time, but all content is from current session)
|
|
@@ -65,7 +65,7 @@ export function searchAllSources(opts) {
|
|
|
65
65
|
}
|
|
66
66
|
// Source 3: Auto-memory
|
|
67
67
|
try {
|
|
68
|
-
const memResults = searchAutoMemory([query], limit, projectDir, configDir);
|
|
68
|
+
const memResults = searchAutoMemory([query], limit, projectDir, configDir, adapter);
|
|
69
69
|
results.push(...memResults);
|
|
70
70
|
}
|
|
71
71
|
catch (e) {
|
package/build/server.d.ts
CHANGED
|
@@ -8,3 +8,45 @@ import { ContentStore } from "./store.js";
|
|
|
8
8
|
export declare function positionsFromHighlight(highlighted: string): number[];
|
|
9
9
|
export declare function extractSnippet(content: string, query: string, maxLen?: number, highlighted?: string): string;
|
|
10
10
|
export declare function formatBatchQueryResults(store: ContentStore, queries: string[], source: string, maxOutput?: number): string[];
|
|
11
|
+
export interface BatchCommand {
|
|
12
|
+
label: string;
|
|
13
|
+
command: string;
|
|
14
|
+
}
|
|
15
|
+
export interface BatchRunResult {
|
|
16
|
+
outputs: string[];
|
|
17
|
+
timedOut: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface BatchRunOptions {
|
|
20
|
+
timeout: number;
|
|
21
|
+
concurrency: number;
|
|
22
|
+
nodeOptsPrefix: string;
|
|
23
|
+
onFsBytes?: (bytes: number) => void;
|
|
24
|
+
}
|
|
25
|
+
interface BatchExecutor {
|
|
26
|
+
execute(input: {
|
|
27
|
+
language: "shell";
|
|
28
|
+
code: string;
|
|
29
|
+
timeout: number;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
stdout: string;
|
|
32
|
+
timedOut?: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Execute batch commands. concurrency=1 preserves the legacy serial path
|
|
37
|
+
* (shared timeout budget + cascading skip-on-timeout). concurrency>1 runs
|
|
38
|
+
* commands concurrently with at most N in flight; each command receives the
|
|
39
|
+
* full timeout, output is collated by input index, and per-command timeouts
|
|
40
|
+
* record `(timed out)` blocks without skipping siblings.
|
|
41
|
+
*/
|
|
42
|
+
export declare function runBatchCommands(commands: BatchCommand[], opts: BatchRunOptions, executor: BatchExecutor): Promise<BatchRunResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Classify an IP address.
|
|
45
|
+
* - "block": always blocked (link-local/IMDS/multicast/reserved/malformed)
|
|
46
|
+
* - "private": loopback or RFC1918 — allowed by default, blocked in strict mode
|
|
47
|
+
* - "public": safe to fetch
|
|
48
|
+
*
|
|
49
|
+
* Exported (via the function name) so SSRF tests can exercise the matcher directly.
|
|
50
|
+
*/
|
|
51
|
+
export declare function classifyIp(ip: string): "block" | "private" | "public";
|
|
52
|
+
export {};
|