context-mode 1.0.111 → 1.0.113

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.
Files changed (153) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/index.ts +3 -2
  4. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  5. package/.openclaw-plugin/package.json +1 -1
  6. package/README.md +152 -34
  7. package/bin/statusline.mjs +144 -127
  8. package/build/adapters/base.d.ts +8 -5
  9. package/build/adapters/base.js +8 -18
  10. package/build/adapters/claude-code/index.d.ts +24 -3
  11. package/build/adapters/claude-code/index.js +44 -11
  12. package/build/adapters/codex/hooks.d.ts +10 -5
  13. package/build/adapters/codex/hooks.js +10 -5
  14. package/build/adapters/codex/index.d.ts +17 -5
  15. package/build/adapters/codex/index.js +337 -37
  16. package/build/adapters/codex/paths.d.ts +1 -0
  17. package/build/adapters/codex/paths.js +12 -0
  18. package/build/adapters/cursor/index.d.ts +6 -0
  19. package/build/adapters/cursor/index.js +83 -2
  20. package/build/adapters/detect.d.ts +1 -1
  21. package/build/adapters/detect.js +29 -6
  22. package/build/adapters/omp/index.d.ts +65 -0
  23. package/build/adapters/omp/index.js +182 -0
  24. package/build/adapters/omp/plugin.d.ts +75 -0
  25. package/build/adapters/omp/plugin.js +220 -0
  26. package/build/adapters/openclaw/mcp-tools.d.ts +54 -0
  27. package/build/adapters/openclaw/mcp-tools.js +198 -0
  28. package/build/adapters/openclaw/plugin.d.ts +130 -0
  29. package/build/adapters/openclaw/plugin.js +629 -0
  30. package/build/adapters/openclaw/workspace-router.d.ts +29 -0
  31. package/build/adapters/openclaw/workspace-router.js +64 -0
  32. package/build/adapters/opencode/plugin.d.ts +145 -0
  33. package/build/adapters/opencode/plugin.js +457 -0
  34. package/build/adapters/pi/extension.d.ts +26 -0
  35. package/build/adapters/pi/extension.js +552 -0
  36. package/build/adapters/pi/index.d.ts +57 -0
  37. package/build/adapters/pi/index.js +173 -0
  38. package/build/adapters/pi/mcp-bridge.d.ts +113 -0
  39. package/build/adapters/pi/mcp-bridge.js +251 -0
  40. package/build/adapters/types.d.ts +11 -6
  41. package/build/cli.js +186 -170
  42. package/build/db-base.d.ts +15 -2
  43. package/build/db-base.js +50 -5
  44. package/build/executor.d.ts +2 -0
  45. package/build/executor.js +15 -2
  46. package/build/runPool.d.ts +36 -0
  47. package/build/runPool.js +51 -0
  48. package/build/runtime.js +64 -5
  49. package/build/search/auto-memory.js +6 -4
  50. package/build/security.js +30 -10
  51. package/build/server.d.ts +23 -1
  52. package/build/server.js +662 -182
  53. package/build/session/analytics.d.ts +404 -1
  54. package/build/session/analytics.js +1347 -42
  55. package/build/session/db.d.ts +114 -5
  56. package/build/session/db.js +275 -27
  57. package/build/session/event-emit.d.ts +48 -0
  58. package/build/session/event-emit.js +101 -0
  59. package/build/session/extract.d.ts +1 -0
  60. package/build/session/extract.js +79 -12
  61. package/build/session/purge.d.ts +111 -0
  62. package/build/session/purge.js +138 -0
  63. package/build/store.d.ts +7 -0
  64. package/build/store.js +69 -6
  65. package/build/util/claude-config.d.ts +26 -0
  66. package/build/util/claude-config.js +91 -0
  67. package/build/util/hook-config.d.ts +4 -0
  68. package/build/util/hook-config.js +39 -0
  69. package/build/util/project-dir.d.ts +49 -0
  70. package/build/util/project-dir.js +67 -0
  71. package/cli.bundle.mjs +411 -208
  72. package/configs/antigravity/GEMINI.md +0 -3
  73. package/configs/claude-code/CLAUDE.md +1 -4
  74. package/configs/codex/AGENTS.md +1 -4
  75. package/configs/codex/config.toml +3 -0
  76. package/configs/codex/hooks.json +8 -0
  77. package/configs/cursor/context-mode.mdc +0 -3
  78. package/configs/gemini-cli/GEMINI.md +0 -3
  79. package/configs/jetbrains-copilot/copilot-instructions.md +0 -3
  80. package/configs/kilo/AGENTS.md +0 -3
  81. package/configs/kiro/KIRO.md +0 -3
  82. package/configs/omp/SYSTEM.md +85 -0
  83. package/configs/omp/mcp.json +7 -0
  84. package/configs/openclaw/AGENTS.md +0 -3
  85. package/configs/opencode/AGENTS.md +0 -3
  86. package/configs/pi/AGENTS.md +0 -3
  87. package/configs/qwen-code/QWEN.md +1 -4
  88. package/configs/vscode-copilot/copilot-instructions.md +0 -3
  89. package/configs/zed/AGENTS.md +0 -3
  90. package/hooks/codex/posttooluse.mjs +9 -2
  91. package/hooks/codex/precompact.mjs +69 -0
  92. package/hooks/codex/sessionstart.mjs +13 -9
  93. package/hooks/codex/stop.mjs +1 -2
  94. package/hooks/codex/userpromptsubmit.mjs +1 -2
  95. package/hooks/core/routing.mjs +237 -18
  96. package/hooks/cursor/afteragentresponse.mjs +1 -1
  97. package/hooks/cursor/hooks.json +31 -0
  98. package/hooks/cursor/posttooluse.mjs +1 -1
  99. package/hooks/cursor/sessionstart.mjs +5 -5
  100. package/hooks/cursor/stop.mjs +1 -1
  101. package/hooks/ensure-deps.mjs +12 -13
  102. package/hooks/gemini-cli/aftertool.mjs +1 -1
  103. package/hooks/gemini-cli/beforeagent.mjs +1 -1
  104. package/hooks/gemini-cli/precompress.mjs +3 -2
  105. package/hooks/gemini-cli/sessionstart.mjs +9 -9
  106. package/hooks/jetbrains-copilot/posttooluse.mjs +1 -1
  107. package/hooks/jetbrains-copilot/precompact.mjs +3 -2
  108. package/hooks/jetbrains-copilot/sessionstart.mjs +9 -9
  109. package/hooks/kiro/agentspawn.mjs +5 -5
  110. package/hooks/kiro/posttooluse.mjs +2 -2
  111. package/hooks/kiro/userpromptsubmit.mjs +1 -1
  112. package/hooks/posttooluse.mjs +45 -0
  113. package/hooks/precompact.mjs +17 -0
  114. package/hooks/pretooluse.mjs +23 -0
  115. package/hooks/routing-block.mjs +0 -12
  116. package/hooks/run-hook.mjs +16 -3
  117. package/hooks/session-db.bundle.mjs +27 -18
  118. package/hooks/session-extract.bundle.mjs +2 -2
  119. package/hooks/session-helpers.mjs +101 -64
  120. package/hooks/sessionstart.mjs +51 -2
  121. package/hooks/vscode-copilot/posttooluse.mjs +1 -1
  122. package/hooks/vscode-copilot/precompact.mjs +3 -2
  123. package/hooks/vscode-copilot/sessionstart.mjs +9 -9
  124. package/openclaw.plugin.json +1 -1
  125. package/package.json +14 -8
  126. package/server.bundle.mjs +349 -147
  127. package/start.mjs +16 -4
  128. package/skills/UPSTREAM-CREDITS.md +0 -51
  129. package/skills/context-mode-ops/SKILL.md +0 -299
  130. package/skills/context-mode-ops/agent-teams.md +0 -198
  131. package/skills/context-mode-ops/communication.md +0 -224
  132. package/skills/context-mode-ops/marketing.md +0 -124
  133. package/skills/context-mode-ops/release.md +0 -214
  134. package/skills/context-mode-ops/review-pr.md +0 -269
  135. package/skills/context-mode-ops/tdd.md +0 -329
  136. package/skills/context-mode-ops/triage-issue.md +0 -266
  137. package/skills/context-mode-ops/validation.md +0 -307
  138. package/skills/diagnose/SKILL.md +0 -122
  139. package/skills/diagnose/scripts/hitl-loop.template.sh +0 -41
  140. package/skills/grill-me/SKILL.md +0 -15
  141. package/skills/grill-with-docs/ADR-FORMAT.md +0 -47
  142. package/skills/grill-with-docs/CONTEXT-FORMAT.md +0 -77
  143. package/skills/grill-with-docs/SKILL.md +0 -93
  144. package/skills/improve-codebase-architecture/DEEPENING.md +0 -37
  145. package/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
  146. package/skills/improve-codebase-architecture/LANGUAGE.md +0 -53
  147. package/skills/improve-codebase-architecture/SKILL.md +0 -76
  148. package/skills/tdd/SKILL.md +0 -114
  149. package/skills/tdd/deep-modules.md +0 -33
  150. package/skills/tdd/interface-design.md +0 -31
  151. package/skills/tdd/mocking.md +0 -59
  152. package/skills/tdd/refactoring.md +0 -10
  153. package/skills/tdd/tests.md +0 -61
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Generic in-flight-capped worker pool.
3
+ *
4
+ * Used by:
5
+ * - runBatchCommands (ctx_batch_execute parallel branch)
6
+ * - runBatchFetch (ctx_fetch_and_index batch path)
7
+ *
8
+ * Returns Promise.allSettled-style results so one job's throw cannot
9
+ * strand siblings. Caller maps fulfilled/rejected per index. Output
10
+ * order is preserved by input index (not completion order).
11
+ *
12
+ * Designed to be the SINGLE concurrency primitive for the project —
13
+ * all "run N independent operations with at most M in flight" needs
14
+ * route here. Avoids the worker-pool copy-paste flagged in the
15
+ * concurrency PRD architectural review (finding G).
16
+ */
17
+ export interface PoolJob<T> {
18
+ run(): Promise<T>;
19
+ }
20
+ export interface RunPoolOptions {
21
+ /** Hard concurrency cap (1-N). Auto-clamped to job count. */
22
+ concurrency: number;
23
+ /** Optional: also clamp by `os.cpus().length` (memory-pressure safety). Default false. */
24
+ capByCpuCount?: boolean;
25
+ /** Optional: per-settled callback (e.g. for progress reporting / metrics). */
26
+ onSettled?: (idx: number, result: PromiseSettledResult<unknown>) => void;
27
+ }
28
+ export interface RunPoolResult<T> {
29
+ /** Per-index settled result, ordered by input index. */
30
+ settled: PromiseSettledResult<T>[];
31
+ /** Concurrency actually used after all caps applied. */
32
+ effectiveConcurrency: number;
33
+ /** True when effectiveConcurrency < requested concurrency. */
34
+ capped: boolean;
35
+ }
36
+ export declare function runPool<T>(jobs: PoolJob<T>[], opts: RunPoolOptions): Promise<RunPoolResult<T>>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Generic in-flight-capped worker pool.
3
+ *
4
+ * Used by:
5
+ * - runBatchCommands (ctx_batch_execute parallel branch)
6
+ * - runBatchFetch (ctx_fetch_and_index batch path)
7
+ *
8
+ * Returns Promise.allSettled-style results so one job's throw cannot
9
+ * strand siblings. Caller maps fulfilled/rejected per index. Output
10
+ * order is preserved by input index (not completion order).
11
+ *
12
+ * Designed to be the SINGLE concurrency primitive for the project —
13
+ * all "run N independent operations with at most M in flight" needs
14
+ * route here. Avoids the worker-pool copy-paste flagged in the
15
+ * concurrency PRD architectural review (finding G).
16
+ */
17
+ import { cpus } from "node:os";
18
+ export async function runPool(jobs, opts) {
19
+ const { concurrency, capByCpuCount = false, onSettled } = opts;
20
+ if (jobs.length === 0) {
21
+ return { settled: [], effectiveConcurrency: 0, capped: false };
22
+ }
23
+ const requested = Math.max(1, concurrency);
24
+ const cpuCap = capByCpuCount ? Math.max(1, cpus().length) : requested;
25
+ const effectiveConcurrency = Math.min(requested, cpuCap, jobs.length);
26
+ const capped = effectiveConcurrency < requested;
27
+ const settled = new Array(jobs.length);
28
+ let nextIdx = 0;
29
+ async function worker() {
30
+ while (true) {
31
+ const idx = nextIdx++;
32
+ if (idx >= jobs.length)
33
+ return;
34
+ try {
35
+ const value = await jobs[idx].run();
36
+ settled[idx] = { status: "fulfilled", value };
37
+ }
38
+ catch (err) {
39
+ settled[idx] = { status: "rejected", reason: err };
40
+ }
41
+ onSettled?.(idx, settled[idx]);
42
+ }
43
+ }
44
+ const workers = [];
45
+ for (let w = 0; w < effectiveConcurrency; w++)
46
+ workers.push(worker());
47
+ // allSettled defends against any promise rejection escaping a worker
48
+ // (the worker already swallows its own errors, but this is belt-and-braces).
49
+ await Promise.allSettled(workers);
50
+ return { settled, effectiveConcurrency, capped };
51
+ }
package/build/runtime.js CHANGED
@@ -29,6 +29,48 @@ function commandExists(cmd) {
29
29
  return false;
30
30
  }
31
31
  }
32
+ /**
33
+ * Stricter probe than commandExists() — also verifies the resolved binary
34
+ * actually runs. On Windows, `where python3` matches the Microsoft Store
35
+ * App Execution Alias stub at C:\Users\<u>\AppData\Local\Microsoft\WindowsApps\
36
+ * even when no real Python is installed; the stub exits non-zero (9009) and
37
+ * pops the Store. Filter those entries out and require `<cmd> --version` to
38
+ * exit 0 before declaring the runtime available (#455).
39
+ */
40
+ function runnableExists(cmd) {
41
+ if (isWindows) {
42
+ // Reject if every `where` hit lives under Microsoft\WindowsApps (Store stubs).
43
+ try {
44
+ const out = execSync(`where ${cmd}`, { encoding: "utf-8", stdio: "pipe" });
45
+ const hits = out.trim().split(/\r?\n/).map(p => p.trim()).filter(Boolean);
46
+ if (hits.length === 0)
47
+ return false;
48
+ const realHits = hits.filter(p => !/\\Microsoft\\WindowsApps\\/i.test(p));
49
+ if (realHits.length === 0)
50
+ return false;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ else if (!commandExists(cmd)) {
57
+ return false;
58
+ }
59
+ // Probe with --version. On Windows, allow 5s for cold-start (MS Store stub
60
+ // fallthrough can be slow). On POSIX, 1500ms is plenty for a real binary
61
+ // and keeps cold detection of python3 → python → py under ~5s total (#454).
62
+ try {
63
+ execFileSync(cmd, ["--version"], {
64
+ shell: isWindows,
65
+ stdio: "pipe",
66
+ timeout: isWindows ? 5000 : 1500,
67
+ });
68
+ return true;
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
32
74
  function bunExists() {
33
75
  if (commandExists("bun"))
34
76
  return true;
@@ -39,12 +81,19 @@ function bunExists() {
39
81
  return false;
40
82
  }
41
83
  function bunCommand() {
42
- if (commandExists("bun"))
43
- return "bun";
84
+ // Prefer absolute .exe paths so spawn() can run with shell:false on Windows.
85
+ // `where bun` may resolve to a `bun.cmd` npm shim (#506) which CreateProcess
86
+ // cannot execute directly — return the real .exe wherever we can find one.
44
87
  for (const p of bunFallbackPaths()) {
45
88
  if (existsSync(p))
46
89
  return p;
47
90
  }
91
+ // Bare name only if PATH resolution confirms it. On Windows this is
92
+ // typically a .cmd shim — the executor's needsShell list (which now
93
+ // includes "bun" — see #506) ensures shell:true so cmd.exe can resolve it.
94
+ if (commandExists("bun"))
95
+ return "bun";
96
+ // Synthetic last-resort path for diagnostics/error messages.
48
97
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
49
98
  return isWindows ? `${home}\\.bun\\bin\\bun.exe` : `${home}/.bun/bin/bun`;
50
99
  }
@@ -53,9 +102,17 @@ function bunFallbackPaths() {
53
102
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
54
103
  if (isWindows) {
55
104
  const localAppData = process.env.LOCALAPPDATA ?? "";
105
+ const appData = process.env.APPDATA ?? "";
56
106
  return [
107
+ // Native bun installer locations (irm bun.sh/install.ps1).
57
108
  ...(home ? [`${home}\\.bun\\bin\\bun.exe`] : []),
58
109
  ...(localAppData ? [`${localAppData}\\bun\\bin\\bun.exe`] : []),
110
+ // npm i -g bun installs bun.exe under the npm prefix (typically
111
+ // %APPDATA%\npm\node_modules\bun\bin\bun.exe). Without this, npm
112
+ // installs were "found" via bun.cmd shim on PATH and the bare "bun"
113
+ // string was returned — spawn() then ENOENT'd because CreateProcess
114
+ // can't execute .cmd files (#506).
115
+ ...(appData ? [`${appData}\\npm\\node_modules\\bun\\bin\\bun.exe`] : []),
59
116
  ];
60
117
  }
61
118
  return home ? [`${home}/.bun/bin/bun`] : [];
@@ -133,11 +190,13 @@ export function detectRuntimes() {
133
190
  : commandExists("ts-node")
134
191
  ? "ts-node"
135
192
  : null,
136
- python: commandExists("python3")
193
+ python: runnableExists("python3")
137
194
  ? "python3"
138
- : commandExists("python")
195
+ : runnableExists("python")
139
196
  ? "python"
140
- : null,
197
+ : runnableExists("py")
198
+ ? "py"
199
+ : null,
141
200
  shell: shellOverride ?? (isWin
142
201
  ? (resolveWindowsBash() ?? (commandExists("sh") ? "sh" : commandExists("powershell") ? "powershell" : "cmd.exe"))
143
202
  : commandExists("bash") ? "bash" : "sh"),
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
9
9
  import { join, isAbsolute } from "node:path";
10
- import { homedir } from "node:os";
10
+ import { resolveClaudeConfigDir } from "../util/claude-config.js";
11
11
  const DEBUG = process.env.DEBUG?.includes("context-mode");
12
12
  /**
13
13
  * Search auto-memory files for content matching any of the given queries.
@@ -33,9 +33,11 @@ export function searchAutoMemory(queries, limit = 5, projectDir, configDir, adap
33
33
  // over the historical Claude defaults.
34
34
  const instructionFiles = adapter?.getInstructionFiles() ?? ["CLAUDE.md"];
35
35
  const adapterConfigDir = adapter?.getConfigDir();
36
- const effectiveConfigDir = adapterConfigDir
37
- ? resolveAgainst(projectDir, adapterConfigDir)
38
- : (configDir || join(homedir(), ".claude"));
36
+ // Issue #460 round-3: legacy fallback honors $CLAUDE_CONFIG_DIR via the
37
+ // canonical util so callers without an adapter still respect relocated
38
+ // CC config trees (and empty/whitespace env doesn't poison the path).
39
+ const adapterRelative = adapterConfigDir ? resolveAgainst(projectDir, adapterConfigDir) : null;
40
+ const effectiveConfigDir = adapterRelative ?? configDir ?? resolveClaudeConfigDir();
39
41
  const adapterMemoryDir = adapter?.getMemoryDir();
40
42
  const memoryDir = adapterMemoryDir
41
43
  ? resolveAgainst(projectDir, adapterMemoryDir)
package/build/security.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { readFileSync, realpathSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
- import { homedir } from "node:os";
3
+ import { resolveAdapterGlobalSettingsPaths } from "./util/claude-config.js";
4
4
  // ==============================================================================
5
5
  // Pattern Parsing
6
6
  // ==============================================================================
@@ -238,10 +238,18 @@ export function readBashPolicies(projectDir, globalSettingsPath) {
238
238
  if (sharedPolicy)
239
239
  policies.push(sharedPolicy);
240
240
  }
241
- const globalPath = globalSettingsPath ?? resolve(homedir(), ".claude", "settings.json");
242
- const globalPolicy = readSingleSettings(globalPath);
243
- if (globalPolicy)
244
- policies.push(globalPolicy);
241
+ // Issue #451 round-3: read settings from EVERY adapter-specific global path
242
+ // PLUS the claude global (defense in depth). When the caller passes an
243
+ // explicit globalSettingsPath we honor it verbatim (back-compat with tests
244
+ // and callers that already know which file to read).
245
+ const globalPaths = globalSettingsPath !== undefined
246
+ ? [globalSettingsPath]
247
+ : resolveAdapterGlobalSettingsPaths();
248
+ for (const globalPath of globalPaths) {
249
+ const globalPolicy = readSingleSettings(globalPath);
250
+ if (globalPolicy)
251
+ policies.push(globalPolicy);
252
+ }
245
253
  return policies;
246
254
  }
247
255
  /**
@@ -293,10 +301,18 @@ export function readToolDenyPatterns(toolName, projectDir, globalSettingsPath) {
293
301
  if (sharedGlobs !== null)
294
302
  result.push(sharedGlobs);
295
303
  }
296
- const globalPath = globalSettingsPath ?? resolve(homedir(), ".claude", "settings.json");
297
- const globalGlobs = extractGlobs(globalPath);
298
- if (globalGlobs !== null)
299
- result.push(globalGlobs);
304
+ // Issue #451 round-3: union over every adapter-specific global path PLUS
305
+ // claude global. Each settings file contributes its own globs array entry
306
+ // so the precedence ordering downstream remains per-file rather than
307
+ // collapsed.
308
+ const globalPaths = globalSettingsPath !== undefined
309
+ ? [globalSettingsPath]
310
+ : resolveAdapterGlobalSettingsPaths();
311
+ for (const globalPath of globalPaths) {
312
+ const globalGlobs = extractGlobs(globalPath);
313
+ if (globalGlobs !== null)
314
+ result.push(globalGlobs);
315
+ }
300
316
  return result;
301
317
  }
302
318
  /**
@@ -395,7 +411,11 @@ export function evaluateFilePath(filePath, denyGlobs, caseInsensitive = process.
395
411
  }
396
412
  for (const globs of denyGlobs) {
397
413
  for (const glob of globs) {
398
- const regex = fileGlobToRegex(glob, caseInsensitive);
414
+ // Normalize the glob's path separators the same way candidates were
415
+ // normalized — otherwise a Windows absolute deny rule like
416
+ // `Read(C:\Users\...\secret.env)` parses with literal backslashes that
417
+ // never match a forward-slash candidate.
418
+ const regex = fileGlobToRegex(toForward(glob), caseInsensitive);
399
419
  for (const candidate of candidates) {
400
420
  if (regex.test(candidate)) {
401
421
  return { denied: true, matchedPattern: glob };
package/build/server.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { type SpawnSyncOptions, type SpawnSyncReturns } from "node:child_process";
2
3
  import { ContentStore } from "./store.js";
3
4
  /**
4
5
  * Parse FTS5 highlight markers to find match positions in the
@@ -46,6 +47,7 @@ export declare function buildBatchNodeOptionsPrefix(shellPath: string, preloadPa
46
47
  * record `(timed out)` blocks without skipping siblings.
47
48
  */
48
49
  export declare function runBatchCommands(commands: BatchCommand[], opts: BatchRunOptions, executor: BatchExecutor): Promise<BatchRunResult>;
50
+ export declare function buildFetchCode(url: string, outputPath: string): string;
49
51
  /**
50
52
  * Classify an IP address.
51
53
  * - "block": always blocked (link-local/IMDS/multicast/reserved/malformed)
@@ -54,5 +56,25 @@ export declare function runBatchCommands(commands: BatchCommand[], opts: BatchRu
54
56
  *
55
57
  * Exported (via the function name) so SSRF tests can exercise the matcher directly.
56
58
  */
57
- export declare function classifyIp(ip: string): "block" | "private" | "public";
59
+ export declare function classifyIp(rawIp: string): "block" | "private" | "public";
60
+ export type SpawnSyncFn = (cmd: string, args: readonly string[], opts?: SpawnSyncOptions) => SpawnSyncReturns<string | Buffer>;
61
+ export type BrowserOpenResult = {
62
+ ok: true;
63
+ method: string;
64
+ } | {
65
+ ok: false;
66
+ method: "none";
67
+ reason: string;
68
+ };
69
+ export type KillResult = {
70
+ killedPids: string[];
71
+ attemptedPids: string[];
72
+ errors: string[];
73
+ };
74
+ export declare function browserOpenArgv(url: string, platform: NodeJS.Platform): readonly {
75
+ cmd: string;
76
+ args: readonly string[];
77
+ }[];
78
+ export declare function openBrowserSync(url: string, platform?: NodeJS.Platform, runner?: SpawnSyncFn): BrowserOpenResult;
79
+ export declare function killProcessOnPort(port: number, platform?: NodeJS.Platform, runner?: SpawnSyncFn): KillResult;
58
80
  export {};