@wrongstack/tools 0.296.4 → 0.297.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/dist/audit.js +15 -0
- package/dist/audit.js.map +2 -2
- package/dist/bash.js +15 -0
- package/dist/bash.js.map +2 -2
- package/dist/builtin.js +42 -0
- package/dist/builtin.js.map +2 -2
- package/dist/codebase-index/index.js +27 -0
- package/dist/codebase-index/index.js.map +2 -2
- package/dist/codebase-index/project-server-client.d.ts.map +1 -1
- package/dist/codebase-index/project-server.js +16 -0
- package/dist/codebase-index/project-server.js.map +2 -2
- package/dist/exec.js +15 -0
- package/dist/exec.js.map +2 -2
- package/dist/format.js +15 -0
- package/dist/format.js.map +2 -2
- package/dist/index.js +42 -0
- package/dist/index.js.map +2 -2
- package/dist/install.js +15 -0
- package/dist/install.js.map +2 -2
- package/dist/languages/index.js +15 -0
- package/dist/languages/index.js.map +2 -2
- package/dist/lint.js +15 -0
- package/dist/lint.js.map +2 -2
- package/dist/next-steps.d.ts +23 -0
- package/dist/next-steps.d.ts.map +1 -1
- package/dist/next-steps.js +4 -0
- package/dist/next-steps.js.map +2 -2
- package/dist/outdated.js +15 -0
- package/dist/outdated.js.map +2 -2
- package/dist/pack.js +42 -0
- package/dist/pack.js.map +2 -2
- package/dist/process-registry.d.ts +9 -0
- package/dist/process-registry.d.ts.map +1 -1
- package/dist/process-registry.js +15 -0
- package/dist/process-registry.js.map +2 -2
- package/dist/ps-slash.js +15 -0
- package/dist/ps-slash.js.map +2 -2
- package/dist/read.js +27 -0
- package/dist/read.js.map +2 -2
- package/dist/test.js +15 -0
- package/dist/test.js.map +2 -2
- package/dist/tool-tier.js +42 -0
- package/dist/tool-tier.js.map +2 -2
- package/dist/typecheck.js +15 -0
- package/dist/typecheck.js.map +2 -2
- package/package.json +3 -3
package/dist/typecheck.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/typecheck.ts", "../src/_spawn-stream.ts", "../src/_output-spool.ts", "../src/process-registry.ts", "../src/circuit-breaker.ts", "../src/_redact-command.ts", "../src/_win32-resolve.ts", "../src/_util.ts", "../src/languages/legacy-bridge.ts", "../src/languages/detect.ts", "../src/languages/profile-helpers.ts", "../src/languages/profiles/additional.ts", "../src/languages/profiles/primary.ts", "../src/languages/registry.ts", "../src/languages/diagnostics.ts", "../src/languages/execute.ts", "../src/languages/plan.ts"],
|
|
4
|
-
"sourcesContent": ["import * as path from 'node:path';\nimport type { Tool, ToolStreamEvent } from '@wrongstack/core/types';\nimport { spawnStream } from './_spawn-stream.js';\nimport { normalizeCommandOutput, safeResolve } from './_util.js';\nimport { tryLegacyCodeOperation } from './languages/legacy-bridge.js';\n\ninterface TypecheckInput {\n project?: string | undefined;\n cwd?: string | undefined;\n strict?: boolean | undefined;\n all?: boolean | undefined;\n /** Emit JSON for machine-readable output (default: false). */\n json?: boolean | undefined;\n}\n\ninterface TypecheckOutput {\n project: string;\n exit_code: number;\n errors: number;\n warnings: number;\n output: string;\n truncated: boolean;\n}\n\nexport const typecheckTool: Tool<TypecheckInput, TypecheckOutput> = {\n name: 'typecheck',\n category: 'Code Quality',\n description:\n \"Run the project's TypeScript type checker (`tsc --noEmit` or equivalent). Essential for verifying type safety before making changes or committing.\",\n usageHint:\n 'ALWAYS RUN BEFORE CONSIDERING WORK COMPLETE:\\n\\n' +\n '- Use this to catch type errors early.\\n' +\n '- In monorepos, `all: true` will check every package.\\n' +\n '- This is one of the most important quality gates in this project.\\n' +\n 'Never claim a task is done without a clean typecheck (unless the user explicitly says otherwise).',\n permission: 'confirm',\n mutating: false,\n timeoutMs: 120_000,\n capabilities: ['shell.restricted'],\n icon: 'code',\n inputSchema: {\n type: 'object',\n properties: {\n project: { type: 'string', description: 'Path to tsconfig.json (default: auto-detect)' },\n cwd: { type: 'string', description: 'Working directory (default: cwd)' },\n strict: {\n type: 'boolean',\n description: 'Add --strict flag for maximum type checking (default: false)',\n },\n all: {\n type: 'boolean',\n description: 'Type-check all projects (pnpm -r) (default: false)',\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON output from tsc (default: false)',\n },\n },\n },\n async execute(input, ctx, opts) {\n let final: TypecheckOutput | undefined;\n const executeStream = typecheckTool.executeStream;\n if (!executeStream) throw new Error('typecheckTool: stream execution unavailable');\n for await (const ev of executeStream(input, ctx, opts)) {\n if (ev.type === 'final') final = ev.output;\n }\n if (!final) throw new Error('typecheck: stream ended without final event');\n return final;\n },\n async *executeStream(input, ctx, opts): AsyncGenerator<ToolStreamEvent<TypecheckOutput>> {\n const cwd = input.cwd ? safeResolve(input.cwd, ctx) : ctx.cwd;\n\n // Delegate to the language planner for non-JS ecosystems (Go, Rust, PHP, C#).\n const bridge = await tryLegacyCodeOperation('semantic', {\n cwd,\n projectRoot: ctx.projectRoot,\n signal: opts.signal,\n });\n if (bridge?.run) {\n const run = bridge.run;\n yield {\n type: 'final',\n output: {\n project: `${bridge.language} workspace`,\n exit_code: run.exitCode ?? 0,\n errors: run.summary.errors,\n warnings: run.summary.warnings,\n output: normalizeCommandOutput(run.output || run.error || ''),\n truncated: run.truncated,\n },\n };\n return;\n }\n\n let args: string[];\n let project: string;\n if (input.all) {\n args = ['--noEmit'];\n project = 'workspace';\n } else {\n const tsconfig = input.project ? safeResolve(input.project, ctx) : await findTsConfig(cwd);\n args = ['--noEmit'];\n if (input.strict) args.push('--strict');\n if (tsconfig) args.push('--project', tsconfig);\n project = tsconfig ?? 'default';\n }\n if (input.json) args.push('--json');\n\n yield { type: 'log', text: `tsc ${args.join(' ')}`, data: { project } };\n\n const result = yield* spawnStream({\n cmd: 'npx',\n args: ['tsc', ...args],\n cwd,\n signal: opts.signal,\n maxBytes: 200_000,\n });\n\n const errors = [...result.stdout.matchAll(/\\berror\\b/gi)].length;\n const warnings = [...result.stdout.matchAll(/\\bwarning\\b/gi)].length;\n\n yield {\n type: 'final',\n output: {\n project,\n exit_code: result.exitCode,\n errors,\n warnings,\n output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ''),\n truncated: result.truncated,\n },\n };\n },\n};\n\nasync function findTsConfig(cwd: string): Promise<string | null> {\n const { stat } = await import('node:fs/promises');\n const candidates = ['tsconfig.json', 'tsconfig.base.json'];\n for (const f of candidates) {\n try {\n const s = await stat(path.join(cwd, f));\n if (s.isFile()) return path.join(cwd, f);\n } catch {\n // continue\n }\n }\n return null;\n}\n", "import { spawn } from 'node:child_process';\nimport {\n emitProcessCompleted,\n emitProcessOutput,\n emitProcessStarted,\n} from '@wrongstack/core/observability';\nimport { buildChildEnv } from '@wrongstack/core/utils';\nimport type { ToolProgressEvent } from '@wrongstack/core/types';\nimport { createOutputSpool, spoolNote } from './_output-spool.js';\nimport { getProcessRegistry, redactCommand } from './process-registry.js';\nimport {\n buildWin32CmdShimInvocation,\n resolveWin32Command,\n} from './_win32-resolve.js';\n\nconst isWin = process.platform === 'win32';\nexport interface SpawnStreamResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n truncated: boolean;\n error?: string | undefined;\n /** When the output exceeded maxBytes, the FULL output was spooled here. */\n spoolPath?: string | undefined;\n /** Total output bytes produced (only set when spooled). */\n spoolBytes?: number | undefined;\n}\n\nexport interface SpawnStreamOptions {\n cmd: string;\n args: string[];\n cwd: string;\n signal: AbortSignal;\n maxBytes?: number | undefined;\n /** Bytes of new stdout/stderr to accumulate before yielding a `partial_output` event. */\n flushBytes?: number | undefined;\n /** Maximum chunks to buffer before applying backpressure to the child. Default 500. */\n maxQueueSize?: number | undefined;\n}\n\n/**\n * Spawn a child process and yield `partial_output` progress events as\n * stdout/stderr arrive (batched by byte threshold), then return the full\n * buffered result. Shared between install/lint/format/typecheck/test/audit\n * so the TUI live tail sees consistent progress regardless of which tool\n * is running.\n */\nexport async function* spawnStream(\n opts: SpawnStreamOptions,\n): AsyncGenerator<ToolProgressEvent, SpawnStreamResult> {\n const max = opts.maxBytes ?? 200_000;\n const flushAt = opts.flushBytes ?? 4 * 1024;\n const maxQueue = opts.maxQueueSize ?? 500;\n let stdout = '';\n let stderr = '';\n let pending = '';\n let error: string | undefined;\n // Full-output spool: stdout/stderr keep only the first `max` bytes for the\n // model. Once the combined output exceeds that, the FULL stream goes to a\n // file and the result carries a marker \u2014 so a huge vitest/tsc run lands on\n // disk, not in the host heap or the chat history.\n const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });\n\n const resolved = resolveWin32Command(opts.cmd);\n const needsShell = isWin && (resolved.endsWith('.cmd') || resolved.endsWith('.bat'));\n const shim = needsShell ? buildWin32CmdShimInvocation(resolved, opts.args) : null;\n const cmd = shim?.command ?? resolved;\n const args = shim?.args ?? opts.args;\n\n // On Windows the abort signal is handled manually below instead of being\n // passed to spawn(): Node's built-in handling kills only the direct child.\n // With the .cmd/.bat shell wrapper the real command (vitest, tsc, \u2026) is a\n // *grandchild* of cmd.exe \u2014 killing the wrapper orphans it, the orphan\n // keeps the inherited stdio pipes open (so 'close' never fires) and\n // streams into this process for the rest of the session. registry.kill()\n // tree-kills via taskkill /T instead \u2014 same rationale as bash.ts/exec.ts.\n const child = spawn(cmd, args, {\n cwd: opts.cwd,\n env: buildChildEnv(),\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n ...(isWin ? {} : { signal: opts.signal }),\n ...(shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}),\n });\n\n // Register with the global registry so Ctrl+C / /kill can find and\n // tree-kill it \u2014 spawnStream consumers (test/lint/typecheck/install/\u2026)\n // were previously invisible to the registry.\n const registry = getProcessRegistry();\n const pid = child.pid;\n const processStartedAt = Date.now();\n let stdoutBytes = 0;\n let stderrBytes = 0;\n let telemetryCompleted = false;\n emitProcessStarted({\n ...(pid !== undefined ? { pid } : {}),\n parentPid: process.pid,\n command: redactCommand(`${opts.cmd} ${opts.args.join(' ')}`),\n args: redactCommand(opts.args.join(' ')).split(' ').filter(Boolean),\n cwd: opts.cwd,\n background: false,\n startedAt: new Date(processStartedAt).toISOString(),\n });\n if (typeof pid === 'number') {\n registry.register({\n pid,\n name: opts.cmd,\n command: redactCommand(`${opts.cmd} ${opts.args.join(' ')}`),\n startedAt: Date.now(),\n child,\n });\n }\n\n type Chunk = { kind: 'out' | 'err' | 'close' | 'error'; data: string; code?: number | undefined; signal?: string | undefined };\n const queue: Chunk[] = [];\n let waiter: (() => void) | undefined;\n let paused = false;\n const wake = () => {\n if (waiter) {\n const w = waiter;\n waiter = undefined;\n w();\n }\n };\n\n // Resume the stream when there's room in the queue\n const resume = () => {\n if (paused && queue.length < maxQueue) {\n paused = false;\n child.stdout?.resume();\n child.stderr?.resume();\n }\n };\n\n // Note: chunks may still arrive briefly after pause() (already in flight) \u2014\n // they are accumulated and queued rather than dropped, so the queue can\n // overshoot maxQueue by a few entries but no output is silently lost.\n // Named handlers so the teardown in `finally` can detach them.\n const onOut = (c: Buffer) => {\n const s = c.toString();\n stdoutBytes += c.byteLength;\n emitProcessOutput({ pid, stream: 'stdout', chunk: c });\n if (stdout.length < max) stdout += s;\n spool.write(s);\n queue.push({ kind: 'out', data: s });\n wake();\n // Apply backpressure if queue is growing faster than we consume\n if (!paused && queue.length >= maxQueue) {\n paused = true;\n child.stdout?.pause();\n child.stderr?.pause();\n }\n };\n const onErr = (c: Buffer) => {\n const s = c.toString();\n stderrBytes += c.byteLength;\n emitProcessOutput({ pid, stream: 'stderr', chunk: c });\n if (stderr.length < max) stderr += s;\n spool.write(s);\n queue.push({ kind: 'err', data: s });\n wake();\n if (!paused && queue.length >= maxQueue) {\n paused = true;\n child.stdout?.pause();\n child.stderr?.pause();\n }\n };\n child.stdout?.on('data', onOut);\n child.stderr?.on('data', onErr);\n child.on('error', (e) => {\n error = e.message;\n queue.push({ kind: 'error', data: e.message });\n wake();\n });\n const completeTelemetry = (code: number, signal?: string | undefined, timedOut = false) => {\n if (telemetryCompleted) return;\n telemetryCompleted = true;\n emitProcessCompleted({\n ...(pid !== undefined ? { pid } : {}),\n exitCode: code,\n ...(signal ? { signal } : {}),\n durationMs: Date.now() - processStartedAt,\n stdoutBytes,\n stderrBytes,\n timedOut,\n endedAt: new Date().toISOString(),\n });\n };\n child.on('close', (code, signal) => {\n if (typeof pid === 'number') registry.unregister(pid);\n const exitCode = code ?? (signal ? 1 : 0);\n completeTelemetry(exitCode, signal ?? undefined);\n queue.push({ kind: 'close', data: '', code: exitCode, ...(signal ? { signal } : {}) });\n wake();\n });\n\n // Abort: tree-kill the child and wake the consumer loop with a synthetic\n // close (exit code 124, matching exec.ts's timeout convention). Without\n // the sentinel the loop can park forever on `waiter` when the pipes are\n // paused (queue full) or a win32 orphan holds them open \u2014 the executor's\n // iter.return() then never completes, the tool call hangs for the rest of\n // the session and retains the queue (up to maxQueue chunks) on the heap.\n //\n // Only on Windows: on POSIX the signal is already passed to spawn() above\n // (line 72) so Node.js handles the kill via the signal; attaching a second\n // handler here would double-kill the child and leak the listener when the\n // generator exits without aborting.\n const onAbort = () => {\n if (typeof pid === 'number') {\n registry.kill(pid, { force: true });\n } else {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already gone */\n }\n }\n queue.push({ kind: 'close', data: '', code: 124 });\n completeTelemetry(124, 'SIGKILL', true);\n wake();\n };\n if (isWin) {\n if (opts.signal.aborted) onAbort();\n else opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n let exitCode = 0;\n let spawnFailed = false;\n try {\n for (;;) {\n while (queue.length === 0) {\n await new Promise<void>((resolve) => {\n waiter = resolve;\n });\n }\n const chunk = queue.shift()!;\n // Resume reading after consuming a chunk\n resume();\n if (chunk.kind === 'close') {\n // If we already saw a spawn error (ENOENT etc.), keep exitCode=1\n // rather than the negative platform code Node fabricates.\n if (!spawnFailed) exitCode = chunk.code ?? 0;\n break;\n }\n if (chunk.kind === 'error') {\n spawnFailed = true;\n exitCode = 1;\n // close usually follows\n continue;\n }\n pending += chunk.data;\n if (pending.length >= flushAt) {\n yield { type: 'partial_output', text: pending };\n pending = '';\n }\n }\n if (pending.length > 0) {\n yield { type: 'partial_output', text: pending };\n }\n\n const spooled = spool.finalize();\n return {\n // The marker rides on stdout's tail so every consumer's head+tail\n // normalization keeps it without per-tool changes.\n stdout: spooled ? stdout + spoolNote(spooled) : stdout,\n stderr,\n exitCode,\n truncated: stdout.length >= max || stderr.length >= max,\n error,\n spoolPath: spooled?.path,\n spoolBytes: spooled?.bytes,\n };\n } finally {\n // Teardown \u2014 this generator can be abandoned mid-stream (executor\n // timeout/abort, or the consumer erroring out of its for-await loop).\n // The data handlers would otherwise stay attached and keep queueing\n // output with no consumer (bounded only by the pause cap), and a\n // surviving child would keep the closures \u2014 queue, output buffers,\n // child handle \u2014 alive until OOM. Detach the handlers, destroy the\n // pipes, and make sure nothing is left running.\n spool.finalize(); // idempotent \u2014 closes the file if the stream was abandoned\n if (isWin) opts.signal.removeEventListener('abort', onAbort);\n child.stdout?.off('data', onOut);\n child.stderr?.off('data', onErr);\n child.stdout?.destroy();\n child.stderr?.destroy();\n if (child.exitCode === null && !child.killed) {\n if (typeof pid === 'number') {\n registry.kill(pid, { force: true });\n } else {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already gone */\n }\n }\n }\n }\n}\n", "/**\n * _output-spool \u2014 file-based capture of FULL command output.\n *\n * Command tools (bash/exec and the _spawn-stream consumers) cap what they\n * keep in memory and what reaches the model (COMMAND_OUTPUT_MAX_BYTES head+\n * tail). Everything past the cap used to be silently dropped, which pushed\n * agents to re-run commands with bigger buffers or stuff huge outputs into\n * chat history. The spool keeps the host's memory and the context window\n * small while losing nothing: once a command's output exceeds the in-memory\n * threshold, the FULL stream is written to a log file under\n * `~/.wrongstack/tool-output/` and the capped tool result carries a\n * `[full output: <path>]` marker so the model can read/grep the file\n * selectively instead of dumping it into context.\n *\n * Properties:\n * - zero disk I/O for small outputs (file is created lazily on first byte\n * past the threshold; the buffered head is flushed at that moment)\n * - bounded memory: the head buffer never exceeds the threshold, and disk\n * backpressure drops chunks past a 4 MB writable-buffer high-water mark\n * (counted and reported in the marker) instead of queueing them on the heap\n * - best-effort: any fs error disables the spool silently \u2014 command tools\n * must never fail because diagnostics couldn't be written\n * - retention: spool files older than 7 days are swept once per process\n */\nimport { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { wstackGlobalRoot } from '@wrongstack/core/utils';\n\nconst SPOOL_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n/** Stop queueing chunks on the heap when the fs stream falls this far behind. */\nconst SPOOL_WRITE_HWM_BYTES = 4 * 1024 * 1024;\n\nlet sweepStarted = false;\n\n/** Directory for spooled command output (under the wstack global root). */\nexport function toolOutputDir(): string {\n return path.join(wstackGlobalRoot(), 'tool-output');\n}\n\n/** Reset module state \u2014 test hook (per-process sweep memo + nothing else). */\nexport function _resetOutputSpoolForTests(): void {\n sweepStarted = false;\n}\n\nfunction sweepOldSpoolFiles(dir: string): void {\n if (sweepStarted) return;\n sweepStarted = true;\n void (async () => {\n try {\n const now = Date.now();\n for (const name of await fsp.readdir(dir)) {\n if (!name.endsWith('.log')) continue;\n const p = path.join(dir, name);\n try {\n const st = await fsp.stat(p);\n if (now - st.mtimeMs > SPOOL_RETENTION_MS) await fsp.unlink(p);\n } catch {\n /* concurrently removed \u2014 ignore */\n }\n }\n } catch {\n /* directory doesn't exist yet \u2014 nothing to sweep */\n }\n })();\n}\n\nexport interface SpoolInfo {\n /** Absolute path of the spool file. */\n path: string;\n /** Total bytes of output produced (including what reached the file). */\n bytes: number;\n /** Bytes dropped due to disk backpressure (0 in the normal case). */\n droppedBytes: number;\n}\n\nexport interface OutputSpool {\n /** Feed every raw output chunk. Never throws. */\n write(text: string): void;\n /**\n * Close the file (if one was opened) and return its info, or null when the\n * output never exceeded the threshold. Idempotent.\n */\n finalize(): SpoolInfo | null;\n}\n\nexport interface CreateOutputSpoolOptions {\n /** Tool name used in the spool filename (sanitized). */\n tool: string;\n /**\n * Output size at which the spool activates. Should match the tool's\n * in-memory cap so files are only created for output the model can't\n * already see in full. Default 32 KB.\n */\n thresholdBytes?: number | undefined;\n}\n\n/**\n * Render the marker line appended to a capped tool result. Kept in one place\n * so every command tool phrases it identically (and tests can match it).\n */\nexport function spoolNote(info: SpoolInfo): string {\n const dropped =\n info.droppedBytes > 0 ? `, ~${info.droppedBytes} bytes dropped under backpressure` : '';\n return `\\n[output truncated \u2014 full ${info.bytes} bytes at ${info.path}${dropped}; read/grep that file selectively instead of re-running with more output]`;\n}\n\nexport function createOutputSpool(opts: CreateOutputSpoolOptions): OutputSpool {\n const threshold = opts.thresholdBytes ?? 32_768;\n const safeTool = opts.tool.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 40) || 'tool';\n\n let head = '';\n let headBytes = 0;\n let totalBytes = 0;\n let droppedBytes = 0;\n let stream: WriteStream | null = null;\n let filePath: string | null = null;\n let failed = false;\n let finalized = false;\n\n const open = (): void => {\n if (stream || failed) return;\n try {\n const dir = toolOutputDir();\n // Synchronous on purpose: createWriteStream would race an async mkdir\n // and error with ENOENT. This runs at most once per oversized command,\n // and after the first call the dir exists (mkdirSync is a no-op stat).\n mkdirSync(dir, { recursive: true });\n sweepOldSpoolFiles(dir);\n const stamp = new Date().toISOString().replace(/[:.]/g, '-');\n const rand = Math.random().toString(36).slice(2, 6);\n filePath = path.join(dir, `${stamp}-${safeTool}-${rand}.log`);\n stream = createWriteStream(filePath, { flags: 'w', encoding: 'utf8' });\n stream.on('error', () => {\n // Disk full / permission \u2014 disable the spool, keep the tool alive.\n failed = true;\n stream = null;\n filePath = null;\n });\n // Flush the buffered head first so the file is the complete output.\n stream.write(head);\n } catch {\n failed = true;\n stream = null;\n filePath = null;\n }\n };\n\n return {\n write(text: string): void {\n if (finalized || !text) return;\n totalBytes += Buffer.byteLength(text, 'utf8');\n if (!stream && !failed) {\n if (headBytes + text.length <= threshold) {\n head += text;\n headBytes += text.length;\n return;\n }\n head += text; // include the crossing chunk so the file misses nothing\n open();\n head = ''; // flushed into the stream by open(); release the heap copy\n return;\n }\n if (stream) {\n if (stream.writableLength > SPOOL_WRITE_HWM_BYTES) {\n droppedBytes += Buffer.byteLength(text, 'utf8');\n return;\n }\n stream.write(text);\n }\n },\n finalize(): SpoolInfo | null {\n if (finalized) {\n return filePath ? { path: filePath, bytes: totalBytes, droppedBytes } : null;\n }\n finalized = true;\n head = '';\n if (!stream || !filePath) return null;\n try {\n stream.end();\n } catch {\n /* already closed */\n }\n return { path: filePath, bytes: totalBytes, droppedBytes };\n },\n };\n}\n", "/**\n * ProcessRegistry \u2014 global singleton that tracks all spawned child processes\n * from `bash` and `exec` tools. Enables:\n *\n * - Listing active processes (for TUI status bar)\n * - Killing individual processes or all processes (for Ctrl+C and /kill)\n * - Detecting runaway processes (hung, looping)\n * - Circuit breaker integration to prevent recursive/repeated failures\n *\n * Thread-safety: Node.js is single-threaded, but async callbacks can fire\n * in any order. All mutations go through synchronized Map methods.\n */\nimport { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport * as os from 'node:os';\nimport { CircuitBreaker, type CircuitBreakerSnapshot, type CircuitBreakerConfig } from './circuit-breaker.js';\nexport type { CircuitBreakerSnapshot, CircuitBreakerConfig } from './circuit-breaker.js';\n\nexport interface TrackedProcess {\n pid: number;\n name: string;\n /** Display-safe redacted command string \u2014 safe for logs, /ps, crash dumps.\n * Contains [REDACTED] in place of sensitive flag values. */\n command: string;\n startedAt: number;\n sessionId?: string | undefined;\n /** The raw ChildProcess handle. Never call .kill() directly on this \u2014\n * use `kill()` below which handles process groups correctly on POSIX\n * and degrades gracefully on Windows. */\n child: ChildProcess;\n /** True only when this child was spawned as a POSIX process-group/session\n * leader (for example `spawn(..., { detached: true })`) and `pid` is the\n * actual `child.pid`. Negative-PID signaling is host-wide dangerous for\n * values like -1, so tests and manually registered entries must not opt in. */\n processGroupLeader?: boolean | undefined;\n /** True once the process has been kill()ed but not yet exited.\n * We keep it in the registry until 'close' fires so callers can\n * distinguish \"still running\" from \"just exited\". */\n killed: boolean;\n /** If true, kill() and killAll() will refuse to kill this process.\n * Used for infrastructure processes (browser, dev servers, \u2026) that\n * must outlive the agent session. */\n protected: boolean;\n /** True for an explicitly detached/background tool launch. */\n background: boolean;\n}\n\n// redactCommand (and its sensitive-flag patterns) lives in _redact-command.ts\n// so registry-only consumers (e.g. ps-slash) don't carry its dependencies.\n// Re-exported here to keep this module's historical public API intact.\nexport { redactCommand } from './_redact-command.js';\n\ninterface KillOpts {\n /** SIGKILL instead of SIGTERM. Default: false (SIGTERM first). */\n force?: boolean | undefined;\n /** MS to wait between SIGTERM and SIGKILL on POSIX. Default: 2000. */\n graceMs?: number | undefined;\n /** Leave explicitly backgrounded jobs alive. Default false. */\n preserveBackground?: boolean | undefined;\n}\n\n/**\n * Snapshot of the armed auto kill/reset countdown, or null when nothing is\n * armed. `remainingMs` ticks down in real time; the TUI statusline renders it.\n */\nexport interface BreakerCountdown {\n remainingMs: number;\n totalMs: number;\n}\n\ntype BreakerCountdownListener = (snapshot: BreakerCountdown | null) => void;\n\nexport interface RegistryStats {\n activeCount: number;\n backgroundCount: number;\n totalCount: number;\n breaker: CircuitBreakerSnapshot;\n}\n\nconst DEFAULT_GRACE_MS = 2000;\nconst WIN32_TASKKILL_TIMEOUT_MS = 5000;\n\ninterface Win32TreeKillOptions {\n /**\n * Upper bound for taskkill itself before the caller's fallback may run.\n * This is deliberately separate from POSIX SIGTERM grace: on Windows the\n * direct-child fallback must not fire while taskkill is still walking the\n * child tree, or it can orphan grandchildren that keep stdio open.\n */\n timeoutMs?: number | undefined;\n onSettled?: (() => void) | undefined;\n}\n\n/**\n * Kill an entire process tree on Windows via `taskkill /T /F`.\n *\n * TerminateProcess (what `child.kill()` maps to) has no process-group\n * semantics, so killing a shell wrapper (`cmd.exe /c \u2026`) orphans its\n * grandchildren (node, vitest forks, dev servers). The orphans inherit the\n * parent's stdio pipe handles and can keep streaming into this process for\n * the rest of the session \u2014 which both prevents the child's 'close' event\n * from ever firing and grows in-memory output buffers without bound.\n *\n * Returns true if taskkill was spawned, false if spawning it failed (caller\n * should fall back to a direct `child.kill()`). Callers that need a direct\n * fallback should pass `onSettled`; it runs after taskkill exits, errors, or\n * exceeds `timeoutMs`, avoiding the race where killing cmd.exe first prevents\n * taskkill from enumerating and killing grandchildren.\n */\nexport function killWin32Tree(pid: number, opts: Win32TreeKillOptions = {}): boolean {\n try {\n const child = spawn('taskkill', ['/pid', String(pid), '/T', '/F'], {\n stdio: 'ignore',\n windowsHide: true,\n });\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const settle = () => {\n if (settled) return;\n settled = true;\n if (timeout) clearTimeout(timeout);\n try {\n opts.onSettled?.();\n } catch {\n /* fallback callbacks are best-effort */\n }\n };\n // spawn() reports a failure to launch (e.g. taskkill not on PATH, blocked by\n // security software) via an ASYNC 'error' event \u2014 the surrounding try/catch\n // only traps synchronous throws. Without a listener that event is unhandled\n // and crashes the whole process. Swallow it: this is best-effort tree-kill\n // and the registry still has the direct child.kill() fallback.\n child.on('error', settle);\n child.on('close', settle);\n timeout = setTimeout(() => {\n try {\n child.kill();\n } catch {\n /* already exited */\n }\n settle();\n }, Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS));\n timeout.unref?.();\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nexport class ProcessRegistryImpl {\n private readonly processes = new Map<number, TrackedProcess>();\n private readonly breaker: CircuitBreaker;\n\n /**\n * Auto kill/reset config. When the breaker trips and `autoKillResetMs > 0`,\n * a countdown is armed; on expiry all tracked processes are killed and the\n * breaker is reset to closed (forced recovery). Zero means manual recovery\n * only (`/kill reset`).\n */\n private autoKillResetMs = 0;\n private autoKillTimer: ReturnType<typeof setTimeout> | null = null;\n private autoKillArmedAt: number | null = null;\n private breakerCountdownListeners: BreakerCountdownListener[] = [];\n\n constructor(breakerConfig?: CircuitBreakerConfig) {\n this.breaker = new CircuitBreaker(breakerConfig);\n // Arm on trip, cancel on recovery. Listeners are best-effort.\n this.breaker.onTrip = () => this._armAutoKillReset();\n this.breaker.onReset = () => this._cancelAutoKillReset();\n // Protection is OFF by default \u2014 the user opts in via `/settings breaker on`.\n this.breaker.setEnabled(false);\n }\n\n register(\n info: Omit<TrackedProcess, 'killed' | 'protected' | 'background'> & {\n protected?: boolean | undefined;\n background?: boolean | undefined;\n },\n ): void {\n this.processes.set(info.pid, {\n ...info,\n killed: false,\n protected: info.protected ?? false,\n background: info.background ?? false,\n });\n }\n\n private _isSafeSignalPid(pid: number): boolean {\n return Number.isInteger(pid) && pid > 1 && pid !== process.pid && pid !== process.ppid;\n }\n\n private _canSignalProcessGroup(p: TrackedProcess): boolean {\n return (\n os.platform() !== 'win32' &&\n p.processGroupLeader === true &&\n this._isSafeSignalPid(p.pid) &&\n typeof p.child.pid === 'number' &&\n p.child.pid === p.pid\n );\n }\n\n private _killChildDirect(p: TrackedProcess, signal: NodeJS.Signals): void {\n try {\n p.child.kill(signal);\n } catch {\n // Process may have already exited, or this may be a persistent entry\n // without a live ChildProcess handle in the current process.\n }\n }\n\n private _killPosix(p: TrackedProcess, signal: NodeJS.Signals): void {\n if (this._canSignalProcessGroup(p)) {\n try {\n process.kill(-p.pid, signal);\n return;\n } catch {\n // Process group may already be gone; fall back to the direct child.\n }\n }\n this._killChildDirect(p, signal);\n }\n\n /** Unregister a process by PID. Called on 'close' / 'exit' events. */\n unregister(pid: number): void {\n this.processes.delete(pid);\n }\n\n /** Get a single process by PID. */\n get(pid: number): TrackedProcess | undefined {\n this._pruneStale(pid);\n return this.processes.get(pid);\n }\n\n /** Get all tracked processes. */\n list(): TrackedProcess[] {\n return Array.from(this.processes.values());\n }\n\n /** Get processes filtered by name (e.g. 'bash', 'exec'). */\n byName(name: string): TrackedProcess[] {\n return this.list().filter((p) => p.name === name);\n }\n\n /** Get processes filtered by session. */\n bySession(sessionId: string): TrackedProcess[] {\n return this.list().filter((p) => p.sessionId === sessionId);\n }\n\n /** Count of active (non-killed) processes. */\n get activeCount(): number {\n let n = 0;\n for (const p of this.processes.values()) {\n if (!p.killed) n++;\n }\n return n;\n }\n\n /** Count of active jobs explicitly launched in background mode. */\n get activeBackgroundCount(): number {\n let n = 0;\n for (const p of this.processes.values()) {\n if (p.background && !p.killed) n++;\n }\n return n;\n }\n\n /**\n * Combined stats for observability \u2014 used by /ps and the TUI status bar.\n */\n stats(): RegistryStats {\n return {\n activeCount: this.activeCount,\n backgroundCount: this.activeBackgroundCount,\n totalCount: this.processes.size,\n breaker: this.breaker.snapshot(),\n };\n }\n\n /**\n * Returns true if the circuit allows a new bash/exec call to proceed.\n * When false, callers MUST NOT spawn a process.\n */\n get canProceed(): boolean {\n return this.breaker.canProceed;\n }\n\n /**\n * Called before spawning a process. Returns true if allowed; false if\n * the circuit breaker is open.\n *\n * @param bypass - If true, skip circuit breaker check (for background processes).\n */\n beforeCall(bypass = false): boolean {\n return this.breaker.beforeCall(bypass);\n }\n\n /**\n * Called after a process finishes. `durationMs` is wall-clock time;\n * `failed` is true for non-zero exit codes.\n *\n * @param bypass - If true, do not update circuit breaker state (for background processes).\n */\n afterCall(durationMs: number, failed: boolean, bypass = false): void {\n this.breaker.afterCall(durationMs, failed, bypass);\n }\n\n /** Force-open the circuit breaker (Ctrl+C, /kill force). */\n forceBreakerOpen(): void {\n this.breaker.forceOpen();\n }\n\n /** Force-reset the circuit breaker to closed (/kill reset). */\n forceBreakerReset(): void {\n this.breaker.forceReset();\n }\n\n /**\n * Configure circuit-breaker protection at runtime. Called from `/settings`\n * (instant, all modes) and on TUI mount (applies persisted config).\n *\n * - `enabled` toggles whether the breaker gates `bash`/`exec`.\n * - `autoKillResetMs` arms the auto kill/reset countdown when the breaker\n * trips (0 = manual recovery only).\n *\n * Re-applies cleanly on every call: cancels a pending countdown when the\n * timeout is cleared or protection disabled, and re-arms if the breaker is\n * currently open under the new settings.\n */\n setBreakerConfig(cfg: { enabled?: boolean | undefined; autoKillResetMs?: number | undefined }): void {\n if (cfg.enabled !== undefined) this.breaker.setEnabled(cfg.enabled);\n if (cfg.autoKillResetMs !== undefined) this.autoKillResetMs = Math.max(0, cfg.autoKillResetMs);\n\n if (this.autoKillResetMs <= 0) {\n this._cancelAutoKillReset();\n return;\n }\n // If protection is active and the breaker is currently tripped, ensure a\n // countdown is armed for the new window (covers a live config change while\n // the breaker is already open).\n if (this.breaker.isEnabled && this.breaker.snapshot().state === 'open') {\n this._armAutoKillReset();\n }\n }\n\n /**\n * Live countdown to the next auto kill/reset, or null when nothing is armed.\n * The TUI polls this on a 1s tick while armed so the statusline decrements.\n */\n getBreakerCountdown(): BreakerCountdown | null {\n if (this.autoKillArmedAt === null || this.autoKillResetMs <= 0) return null;\n const elapsed = Date.now() - this.autoKillArmedAt;\n return { remainingMs: Math.max(0, this.autoKillResetMs - elapsed), totalMs: this.autoKillResetMs };\n }\n\n /**\n * Subscribe to countdown arm/cancel events. Returns an unsubscribe function.\n * Use {@link getBreakerCountdown} for the live ticking value between events.\n */\n onBreakerCountdownChange(listener: BreakerCountdownListener): () => void {\n this.breakerCountdownListeners.push(listener);\n return () => {\n this.breakerCountdownListeners = this.breakerCountdownListeners.filter((l) => l !== listener);\n };\n }\n\n private _emitBreakerCountdown(): void {\n const snap = this.getBreakerCountdown();\n for (const l of this.breakerCountdownListeners) {\n try {\n l(snap);\n } catch {\n /* listener failure must never affect breaker behavior */\n }\n }\n }\n\n /**\n * Arm the auto kill/reset countdown. Idempotent: re-arming resets the window\n * (a fresh trip after a failed half-open probe restarts the clock). No-op\n * when protection is off or no timeout is configured.\n */\n private _armAutoKillReset(): void {\n if (this.autoKillResetMs <= 0 || !this.breaker.isEnabled) return;\n this._clearAutoKillTimer();\n this.autoKillArmedAt = Date.now();\n this.autoKillTimer = setTimeout(() => {\n this.autoKillTimer = null;\n this.autoKillArmedAt = null;\n // Forced recovery: nuke runaway processes and reopen the circuit.\n this.killAll({ force: false, preserveBackground: true });\n this.breaker.forceReset();\n this._emitBreakerCountdown();\n }, this.autoKillResetMs);\n // Don't keep the event loop alive purely for auto-recovery.\n this.autoKillTimer.unref?.();\n this._emitBreakerCountdown();\n }\n\n private _cancelAutoKillReset(): void {\n const wasArmed = this.autoKillArmedAt !== null;\n this._clearAutoKillTimer();\n if (wasArmed) {\n this.autoKillArmedAt = null;\n this._emitBreakerCountdown();\n }\n }\n\n private _clearAutoKillTimer(): void {\n if (this.autoKillTimer !== null) {\n clearTimeout(this.autoKillTimer);\n this.autoKillTimer = null;\n }\n }\n\n /** Kill a single process by PID.\n *\n * On POSIX: sends SIGTERM to the *process group* (-pid) so that\n * runaway grandchild processes (`sleep 9999 & disown`) are also killed.\n * After `graceMs` a SIGKILL is sent if the process hasn't exited.\n *\n * On Windows: `child.kill()` maps to TerminateProcess \u2014 process groups\n * are not meaningfully supported. A second `force=true` call sends\n * SIGKILL (which maps to TerminateProcess again \u2014 the distinction is\n * in the exit code, not the signal).\n *\n * Returns true if the process was found and kill was attempted.\n */\n kill(pid: number, opts: KillOpts = {}): boolean {\n this._pruneStale(pid);\n const p = this.processes.get(pid);\n if (!p) return false;\n if (p.killed) return true; // already kill()ed, don't double-send\n if (p.protected) return false; // protected processes are never kill()ed\n if (opts.preserveBackground && p.background) return false;\n\n const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;\n const isWin = os.platform() === 'win32';\n\n if (isWin) {\n // Windows: no process group semantics. A direct kill terminates only\n // the immediate child \u2014 shell-wrapped commands (cmd.exe /c \u2026) leave\n // grandchildren running that hold the inherited stdio pipes open and\n // keep feeding output into this process indefinitely. Kill the whole\n // tree via taskkill instead, but only for a real, still-running child\n // (exitCode === null); test fakes and already-exited processes take\n // the plain-kill path. The direct kill is deliberately NOT sent\n // immediately alongside taskkill: killing the root first would break\n // taskkill's parent-pid tree enumeration and orphan the grandchildren\n // again \u2014 it runs as a delayed fallback instead.\n const liveRealChild = p.child.exitCode === null && typeof p.child.pid === 'number';\n const directFallback = () => {\n if (p.child.exitCode === null) {\n try {\n p.child.kill('SIGKILL');\n } catch {\n // Process may have already exited.\n }\n }\n };\n if (\n liveRealChild &&\n killWin32Tree(pid, {\n timeoutMs: Math.max(graceMs, WIN32_TASKKILL_TIMEOUT_MS),\n onSettled: directFallback,\n })\n ) {\n // The direct fallback is intentionally chained from taskkill's\n // completion. Killing cmd.exe before taskkill has walked the tree can\n // orphan the real command and leave stdio pipes open forever.\n } else {\n try {\n p.child.kill(force ? 'SIGKILL' : 'SIGTERM');\n } catch {\n // Process may have already exited.\n }\n }\n p.killed = true;\n return true;\n }\n\n // POSIX: kill the process group only when the tracked child is proven to\n // be the group leader. Otherwise use child.kill(); negative PID signaling\n // with untrusted/fake PIDs can target unrelated host processes.\n try {\n if (force) {\n this._killPosix(p, 'SIGKILL');\n } else {\n this._killPosix(p, 'SIGTERM');\n // Schedule SIGKILL as backup.\n const timer = setTimeout(() => {\n // Re-check: process may have exited on its own.\n if (this.processes.has(pid) && !p.child.killed) {\n this._killPosix(p, 'SIGKILL');\n }\n }, graceMs);\n timer.unref?.(); // Don't keep event loop alive.\n }\n } catch {\n // Process may have already exited.\n }\n p.killed = true;\n return true;\n }\n\n /**\n * Kill all tracked processes.\n * Returns the PIDs that were kill()ed.\n */\n killAll(opts: KillOpts = {}): number[] {\n const pids = Array.from(this.processes.keys());\n const killed: number[] = [];\n for (const pid of pids) {\n const p = this.processes.get(pid);\n if (p && !p.protected && this.kill(pid, opts)) killed.push(pid);\n }\n return killed;\n }\n\n /**\n * Kill all processes for a specific session.\n * Returns the PIDs that were kill()ed.\n */\n killSession(sessionId: string, opts: KillOpts = {}): number[] {\n const pids = this.bySession(sessionId).map((p) => p.pid);\n const killed: number[] = [];\n for (const pid of pids) {\n if (this.kill(pid, opts)) killed.push(pid);\n }\n return killed;\n }\n\n /**\n * Check whether a tracked process entry is stale \u2014 the child has exited\n * (exitCode !== null) AND it's been in the registry long enough that the\n * OS may have reused the PID for a new, unrelated process.\n *\n * P3 #24 (before-release.md): on POSIX, PIDs are reused after process\n * exit. If a tracked process exits but its 'close' event hasn't fired yet\n * (or was missed), the registry still holds the entry. A new process\n * gets the same PID, and PID-based lookups (get, kill, shouldBlockKill)\n * may incorrectly protect or target the wrong process.\n *\n * The 60s threshold is conservative \u2014 the OS typically waits much longer\n * before reusing a PID, but we want to clean up before that becomes a risk.\n */\n private _isStaleEntry(entry: TrackedProcess): boolean {\n return entry.child.exitCode !== null && Date.now() - entry.startedAt > 60_000;\n }\n\n /**\n * Remove a stale entry for a specific PID before any PID-based lookup.\n * This prevents PID reuse from causing the registry to act on a dead\n * process that has been replaced by a new one with the same PID.\n */\n private _pruneStale(pid: number): void {\n const entry = this.processes.get(pid);\n if (entry && this._isStaleEntry(entry)) {\n this.processes.delete(pid);\n }\n }\n}\n\n/** Module-level singleton. Initialized on first access. */\nlet _registry: ProcessRegistryImpl | undefined;\n\nexport function getProcessRegistry(): ProcessRegistryImpl {\n if (!_registry) {\n _registry = new ProcessRegistryImpl();\n }\n return _registry;\n}\n\n/** Reset for tests. */\nexport function _resetProcessRegistry(): void {\n _registry = undefined;\n}\n\n// \u2500\u2500 Convenience re-exports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type { KillOpts };\n", "/**\n * CircuitBreaker \u2014 prevents runaway bash/exec tool chains by:\n *\n * - Tripping on consecutive failures (models that keep repeating the\n * same failing command, e.g. `npm install` with wrong args in a loop)\n * - Tripping on slow call ratio (too many long-running commands suggest\n * a hung subprocess that the model doesn't know how to kill)\n * - Rate-limiting bursts (rapid succession of commands without reading\n * output suggests the model isn't processing results)\n * - Auto-recovering after a cooldown period so a fixed model can resume\n *\n * The breaker is owned by the ProcessRegistry so any tool that registers\n * a process participates in the same circuit. \"Per-tool\" isolation is\n * intentionally NOT implemented \u2014 the model treats bash/exec as one\n * resource pool; isolating them would let the model route around the\n * breaker by alternating which tool it uses.\n */\n\nexport interface CircuitBreakerConfig {\n /**\n * Consecutive failures before trip. Default: 5.\n * A single success resets this counter to 0.\n */\n maxConsecutiveFailures?: number | undefined;\n /**\n * Slow-call threshold in ms. A call that runs longer than this is\n * counted as \"slow\". Default: 60_000 (1 minute).\n */\n slowCallThresholdMs?: number | undefined;\n /**\n * Max slow calls before trip (within the sliding window). Default: 3.\n */\n maxSlowCalls?: number | undefined;\n /**\n * Sliding window for rate-limit and slow-call counting, in ms.\n * Default: 60_000 (1 minute).\n */\n windowMs?: number | undefined;\n /**\n * Max calls within the sliding window. Default: 30.\n * Burst exceeding this trips the breaker immediately.\n */\n maxCallsPerWindow?: number | undefined;\n /**\n * Cooldown before auto-recovery attempt, in ms. Default: 30_000 (30s).\n * After this the breaker enters \"half-open\" state and allows one call\n * through to test whether the problem is resolved.\n */\n cooldownMs?: number | undefined;\n}\n\ninterface CallRecord {\n at: number;\n /** True if the call threw or returned an is_error result. */\n failed: boolean;\n /** True if elapsed time exceeded slowCallThresholdMs. */\n slow: boolean;\n}\n\ntype BreakerState = 'closed' | 'open' | 'half-open';\n\nconst DEFAULT_MAX_CONSECUTIVE_FAILURES = 5;\nconst DEFAULT_SLOW_CALL_THRESHOLD_MS = 180_000;\n// 3 minutes \u2014 balanced against the 5-minute bash timeout. Commands\n// running <3min are normal; 3-5min are \"slow\" and count toward the\n// breaker. 3 consecutive slow calls trip the circuit.\nconst DEFAULT_MAX_SLOW_CALLS = 3;\nconst DEFAULT_WINDOW_MS = 60_000;\nconst DEFAULT_MAX_CALLS_PER_WINDOW = 30;\nconst DEFAULT_COOLDOWN_MS = 30_000;\n\nexport interface CircuitBreakerSnapshot {\n state: 'closed' | 'open' | 'half-open';\n consecutiveFailures: number;\n slowCallsInWindow: number;\n callsInWindow: number;\n windowMs: number;\n cooldownRemainingMs: number | null;\n lastFailureAt: number | null;\n lastSlowAt: number | null;\n}\n\nexport class CircuitBreaker {\n private readonly maxConsecutiveFailures: number;\n private readonly slowCallThresholdMs: number;\n private readonly maxSlowCalls: number;\n private readonly windowMs: number;\n private readonly maxCallsPerWindow: number;\n private readonly cooldownMs: number;\n\n private state: BreakerState = 'closed';\n private consecutiveFailures = 0;\n private window: CallRecord[] = [];\n private lastFailureAt: number | null = null;\n private lastSlowAt: number | null = null;\n /** Timestamp when the breaker was opened (for cooldown calculation). */\n private openedAt: number | null = null;\n\n /**\n * Master enable flag. When false the breaker is bypassed: `beforeCall`\n * always returns true and `afterCall` records nothing. The class itself\n * defaults to enabled (so the standalone unit tests exercise tripping); the\n * ProcessRegistry flips this off until the user opts in via `/settings`.\n */\n private enabled = true;\n\n /**\n * Fired (best-effort) when the breaker transitions into the `open` state.\n * The registry uses this to arm its auto kill/reset countdown.\n */\n onTrip?: (() => void) | undefined;\n /**\n * Fired (best-effort) when the breaker returns to `closed` after having been\n * open/half-open. The registry uses this to cancel a pending kill/reset.\n */\n onReset?: (() => void) | undefined;\n\n constructor(config: CircuitBreakerConfig = {}) {\n this.maxConsecutiveFailures = config.maxConsecutiveFailures ?? DEFAULT_MAX_CONSECUTIVE_FAILURES;\n this.slowCallThresholdMs = config.slowCallThresholdMs ?? DEFAULT_SLOW_CALL_THRESHOLD_MS;\n this.maxSlowCalls = config.maxSlowCalls ?? DEFAULT_MAX_SLOW_CALLS;\n this.windowMs = config.windowMs ?? DEFAULT_WINDOW_MS;\n this.maxCallsPerWindow = config.maxCallsPerWindow ?? DEFAULT_MAX_CALLS_PER_WINDOW;\n this.cooldownMs = config.cooldownMs ?? DEFAULT_COOLDOWN_MS;\n }\n\n /** Toggle the master enable. Disabling resets to a clean `closed` state. */\n setEnabled(enabled: boolean): void {\n if (this.enabled === enabled) return;\n this.enabled = enabled;\n if (!enabled) this._reset();\n }\n\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Returns true if the circuit allows a new call to proceed.\n * When false, callers should abort the tool call and return a\n * circuit-breaker error instead of spawning a process.\n */\n get canProceed(): boolean {\n if (!this.enabled) return true;\n this._checkStateTransition();\n return this.state !== 'open';\n }\n\n /**\n * Snapshot of the current breaker state for observability (`/kill`).\n */\n snapshot(): CircuitBreakerSnapshot {\n this._checkStateTransition();\n const now = Date.now();\n let cooldownRemaining: number | null = null;\n if (this.openedAt !== null && this.state === 'open') {\n const elapsed = now - this.openedAt;\n cooldownRemaining = Math.max(0, this.cooldownMs - elapsed);\n }\n return {\n state: this.state,\n consecutiveFailures: this.consecutiveFailures,\n slowCallsInWindow: this.window.filter((c) => c.slow).length,\n callsInWindow: this.window.length,\n windowMs: this.windowMs,\n cooldownRemainingMs: cooldownRemaining,\n lastFailureAt: this.lastFailureAt,\n lastSlowAt: this.lastSlowAt,\n };\n }\n\n /**\n * Call this BEFORE spawning a bash/exec process.\n * Returns true if the call is allowed; false if the breaker is open.\n * When false, callers MUST NOT spawn a process.\n *\n * @param bypass - If true, skip the circuit breaker check entirely.\n * Use for background/fire-and-forget processes that should\n * not affect breaker state.\n */\n beforeCall(bypass = false): boolean {\n if (bypass || !this.enabled) return true;\n this._checkStateTransition();\n if (this.state === 'open') return false;\n return true;\n }\n\n /**\n * Call this AFTER a bash/exec process finishes (success or failure).\n * `durationMs` is the wall-clock time the process ran.\n * `failed` is true when the process returned a non-zero exit code or\n * threw an exception before spawning.\n *\n * @param bypass - If true, do not update breaker state.\n * Use for background/fire-and-forget processes.\n */\n afterCall(durationMs: number, failed: boolean, bypass = false): void {\n if (bypass || !this.enabled) return;\n\n const now = Date.now();\n\n if (this.state === 'half-open') {\n // First call through after cooldown \u2014 if it failed, go back to open.\n if (failed) {\n this._trip();\n return;\n }\n // Success in half-open \u2192 reset to closed.\n this._reset();\n return;\n }\n\n // Prune old records outside the sliding window.\n this._pruneWindow(now);\n\n const slow = durationMs >= this.slowCallThresholdMs;\n this.window.push({ at: now, failed, slow });\n\n if (failed) {\n this.consecutiveFailures++;\n this.lastFailureAt = now;\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n this._trip();\n }\n return;\n }\n\n // Success: reset consecutive failure counter.\n this.consecutiveFailures = 0;\n\n if (slow) {\n this.lastSlowAt = now;\n const slowCount = this.window.filter((c) => c.slow).length;\n if (slowCount >= this.maxSlowCalls) {\n this._trip();\n }\n }\n\n const callCount = this.window.length;\n if (callCount >= this.maxCallsPerWindow) {\n // Rate limit exceeded. This is a soft trip \u2014 we reset the window\n // and let the next call try immediately (the caller will still see\n // canProceed=false until the window drains naturally).\n this._trip();\n }\n }\n\n /** Force the breaker open. Used by /kill force and Ctrl+C. */\n forceOpen(): void {\n this._trip();\n }\n\n /** Force a reset to closed. Used by tests and /kill reset. */\n forceReset(): void {\n this._reset();\n }\n\n private _trip(): void {\n if (this.state === 'open') return; // already open\n this.state = 'open';\n this.openedAt = Date.now();\n // P3 #23 (before-release.md): clear the window on trip. Old records are\n // irrelevant once tripped \u2014 the breaker starts fresh after cooldown\n // (half-open \u2192 closed resets the counters). Without this the window array\n // holds onto CallRecord entries for its lifetime if no new afterCall()\n // arrives (which is the case when the breaker stays open and no new calls\n // are attempted).\n this.window = [];\n // Best-effort: never let a listener failure corrupt breaker state.\n try {\n this.onTrip?.();\n } catch {\n /* ignored \u2014 observability hook only */\n }\n }\n\n private _reset(): void {\n const wasRecovering = this.state !== 'closed';\n this.state = 'closed';\n this.consecutiveFailures = 0;\n this.window = [];\n this.openedAt = null;\n // Only notify on a real recovery (open/half-open \u2192 closed), not on the\n // initial closed state or an idempotent re-reset.\n if (wasRecovering) {\n try {\n this.onReset?.();\n } catch {\n /* ignored \u2014 observability hook only */\n }\n }\n }\n\n /** Transition from open \u2192 half-open when cooldown elapses. */\n private _checkStateTransition(): void {\n if (this.state !== 'open' || this.openedAt === null) return;\n const elapsed = Date.now() - this.openedAt;\n if (elapsed >= this.cooldownMs) {\n this.state = 'half-open';\n this.openedAt = null;\n }\n }\n\n private _pruneWindow(now: number): void {\n const cutoff = now - this.windowMs;\n this.window = this.window.filter((c) => c.at >= cutoff);\n }\n}", "import { expectDefined } from '@wrongstack/core/utils';\n\n// Sensitive CLI flag patterns that may appear in process command lines.\n// Redacted to [REDACTED] so crash dumps /ps output cannot leak secrets.\n// Split out of process-registry.ts so entries that only need the registry\n// (e.g. ps-slash) don't carry this module's dependencies.\n//\n// NOTE: @wrongstack/core carries its own copy (observability/redact-command.ts)\n// so the emitProcessStarted telemetry producer can redact command+args\n// centrally. Keep these two copies in sync when updating the patterns.\nconst SENSITIVE_FLAG_PATTERNS: RegExp[] = [\n // --flag=value or --flag \"value\" (value captured up to next space or comma)\n /--(?:token|password|passwd|pwd|secret|api[-_]?key|api[-_]?secret|auth|credential|private[-_]?key|access[-_]?key|github[-_]?token|gh[-_]?token|bearer|jwt|oauth|pin|pincode|passphrase|access[-_]?token)(?:[=\\s,][^\\s]*)?/gi,\n // -t short flag (token): attached (-tVALUE), separated (-t VALUE), or -t=VALUE.\n // (?<![-\\w]) anchors to a token start so we don't match the `-t` inside `--token`.\n // NOTE: synced with @wrongstack/core observability/redact-command.ts.\n /(?<![-\\w])-t(?:[=\\s]+)?[^\\s,-]+/,\n // -p|-password|-a (redis auth) short flags: attached + separated + =value.\n // Same token-start anchor; over-redaction is an accepted tradeoff for a\n // redaction function. Synced with core copy.\n /(?<![-\\w])-(?:password|p|a)(?:[=\\s]+)?[^\\s,-]+/gi,\n // env var\u2013style secrets: TOKEN=x, API_KEY=y, etc.\n /(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\\s*[=:]\\s*[^\\s,]+/gi,\n // Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits \u2014 but only\n // when preceded by a flag name (e.g. --github-token=EyJ...).\n /--\\w*(?:token|key|secret|password|passwd|auth|credential)\\w*[=\\s,][A-Za-z0-9+/=]{32,}/,\n];\n\n/**\n * Returns a display-safe copy of `cmd` with sensitive flag values replaced by [REDACTED].\n * The original string is unchanged; this is pure and has no side effects.\n */\nexport function redactCommand(cmd: string): string {\n let result = cmd;\n for (const pattern of SENSITIVE_FLAG_PATTERNS) {\n result = result.replace(pattern, (match) => {\n // Preserve the flag name portion; redact only the value part.\n // e.g. \"--token=sekrit_abc\" \u2192 \"--token=[REDACTED]\"\n const eq = match.indexOf('=');\n const sp = match.search(/\\s/);\n const delim = eq !== -1 ? '=' : sp !== -1 ? match[sp] : null;\n if (delim !== null) {\n const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);\n return `${flag}[REDACTED]`;\n }\n // No delimitable separator found in the match.\n if (match.startsWith('--')) {\n // Long flag with no value attached (e.g. a bare \"--token\" argv token).\n // No secret here \u2014 leave it untouched so downstream pair-scan can still\n // recognize the bare flag. NOTE: keep this synced with\n // @wrongstack/core observability/redact-command.ts.\n return match;\n }\n // Short flag attached form (-pVALUE, -tVALUE, -aVALUE): flag name is the\n // leading -X (2 chars); redact everything after. Don't use a greedy\n // [a-zA-Z0-9_-]* flag-name match \u2014 value chars would be consumed into the\n // flag name and the secret would survive. Synced with core copy.\n return `${match.slice(0, 2)}[REDACTED]`;\n });\n }\n return result;\n}\n", "import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * On Windows, Node.js `spawn()` without a shell does NOT resolve .cmd/.bat\n * extensions through PATHEXT \u2014 it only auto-resolves .exe. Most Node.js CLI\n * tools (npx, pnpm, biome, tsc, vitest, etc.) ship as .cmd wrappers on\n * Windows. This function resolves the command name to its full path so spawn\n * can find it without relying on shell-mode argument concatenation.\n *\n * On non-Windows, returns the command unchanged.\n */\nexport function resolveWin32Command(cmd: string): string {\n if (process.platform !== 'win32') return cmd;\n\n // Already has a path or extension \u2014 use as-is\n // Normalize forward slashes so path.extname correctly detects extensions\n // even when a Unix-style path is passed on Windows.\n if (cmd.includes('/') || cmd.includes('\\\\') || path.extname(cmd.replace(/\\//g, '\\\\'))) {\n return cmd;\n }\n\n const pathext = (process.env['PATHEXT'] ?? '.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC')\n .toLowerCase()\n .split(';');\n\n const pathDirs = (process.env['PATH'] ?? '').split(path.delimiter);\n\n for (const dir of pathDirs) {\n const base = path.join(dir, cmd);\n // Check extensions in PATHEXT order. .EXE should win first because\n // it's typically listed first, and .exe doesn't need shell: true.\n for (const ext of pathext) {\n const full = `${base}${ext}`;\n try {\n fs.accessSync(full, fs.constants.X_OK);\n return full;\n } catch {\n // Not found with this extension \u2014 try next\n }\n }\n }\n\n // Not found \u2014 return original; let spawn report ENOENT with the\n // expected error message so tools can surface it properly.\n return cmd;\n}\n\n/**\n * Resolve a PowerShell binary by name. `pickShell` in `_shell-pick.ts`\n * already decides whether the user wants `'pwsh'` (PowerShell 7+) or\n * `'powershell'` (Windows PowerShell 5.1). This helper turns that decision\n * into a real on-disk path.\n *\n * Order:\n * 1. If `cmd` is `pwsh` and a `pwsh.exe` exists on PATH \u2192 return that.\n * 2. If `cmd` is `pwsh` and only `powershell.exe` exists \u2192 fall back to\n * that (the alternative is a cryptic ENOENT for the user).\n * 3. Symmetric for `powershell`: prefer `powershell.exe`, fall back to\n * `pwsh.exe` if installed and the legacy binary is missing.\n * 4. Anything else \u2192 delegate to `resolveWin32Command` (handles `.cmd`\n * shims a sysadmin might drop in place, etc.).\n *\n * Returns the original command on ENOENT \u2014 `spawn()` will surface a clean\n * ENOENT and the user sees \"PowerShell not installed\", which is the right\n * diagnostic. We never throw from here.\n */\nexport function resolvePowerShell(cmd: string): string {\n if (process.platform !== 'win32') return cmd;\n const lower = cmd.toLowerCase();\n if (lower !== 'pwsh' && lower !== 'powershell' && lower !== 'pwsh.exe' && lower !== 'powershell.exe') {\n return resolveWin32Command(cmd);\n }\n // Prefer the requested edition, fall back to the other one.\n const primary = lower.startsWith('pwsh') ? 'pwsh.exe' : 'powershell.exe';\n const fallback = lower.startsWith('pwsh') ? 'powershell.exe' : 'pwsh.exe';\n const resolved = resolveWin32Command(primary);\n if (resolved !== primary) {\n // resolveWin32Command returns the original string when not found.\n const fb = resolveWin32Command(fallback);\n return fb === fallback ? cmd : fb;\n }\n return resolved;\n}\n\n/**\n * cmd.exe metacharacters that chain a new command or redirect I/O. When a\n * `.cmd`/`.bat` wrapper is launched through `cmd.exe`, any argument carrying\n * one of these can break out of the intended command line and run an\n * attacker-chosen command (the CVE-2024-27980 / \"BatBadBut\" argument-injection\n * class). We use a single vetted command line for cmd shims, so this guard is\n * mandatory before spawning.\n *\n * The set is limited to the unambiguous command-separator / redirection chars\n * plus newlines and NUL. Legitimate package-manager / test-runner flags and\n * Windows file paths (which use `:` `\\` `/` `.` `-` `_` space `(` `)`) never\n * contain these, so the guard is false-positive-free. Double quotes are also\n * rejected because cmd.exe quote toggling can break argument grouping.\n */\nconst WIN32_SHELL_META = /[&|<>\"\\r\\n\\0]/;\n\nexport interface Win32CmdShimInvocation {\n command: string;\n args: string[];\n windowsVerbatimArguments: true;\n}\n\n/**\n * Throw if any argument contains a cmd.exe command-injection metacharacter.\n * Call this ONLY on the Windows `.cmd`/`.bat` shim path. A no-op for safe args.\n */\nexport function assertSafeWin32ShellArgs(args: readonly unknown[]): void {\n for (const arg of args) {\n if (typeof arg === 'string' && WIN32_SHELL_META.test(arg)) {\n throw new Error(\n 'win32 cmd shim spawn: argument contains a shell metacharacter ' +\n '(one of & | < > \", or a newline) that could enable command injection ' +\n 'through the .cmd/.bat wrapper - refusing to run. Offending argument: ' +\n JSON.stringify(arg),\n );\n }\n }\n}\n\nexport function buildWin32CmdShimInvocation(\n command: string,\n args: readonly string[] = [],\n): Win32CmdShimInvocation {\n assertSafeWin32ShellArgs([command, ...args]);\n const line = ['call', quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(' ');\n return {\n command: process.env['COMSPEC'] ?? 'cmd.exe',\n args: ['/d', '/c', line],\n windowsVerbatimArguments: true,\n };\n}\n\nfunction quoteWin32CmdArg(arg: string): string {\n return `\"${arg}\"`;\n}\n", "import { createHash } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as Core from '@wrongstack/core/utils';\nimport type { Context } from '@wrongstack/core/agent';\n\n/**\n * sha-256 hex of a UTF-8 string. Used by the file tools to record a content\n * hash alongside the mtime in `ctx.recordRead` \u2014 the hash is the authoritative\n * staleness arbiter for `edit` (mtime has a 2 s tolerance window on Windows).\n */\nexport function sha256hex(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex');\n}\n/** Detected package manager for a project directory. */\nexport type PackageManager = 'pnpm' | 'yarn' | 'npm';\n\n/**\n * Detect the project's package manager by inspecting lockfiles in `cwd`.\n * Order: pnpm \u2192 yarn \u2192 npm (default). Missing or unreadable directories fall\n * back to `npm` rather than throwing, so a `safeResolve`-checked cwd that\n * happens to be empty never aborts the tool.\n */\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const { stat } = await import('node:fs/promises');\n try {\n await stat(`${cwd}/pnpm-lock.yaml`);\n return 'pnpm';\n } catch {\n /* not pnpm */\n }\n try {\n await stat(`${cwd}/yarn.lock`);\n return 'yarn';\n } catch {\n /* not yarn */\n }\n return 'npm';\n}\n\nexport function resolvePath(input: string, ctx: Context): string {\n return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.workingDir ?? ctx.cwd, input);\n}\n\n/**\n * Roots every file tool may always reach, even in restricted mode: the\n * project root and the user-global `~/.wrongstack` directory (config, memory,\n * sessions, skills). `~/.wrongstack` honors the `WRONGSTACK_HOME` override.\n */\nfunction allowedRoots(ctx: Context): string[] {\n return [path.resolve(ctx.projectRoot), path.resolve(Core.wstackGlobalRoot())];\n}\n\n/** True if `target` is `root` itself or nested inside any of `roots`. */\nfunction isInsideAny(target: string, roots: string[]): boolean {\n return roots.some((root) => {\n const rel = path.relative(root, target);\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n });\n}\n\nexport function ensureInsideRoot(absPath: string, ctx: Context): string {\n const target = path.resolve(absPath);\n // Unrestricted filesystem access: skip the project-root containment check.\n if (ctx.allowOutsideProjectRoot) return target;\n if (isInsideAny(target, allowedRoots(ctx))) return target;\n throw new Error(`Path \"${absPath}\" is outside project root \"${path.resolve(ctx.projectRoot)}\"`);\n}\n\nexport function safeResolve(input: string, ctx: Context): string {\n return ensureInsideRoot(resolvePath(input, ctx), ctx);\n}\n\n/**\n * Defense against in-root\u2192out-of-root symlink escape (CWE-59). `safeResolve`\n * only does a syntactic `../` check, so a symlink that lives *inside* the\n * project root but points outside still passes it. This resolves the path\n * through `fs.realpath` and re-verifies containment against the realpath of\n * the project root (comparing like-for-like, since the root itself may be a\n * symlink \u2014 macOS `/var`\u2192`/private/var`, Windows 8.3 short names). For a path\n * that does not exist yet (e.g. a `write` to a new file) the nearest existing\n * ancestor directory is checked instead. Throws if the real target escapes.\n *\n * Mirrors the per-file guard already used in `replace.ts`/`grep.ts`; applied\n * to single-file `read`/`edit`/`write` it throws (rather than skips) because\n * the caller named exactly one file.\n */\nexport async function assertRealInsideRoot(absPath: string, ctx: Context): Promise<void> {\n // Unrestricted filesystem access: no symlink-escape check to perform.\n if (ctx.allowOutsideProjectRoot) return;\n // Compare like-for-like against the realpath of each always-allowed root\n // (project root + ~/.wrongstack), since a root may itself be a symlink.\n const realRoots = await Promise.all(\n allowedRoots(ctx).map((r) => fsp.realpath(r).catch(() => path.resolve(r))),\n );\n let probe = absPath;\n for (;;) {\n let real: string;\n try {\n real = await fsp.realpath(probe);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const parent = path.dirname(probe);\n if (parent === probe) return; // reached fs root without escaping\n probe = parent;\n continue;\n }\n throw err;\n }\n if (isInsideAny(real, realRoots)) return;\n throw new Error(\n `Path \"${absPath}\" resolves through a symlink outside project root \"${realRoots[0]}\"`,\n );\n }\n}\n\n/** `safeResolve` + symlink realpath containment check. Async. */\nexport async function safeResolveReal(input: string, ctx: Context): Promise<string> {\n const abs = safeResolve(input, ctx);\n await assertRealInsideRoot(abs, ctx);\n return abs;\n}\n\nexport function truncateMiddle(s: string, max: number): string {\n if (Buffer.byteLength(s, 'utf8') <= max) return s;\n const half = Math.floor(max / 2);\n return (\n s.slice(0, half) +\n `\\n\u2026[truncated ${Buffer.byteLength(s, 'utf8') - max} bytes from middle]\u2026\\n` +\n s.slice(-half)\n );\n}\n\nexport function isBinaryBuffer(buf: Buffer): boolean {\n const len = Math.min(buf.length, 8192);\n for (let i = 0; i < len; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n}\n\n// \u2500\u2500\u2500 Command-output normalization (token-saving) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Raw process output is full of tokens the model gains nothing from: ANSI\n// escapes, carriage-return progress spam, runs of identical warning lines, and\n// huge tails of build noise. These helpers strip that noise before the output\n// reaches the LLM. They are scoped to COMMAND tools (bash/git/exec and the\n// _spawn-stream consumers) \u2014 never applied to structured/code outputs.\n\n/** Unified byte cap for all command tool output fed to the model. */\nexport const COMMAND_OUTPUT_MAX_BYTES = 32_768;\n\n/** Runs of >= this many identical consecutive lines are collapsed. */\nconst REPEAT_RUN_THRESHOLD = 3;\n\n/**\n * Collapse carriage-return overwrites the way a terminal would: `\\r\\n` becomes\n * `\\n`, and a bare `\\r` (progress redraw) keeps only the text after the LAST\n * `\\r` on its physical line. Without this, a single progress bar that redraws\n * 200 times explodes into 200 lines.\n */\nexport function collapseCarriageReturns(text: string): string {\n const lf = text.replace(/\\r\\n/g, '\\n');\n if (!lf.includes('\\r')) return lf;\n return lf\n .split('\\n')\n .map((line) => (line.includes('\\r') ? line.slice(line.lastIndexOf('\\r') + 1) : line))\n .join('\\n');\n}\n\n/**\n * Collapse a run of `minRun`+ identical consecutive lines into the line once\n * plus a marker. Consecutive-only \u2014 it never reorders or dedups non-adjacent\n * lines, so diffs/source stay intact.\n */\nexport function collapseConsecutiveDuplicates(text: string, minRun = REPEAT_RUN_THRESHOLD): string {\n const lines = text.split('\\n');\n const out: string[] = [];\n let i = 0;\n while (i < lines.length) {\n let j = i + 1;\n while (j < lines.length && lines[j] === lines[i]) j++;\n const run = j - i;\n if (run >= minRun) {\n out.push(lines[i]!, `\u2026 \u27E8repeated ${run}\u00D7\u27E9`);\n } else {\n for (let k = i; k < j; k++) out.push(lines[k]!);\n }\n i = j;\n }\n return out.join('\\n');\n}\n\n/** Largest prefix of `s` whose UTF-8 byte length is <= `maxBytes`. */\nfunction takeHeadBytes(s: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n /* v8 ignore next -- only caller (truncateHeadTail) passes a budget smaller than s; defensive. */\n if (Buffer.byteLength(s, 'utf8') <= maxBytes) return s;\n let lo = 0;\n let hi = s.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (Buffer.byteLength(s.slice(0, mid), 'utf8') <= maxBytes) lo = mid;\n else hi = mid - 1;\n }\n return s.slice(0, lo);\n}\n\n/** Largest suffix of `s` whose UTF-8 byte length is <= `maxBytes`. */\nfunction takeTailBytes(s: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n /* v8 ignore next -- only caller (truncateHeadTail) passes a budget smaller than s; defensive. */\n if (Buffer.byteLength(s, 'utf8') <= maxBytes) return s;\n let lo = 0;\n let hi = s.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (Buffer.byteLength(s.slice(s.length - mid), 'utf8') <= maxBytes) lo = mid;\n else hi = mid - 1;\n }\n return s.slice(s.length - lo);\n}\n\n/**\n * Truncate to `maxBytes` keeping BOTH ends \u2014 the head (what ran / early context)\n * and the tail (errors and summaries usually land last), biased ~45/55 toward\n * the tail. The result never exceeds `maxBytes`.\n */\nexport function truncateHeadTail(s: string, maxBytes: number): string {\n const total = Buffer.byteLength(s, 'utf8');\n if (total <= maxBytes) return s;\n // Reserve a fixed allowance for the marker so the final string can't exceed\n // the cap even though the dropped-byte count's digit width varies.\n const MARKER_RESERVE = 64;\n const avail = Math.max(0, maxBytes - MARKER_RESERVE);\n const headBudget = Math.floor(avail * 0.45);\n const head = takeHeadBytes(s, headBudget);\n const tail = takeTailBytes(s, avail - Buffer.byteLength(head, 'utf8'));\n const kept = Buffer.byteLength(head, 'utf8') + Buffer.byteLength(tail, 'utf8');\n return `${head}\\n\u2026[truncated ${total - kept} bytes]\u2026\\n${tail}`;\n}\n\n/**\n * Full token-saving pipeline for command tool output: strip ANSI \u2192 collapse\n * carriage-return progress \u2192 trim trailing whitespace \u2192 collapse identical\n * consecutive lines \u2192 squeeze blank-line runs \u2192 head+tail truncate to the cap.\n */\nexport function normalizeCommandOutput(\n raw: string,\n opts: { maxBytes?: number | undefined } = {},\n): string {\n if (!raw) return raw;\n let text = Core.stripAnsi(raw);\n text = collapseCarriageReturns(text);\n text = text.replace(/[ \\t]+$/gm, ''); // trailing whitespace per line\n text = collapseConsecutiveDuplicates(text);\n text = text.replace(/\\n{3,}/g, '\\n\\n'); // >=2 blank lines \u2192 1\n return truncateHeadTail(text, opts.maxBytes ?? COMMAND_OUTPUT_MAX_BYTES);\n}\n", "/**\n * Legacy-to-language bridge: lets `typecheck`, `lint`, `format`, `test`,\n * `install`, `audit`, and `outdated` delegate through the deterministic\n * language planner when the workspace is a non-JavaScript ecosystem\n * (Go, Rust, PHP, C#).\n *\n * When the workspace IS JavaScript/TypeScript (or has no detected\n * language marker), the bridge returns `null` and the legacy tool\n * continues on its existing code path unchanged. This preserves 100 %\n * backward compatibility for the TS/JS ecosystem where these tools\n * originated.\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nimport { executeLanguagePlan, executePackagePlan, planLanguageOperation } from './index.js';\nimport type {\n LanguageOperation,\n LanguagePackageOutcome,\n LanguageProfileId,\n LanguageRunResult,\n} from './types.js';\n\nconst NON_JS_MARKERS: ReadonlyArray<{ filename: string; language: LanguageProfileId }> = [\n { filename: 'go.mod', language: 'go' },\n { filename: 'go.work', language: 'go' },\n { filename: 'Cargo.toml', language: 'rust' },\n { filename: 'composer.json', language: 'php' },\n];\n\nconst NON_JS_SUFFIXES: ReadonlyArray<{ suffix: string; language: LanguageProfileId }> = [\n { suffix: '.csproj', language: 'csharp' },\n { suffix: '.fsproj', language: 'csharp' },\n];\n\nexport interface LegacyBridgeContext {\n cwd: string;\n projectRoot: string;\n signal: AbortSignal;\n target?: string | undefined;\n}\n\n/**\n * Quick check: does the cwd (or any parent up to projectRoot) contain a\n * non-JS ecosystem marker? Returns the detected language or `null`.\n */\nexport async function detectNonJsEcosystem(\n cwd: string,\n projectRoot: string,\n): Promise<LanguageProfileId | null> {\n try {\n let dir = path.resolve(cwd);\n const root = path.resolve(projectRoot);\n\n for (let depth = 0; depth <= 4 && dir.startsWith(root); depth++) {\n for (const marker of NON_JS_MARKERS) {\n try {\n const s = await fs.stat(path.join(dir, marker.filename));\n if (s.isFile()) return marker.language;\n } catch {\n // not present\n }\n }\n try {\n const entries = await fs.readdir(dir);\n for (const entry of entries) {\n for (const suffix of NON_JS_SUFFIXES) {\n if (entry.toLowerCase().endsWith(suffix.suffix)) return suffix.language;\n }\n }\n } catch {\n // not a directory or not readable\n }\n if (dir === root) break;\n dir = path.dirname(dir);\n }\n } catch {\n // Module mocks or unusual environments may not provide all fs methods.\n // Return null so the legacy tool falls back to its existing path.\n }\n return null;\n}\n\nexport interface LegacyBridgeResult {\n language: LanguageProfileId;\n run?: LanguageRunResult;\n outcome?: LanguagePackageOutcome;\n}\n\n/**\n * Attempt to plan and execute a code-quality operation through the language\n * system. Returns the result or `null` when the workspace is JS/TS or the\n * planner has no plan.\n */\nexport async function tryLegacyCodeOperation(\n operation: LanguageOperation,\n ctx: LegacyBridgeContext,\n): Promise<LegacyBridgeResult | null> {\n const language = await detectNonJsEcosystem(ctx.cwd, ctx.projectRoot);\n if (!language) return null;\n\n const planResult = await planLanguageOperation({\n projectRoot: ctx.projectRoot,\n cwd: ctx.cwd,\n operation,\n language,\n ...(ctx.target ? { target: ctx.target } : {}),\n signal: ctx.signal,\n });\n if (planResult.status !== 'planned') return null;\n\n const runner = executeLanguagePlan({\n projectRoot: ctx.projectRoot,\n workspace: planResult.workspace,\n plan: planResult.plan,\n signal: ctx.signal,\n });\n for (;;) {\n const next = await runner.next();\n if (next.done) return { language, run: next.value };\n }\n}\n\n/**\n * Attempt to plan and execute a package operation through the language\n * system. Returns the result or `null` when the workspace is JS/TS.\n */\nexport async function tryLegacyPackageOperation(\n operation: LanguageOperation,\n ctx: LegacyBridgeContext,\n packages: readonly string[] = [],\n): Promise<LegacyBridgeResult | null> {\n const language = await detectNonJsEcosystem(ctx.cwd, ctx.projectRoot);\n if (!language) return null;\n\n const planResult = await planLanguageOperation({\n projectRoot: ctx.projectRoot,\n cwd: ctx.cwd,\n operation,\n language,\n signal: ctx.signal,\n ...(packages.length > 0 ? { operationOptions: { packages: [...packages] } } : {}),\n });\n if (planResult.status !== 'planned') return null;\n\n const runner = executePackagePlan({\n projectRoot: ctx.projectRoot,\n workspace: planResult.workspace,\n plan: planResult.plan,\n packages,\n signal: ctx.signal,\n });\n for (;;) {\n const next = await runner.next();\n if (next.done) return { language, outcome: next.value };\n }\n}\n", "import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n DetectedWorkspace,\n DetectionLimits,\n DetectionResult,\n DetectLanguageOptions,\n LanguageEvidence,\n LanguageProfile,\n} from './types.js';\n\nconst DEFAULT_LIMITS: DetectionLimits = { maxDepth: 6, maxEntries: 5_000 };\nconst SOURCE_WEIGHT = 5;\nconst SOURCE_WEIGHT_CAP = 25;\nconst TARGET_WEIGHT = 100;\n\nconst GLOBAL_IGNORES = new Set([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'target',\n 'bin',\n 'obj',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.cache',\n '.idea',\n '.vscode',\n '.next',\n '.nuxt',\n]);\n\ninterface CandidateState {\n profile: LanguageProfile;\n root: string;\n evidence: LanguageEvidence[];\n manifests: string[];\n}\n\ninterface ScanState {\n entries: number;\n truncated: boolean;\n sourcePaths: Map<string, string[]>;\n candidates: Map<string, CandidateState>;\n}\n\nexport async function detectLanguageWorkspaces(\n options: DetectLanguageOptions,\n): Promise<DetectionResult> {\n const projectRoot = await canonicalDirectory(options.projectRoot);\n const cwdInput = options.cwd\n ? path.isAbsolute(options.cwd)\n ? options.cwd\n : path.resolve(projectRoot, options.cwd)\n : projectRoot;\n const cwd = await canonicalInside(cwdInput, projectRoot, 'cwd');\n const target = options.target\n ? await canonicalInside(resolveFrom(cwd, options.target), projectRoot, 'target')\n : undefined;\n const profiles = (options.profiles ?? languageProfileRegistry.list())\n .filter((profile) => !options.language || profile.id === options.language)\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id));\n const limits = normalizeLimits(options.limits);\n const extraIgnores = new Set(options.ignoredDirectories ?? []);\n const state: ScanState = {\n entries: 0,\n truncated: false,\n sourcePaths: new Map(),\n candidates: new Map(),\n };\n\n await scanDirectory(projectRoot, 0, profiles, limits, state, extraIgnores, options.signal);\n addSourceFallbacks(projectRoot, profiles, state);\n if (target) addTargetEvidence(target, projectRoot, profiles, state);\n\n const workspaces = await Promise.all(\n [...state.candidates.values()].map((candidate) => finalizeCandidate(candidate, projectRoot)),\n );\n workspaces.sort(compareWorkspaces);\n return {\n projectRoot,\n scannedEntries: state.entries,\n truncated: state.truncated,\n workspaces,\n };\n}\n\nasync function scanDirectory(\n directory: string,\n depth: number,\n profiles: readonly LanguageProfile[],\n limits: DetectionLimits,\n state: ScanState,\n extraIgnores: ReadonlySet<string>,\n signal?: AbortSignal,\n): Promise<void> {\n signal?.throwIfAborted();\n if (depth > limits.maxDepth || state.entries >= limits.maxEntries) {\n state.truncated = true;\n return;\n }\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(directory, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const entry of entries) {\n signal?.throwIfAborted();\n if (state.entries >= limits.maxEntries) {\n state.truncated = true;\n return;\n }\n state.entries++;\n const fullPath = path.join(directory, entry.name);\n if (entry.isSymbolicLink()) continue;\n if (entry.isDirectory()) {\n if (shouldIgnoreDirectory(entry.name, profiles, extraIgnores)) continue;\n if (depth >= limits.maxDepth) {\n state.truncated = true;\n continue;\n }\n await scanDirectory(fullPath, depth + 1, profiles, limits, state, extraIgnores, signal);\n continue;\n }\n if (!entry.isFile()) continue;\n collectFileEvidence(directory, fullPath, entry.name, profiles, state);\n }\n}\n\nfunction collectFileEvidence(\n directory: string,\n fullPath: string,\n basename: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n const lower = basename.toLowerCase();\n const extension = path.extname(lower);\n for (const profile of profiles) {\n const detector = profile.detectors.find((rule) =>\n rule.filename\n ? lower === rule.filename.toLowerCase()\n : lower.endsWith(rule.suffix!.toLowerCase()),\n );\n if (detector) {\n const candidate = getCandidate(state, profile, directory);\n candidate.evidence.push({\n kind: detector.kind,\n path: fullPath,\n value: basename,\n weight: detector.weight,\n });\n if (detector.kind === 'manifest' || detector.kind === 'config') {\n candidate.manifests.push(fullPath);\n }\n }\n if (profile.extensions.includes(extension)) {\n const paths = state.sourcePaths.get(profile.id) ?? [];\n if (paths.length < SOURCE_WEIGHT_CAP / SOURCE_WEIGHT) paths.push(fullPath);\n state.sourcePaths.set(profile.id, paths);\n }\n }\n}\n\nfunction addSourceFallbacks(\n projectRoot: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n for (const profile of profiles) {\n const sources = state.sourcePaths.get(profile.id) ?? [];\n if (sources.length === 0) continue;\n const profileCandidates = [...state.candidates.values()].filter(\n (item) => item.profile.id === profile.id,\n );\n for (const source of sources) {\n const containing = profileCandidates\n .filter((candidate) => isInside(source, candidate.root))\n .sort(\n (a, b) =>\n pathDepth(b.root, projectRoot) - pathDepth(a.root, projectRoot) ||\n a.root.localeCompare(b.root),\n );\n const candidate =\n containing[0] ??\n (profile.sourceFallback === false ? undefined : getCandidate(state, profile, projectRoot));\n if (!candidate) continue;\n candidate.evidence.push({\n kind: 'source',\n path: source,\n value: path.extname(source),\n weight: SOURCE_WEIGHT,\n });\n }\n }\n}\n\nfunction addTargetEvidence(\n target: string,\n projectRoot: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n const extension = path.extname(target).toLowerCase();\n for (const profile of profiles) {\n if (!profile.extensions.includes(extension)) continue;\n const candidates = [...state.candidates.values()].filter(\n (candidate) => candidate.profile.id === profile.id && isInside(target, candidate.root),\n );\n const candidate =\n candidates.length > 0\n ? candidates.sort(\n (a, b) =>\n pathDepth(b.root, projectRoot) - pathDepth(a.root, projectRoot) ||\n a.root.localeCompare(b.root),\n )[0]!\n : profile.sourceFallback === false\n ? undefined\n : getCandidate(state, profile, path.dirname(target));\n if (!candidate) continue;\n candidate.evidence.push({\n kind: 'target',\n path: target,\n value: extension,\n weight: TARGET_WEIGHT,\n });\n }\n}\n\nasync function finalizeCandidate(\n candidate: CandidateState,\n projectRoot: string,\n): Promise<DetectedWorkspace> {\n const evidence = dedupeEvidence(candidate.evidence).sort(compareEvidence);\n const manifests = [...new Set(candidate.manifests)].sort();\n const confidence = Math.min(1, evidence.reduce((sum, item) => sum + item.weight, 0) / 100);\n const packageManager = await detectPackageManager(candidate.profile, candidate.root, evidence);\n const id = createHash('sha256')\n .update(`${candidate.profile.id}\\0${path.relative(projectRoot, candidate.root)}`)\n .digest('hex')\n .slice(0, 16);\n return Object.freeze({\n id,\n language: candidate.profile.id,\n root: candidate.root,\n confidence,\n evidence: Object.freeze(evidence.map((item) => Object.freeze(item))),\n ...(packageManager ? { packageManager } : {}),\n manifests: Object.freeze(manifests),\n capabilities: Object.freeze(\n Object.keys(candidate.profile.operations).sort() as DetectedWorkspace['capabilities'],\n ),\n });\n}\n\nasync function detectPackageManager(\n profile: LanguageProfile,\n root: string,\n evidence: readonly LanguageEvidence[],\n): Promise<string | undefined> {\n if (profile.packageManagers.length === 1) return profile.packageManagers[0];\n if (profile.id !== 'typescript' && profile.id !== 'javascript') return undefined;\n\n let declared: string | undefined;\n try {\n const pkg = JSON.parse(await fs.readFile(path.join(root, 'package.json'), 'utf8')) as {\n packageManager?: unknown;\n };\n if (typeof pkg.packageManager === 'string') {\n const manager = pkg.packageManager.split('@')[0];\n if (manager && profile.packageManagers.includes(manager)) declared = manager;\n }\n } catch {\n // Missing or malformed package.json is evidence failure, not detector failure.\n }\n const lockManagers = new Set<string>();\n for (const item of evidence) {\n const name = path.basename(item.path).toLowerCase();\n if (name === 'pnpm-lock.yaml') lockManagers.add('pnpm');\n else if (name === 'yarn.lock') lockManagers.add('yarn');\n else if (name === 'bun.lock' || name === 'bun.lockb') lockManagers.add('bun');\n else if (name === 'package-lock.json') lockManagers.add('npm');\n }\n if (\n declared &&\n (lockManagers.size === 0 || (lockManagers.size === 1 && lockManagers.has(declared)))\n ) {\n return declared;\n }\n if (lockManagers.size === 1) return [...lockManagers][0];\n if (lockManagers.size > 1) return undefined;\n return declared ?? 'npm';\n}\n\nfunction getCandidate(state: ScanState, profile: LanguageProfile, root: string): CandidateState {\n const key = `${profile.id}\\0${root}`;\n let candidate = state.candidates.get(key);\n if (!candidate) {\n candidate = { profile, root, evidence: [], manifests: [] };\n state.candidates.set(key, candidate);\n }\n return candidate;\n}\n\nfunction shouldIgnoreDirectory(\n name: string,\n profiles: readonly LanguageProfile[],\n extraIgnores: ReadonlySet<string>,\n): boolean {\n if (GLOBAL_IGNORES.has(name) || extraIgnores.has(name) || name.startsWith('.')) return true;\n return profiles.some((profile) => profile.ignoredDirectories.includes(name));\n}\n\nfunction normalizeLimits(input: DetectLanguageOptions['limits']): DetectionLimits {\n const maxDepth = Math.max(\n 0,\n Math.min(12, Math.trunc(input?.maxDepth ?? DEFAULT_LIMITS.maxDepth)),\n );\n const maxEntries = Math.max(\n 1,\n Math.min(50_000, Math.trunc(input?.maxEntries ?? DEFAULT_LIMITS.maxEntries)),\n );\n return { maxDepth, maxEntries };\n}\n\nasync function canonicalDirectory(input: string): Promise<string> {\n const resolved = path.resolve(input);\n const real = await fs.realpath(resolved);\n const stat = await fs.stat(real);\n if (!stat.isDirectory()) throw new Error(`Project root is not a directory: ${input}`);\n return real;\n}\n\nasync function canonicalInside(input: string, root: string, label: string): Promise<string> {\n const resolved = path.resolve(input);\n let real: string;\n try {\n real = await fs.realpath(resolved);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n const parent = await fs.realpath(path.dirname(resolved));\n real = path.join(parent, path.basename(resolved));\n }\n if (!isInside(real, root)) throw new Error(`${label} is outside project root: ${input}`);\n return real;\n}\n\nfunction resolveFrom(cwd: string, input: string): string {\n return path.isAbsolute(input) ? input : path.resolve(cwd, input);\n}\n\nfunction isInside(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nfunction pathDepth(candidate: string, root: string): number {\n const relative = path.relative(root, candidate);\n return relative === '' ? 0 : relative.split(path.sep).length;\n}\n\nfunction dedupeEvidence(items: readonly LanguageEvidence[]): LanguageEvidence[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = `${item.kind}\\0${item.path}\\0${item.value}\\0${item.weight}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction compareEvidence(a: LanguageEvidence, b: LanguageEvidence): number {\n return a.path.localeCompare(b.path) || a.kind.localeCompare(b.kind) || b.weight - a.weight;\n}\n\nfunction compareWorkspaces(a: DetectedWorkspace, b: DetectedWorkspace): number {\n return (\n b.confidence - a.confidence ||\n a.language.localeCompare(b.language) ||\n a.root.localeCompare(b.root) ||\n a.id.localeCompare(b.id)\n );\n}\n", "import type {\n CommandPlan,\n LanguageOperation,\n LanguageProfileId,\n OperationPlanResult,\n ProfileContext,\n} from './types.js';\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst DEFAULT_OUTPUT_LIMIT_BYTES = 200_000;\n\nexport function processPlan(\n ctx: ProfileContext,\n operation: LanguageOperation,\n command: string,\n args: readonly string[],\n options: {\n parser: string;\n reason: string;\n timeoutMs?: number | undefined;\n mutating?: boolean | undefined;\n network?: boolean | undefined;\n executesProjectCode?: boolean | undefined;\n },\n): CommandPlan {\n return {\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n kind: 'process',\n command,\n args: Object.freeze([...args]),\n cwd: ctx.workspace.root,\n env: Object.freeze({}),\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n outputLimitBytes: DEFAULT_OUTPUT_LIMIT_BYTES,\n mutating: options.mutating ?? false,\n network: options.network ?? false,\n executesProjectCode: options.executesProjectCode ?? false,\n reason: options.reason,\n evidence: ctx.workspace.evidence,\n parser: options.parser,\n };\n}\n\nexport function internalPlan(\n ctx: ProfileContext,\n operation: LanguageOperation,\n parser: string,\n reason: string,\n): CommandPlan {\n return {\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n kind: 'internal',\n command: null,\n args: Object.freeze([]),\n cwd: ctx.workspace.root,\n env: Object.freeze({}),\n timeoutMs: 5_000,\n outputLimitBytes: 32_768,\n mutating: false,\n network: false,\n executesProjectCode: false,\n reason,\n evidence: ctx.workspace.evidence,\n parser,\n };\n}\n\nexport function unavailable(\n ctx: ProfileContext,\n operation: LanguageOperation,\n reason: string,\n): OperationPlanResult {\n return {\n status: 'unavailable',\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n reason,\n };\n}\n\nexport function packageNames(ctx: ProfileContext): readonly string[] {\n return ctx.options.packages ?? [];\n}\n\nexport function profileId(value: LanguageProfileId): LanguageProfileId {\n return value;\n}\n", "import { packageNames, processPlan, unavailable } from '../profile-helpers.js';\nimport type { LanguageProfile, ProfileContext } from '../types.js';\n\nconst IGNORES = Object.freeze([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'dist',\n 'build',\n 'coverage',\n]);\n\nfunction pythonProfile(): LanguageProfile {\n return {\n id: 'python',\n displayName: 'Python',\n extensions: Object.freeze(['.py', '.pyi']),\n lspLanguageIds: Object.freeze(['python']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'pyproject.toml', weight: 90 },\n { kind: 'config', filename: 'setup.py', weight: 70 },\n { kind: 'config', filename: 'setup.cfg', weight: 60 },\n { kind: 'manifest', filename: 'requirements.txt', weight: 55 },\n { kind: 'manifest', filename: 'Pipfile', weight: 50 },\n { kind: 'lockfile', filename: 'poetry.lock', weight: 30 },\n { kind: 'lockfile', filename: 'Pipfile.lock', weight: 30 },\n { kind: 'lockfile', filename: 'uv.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['pip', 'poetry', 'pipenv', 'uv']),\n executables: Object.freeze([\n 'python',\n 'python3',\n 'pip',\n 'pip3',\n 'poetry',\n 'pipenv',\n 'uv',\n 'ruff',\n 'black',\n 'pytest',\n 'mypy',\n 'pyright',\n ]),\n operations: Object.freeze({\n syntax: async (ctx) => {\n const py = ctx.options.target ? 'python3' : 'python3';\n return ctx.options.target\n ? processPlan(ctx, 'syntax', py, ['-m', 'py_compile', ctx.options.target], {\n parser: 'python',\n reason: 'Compile the target file to check for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Python syntax check requires an explicit target file.');\n },\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'mypy', ['.', '--no-error-summary'], {\n parser: 'mypy',\n reason: 'Run mypy type checking on the workspace.',\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'ruff', ['check', '.'], {\n parser: 'ruff',\n reason: 'Run the Ruff linter on the workspace.',\n }),\n 'format-check': async (ctx) =>\n processPlan(ctx, 'format-check', 'ruff', ['format', '--check', '.'], {\n parser: 'ruff',\n reason: 'Check Python formatting without writing files.',\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'ruff', ['format', '.'], {\n parser: 'ruff',\n reason: 'Format Python source files.',\n mutating: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'pytest',\n [...(ctx.options.filter ? ['-k', ctx.options.filter] : []), '.'],\n {\n parser: 'pytest',\n reason: ctx.options.filter ? 'Run filtered Python tests.' : 'Run all Python tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n unavailable(ctx, 'build', 'Python is interpreted; use semantic or test instead.'),\n 'debug-compile': async (ctx) =>\n processPlan(ctx, 'debug-compile', 'mypy', ['.', '--no-error-summary'], {\n parser: 'mypy',\n reason: 'Collect mypy type diagnostics.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'pip', ['install', '--no-cache-dir'], {\n parser: 'package-text',\n reason: 'Install dependencies from requirements.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one package name is required.')\n : processPlan(ctx, 'package-add', 'pip', ['install', ...names], {\n parser: 'package-text',\n reason: 'Install specified Python packages.',\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one package name is required.')\n : processPlan(ctx, 'package-remove', 'pip', ['uninstall', '--yes', ...names], {\n parser: 'package-text',\n reason: 'Remove validated Python packages.',\n mutating: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'pip', ['audit'], {\n parser: 'pip-audit',\n reason: 'Audit Python dependencies for vulnerabilities.',\n network: true,\n }),\n run: async (ctx) => {\n // Try common Python entry points in priority order.\n const entries = ['main.py', 'app.py', '__main__.py', 'manage.py'];\n const first: string | undefined = (\n await Promise.all(\n entries.map((name) => ctx.pathExists(name).then((ok) => (ok ? name : undefined))),\n )\n ).find(Boolean);\n const args = first ? [first] : [];\n return processPlan(ctx, 'run', 'python3', args, {\n parser: 'command-text',\n reason: first\n ? `Run the Python entry point ${first}.`\n : 'Run the Python project (no common entry point detected \u2014 add the module path manually).',\n executesProjectCode: true,\n mutating: true,\n });\n },\n }),\n };\n}\n\nfunction hasGradleEvidence(ctx: ProfileContext): boolean {\n return ctx.workspace.evidence.some(\n (e) =>\n (e.kind === 'manifest' &&\n (e.value === 'build.gradle' ||\n e.value === 'build.gradle.kts' ||\n e.value === 'settings.gradle')) ||\n (e.kind === 'lockfile' && e.value === 'gradle.lockfile'),\n );\n}\n\nasync function gradleRunner(ctx: ProfileContext): Promise<string> {\n // Check for the Gradle wrapper at the workspace root. The wrapper is the\n // conventional way to run Gradle \u2014 it pins the Gradle version and downloads\n // it automatically if missing.\n if (await ctx.pathExists('gradlew')) return 'gradlew';\n return 'gradle';\n}\n\nfunction javaProfile(): LanguageProfile {\n return {\n id: 'java',\n displayName: 'Java / Kotlin',\n extensions: Object.freeze(['.java', '.kt', '.kts', '.scala']),\n lspLanguageIds: Object.freeze(['java', 'kotlin']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'pom.xml', weight: 90 },\n { kind: 'manifest', filename: 'build.gradle', weight: 85 },\n { kind: 'manifest', filename: 'build.gradle.kts', weight: 85 },\n { kind: 'manifest', filename: 'settings.gradle', weight: 50 },\n { kind: 'lockfile', filename: 'gradle.lockfile', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['maven', 'gradle']),\n executables: Object.freeze(['mvn', 'gradle', 'gradlew', 'java', 'kotlinc']),\n operations: Object.freeze({\n semantic: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['compileJava'] : ['compile', '-q'];\n const reason = isGradle ? 'Compile the Gradle project.' : 'Compile the Maven project.';\n return processPlan(ctx, 'semantic', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n lint: async (ctx) =>\n unavailable(\n ctx,\n 'lint',\n 'Java linting requires a configured checkstyle or spotbugs plugin.',\n ),\n 'format-check': async (ctx) =>\n unavailable(\n ctx,\n 'format-check',\n 'Java formatting check requires a configured spotless or google-java-format plugin.',\n ),\n test: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['test'] : ['test', '-q'];\n const reason = isGradle ? 'Run Gradle tests.' : 'Run Maven tests.';\n return processPlan(ctx, 'test', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n build: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['build'] : ['package', '-q', '-DskipTests'];\n const reason = isGradle\n ? 'Build the Gradle project.'\n : 'Build the Maven project, skipping tests.';\n return processPlan(ctx, 'build', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n run: async (ctx) => {\n if (!hasGradleEvidence(ctx))\n return unavailable(\n ctx,\n 'run',\n 'Maven run requires exec-maven-plugin configuration. Use `mvn exec:java -q` manually.',\n );\n const runner = await gradleRunner(ctx);\n return processPlan(ctx, 'run', runner, ['run'], {\n parser: 'command-text',\n reason: `Run the Gradle project entry point via ${runner}.`,\n executesProjectCode: true,\n mutating: true,\n });\n },\n 'package-install': async (ctx) =>\n unavailable(\n ctx,\n 'package-install',\n 'JVM dependency installation happens through build or dependency:get.',\n ),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one dependency coordinate is required.')\n : processPlan(ctx, 'package-add', 'mvn', ['dependency:get', `-Dartifact=${names[0]}`], {\n parser: 'maven',\n reason: 'Resolve and fetch a Maven dependency.',\n mutating: true,\n network: true,\n });\n },\n }),\n };\n}\n\nfunction rubyProfile(): LanguageProfile {\n return {\n id: 'ruby',\n displayName: 'Ruby',\n extensions: Object.freeze(['.rb']),\n lspLanguageIds: Object.freeze(['ruby']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'Gemfile', weight: 90 },\n { kind: 'config', filename: '.ruby-version', weight: 40 },\n { kind: 'lockfile', filename: 'Gemfile.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['gem', 'bundler']),\n executables: Object.freeze(['ruby', 'gem', 'bundle', 'rubocop', 'rspec']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'syntax', 'ruby', ['-c', ctx.options.target], {\n parser: 'ruby',\n reason: 'Check the target Ruby file for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Ruby syntax check requires an explicit target file.'),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'rubocop', ['--format=json'], {\n parser: 'rubocop',\n reason: 'Run RuboCop linter.',\n executesProjectCode: true,\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'rubocop', ['--auto-correct'], {\n parser: 'rubocop',\n reason: 'Auto-correct RuboCop violations.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'rspec', [], {\n parser: 'rspec',\n reason: 'Run the RSpec test suite.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'bundle', ['install'], {\n parser: 'package-text',\n reason: 'Install Ruby gem dependencies.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one gem name is required.')\n : processPlan(ctx, 'package-add', 'gem', ['install', ...names], {\n parser: 'package-text',\n reason: 'Install specified Ruby gems.',\n mutating: true,\n network: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'bundle', ['audit', '--format=json'], {\n parser: 'bundler-audit',\n reason: 'Audit Ruby gems for vulnerabilities.',\n network: true,\n }),\n run: async (ctx) => {\n // Try common Ruby entry points in priority order.\n const entries = ['main.rb', 'app.rb', 'server.rb', 'config.ru'];\n const first: string | undefined = (\n await Promise.all(\n entries.map((name) => ctx.pathExists(name).then((ok) => (ok ? name : undefined))),\n )\n ).find(Boolean);\n const hasGemfile = await ctx.pathExists('Gemfile');\n const cmd = hasGemfile ? 'bundle' : 'ruby';\n const args = hasGemfile ? ['exec', 'ruby', first ?? ''] : [first ?? ''];\n return processPlan(ctx, 'run', cmd, args, {\n parser: 'command-text',\n reason: first\n ? `Run the Ruby entry point ${first}.`\n : 'Run the Ruby project (no common entry point detected \u2014 add the file path manually).',\n executesProjectCode: true,\n mutating: true,\n });\n },\n }),\n };\n}\n\nfunction cProfile(): LanguageProfile {\n return {\n id: 'c',\n displayName: 'C / C++',\n extensions: Object.freeze(['.c', '.h']),\n lspLanguageIds: Object.freeze(['c']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'CMakeLists.txt', weight: 85 },\n { kind: 'manifest', filename: 'Makefile', weight: 60 },\n { kind: 'config', suffix: '.cmake', weight: 50 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['cc', 'gcc', 'clang', 'cmake', 'make']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'cmake', ['--build', '.', '--target', 'all'], {\n parser: 'cmake',\n reason: 'Build C project to collect compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n unavailable(\n ctx,\n 'test',\n 'C test execution requires a configured test runner (ctest, etc.).',\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'cmake', ['--build', '.'], {\n parser: 'cmake',\n reason: 'Build the C project.',\n mutating: true,\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction cppProfile(): LanguageProfile {\n return {\n ...cProfile(),\n id: 'cpp',\n displayName: 'C++',\n extensions: Object.freeze(['.cpp', '.cc', '.cxx', '.hpp', '.hxx']),\n lspLanguageIds: Object.freeze(['cpp']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'CMakeLists.txt', weight: 85 },\n { kind: 'manifest', filename: 'Makefile', weight: 50 },\n ]),\n executables: Object.freeze(['c++', 'g++', 'clang++', 'cmake', 'make']),\n };\n}\n\nfunction swiftProfile(): LanguageProfile {\n return {\n id: 'swift',\n displayName: 'Swift',\n extensions: Object.freeze(['.swift']),\n lspLanguageIds: Object.freeze(['swift']),\n detectors: Object.freeze([{ kind: 'manifest', filename: 'Package.swift', weight: 90 }]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['swift']),\n executables: Object.freeze(['swift', 'swiftc']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'swift', ['build'], {\n parser: 'swift',\n reason: 'Build Swift package to collect compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'swift', ['test'], {\n parser: 'swift-test',\n reason: 'Run Swift tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'swift', ['build', '-c', 'release'], {\n parser: 'swift',\n reason: 'Build the Swift package in release mode.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'swift', ['run'], {\n parser: 'command-text',\n reason: 'Run the Swift package entry point.',\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction dartProfile(): LanguageProfile {\n return {\n id: 'dart',\n displayName: 'Dart / Flutter',\n extensions: Object.freeze(['.dart']),\n lspLanguageIds: Object.freeze(['dart']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'pubspec.yaml', weight: 90 },\n { kind: 'lockfile', filename: 'pubspec.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['pub']),\n executables: Object.freeze(['dart', 'flutter']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'dart', ['analyze'], {\n parser: 'dart-analyze',\n reason: 'Run Dart static analysis.',\n }),\n 'format-check': async (ctx) =>\n processPlan(\n ctx,\n 'format-check',\n 'dart',\n ['format', '--output=none', '--set-exit-if-changed', '.'],\n {\n parser: 'dart-format',\n reason: 'Check Dart formatting without writing files.',\n },\n ),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'dart', ['format', '.'], {\n parser: 'dart-format',\n reason: 'Format Dart source files.',\n mutating: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'dart', ['test'], {\n parser: 'dart-test',\n reason: 'Run Dart tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'dart', ['pub', 'get'], {\n parser: 'package-text',\n reason: 'Fetch Dart package dependencies.',\n mutating: true,\n network: true,\n }),\n 'package-outdated': async (ctx) =>\n processPlan(ctx, 'package-outdated', 'dart', ['pub', 'outdated'], {\n parser: 'dart-outdated',\n reason: 'Check for outdated Dart packages.',\n network: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'dart', ['run'], {\n parser: 'command-text',\n reason: 'Run the Dart / Flutter project entry point.',\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction denoProfile(): LanguageProfile {\n return {\n id: 'deno',\n displayName: 'Deno',\n extensions: Object.freeze(['.ts', '.tsx', '.js', '.jsx']),\n lspLanguageIds: Object.freeze(['typescript', 'javascript']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'deno.json', weight: 90 },\n { kind: 'config', filename: 'deno.jsonc', weight: 90 },\n { kind: 'config', filename: 'import_map.json', weight: 60 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['deno']),\n // .ts/.js extensions are shared with the TypeScript/JavaScript profiles;\n // only a deno.json(c)/import_map.json detector hit may establish a workspace.\n sourceFallback: false,\n operations: Object.freeze({\n test: async (ctx) =>\n processPlan(ctx, 'test', 'deno', ['test'], {\n parser: 'deno-test',\n reason: 'Run Deno tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'deno', ['run', '--allow-all', 'main.ts'], {\n parser: 'command-text',\n reason: 'Run the Deno project entry point with full permission.',\n executesProjectCode: true,\n mutating: true,\n }),\n }),\n };\n}\n\nfunction elixirProfile(): LanguageProfile {\n return {\n id: 'elixir',\n displayName: 'Elixir',\n extensions: Object.freeze(['.ex', '.exs']),\n lspLanguageIds: Object.freeze(['elixir']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'mix.exs', weight: 90 },\n { kind: 'lockfile', filename: 'mix.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['mix']),\n executables: Object.freeze(['mix', 'elixir']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n unavailable(ctx, 'semantic', 'Elixir compilation is handled by the build operation.'),\n lint: async (ctx) => unavailable(ctx, 'lint', 'Elixir linting requires the credo package.'),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'mix', ['test'], {\n parser: 'mix-test',\n reason: 'Run ExUnit tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'mix', ['compile'], {\n parser: 'mix',\n reason: 'Compile the Mix project.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'mix', ['run'], {\n parser: 'command-text',\n reason: 'Run the Mix project entry point.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'mix', ['deps.get'], {\n parser: 'package-text',\n reason: 'Fetch Elixir dependencies.',\n mutating: true,\n network: true,\n }),\n }),\n };\n}\n\nfunction shellProfile(): LanguageProfile {\n return {\n id: 'shell',\n displayName: 'Shell',\n extensions: Object.freeze(['.sh', '.bash']),\n lspLanguageIds: Object.freeze(['shellscript']),\n detectors: Object.freeze([{ kind: 'config', filename: 'ShellCheckrc', weight: 50 }]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['bash', 'sh', 'shellcheck', 'shfmt']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'syntax', 'bash', ['-n', ctx.options.target], {\n parser: 'shell',\n reason: 'Check the shell script for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Shell syntax check requires an explicit target file.'),\n lint: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'lint', 'shellcheck', ['--format=json', ctx.options.target], {\n parser: 'shellcheck',\n reason: 'Run ShellCheck on the target script.',\n })\n : unavailable(ctx, 'lint', 'Shell linting requires an explicit target file.'),\n 'format-check': async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'format-check', 'shfmt', ['-d', ctx.options.target], {\n parser: 'shell',\n reason: 'Check shell formatting without writing.',\n })\n : unavailable(\n ctx,\n 'format-check',\n 'Shell formatting check requires an explicit target file.',\n ),\n 'format-write': async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'format-write', 'shfmt', ['-w', ctx.options.target], {\n parser: 'shell',\n reason: 'Format the shell script.',\n mutating: true,\n })\n : unavailable(ctx, 'format-write', 'Shell formatting requires an explicit target file.'),\n }),\n };\n}\n\nexport const ADDITIONAL_LANGUAGE_PROFILES: readonly LanguageProfile[] = Object.freeze([\n pythonProfile(),\n javaProfile(),\n rubyProfile(),\n cProfile(),\n cppProfile(),\n swiftProfile(),\n dartProfile(),\n denoProfile(),\n elixirProfile(),\n shellProfile(),\n]);\n", "import { internalPlan, packageNames, processPlan, unavailable } from '../profile-helpers.js';\nimport type { LanguageOperation, LanguageProfile, ProfileContext } from '../types.js';\n\nconst COMMON_IGNORES = Object.freeze([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'target',\n 'bin',\n 'obj',\n 'dist',\n 'build',\n 'coverage',\n]);\n\nfunction nodeManager(ctx: ProfileContext): string | undefined {\n const lockfiles = new Set(\n ctx.workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.value.toLowerCase()),\n );\n if (lockfiles.size > 1 && !ctx.workspace.packageManager) return undefined;\n return ctx.workspace.packageManager ?? 'npm';\n}\n\nfunction scriptPlan(ctx: ProfileContext, operation: string, script: string) {\n const manager = nodeManager(ctx);\n if (!manager)\n return unavailable(\n ctx,\n operation as LanguageOperation,\n 'Conflicting Node lockfiles make the package manager ambiguous.',\n );\n const args = manager === 'npm' ? ['run', script] : [script];\n return processPlan(ctx, operation as LanguageOperation, manager, args, {\n parser: 'command-text',\n reason: `Run the detected ${manager} ${script} script for this workspace.`,\n mutating: true,\n executesProjectCode: true,\n });\n}\n\nfunction nodeExec(ctx: ProfileContext, executable: string, args: readonly string[]) {\n const manager = ctx.workspace.packageManager ?? 'npm';\n if (manager === 'pnpm') return { command: 'pnpm', args: ['exec', executable, ...args] };\n if (manager === 'yarn') return { command: 'yarn', args: ['exec', executable, ...args] };\n if (manager === 'bun') return { command: 'bun', args: ['x', executable, ...args] };\n return { command: 'npx', args: ['--no-install', executable, ...args] };\n}\n\nfunction typescriptProfile(): LanguageProfile {\n return {\n id: 'typescript',\n displayName: 'TypeScript',\n extensions: Object.freeze(['.ts', '.tsx', '.mts', '.cts']),\n lspLanguageIds: Object.freeze(['typescript', 'typescriptreact']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'tsconfig.json', weight: 90 },\n { kind: 'manifest', filename: 'package.json', weight: 55 },\n { kind: 'lockfile', filename: 'pnpm-lock.yaml', weight: 30 },\n { kind: 'lockfile', filename: 'yarn.lock', weight: 30 },\n { kind: 'lockfile', filename: 'package-lock.json', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lock', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lockb', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['pnpm', 'yarn', 'bun', 'npm']),\n executables: Object.freeze(['pnpm', 'yarn', 'bun', 'npx', 'npm']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n internalPlan(\n ctx,\n 'syntax',\n 'typescript-parser',\n 'Parse the target with the TypeScript compiler API.',\n ),\n semantic: async (ctx) => {\n const run = nodeExec(ctx, 'tsc', ['--noEmit', '--pretty', 'false']);\n return processPlan(ctx, 'semantic', run.command, run.args, {\n parser: 'typescript',\n reason: 'Run the workspace TypeScript compiler without emitting files.',\n executesProjectCode: true,\n });\n },\n lint: async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['lint', '.']);\n return processPlan(ctx, 'lint', run.command, run.args, {\n parser: 'biome',\n reason: 'Run the project-local Biome linter.',\n executesProjectCode: true,\n });\n },\n 'format-check': async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['format', '--check', '.']);\n return processPlan(ctx, 'format-check', run.command, run.args, {\n parser: 'biome',\n reason: 'Check formatting with the project-local Biome formatter.',\n executesProjectCode: true,\n });\n },\n 'format-write': async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['format', '--write', '.']);\n return processPlan(ctx, 'format-write', run.command, run.args, {\n parser: 'biome',\n reason: 'Format the workspace with the project-local Biome formatter.',\n mutating: true,\n executesProjectCode: true,\n });\n },\n test: async (ctx) =>\n ctx.options.filter || ctx.options.coverage\n ? unavailable(\n ctx,\n 'test',\n 'The detected package script does not expose deterministic filter or coverage adapters.',\n )\n : scriptPlan(ctx, 'test', 'test'),\n build: async (ctx) => scriptPlan(ctx, 'build', 'build'),\n run: async (ctx) => scriptPlan(ctx, 'run', 'dev'),\n 'debug-compile': async (ctx) => {\n const run = nodeExec(ctx, 'tsc', ['--noEmit', '--pretty', 'false']);\n return processPlan(ctx, 'debug-compile', run.command, run.args, {\n parser: 'typescript',\n reason: 'Collect deterministic TypeScript compiler diagnostics.',\n executesProjectCode: true,\n });\n },\n 'package-install': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'yarn' ? ['install', '--ignore-scripts'] : ['install', '--ignore-scripts'];\n return processPlan(ctx, 'package-install', manager, args, {\n parser: 'package-text',\n reason: `Restore declared dependencies with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n executesProjectCode: false,\n });\n },\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-add', 'At least one package name is required.');\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'npm'\n ? ['install', '--ignore-scripts', ...names]\n : ['add', '--ignore-scripts', ...names];\n return processPlan(ctx, 'package-add', manager, args, {\n parser: 'package-text',\n reason: `Add validated packages with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-remove', 'At least one package name is required.');\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'npm'\n ? ['uninstall', '--ignore-scripts', ...names]\n : ['remove', '--ignore-scripts', ...names];\n return processPlan(ctx, 'package-remove', manager, args, {\n parser: 'package-text',\n reason: `Remove validated packages with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n });\n },\n 'package-audit': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n return processPlan(ctx, 'package-audit', manager, ['audit', '--json'], {\n parser: 'npm-audit',\n reason: `Audit dependencies with the detected ${manager} package manager.`,\n network: true,\n });\n },\n 'package-outdated': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n return processPlan(ctx, 'package-outdated', manager, ['outdated', '--json'], {\n parser: 'npm-outdated',\n reason: `Check outdated dependencies with ${manager}.`,\n network: true,\n });\n },\n }),\n };\n}\n\nfunction javascriptProfile(): LanguageProfile {\n const ts = typescriptProfile();\n return {\n ...ts,\n id: 'javascript',\n displayName: 'JavaScript',\n extensions: Object.freeze(['.js', '.jsx', '.mjs', '.cjs']),\n lspLanguageIds: Object.freeze(['javascript', 'javascriptreact']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'jsconfig.json', weight: 90 },\n { kind: 'manifest', filename: 'package.json', weight: 70 },\n { kind: 'lockfile', filename: 'pnpm-lock.yaml', weight: 30 },\n { kind: 'lockfile', filename: 'yarn.lock', weight: 30 },\n { kind: 'lockfile', filename: 'package-lock.json', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lock', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lockb', weight: 30 },\n ]),\n operations: Object.freeze({\n ...ts.operations,\n syntax: async (ctx: ProfileContext) =>\n internalPlan(\n ctx,\n 'syntax',\n 'typescript-parser',\n 'Parse JavaScript with the TypeScript compiler API.',\n ),\n }),\n };\n}\n\nconst goProfile: LanguageProfile = {\n id: 'go',\n displayName: 'Go',\n extensions: Object.freeze(['.go']),\n lspLanguageIds: Object.freeze(['go']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'go.mod', weight: 90 },\n { kind: 'manifest', filename: 'go.work', weight: 95 },\n { kind: 'lockfile', filename: 'go.sum', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['go']),\n executables: Object.freeze(['go', 'gofmt']),\n operations: Object.freeze({\n syntax: async (ctx) => {\n if (!ctx.target)\n return unavailable(ctx, 'syntax', 'Go syntax planning requires a target file.');\n return processPlan(ctx, 'syntax', 'gofmt', ['-e', '-d', ctx.target], {\n parser: 'gofmt',\n reason: 'Parse the target and report syntax errors without writing it.',\n });\n },\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'go', ['test', '-run', '^$', './...'], {\n parser: 'go-test',\n reason: 'Compile all Go packages without selecting tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'go', ['vet', './...'], {\n parser: 'go-compiler',\n reason: 'Run the standard Go vet checks.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'format-check', 'gofmt', ['-d', ctx.target], {\n parser: 'gofmt',\n reason: 'Report Go formatting differences for the target without writing it.',\n })\n : unavailable(ctx, 'format-check', 'Go formatting requires an explicit target file.'),\n 'format-write': async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'format-write', 'gofmt', ['-w', ctx.target], {\n parser: 'gofmt',\n reason: 'Format the target Go source file.',\n mutating: true,\n })\n : unavailable(ctx, 'format-write', 'Go formatting requires an explicit target file.'),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'go',\n ['test', ...(ctx.options.filter ? ['-run', ctx.options.filter] : []), './...'],\n {\n parser: 'go-test',\n reason: ctx.options.filter ? 'Run filtered Go tests.' : 'Run all Go tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'go', ['build', './...'], {\n parser: 'go-compiler',\n reason: 'Build all Go packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'go', ['run', '.'], {\n parser: 'command-text',\n reason: 'Run the Go module entry point.',\n executesProjectCode: true,\n }),\n 'debug-race': async (ctx) =>\n processPlan(ctx, 'debug-race', 'go', ['test', '-race', './...'], {\n parser: 'go-test',\n reason: 'Collect Go race-detector evidence.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'go', ['mod', 'download'], {\n parser: 'go-module',\n reason: 'Download the dependencies declared by go.mod.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-add', 'At least one Go module is required.');\n return processPlan(ctx, 'package-add', 'go', ['get', ...names], {\n parser: 'go-module',\n reason: 'Add validated Go modules.',\n mutating: true,\n network: true,\n });\n },\n 'package-update': async (ctx) =>\n processPlan(ctx, 'package-update', 'go', ['get', '-u', './...'], {\n parser: 'go-module',\n reason: 'Update dependencies of all Go packages.',\n mutating: true,\n network: true,\n }),\n }),\n};\n\nconst rustProfile: LanguageProfile = {\n id: 'rust',\n displayName: 'Rust',\n extensions: Object.freeze(['.rs']),\n lspLanguageIds: Object.freeze(['rust']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'Cargo.toml', weight: 90 },\n { kind: 'lockfile', filename: 'Cargo.lock', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['cargo']),\n executables: Object.freeze(['cargo']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n processPlan(ctx, 'syntax', 'cargo', ['check', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Check Rust syntax and semantics with Cargo.',\n mutating: true,\n executesProjectCode: true,\n }),\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'cargo', ['check', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Collect Rust compiler diagnostics with Cargo check.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'cargo', ['clippy', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Run Clippy for this crate.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n processPlan(ctx, 'format-check', 'cargo', ['fmt', '--check'], {\n parser: 'cargo-fmt',\n reason: 'Check Rust formatting without writing files.',\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'cargo', ['fmt'], {\n parser: 'cargo-fmt',\n reason: 'Format Rust source files in the workspace.',\n mutating: true,\n }),\n 'test-compile': async (ctx) =>\n processPlan(ctx, 'test-compile', 'cargo', ['test', '--no-run', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Compile Rust tests without running them.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'cargo',\n ['test', ...(ctx.options.filter ? [ctx.options.filter] : [])],\n {\n parser: 'cargo-test',\n reason: ctx.options.filter ? 'Run filtered Rust tests.' : 'Run Rust tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'cargo', ['build', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Build the Rust workspace.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'cargo', ['run'], {\n parser: 'command-text',\n reason: 'Run the Rust workspace entry point.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'cargo', ['fetch', '--locked'], {\n parser: 'cargo-json',\n reason: 'Fetch locked Rust dependencies.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one crate is required.')\n : processPlan(ctx, 'package-add', 'cargo', ['add', ...names], {\n parser: 'cargo-text',\n reason: 'Add validated Rust crates.',\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one crate is required.')\n : processPlan(ctx, 'package-remove', 'cargo', ['remove', ...names], {\n parser: 'cargo-text',\n reason: 'Remove validated Rust crates.',\n mutating: true,\n });\n },\n 'package-update': async (ctx) =>\n processPlan(ctx, 'package-update', 'cargo', ['update'], {\n parser: 'cargo-text',\n reason: 'Update the Cargo lockfile.',\n mutating: true,\n network: true,\n }),\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'cargo', ['audit', '--json'], {\n parser: 'cargo-audit',\n reason: 'Audit Rust dependencies when cargo-audit is installed.',\n network: true,\n }),\n }),\n};\n\nconst phpProfile: LanguageProfile = {\n id: 'php',\n displayName: 'PHP',\n extensions: Object.freeze(['.php']),\n lspLanguageIds: Object.freeze(['php']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'composer.json', weight: 90 },\n { kind: 'lockfile', filename: 'composer.lock', weight: 30 },\n { kind: 'config', filename: 'phpunit.xml', weight: 25 },\n { kind: 'config', filename: 'phpunit.xml.dist', weight: 25 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['composer']),\n executables: Object.freeze(['php', 'composer']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'syntax', 'php', ['-l', ctx.target], {\n parser: 'php-lint',\n reason: 'Lint the target PHP file without executing it.',\n })\n : unavailable(ctx, 'syntax', 'PHP syntax planning requires a target file.'),\n semantic: async (ctx) =>\n unavailable(\n ctx,\n 'semantic',\n 'No configured PHPStan or Psalm adapter was detected in Phase 1.',\n ),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'php',\n ['vendor/bin/phpunit', ...(ctx.options.filter ? ['--filter', ctx.options.filter] : [])],\n {\n parser: 'phpunit',\n reason: ctx.options.filter\n ? 'Run filtered tests with the project-local PHPUnit runner.'\n : 'Run the project-local PHPUnit test runner.',\n executesProjectCode: true,\n },\n ),\n 'package-install': async (ctx) =>\n processPlan(\n ctx,\n 'package-install',\n 'composer',\n ['install', '--no-interaction', '--no-scripts'],\n {\n parser: 'composer',\n reason: 'Restore Composer dependencies without scripts.',\n mutating: true,\n network: true,\n },\n ),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one Composer package is required.')\n : processPlan(\n ctx,\n 'package-add',\n 'composer',\n ['require', '--no-interaction', '--no-scripts', ...names],\n {\n parser: 'composer',\n reason: 'Add validated Composer packages without scripts.',\n mutating: true,\n network: true,\n },\n );\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one Composer package is required.')\n : processPlan(\n ctx,\n 'package-remove',\n 'composer',\n ['remove', '--no-interaction', '--no-scripts', ...names],\n {\n parser: 'composer',\n reason: 'Remove validated Composer packages without scripts.',\n mutating: true,\n },\n );\n },\n 'package-update': async (ctx) =>\n processPlan(\n ctx,\n 'package-update',\n 'composer',\n ['update', '--no-interaction', '--no-scripts'],\n {\n parser: 'composer',\n reason: 'Update Composer dependencies without scripts.',\n mutating: true,\n network: true,\n },\n ),\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'composer', ['audit', '--format=json'], {\n parser: 'composer-audit',\n reason: 'Audit Composer dependencies.',\n network: true,\n }),\n 'package-outdated': async (ctx) =>\n processPlan(ctx, 'package-outdated', 'composer', ['outdated', '--format=json'], {\n parser: 'composer-outdated',\n reason: 'Check outdated Composer dependencies.',\n network: true,\n }),\n }),\n};\n\nconst csharpProfile: LanguageProfile = {\n id: 'csharp',\n displayName: 'C# / .NET',\n extensions: Object.freeze(['.cs']),\n lspLanguageIds: Object.freeze(['csharp']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'global.json', weight: 25 },\n { kind: 'manifest', suffix: '.slnx', weight: 95 },\n { kind: 'manifest', suffix: '.sln', weight: 95 },\n { kind: 'manifest', suffix: '.csproj', weight: 90 },\n { kind: 'manifest', suffix: '.fsproj', weight: 90 },\n { kind: 'lockfile', filename: 'packages.lock.json', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['dotnet']),\n executables: Object.freeze(['dotnet']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n processPlan(ctx, 'syntax', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Use the nearest project or solution to collect C# syntax diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Build without restoring to collect .NET compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'dotnet', ['format', '--verify-no-changes', '--no-restore'], {\n parser: 'dotnet-format',\n reason: 'Verify .NET formatting and analyzers without writing source files.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n processPlan(\n ctx,\n 'format-check',\n 'dotnet',\n ['format', '--verify-no-changes', '--no-restore'],\n {\n parser: 'dotnet-format',\n reason: 'Verify .NET formatting without source writes.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'dotnet', ['format', '--no-restore'], {\n parser: 'dotnet-format',\n reason: 'Format .NET source files without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'dotnet',\n ['test', '--no-restore', ...(ctx.options.filter ? ['--filter', ctx.options.filter] : [])],\n {\n parser: 'dotnet-test',\n reason: ctx.options.filter\n ? 'Run filtered .NET tests without restoring packages.'\n : 'Run .NET tests without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Build the nearest .NET project or solution without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'dotnet', ['run', '--no-restore'], {\n parser: 'command-text',\n reason: 'Run the .NET project entry point.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'dotnet', ['restore', '--locked-mode'], {\n parser: 'dotnet-restore',\n reason: 'Restore locked .NET dependencies.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n const [spec] = names;\n const versionAt = spec?.lastIndexOf('@') ?? -1;\n const packageName = versionAt > 0 ? spec?.slice(0, versionAt) : spec;\n const packageVersion = versionAt > 0 ? spec?.slice(versionAt + 1) : undefined;\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one NuGet package is required.')\n : names.length > 1\n ? unavailable(ctx, 'package-add', 'NuGet package changes run one package at a time.')\n : processPlan(\n ctx,\n 'package-add',\n 'dotnet',\n [\n 'add',\n 'package',\n packageName ?? '',\n ...(packageVersion ? ['--version', packageVersion] : []),\n ],\n {\n parser: 'dotnet-package',\n reason: 'Add validated NuGet packages.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n },\n );\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one NuGet package is required.')\n : processPlan(ctx, 'package-remove', 'dotnet', ['remove', 'package', ...names], {\n parser: 'dotnet-package',\n reason: 'Remove validated NuGet packages.',\n mutating: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(\n ctx,\n 'package-audit',\n 'dotnet',\n ['list', 'package', '--vulnerable', '--format', 'json'],\n { parser: 'dotnet-package', reason: 'List vulnerable NuGet dependencies.', network: true },\n ),\n 'package-outdated': async (ctx) =>\n processPlan(\n ctx,\n 'package-outdated',\n 'dotnet',\n ['list', 'package', '--outdated', '--format', 'json'],\n { parser: 'dotnet-package', reason: 'List outdated NuGet dependencies.', network: true },\n ),\n }),\n};\n\nexport const PRIMARY_LANGUAGE_PROFILES: readonly LanguageProfile[] = Object.freeze([\n Object.freeze(typescriptProfile()),\n Object.freeze(javascriptProfile()),\n Object.freeze(goProfile),\n Object.freeze(rustProfile),\n Object.freeze(phpProfile),\n Object.freeze(csharpProfile),\n]);\n", "import { ADDITIONAL_LANGUAGE_PROFILES } from './profiles/additional.js';\nimport { PRIMARY_LANGUAGE_PROFILES } from './profiles/primary.js';\nimport type { LanguageOperation, LanguageProfile, LanguageProfileId } from './types.js';\n\nconst PROFILE_ID_RE = /^[a-z][a-z0-9-]{0,63}$/;\nconst EXECUTABLE_RE = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;\nconst KNOWN_OPERATIONS = new Set<LanguageOperation>([\n 'syntax',\n 'semantic',\n 'lint',\n 'format-check',\n 'format-write',\n 'test-compile',\n 'test',\n 'build',\n 'run',\n 'debug-compile',\n 'debug-test',\n 'debug-runtime',\n 'debug-race',\n 'package-install',\n 'package-add',\n 'package-remove',\n 'package-update',\n 'package-audit',\n 'package-outdated',\n]);\n\nexport class LanguageProfileRegistry {\n readonly #profiles = new Map<LanguageProfileId, LanguageProfile>();\n\n constructor(profiles: readonly LanguageProfile[] = []) {\n for (const profile of profiles) this.register(profile);\n }\n\n register(profile: LanguageProfile): void {\n const errors = validateLanguageProfile(profile);\n if (errors.length > 0) {\n throw new Error(`Invalid language profile \"${profile.id}\": ${errors.join('; ')}`);\n }\n if (this.#profiles.has(profile.id)) {\n throw new Error(`Language profile \"${profile.id}\" is already registered`);\n }\n this.#profiles.set(profile.id, freezeProfile(profile));\n }\n\n get(id: LanguageProfileId): LanguageProfile | undefined {\n return this.#profiles.get(id);\n }\n\n list(): readonly LanguageProfile[] {\n return Object.freeze([...this.#profiles.values()]);\n }\n}\n\nexport function validateLanguageProfile(profile: LanguageProfile): string[] {\n const errors: string[] = [];\n if (!PROFILE_ID_RE.test(profile.id)) errors.push('id must be a lowercase stable identifier');\n if (!profile.displayName.trim()) errors.push('displayName is required');\n if (profile.extensions.length === 0) errors.push('at least one extension is required');\n for (const ext of profile.extensions) {\n if (!/^\\.[a-z0-9+.-]+$/i.test(ext)) errors.push(`invalid extension \"${ext}\"`);\n }\n if (profile.detectors.length === 0) errors.push('at least one detector is required');\n for (const detector of profile.detectors) {\n if ((detector.filename ? 1 : 0) + (detector.suffix ? 1 : 0) !== 1) {\n errors.push('each detector must declare exactly one of filename or suffix');\n }\n if (!Number.isFinite(detector.weight) || detector.weight <= 0 || detector.weight > 100) {\n errors.push('detector weights must be in the range 1..100');\n }\n const marker = detector.filename ?? detector.suffix ?? '';\n if (marker.includes('/') || marker.includes('\\\\') || marker.includes('\\0')) {\n errors.push(`detector marker \"${marker}\" must be a basename or suffix`);\n }\n }\n if (profile.executables.length === 0) errors.push('at least one executable is required');\n for (const executable of profile.executables) {\n if (!EXECUTABLE_RE.test(executable)) errors.push(`invalid executable token \"${executable}\"`);\n }\n for (const operation of Object.keys(profile.operations)) {\n if (!KNOWN_OPERATIONS.has(operation as LanguageOperation)) {\n errors.push(`unknown operation \"${operation}\"`);\n }\n if (typeof profile.operations[operation as LanguageOperation] !== 'function') {\n errors.push(`operation \"${operation}\" must be a resolver function`);\n }\n }\n return [...new Set(errors)];\n}\n\nfunction freezeProfile(profile: LanguageProfile): LanguageProfile {\n const detectors = Object.freeze(profile.detectors.map((item) => Object.freeze({ ...item })));\n const operations = Object.freeze({ ...profile.operations });\n return Object.freeze({\n ...profile,\n extensions: Object.freeze([...profile.extensions]),\n lspLanguageIds: Object.freeze([...profile.lspLanguageIds]),\n detectors,\n ignoredDirectories: Object.freeze([...profile.ignoredDirectories]),\n packageManagers: Object.freeze([...profile.packageManagers]),\n executables: Object.freeze([...profile.executables]),\n operations,\n });\n}\n\nexport const languageProfileRegistry = new LanguageProfileRegistry([\n ...PRIMARY_LANGUAGE_PROFILES,\n ...ADDITIONAL_LANGUAGE_PROFILES,\n]);\n", "import * as path from 'node:path';\nimport type {\n LanguageDiagnostic,\n LanguagePackageMutation,\n LanguagePackageVulnerability,\n LanguageProfileId,\n LanguageRunSummary,\n} from './types.js';\n\nconst MAX_DIAGNOSTICS = 200;\n\nexport interface ParsedDiagnostics {\n diagnostics: readonly LanguageDiagnostic[];\n omitted: number;\n summary: LanguageRunSummary;\n}\n\nexport function parseLanguageDiagnostics(\n parser: string,\n stdout: string,\n stderr: string,\n workspaceRoot: string,\n): ParsedDiagnostics {\n const text = `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}`;\n let diagnostics: LanguageDiagnostic[];\n switch (parser) {\n case 'typescript':\n diagnostics = parseTypeScript(text, workspaceRoot);\n break;\n case 'cargo-json':\n diagnostics = parseCargoJson(text, workspaceRoot);\n break;\n case 'php-lint':\n diagnostics = parsePhpLint(text, workspaceRoot);\n break;\n case 'dotnet-build':\n case 'dotnet-format':\n case 'dotnet-test':\n diagnostics = parseDotnet(text, workspaceRoot);\n break;\n case 'go-test':\n case 'go-compiler':\n case 'gofmt':\n diagnostics = parseGo(text, workspaceRoot);\n break;\n case 'biome':\n diagnostics = parseBiome(text, workspaceRoot);\n break;\n default:\n diagnostics = parseGeneric(text, parser, workspaceRoot);\n break;\n }\n const sorted = dedupeDiagnostics(diagnostics).sort(compareDiagnostics);\n const omitted = Math.max(0, sorted.length - MAX_DIAGNOSTICS);\n const kept = Object.freeze(sorted.slice(0, MAX_DIAGNOSTICS).map((item) => Object.freeze(item)));\n return {\n diagnostics: kept,\n omitted,\n summary: summarize(kept),\n };\n}\n\nexport function diagnosticsForInternalSyntax(\n language: LanguageProfileId,\n target: string,\n sourceText: string,\n): Promise<ParsedDiagnostics> {\n if (language !== 'typescript' && language !== 'javascript') {\n return Promise.resolve({ diagnostics: [], omitted: 0, summary: emptySummary() });\n }\n return import('@typescript/typescript6').then((tsModule) => {\n const ts = ((tsModule as unknown as { default?: typeof tsModule }).default ??\n tsModule) as typeof tsModule;\n const extension = path.extname(target).toLowerCase();\n const scriptKind =\n extension === '.tsx'\n ? ts.ScriptKind.TSX\n : extension === '.ts' || extension === '.mts' || extension === '.cts'\n ? ts.ScriptKind.TS\n : ts.ScriptKind.JSX;\n const sourceFile = ts.createSourceFile(\n path.basename(target),\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n scriptKind,\n );\n const native =\n (sourceFile as unknown as {\n parseDiagnostics?: import('@typescript/typescript6').Diagnostic[];\n })\n .parseDiagnostics ?? [];\n const diagnostics = native.map<LanguageDiagnostic>((diagnostic) => {\n const start = diagnostic.start ?? 0;\n const location = sourceFile.getLineAndCharacterOfPosition(start);\n return {\n severity: diagnostic.category === ts.DiagnosticCategory.Warning ? 'warning' : 'error',\n ...(diagnostic.code ? { code: `TS${diagnostic.code}` } : {}),\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, ' '),\n file: target,\n range: { start: { line: location.line + 1, column: location.character + 1 } },\n source: 'typescript-parser',\n };\n });\n const sorted = dedupeDiagnostics(diagnostics).sort(compareDiagnostics);\n const omitted = Math.max(0, sorted.length - MAX_DIAGNOSTICS);\n const kept = Object.freeze(sorted.slice(0, MAX_DIAGNOSTICS).map((item) => Object.freeze(item)));\n return { diagnostics: kept, omitted, summary: summarize(kept) };\n });\n}\n\nfunction parseTypeScript(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?)\\((\\d+),(\\d+)\\):\\s+(error|warning)\\s+(TS\\d+):\\s*(.+)$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: match[4] === 'warning' ? 'warning' : 'error',\n code: match[5],\n message: match[6]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'typescript',\n });\n }\n return diagnostics;\n}\n\nfunction parseCargoJson(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const value = JSON.parse(line) as {\n reason?: string;\n message?: {\n level?: string;\n code?: { code?: string };\n message?: string;\n spans?: Array<{\n file_name?: string;\n line_start?: number;\n column_start?: number;\n is_primary?: boolean;\n }>;\n };\n };\n if (value.reason !== 'compiler-message' || !value.message?.message) continue;\n const primary =\n value.message.spans?.find((span) => span.is_primary) ?? value.message.spans?.[0];\n diagnostics.push({\n severity: normalizeSeverity(value.message.level),\n ...(value.message.code?.code ? { code: value.message.code.code } : {}),\n message: value.message.message,\n ...(primary?.file_name ? { file: normalizeDiagnosticPath(primary.file_name, root) } : {}),\n ...(primary?.line_start\n ? { range: { start: { line: primary.line_start, column: primary.column_start ?? 1 } } }\n : {}),\n source: 'rustc',\n });\n } catch {\n // Non-JSON build output is retained as raw output, not fabricated into diagnostics.\n }\n }\n return diagnostics;\n}\n\nfunction parseGo(text: string, root: string): LanguageDiagnostic[] {\n return parseLinePattern(\n text,\n /^(.*?\\.go):(\\d+):(\\d+):\\s*(.+)$/gm,\n root,\n 'go',\n (_match, message) => ({ message, severity: /warning/i.test(message) ? 'warning' : 'error' }),\n );\n}\n\nfunction parsePhpLint(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /(?:PHP\\s+)?(?:Parse|Fatal) error:\\s*(.+?)\\s+in\\s+(.+?)\\s+on line\\s+(\\d+)/gi;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: 'error',\n message: match[1]!.trim(),\n file: normalizeDiagnosticPath(match[2]!, root),\n range: { start: { line: toPositiveInt(match[3]), column: 1 } },\n source: 'php',\n });\n }\n return diagnostics;\n}\n\nfunction parseDotnet(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?)\\((\\d+),(\\d+)\\):\\s*(error|warning)\\s+([A-Z]+\\d+):\\s*(.+?)(?:\\s+\\[.+\\])?$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: match[4] === 'warning' ? 'warning' : 'error',\n code: match[5],\n message: match[6]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'dotnet',\n });\n }\n return diagnostics;\n}\n\nfunction parseBiome(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?):(\\d+):(\\d+)\\s+(lint\\/[^\\s]+|format)\\s+(.+)$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: 'warning',\n code: match[4],\n message: match[5]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'biome',\n });\n }\n return diagnostics;\n}\n\nfunction parseGeneric(text: string, source: string, root: string): LanguageDiagnostic[] {\n return parseLinePattern(\n text,\n /^(.+?):(\\d+):(\\d+):\\s*(?:(error|warning|info):\\s*)?(.+)$/gm,\n root,\n source,\n (match, fallback) => ({\n severity: normalizeSeverity(match[4]),\n message: match[5]?.trim() || fallback,\n }),\n );\n}\n\nexport interface ParsedPackageReports {\n diagnostics: readonly LanguageDiagnostic[];\n vulnerabilities: readonly LanguagePackageVulnerability[];\n outdated: readonly LanguagePackageMutation[];\n}\n\nexport function parsePackageReports(\n parser: string,\n stdout: string,\n stderr: string,\n): ParsedPackageReports {\n const text = `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}`;\n switch (parser) {\n case 'npm-audit':\n return parseNpmAudit(text);\n case 'npm-outdated':\n return parseNpmOutdated(text);\n case 'cargo-audit':\n return parseCargoAudit(text);\n case 'composer-audit':\n return parseComposerAudit(text);\n case 'composer-outdated':\n return parseComposerOutdated(text);\n case 'dotnet-package':\n return parseDotnetPackage(text);\n default:\n return { diagnostics: [], vulnerabilities: [], outdated: [] };\n }\n}\n\nfunction parseNpmAudit(text: string): ParsedPackageReports {\n const advisories: LanguagePackageVulnerability[] = [];\n const diagnostics: LanguageDiagnostic[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities: advisories, outdated: [] };\n }\n const vulnerabilities =\n (root as { vulnerabilities?: Record<string, unknown> })?.vulnerabilities ?? {};\n const advisoriesRecord =\n (root as { advisories?: Record<string, unknown> })?.advisories ?? vulnerabilities;\n for (const [id, value] of Object.entries(advisoriesRecord)) {\n const advisory = value as {\n module_name?: string;\n package_name?: string;\n name?: string;\n title?: string;\n severity?: string;\n url?: string;\n range?: string;\n patched_versions?: string;\n };\n const name = advisory.module_name ?? advisory.package_name ?? advisory.name ?? id;\n advisories.push({\n package: name,\n ...(advisory.title ? { advisory: advisory.title } : { advisory: id }),\n severity: mapSeverity(advisory.severity),\n ...(advisory.patched_versions ? { fixedIn: advisory.patched_versions } : {}),\n ...(advisory.url ? { url: advisory.url } : {}),\n });\n diagnostics.push({\n severity:\n mapSeverity(advisory.severity) === 'critical' || mapSeverity(advisory.severity) === 'high'\n ? 'error'\n : 'warning',\n code: id,\n message: advisory.title ?? `Vulnerability reported for ${name}.`,\n source: 'npm-audit',\n });\n }\n return { diagnostics, vulnerabilities: advisories, outdated: [] };\n}\n\nfunction parseNpmOutdated(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const outdated: LanguagePackageMutation[] = [];\n let payload: Record<string, unknown> = {};\n try {\n payload = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities: [], outdated };\n }\n for (const [name, info] of Object.entries(payload)) {\n const entry = info as {\n current?: string;\n latest?: string;\n wanted?: string;\n type?: string;\n location?: string;\n };\n if (!entry.latest || entry.latest === entry.current) continue;\n outdated.push({\n name,\n previous: entry.current,\n resolved: entry.latest,\n kind: mapOutdatedKind(entry.type),\n });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${name}: ${entry.current ?? '?'} \u2192 ${entry.latest}`,\n source: 'npm-outdated',\n });\n }\n return { diagnostics, vulnerabilities: [], outdated };\n}\n\nfunction parseCargoAudit(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities, outdated: [] };\n }\n const findings = (root as { vulnerabilities?: { found?: unknown } }).vulnerabilities?.found;\n if (!Array.isArray(findings)) return { diagnostics, vulnerabilities, outdated: [] };\n for (const finding of findings) {\n const item = finding as {\n id?: string;\n package?: string;\n title?: string;\n severity?: string;\n patched_versions?: string[];\n url?: { long?: string; short?: string };\n advisory?: { id?: string };\n };\n const name = item.package ?? 'unknown';\n const advisory = item.id ?? item.advisory?.id ?? 'cargo-audit';\n vulnerabilities.push({\n package: name,\n ...(item.title ? { advisory: item.title } : { advisory }),\n severity: mapSeverity(item.severity),\n ...(item.patched_versions && item.patched_versions.length > 0\n ? { fixedIn: item.patched_versions[0] }\n : {}),\n ...(item.url?.short ? { url: item.url.short } : {}),\n });\n diagnostics.push({\n severity:\n mapSeverity(item.severity) === 'critical' || mapSeverity(item.severity) === 'high'\n ? 'error'\n : 'warning',\n code: advisory,\n message: item.title ?? `${name} reported by cargo-audit.`,\n source: 'cargo-audit',\n });\n }\n return { diagnostics, vulnerabilities, outdated: [] };\n}\n\nfunction parseComposerAudit(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const entry = JSON.parse(line) as {\n package?: string;\n advisory?: string;\n title?: string;\n severity?: string;\n affectedVersions?: string;\n url?: string;\n };\n if (!entry.package) continue;\n vulnerabilities.push({\n package: entry.package,\n ...(entry.advisory ? { advisory: entry.advisory } : {}),\n ...(entry.title\n ? { advisory: entry.title }\n : { advisory: entry.advisory ?? 'composer-audit' }),\n severity: mapSeverity(entry.severity),\n ...(entry.affectedVersions ? { fixedIn: entry.affectedVersions } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n });\n diagnostics.push({\n severity: 'warning',\n code: entry.advisory ?? 'composer-audit',\n message: entry.title ?? `${entry.package} reported by composer audit.`,\n source: 'composer-audit',\n });\n } catch {\n // Ignore malformed composer audit lines; raw output is preserved.\n }\n }\n return { diagnostics, vulnerabilities, outdated: [] };\n}\n\nfunction parseComposerOutdated(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const outdated: LanguagePackageMutation[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const entry = JSON.parse(line) as {\n name?: string;\n version?: string;\n latest?: string;\n description?: string;\n };\n if (!entry.name || entry.version === entry.latest) continue;\n outdated.push({\n name: entry.name,\n previous: entry.version,\n resolved: entry.latest ?? entry.version,\n });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${entry.name}: ${entry.version ?? '?'} \u2192 ${entry.latest ?? '?'}`,\n source: 'composer-outdated',\n });\n } catch {\n // Skip malformed line; the raw output remains available.\n }\n }\n return { diagnostics, vulnerabilities: [], outdated };\n}\n\nfunction parseDotnetPackage(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n const outdated: LanguagePackageMutation[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities, outdated };\n }\n const projects = (root as { projects?: Array<{ frameworks?: unknown; packages?: unknown }> })\n .projects;\n if (!Array.isArray(projects)) return { diagnostics, vulnerabilities, outdated };\n for (const project of projects) {\n const packages = Array.isArray(project.packages) ? project.packages : [];\n for (const pkg of packages as Array<Record<string, unknown>>) {\n const name = typeof pkg.name === 'string' ? pkg.name : 'unknown';\n const requested = typeof pkg.requestedVersion === 'string' ? pkg.requestedVersion : undefined;\n const resolved = typeof pkg.resolvedVersion === 'string' ? pkg.resolvedVersion : undefined;\n const vulnerabilitiesRaw = Array.isArray(pkg.vulnerabilities) ? pkg.vulnerabilities : [];\n for (const vuln of vulnerabilitiesRaw as Array<Record<string, unknown>>) {\n const advisory =\n typeof vuln.advisoryUrl === 'string' ? vuln.advisoryUrl : 'dotnet-vulnerable';\n vulnerabilities.push({\n package: name,\n advisory,\n severity: mapSeverity(typeof vuln.severity === 'string' ? vuln.severity : undefined),\n });\n }\n if (vulnerabilitiesRaw.length > 0) {\n diagnostics.push({\n severity: 'warning',\n code: 'dotnet-vulnerable',\n message: `${name} has ${vulnerabilitiesRaw.length} known vulnerability entry/entries.`,\n source: 'dotnet-package',\n });\n }\n if (\n requested &&\n resolved &&\n requested.startsWith('>') &&\n requested.split('>')[1]!.split('.').slice(0, 2).join('.') !==\n resolved.split('.').slice(0, 2).join('.')\n ) {\n outdated.push({ name, requested, resolved });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${name}: ${requested} \u2192 ${resolved}`,\n source: 'dotnet-package',\n });\n }\n }\n }\n return { diagnostics, vulnerabilities, outdated };\n}\n\nfunction mapSeverity(value: string | undefined): LanguagePackageVulnerability['severity'] {\n switch (value?.toLowerCase()) {\n case 'critical':\n case 'high':\n return 'high';\n case 'medium':\n case 'moderate':\n return 'moderate';\n case 'low':\n return 'low';\n case 'unknown':\n return 'unknown';\n default:\n return 'unknown';\n }\n}\n\nfunction mapOutdatedKind(value: string | undefined): 'runtime' | 'development' | 'optional' {\n switch (value?.toLowerCase()) {\n case 'devdependencies':\n case 'development':\n return 'development';\n case 'optionaldependencies':\n case 'optional':\n return 'optional';\n default:\n return 'runtime';\n }\n}\n\nfunction parseLinePattern(\n text: string,\n regex: RegExp,\n root: string,\n source: string,\n details: (\n match: RegExpMatchArray,\n fallback: string,\n ) => { severity: LanguageDiagnostic['severity']; message: string },\n): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n for (const match of text.matchAll(regex)) {\n const parsed = details(match, match.at(-1)?.trim() ?? 'Diagnostic');\n diagnostics.push({\n severity: parsed.severity,\n message: parsed.message,\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source,\n });\n }\n return diagnostics;\n}\n\nfunction normalizeDiagnosticPath(value: string, root: string): string {\n const clean = value.trim().replace(/^['\"]|['\"]$/g, '');\n return path.resolve(root, clean);\n}\n\nfunction normalizeSeverity(value: string | undefined): LanguageDiagnostic['severity'] {\n if (value === 'warning' || value === 'warn') return 'warning';\n if (value === 'info' || value === 'note' || value === 'help') return 'info';\n if (value === 'hint') return 'hint';\n return 'error';\n}\n\nfunction toPositiveInt(value: string | undefined): number {\n return Math.max(1, Number.parseInt(value ?? '1', 10) || 1);\n}\n\nfunction summarize(diagnostics: readonly LanguageDiagnostic[]): LanguageRunSummary {\n return {\n errors: diagnostics.filter((item) => item.severity === 'error').length,\n warnings: diagnostics.filter((item) => item.severity === 'warning').length,\n infos: diagnostics.filter((item) => item.severity === 'info' || item.severity === 'hint')\n .length,\n };\n}\n\nfunction emptySummary(): LanguageRunSummary {\n return { errors: 0, warnings: 0, infos: 0 };\n}\n\nfunction dedupeDiagnostics(items: readonly LanguageDiagnostic[]): LanguageDiagnostic[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = [\n item.source,\n item.code ?? '',\n item.file ?? '',\n item.range?.start.line ?? 0,\n item.range?.start.column ?? 0,\n item.message,\n ].join('\\0');\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction compareDiagnostics(a: LanguageDiagnostic, b: LanguageDiagnostic): number {\n return (\n (a.file ?? '').localeCompare(b.file ?? '') ||\n (a.range?.start.line ?? 0) - (b.range?.start.line ?? 0) ||\n (a.range?.start.column ?? 0) - (b.range?.start.column ?? 0) ||\n severityRank(a.severity) - severityRank(b.severity) ||\n (a.code ?? '').localeCompare(b.code ?? '') ||\n a.message.localeCompare(b.message)\n );\n}\n\nfunction severityRank(value: LanguageDiagnostic['severity']): number {\n return value === 'error' ? 0 : value === 'warning' ? 1 : value === 'info' ? 2 : 3;\n}\n", "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ToolProgressEvent } from '@wrongstack/core/types';\nimport { type SpawnStreamResult, spawnStream } from '../_spawn-stream.js';\nimport { normalizeCommandOutput } from '../_util.js';\nimport {\n diagnosticsForInternalSyntax,\n parseLanguageDiagnostics,\n parsePackageReports,\n} from './diagnostics.js';\nimport { validateCommandPlan } from './plan.js';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n CommandPlan,\n DetectedWorkspace,\n LanguagePackageMutation,\n LanguagePackageOutcome,\n LanguagePackageVulnerability,\n LanguageRunResult,\n LanguageRunSummary,\n} from './types.js';\n\nconst MAX_INTERNAL_SOURCE_BYTES = 1_500_000;\n\nexport interface ExecuteLanguagePlanOptions {\n projectRoot: string;\n workspace: DetectedWorkspace;\n plan: CommandPlan;\n signal: AbortSignal;\n}\n\nexport async function* executeLanguagePlan(\n options: ExecuteLanguagePlanOptions,\n): AsyncGenerator<ToolProgressEvent, LanguageRunResult> {\n const { plan, workspace } = options;\n if (options.signal.aborted) {\n return terminalResult(options, 'cancelled', options.signal.reason);\n }\n const profile = languageProfileRegistry.get(plan.profileId);\n if (!profile) return unavailableResult(options, `Unknown language profile: ${plan.profileId}`);\n if (workspace.id !== plan.workspaceId || workspace.language !== plan.profileId) {\n return unavailableResult(options, 'Plan and workspace identity do not match.');\n }\n const validation = validateCommandPlan(plan, profile, options.projectRoot);\n if (validation.length > 0) {\n return unavailableResult(options, `Plan failed execution validation: ${validation.join('; ')}`);\n }\n const containmentError = await validatePlanRealpaths(plan, options.projectRoot);\n if (containmentError) return unavailableResult(options, containmentError);\n if (plan.operation.startsWith('package-') || plan.network) {\n return terminalNonPackageResult(\n options,\n 'Package and network plans require the separate language_package tool (Phase 3).',\n );\n }\n\n const startedAt = Date.now();\n yield {\n type: 'log',\n text:\n plan.kind === 'internal'\n ? `Running ${plan.parser}\u2026`\n : `${plan.command} ${plan.args.join(' ')}`,\n data: { language: plan.profileId, operation: plan.operation, workspace: workspace.root },\n };\n\n if (plan.kind === 'internal') {\n try {\n return await executeInternal(options, startedAt);\n } catch (error) {\n return unavailableResult(options, error instanceof Error ? error.message : String(error));\n }\n }\n\n const timeoutController = new AbortController();\n const timer = setTimeout(\n () => timeoutController.abort(new Error('language plan timed out')),\n plan.timeoutMs,\n );\n timer.unref?.();\n const signal = AbortSignal.any([options.signal, timeoutController.signal]);\n let spawned: SpawnStreamResult;\n try {\n const stream = spawnStream({\n cmd: plan.command!,\n args: [...plan.args],\n cwd: plan.cwd,\n signal,\n maxBytes: plan.outputLimitBytes,\n });\n for (;;) {\n const next = await stream.next();\n if (next.done) {\n spawned = next.value;\n break;\n }\n yield next.value;\n }\n } catch (error) {\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n return {\n status: timedOut ? 'timed_out' : cancelled ? 'cancelled' : 'failed',\n language: plan.profileId,\n workspace,\n plan,\n exitCode: null,\n durationMs: Date.now() - startedAt,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: '',\n truncated: false,\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n clearTimeout(timer);\n }\n\n const parsed = parseLanguageDiagnostics(\n plan.parser,\n spawned.stdout,\n spawned.stderr,\n workspace.root,\n );\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n const spawnUnavailable = Boolean(\n spawned.error && /ENOENT|not found|cannot find/i.test(spawned.error),\n );\n const status: LanguageRunResult['status'] = timedOut\n ? 'timed_out'\n : cancelled\n ? 'cancelled'\n : spawnUnavailable\n ? 'unavailable'\n : spawned.exitCode === 0\n ? 'passed'\n : 'failed';\n const raw = [spawned.stdout, spawned.stderr, spawned.error].filter(Boolean).join('\\n');\n return {\n status,\n language: plan.profileId,\n workspace,\n plan,\n exitCode: spawned.exitCode,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output: normalizeCommandOutput(raw, { maxBytes: plan.outputLimitBytes }),\n truncated: spawned.truncated,\n ...(spawned.spoolPath ? { spoolPath: spawned.spoolPath } : {}),\n ...(spawned.error ? { error: spawned.error } : {}),\n };\n}\n\nasync function executeInternal(\n options: ExecuteLanguagePlanOptions,\n startedAt: number,\n): Promise<LanguageRunResult> {\n const target = options.plan.evidence.find((item) => item.kind === 'target')?.path;\n if (!target) return unavailableResult(options, 'Internal syntax plan has no target evidence.');\n const safeTarget = await assertContainedFile(target, options.projectRoot);\n const stat = await fs.stat(safeTarget);\n if (stat.size > MAX_INTERNAL_SOURCE_BYTES) {\n return unavailableResult(\n options,\n `Internal syntax target exceeds ${MAX_INTERNAL_SOURCE_BYTES} bytes.`,\n );\n }\n const source = await fs.readFile(safeTarget, 'utf8');\n const parsed = await diagnosticsForInternalSyntax(options.plan.profileId, safeTarget, source);\n return {\n status: parsed.summary.errors > 0 ? 'failed' : 'passed',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: parsed.summary.errors > 0 ? 1 : 0,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output:\n parsed.summary.errors > 0\n ? `${parsed.summary.errors} syntax error(s) found.`\n : 'Syntax check passed.',\n truncated: false,\n };\n}\n\nasync function validatePlanRealpaths(\n plan: CommandPlan,\n projectRoot: string,\n): Promise<string | undefined> {\n const realRoot = await fs.realpath(projectRoot);\n let realCwd: string;\n try {\n realCwd = await fs.realpath(plan.cwd);\n } catch (error) {\n return `Plan cwd is unavailable: ${error instanceof Error ? error.message : String(error)}`;\n }\n if (!isRealInside(realCwd, realRoot)) return 'Plan cwd resolves outside project root.';\n for (const argument of plan.args) {\n if (!path.isAbsolute(argument)) continue;\n try {\n const realArgument = await fs.realpath(argument);\n if (!isRealInside(realArgument, realRoot)) {\n return `Plan argument resolves outside project root: ${argument}`;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n return `Plan argument could not be resolved safely: ${argument}`;\n }\n }\n }\n return undefined;\n}\n\nfunction isRealInside(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nasync function assertContainedFile(candidate: string, projectRoot: string): Promise<string> {\n const realRoot = await fs.realpath(projectRoot);\n const realTarget = await fs.realpath(candidate);\n const relative = path.relative(realRoot, realTarget);\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new Error(`Internal syntax target resolves outside project root: ${candidate}`);\n }\n return realTarget;\n}\n\nfunction terminalResult(\n options: ExecuteLanguagePlanOptions,\n status: 'cancelled' | 'timed_out',\n reason: unknown,\n): LanguageRunResult {\n const message = reason instanceof Error ? reason.message : reason ? String(reason) : status;\n return {\n status,\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: '',\n truncated: false,\n error: message,\n };\n}\n\nfunction unavailableResult(options: ExecuteLanguagePlanOptions, reason: string): LanguageRunResult {\n return {\n status: 'unavailable',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: reason,\n truncated: false,\n error: reason,\n };\n}\n\nfunction emptySummary(): LanguageRunSummary {\n return { errors: 0, warnings: 0, infos: 0 };\n}\n\nfunction terminalNonPackageResult(\n options: ExecuteLanguagePlanOptions,\n reason: string,\n): LanguageRunResult {\n return {\n status: 'unavailable',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: reason,\n truncated: false,\n error: reason,\n };\n}\n\nexport interface ExecutePackagePlanOptions {\n projectRoot: string;\n workspace: DetectedWorkspace;\n plan: CommandPlan;\n packages: readonly string[];\n signal: AbortSignal;\n}\n\nexport async function* executePackagePlan(\n options: ExecutePackagePlanOptions,\n): AsyncGenerator<ToolProgressEvent, LanguagePackageOutcome> {\n const { plan, workspace } = options;\n const startedAt = Date.now();\n if (options.signal.aborted) {\n yield { type: 'log', text: 'Run cancelled before execution.' };\n return terminalPackageResult(options, 'cancelled', startedAt);\n }\n const profile = languageProfileRegistry.get(plan.profileId);\n if (!profile) {\n yield { type: 'warning', text: `Unknown language profile: ${plan.profileId}` };\n return terminalPackageResult(options, 'unavailable', startedAt, 'Unknown language profile.');\n }\n if (workspace.id !== plan.workspaceId || workspace.language !== plan.profileId) {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n 'Plan and workspace identity do not match.',\n );\n }\n const validation = validateCommandPlan(plan, profile, options.projectRoot);\n if (validation.length > 0) {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n `Plan failed execution validation: ${validation.join('; ')}`,\n );\n }\n const containmentError = await validatePlanRealpaths(plan, options.projectRoot);\n if (containmentError) {\n return terminalPackageResult(options, 'unavailable', startedAt, containmentError);\n }\n\n const manifestsBefore = await snapshotPaths(workspace.manifests);\n const lockfilePaths = collectLockfilePaths(workspace);\n const lockfilesBefore = await snapshotPaths(lockfilePaths);\n const manifestSizesBefore = await snapshotSizes(workspace.manifests);\n const lockfileSizesBefore = await snapshotSizes(lockfilePaths);\n\n yield {\n type: 'log',\n text:\n plan.kind === 'process'\n ? `${plan.command} ${plan.args.join(' ')}`\n : `${plan.parser}: ${plan.operation}`,\n data: {\n language: plan.profileId,\n operation: plan.operation,\n workspace: workspace.root,\n packages: [...options.packages],\n },\n };\n\n const timeoutController = new AbortController();\n const timer = setTimeout(\n () => timeoutController.abort(new Error('language package plan timed out')),\n plan.timeoutMs,\n );\n timer.unref?.();\n const signal = AbortSignal.any([options.signal, timeoutController.signal]);\n let spawned: SpawnStreamResult | undefined;\n let run: LanguageRunResult | undefined;\n let status: LanguagePackageOutcome['status'] = 'unavailable';\n let error: string | undefined;\n try {\n if (plan.kind !== 'process') {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n 'Package operations require an executable plan; internal plans cannot mutate the manifest.',\n );\n }\n const stream = spawnStream({\n cmd: plan.command!,\n args: [...plan.args],\n cwd: plan.cwd,\n signal,\n maxBytes: plan.outputLimitBytes,\n });\n for (;;) {\n const next = await stream.next();\n if (next.done) {\n spawned = next.value;\n break;\n }\n yield next.value;\n }\n } catch (error_) {\n error = error_ instanceof Error ? error_.message : String(error_);\n } finally {\n clearTimeout(timer);\n }\n\n if (spawned) {\n const parsed = parseLanguageDiagnostics(\n plan.parser,\n spawned.stdout,\n spawned.stderr,\n workspace.root,\n );\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n const spawnUnavailable = Boolean(\n spawned.error && /ENOENT|not found|cannot find/i.test(spawned.error),\n );\n status = timedOut\n ? 'timed_out'\n : cancelled\n ? 'cancelled'\n : spawnUnavailable\n ? 'unavailable'\n : spawned.exitCode === 0\n ? 'passed'\n : 'failed';\n error ??= spawned.error;\n const raw = [spawned.stdout, spawned.stderr, spawned.error].filter(Boolean).join('\\n');\n run = {\n status,\n language: plan.profileId,\n workspace,\n plan,\n exitCode: spawned.exitCode,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output: normalizeCommandOutput(raw, { maxBytes: plan.outputLimitBytes }),\n truncated: spawned.truncated,\n ...(spawned.spoolPath ? { spoolPath: spawned.spoolPath } : {}),\n ...(spawned.error ? { error: spawned.error } : {}),\n };\n } else {\n status = options.signal.aborted\n ? 'cancelled'\n : timeoutController.signal.aborted\n ? 'timed_out'\n : 'failed';\n }\n\n if (status !== 'passed') {\n return terminalPackageResult(\n options,\n status,\n startedAt,\n error,\n run,\n manifestsBefore,\n lockfilesBefore,\n );\n }\n\n const manifestsAfter = await snapshotPaths(workspace.manifests);\n const lockfilesAfter = await snapshotPaths(lockfilePaths);\n const manifestSizesAfter = await snapshotSizes(workspace.manifests);\n const lockfileSizesAfter = await snapshotSizes(lockfilePaths);\n const manifestsChanged = await changedPaths(\n manifestsBefore,\n manifestsAfter,\n manifestSizesBefore,\n manifestSizesAfter,\n );\n const lockfilesChanged = await changedPaths(\n lockfilesBefore,\n lockfilesAfter,\n lockfileSizesBefore,\n lockfileSizesAfter,\n );\n const reports = parsePackageReports(plan.parser, spawned?.stdout ?? '', spawned?.stderr ?? '');\n const mutations = packageMutationsFromInputs(options.packages, reports.outdated);\n return {\n workspace,\n language: plan.profileId,\n operation: plan.operation,\n status,\n ...(run ? { run } : {}),\n durationMs: Date.now() - startedAt,\n manifestsBefore,\n lockfilesBefore,\n manifestsAfter,\n lockfilesAfter,\n mutations,\n vulnerabilities: reports.vulnerabilities,\n outdated: reports.outdated,\n manifestsChanged: Object.freeze(manifestsChanged),\n lockfilesChanged: Object.freeze(lockfilesChanged),\n };\n}\n\nfunction packageMutationsFromInputs(\n inputs: readonly string[],\n outdated: readonly LanguagePackageMutation[],\n): readonly LanguagePackageMutation[] {\n const outdatedNames = new Set(outdated.map((entry) => entry.name));\n return inputs\n .filter((name) => !outdatedNames.has(name))\n .map<LanguagePackageMutation>((name) => ({ name, requested: name, kind: 'runtime' }));\n}\n\nasync function snapshotPaths(paths: readonly string[]): Promise<readonly string[]> {\n const existing: string[] = [];\n for (const candidate of paths) {\n try {\n const stat = await fs.stat(candidate);\n if (!stat.isFile()) continue;\n existing.push(candidate);\n } catch {\n // Missing path is fine.\n }\n }\n return Object.freeze(existing);\n}\n\nasync function changedPaths(\n before: readonly string[],\n after: readonly string[],\n beforeSizes?: ReadonlyMap<string, number>,\n afterSizes?: ReadonlyMap<string, number>,\n): Promise<string[]> {\n const beforeSet = new Set(before);\n const afterSet = new Set(after);\n const changed = new Set<string>();\n for (const path of after) {\n if (!beforeSet.has(path)) changed.add(path);\n }\n for (const path of before) {\n if (!afterSet.has(path)) changed.add(path);\n }\n if (beforeSizes && afterSizes) {\n for (const path of after) {\n if (beforeSizes.get(path) !== afterSizes.get(path)) changed.add(path);\n }\n }\n return [...changed].sort();\n}\n\nasync function snapshotSizes(paths: readonly string[]): Promise<ReadonlyMap<string, number>> {\n const sizes = new Map<string, number>();\n for (const candidate of paths) {\n try {\n const stat = await fs.stat(candidate);\n if (stat.isFile()) sizes.set(candidate, stat.size);\n } catch {\n // Skip missing files.\n }\n }\n return sizes;\n}\n\nfunction collectLockfilePaths(workspace: DetectedWorkspace): readonly string[] {\n const explicit = workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.path);\n const detected =\n LOCKFILE_NAMES_BY_PROFILE.get(workspace.language)?.map((name) =>\n path.join(workspace.root, name),\n ) ?? [];\n const merged = new Set<string>();\n for (const candidate of [...explicit, ...detected]) merged.add(candidate);\n return Object.freeze([...merged]);\n}\n\nconst LOCKFILE_NAMES_BY_PROFILE: ReadonlyMap<DetectedWorkspace['language'], readonly string[]> =\n new Map([\n ['typescript', ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock', 'bun.lockb']],\n ['javascript', ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock', 'bun.lockb']],\n ['go', ['go.sum']],\n ['rust', ['Cargo.lock']],\n ['php', ['composer.lock']],\n ['csharp', ['packages.lock.json']],\n ]);\n\nfunction terminalPackageResult(\n options: ExecutePackagePlanOptions,\n status: LanguagePackageOutcome['status'],\n startedAt: number,\n error?: string,\n run?: LanguageRunResult,\n manifestsBefore: readonly string[] = [],\n lockfilesBefore: readonly string[] = [],\n): LanguagePackageOutcome {\n return {\n workspace: options.workspace,\n language: options.plan.profileId,\n operation: options.plan.operation,\n status,\n ...(run ? { run } : {}),\n durationMs: Date.now() - startedAt,\n manifestsBefore,\n lockfilesBefore,\n manifestsAfter: manifestsBefore,\n lockfilesAfter: lockfilesBefore,\n manifestsChanged: Object.freeze([]),\n lockfilesChanged: Object.freeze([]),\n mutations: Object.freeze([]),\n vulnerabilities: Object.freeze([]) as readonly LanguagePackageVulnerability[],\n outdated: Object.freeze([]) as readonly LanguagePackageMutation[],\n ...(error ? { error } : {}),\n };\n}\n", "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { detectLanguageWorkspaces } from './detect.js';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n CommandPlan,\n DetectedWorkspace,\n LanguageOperation,\n LanguageProfile,\n PlanLanguageOptions,\n PlanLanguageResult,\n ProfileContext,\n} from './types.js';\n\nconst MAX_ARGUMENTS = 128;\nconst MAX_ARGUMENT_LENGTH = 4_096;\nconst PACKAGE_NAME_RE = /^(?:@[a-z0-9._-]+\\/)?[a-z0-9._-]+(?:@[a-z0-9*+._~^<>=|-]+)?$/i;\nconst COMPOSER_PACKAGE_RE = /^[a-z0-9_.-]+\\/[a-z0-9_.-]+(?::[a-z0-9*+._~^<>=|-]+)?$/i;\nconst GO_MODULE_RE = /^(?:[a-z0-9.-]+\\.)+[a-z0-9.-]+\\/[a-z0-9._~+/@-]+$/i;\nconst PYTHON_PACKAGE_RE = /^[a-z0-9._-]+(?:\\[[a-z0-9._,-]+\\])?==[a-z0-9*+._!~-]+$/i;\n\nexport async function planLanguageOperation(\n options: PlanLanguageOptions,\n): Promise<PlanLanguageResult> {\n validateOperationOptions(options.operation, options.operationOptions?.packages);\n const detection = await detectLanguageWorkspaces(options);\n const candidates = detection.workspaces.filter((workspace) =>\n workspace.capabilities.includes(options.operation),\n );\n const selected = selectWorkspace(candidates, options);\n if (selected.status !== 'selected') return selected.result;\n\n const profile = (options.profiles ?? languageProfileRegistry.list()).find(\n (item) => item.id === selected.workspace.language,\n );\n if (!profile) {\n return {\n status: 'not_found',\n reason: `Profile ${selected.workspace.language} is unavailable.`,\n candidates,\n };\n }\n if (\n (profile.id === 'typescript' || profile.id === 'javascript') &&\n options.operation !== 'syntax' &&\n selected.workspace.packageManager === undefined &&\n new Set(\n selected.workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.value.toLowerCase()),\n ).size > 1\n ) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: 'Conflicting Node lockfiles make the package manager ambiguous.',\n },\n };\n }\n const resolver = profile.operations[options.operation];\n if (!resolver) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: `${profile.displayName} does not define ${options.operation}.`,\n },\n };\n }\n const canonicalCwd = options.cwd\n ? path.isAbsolute(options.cwd)\n ? options.cwd\n : path.resolve(detection.projectRoot, options.cwd)\n : detection.projectRoot;\n const target = options.target\n ? await canonicalTarget(canonicalCwd, options.target, detection.projectRoot)\n : undefined;\n const ctx: ProfileContext = {\n projectRoot: detection.projectRoot,\n workspace: selected.workspace,\n ...(target ? { target } : {}),\n mode: options.mode ?? 'standard',\n options: options.operationOptions ?? {},\n platform: process.platform,\n pathExists: async (candidate) => {\n try {\n await fs.access(path.resolve(detection.projectRoot, candidate));\n return true;\n } catch {\n return false;\n }\n },\n };\n const result = await resolver(ctx);\n if ('status' in result) {\n return { status: 'unavailable', workspace: selected.workspace, unavailable: result };\n }\n const errors = validateCommandPlan(result, profile, detection.projectRoot);\n if (errors.length > 0) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: `Generated plan failed validation: ${errors.join('; ')}`,\n },\n };\n }\n return { status: 'planned', workspace: selected.workspace, plan: Object.freeze(result) };\n}\n\nexport function validateCommandPlan(\n plan: CommandPlan,\n profile: LanguageProfile,\n projectRoot: string,\n): string[] {\n const errors: string[] = [];\n if (plan.profileId !== profile.id) errors.push('profile id does not match');\n if (!isInside(plan.cwd, projectRoot)) errors.push('cwd is outside project root');\n if (plan.args.length > MAX_ARGUMENTS) errors.push(`argument count exceeds ${MAX_ARGUMENTS}`);\n if (plan.args.some((arg) => arg.length > MAX_ARGUMENT_LENGTH || /[\\r\\n\\0]/.test(arg))) {\n errors.push('arguments contain an invalid or oversized value');\n }\n if (!Number.isFinite(plan.timeoutMs) || plan.timeoutMs < 1 || plan.timeoutMs > 600_000) {\n errors.push('timeout is outside 1..600000ms');\n }\n if (\n !Number.isFinite(plan.outputLimitBytes) ||\n plan.outputLimitBytes < 1 ||\n plan.outputLimitBytes > 1_000_000\n ) {\n errors.push('output limit is outside 1..1000000 bytes');\n }\n if (plan.kind === 'internal') {\n if (plan.command !== null || plan.args.length !== 0)\n errors.push('internal plans cannot declare a command');\n } else {\n if (!plan.command || !profile.executables.includes(plan.command)) {\n errors.push(`executable \"${plan.command ?? ''}\" is not allowlisted by the profile`);\n }\n }\n if (Object.keys(plan.env).length > 0)\n errors.push('Phase 1 plans cannot override environment variables');\n return errors;\n}\n\nfunction selectWorkspace(\n candidates: readonly DetectedWorkspace[],\n options: PlanLanguageOptions,\n):\n | { status: 'selected'; workspace: DetectedWorkspace }\n | { status: 'result'; result: PlanLanguageResult } {\n if (candidates.length === 0) {\n return {\n status: 'result',\n result: {\n status: 'not_found',\n reason: `No workspace supports ${options.operation}.`,\n candidates: [],\n },\n };\n }\n if (options.workspace) {\n const requested = path.isAbsolute(options.workspace)\n ? path.resolve(options.workspace)\n : path.resolve(options.projectRoot, options.workspace);\n const matches = candidates.filter(\n (item) => item.id === options.workspace || path.resolve(item.root) === requested,\n );\n if (matches.length === 1) return { status: 'selected', workspace: matches[0]! };\n return {\n status: 'result',\n result: {\n status: 'not_found',\n reason: `Requested workspace \"${options.workspace}\" was not detected.`,\n candidates: [...candidates],\n },\n };\n }\n if (options.target) {\n const base = options.cwd\n ? path.isAbsolute(options.cwd)\n ? path.resolve(options.cwd)\n : path.resolve(options.projectRoot, options.cwd)\n : path.resolve(options.projectRoot);\n const target = path.isAbsolute(options.target)\n ? path.resolve(options.target)\n : path.resolve(base, options.target);\n const targeted = candidates\n .filter((item) => item.evidence.some((evidence) => evidence.kind === 'target'))\n .sort(\n (a, b) =>\n workspaceDepth(b.root, options.projectRoot) -\n workspaceDepth(a.root, options.projectRoot) || compareCandidates(a, b),\n );\n if (targeted[0]) return { status: 'selected', workspace: targeted[0] };\n const containing = candidates\n .filter((item) => isInside(target, item.root))\n .sort(\n (a, b) =>\n workspaceDepth(b.root, options.projectRoot) -\n workspaceDepth(a.root, options.projectRoot) || compareCandidates(a, b),\n );\n if (containing[0]) return { status: 'selected', workspace: containing[0] };\n }\n const sorted = [...candidates].sort(compareCandidates);\n const first = sorted[0]!;\n const firstDepth = workspaceDepth(first.root, options.projectRoot);\n const tied = sorted.filter(\n (item) =>\n item.confidence === first.confidence &&\n workspaceDepth(item.root, options.projectRoot) === firstDepth,\n );\n if (tied.length > 1) {\n return {\n status: 'result',\n result: {\n status: 'ambiguous',\n reason:\n 'Multiple workspaces have equal confidence; provide target, language, or workspace.',\n candidates: tied,\n },\n };\n }\n return { status: 'selected', workspace: first };\n}\n\nfunction compareCandidates(a: DetectedWorkspace, b: DetectedWorkspace): number {\n return (\n b.confidence - a.confidence ||\n a.language.localeCompare(b.language) ||\n a.root.localeCompare(b.root)\n );\n}\n\nfunction workspaceDepth(workspaceRoot: string, projectRoot: string): number {\n const relative = path.relative(path.resolve(projectRoot), path.resolve(workspaceRoot));\n return relative === '' ? 0 : relative.split(path.sep).length;\n}\n\nfunction validateOperationOptions(\n operation: LanguageOperation,\n packages?: readonly string[],\n): void {\n if (!operation.startsWith('package-') || !packages) return;\n for (const value of packages) {\n if (!value || value.length > 214 || value.startsWith('-') || /[\\r\\n\\0;&|`$<>\\\\]/.test(value)) {\n throw new Error(`Invalid package identifier \"${value}\"`);\n }\n if (\n value.startsWith('.') ||\n value.startsWith('/') ||\n /^[A-Za-z]:/.test(value) ||\n value.includes('://')\n ) {\n throw new Error(`Package paths and URLs are not supported: \"${value}\"`);\n }\n if (\n !PACKAGE_NAME_RE.test(value) &&\n !COMPOSER_PACKAGE_RE.test(value) &&\n !GO_MODULE_RE.test(value) &&\n !PYTHON_PACKAGE_RE.test(value)\n ) {\n throw new Error(`Invalid package identifier \"${value}\"`);\n }\n }\n}\n\nasync function canonicalTarget(cwd: string, target: string, projectRoot: string): Promise<string> {\n const resolved = path.isAbsolute(target) ? path.resolve(target) : path.resolve(cwd, target);\n let real: string;\n try {\n real = await fs.realpath(resolved);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n const parent = await fs.realpath(path.dirname(resolved));\n real = path.join(parent, path.basename(resolved));\n }\n if (!isInside(real, projectRoot)) throw new Error(`target is outside project root: ${target}`);\n return real;\n}\n\nfunction isInside(candidate: string, root: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(candidate));\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import * as path from 'node:path';\nimport type { Tool, ToolStreamEvent } from '@wrongstack/core/types';\nimport { spawnStream } from './_spawn-stream.js';\nimport { normalizeCommandOutput, safeResolve } from './_util.js';\nimport { tryLegacyCodeOperation } from './languages/legacy-bridge.js';\n\ninterface TypecheckInput {\n project?: string | undefined;\n cwd?: string | undefined;\n strict?: boolean | undefined;\n all?: boolean | undefined;\n /** Emit JSON for machine-readable output (default: false). */\n json?: boolean | undefined;\n}\n\ninterface TypecheckOutput {\n project: string;\n exit_code: number;\n errors: number;\n warnings: number;\n output: string;\n truncated: boolean;\n}\n\nexport const typecheckTool: Tool<TypecheckInput, TypecheckOutput> = {\n name: 'typecheck',\n category: 'Code Quality',\n description:\n \"Run the project's TypeScript type checker (`tsc --noEmit` or equivalent). Essential for verifying type safety before making changes or committing.\",\n usageHint:\n 'ALWAYS RUN BEFORE CONSIDERING WORK COMPLETE:\\n\\n' +\n '- Use this to catch type errors early.\\n' +\n '- In monorepos, `all: true` will check every package.\\n' +\n '- This is one of the most important quality gates in this project.\\n' +\n 'Never claim a task is done without a clean typecheck (unless the user explicitly says otherwise).',\n permission: 'confirm',\n mutating: false,\n timeoutMs: 120_000,\n capabilities: ['shell.restricted'],\n icon: 'code',\n inputSchema: {\n type: 'object',\n properties: {\n project: { type: 'string', description: 'Path to tsconfig.json (default: auto-detect)' },\n cwd: { type: 'string', description: 'Working directory (default: cwd)' },\n strict: {\n type: 'boolean',\n description: 'Add --strict flag for maximum type checking (default: false)',\n },\n all: {\n type: 'boolean',\n description: 'Type-check all projects (pnpm -r) (default: false)',\n },\n json: {\n type: 'boolean',\n description: 'Emit JSON output from tsc (default: false)',\n },\n },\n },\n async execute(input, ctx, opts) {\n let final: TypecheckOutput | undefined;\n const executeStream = typecheckTool.executeStream;\n if (!executeStream) throw new Error('typecheckTool: stream execution unavailable');\n for await (const ev of executeStream(input, ctx, opts)) {\n if (ev.type === 'final') final = ev.output;\n }\n if (!final) throw new Error('typecheck: stream ended without final event');\n return final;\n },\n async *executeStream(input, ctx, opts): AsyncGenerator<ToolStreamEvent<TypecheckOutput>> {\n const cwd = input.cwd ? safeResolve(input.cwd, ctx) : ctx.cwd;\n\n // Delegate to the language planner for non-JS ecosystems (Go, Rust, PHP, C#).\n const bridge = await tryLegacyCodeOperation('semantic', {\n cwd,\n projectRoot: ctx.projectRoot,\n signal: opts.signal,\n });\n if (bridge?.run) {\n const run = bridge.run;\n yield {\n type: 'final',\n output: {\n project: `${bridge.language} workspace`,\n exit_code: run.exitCode ?? 0,\n errors: run.summary.errors,\n warnings: run.summary.warnings,\n output: normalizeCommandOutput(run.output || run.error || ''),\n truncated: run.truncated,\n },\n };\n return;\n }\n\n let args: string[];\n let project: string;\n if (input.all) {\n args = ['--noEmit'];\n project = 'workspace';\n } else {\n const tsconfig = input.project ? safeResolve(input.project, ctx) : await findTsConfig(cwd);\n args = ['--noEmit'];\n if (input.strict) args.push('--strict');\n if (tsconfig) args.push('--project', tsconfig);\n project = tsconfig ?? 'default';\n }\n if (input.json) args.push('--json');\n\n yield { type: 'log', text: `tsc ${args.join(' ')}`, data: { project } };\n\n const result = yield* spawnStream({\n cmd: 'npx',\n args: ['tsc', ...args],\n cwd,\n signal: opts.signal,\n maxBytes: 200_000,\n });\n\n const errors = [...result.stdout.matchAll(/\\berror\\b/gi)].length;\n const warnings = [...result.stdout.matchAll(/\\bwarning\\b/gi)].length;\n\n yield {\n type: 'final',\n output: {\n project,\n exit_code: result.exitCode,\n errors,\n warnings,\n output: normalizeCommandOutput(result.stdout || result.stderr || result.error || ''),\n truncated: result.truncated,\n },\n };\n },\n};\n\nasync function findTsConfig(cwd: string): Promise<string | null> {\n const { stat } = await import('node:fs/promises');\n const candidates = ['tsconfig.json', 'tsconfig.base.json'];\n for (const f of candidates) {\n try {\n const s = await stat(path.join(cwd, f));\n if (s.isFile()) return path.join(cwd, f);\n } catch {\n // continue\n }\n }\n return null;\n}\n", "import { spawn } from 'node:child_process';\nimport {\n emitProcessCompleted,\n emitProcessOutput,\n emitProcessStarted,\n} from '@wrongstack/core/observability';\nimport { buildChildEnv } from '@wrongstack/core/utils';\nimport type { ToolProgressEvent } from '@wrongstack/core/types';\nimport { createOutputSpool, spoolNote } from './_output-spool.js';\nimport { getProcessRegistry, redactCommand } from './process-registry.js';\nimport {\n buildWin32CmdShimInvocation,\n resolveWin32Command,\n} from './_win32-resolve.js';\n\nconst isWin = process.platform === 'win32';\nexport interface SpawnStreamResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n truncated: boolean;\n error?: string | undefined;\n /** When the output exceeded maxBytes, the FULL output was spooled here. */\n spoolPath?: string | undefined;\n /** Total output bytes produced (only set when spooled). */\n spoolBytes?: number | undefined;\n}\n\nexport interface SpawnStreamOptions {\n cmd: string;\n args: string[];\n cwd: string;\n signal: AbortSignal;\n maxBytes?: number | undefined;\n /** Bytes of new stdout/stderr to accumulate before yielding a `partial_output` event. */\n flushBytes?: number | undefined;\n /** Maximum chunks to buffer before applying backpressure to the child. Default 500. */\n maxQueueSize?: number | undefined;\n}\n\n/**\n * Spawn a child process and yield `partial_output` progress events as\n * stdout/stderr arrive (batched by byte threshold), then return the full\n * buffered result. Shared between install/lint/format/typecheck/test/audit\n * so the TUI live tail sees consistent progress regardless of which tool\n * is running.\n */\nexport async function* spawnStream(\n opts: SpawnStreamOptions,\n): AsyncGenerator<ToolProgressEvent, SpawnStreamResult> {\n const max = opts.maxBytes ?? 200_000;\n const flushAt = opts.flushBytes ?? 4 * 1024;\n const maxQueue = opts.maxQueueSize ?? 500;\n let stdout = '';\n let stderr = '';\n let pending = '';\n let error: string | undefined;\n // Full-output spool: stdout/stderr keep only the first `max` bytes for the\n // model. Once the combined output exceeds that, the FULL stream goes to a\n // file and the result carries a marker \u2014 so a huge vitest/tsc run lands on\n // disk, not in the host heap or the chat history.\n const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });\n\n const resolved = resolveWin32Command(opts.cmd);\n const needsShell = isWin && (resolved.endsWith('.cmd') || resolved.endsWith('.bat'));\n const shim = needsShell ? buildWin32CmdShimInvocation(resolved, opts.args) : null;\n const cmd = shim?.command ?? resolved;\n const args = shim?.args ?? opts.args;\n\n // On Windows the abort signal is handled manually below instead of being\n // passed to spawn(): Node's built-in handling kills only the direct child.\n // With the .cmd/.bat shell wrapper the real command (vitest, tsc, \u2026) is a\n // *grandchild* of cmd.exe \u2014 killing the wrapper orphans it, the orphan\n // keeps the inherited stdio pipes open (so 'close' never fires) and\n // streams into this process for the rest of the session. registry.kill()\n // tree-kills via taskkill /T instead \u2014 same rationale as bash.ts/exec.ts.\n const child = spawn(cmd, args, {\n cwd: opts.cwd,\n env: buildChildEnv(),\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n ...(isWin ? {} : { signal: opts.signal }),\n ...(shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}),\n });\n\n // Register with the global registry so Ctrl+C / /kill can find and\n // tree-kill it \u2014 spawnStream consumers (test/lint/typecheck/install/\u2026)\n // were previously invisible to the registry.\n const registry = getProcessRegistry();\n const pid = child.pid;\n const processStartedAt = Date.now();\n let stdoutBytes = 0;\n let stderrBytes = 0;\n let telemetryCompleted = false;\n emitProcessStarted({\n ...(pid !== undefined ? { pid } : {}),\n parentPid: process.pid,\n command: redactCommand(`${opts.cmd} ${opts.args.join(' ')}`),\n args: redactCommand(opts.args.join(' ')).split(' ').filter(Boolean),\n cwd: opts.cwd,\n background: false,\n startedAt: new Date(processStartedAt).toISOString(),\n });\n if (typeof pid === 'number') {\n registry.register({\n pid,\n name: opts.cmd,\n command: redactCommand(`${opts.cmd} ${opts.args.join(' ')}`),\n startedAt: Date.now(),\n child,\n });\n }\n\n type Chunk = { kind: 'out' | 'err' | 'close' | 'error'; data: string; code?: number | undefined; signal?: string | undefined };\n const queue: Chunk[] = [];\n let waiter: (() => void) | undefined;\n let paused = false;\n const wake = () => {\n if (waiter) {\n const w = waiter;\n waiter = undefined;\n w();\n }\n };\n\n // Resume the stream when there's room in the queue\n const resume = () => {\n if (paused && queue.length < maxQueue) {\n paused = false;\n child.stdout?.resume();\n child.stderr?.resume();\n }\n };\n\n // Note: chunks may still arrive briefly after pause() (already in flight) \u2014\n // they are accumulated and queued rather than dropped, so the queue can\n // overshoot maxQueue by a few entries but no output is silently lost.\n // Named handlers so the teardown in `finally` can detach them.\n const onOut = (c: Buffer) => {\n const s = c.toString();\n stdoutBytes += c.byteLength;\n emitProcessOutput({ pid, stream: 'stdout', chunk: c });\n if (stdout.length < max) stdout += s;\n spool.write(s);\n queue.push({ kind: 'out', data: s });\n wake();\n // Apply backpressure if queue is growing faster than we consume\n if (!paused && queue.length >= maxQueue) {\n paused = true;\n child.stdout?.pause();\n child.stderr?.pause();\n }\n };\n const onErr = (c: Buffer) => {\n const s = c.toString();\n stderrBytes += c.byteLength;\n emitProcessOutput({ pid, stream: 'stderr', chunk: c });\n if (stderr.length < max) stderr += s;\n spool.write(s);\n queue.push({ kind: 'err', data: s });\n wake();\n if (!paused && queue.length >= maxQueue) {\n paused = true;\n child.stdout?.pause();\n child.stderr?.pause();\n }\n };\n child.stdout?.on('data', onOut);\n child.stderr?.on('data', onErr);\n child.on('error', (e) => {\n error = e.message;\n queue.push({ kind: 'error', data: e.message });\n wake();\n });\n const completeTelemetry = (code: number, signal?: string | undefined, timedOut = false) => {\n if (telemetryCompleted) return;\n telemetryCompleted = true;\n emitProcessCompleted({\n ...(pid !== undefined ? { pid } : {}),\n exitCode: code,\n ...(signal ? { signal } : {}),\n durationMs: Date.now() - processStartedAt,\n stdoutBytes,\n stderrBytes,\n timedOut,\n endedAt: new Date().toISOString(),\n });\n };\n child.on('close', (code, signal) => {\n if (typeof pid === 'number') registry.unregister(pid);\n const exitCode = code ?? (signal ? 1 : 0);\n completeTelemetry(exitCode, signal ?? undefined);\n queue.push({ kind: 'close', data: '', code: exitCode, ...(signal ? { signal } : {}) });\n wake();\n });\n\n // Abort: tree-kill the child and wake the consumer loop with a synthetic\n // close (exit code 124, matching exec.ts's timeout convention). Without\n // the sentinel the loop can park forever on `waiter` when the pipes are\n // paused (queue full) or a win32 orphan holds them open \u2014 the executor's\n // iter.return() then never completes, the tool call hangs for the rest of\n // the session and retains the queue (up to maxQueue chunks) on the heap.\n //\n // Only on Windows: on POSIX the signal is already passed to spawn() above\n // (line 72) so Node.js handles the kill via the signal; attaching a second\n // handler here would double-kill the child and leak the listener when the\n // generator exits without aborting.\n const onAbort = () => {\n if (typeof pid === 'number') {\n registry.kill(pid, { force: true });\n } else {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already gone */\n }\n }\n queue.push({ kind: 'close', data: '', code: 124 });\n completeTelemetry(124, 'SIGKILL', true);\n wake();\n };\n if (isWin) {\n if (opts.signal.aborted) onAbort();\n else opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n let exitCode = 0;\n let spawnFailed = false;\n try {\n for (;;) {\n while (queue.length === 0) {\n await new Promise<void>((resolve) => {\n waiter = resolve;\n });\n }\n const chunk = queue.shift()!;\n // Resume reading after consuming a chunk\n resume();\n if (chunk.kind === 'close') {\n // If we already saw a spawn error (ENOENT etc.), keep exitCode=1\n // rather than the negative platform code Node fabricates.\n if (!spawnFailed) exitCode = chunk.code ?? 0;\n break;\n }\n if (chunk.kind === 'error') {\n spawnFailed = true;\n exitCode = 1;\n // close usually follows\n continue;\n }\n pending += chunk.data;\n if (pending.length >= flushAt) {\n yield { type: 'partial_output', text: pending };\n pending = '';\n }\n }\n if (pending.length > 0) {\n yield { type: 'partial_output', text: pending };\n }\n\n const spooled = spool.finalize();\n return {\n // The marker rides on stdout's tail so every consumer's head+tail\n // normalization keeps it without per-tool changes.\n stdout: spooled ? stdout + spoolNote(spooled) : stdout,\n stderr,\n exitCode,\n truncated: stdout.length >= max || stderr.length >= max,\n error,\n spoolPath: spooled?.path,\n spoolBytes: spooled?.bytes,\n };\n } finally {\n // Teardown \u2014 this generator can be abandoned mid-stream (executor\n // timeout/abort, or the consumer erroring out of its for-await loop).\n // The data handlers would otherwise stay attached and keep queueing\n // output with no consumer (bounded only by the pause cap), and a\n // surviving child would keep the closures \u2014 queue, output buffers,\n // child handle \u2014 alive until OOM. Detach the handlers, destroy the\n // pipes, and make sure nothing is left running.\n spool.finalize(); // idempotent \u2014 closes the file if the stream was abandoned\n if (isWin) opts.signal.removeEventListener('abort', onAbort);\n child.stdout?.off('data', onOut);\n child.stderr?.off('data', onErr);\n child.stdout?.destroy();\n child.stderr?.destroy();\n if (child.exitCode === null && !child.killed) {\n if (typeof pid === 'number') {\n registry.kill(pid, { force: true });\n } else {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already gone */\n }\n }\n }\n }\n}\n", "/**\n * _output-spool \u2014 file-based capture of FULL command output.\n *\n * Command tools (bash/exec and the _spawn-stream consumers) cap what they\n * keep in memory and what reaches the model (COMMAND_OUTPUT_MAX_BYTES head+\n * tail). Everything past the cap used to be silently dropped, which pushed\n * agents to re-run commands with bigger buffers or stuff huge outputs into\n * chat history. The spool keeps the host's memory and the context window\n * small while losing nothing: once a command's output exceeds the in-memory\n * threshold, the FULL stream is written to a log file under\n * `~/.wrongstack/tool-output/` and the capped tool result carries a\n * `[full output: <path>]` marker so the model can read/grep the file\n * selectively instead of dumping it into context.\n *\n * Properties:\n * - zero disk I/O for small outputs (file is created lazily on first byte\n * past the threshold; the buffered head is flushed at that moment)\n * - bounded memory: the head buffer never exceeds the threshold, and disk\n * backpressure drops chunks past a 4 MB writable-buffer high-water mark\n * (counted and reported in the marker) instead of queueing them on the heap\n * - best-effort: any fs error disables the spool silently \u2014 command tools\n * must never fail because diagnostics couldn't be written\n * - retention: spool files older than 7 days are swept once per process\n */\nimport { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { wstackGlobalRoot } from '@wrongstack/core/utils';\n\nconst SPOOL_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n/** Stop queueing chunks on the heap when the fs stream falls this far behind. */\nconst SPOOL_WRITE_HWM_BYTES = 4 * 1024 * 1024;\n\nlet sweepStarted = false;\n\n/** Directory for spooled command output (under the wstack global root). */\nexport function toolOutputDir(): string {\n return path.join(wstackGlobalRoot(), 'tool-output');\n}\n\n/** Reset module state \u2014 test hook (per-process sweep memo + nothing else). */\nexport function _resetOutputSpoolForTests(): void {\n sweepStarted = false;\n}\n\nfunction sweepOldSpoolFiles(dir: string): void {\n if (sweepStarted) return;\n sweepStarted = true;\n void (async () => {\n try {\n const now = Date.now();\n for (const name of await fsp.readdir(dir)) {\n if (!name.endsWith('.log')) continue;\n const p = path.join(dir, name);\n try {\n const st = await fsp.stat(p);\n if (now - st.mtimeMs > SPOOL_RETENTION_MS) await fsp.unlink(p);\n } catch {\n /* concurrently removed \u2014 ignore */\n }\n }\n } catch {\n /* directory doesn't exist yet \u2014 nothing to sweep */\n }\n })();\n}\n\nexport interface SpoolInfo {\n /** Absolute path of the spool file. */\n path: string;\n /** Total bytes of output produced (including what reached the file). */\n bytes: number;\n /** Bytes dropped due to disk backpressure (0 in the normal case). */\n droppedBytes: number;\n}\n\nexport interface OutputSpool {\n /** Feed every raw output chunk. Never throws. */\n write(text: string): void;\n /**\n * Close the file (if one was opened) and return its info, or null when the\n * output never exceeded the threshold. Idempotent.\n */\n finalize(): SpoolInfo | null;\n}\n\nexport interface CreateOutputSpoolOptions {\n /** Tool name used in the spool filename (sanitized). */\n tool: string;\n /**\n * Output size at which the spool activates. Should match the tool's\n * in-memory cap so files are only created for output the model can't\n * already see in full. Default 32 KB.\n */\n thresholdBytes?: number | undefined;\n}\n\n/**\n * Render the marker line appended to a capped tool result. Kept in one place\n * so every command tool phrases it identically (and tests can match it).\n */\nexport function spoolNote(info: SpoolInfo): string {\n const dropped =\n info.droppedBytes > 0 ? `, ~${info.droppedBytes} bytes dropped under backpressure` : '';\n return `\\n[output truncated \u2014 full ${info.bytes} bytes at ${info.path}${dropped}; read/grep that file selectively instead of re-running with more output]`;\n}\n\nexport function createOutputSpool(opts: CreateOutputSpoolOptions): OutputSpool {\n const threshold = opts.thresholdBytes ?? 32_768;\n const safeTool = opts.tool.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 40) || 'tool';\n\n let head = '';\n let headBytes = 0;\n let totalBytes = 0;\n let droppedBytes = 0;\n let stream: WriteStream | null = null;\n let filePath: string | null = null;\n let failed = false;\n let finalized = false;\n\n const open = (): void => {\n if (stream || failed) return;\n try {\n const dir = toolOutputDir();\n // Synchronous on purpose: createWriteStream would race an async mkdir\n // and error with ENOENT. This runs at most once per oversized command,\n // and after the first call the dir exists (mkdirSync is a no-op stat).\n mkdirSync(dir, { recursive: true });\n sweepOldSpoolFiles(dir);\n const stamp = new Date().toISOString().replace(/[:.]/g, '-');\n const rand = Math.random().toString(36).slice(2, 6);\n filePath = path.join(dir, `${stamp}-${safeTool}-${rand}.log`);\n stream = createWriteStream(filePath, { flags: 'w', encoding: 'utf8' });\n stream.on('error', () => {\n // Disk full / permission \u2014 disable the spool, keep the tool alive.\n failed = true;\n stream = null;\n filePath = null;\n });\n // Flush the buffered head first so the file is the complete output.\n stream.write(head);\n } catch {\n failed = true;\n stream = null;\n filePath = null;\n }\n };\n\n return {\n write(text: string): void {\n if (finalized || !text) return;\n totalBytes += Buffer.byteLength(text, 'utf8');\n if (!stream && !failed) {\n if (headBytes + text.length <= threshold) {\n head += text;\n headBytes += text.length;\n return;\n }\n head += text; // include the crossing chunk so the file misses nothing\n open();\n head = ''; // flushed into the stream by open(); release the heap copy\n return;\n }\n if (stream) {\n if (stream.writableLength > SPOOL_WRITE_HWM_BYTES) {\n droppedBytes += Buffer.byteLength(text, 'utf8');\n return;\n }\n stream.write(text);\n }\n },\n finalize(): SpoolInfo | null {\n if (finalized) {\n return filePath ? { path: filePath, bytes: totalBytes, droppedBytes } : null;\n }\n finalized = true;\n head = '';\n if (!stream || !filePath) return null;\n try {\n stream.end();\n } catch {\n /* already closed */\n }\n return { path: filePath, bytes: totalBytes, droppedBytes };\n },\n };\n}\n", "/**\n * ProcessRegistry \u2014 global singleton that tracks all spawned child processes\n * from `bash` and `exec` tools. Enables:\n *\n * - Listing active processes (for TUI status bar)\n * - Killing individual processes or all processes (for Ctrl+C and /kill)\n * - Detecting runaway processes (hung, looping)\n * - Circuit breaker integration to prevent recursive/repeated failures\n *\n * Thread-safety: Node.js is single-threaded, but async callbacks can fire\n * in any order. All mutations go through synchronized Map methods.\n */\nimport { spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport * as os from 'node:os';\nimport { CircuitBreaker, type CircuitBreakerSnapshot, type CircuitBreakerConfig } from './circuit-breaker.js';\nexport type { CircuitBreakerSnapshot, CircuitBreakerConfig } from './circuit-breaker.js';\n\nexport interface TrackedProcess {\n pid: number;\n name: string;\n /** Display-safe redacted command string \u2014 safe for logs, /ps, crash dumps.\n * Contains [REDACTED] in place of sensitive flag values. */\n command: string;\n startedAt: number;\n sessionId?: string | undefined;\n /** The raw ChildProcess handle. Never call .kill() directly on this \u2014\n * use `kill()` below which handles process groups correctly on POSIX\n * and degrades gracefully on Windows. */\n child: ChildProcess;\n /** True only when this child was spawned as a POSIX process-group/session\n * leader (for example `spawn(..., { detached: true })`) and `pid` is the\n * actual `child.pid`. Negative-PID signaling is host-wide dangerous for\n * values like -1, so tests and manually registered entries must not opt in. */\n processGroupLeader?: boolean | undefined;\n /** True once the process has been kill()ed but not yet exited.\n * We keep it in the registry until 'close' fires so callers can\n * distinguish \"still running\" from \"just exited\". */\n killed: boolean;\n /** If true, kill() and killAll() will refuse to kill this process.\n * Used for infrastructure processes (browser, dev servers, \u2026) that\n * must outlive the agent session. */\n protected: boolean;\n /** True for an explicitly detached/background tool launch. */\n background: boolean;\n}\n\n// redactCommand (and its sensitive-flag patterns) lives in _redact-command.ts\n// so registry-only consumers (e.g. ps-slash) don't carry its dependencies.\n// Re-exported here to keep this module's historical public API intact.\nexport { redactCommand } from './_redact-command.js';\n\ninterface KillOpts {\n /** SIGKILL instead of SIGTERM. Default: false (SIGTERM first). */\n force?: boolean | undefined;\n /** MS to wait between SIGTERM and SIGKILL on POSIX. Default: 2000. */\n graceMs?: number | undefined;\n /** Leave explicitly backgrounded jobs alive. Default false. */\n preserveBackground?: boolean | undefined;\n}\n\n/**\n * Snapshot of the armed auto kill/reset countdown, or null when nothing is\n * armed. `remainingMs` ticks down in real time; the TUI statusline renders it.\n */\nexport interface BreakerCountdown {\n remainingMs: number;\n totalMs: number;\n}\n\ntype BreakerCountdownListener = (snapshot: BreakerCountdown | null) => void;\n\nexport interface RegistryStats {\n activeCount: number;\n backgroundCount: number;\n totalCount: number;\n breaker: CircuitBreakerSnapshot;\n}\n\nconst DEFAULT_GRACE_MS = 2000;\nconst WIN32_TASKKILL_TIMEOUT_MS = 5000;\n\ninterface Win32TreeKillOptions {\n /**\n * Upper bound for taskkill itself before the caller's fallback may run.\n * This is deliberately separate from POSIX SIGTERM grace: on Windows the\n * direct-child fallback must not fire while taskkill is still walking the\n * child tree, or it can orphan grandchildren that keep stdio open.\n */\n timeoutMs?: number | undefined;\n onSettled?: (() => void) | undefined;\n}\n\n/**\n * Kill an entire process tree on Windows via `taskkill /T /F`.\n *\n * TerminateProcess (what `child.kill()` maps to) has no process-group\n * semantics, so killing a shell wrapper (`cmd.exe /c \u2026`) orphans its\n * grandchildren (node, vitest forks, dev servers). The orphans inherit the\n * parent's stdio pipe handles and can keep streaming into this process for\n * the rest of the session \u2014 which both prevents the child's 'close' event\n * from ever firing and grows in-memory output buffers without bound.\n *\n * Returns true if taskkill was spawned, false if spawning it failed (caller\n * should fall back to a direct `child.kill()`). Callers that need a direct\n * fallback should pass `onSettled`; it runs after taskkill exits, errors, or\n * exceeds `timeoutMs`, avoiding the race where killing cmd.exe first prevents\n * taskkill from enumerating and killing grandchildren.\n */\nexport function killWin32Tree(pid: number, opts: Win32TreeKillOptions = {}): boolean {\n try {\n const child = spawn('taskkill', ['/pid', String(pid), '/T', '/F'], {\n stdio: 'ignore',\n windowsHide: true,\n });\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const settle = () => {\n if (settled) return;\n settled = true;\n if (timeout) clearTimeout(timeout);\n try {\n opts.onSettled?.();\n } catch {\n /* fallback callbacks are best-effort */\n }\n };\n // spawn() reports a failure to launch (e.g. taskkill not on PATH, blocked by\n // security software) via an ASYNC 'error' event \u2014 the surrounding try/catch\n // only traps synchronous throws. Without a listener that event is unhandled\n // and crashes the whole process. Swallow it: this is best-effort tree-kill\n // and the registry still has the direct child.kill() fallback.\n child.on('error', settle);\n child.on('close', settle);\n timeout = setTimeout(() => {\n try {\n child.kill();\n } catch {\n /* already exited */\n }\n settle();\n }, Math.max(1, opts.timeoutMs ?? WIN32_TASKKILL_TIMEOUT_MS));\n timeout.unref?.();\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nexport class ProcessRegistryImpl {\n private readonly processes = new Map<number, TrackedProcess>();\n private readonly breaker: CircuitBreaker;\n\n /**\n * Auto kill/reset config. When the breaker trips and `autoKillResetMs > 0`,\n * a countdown is armed; on expiry all tracked processes are killed and the\n * breaker is reset to closed (forced recovery). Zero means manual recovery\n * only (`/kill reset`).\n */\n private autoKillResetMs = 0;\n private autoKillTimer: ReturnType<typeof setTimeout> | null = null;\n private autoKillArmedAt: number | null = null;\n private breakerCountdownListeners: BreakerCountdownListener[] = [];\n\n constructor(breakerConfig?: CircuitBreakerConfig) {\n this.breaker = new CircuitBreaker(breakerConfig);\n // Arm on trip, cancel on recovery. Listeners are best-effort.\n this.breaker.onTrip = () => this._armAutoKillReset();\n this.breaker.onReset = () => this._cancelAutoKillReset();\n // Protection is OFF by default \u2014 the user opts in via `/settings breaker on`.\n this.breaker.setEnabled(false);\n }\n\n register(\n info: Omit<TrackedProcess, 'killed' | 'protected' | 'background'> & {\n protected?: boolean | undefined;\n background?: boolean | undefined;\n },\n ): void {\n this.processes.set(info.pid, {\n ...info,\n killed: false,\n protected: info.protected ?? false,\n background: info.background ?? false,\n });\n }\n\n private _isSafeSignalPid(pid: number): boolean {\n return Number.isInteger(pid) && pid > 1 && pid !== process.pid && pid !== process.ppid;\n }\n\n private _canSignalProcessGroup(p: TrackedProcess): boolean {\n return (\n os.platform() !== 'win32' &&\n p.processGroupLeader === true &&\n this._isSafeSignalPid(p.pid) &&\n typeof p.child.pid === 'number' &&\n p.child.pid === p.pid\n );\n }\n\n private _killChildDirect(p: TrackedProcess, signal: NodeJS.Signals): void {\n try {\n p.child.kill(signal);\n } catch {\n // Process may have already exited, or this may be a persistent entry\n // without a live ChildProcess handle in the current process.\n }\n }\n\n private _killPosix(p: TrackedProcess, signal: NodeJS.Signals): void {\n if (this._canSignalProcessGroup(p)) {\n try {\n process.kill(-p.pid, signal);\n return;\n } catch {\n // Process group may already be gone; fall back to the direct child.\n }\n }\n this._killChildDirect(p, signal);\n }\n\n /** Unregister a process by PID. Called on 'close' / 'exit' events. */\n unregister(pid: number): void {\n this.processes.delete(pid);\n }\n\n /** Get a single process by PID. */\n get(pid: number): TrackedProcess | undefined {\n this._pruneStale(pid);\n return this.processes.get(pid);\n }\n\n /** Get all tracked processes. */\n list(): TrackedProcess[] {\n this._pruneAllStale();\n return Array.from(this.processes.values());\n }\n\n /** Get processes filtered by name (e.g. 'bash', 'exec'). */\n byName(name: string): TrackedProcess[] {\n return this.list().filter((p) => p.name === name);\n }\n\n /** Get processes filtered by session. */\n bySession(sessionId: string): TrackedProcess[] {\n return this.list().filter((p) => p.sessionId === sessionId);\n }\n\n /** Count of active (non-killed) processes. */\n get activeCount(): number {\n let n = 0;\n for (const p of this.processes.values()) {\n if (!p.killed) n++;\n }\n return n;\n }\n\n /** Count of active jobs explicitly launched in background mode. */\n get activeBackgroundCount(): number {\n let n = 0;\n for (const p of this.processes.values()) {\n if (p.background && !p.killed) n++;\n }\n return n;\n }\n\n /**\n * Combined stats for observability \u2014 used by /ps and the TUI status bar.\n */\n stats(): RegistryStats {\n this._pruneAllStale();\n return {\n activeCount: this.activeCount,\n backgroundCount: this.activeBackgroundCount,\n totalCount: this.processes.size,\n breaker: this.breaker.snapshot(),\n };\n }\n\n /**\n * Returns true if the circuit allows a new bash/exec call to proceed.\n * When false, callers MUST NOT spawn a process.\n */\n get canProceed(): boolean {\n return this.breaker.canProceed;\n }\n\n /**\n * Called before spawning a process. Returns true if allowed; false if\n * the circuit breaker is open.\n *\n * @param bypass - If true, skip circuit breaker check (for background processes).\n */\n beforeCall(bypass = false): boolean {\n return this.breaker.beforeCall(bypass);\n }\n\n /**\n * Called after a process finishes. `durationMs` is wall-clock time;\n * `failed` is true for non-zero exit codes.\n *\n * @param bypass - If true, do not update circuit breaker state (for background processes).\n */\n afterCall(durationMs: number, failed: boolean, bypass = false): void {\n this.breaker.afterCall(durationMs, failed, bypass);\n }\n\n /** Force-open the circuit breaker (Ctrl+C, /kill force). */\n forceBreakerOpen(): void {\n this.breaker.forceOpen();\n }\n\n /** Force-reset the circuit breaker to closed (/kill reset). */\n forceBreakerReset(): void {\n this.breaker.forceReset();\n }\n\n /**\n * Configure circuit-breaker protection at runtime. Called from `/settings`\n * (instant, all modes) and on TUI mount (applies persisted config).\n *\n * - `enabled` toggles whether the breaker gates `bash`/`exec`.\n * - `autoKillResetMs` arms the auto kill/reset countdown when the breaker\n * trips (0 = manual recovery only).\n *\n * Re-applies cleanly on every call: cancels a pending countdown when the\n * timeout is cleared or protection disabled, and re-arms if the breaker is\n * currently open under the new settings.\n */\n setBreakerConfig(cfg: { enabled?: boolean | undefined; autoKillResetMs?: number | undefined }): void {\n if (cfg.enabled !== undefined) this.breaker.setEnabled(cfg.enabled);\n if (cfg.autoKillResetMs !== undefined) this.autoKillResetMs = Math.max(0, cfg.autoKillResetMs);\n\n if (this.autoKillResetMs <= 0) {\n this._cancelAutoKillReset();\n return;\n }\n // If protection is active and the breaker is currently tripped, ensure a\n // countdown is armed for the new window (covers a live config change while\n // the breaker is already open).\n if (this.breaker.isEnabled && this.breaker.snapshot().state === 'open') {\n this._armAutoKillReset();\n }\n }\n\n /**\n * Live countdown to the next auto kill/reset, or null when nothing is armed.\n * The TUI polls this on a 1s tick while armed so the statusline decrements.\n */\n getBreakerCountdown(): BreakerCountdown | null {\n if (this.autoKillArmedAt === null || this.autoKillResetMs <= 0) return null;\n const elapsed = Date.now() - this.autoKillArmedAt;\n return { remainingMs: Math.max(0, this.autoKillResetMs - elapsed), totalMs: this.autoKillResetMs };\n }\n\n /**\n * Subscribe to countdown arm/cancel events. Returns an unsubscribe function.\n * Use {@link getBreakerCountdown} for the live ticking value between events.\n */\n onBreakerCountdownChange(listener: BreakerCountdownListener): () => void {\n this.breakerCountdownListeners.push(listener);\n return () => {\n this.breakerCountdownListeners = this.breakerCountdownListeners.filter((l) => l !== listener);\n };\n }\n\n private _emitBreakerCountdown(): void {\n const snap = this.getBreakerCountdown();\n for (const l of this.breakerCountdownListeners) {\n try {\n l(snap);\n } catch {\n /* listener failure must never affect breaker behavior */\n }\n }\n }\n\n /**\n * Arm the auto kill/reset countdown. Idempotent: re-arming resets the window\n * (a fresh trip after a failed half-open probe restarts the clock). No-op\n * when protection is off or no timeout is configured.\n */\n private _armAutoKillReset(): void {\n if (this.autoKillResetMs <= 0 || !this.breaker.isEnabled) return;\n this._clearAutoKillTimer();\n this.autoKillArmedAt = Date.now();\n this.autoKillTimer = setTimeout(() => {\n this.autoKillTimer = null;\n this.autoKillArmedAt = null;\n // Forced recovery: nuke runaway processes and reopen the circuit.\n this.killAll({ force: false, preserveBackground: true });\n this.breaker.forceReset();\n this._emitBreakerCountdown();\n }, this.autoKillResetMs);\n // Don't keep the event loop alive purely for auto-recovery.\n this.autoKillTimer.unref?.();\n this._emitBreakerCountdown();\n }\n\n private _cancelAutoKillReset(): void {\n const wasArmed = this.autoKillArmedAt !== null;\n this._clearAutoKillTimer();\n if (wasArmed) {\n this.autoKillArmedAt = null;\n this._emitBreakerCountdown();\n }\n }\n\n private _clearAutoKillTimer(): void {\n if (this.autoKillTimer !== null) {\n clearTimeout(this.autoKillTimer);\n this.autoKillTimer = null;\n }\n }\n\n /** Kill a single process by PID.\n *\n * On POSIX: sends SIGTERM to the *process group* (-pid) so that\n * runaway grandchild processes (`sleep 9999 & disown`) are also killed.\n * After `graceMs` a SIGKILL is sent if the process hasn't exited.\n *\n * On Windows: `child.kill()` maps to TerminateProcess \u2014 process groups\n * are not meaningfully supported. A second `force=true` call sends\n * SIGKILL (which maps to TerminateProcess again \u2014 the distinction is\n * in the exit code, not the signal).\n *\n * Returns true if the process was found and kill was attempted.\n */\n kill(pid: number, opts: KillOpts = {}): boolean {\n this._pruneStale(pid);\n const p = this.processes.get(pid);\n if (!p) return false;\n if (p.killed) return true; // already kill()ed, don't double-send\n if (p.protected) return false; // protected processes are never kill()ed\n if (opts.preserveBackground && p.background) return false;\n\n const { force = false, graceMs = DEFAULT_GRACE_MS } = opts;\n const isWin = os.platform() === 'win32';\n\n if (isWin) {\n // Windows: no process group semantics. A direct kill terminates only\n // the immediate child \u2014 shell-wrapped commands (cmd.exe /c \u2026) leave\n // grandchildren running that hold the inherited stdio pipes open and\n // keep feeding output into this process indefinitely. Kill the whole\n // tree via taskkill instead, but only for a real, still-running child\n // (exitCode === null); test fakes and already-exited processes take\n // the plain-kill path. The direct kill is deliberately NOT sent\n // immediately alongside taskkill: killing the root first would break\n // taskkill's parent-pid tree enumeration and orphan the grandchildren\n // again \u2014 it runs as a delayed fallback instead.\n const liveRealChild = p.child.exitCode === null && typeof p.child.pid === 'number';\n const directFallback = () => {\n if (p.child.exitCode === null) {\n try {\n p.child.kill('SIGKILL');\n } catch {\n // Process may have already exited.\n }\n }\n };\n if (\n liveRealChild &&\n killWin32Tree(pid, {\n timeoutMs: Math.max(graceMs, WIN32_TASKKILL_TIMEOUT_MS),\n onSettled: directFallback,\n })\n ) {\n // The direct fallback is intentionally chained from taskkill's\n // completion. Killing cmd.exe before taskkill has walked the tree can\n // orphan the real command and leave stdio pipes open forever.\n } else {\n try {\n p.child.kill(force ? 'SIGKILL' : 'SIGTERM');\n } catch {\n // Process may have already exited.\n }\n }\n p.killed = true;\n return true;\n }\n\n // POSIX: kill the process group only when the tracked child is proven to\n // be the group leader. Otherwise use child.kill(); negative PID signaling\n // with untrusted/fake PIDs can target unrelated host processes.\n try {\n if (force) {\n this._killPosix(p, 'SIGKILL');\n } else {\n this._killPosix(p, 'SIGTERM');\n // Schedule SIGKILL as backup.\n const timer = setTimeout(() => {\n // Re-check: process may have exited on its own.\n if (this.processes.has(pid) && !p.child.killed) {\n this._killPosix(p, 'SIGKILL');\n }\n }, graceMs);\n timer.unref?.(); // Don't keep event loop alive.\n }\n } catch {\n // Process may have already exited.\n }\n p.killed = true;\n return true;\n }\n\n /**\n * Kill all tracked processes.\n * Returns the PIDs that were kill()ed.\n */\n killAll(opts: KillOpts = {}): number[] {\n const pids = Array.from(this.processes.keys());\n const killed: number[] = [];\n for (const pid of pids) {\n const p = this.processes.get(pid);\n if (p && !p.protected && this.kill(pid, opts)) killed.push(pid);\n }\n return killed;\n }\n\n /**\n * Kill all processes for a specific session.\n * Returns the PIDs that were kill()ed.\n */\n killSession(sessionId: string, opts: KillOpts = {}): number[] {\n const pids = this.bySession(sessionId).map((p) => p.pid);\n const killed: number[] = [];\n for (const pid of pids) {\n if (this.kill(pid, opts)) killed.push(pid);\n }\n return killed;\n }\n\n /**\n * Check whether a tracked process entry is stale \u2014 the child has exited\n * (exitCode !== null) AND it's been in the registry long enough that the\n * OS may have reused the PID for a new, unrelated process.\n *\n * P3 #24 (before-release.md): on POSIX, PIDs are reused after process\n * exit. If a tracked process exits but its 'close' event hasn't fired yet\n * (or was missed), the registry still holds the entry. A new process\n * gets the same PID, and PID-based lookups (get, kill, shouldBlockKill)\n * may incorrectly protect or target the wrong process.\n *\n * The 60s threshold is conservative \u2014 the OS typically waits much longer\n * before reusing a PID, but we want to clean up before that becomes a risk.\n */\n private _isStaleEntry(entry: TrackedProcess): boolean {\n return entry.child.exitCode !== null && Date.now() - entry.startedAt > 60_000;\n }\n\n /**\n * Remove a stale entry for a specific PID before any PID-based lookup.\n * This prevents PID reuse from causing the registry to act on a dead\n * process that has been replaced by a new one with the same PID.\n */\n private _pruneStale(pid: number): void {\n const entry = this.processes.get(pid);\n if (entry && this._isStaleEntry(entry)) {\n this.processes.delete(pid);\n }\n }\n\n /**\n * Remove every stale entry, not just one PID. `list()`/`stats()` \u2014 the\n * surfaces the TUI status bar and `/ps` poll \u2014 must prune too: a child\n * whose 'close' event never fires (e.g. Windows grandchildren holding stdio\n * open) would otherwise linger in the registry until someone looks up its\n * exact PID, and PID reuse meanwhile makes `get()`/`kill()` target the\n * wrong process. RAM-leak audit 2026-07-31, MEDIUM.\n */\n private _pruneAllStale(): void {\n for (const [pid, entry] of this.processes) {\n if (this._isStaleEntry(entry)) this.processes.delete(pid);\n }\n }\n}\n\n/** Module-level singleton. Initialized on first access. */\nlet _registry: ProcessRegistryImpl | undefined;\n\nexport function getProcessRegistry(): ProcessRegistryImpl {\n if (!_registry) {\n _registry = new ProcessRegistryImpl();\n }\n return _registry;\n}\n\n/** Reset for tests. */\nexport function _resetProcessRegistry(): void {\n _registry = undefined;\n}\n\n// \u2500\u2500 Convenience re-exports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type { KillOpts };\n", "/**\n * CircuitBreaker \u2014 prevents runaway bash/exec tool chains by:\n *\n * - Tripping on consecutive failures (models that keep repeating the\n * same failing command, e.g. `npm install` with wrong args in a loop)\n * - Tripping on slow call ratio (too many long-running commands suggest\n * a hung subprocess that the model doesn't know how to kill)\n * - Rate-limiting bursts (rapid succession of commands without reading\n * output suggests the model isn't processing results)\n * - Auto-recovering after a cooldown period so a fixed model can resume\n *\n * The breaker is owned by the ProcessRegistry so any tool that registers\n * a process participates in the same circuit. \"Per-tool\" isolation is\n * intentionally NOT implemented \u2014 the model treats bash/exec as one\n * resource pool; isolating them would let the model route around the\n * breaker by alternating which tool it uses.\n */\n\nexport interface CircuitBreakerConfig {\n /**\n * Consecutive failures before trip. Default: 5.\n * A single success resets this counter to 0.\n */\n maxConsecutiveFailures?: number | undefined;\n /**\n * Slow-call threshold in ms. A call that runs longer than this is\n * counted as \"slow\". Default: 60_000 (1 minute).\n */\n slowCallThresholdMs?: number | undefined;\n /**\n * Max slow calls before trip (within the sliding window). Default: 3.\n */\n maxSlowCalls?: number | undefined;\n /**\n * Sliding window for rate-limit and slow-call counting, in ms.\n * Default: 60_000 (1 minute).\n */\n windowMs?: number | undefined;\n /**\n * Max calls within the sliding window. Default: 30.\n * Burst exceeding this trips the breaker immediately.\n */\n maxCallsPerWindow?: number | undefined;\n /**\n * Cooldown before auto-recovery attempt, in ms. Default: 30_000 (30s).\n * After this the breaker enters \"half-open\" state and allows one call\n * through to test whether the problem is resolved.\n */\n cooldownMs?: number | undefined;\n}\n\ninterface CallRecord {\n at: number;\n /** True if the call threw or returned an is_error result. */\n failed: boolean;\n /** True if elapsed time exceeded slowCallThresholdMs. */\n slow: boolean;\n}\n\ntype BreakerState = 'closed' | 'open' | 'half-open';\n\nconst DEFAULT_MAX_CONSECUTIVE_FAILURES = 5;\nconst DEFAULT_SLOW_CALL_THRESHOLD_MS = 180_000;\n// 3 minutes \u2014 balanced against the 5-minute bash timeout. Commands\n// running <3min are normal; 3-5min are \"slow\" and count toward the\n// breaker. 3 consecutive slow calls trip the circuit.\nconst DEFAULT_MAX_SLOW_CALLS = 3;\nconst DEFAULT_WINDOW_MS = 60_000;\nconst DEFAULT_MAX_CALLS_PER_WINDOW = 30;\nconst DEFAULT_COOLDOWN_MS = 30_000;\n\nexport interface CircuitBreakerSnapshot {\n state: 'closed' | 'open' | 'half-open';\n consecutiveFailures: number;\n slowCallsInWindow: number;\n callsInWindow: number;\n windowMs: number;\n cooldownRemainingMs: number | null;\n lastFailureAt: number | null;\n lastSlowAt: number | null;\n}\n\nexport class CircuitBreaker {\n private readonly maxConsecutiveFailures: number;\n private readonly slowCallThresholdMs: number;\n private readonly maxSlowCalls: number;\n private readonly windowMs: number;\n private readonly maxCallsPerWindow: number;\n private readonly cooldownMs: number;\n\n private state: BreakerState = 'closed';\n private consecutiveFailures = 0;\n private window: CallRecord[] = [];\n private lastFailureAt: number | null = null;\n private lastSlowAt: number | null = null;\n /** Timestamp when the breaker was opened (for cooldown calculation). */\n private openedAt: number | null = null;\n\n /**\n * Master enable flag. When false the breaker is bypassed: `beforeCall`\n * always returns true and `afterCall` records nothing. The class itself\n * defaults to enabled (so the standalone unit tests exercise tripping); the\n * ProcessRegistry flips this off until the user opts in via `/settings`.\n */\n private enabled = true;\n\n /**\n * Fired (best-effort) when the breaker transitions into the `open` state.\n * The registry uses this to arm its auto kill/reset countdown.\n */\n onTrip?: (() => void) | undefined;\n /**\n * Fired (best-effort) when the breaker returns to `closed` after having been\n * open/half-open. The registry uses this to cancel a pending kill/reset.\n */\n onReset?: (() => void) | undefined;\n\n constructor(config: CircuitBreakerConfig = {}) {\n this.maxConsecutiveFailures = config.maxConsecutiveFailures ?? DEFAULT_MAX_CONSECUTIVE_FAILURES;\n this.slowCallThresholdMs = config.slowCallThresholdMs ?? DEFAULT_SLOW_CALL_THRESHOLD_MS;\n this.maxSlowCalls = config.maxSlowCalls ?? DEFAULT_MAX_SLOW_CALLS;\n this.windowMs = config.windowMs ?? DEFAULT_WINDOW_MS;\n this.maxCallsPerWindow = config.maxCallsPerWindow ?? DEFAULT_MAX_CALLS_PER_WINDOW;\n this.cooldownMs = config.cooldownMs ?? DEFAULT_COOLDOWN_MS;\n }\n\n /** Toggle the master enable. Disabling resets to a clean `closed` state. */\n setEnabled(enabled: boolean): void {\n if (this.enabled === enabled) return;\n this.enabled = enabled;\n if (!enabled) this._reset();\n }\n\n get isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Returns true if the circuit allows a new call to proceed.\n * When false, callers should abort the tool call and return a\n * circuit-breaker error instead of spawning a process.\n */\n get canProceed(): boolean {\n if (!this.enabled) return true;\n this._checkStateTransition();\n return this.state !== 'open';\n }\n\n /**\n * Snapshot of the current breaker state for observability (`/kill`).\n */\n snapshot(): CircuitBreakerSnapshot {\n this._checkStateTransition();\n const now = Date.now();\n let cooldownRemaining: number | null = null;\n if (this.openedAt !== null && this.state === 'open') {\n const elapsed = now - this.openedAt;\n cooldownRemaining = Math.max(0, this.cooldownMs - elapsed);\n }\n return {\n state: this.state,\n consecutiveFailures: this.consecutiveFailures,\n slowCallsInWindow: this.window.filter((c) => c.slow).length,\n callsInWindow: this.window.length,\n windowMs: this.windowMs,\n cooldownRemainingMs: cooldownRemaining,\n lastFailureAt: this.lastFailureAt,\n lastSlowAt: this.lastSlowAt,\n };\n }\n\n /**\n * Call this BEFORE spawning a bash/exec process.\n * Returns true if the call is allowed; false if the breaker is open.\n * When false, callers MUST NOT spawn a process.\n *\n * @param bypass - If true, skip the circuit breaker check entirely.\n * Use for background/fire-and-forget processes that should\n * not affect breaker state.\n */\n beforeCall(bypass = false): boolean {\n if (bypass || !this.enabled) return true;\n this._checkStateTransition();\n if (this.state === 'open') return false;\n return true;\n }\n\n /**\n * Call this AFTER a bash/exec process finishes (success or failure).\n * `durationMs` is the wall-clock time the process ran.\n * `failed` is true when the process returned a non-zero exit code or\n * threw an exception before spawning.\n *\n * @param bypass - If true, do not update breaker state.\n * Use for background/fire-and-forget processes.\n */\n afterCall(durationMs: number, failed: boolean, bypass = false): void {\n if (bypass || !this.enabled) return;\n\n const now = Date.now();\n\n if (this.state === 'half-open') {\n // First call through after cooldown \u2014 if it failed, go back to open.\n if (failed) {\n this._trip();\n return;\n }\n // Success in half-open \u2192 reset to closed.\n this._reset();\n return;\n }\n\n // Prune old records outside the sliding window.\n this._pruneWindow(now);\n\n const slow = durationMs >= this.slowCallThresholdMs;\n this.window.push({ at: now, failed, slow });\n\n if (failed) {\n this.consecutiveFailures++;\n this.lastFailureAt = now;\n if (this.consecutiveFailures >= this.maxConsecutiveFailures) {\n this._trip();\n }\n return;\n }\n\n // Success: reset consecutive failure counter.\n this.consecutiveFailures = 0;\n\n if (slow) {\n this.lastSlowAt = now;\n const slowCount = this.window.filter((c) => c.slow).length;\n if (slowCount >= this.maxSlowCalls) {\n this._trip();\n }\n }\n\n const callCount = this.window.length;\n if (callCount >= this.maxCallsPerWindow) {\n // Rate limit exceeded. This is a soft trip \u2014 we reset the window\n // and let the next call try immediately (the caller will still see\n // canProceed=false until the window drains naturally).\n this._trip();\n }\n }\n\n /** Force the breaker open. Used by /kill force and Ctrl+C. */\n forceOpen(): void {\n this._trip();\n }\n\n /** Force a reset to closed. Used by tests and /kill reset. */\n forceReset(): void {\n this._reset();\n }\n\n private _trip(): void {\n if (this.state === 'open') return; // already open\n this.state = 'open';\n this.openedAt = Date.now();\n // P3 #23 (before-release.md): clear the window on trip. Old records are\n // irrelevant once tripped \u2014 the breaker starts fresh after cooldown\n // (half-open \u2192 closed resets the counters). Without this the window array\n // holds onto CallRecord entries for its lifetime if no new afterCall()\n // arrives (which is the case when the breaker stays open and no new calls\n // are attempted).\n this.window = [];\n // Best-effort: never let a listener failure corrupt breaker state.\n try {\n this.onTrip?.();\n } catch {\n /* ignored \u2014 observability hook only */\n }\n }\n\n private _reset(): void {\n const wasRecovering = this.state !== 'closed';\n this.state = 'closed';\n this.consecutiveFailures = 0;\n this.window = [];\n this.openedAt = null;\n // Only notify on a real recovery (open/half-open \u2192 closed), not on the\n // initial closed state or an idempotent re-reset.\n if (wasRecovering) {\n try {\n this.onReset?.();\n } catch {\n /* ignored \u2014 observability hook only */\n }\n }\n }\n\n /** Transition from open \u2192 half-open when cooldown elapses. */\n private _checkStateTransition(): void {\n if (this.state !== 'open' || this.openedAt === null) return;\n const elapsed = Date.now() - this.openedAt;\n if (elapsed >= this.cooldownMs) {\n this.state = 'half-open';\n this.openedAt = null;\n }\n }\n\n private _pruneWindow(now: number): void {\n const cutoff = now - this.windowMs;\n this.window = this.window.filter((c) => c.at >= cutoff);\n }\n}", "import { expectDefined } from '@wrongstack/core/utils';\n\n// Sensitive CLI flag patterns that may appear in process command lines.\n// Redacted to [REDACTED] so crash dumps /ps output cannot leak secrets.\n// Split out of process-registry.ts so entries that only need the registry\n// (e.g. ps-slash) don't carry this module's dependencies.\n//\n// NOTE: @wrongstack/core carries its own copy (observability/redact-command.ts)\n// so the emitProcessStarted telemetry producer can redact command+args\n// centrally. Keep these two copies in sync when updating the patterns.\nconst SENSITIVE_FLAG_PATTERNS: RegExp[] = [\n // --flag=value or --flag \"value\" (value captured up to next space or comma)\n /--(?:token|password|passwd|pwd|secret|api[-_]?key|api[-_]?secret|auth|credential|private[-_]?key|access[-_]?key|github[-_]?token|gh[-_]?token|bearer|jwt|oauth|pin|pincode|passphrase|access[-_]?token)(?:[=\\s,][^\\s]*)?/gi,\n // -t short flag (token): attached (-tVALUE), separated (-t VALUE), or -t=VALUE.\n // (?<![-\\w]) anchors to a token start so we don't match the `-t` inside `--token`.\n // NOTE: synced with @wrongstack/core observability/redact-command.ts.\n /(?<![-\\w])-t(?:[=\\s]+)?[^\\s,-]+/,\n // -p|-password|-a (redis auth) short flags: attached + separated + =value.\n // Same token-start anchor; over-redaction is an accepted tradeoff for a\n // redaction function. Synced with core copy.\n /(?<![-\\w])-(?:password|p|a)(?:[=\\s]+)?[^\\s,-]+/gi,\n // env var\u2013style secrets: TOKEN=x, API_KEY=y, etc.\n /(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\\s*[=:]\\s*[^\\s,]+/gi,\n // Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits \u2014 but only\n // when preceded by a flag name (e.g. --github-token=EyJ...).\n /--\\w*(?:token|key|secret|password|passwd|auth|credential)\\w*[=\\s,][A-Za-z0-9+/=]{32,}/,\n];\n\n/**\n * Returns a display-safe copy of `cmd` with sensitive flag values replaced by [REDACTED].\n * The original string is unchanged; this is pure and has no side effects.\n */\nexport function redactCommand(cmd: string): string {\n let result = cmd;\n for (const pattern of SENSITIVE_FLAG_PATTERNS) {\n result = result.replace(pattern, (match) => {\n // Preserve the flag name portion; redact only the value part.\n // e.g. \"--token=sekrit_abc\" \u2192 \"--token=[REDACTED]\"\n const eq = match.indexOf('=');\n const sp = match.search(/\\s/);\n const delim = eq !== -1 ? '=' : sp !== -1 ? match[sp] : null;\n if (delim !== null) {\n const flag = match.slice(0, match.indexOf(expectDefined(delim)) + 1);\n return `${flag}[REDACTED]`;\n }\n // No delimitable separator found in the match.\n if (match.startsWith('--')) {\n // Long flag with no value attached (e.g. a bare \"--token\" argv token).\n // No secret here \u2014 leave it untouched so downstream pair-scan can still\n // recognize the bare flag. NOTE: keep this synced with\n // @wrongstack/core observability/redact-command.ts.\n return match;\n }\n // Short flag attached form (-pVALUE, -tVALUE, -aVALUE): flag name is the\n // leading -X (2 chars); redact everything after. Don't use a greedy\n // [a-zA-Z0-9_-]* flag-name match \u2014 value chars would be consumed into the\n // flag name and the secret would survive. Synced with core copy.\n return `${match.slice(0, 2)}[REDACTED]`;\n });\n }\n return result;\n}\n", "import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * On Windows, Node.js `spawn()` without a shell does NOT resolve .cmd/.bat\n * extensions through PATHEXT \u2014 it only auto-resolves .exe. Most Node.js CLI\n * tools (npx, pnpm, biome, tsc, vitest, etc.) ship as .cmd wrappers on\n * Windows. This function resolves the command name to its full path so spawn\n * can find it without relying on shell-mode argument concatenation.\n *\n * On non-Windows, returns the command unchanged.\n */\nexport function resolveWin32Command(cmd: string): string {\n if (process.platform !== 'win32') return cmd;\n\n // Already has a path or extension \u2014 use as-is\n // Normalize forward slashes so path.extname correctly detects extensions\n // even when a Unix-style path is passed on Windows.\n if (cmd.includes('/') || cmd.includes('\\\\') || path.extname(cmd.replace(/\\//g, '\\\\'))) {\n return cmd;\n }\n\n const pathext = (process.env['PATHEXT'] ?? '.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC')\n .toLowerCase()\n .split(';');\n\n const pathDirs = (process.env['PATH'] ?? '').split(path.delimiter);\n\n for (const dir of pathDirs) {\n const base = path.join(dir, cmd);\n // Check extensions in PATHEXT order. .EXE should win first because\n // it's typically listed first, and .exe doesn't need shell: true.\n for (const ext of pathext) {\n const full = `${base}${ext}`;\n try {\n fs.accessSync(full, fs.constants.X_OK);\n return full;\n } catch {\n // Not found with this extension \u2014 try next\n }\n }\n }\n\n // Not found \u2014 return original; let spawn report ENOENT with the\n // expected error message so tools can surface it properly.\n return cmd;\n}\n\n/**\n * Resolve a PowerShell binary by name. `pickShell` in `_shell-pick.ts`\n * already decides whether the user wants `'pwsh'` (PowerShell 7+) or\n * `'powershell'` (Windows PowerShell 5.1). This helper turns that decision\n * into a real on-disk path.\n *\n * Order:\n * 1. If `cmd` is `pwsh` and a `pwsh.exe` exists on PATH \u2192 return that.\n * 2. If `cmd` is `pwsh` and only `powershell.exe` exists \u2192 fall back to\n * that (the alternative is a cryptic ENOENT for the user).\n * 3. Symmetric for `powershell`: prefer `powershell.exe`, fall back to\n * `pwsh.exe` if installed and the legacy binary is missing.\n * 4. Anything else \u2192 delegate to `resolveWin32Command` (handles `.cmd`\n * shims a sysadmin might drop in place, etc.).\n *\n * Returns the original command on ENOENT \u2014 `spawn()` will surface a clean\n * ENOENT and the user sees \"PowerShell not installed\", which is the right\n * diagnostic. We never throw from here.\n */\nexport function resolvePowerShell(cmd: string): string {\n if (process.platform !== 'win32') return cmd;\n const lower = cmd.toLowerCase();\n if (lower !== 'pwsh' && lower !== 'powershell' && lower !== 'pwsh.exe' && lower !== 'powershell.exe') {\n return resolveWin32Command(cmd);\n }\n // Prefer the requested edition, fall back to the other one.\n const primary = lower.startsWith('pwsh') ? 'pwsh.exe' : 'powershell.exe';\n const fallback = lower.startsWith('pwsh') ? 'powershell.exe' : 'pwsh.exe';\n const resolved = resolveWin32Command(primary);\n if (resolved !== primary) {\n // resolveWin32Command returns the original string when not found.\n const fb = resolveWin32Command(fallback);\n return fb === fallback ? cmd : fb;\n }\n return resolved;\n}\n\n/**\n * cmd.exe metacharacters that chain a new command or redirect I/O. When a\n * `.cmd`/`.bat` wrapper is launched through `cmd.exe`, any argument carrying\n * one of these can break out of the intended command line and run an\n * attacker-chosen command (the CVE-2024-27980 / \"BatBadBut\" argument-injection\n * class). We use a single vetted command line for cmd shims, so this guard is\n * mandatory before spawning.\n *\n * The set is limited to the unambiguous command-separator / redirection chars\n * plus newlines and NUL. Legitimate package-manager / test-runner flags and\n * Windows file paths (which use `:` `\\` `/` `.` `-` `_` space `(` `)`) never\n * contain these, so the guard is false-positive-free. Double quotes are also\n * rejected because cmd.exe quote toggling can break argument grouping.\n */\nconst WIN32_SHELL_META = /[&|<>\"\\r\\n\\0]/;\n\nexport interface Win32CmdShimInvocation {\n command: string;\n args: string[];\n windowsVerbatimArguments: true;\n}\n\n/**\n * Throw if any argument contains a cmd.exe command-injection metacharacter.\n * Call this ONLY on the Windows `.cmd`/`.bat` shim path. A no-op for safe args.\n */\nexport function assertSafeWin32ShellArgs(args: readonly unknown[]): void {\n for (const arg of args) {\n if (typeof arg === 'string' && WIN32_SHELL_META.test(arg)) {\n throw new Error(\n 'win32 cmd shim spawn: argument contains a shell metacharacter ' +\n '(one of & | < > \", or a newline) that could enable command injection ' +\n 'through the .cmd/.bat wrapper - refusing to run. Offending argument: ' +\n JSON.stringify(arg),\n );\n }\n }\n}\n\nexport function buildWin32CmdShimInvocation(\n command: string,\n args: readonly string[] = [],\n): Win32CmdShimInvocation {\n assertSafeWin32ShellArgs([command, ...args]);\n const line = ['call', quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(' ');\n return {\n command: process.env['COMSPEC'] ?? 'cmd.exe',\n args: ['/d', '/c', line],\n windowsVerbatimArguments: true,\n };\n}\n\nfunction quoteWin32CmdArg(arg: string): string {\n return `\"${arg}\"`;\n}\n", "import { createHash } from 'node:crypto';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as Core from '@wrongstack/core/utils';\nimport type { Context } from '@wrongstack/core/agent';\n\n/**\n * sha-256 hex of a UTF-8 string. Used by the file tools to record a content\n * hash alongside the mtime in `ctx.recordRead` \u2014 the hash is the authoritative\n * staleness arbiter for `edit` (mtime has a 2 s tolerance window on Windows).\n */\nexport function sha256hex(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex');\n}\n/** Detected package manager for a project directory. */\nexport type PackageManager = 'pnpm' | 'yarn' | 'npm';\n\n/**\n * Detect the project's package manager by inspecting lockfiles in `cwd`.\n * Order: pnpm \u2192 yarn \u2192 npm (default). Missing or unreadable directories fall\n * back to `npm` rather than throwing, so a `safeResolve`-checked cwd that\n * happens to be empty never aborts the tool.\n */\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const { stat } = await import('node:fs/promises');\n try {\n await stat(`${cwd}/pnpm-lock.yaml`);\n return 'pnpm';\n } catch {\n /* not pnpm */\n }\n try {\n await stat(`${cwd}/yarn.lock`);\n return 'yarn';\n } catch {\n /* not yarn */\n }\n return 'npm';\n}\n\nexport function resolvePath(input: string, ctx: Context): string {\n return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.workingDir ?? ctx.cwd, input);\n}\n\n/**\n * Roots every file tool may always reach, even in restricted mode: the\n * project root and the user-global `~/.wrongstack` directory (config, memory,\n * sessions, skills). `~/.wrongstack` honors the `WRONGSTACK_HOME` override.\n */\nfunction allowedRoots(ctx: Context): string[] {\n return [path.resolve(ctx.projectRoot), path.resolve(Core.wstackGlobalRoot())];\n}\n\n/** True if `target` is `root` itself or nested inside any of `roots`. */\nfunction isInsideAny(target: string, roots: string[]): boolean {\n return roots.some((root) => {\n const rel = path.relative(root, target);\n return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));\n });\n}\n\nexport function ensureInsideRoot(absPath: string, ctx: Context): string {\n const target = path.resolve(absPath);\n // Unrestricted filesystem access: skip the project-root containment check.\n if (ctx.allowOutsideProjectRoot) return target;\n if (isInsideAny(target, allowedRoots(ctx))) return target;\n throw new Error(`Path \"${absPath}\" is outside project root \"${path.resolve(ctx.projectRoot)}\"`);\n}\n\nexport function safeResolve(input: string, ctx: Context): string {\n return ensureInsideRoot(resolvePath(input, ctx), ctx);\n}\n\n/**\n * Defense against in-root\u2192out-of-root symlink escape (CWE-59). `safeResolve`\n * only does a syntactic `../` check, so a symlink that lives *inside* the\n * project root but points outside still passes it. This resolves the path\n * through `fs.realpath` and re-verifies containment against the realpath of\n * the project root (comparing like-for-like, since the root itself may be a\n * symlink \u2014 macOS `/var`\u2192`/private/var`, Windows 8.3 short names). For a path\n * that does not exist yet (e.g. a `write` to a new file) the nearest existing\n * ancestor directory is checked instead. Throws if the real target escapes.\n *\n * Mirrors the per-file guard already used in `replace.ts`/`grep.ts`; applied\n * to single-file `read`/`edit`/`write` it throws (rather than skips) because\n * the caller named exactly one file.\n */\nexport async function assertRealInsideRoot(absPath: string, ctx: Context): Promise<void> {\n // Unrestricted filesystem access: no symlink-escape check to perform.\n if (ctx.allowOutsideProjectRoot) return;\n // Compare like-for-like against the realpath of each always-allowed root\n // (project root + ~/.wrongstack), since a root may itself be a symlink.\n const realRoots = await Promise.all(\n allowedRoots(ctx).map((r) => fsp.realpath(r).catch(() => path.resolve(r))),\n );\n let probe = absPath;\n for (;;) {\n let real: string;\n try {\n real = await fsp.realpath(probe);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n const parent = path.dirname(probe);\n if (parent === probe) return; // reached fs root without escaping\n probe = parent;\n continue;\n }\n throw err;\n }\n if (isInsideAny(real, realRoots)) return;\n throw new Error(\n `Path \"${absPath}\" resolves through a symlink outside project root \"${realRoots[0]}\"`,\n );\n }\n}\n\n/** `safeResolve` + symlink realpath containment check. Async. */\nexport async function safeResolveReal(input: string, ctx: Context): Promise<string> {\n const abs = safeResolve(input, ctx);\n await assertRealInsideRoot(abs, ctx);\n return abs;\n}\n\nexport function truncateMiddle(s: string, max: number): string {\n if (Buffer.byteLength(s, 'utf8') <= max) return s;\n const half = Math.floor(max / 2);\n return (\n s.slice(0, half) +\n `\\n\u2026[truncated ${Buffer.byteLength(s, 'utf8') - max} bytes from middle]\u2026\\n` +\n s.slice(-half)\n );\n}\n\nexport function isBinaryBuffer(buf: Buffer): boolean {\n const len = Math.min(buf.length, 8192);\n for (let i = 0; i < len; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n}\n\n// \u2500\u2500\u2500 Command-output normalization (token-saving) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Raw process output is full of tokens the model gains nothing from: ANSI\n// escapes, carriage-return progress spam, runs of identical warning lines, and\n// huge tails of build noise. These helpers strip that noise before the output\n// reaches the LLM. They are scoped to COMMAND tools (bash/git/exec and the\n// _spawn-stream consumers) \u2014 never applied to structured/code outputs.\n\n/** Unified byte cap for all command tool output fed to the model. */\nexport const COMMAND_OUTPUT_MAX_BYTES = 32_768;\n\n/** Runs of >= this many identical consecutive lines are collapsed. */\nconst REPEAT_RUN_THRESHOLD = 3;\n\n/**\n * Collapse carriage-return overwrites the way a terminal would: `\\r\\n` becomes\n * `\\n`, and a bare `\\r` (progress redraw) keeps only the text after the LAST\n * `\\r` on its physical line. Without this, a single progress bar that redraws\n * 200 times explodes into 200 lines.\n */\nexport function collapseCarriageReturns(text: string): string {\n const lf = text.replace(/\\r\\n/g, '\\n');\n if (!lf.includes('\\r')) return lf;\n return lf\n .split('\\n')\n .map((line) => (line.includes('\\r') ? line.slice(line.lastIndexOf('\\r') + 1) : line))\n .join('\\n');\n}\n\n/**\n * Collapse a run of `minRun`+ identical consecutive lines into the line once\n * plus a marker. Consecutive-only \u2014 it never reorders or dedups non-adjacent\n * lines, so diffs/source stay intact.\n */\nexport function collapseConsecutiveDuplicates(text: string, minRun = REPEAT_RUN_THRESHOLD): string {\n const lines = text.split('\\n');\n const out: string[] = [];\n let i = 0;\n while (i < lines.length) {\n let j = i + 1;\n while (j < lines.length && lines[j] === lines[i]) j++;\n const run = j - i;\n if (run >= minRun) {\n out.push(lines[i]!, `\u2026 \u27E8repeated ${run}\u00D7\u27E9`);\n } else {\n for (let k = i; k < j; k++) out.push(lines[k]!);\n }\n i = j;\n }\n return out.join('\\n');\n}\n\n/** Largest prefix of `s` whose UTF-8 byte length is <= `maxBytes`. */\nfunction takeHeadBytes(s: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n /* v8 ignore next -- only caller (truncateHeadTail) passes a budget smaller than s; defensive. */\n if (Buffer.byteLength(s, 'utf8') <= maxBytes) return s;\n let lo = 0;\n let hi = s.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (Buffer.byteLength(s.slice(0, mid), 'utf8') <= maxBytes) lo = mid;\n else hi = mid - 1;\n }\n return s.slice(0, lo);\n}\n\n/** Largest suffix of `s` whose UTF-8 byte length is <= `maxBytes`. */\nfunction takeTailBytes(s: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n /* v8 ignore next -- only caller (truncateHeadTail) passes a budget smaller than s; defensive. */\n if (Buffer.byteLength(s, 'utf8') <= maxBytes) return s;\n let lo = 0;\n let hi = s.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (Buffer.byteLength(s.slice(s.length - mid), 'utf8') <= maxBytes) lo = mid;\n else hi = mid - 1;\n }\n return s.slice(s.length - lo);\n}\n\n/**\n * Truncate to `maxBytes` keeping BOTH ends \u2014 the head (what ran / early context)\n * and the tail (errors and summaries usually land last), biased ~45/55 toward\n * the tail. The result never exceeds `maxBytes`.\n */\nexport function truncateHeadTail(s: string, maxBytes: number): string {\n const total = Buffer.byteLength(s, 'utf8');\n if (total <= maxBytes) return s;\n // Reserve a fixed allowance for the marker so the final string can't exceed\n // the cap even though the dropped-byte count's digit width varies.\n const MARKER_RESERVE = 64;\n const avail = Math.max(0, maxBytes - MARKER_RESERVE);\n const headBudget = Math.floor(avail * 0.45);\n const head = takeHeadBytes(s, headBudget);\n const tail = takeTailBytes(s, avail - Buffer.byteLength(head, 'utf8'));\n const kept = Buffer.byteLength(head, 'utf8') + Buffer.byteLength(tail, 'utf8');\n return `${head}\\n\u2026[truncated ${total - kept} bytes]\u2026\\n${tail}`;\n}\n\n/**\n * Full token-saving pipeline for command tool output: strip ANSI \u2192 collapse\n * carriage-return progress \u2192 trim trailing whitespace \u2192 collapse identical\n * consecutive lines \u2192 squeeze blank-line runs \u2192 head+tail truncate to the cap.\n */\nexport function normalizeCommandOutput(\n raw: string,\n opts: { maxBytes?: number | undefined } = {},\n): string {\n if (!raw) return raw;\n let text = Core.stripAnsi(raw);\n text = collapseCarriageReturns(text);\n text = text.replace(/[ \\t]+$/gm, ''); // trailing whitespace per line\n text = collapseConsecutiveDuplicates(text);\n text = text.replace(/\\n{3,}/g, '\\n\\n'); // >=2 blank lines \u2192 1\n return truncateHeadTail(text, opts.maxBytes ?? COMMAND_OUTPUT_MAX_BYTES);\n}\n", "/**\n * Legacy-to-language bridge: lets `typecheck`, `lint`, `format`, `test`,\n * `install`, `audit`, and `outdated` delegate through the deterministic\n * language planner when the workspace is a non-JavaScript ecosystem\n * (Go, Rust, PHP, C#).\n *\n * When the workspace IS JavaScript/TypeScript (or has no detected\n * language marker), the bridge returns `null` and the legacy tool\n * continues on its existing code path unchanged. This preserves 100 %\n * backward compatibility for the TS/JS ecosystem where these tools\n * originated.\n */\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nimport { executeLanguagePlan, executePackagePlan, planLanguageOperation } from './index.js';\nimport type {\n LanguageOperation,\n LanguagePackageOutcome,\n LanguageProfileId,\n LanguageRunResult,\n} from './types.js';\n\nconst NON_JS_MARKERS: ReadonlyArray<{ filename: string; language: LanguageProfileId }> = [\n { filename: 'go.mod', language: 'go' },\n { filename: 'go.work', language: 'go' },\n { filename: 'Cargo.toml', language: 'rust' },\n { filename: 'composer.json', language: 'php' },\n];\n\nconst NON_JS_SUFFIXES: ReadonlyArray<{ suffix: string; language: LanguageProfileId }> = [\n { suffix: '.csproj', language: 'csharp' },\n { suffix: '.fsproj', language: 'csharp' },\n];\n\nexport interface LegacyBridgeContext {\n cwd: string;\n projectRoot: string;\n signal: AbortSignal;\n target?: string | undefined;\n}\n\n/**\n * Quick check: does the cwd (or any parent up to projectRoot) contain a\n * non-JS ecosystem marker? Returns the detected language or `null`.\n */\nexport async function detectNonJsEcosystem(\n cwd: string,\n projectRoot: string,\n): Promise<LanguageProfileId | null> {\n try {\n let dir = path.resolve(cwd);\n const root = path.resolve(projectRoot);\n\n for (let depth = 0; depth <= 4 && dir.startsWith(root); depth++) {\n for (const marker of NON_JS_MARKERS) {\n try {\n const s = await fs.stat(path.join(dir, marker.filename));\n if (s.isFile()) return marker.language;\n } catch {\n // not present\n }\n }\n try {\n const entries = await fs.readdir(dir);\n for (const entry of entries) {\n for (const suffix of NON_JS_SUFFIXES) {\n if (entry.toLowerCase().endsWith(suffix.suffix)) return suffix.language;\n }\n }\n } catch {\n // not a directory or not readable\n }\n if (dir === root) break;\n dir = path.dirname(dir);\n }\n } catch {\n // Module mocks or unusual environments may not provide all fs methods.\n // Return null so the legacy tool falls back to its existing path.\n }\n return null;\n}\n\nexport interface LegacyBridgeResult {\n language: LanguageProfileId;\n run?: LanguageRunResult;\n outcome?: LanguagePackageOutcome;\n}\n\n/**\n * Attempt to plan and execute a code-quality operation through the language\n * system. Returns the result or `null` when the workspace is JS/TS or the\n * planner has no plan.\n */\nexport async function tryLegacyCodeOperation(\n operation: LanguageOperation,\n ctx: LegacyBridgeContext,\n): Promise<LegacyBridgeResult | null> {\n const language = await detectNonJsEcosystem(ctx.cwd, ctx.projectRoot);\n if (!language) return null;\n\n const planResult = await planLanguageOperation({\n projectRoot: ctx.projectRoot,\n cwd: ctx.cwd,\n operation,\n language,\n ...(ctx.target ? { target: ctx.target } : {}),\n signal: ctx.signal,\n });\n if (planResult.status !== 'planned') return null;\n\n const runner = executeLanguagePlan({\n projectRoot: ctx.projectRoot,\n workspace: planResult.workspace,\n plan: planResult.plan,\n signal: ctx.signal,\n });\n for (;;) {\n const next = await runner.next();\n if (next.done) return { language, run: next.value };\n }\n}\n\n/**\n * Attempt to plan and execute a package operation through the language\n * system. Returns the result or `null` when the workspace is JS/TS.\n */\nexport async function tryLegacyPackageOperation(\n operation: LanguageOperation,\n ctx: LegacyBridgeContext,\n packages: readonly string[] = [],\n): Promise<LegacyBridgeResult | null> {\n const language = await detectNonJsEcosystem(ctx.cwd, ctx.projectRoot);\n if (!language) return null;\n\n const planResult = await planLanguageOperation({\n projectRoot: ctx.projectRoot,\n cwd: ctx.cwd,\n operation,\n language,\n signal: ctx.signal,\n ...(packages.length > 0 ? { operationOptions: { packages: [...packages] } } : {}),\n });\n if (planResult.status !== 'planned') return null;\n\n const runner = executePackagePlan({\n projectRoot: ctx.projectRoot,\n workspace: planResult.workspace,\n plan: planResult.plan,\n packages,\n signal: ctx.signal,\n });\n for (;;) {\n const next = await runner.next();\n if (next.done) return { language, outcome: next.value };\n }\n}\n", "import { createHash } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n DetectedWorkspace,\n DetectionLimits,\n DetectionResult,\n DetectLanguageOptions,\n LanguageEvidence,\n LanguageProfile,\n} from './types.js';\n\nconst DEFAULT_LIMITS: DetectionLimits = { maxDepth: 6, maxEntries: 5_000 };\nconst SOURCE_WEIGHT = 5;\nconst SOURCE_WEIGHT_CAP = 25;\nconst TARGET_WEIGHT = 100;\n\nconst GLOBAL_IGNORES = new Set([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'target',\n 'bin',\n 'obj',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.cache',\n '.idea',\n '.vscode',\n '.next',\n '.nuxt',\n]);\n\ninterface CandidateState {\n profile: LanguageProfile;\n root: string;\n evidence: LanguageEvidence[];\n manifests: string[];\n}\n\ninterface ScanState {\n entries: number;\n truncated: boolean;\n sourcePaths: Map<string, string[]>;\n candidates: Map<string, CandidateState>;\n}\n\nexport async function detectLanguageWorkspaces(\n options: DetectLanguageOptions,\n): Promise<DetectionResult> {\n const projectRoot = await canonicalDirectory(options.projectRoot);\n const cwdInput = options.cwd\n ? path.isAbsolute(options.cwd)\n ? options.cwd\n : path.resolve(projectRoot, options.cwd)\n : projectRoot;\n const cwd = await canonicalInside(cwdInput, projectRoot, 'cwd');\n const target = options.target\n ? await canonicalInside(resolveFrom(cwd, options.target), projectRoot, 'target')\n : undefined;\n const profiles = (options.profiles ?? languageProfileRegistry.list())\n .filter((profile) => !options.language || profile.id === options.language)\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id));\n const limits = normalizeLimits(options.limits);\n const extraIgnores = new Set(options.ignoredDirectories ?? []);\n const state: ScanState = {\n entries: 0,\n truncated: false,\n sourcePaths: new Map(),\n candidates: new Map(),\n };\n\n await scanDirectory(projectRoot, 0, profiles, limits, state, extraIgnores, options.signal);\n addSourceFallbacks(projectRoot, profiles, state);\n if (target) addTargetEvidence(target, projectRoot, profiles, state);\n\n const workspaces = await Promise.all(\n [...state.candidates.values()].map((candidate) => finalizeCandidate(candidate, projectRoot)),\n );\n workspaces.sort(compareWorkspaces);\n return {\n projectRoot,\n scannedEntries: state.entries,\n truncated: state.truncated,\n workspaces,\n };\n}\n\nasync function scanDirectory(\n directory: string,\n depth: number,\n profiles: readonly LanguageProfile[],\n limits: DetectionLimits,\n state: ScanState,\n extraIgnores: ReadonlySet<string>,\n signal?: AbortSignal,\n): Promise<void> {\n signal?.throwIfAborted();\n if (depth > limits.maxDepth || state.entries >= limits.maxEntries) {\n state.truncated = true;\n return;\n }\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(directory, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => a.name.localeCompare(b.name));\n for (const entry of entries) {\n signal?.throwIfAborted();\n if (state.entries >= limits.maxEntries) {\n state.truncated = true;\n return;\n }\n state.entries++;\n const fullPath = path.join(directory, entry.name);\n if (entry.isSymbolicLink()) continue;\n if (entry.isDirectory()) {\n if (shouldIgnoreDirectory(entry.name, profiles, extraIgnores)) continue;\n if (depth >= limits.maxDepth) {\n state.truncated = true;\n continue;\n }\n await scanDirectory(fullPath, depth + 1, profiles, limits, state, extraIgnores, signal);\n continue;\n }\n if (!entry.isFile()) continue;\n collectFileEvidence(directory, fullPath, entry.name, profiles, state);\n }\n}\n\nfunction collectFileEvidence(\n directory: string,\n fullPath: string,\n basename: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n const lower = basename.toLowerCase();\n const extension = path.extname(lower);\n for (const profile of profiles) {\n const detector = profile.detectors.find((rule) =>\n rule.filename\n ? lower === rule.filename.toLowerCase()\n : lower.endsWith(rule.suffix!.toLowerCase()),\n );\n if (detector) {\n const candidate = getCandidate(state, profile, directory);\n candidate.evidence.push({\n kind: detector.kind,\n path: fullPath,\n value: basename,\n weight: detector.weight,\n });\n if (detector.kind === 'manifest' || detector.kind === 'config') {\n candidate.manifests.push(fullPath);\n }\n }\n if (profile.extensions.includes(extension)) {\n const paths = state.sourcePaths.get(profile.id) ?? [];\n if (paths.length < SOURCE_WEIGHT_CAP / SOURCE_WEIGHT) paths.push(fullPath);\n state.sourcePaths.set(profile.id, paths);\n }\n }\n}\n\nfunction addSourceFallbacks(\n projectRoot: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n for (const profile of profiles) {\n const sources = state.sourcePaths.get(profile.id) ?? [];\n if (sources.length === 0) continue;\n const profileCandidates = [...state.candidates.values()].filter(\n (item) => item.profile.id === profile.id,\n );\n for (const source of sources) {\n const containing = profileCandidates\n .filter((candidate) => isInside(source, candidate.root))\n .sort(\n (a, b) =>\n pathDepth(b.root, projectRoot) - pathDepth(a.root, projectRoot) ||\n a.root.localeCompare(b.root),\n );\n const candidate =\n containing[0] ??\n (profile.sourceFallback === false ? undefined : getCandidate(state, profile, projectRoot));\n if (!candidate) continue;\n candidate.evidence.push({\n kind: 'source',\n path: source,\n value: path.extname(source),\n weight: SOURCE_WEIGHT,\n });\n }\n }\n}\n\nfunction addTargetEvidence(\n target: string,\n projectRoot: string,\n profiles: readonly LanguageProfile[],\n state: ScanState,\n): void {\n const extension = path.extname(target).toLowerCase();\n for (const profile of profiles) {\n if (!profile.extensions.includes(extension)) continue;\n const candidates = [...state.candidates.values()].filter(\n (candidate) => candidate.profile.id === profile.id && isInside(target, candidate.root),\n );\n const candidate =\n candidates.length > 0\n ? candidates.sort(\n (a, b) =>\n pathDepth(b.root, projectRoot) - pathDepth(a.root, projectRoot) ||\n a.root.localeCompare(b.root),\n )[0]!\n : profile.sourceFallback === false\n ? undefined\n : getCandidate(state, profile, path.dirname(target));\n if (!candidate) continue;\n candidate.evidence.push({\n kind: 'target',\n path: target,\n value: extension,\n weight: TARGET_WEIGHT,\n });\n }\n}\n\nasync function finalizeCandidate(\n candidate: CandidateState,\n projectRoot: string,\n): Promise<DetectedWorkspace> {\n const evidence = dedupeEvidence(candidate.evidence).sort(compareEvidence);\n const manifests = [...new Set(candidate.manifests)].sort();\n const confidence = Math.min(1, evidence.reduce((sum, item) => sum + item.weight, 0) / 100);\n const packageManager = await detectPackageManager(candidate.profile, candidate.root, evidence);\n const id = createHash('sha256')\n .update(`${candidate.profile.id}\\0${path.relative(projectRoot, candidate.root)}`)\n .digest('hex')\n .slice(0, 16);\n return Object.freeze({\n id,\n language: candidate.profile.id,\n root: candidate.root,\n confidence,\n evidence: Object.freeze(evidence.map((item) => Object.freeze(item))),\n ...(packageManager ? { packageManager } : {}),\n manifests: Object.freeze(manifests),\n capabilities: Object.freeze(\n Object.keys(candidate.profile.operations).sort() as DetectedWorkspace['capabilities'],\n ),\n });\n}\n\nasync function detectPackageManager(\n profile: LanguageProfile,\n root: string,\n evidence: readonly LanguageEvidence[],\n): Promise<string | undefined> {\n if (profile.packageManagers.length === 1) return profile.packageManagers[0];\n if (profile.id !== 'typescript' && profile.id !== 'javascript') return undefined;\n\n let declared: string | undefined;\n try {\n const pkg = JSON.parse(await fs.readFile(path.join(root, 'package.json'), 'utf8')) as {\n packageManager?: unknown;\n };\n if (typeof pkg.packageManager === 'string') {\n const manager = pkg.packageManager.split('@')[0];\n if (manager && profile.packageManagers.includes(manager)) declared = manager;\n }\n } catch {\n // Missing or malformed package.json is evidence failure, not detector failure.\n }\n const lockManagers = new Set<string>();\n for (const item of evidence) {\n const name = path.basename(item.path).toLowerCase();\n if (name === 'pnpm-lock.yaml') lockManagers.add('pnpm');\n else if (name === 'yarn.lock') lockManagers.add('yarn');\n else if (name === 'bun.lock' || name === 'bun.lockb') lockManagers.add('bun');\n else if (name === 'package-lock.json') lockManagers.add('npm');\n }\n if (\n declared &&\n (lockManagers.size === 0 || (lockManagers.size === 1 && lockManagers.has(declared)))\n ) {\n return declared;\n }\n if (lockManagers.size === 1) return [...lockManagers][0];\n if (lockManagers.size > 1) return undefined;\n return declared ?? 'npm';\n}\n\nfunction getCandidate(state: ScanState, profile: LanguageProfile, root: string): CandidateState {\n const key = `${profile.id}\\0${root}`;\n let candidate = state.candidates.get(key);\n if (!candidate) {\n candidate = { profile, root, evidence: [], manifests: [] };\n state.candidates.set(key, candidate);\n }\n return candidate;\n}\n\nfunction shouldIgnoreDirectory(\n name: string,\n profiles: readonly LanguageProfile[],\n extraIgnores: ReadonlySet<string>,\n): boolean {\n if (GLOBAL_IGNORES.has(name) || extraIgnores.has(name) || name.startsWith('.')) return true;\n return profiles.some((profile) => profile.ignoredDirectories.includes(name));\n}\n\nfunction normalizeLimits(input: DetectLanguageOptions['limits']): DetectionLimits {\n const maxDepth = Math.max(\n 0,\n Math.min(12, Math.trunc(input?.maxDepth ?? DEFAULT_LIMITS.maxDepth)),\n );\n const maxEntries = Math.max(\n 1,\n Math.min(50_000, Math.trunc(input?.maxEntries ?? DEFAULT_LIMITS.maxEntries)),\n );\n return { maxDepth, maxEntries };\n}\n\nasync function canonicalDirectory(input: string): Promise<string> {\n const resolved = path.resolve(input);\n const real = await fs.realpath(resolved);\n const stat = await fs.stat(real);\n if (!stat.isDirectory()) throw new Error(`Project root is not a directory: ${input}`);\n return real;\n}\n\nasync function canonicalInside(input: string, root: string, label: string): Promise<string> {\n const resolved = path.resolve(input);\n let real: string;\n try {\n real = await fs.realpath(resolved);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n const parent = await fs.realpath(path.dirname(resolved));\n real = path.join(parent, path.basename(resolved));\n }\n if (!isInside(real, root)) throw new Error(`${label} is outside project root: ${input}`);\n return real;\n}\n\nfunction resolveFrom(cwd: string, input: string): string {\n return path.isAbsolute(input) ? input : path.resolve(cwd, input);\n}\n\nfunction isInside(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nfunction pathDepth(candidate: string, root: string): number {\n const relative = path.relative(root, candidate);\n return relative === '' ? 0 : relative.split(path.sep).length;\n}\n\nfunction dedupeEvidence(items: readonly LanguageEvidence[]): LanguageEvidence[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = `${item.kind}\\0${item.path}\\0${item.value}\\0${item.weight}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction compareEvidence(a: LanguageEvidence, b: LanguageEvidence): number {\n return a.path.localeCompare(b.path) || a.kind.localeCompare(b.kind) || b.weight - a.weight;\n}\n\nfunction compareWorkspaces(a: DetectedWorkspace, b: DetectedWorkspace): number {\n return (\n b.confidence - a.confidence ||\n a.language.localeCompare(b.language) ||\n a.root.localeCompare(b.root) ||\n a.id.localeCompare(b.id)\n );\n}\n", "import type {\n CommandPlan,\n LanguageOperation,\n LanguageProfileId,\n OperationPlanResult,\n ProfileContext,\n} from './types.js';\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst DEFAULT_OUTPUT_LIMIT_BYTES = 200_000;\n\nexport function processPlan(\n ctx: ProfileContext,\n operation: LanguageOperation,\n command: string,\n args: readonly string[],\n options: {\n parser: string;\n reason: string;\n timeoutMs?: number | undefined;\n mutating?: boolean | undefined;\n network?: boolean | undefined;\n executesProjectCode?: boolean | undefined;\n },\n): CommandPlan {\n return {\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n kind: 'process',\n command,\n args: Object.freeze([...args]),\n cwd: ctx.workspace.root,\n env: Object.freeze({}),\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n outputLimitBytes: DEFAULT_OUTPUT_LIMIT_BYTES,\n mutating: options.mutating ?? false,\n network: options.network ?? false,\n executesProjectCode: options.executesProjectCode ?? false,\n reason: options.reason,\n evidence: ctx.workspace.evidence,\n parser: options.parser,\n };\n}\n\nexport function internalPlan(\n ctx: ProfileContext,\n operation: LanguageOperation,\n parser: string,\n reason: string,\n): CommandPlan {\n return {\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n kind: 'internal',\n command: null,\n args: Object.freeze([]),\n cwd: ctx.workspace.root,\n env: Object.freeze({}),\n timeoutMs: 5_000,\n outputLimitBytes: 32_768,\n mutating: false,\n network: false,\n executesProjectCode: false,\n reason,\n evidence: ctx.workspace.evidence,\n parser,\n };\n}\n\nexport function unavailable(\n ctx: ProfileContext,\n operation: LanguageOperation,\n reason: string,\n): OperationPlanResult {\n return {\n status: 'unavailable',\n profileId: ctx.workspace.language,\n workspaceId: ctx.workspace.id,\n operation,\n reason,\n };\n}\n\nexport function packageNames(ctx: ProfileContext): readonly string[] {\n return ctx.options.packages ?? [];\n}\n\nexport function profileId(value: LanguageProfileId): LanguageProfileId {\n return value;\n}\n", "import { packageNames, processPlan, unavailable } from '../profile-helpers.js';\nimport type { LanguageProfile, ProfileContext } from '../types.js';\n\nconst IGNORES = Object.freeze([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'dist',\n 'build',\n 'coverage',\n]);\n\nfunction pythonProfile(): LanguageProfile {\n return {\n id: 'python',\n displayName: 'Python',\n extensions: Object.freeze(['.py', '.pyi']),\n lspLanguageIds: Object.freeze(['python']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'pyproject.toml', weight: 90 },\n { kind: 'config', filename: 'setup.py', weight: 70 },\n { kind: 'config', filename: 'setup.cfg', weight: 60 },\n { kind: 'manifest', filename: 'requirements.txt', weight: 55 },\n { kind: 'manifest', filename: 'Pipfile', weight: 50 },\n { kind: 'lockfile', filename: 'poetry.lock', weight: 30 },\n { kind: 'lockfile', filename: 'Pipfile.lock', weight: 30 },\n { kind: 'lockfile', filename: 'uv.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['pip', 'poetry', 'pipenv', 'uv']),\n executables: Object.freeze([\n 'python',\n 'python3',\n 'pip',\n 'pip3',\n 'poetry',\n 'pipenv',\n 'uv',\n 'ruff',\n 'black',\n 'pytest',\n 'mypy',\n 'pyright',\n ]),\n operations: Object.freeze({\n syntax: async (ctx) => {\n const py = ctx.options.target ? 'python3' : 'python3';\n return ctx.options.target\n ? processPlan(ctx, 'syntax', py, ['-m', 'py_compile', ctx.options.target], {\n parser: 'python',\n reason: 'Compile the target file to check for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Python syntax check requires an explicit target file.');\n },\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'mypy', ['.', '--no-error-summary'], {\n parser: 'mypy',\n reason: 'Run mypy type checking on the workspace.',\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'ruff', ['check', '.'], {\n parser: 'ruff',\n reason: 'Run the Ruff linter on the workspace.',\n }),\n 'format-check': async (ctx) =>\n processPlan(ctx, 'format-check', 'ruff', ['format', '--check', '.'], {\n parser: 'ruff',\n reason: 'Check Python formatting without writing files.',\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'ruff', ['format', '.'], {\n parser: 'ruff',\n reason: 'Format Python source files.',\n mutating: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'pytest',\n [...(ctx.options.filter ? ['-k', ctx.options.filter] : []), '.'],\n {\n parser: 'pytest',\n reason: ctx.options.filter ? 'Run filtered Python tests.' : 'Run all Python tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n unavailable(ctx, 'build', 'Python is interpreted; use semantic or test instead.'),\n 'debug-compile': async (ctx) =>\n processPlan(ctx, 'debug-compile', 'mypy', ['.', '--no-error-summary'], {\n parser: 'mypy',\n reason: 'Collect mypy type diagnostics.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'pip', ['install', '--no-cache-dir'], {\n parser: 'package-text',\n reason: 'Install dependencies from requirements.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one package name is required.')\n : processPlan(ctx, 'package-add', 'pip', ['install', ...names], {\n parser: 'package-text',\n reason: 'Install specified Python packages.',\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one package name is required.')\n : processPlan(ctx, 'package-remove', 'pip', ['uninstall', '--yes', ...names], {\n parser: 'package-text',\n reason: 'Remove validated Python packages.',\n mutating: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'pip', ['audit'], {\n parser: 'pip-audit',\n reason: 'Audit Python dependencies for vulnerabilities.',\n network: true,\n }),\n run: async (ctx) => {\n // Try common Python entry points in priority order.\n const entries = ['main.py', 'app.py', '__main__.py', 'manage.py'];\n const first: string | undefined = (\n await Promise.all(\n entries.map((name) => ctx.pathExists(name).then((ok) => (ok ? name : undefined))),\n )\n ).find(Boolean);\n const args = first ? [first] : [];\n return processPlan(ctx, 'run', 'python3', args, {\n parser: 'command-text',\n reason: first\n ? `Run the Python entry point ${first}.`\n : 'Run the Python project (no common entry point detected \u2014 add the module path manually).',\n executesProjectCode: true,\n mutating: true,\n });\n },\n }),\n };\n}\n\nfunction hasGradleEvidence(ctx: ProfileContext): boolean {\n return ctx.workspace.evidence.some(\n (e) =>\n (e.kind === 'manifest' &&\n (e.value === 'build.gradle' ||\n e.value === 'build.gradle.kts' ||\n e.value === 'settings.gradle')) ||\n (e.kind === 'lockfile' && e.value === 'gradle.lockfile'),\n );\n}\n\nasync function gradleRunner(ctx: ProfileContext): Promise<string> {\n // Check for the Gradle wrapper at the workspace root. The wrapper is the\n // conventional way to run Gradle \u2014 it pins the Gradle version and downloads\n // it automatically if missing.\n if (await ctx.pathExists('gradlew')) return 'gradlew';\n return 'gradle';\n}\n\nfunction javaProfile(): LanguageProfile {\n return {\n id: 'java',\n displayName: 'Java / Kotlin',\n extensions: Object.freeze(['.java', '.kt', '.kts', '.scala']),\n lspLanguageIds: Object.freeze(['java', 'kotlin']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'pom.xml', weight: 90 },\n { kind: 'manifest', filename: 'build.gradle', weight: 85 },\n { kind: 'manifest', filename: 'build.gradle.kts', weight: 85 },\n { kind: 'manifest', filename: 'settings.gradle', weight: 50 },\n { kind: 'lockfile', filename: 'gradle.lockfile', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['maven', 'gradle']),\n executables: Object.freeze(['mvn', 'gradle', 'gradlew', 'java', 'kotlinc']),\n operations: Object.freeze({\n semantic: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['compileJava'] : ['compile', '-q'];\n const reason = isGradle ? 'Compile the Gradle project.' : 'Compile the Maven project.';\n return processPlan(ctx, 'semantic', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n lint: async (ctx) =>\n unavailable(\n ctx,\n 'lint',\n 'Java linting requires a configured checkstyle or spotbugs plugin.',\n ),\n 'format-check': async (ctx) =>\n unavailable(\n ctx,\n 'format-check',\n 'Java formatting check requires a configured spotless or google-java-format plugin.',\n ),\n test: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['test'] : ['test', '-q'];\n const reason = isGradle ? 'Run Gradle tests.' : 'Run Maven tests.';\n return processPlan(ctx, 'test', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n build: async (ctx) => {\n const isGradle = hasGradleEvidence(ctx);\n const runner = isGradle ? await gradleRunner(ctx) : 'mvn';\n const args = isGradle ? ['build'] : ['package', '-q', '-DskipTests'];\n const reason = isGradle\n ? 'Build the Gradle project.'\n : 'Build the Maven project, skipping tests.';\n return processPlan(ctx, 'build', runner, args, {\n parser: isGradle ? 'gradle' : 'maven',\n reason,\n mutating: true,\n executesProjectCode: true,\n });\n },\n run: async (ctx) => {\n if (!hasGradleEvidence(ctx))\n return unavailable(\n ctx,\n 'run',\n 'Maven run requires exec-maven-plugin configuration. Use `mvn exec:java -q` manually.',\n );\n const runner = await gradleRunner(ctx);\n return processPlan(ctx, 'run', runner, ['run'], {\n parser: 'command-text',\n reason: `Run the Gradle project entry point via ${runner}.`,\n executesProjectCode: true,\n mutating: true,\n });\n },\n 'package-install': async (ctx) =>\n unavailable(\n ctx,\n 'package-install',\n 'JVM dependency installation happens through build or dependency:get.',\n ),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one dependency coordinate is required.')\n : processPlan(ctx, 'package-add', 'mvn', ['dependency:get', `-Dartifact=${names[0]}`], {\n parser: 'maven',\n reason: 'Resolve and fetch a Maven dependency.',\n mutating: true,\n network: true,\n });\n },\n }),\n };\n}\n\nfunction rubyProfile(): LanguageProfile {\n return {\n id: 'ruby',\n displayName: 'Ruby',\n extensions: Object.freeze(['.rb']),\n lspLanguageIds: Object.freeze(['ruby']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'Gemfile', weight: 90 },\n { kind: 'config', filename: '.ruby-version', weight: 40 },\n { kind: 'lockfile', filename: 'Gemfile.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['gem', 'bundler']),\n executables: Object.freeze(['ruby', 'gem', 'bundle', 'rubocop', 'rspec']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'syntax', 'ruby', ['-c', ctx.options.target], {\n parser: 'ruby',\n reason: 'Check the target Ruby file for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Ruby syntax check requires an explicit target file.'),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'rubocop', ['--format=json'], {\n parser: 'rubocop',\n reason: 'Run RuboCop linter.',\n executesProjectCode: true,\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'rubocop', ['--auto-correct'], {\n parser: 'rubocop',\n reason: 'Auto-correct RuboCop violations.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'rspec', [], {\n parser: 'rspec',\n reason: 'Run the RSpec test suite.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'bundle', ['install'], {\n parser: 'package-text',\n reason: 'Install Ruby gem dependencies.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one gem name is required.')\n : processPlan(ctx, 'package-add', 'gem', ['install', ...names], {\n parser: 'package-text',\n reason: 'Install specified Ruby gems.',\n mutating: true,\n network: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'bundle', ['audit', '--format=json'], {\n parser: 'bundler-audit',\n reason: 'Audit Ruby gems for vulnerabilities.',\n network: true,\n }),\n run: async (ctx) => {\n // Try common Ruby entry points in priority order.\n const entries = ['main.rb', 'app.rb', 'server.rb', 'config.ru'];\n const first: string | undefined = (\n await Promise.all(\n entries.map((name) => ctx.pathExists(name).then((ok) => (ok ? name : undefined))),\n )\n ).find(Boolean);\n const hasGemfile = await ctx.pathExists('Gemfile');\n const cmd = hasGemfile ? 'bundle' : 'ruby';\n const args = hasGemfile ? ['exec', 'ruby', first ?? ''] : [first ?? ''];\n return processPlan(ctx, 'run', cmd, args, {\n parser: 'command-text',\n reason: first\n ? `Run the Ruby entry point ${first}.`\n : 'Run the Ruby project (no common entry point detected \u2014 add the file path manually).',\n executesProjectCode: true,\n mutating: true,\n });\n },\n }),\n };\n}\n\nfunction cProfile(): LanguageProfile {\n return {\n id: 'c',\n displayName: 'C / C++',\n extensions: Object.freeze(['.c', '.h']),\n lspLanguageIds: Object.freeze(['c']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'CMakeLists.txt', weight: 85 },\n { kind: 'manifest', filename: 'Makefile', weight: 60 },\n { kind: 'config', suffix: '.cmake', weight: 50 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['cc', 'gcc', 'clang', 'cmake', 'make']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'cmake', ['--build', '.', '--target', 'all'], {\n parser: 'cmake',\n reason: 'Build C project to collect compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n unavailable(\n ctx,\n 'test',\n 'C test execution requires a configured test runner (ctest, etc.).',\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'cmake', ['--build', '.'], {\n parser: 'cmake',\n reason: 'Build the C project.',\n mutating: true,\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction cppProfile(): LanguageProfile {\n return {\n ...cProfile(),\n id: 'cpp',\n displayName: 'C++',\n extensions: Object.freeze(['.cpp', '.cc', '.cxx', '.hpp', '.hxx']),\n lspLanguageIds: Object.freeze(['cpp']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'CMakeLists.txt', weight: 85 },\n { kind: 'manifest', filename: 'Makefile', weight: 50 },\n ]),\n executables: Object.freeze(['c++', 'g++', 'clang++', 'cmake', 'make']),\n };\n}\n\nfunction swiftProfile(): LanguageProfile {\n return {\n id: 'swift',\n displayName: 'Swift',\n extensions: Object.freeze(['.swift']),\n lspLanguageIds: Object.freeze(['swift']),\n detectors: Object.freeze([{ kind: 'manifest', filename: 'Package.swift', weight: 90 }]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['swift']),\n executables: Object.freeze(['swift', 'swiftc']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'swift', ['build'], {\n parser: 'swift',\n reason: 'Build Swift package to collect compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'swift', ['test'], {\n parser: 'swift-test',\n reason: 'Run Swift tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'swift', ['build', '-c', 'release'], {\n parser: 'swift',\n reason: 'Build the Swift package in release mode.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'swift', ['run'], {\n parser: 'command-text',\n reason: 'Run the Swift package entry point.',\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction dartProfile(): LanguageProfile {\n return {\n id: 'dart',\n displayName: 'Dart / Flutter',\n extensions: Object.freeze(['.dart']),\n lspLanguageIds: Object.freeze(['dart']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'pubspec.yaml', weight: 90 },\n { kind: 'lockfile', filename: 'pubspec.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['pub']),\n executables: Object.freeze(['dart', 'flutter']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'dart', ['analyze'], {\n parser: 'dart-analyze',\n reason: 'Run Dart static analysis.',\n }),\n 'format-check': async (ctx) =>\n processPlan(\n ctx,\n 'format-check',\n 'dart',\n ['format', '--output=none', '--set-exit-if-changed', '.'],\n {\n parser: 'dart-format',\n reason: 'Check Dart formatting without writing files.',\n },\n ),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'dart', ['format', '.'], {\n parser: 'dart-format',\n reason: 'Format Dart source files.',\n mutating: true,\n }),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'dart', ['test'], {\n parser: 'dart-test',\n reason: 'Run Dart tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'dart', ['pub', 'get'], {\n parser: 'package-text',\n reason: 'Fetch Dart package dependencies.',\n mutating: true,\n network: true,\n }),\n 'package-outdated': async (ctx) =>\n processPlan(ctx, 'package-outdated', 'dart', ['pub', 'outdated'], {\n parser: 'dart-outdated',\n reason: 'Check for outdated Dart packages.',\n network: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'dart', ['run'], {\n parser: 'command-text',\n reason: 'Run the Dart / Flutter project entry point.',\n executesProjectCode: true,\n }),\n }),\n };\n}\n\nfunction denoProfile(): LanguageProfile {\n return {\n id: 'deno',\n displayName: 'Deno',\n extensions: Object.freeze(['.ts', '.tsx', '.js', '.jsx']),\n lspLanguageIds: Object.freeze(['typescript', 'javascript']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'deno.json', weight: 90 },\n { kind: 'config', filename: 'deno.jsonc', weight: 90 },\n { kind: 'config', filename: 'import_map.json', weight: 60 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['deno']),\n // .ts/.js extensions are shared with the TypeScript/JavaScript profiles;\n // only a deno.json(c)/import_map.json detector hit may establish a workspace.\n sourceFallback: false,\n operations: Object.freeze({\n test: async (ctx) =>\n processPlan(ctx, 'test', 'deno', ['test'], {\n parser: 'deno-test',\n reason: 'Run Deno tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'deno', ['run', '--allow-all', 'main.ts'], {\n parser: 'command-text',\n reason: 'Run the Deno project entry point with full permission.',\n executesProjectCode: true,\n mutating: true,\n }),\n }),\n };\n}\n\nfunction elixirProfile(): LanguageProfile {\n return {\n id: 'elixir',\n displayName: 'Elixir',\n extensions: Object.freeze(['.ex', '.exs']),\n lspLanguageIds: Object.freeze(['elixir']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'mix.exs', weight: 90 },\n { kind: 'lockfile', filename: 'mix.lock', weight: 30 },\n ]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze(['mix']),\n executables: Object.freeze(['mix', 'elixir']),\n operations: Object.freeze({\n semantic: async (ctx) =>\n unavailable(ctx, 'semantic', 'Elixir compilation is handled by the build operation.'),\n lint: async (ctx) => unavailable(ctx, 'lint', 'Elixir linting requires the credo package.'),\n test: async (ctx) =>\n processPlan(ctx, 'test', 'mix', ['test'], {\n parser: 'mix-test',\n reason: 'Run ExUnit tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'mix', ['compile'], {\n parser: 'mix',\n reason: 'Compile the Mix project.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'mix', ['run'], {\n parser: 'command-text',\n reason: 'Run the Mix project entry point.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'mix', ['deps.get'], {\n parser: 'package-text',\n reason: 'Fetch Elixir dependencies.',\n mutating: true,\n network: true,\n }),\n }),\n };\n}\n\nfunction shellProfile(): LanguageProfile {\n return {\n id: 'shell',\n displayName: 'Shell',\n extensions: Object.freeze(['.sh', '.bash']),\n lspLanguageIds: Object.freeze(['shellscript']),\n detectors: Object.freeze([{ kind: 'config', filename: 'ShellCheckrc', weight: 50 }]),\n ignoredDirectories: IGNORES,\n packageManagers: Object.freeze([]),\n executables: Object.freeze(['bash', 'sh', 'shellcheck', 'shfmt']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'syntax', 'bash', ['-n', ctx.options.target], {\n parser: 'shell',\n reason: 'Check the shell script for syntax errors.',\n })\n : unavailable(ctx, 'syntax', 'Shell syntax check requires an explicit target file.'),\n lint: async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'lint', 'shellcheck', ['--format=json', ctx.options.target], {\n parser: 'shellcheck',\n reason: 'Run ShellCheck on the target script.',\n })\n : unavailable(ctx, 'lint', 'Shell linting requires an explicit target file.'),\n 'format-check': async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'format-check', 'shfmt', ['-d', ctx.options.target], {\n parser: 'shell',\n reason: 'Check shell formatting without writing.',\n })\n : unavailable(\n ctx,\n 'format-check',\n 'Shell formatting check requires an explicit target file.',\n ),\n 'format-write': async (ctx) =>\n ctx.options.target\n ? processPlan(ctx, 'format-write', 'shfmt', ['-w', ctx.options.target], {\n parser: 'shell',\n reason: 'Format the shell script.',\n mutating: true,\n })\n : unavailable(ctx, 'format-write', 'Shell formatting requires an explicit target file.'),\n }),\n };\n}\n\nexport const ADDITIONAL_LANGUAGE_PROFILES: readonly LanguageProfile[] = Object.freeze([\n pythonProfile(),\n javaProfile(),\n rubyProfile(),\n cProfile(),\n cppProfile(),\n swiftProfile(),\n dartProfile(),\n denoProfile(),\n elixirProfile(),\n shellProfile(),\n]);\n", "import { internalPlan, packageNames, processPlan, unavailable } from '../profile-helpers.js';\nimport type { LanguageOperation, LanguageProfile, ProfileContext } from '../types.js';\n\nconst COMMON_IGNORES = Object.freeze([\n '.git',\n '.wrongstack',\n 'node_modules',\n 'vendor',\n 'target',\n 'bin',\n 'obj',\n 'dist',\n 'build',\n 'coverage',\n]);\n\nfunction nodeManager(ctx: ProfileContext): string | undefined {\n const lockfiles = new Set(\n ctx.workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.value.toLowerCase()),\n );\n if (lockfiles.size > 1 && !ctx.workspace.packageManager) return undefined;\n return ctx.workspace.packageManager ?? 'npm';\n}\n\nfunction scriptPlan(ctx: ProfileContext, operation: string, script: string) {\n const manager = nodeManager(ctx);\n if (!manager)\n return unavailable(\n ctx,\n operation as LanguageOperation,\n 'Conflicting Node lockfiles make the package manager ambiguous.',\n );\n const args = manager === 'npm' ? ['run', script] : [script];\n return processPlan(ctx, operation as LanguageOperation, manager, args, {\n parser: 'command-text',\n reason: `Run the detected ${manager} ${script} script for this workspace.`,\n mutating: true,\n executesProjectCode: true,\n });\n}\n\nfunction nodeExec(ctx: ProfileContext, executable: string, args: readonly string[]) {\n const manager = ctx.workspace.packageManager ?? 'npm';\n if (manager === 'pnpm') return { command: 'pnpm', args: ['exec', executable, ...args] };\n if (manager === 'yarn') return { command: 'yarn', args: ['exec', executable, ...args] };\n if (manager === 'bun') return { command: 'bun', args: ['x', executable, ...args] };\n return { command: 'npx', args: ['--no-install', executable, ...args] };\n}\n\nfunction typescriptProfile(): LanguageProfile {\n return {\n id: 'typescript',\n displayName: 'TypeScript',\n extensions: Object.freeze(['.ts', '.tsx', '.mts', '.cts']),\n lspLanguageIds: Object.freeze(['typescript', 'typescriptreact']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'tsconfig.json', weight: 90 },\n { kind: 'manifest', filename: 'package.json', weight: 55 },\n { kind: 'lockfile', filename: 'pnpm-lock.yaml', weight: 30 },\n { kind: 'lockfile', filename: 'yarn.lock', weight: 30 },\n { kind: 'lockfile', filename: 'package-lock.json', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lock', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lockb', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['pnpm', 'yarn', 'bun', 'npm']),\n executables: Object.freeze(['pnpm', 'yarn', 'bun', 'npx', 'npm']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n internalPlan(\n ctx,\n 'syntax',\n 'typescript-parser',\n 'Parse the target with the TypeScript compiler API.',\n ),\n semantic: async (ctx) => {\n const run = nodeExec(ctx, 'tsc', ['--noEmit', '--pretty', 'false']);\n return processPlan(ctx, 'semantic', run.command, run.args, {\n parser: 'typescript',\n reason: 'Run the workspace TypeScript compiler without emitting files.',\n executesProjectCode: true,\n });\n },\n lint: async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['lint', '.']);\n return processPlan(ctx, 'lint', run.command, run.args, {\n parser: 'biome',\n reason: 'Run the project-local Biome linter.',\n executesProjectCode: true,\n });\n },\n 'format-check': async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['format', '--check', '.']);\n return processPlan(ctx, 'format-check', run.command, run.args, {\n parser: 'biome',\n reason: 'Check formatting with the project-local Biome formatter.',\n executesProjectCode: true,\n });\n },\n 'format-write': async (ctx) => {\n const run = nodeExec(ctx, 'biome', ['format', '--write', '.']);\n return processPlan(ctx, 'format-write', run.command, run.args, {\n parser: 'biome',\n reason: 'Format the workspace with the project-local Biome formatter.',\n mutating: true,\n executesProjectCode: true,\n });\n },\n test: async (ctx) =>\n ctx.options.filter || ctx.options.coverage\n ? unavailable(\n ctx,\n 'test',\n 'The detected package script does not expose deterministic filter or coverage adapters.',\n )\n : scriptPlan(ctx, 'test', 'test'),\n build: async (ctx) => scriptPlan(ctx, 'build', 'build'),\n run: async (ctx) => scriptPlan(ctx, 'run', 'dev'),\n 'debug-compile': async (ctx) => {\n const run = nodeExec(ctx, 'tsc', ['--noEmit', '--pretty', 'false']);\n return processPlan(ctx, 'debug-compile', run.command, run.args, {\n parser: 'typescript',\n reason: 'Collect deterministic TypeScript compiler diagnostics.',\n executesProjectCode: true,\n });\n },\n 'package-install': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'yarn' ? ['install', '--ignore-scripts'] : ['install', '--ignore-scripts'];\n return processPlan(ctx, 'package-install', manager, args, {\n parser: 'package-text',\n reason: `Restore declared dependencies with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n executesProjectCode: false,\n });\n },\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-add', 'At least one package name is required.');\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'npm'\n ? ['install', '--ignore-scripts', ...names]\n : ['add', '--ignore-scripts', ...names];\n return processPlan(ctx, 'package-add', manager, args, {\n parser: 'package-text',\n reason: `Add validated packages with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-remove', 'At least one package name is required.');\n const manager = ctx.workspace.packageManager ?? 'npm';\n const args =\n manager === 'npm'\n ? ['uninstall', '--ignore-scripts', ...names]\n : ['remove', '--ignore-scripts', ...names];\n return processPlan(ctx, 'package-remove', manager, args, {\n parser: 'package-text',\n reason: `Remove validated packages with ${manager} and lifecycle scripts disabled.`,\n mutating: true,\n network: true,\n });\n },\n 'package-audit': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n return processPlan(ctx, 'package-audit', manager, ['audit', '--json'], {\n parser: 'npm-audit',\n reason: `Audit dependencies with the detected ${manager} package manager.`,\n network: true,\n });\n },\n 'package-outdated': async (ctx) => {\n const manager = ctx.workspace.packageManager ?? 'npm';\n return processPlan(ctx, 'package-outdated', manager, ['outdated', '--json'], {\n parser: 'npm-outdated',\n reason: `Check outdated dependencies with ${manager}.`,\n network: true,\n });\n },\n }),\n };\n}\n\nfunction javascriptProfile(): LanguageProfile {\n const ts = typescriptProfile();\n return {\n ...ts,\n id: 'javascript',\n displayName: 'JavaScript',\n extensions: Object.freeze(['.js', '.jsx', '.mjs', '.cjs']),\n lspLanguageIds: Object.freeze(['javascript', 'javascriptreact']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'jsconfig.json', weight: 90 },\n { kind: 'manifest', filename: 'package.json', weight: 70 },\n { kind: 'lockfile', filename: 'pnpm-lock.yaml', weight: 30 },\n { kind: 'lockfile', filename: 'yarn.lock', weight: 30 },\n { kind: 'lockfile', filename: 'package-lock.json', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lock', weight: 30 },\n { kind: 'lockfile', filename: 'bun.lockb', weight: 30 },\n ]),\n operations: Object.freeze({\n ...ts.operations,\n syntax: async (ctx: ProfileContext) =>\n internalPlan(\n ctx,\n 'syntax',\n 'typescript-parser',\n 'Parse JavaScript with the TypeScript compiler API.',\n ),\n }),\n };\n}\n\nconst goProfile: LanguageProfile = {\n id: 'go',\n displayName: 'Go',\n extensions: Object.freeze(['.go']),\n lspLanguageIds: Object.freeze(['go']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'go.mod', weight: 90 },\n { kind: 'manifest', filename: 'go.work', weight: 95 },\n { kind: 'lockfile', filename: 'go.sum', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['go']),\n executables: Object.freeze(['go', 'gofmt']),\n operations: Object.freeze({\n syntax: async (ctx) => {\n if (!ctx.target)\n return unavailable(ctx, 'syntax', 'Go syntax planning requires a target file.');\n return processPlan(ctx, 'syntax', 'gofmt', ['-e', '-d', ctx.target], {\n parser: 'gofmt',\n reason: 'Parse the target and report syntax errors without writing it.',\n });\n },\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'go', ['test', '-run', '^$', './...'], {\n parser: 'go-test',\n reason: 'Compile all Go packages without selecting tests.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'go', ['vet', './...'], {\n parser: 'go-compiler',\n reason: 'Run the standard Go vet checks.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'format-check', 'gofmt', ['-d', ctx.target], {\n parser: 'gofmt',\n reason: 'Report Go formatting differences for the target without writing it.',\n })\n : unavailable(ctx, 'format-check', 'Go formatting requires an explicit target file.'),\n 'format-write': async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'format-write', 'gofmt', ['-w', ctx.target], {\n parser: 'gofmt',\n reason: 'Format the target Go source file.',\n mutating: true,\n })\n : unavailable(ctx, 'format-write', 'Go formatting requires an explicit target file.'),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'go',\n ['test', ...(ctx.options.filter ? ['-run', ctx.options.filter] : []), './...'],\n {\n parser: 'go-test',\n reason: ctx.options.filter ? 'Run filtered Go tests.' : 'Run all Go tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'go', ['build', './...'], {\n parser: 'go-compiler',\n reason: 'Build all Go packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'go', ['run', '.'], {\n parser: 'command-text',\n reason: 'Run the Go module entry point.',\n executesProjectCode: true,\n }),\n 'debug-race': async (ctx) =>\n processPlan(ctx, 'debug-race', 'go', ['test', '-race', './...'], {\n parser: 'go-test',\n reason: 'Collect Go race-detector evidence.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'go', ['mod', 'download'], {\n parser: 'go-module',\n reason: 'Download the dependencies declared by go.mod.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n if (names.length === 0)\n return unavailable(ctx, 'package-add', 'At least one Go module is required.');\n return processPlan(ctx, 'package-add', 'go', ['get', ...names], {\n parser: 'go-module',\n reason: 'Add validated Go modules.',\n mutating: true,\n network: true,\n });\n },\n 'package-update': async (ctx) =>\n processPlan(ctx, 'package-update', 'go', ['get', '-u', './...'], {\n parser: 'go-module',\n reason: 'Update dependencies of all Go packages.',\n mutating: true,\n network: true,\n }),\n }),\n};\n\nconst rustProfile: LanguageProfile = {\n id: 'rust',\n displayName: 'Rust',\n extensions: Object.freeze(['.rs']),\n lspLanguageIds: Object.freeze(['rust']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'Cargo.toml', weight: 90 },\n { kind: 'lockfile', filename: 'Cargo.lock', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['cargo']),\n executables: Object.freeze(['cargo']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n processPlan(ctx, 'syntax', 'cargo', ['check', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Check Rust syntax and semantics with Cargo.',\n mutating: true,\n executesProjectCode: true,\n }),\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'cargo', ['check', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Collect Rust compiler diagnostics with Cargo check.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'cargo', ['clippy', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Run Clippy for this crate.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n processPlan(ctx, 'format-check', 'cargo', ['fmt', '--check'], {\n parser: 'cargo-fmt',\n reason: 'Check Rust formatting without writing files.',\n }),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'cargo', ['fmt'], {\n parser: 'cargo-fmt',\n reason: 'Format Rust source files in the workspace.',\n mutating: true,\n }),\n 'test-compile': async (ctx) =>\n processPlan(ctx, 'test-compile', 'cargo', ['test', '--no-run', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Compile Rust tests without running them.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'cargo',\n ['test', ...(ctx.options.filter ? [ctx.options.filter] : [])],\n {\n parser: 'cargo-test',\n reason: ctx.options.filter ? 'Run filtered Rust tests.' : 'Run Rust tests.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'cargo', ['build', '--message-format=json'], {\n parser: 'cargo-json',\n reason: 'Build the Rust workspace.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'cargo', ['run'], {\n parser: 'command-text',\n reason: 'Run the Rust workspace entry point.',\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'cargo', ['fetch', '--locked'], {\n parser: 'cargo-json',\n reason: 'Fetch locked Rust dependencies.',\n mutating: true,\n network: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one crate is required.')\n : processPlan(ctx, 'package-add', 'cargo', ['add', ...names], {\n parser: 'cargo-text',\n reason: 'Add validated Rust crates.',\n mutating: true,\n network: true,\n });\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one crate is required.')\n : processPlan(ctx, 'package-remove', 'cargo', ['remove', ...names], {\n parser: 'cargo-text',\n reason: 'Remove validated Rust crates.',\n mutating: true,\n });\n },\n 'package-update': async (ctx) =>\n processPlan(ctx, 'package-update', 'cargo', ['update'], {\n parser: 'cargo-text',\n reason: 'Update the Cargo lockfile.',\n mutating: true,\n network: true,\n }),\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'cargo', ['audit', '--json'], {\n parser: 'cargo-audit',\n reason: 'Audit Rust dependencies when cargo-audit is installed.',\n network: true,\n }),\n }),\n};\n\nconst phpProfile: LanguageProfile = {\n id: 'php',\n displayName: 'PHP',\n extensions: Object.freeze(['.php']),\n lspLanguageIds: Object.freeze(['php']),\n detectors: Object.freeze([\n { kind: 'manifest', filename: 'composer.json', weight: 90 },\n { kind: 'lockfile', filename: 'composer.lock', weight: 30 },\n { kind: 'config', filename: 'phpunit.xml', weight: 25 },\n { kind: 'config', filename: 'phpunit.xml.dist', weight: 25 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['composer']),\n executables: Object.freeze(['php', 'composer']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n ctx.target\n ? processPlan(ctx, 'syntax', 'php', ['-l', ctx.target], {\n parser: 'php-lint',\n reason: 'Lint the target PHP file without executing it.',\n })\n : unavailable(ctx, 'syntax', 'PHP syntax planning requires a target file.'),\n semantic: async (ctx) =>\n unavailable(\n ctx,\n 'semantic',\n 'No configured PHPStan or Psalm adapter was detected in Phase 1.',\n ),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'php',\n ['vendor/bin/phpunit', ...(ctx.options.filter ? ['--filter', ctx.options.filter] : [])],\n {\n parser: 'phpunit',\n reason: ctx.options.filter\n ? 'Run filtered tests with the project-local PHPUnit runner.'\n : 'Run the project-local PHPUnit test runner.',\n executesProjectCode: true,\n },\n ),\n 'package-install': async (ctx) =>\n processPlan(\n ctx,\n 'package-install',\n 'composer',\n ['install', '--no-interaction', '--no-scripts'],\n {\n parser: 'composer',\n reason: 'Restore Composer dependencies without scripts.',\n mutating: true,\n network: true,\n },\n ),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one Composer package is required.')\n : processPlan(\n ctx,\n 'package-add',\n 'composer',\n ['require', '--no-interaction', '--no-scripts', ...names],\n {\n parser: 'composer',\n reason: 'Add validated Composer packages without scripts.',\n mutating: true,\n network: true,\n },\n );\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one Composer package is required.')\n : processPlan(\n ctx,\n 'package-remove',\n 'composer',\n ['remove', '--no-interaction', '--no-scripts', ...names],\n {\n parser: 'composer',\n reason: 'Remove validated Composer packages without scripts.',\n mutating: true,\n },\n );\n },\n 'package-update': async (ctx) =>\n processPlan(\n ctx,\n 'package-update',\n 'composer',\n ['update', '--no-interaction', '--no-scripts'],\n {\n parser: 'composer',\n reason: 'Update Composer dependencies without scripts.',\n mutating: true,\n network: true,\n },\n ),\n 'package-audit': async (ctx) =>\n processPlan(ctx, 'package-audit', 'composer', ['audit', '--format=json'], {\n parser: 'composer-audit',\n reason: 'Audit Composer dependencies.',\n network: true,\n }),\n 'package-outdated': async (ctx) =>\n processPlan(ctx, 'package-outdated', 'composer', ['outdated', '--format=json'], {\n parser: 'composer-outdated',\n reason: 'Check outdated Composer dependencies.',\n network: true,\n }),\n }),\n};\n\nconst csharpProfile: LanguageProfile = {\n id: 'csharp',\n displayName: 'C# / .NET',\n extensions: Object.freeze(['.cs']),\n lspLanguageIds: Object.freeze(['csharp']),\n detectors: Object.freeze([\n { kind: 'config', filename: 'global.json', weight: 25 },\n { kind: 'manifest', suffix: '.slnx', weight: 95 },\n { kind: 'manifest', suffix: '.sln', weight: 95 },\n { kind: 'manifest', suffix: '.csproj', weight: 90 },\n { kind: 'manifest', suffix: '.fsproj', weight: 90 },\n { kind: 'lockfile', filename: 'packages.lock.json', weight: 30 },\n ]),\n ignoredDirectories: COMMON_IGNORES,\n packageManagers: Object.freeze(['dotnet']),\n executables: Object.freeze(['dotnet']),\n operations: Object.freeze({\n syntax: async (ctx) =>\n processPlan(ctx, 'syntax', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Use the nearest project or solution to collect C# syntax diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n semantic: async (ctx) =>\n processPlan(ctx, 'semantic', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Build without restoring to collect .NET compiler diagnostics.',\n mutating: true,\n executesProjectCode: true,\n }),\n lint: async (ctx) =>\n processPlan(ctx, 'lint', 'dotnet', ['format', '--verify-no-changes', '--no-restore'], {\n parser: 'dotnet-format',\n reason: 'Verify .NET formatting and analyzers without writing source files.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'format-check': async (ctx) =>\n processPlan(\n ctx,\n 'format-check',\n 'dotnet',\n ['format', '--verify-no-changes', '--no-restore'],\n {\n parser: 'dotnet-format',\n reason: 'Verify .NET formatting without source writes.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n 'format-write': async (ctx) =>\n processPlan(ctx, 'format-write', 'dotnet', ['format', '--no-restore'], {\n parser: 'dotnet-format',\n reason: 'Format .NET source files without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n test: async (ctx) =>\n processPlan(\n ctx,\n 'test',\n 'dotnet',\n ['test', '--no-restore', ...(ctx.options.filter ? ['--filter', ctx.options.filter] : [])],\n {\n parser: 'dotnet-test',\n reason: ctx.options.filter\n ? 'Run filtered .NET tests without restoring packages.'\n : 'Run .NET tests without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n },\n ),\n build: async (ctx) =>\n processPlan(ctx, 'build', 'dotnet', ['build', '--no-restore'], {\n parser: 'dotnet-build',\n reason: 'Build the nearest .NET project or solution without restoring packages.',\n mutating: true,\n executesProjectCode: true,\n }),\n run: async (ctx) =>\n processPlan(ctx, 'run', 'dotnet', ['run', '--no-restore'], {\n parser: 'command-text',\n reason: 'Run the .NET project entry point.',\n mutating: true,\n executesProjectCode: true,\n }),\n 'package-install': async (ctx) =>\n processPlan(ctx, 'package-install', 'dotnet', ['restore', '--locked-mode'], {\n parser: 'dotnet-restore',\n reason: 'Restore locked .NET dependencies.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n }),\n 'package-add': async (ctx) => {\n const names = packageNames(ctx);\n const [spec] = names;\n const versionAt = spec?.lastIndexOf('@') ?? -1;\n const packageName = versionAt > 0 ? spec?.slice(0, versionAt) : spec;\n const packageVersion = versionAt > 0 ? spec?.slice(versionAt + 1) : undefined;\n return names.length === 0\n ? unavailable(ctx, 'package-add', 'At least one NuGet package is required.')\n : names.length > 1\n ? unavailable(ctx, 'package-add', 'NuGet package changes run one package at a time.')\n : processPlan(\n ctx,\n 'package-add',\n 'dotnet',\n [\n 'add',\n 'package',\n packageName ?? '',\n ...(packageVersion ? ['--version', packageVersion] : []),\n ],\n {\n parser: 'dotnet-package',\n reason: 'Add validated NuGet packages.',\n mutating: true,\n network: true,\n executesProjectCode: true,\n },\n );\n },\n 'package-remove': async (ctx) => {\n const names = packageNames(ctx);\n return names.length === 0\n ? unavailable(ctx, 'package-remove', 'At least one NuGet package is required.')\n : processPlan(ctx, 'package-remove', 'dotnet', ['remove', 'package', ...names], {\n parser: 'dotnet-package',\n reason: 'Remove validated NuGet packages.',\n mutating: true,\n });\n },\n 'package-audit': async (ctx) =>\n processPlan(\n ctx,\n 'package-audit',\n 'dotnet',\n ['list', 'package', '--vulnerable', '--format', 'json'],\n { parser: 'dotnet-package', reason: 'List vulnerable NuGet dependencies.', network: true },\n ),\n 'package-outdated': async (ctx) =>\n processPlan(\n ctx,\n 'package-outdated',\n 'dotnet',\n ['list', 'package', '--outdated', '--format', 'json'],\n { parser: 'dotnet-package', reason: 'List outdated NuGet dependencies.', network: true },\n ),\n }),\n};\n\nexport const PRIMARY_LANGUAGE_PROFILES: readonly LanguageProfile[] = Object.freeze([\n Object.freeze(typescriptProfile()),\n Object.freeze(javascriptProfile()),\n Object.freeze(goProfile),\n Object.freeze(rustProfile),\n Object.freeze(phpProfile),\n Object.freeze(csharpProfile),\n]);\n", "import { ADDITIONAL_LANGUAGE_PROFILES } from './profiles/additional.js';\nimport { PRIMARY_LANGUAGE_PROFILES } from './profiles/primary.js';\nimport type { LanguageOperation, LanguageProfile, LanguageProfileId } from './types.js';\n\nconst PROFILE_ID_RE = /^[a-z][a-z0-9-]{0,63}$/;\nconst EXECUTABLE_RE = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;\nconst KNOWN_OPERATIONS = new Set<LanguageOperation>([\n 'syntax',\n 'semantic',\n 'lint',\n 'format-check',\n 'format-write',\n 'test-compile',\n 'test',\n 'build',\n 'run',\n 'debug-compile',\n 'debug-test',\n 'debug-runtime',\n 'debug-race',\n 'package-install',\n 'package-add',\n 'package-remove',\n 'package-update',\n 'package-audit',\n 'package-outdated',\n]);\n\nexport class LanguageProfileRegistry {\n readonly #profiles = new Map<LanguageProfileId, LanguageProfile>();\n\n constructor(profiles: readonly LanguageProfile[] = []) {\n for (const profile of profiles) this.register(profile);\n }\n\n register(profile: LanguageProfile): void {\n const errors = validateLanguageProfile(profile);\n if (errors.length > 0) {\n throw new Error(`Invalid language profile \"${profile.id}\": ${errors.join('; ')}`);\n }\n if (this.#profiles.has(profile.id)) {\n throw new Error(`Language profile \"${profile.id}\" is already registered`);\n }\n this.#profiles.set(profile.id, freezeProfile(profile));\n }\n\n get(id: LanguageProfileId): LanguageProfile | undefined {\n return this.#profiles.get(id);\n }\n\n list(): readonly LanguageProfile[] {\n return Object.freeze([...this.#profiles.values()]);\n }\n}\n\nexport function validateLanguageProfile(profile: LanguageProfile): string[] {\n const errors: string[] = [];\n if (!PROFILE_ID_RE.test(profile.id)) errors.push('id must be a lowercase stable identifier');\n if (!profile.displayName.trim()) errors.push('displayName is required');\n if (profile.extensions.length === 0) errors.push('at least one extension is required');\n for (const ext of profile.extensions) {\n if (!/^\\.[a-z0-9+.-]+$/i.test(ext)) errors.push(`invalid extension \"${ext}\"`);\n }\n if (profile.detectors.length === 0) errors.push('at least one detector is required');\n for (const detector of profile.detectors) {\n if ((detector.filename ? 1 : 0) + (detector.suffix ? 1 : 0) !== 1) {\n errors.push('each detector must declare exactly one of filename or suffix');\n }\n if (!Number.isFinite(detector.weight) || detector.weight <= 0 || detector.weight > 100) {\n errors.push('detector weights must be in the range 1..100');\n }\n const marker = detector.filename ?? detector.suffix ?? '';\n if (marker.includes('/') || marker.includes('\\\\') || marker.includes('\\0')) {\n errors.push(`detector marker \"${marker}\" must be a basename or suffix`);\n }\n }\n if (profile.executables.length === 0) errors.push('at least one executable is required');\n for (const executable of profile.executables) {\n if (!EXECUTABLE_RE.test(executable)) errors.push(`invalid executable token \"${executable}\"`);\n }\n for (const operation of Object.keys(profile.operations)) {\n if (!KNOWN_OPERATIONS.has(operation as LanguageOperation)) {\n errors.push(`unknown operation \"${operation}\"`);\n }\n if (typeof profile.operations[operation as LanguageOperation] !== 'function') {\n errors.push(`operation \"${operation}\" must be a resolver function`);\n }\n }\n return [...new Set(errors)];\n}\n\nfunction freezeProfile(profile: LanguageProfile): LanguageProfile {\n const detectors = Object.freeze(profile.detectors.map((item) => Object.freeze({ ...item })));\n const operations = Object.freeze({ ...profile.operations });\n return Object.freeze({\n ...profile,\n extensions: Object.freeze([...profile.extensions]),\n lspLanguageIds: Object.freeze([...profile.lspLanguageIds]),\n detectors,\n ignoredDirectories: Object.freeze([...profile.ignoredDirectories]),\n packageManagers: Object.freeze([...profile.packageManagers]),\n executables: Object.freeze([...profile.executables]),\n operations,\n });\n}\n\nexport const languageProfileRegistry = new LanguageProfileRegistry([\n ...PRIMARY_LANGUAGE_PROFILES,\n ...ADDITIONAL_LANGUAGE_PROFILES,\n]);\n", "import * as path from 'node:path';\nimport type {\n LanguageDiagnostic,\n LanguagePackageMutation,\n LanguagePackageVulnerability,\n LanguageProfileId,\n LanguageRunSummary,\n} from './types.js';\n\nconst MAX_DIAGNOSTICS = 200;\n\nexport interface ParsedDiagnostics {\n diagnostics: readonly LanguageDiagnostic[];\n omitted: number;\n summary: LanguageRunSummary;\n}\n\nexport function parseLanguageDiagnostics(\n parser: string,\n stdout: string,\n stderr: string,\n workspaceRoot: string,\n): ParsedDiagnostics {\n const text = `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}`;\n let diagnostics: LanguageDiagnostic[];\n switch (parser) {\n case 'typescript':\n diagnostics = parseTypeScript(text, workspaceRoot);\n break;\n case 'cargo-json':\n diagnostics = parseCargoJson(text, workspaceRoot);\n break;\n case 'php-lint':\n diagnostics = parsePhpLint(text, workspaceRoot);\n break;\n case 'dotnet-build':\n case 'dotnet-format':\n case 'dotnet-test':\n diagnostics = parseDotnet(text, workspaceRoot);\n break;\n case 'go-test':\n case 'go-compiler':\n case 'gofmt':\n diagnostics = parseGo(text, workspaceRoot);\n break;\n case 'biome':\n diagnostics = parseBiome(text, workspaceRoot);\n break;\n default:\n diagnostics = parseGeneric(text, parser, workspaceRoot);\n break;\n }\n const sorted = dedupeDiagnostics(diagnostics).sort(compareDiagnostics);\n const omitted = Math.max(0, sorted.length - MAX_DIAGNOSTICS);\n const kept = Object.freeze(sorted.slice(0, MAX_DIAGNOSTICS).map((item) => Object.freeze(item)));\n return {\n diagnostics: kept,\n omitted,\n summary: summarize(kept),\n };\n}\n\nexport function diagnosticsForInternalSyntax(\n language: LanguageProfileId,\n target: string,\n sourceText: string,\n): Promise<ParsedDiagnostics> {\n if (language !== 'typescript' && language !== 'javascript') {\n return Promise.resolve({ diagnostics: [], omitted: 0, summary: emptySummary() });\n }\n return import('@typescript/typescript6').then((tsModule) => {\n const ts = ((tsModule as unknown as { default?: typeof tsModule }).default ??\n tsModule) as typeof tsModule;\n const extension = path.extname(target).toLowerCase();\n const scriptKind =\n extension === '.tsx'\n ? ts.ScriptKind.TSX\n : extension === '.ts' || extension === '.mts' || extension === '.cts'\n ? ts.ScriptKind.TS\n : ts.ScriptKind.JSX;\n const sourceFile = ts.createSourceFile(\n path.basename(target),\n sourceText,\n ts.ScriptTarget.Latest,\n false,\n scriptKind,\n );\n const native =\n (sourceFile as unknown as {\n parseDiagnostics?: import('@typescript/typescript6').Diagnostic[];\n })\n .parseDiagnostics ?? [];\n const diagnostics = native.map<LanguageDiagnostic>((diagnostic) => {\n const start = diagnostic.start ?? 0;\n const location = sourceFile.getLineAndCharacterOfPosition(start);\n return {\n severity: diagnostic.category === ts.DiagnosticCategory.Warning ? 'warning' : 'error',\n ...(diagnostic.code ? { code: `TS${diagnostic.code}` } : {}),\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, ' '),\n file: target,\n range: { start: { line: location.line + 1, column: location.character + 1 } },\n source: 'typescript-parser',\n };\n });\n const sorted = dedupeDiagnostics(diagnostics).sort(compareDiagnostics);\n const omitted = Math.max(0, sorted.length - MAX_DIAGNOSTICS);\n const kept = Object.freeze(sorted.slice(0, MAX_DIAGNOSTICS).map((item) => Object.freeze(item)));\n return { diagnostics: kept, omitted, summary: summarize(kept) };\n });\n}\n\nfunction parseTypeScript(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?)\\((\\d+),(\\d+)\\):\\s+(error|warning)\\s+(TS\\d+):\\s*(.+)$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: match[4] === 'warning' ? 'warning' : 'error',\n code: match[5],\n message: match[6]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'typescript',\n });\n }\n return diagnostics;\n}\n\nfunction parseCargoJson(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const value = JSON.parse(line) as {\n reason?: string;\n message?: {\n level?: string;\n code?: { code?: string };\n message?: string;\n spans?: Array<{\n file_name?: string;\n line_start?: number;\n column_start?: number;\n is_primary?: boolean;\n }>;\n };\n };\n if (value.reason !== 'compiler-message' || !value.message?.message) continue;\n const primary =\n value.message.spans?.find((span) => span.is_primary) ?? value.message.spans?.[0];\n diagnostics.push({\n severity: normalizeSeverity(value.message.level),\n ...(value.message.code?.code ? { code: value.message.code.code } : {}),\n message: value.message.message,\n ...(primary?.file_name ? { file: normalizeDiagnosticPath(primary.file_name, root) } : {}),\n ...(primary?.line_start\n ? { range: { start: { line: primary.line_start, column: primary.column_start ?? 1 } } }\n : {}),\n source: 'rustc',\n });\n } catch {\n // Non-JSON build output is retained as raw output, not fabricated into diagnostics.\n }\n }\n return diagnostics;\n}\n\nfunction parseGo(text: string, root: string): LanguageDiagnostic[] {\n return parseLinePattern(\n text,\n /^(.*?\\.go):(\\d+):(\\d+):\\s*(.+)$/gm,\n root,\n 'go',\n (_match, message) => ({ message, severity: /warning/i.test(message) ? 'warning' : 'error' }),\n );\n}\n\nfunction parsePhpLint(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /(?:PHP\\s+)?(?:Parse|Fatal) error:\\s*(.+?)\\s+in\\s+(.+?)\\s+on line\\s+(\\d+)/gi;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: 'error',\n message: match[1]!.trim(),\n file: normalizeDiagnosticPath(match[2]!, root),\n range: { start: { line: toPositiveInt(match[3]), column: 1 } },\n source: 'php',\n });\n }\n return diagnostics;\n}\n\nfunction parseDotnet(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?)\\((\\d+),(\\d+)\\):\\s*(error|warning)\\s+([A-Z]+\\d+):\\s*(.+?)(?:\\s+\\[.+\\])?$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: match[4] === 'warning' ? 'warning' : 'error',\n code: match[5],\n message: match[6]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'dotnet',\n });\n }\n return diagnostics;\n}\n\nfunction parseBiome(text: string, root: string): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n const regex = /^(.+?):(\\d+):(\\d+)\\s+(lint\\/[^\\s]+|format)\\s+(.+)$/gm;\n for (const match of text.matchAll(regex)) {\n diagnostics.push({\n severity: 'warning',\n code: match[4],\n message: match[5]!.trim(),\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source: 'biome',\n });\n }\n return diagnostics;\n}\n\nfunction parseGeneric(text: string, source: string, root: string): LanguageDiagnostic[] {\n return parseLinePattern(\n text,\n /^(.+?):(\\d+):(\\d+):\\s*(?:(error|warning|info):\\s*)?(.+)$/gm,\n root,\n source,\n (match, fallback) => ({\n severity: normalizeSeverity(match[4]),\n message: match[5]?.trim() || fallback,\n }),\n );\n}\n\nexport interface ParsedPackageReports {\n diagnostics: readonly LanguageDiagnostic[];\n vulnerabilities: readonly LanguagePackageVulnerability[];\n outdated: readonly LanguagePackageMutation[];\n}\n\nexport function parsePackageReports(\n parser: string,\n stdout: string,\n stderr: string,\n): ParsedPackageReports {\n const text = `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}`;\n switch (parser) {\n case 'npm-audit':\n return parseNpmAudit(text);\n case 'npm-outdated':\n return parseNpmOutdated(text);\n case 'cargo-audit':\n return parseCargoAudit(text);\n case 'composer-audit':\n return parseComposerAudit(text);\n case 'composer-outdated':\n return parseComposerOutdated(text);\n case 'dotnet-package':\n return parseDotnetPackage(text);\n default:\n return { diagnostics: [], vulnerabilities: [], outdated: [] };\n }\n}\n\nfunction parseNpmAudit(text: string): ParsedPackageReports {\n const advisories: LanguagePackageVulnerability[] = [];\n const diagnostics: LanguageDiagnostic[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities: advisories, outdated: [] };\n }\n const vulnerabilities =\n (root as { vulnerabilities?: Record<string, unknown> })?.vulnerabilities ?? {};\n const advisoriesRecord =\n (root as { advisories?: Record<string, unknown> })?.advisories ?? vulnerabilities;\n for (const [id, value] of Object.entries(advisoriesRecord)) {\n const advisory = value as {\n module_name?: string;\n package_name?: string;\n name?: string;\n title?: string;\n severity?: string;\n url?: string;\n range?: string;\n patched_versions?: string;\n };\n const name = advisory.module_name ?? advisory.package_name ?? advisory.name ?? id;\n advisories.push({\n package: name,\n ...(advisory.title ? { advisory: advisory.title } : { advisory: id }),\n severity: mapSeverity(advisory.severity),\n ...(advisory.patched_versions ? { fixedIn: advisory.patched_versions } : {}),\n ...(advisory.url ? { url: advisory.url } : {}),\n });\n diagnostics.push({\n severity:\n mapSeverity(advisory.severity) === 'critical' || mapSeverity(advisory.severity) === 'high'\n ? 'error'\n : 'warning',\n code: id,\n message: advisory.title ?? `Vulnerability reported for ${name}.`,\n source: 'npm-audit',\n });\n }\n return { diagnostics, vulnerabilities: advisories, outdated: [] };\n}\n\nfunction parseNpmOutdated(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const outdated: LanguagePackageMutation[] = [];\n let payload: Record<string, unknown> = {};\n try {\n payload = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities: [], outdated };\n }\n for (const [name, info] of Object.entries(payload)) {\n const entry = info as {\n current?: string;\n latest?: string;\n wanted?: string;\n type?: string;\n location?: string;\n };\n if (!entry.latest || entry.latest === entry.current) continue;\n outdated.push({\n name,\n previous: entry.current,\n resolved: entry.latest,\n kind: mapOutdatedKind(entry.type),\n });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${name}: ${entry.current ?? '?'} \u2192 ${entry.latest}`,\n source: 'npm-outdated',\n });\n }\n return { diagnostics, vulnerabilities: [], outdated };\n}\n\nfunction parseCargoAudit(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities, outdated: [] };\n }\n const findings = (root as { vulnerabilities?: { found?: unknown } }).vulnerabilities?.found;\n if (!Array.isArray(findings)) return { diagnostics, vulnerabilities, outdated: [] };\n for (const finding of findings) {\n const item = finding as {\n id?: string;\n package?: string;\n title?: string;\n severity?: string;\n patched_versions?: string[];\n url?: { long?: string; short?: string };\n advisory?: { id?: string };\n };\n const name = item.package ?? 'unknown';\n const advisory = item.id ?? item.advisory?.id ?? 'cargo-audit';\n vulnerabilities.push({\n package: name,\n ...(item.title ? { advisory: item.title } : { advisory }),\n severity: mapSeverity(item.severity),\n ...(item.patched_versions && item.patched_versions.length > 0\n ? { fixedIn: item.patched_versions[0] }\n : {}),\n ...(item.url?.short ? { url: item.url.short } : {}),\n });\n diagnostics.push({\n severity:\n mapSeverity(item.severity) === 'critical' || mapSeverity(item.severity) === 'high'\n ? 'error'\n : 'warning',\n code: advisory,\n message: item.title ?? `${name} reported by cargo-audit.`,\n source: 'cargo-audit',\n });\n }\n return { diagnostics, vulnerabilities, outdated: [] };\n}\n\nfunction parseComposerAudit(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const entry = JSON.parse(line) as {\n package?: string;\n advisory?: string;\n title?: string;\n severity?: string;\n affectedVersions?: string;\n url?: string;\n };\n if (!entry.package) continue;\n vulnerabilities.push({\n package: entry.package,\n ...(entry.advisory ? { advisory: entry.advisory } : {}),\n ...(entry.title\n ? { advisory: entry.title }\n : { advisory: entry.advisory ?? 'composer-audit' }),\n severity: mapSeverity(entry.severity),\n ...(entry.affectedVersions ? { fixedIn: entry.affectedVersions } : {}),\n ...(entry.url ? { url: entry.url } : {}),\n });\n diagnostics.push({\n severity: 'warning',\n code: entry.advisory ?? 'composer-audit',\n message: entry.title ?? `${entry.package} reported by composer audit.`,\n source: 'composer-audit',\n });\n } catch {\n // Ignore malformed composer audit lines; raw output is preserved.\n }\n }\n return { diagnostics, vulnerabilities, outdated: [] };\n}\n\nfunction parseComposerOutdated(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const outdated: LanguagePackageMutation[] = [];\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n if (!line.trim().startsWith('{')) continue;\n try {\n const entry = JSON.parse(line) as {\n name?: string;\n version?: string;\n latest?: string;\n description?: string;\n };\n if (!entry.name || entry.version === entry.latest) continue;\n outdated.push({\n name: entry.name,\n previous: entry.version,\n resolved: entry.latest ?? entry.version,\n });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${entry.name}: ${entry.version ?? '?'} \u2192 ${entry.latest ?? '?'}`,\n source: 'composer-outdated',\n });\n } catch {\n // Skip malformed line; the raw output remains available.\n }\n }\n return { diagnostics, vulnerabilities: [], outdated };\n}\n\nfunction parseDotnetPackage(text: string): ParsedPackageReports {\n const diagnostics: LanguageDiagnostic[] = [];\n const vulnerabilities: LanguagePackageVulnerability[] = [];\n const outdated: LanguagePackageMutation[] = [];\n let root: unknown;\n try {\n root = JSON.parse(text);\n } catch {\n return { diagnostics, vulnerabilities, outdated };\n }\n const projects = (root as { projects?: Array<{ frameworks?: unknown; packages?: unknown }> })\n .projects;\n if (!Array.isArray(projects)) return { diagnostics, vulnerabilities, outdated };\n for (const project of projects) {\n const packages = Array.isArray(project.packages) ? project.packages : [];\n for (const pkg of packages as Array<Record<string, unknown>>) {\n const name = typeof pkg.name === 'string' ? pkg.name : 'unknown';\n const requested = typeof pkg.requestedVersion === 'string' ? pkg.requestedVersion : undefined;\n const resolved = typeof pkg.resolvedVersion === 'string' ? pkg.resolvedVersion : undefined;\n const vulnerabilitiesRaw = Array.isArray(pkg.vulnerabilities) ? pkg.vulnerabilities : [];\n for (const vuln of vulnerabilitiesRaw as Array<Record<string, unknown>>) {\n const advisory =\n typeof vuln.advisoryUrl === 'string' ? vuln.advisoryUrl : 'dotnet-vulnerable';\n vulnerabilities.push({\n package: name,\n advisory,\n severity: mapSeverity(typeof vuln.severity === 'string' ? vuln.severity : undefined),\n });\n }\n if (vulnerabilitiesRaw.length > 0) {\n diagnostics.push({\n severity: 'warning',\n code: 'dotnet-vulnerable',\n message: `${name} has ${vulnerabilitiesRaw.length} known vulnerability entry/entries.`,\n source: 'dotnet-package',\n });\n }\n if (\n requested &&\n resolved &&\n requested.startsWith('>') &&\n requested.split('>')[1]!.split('.').slice(0, 2).join('.') !==\n resolved.split('.').slice(0, 2).join('.')\n ) {\n outdated.push({ name, requested, resolved });\n diagnostics.push({\n severity: 'info',\n code: 'outdated',\n message: `${name}: ${requested} \u2192 ${resolved}`,\n source: 'dotnet-package',\n });\n }\n }\n }\n return { diagnostics, vulnerabilities, outdated };\n}\n\nfunction mapSeverity(value: string | undefined): LanguagePackageVulnerability['severity'] {\n switch (value?.toLowerCase()) {\n case 'critical':\n case 'high':\n return 'high';\n case 'medium':\n case 'moderate':\n return 'moderate';\n case 'low':\n return 'low';\n case 'unknown':\n return 'unknown';\n default:\n return 'unknown';\n }\n}\n\nfunction mapOutdatedKind(value: string | undefined): 'runtime' | 'development' | 'optional' {\n switch (value?.toLowerCase()) {\n case 'devdependencies':\n case 'development':\n return 'development';\n case 'optionaldependencies':\n case 'optional':\n return 'optional';\n default:\n return 'runtime';\n }\n}\n\nfunction parseLinePattern(\n text: string,\n regex: RegExp,\n root: string,\n source: string,\n details: (\n match: RegExpMatchArray,\n fallback: string,\n ) => { severity: LanguageDiagnostic['severity']; message: string },\n): LanguageDiagnostic[] {\n const diagnostics: LanguageDiagnostic[] = [];\n for (const match of text.matchAll(regex)) {\n const parsed = details(match, match.at(-1)?.trim() ?? 'Diagnostic');\n diagnostics.push({\n severity: parsed.severity,\n message: parsed.message,\n file: normalizeDiagnosticPath(match[1]!, root),\n range: { start: { line: toPositiveInt(match[2]), column: toPositiveInt(match[3]) } },\n source,\n });\n }\n return diagnostics;\n}\n\nfunction normalizeDiagnosticPath(value: string, root: string): string {\n const clean = value.trim().replace(/^['\"]|['\"]$/g, '');\n return path.resolve(root, clean);\n}\n\nfunction normalizeSeverity(value: string | undefined): LanguageDiagnostic['severity'] {\n if (value === 'warning' || value === 'warn') return 'warning';\n if (value === 'info' || value === 'note' || value === 'help') return 'info';\n if (value === 'hint') return 'hint';\n return 'error';\n}\n\nfunction toPositiveInt(value: string | undefined): number {\n return Math.max(1, Number.parseInt(value ?? '1', 10) || 1);\n}\n\nfunction summarize(diagnostics: readonly LanguageDiagnostic[]): LanguageRunSummary {\n return {\n errors: diagnostics.filter((item) => item.severity === 'error').length,\n warnings: diagnostics.filter((item) => item.severity === 'warning').length,\n infos: diagnostics.filter((item) => item.severity === 'info' || item.severity === 'hint')\n .length,\n };\n}\n\nfunction emptySummary(): LanguageRunSummary {\n return { errors: 0, warnings: 0, infos: 0 };\n}\n\nfunction dedupeDiagnostics(items: readonly LanguageDiagnostic[]): LanguageDiagnostic[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = [\n item.source,\n item.code ?? '',\n item.file ?? '',\n item.range?.start.line ?? 0,\n item.range?.start.column ?? 0,\n item.message,\n ].join('\\0');\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction compareDiagnostics(a: LanguageDiagnostic, b: LanguageDiagnostic): number {\n return (\n (a.file ?? '').localeCompare(b.file ?? '') ||\n (a.range?.start.line ?? 0) - (b.range?.start.line ?? 0) ||\n (a.range?.start.column ?? 0) - (b.range?.start.column ?? 0) ||\n severityRank(a.severity) - severityRank(b.severity) ||\n (a.code ?? '').localeCompare(b.code ?? '') ||\n a.message.localeCompare(b.message)\n );\n}\n\nfunction severityRank(value: LanguageDiagnostic['severity']): number {\n return value === 'error' ? 0 : value === 'warning' ? 1 : value === 'info' ? 2 : 3;\n}\n", "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { ToolProgressEvent } from '@wrongstack/core/types';\nimport { type SpawnStreamResult, spawnStream } from '../_spawn-stream.js';\nimport { normalizeCommandOutput } from '../_util.js';\nimport {\n diagnosticsForInternalSyntax,\n parseLanguageDiagnostics,\n parsePackageReports,\n} from './diagnostics.js';\nimport { validateCommandPlan } from './plan.js';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n CommandPlan,\n DetectedWorkspace,\n LanguagePackageMutation,\n LanguagePackageOutcome,\n LanguagePackageVulnerability,\n LanguageRunResult,\n LanguageRunSummary,\n} from './types.js';\n\nconst MAX_INTERNAL_SOURCE_BYTES = 1_500_000;\n\nexport interface ExecuteLanguagePlanOptions {\n projectRoot: string;\n workspace: DetectedWorkspace;\n plan: CommandPlan;\n signal: AbortSignal;\n}\n\nexport async function* executeLanguagePlan(\n options: ExecuteLanguagePlanOptions,\n): AsyncGenerator<ToolProgressEvent, LanguageRunResult> {\n const { plan, workspace } = options;\n if (options.signal.aborted) {\n return terminalResult(options, 'cancelled', options.signal.reason);\n }\n const profile = languageProfileRegistry.get(plan.profileId);\n if (!profile) return unavailableResult(options, `Unknown language profile: ${plan.profileId}`);\n if (workspace.id !== plan.workspaceId || workspace.language !== plan.profileId) {\n return unavailableResult(options, 'Plan and workspace identity do not match.');\n }\n const validation = validateCommandPlan(plan, profile, options.projectRoot);\n if (validation.length > 0) {\n return unavailableResult(options, `Plan failed execution validation: ${validation.join('; ')}`);\n }\n const containmentError = await validatePlanRealpaths(plan, options.projectRoot);\n if (containmentError) return unavailableResult(options, containmentError);\n if (plan.operation.startsWith('package-') || plan.network) {\n return terminalNonPackageResult(\n options,\n 'Package and network plans require the separate language_package tool (Phase 3).',\n );\n }\n\n const startedAt = Date.now();\n yield {\n type: 'log',\n text:\n plan.kind === 'internal'\n ? `Running ${plan.parser}\u2026`\n : `${plan.command} ${plan.args.join(' ')}`,\n data: { language: plan.profileId, operation: plan.operation, workspace: workspace.root },\n };\n\n if (plan.kind === 'internal') {\n try {\n return await executeInternal(options, startedAt);\n } catch (error) {\n return unavailableResult(options, error instanceof Error ? error.message : String(error));\n }\n }\n\n const timeoutController = new AbortController();\n const timer = setTimeout(\n () => timeoutController.abort(new Error('language plan timed out')),\n plan.timeoutMs,\n );\n timer.unref?.();\n const signal = AbortSignal.any([options.signal, timeoutController.signal]);\n let spawned: SpawnStreamResult;\n try {\n const stream = spawnStream({\n cmd: plan.command!,\n args: [...plan.args],\n cwd: plan.cwd,\n signal,\n maxBytes: plan.outputLimitBytes,\n });\n for (;;) {\n const next = await stream.next();\n if (next.done) {\n spawned = next.value;\n break;\n }\n yield next.value;\n }\n } catch (error) {\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n return {\n status: timedOut ? 'timed_out' : cancelled ? 'cancelled' : 'failed',\n language: plan.profileId,\n workspace,\n plan,\n exitCode: null,\n durationMs: Date.now() - startedAt,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: '',\n truncated: false,\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n clearTimeout(timer);\n }\n\n const parsed = parseLanguageDiagnostics(\n plan.parser,\n spawned.stdout,\n spawned.stderr,\n workspace.root,\n );\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n const spawnUnavailable = Boolean(\n spawned.error && /ENOENT|not found|cannot find/i.test(spawned.error),\n );\n const status: LanguageRunResult['status'] = timedOut\n ? 'timed_out'\n : cancelled\n ? 'cancelled'\n : spawnUnavailable\n ? 'unavailable'\n : spawned.exitCode === 0\n ? 'passed'\n : 'failed';\n const raw = [spawned.stdout, spawned.stderr, spawned.error].filter(Boolean).join('\\n');\n return {\n status,\n language: plan.profileId,\n workspace,\n plan,\n exitCode: spawned.exitCode,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output: normalizeCommandOutput(raw, { maxBytes: plan.outputLimitBytes }),\n truncated: spawned.truncated,\n ...(spawned.spoolPath ? { spoolPath: spawned.spoolPath } : {}),\n ...(spawned.error ? { error: spawned.error } : {}),\n };\n}\n\nasync function executeInternal(\n options: ExecuteLanguagePlanOptions,\n startedAt: number,\n): Promise<LanguageRunResult> {\n const target = options.plan.evidence.find((item) => item.kind === 'target')?.path;\n if (!target) return unavailableResult(options, 'Internal syntax plan has no target evidence.');\n const safeTarget = await assertContainedFile(target, options.projectRoot);\n const stat = await fs.stat(safeTarget);\n if (stat.size > MAX_INTERNAL_SOURCE_BYTES) {\n return unavailableResult(\n options,\n `Internal syntax target exceeds ${MAX_INTERNAL_SOURCE_BYTES} bytes.`,\n );\n }\n const source = await fs.readFile(safeTarget, 'utf8');\n const parsed = await diagnosticsForInternalSyntax(options.plan.profileId, safeTarget, source);\n return {\n status: parsed.summary.errors > 0 ? 'failed' : 'passed',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: parsed.summary.errors > 0 ? 1 : 0,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output:\n parsed.summary.errors > 0\n ? `${parsed.summary.errors} syntax error(s) found.`\n : 'Syntax check passed.',\n truncated: false,\n };\n}\n\nasync function validatePlanRealpaths(\n plan: CommandPlan,\n projectRoot: string,\n): Promise<string | undefined> {\n const realRoot = await fs.realpath(projectRoot);\n let realCwd: string;\n try {\n realCwd = await fs.realpath(plan.cwd);\n } catch (error) {\n return `Plan cwd is unavailable: ${error instanceof Error ? error.message : String(error)}`;\n }\n if (!isRealInside(realCwd, realRoot)) return 'Plan cwd resolves outside project root.';\n for (const argument of plan.args) {\n if (!path.isAbsolute(argument)) continue;\n try {\n const realArgument = await fs.realpath(argument);\n if (!isRealInside(realArgument, realRoot)) {\n return `Plan argument resolves outside project root: ${argument}`;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n return `Plan argument could not be resolved safely: ${argument}`;\n }\n }\n }\n return undefined;\n}\n\nfunction isRealInside(candidate: string, root: string): boolean {\n const relative = path.relative(root, candidate);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nasync function assertContainedFile(candidate: string, projectRoot: string): Promise<string> {\n const realRoot = await fs.realpath(projectRoot);\n const realTarget = await fs.realpath(candidate);\n const relative = path.relative(realRoot, realTarget);\n if (relative.startsWith('..') || path.isAbsolute(relative)) {\n throw new Error(`Internal syntax target resolves outside project root: ${candidate}`);\n }\n return realTarget;\n}\n\nfunction terminalResult(\n options: ExecuteLanguagePlanOptions,\n status: 'cancelled' | 'timed_out',\n reason: unknown,\n): LanguageRunResult {\n const message = reason instanceof Error ? reason.message : reason ? String(reason) : status;\n return {\n status,\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: '',\n truncated: false,\n error: message,\n };\n}\n\nfunction unavailableResult(options: ExecuteLanguagePlanOptions, reason: string): LanguageRunResult {\n return {\n status: 'unavailable',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: reason,\n truncated: false,\n error: reason,\n };\n}\n\nfunction emptySummary(): LanguageRunSummary {\n return { errors: 0, warnings: 0, infos: 0 };\n}\n\nfunction terminalNonPackageResult(\n options: ExecuteLanguagePlanOptions,\n reason: string,\n): LanguageRunResult {\n return {\n status: 'unavailable',\n language: options.plan.profileId,\n workspace: options.workspace,\n plan: options.plan,\n exitCode: null,\n durationMs: 0,\n diagnostics: Object.freeze([]),\n omittedDiagnostics: 0,\n summary: emptySummary(),\n output: reason,\n truncated: false,\n error: reason,\n };\n}\n\nexport interface ExecutePackagePlanOptions {\n projectRoot: string;\n workspace: DetectedWorkspace;\n plan: CommandPlan;\n packages: readonly string[];\n signal: AbortSignal;\n}\n\nexport async function* executePackagePlan(\n options: ExecutePackagePlanOptions,\n): AsyncGenerator<ToolProgressEvent, LanguagePackageOutcome> {\n const { plan, workspace } = options;\n const startedAt = Date.now();\n if (options.signal.aborted) {\n yield { type: 'log', text: 'Run cancelled before execution.' };\n return terminalPackageResult(options, 'cancelled', startedAt);\n }\n const profile = languageProfileRegistry.get(plan.profileId);\n if (!profile) {\n yield { type: 'warning', text: `Unknown language profile: ${plan.profileId}` };\n return terminalPackageResult(options, 'unavailable', startedAt, 'Unknown language profile.');\n }\n if (workspace.id !== plan.workspaceId || workspace.language !== plan.profileId) {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n 'Plan and workspace identity do not match.',\n );\n }\n const validation = validateCommandPlan(plan, profile, options.projectRoot);\n if (validation.length > 0) {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n `Plan failed execution validation: ${validation.join('; ')}`,\n );\n }\n const containmentError = await validatePlanRealpaths(plan, options.projectRoot);\n if (containmentError) {\n return terminalPackageResult(options, 'unavailable', startedAt, containmentError);\n }\n\n const manifestsBefore = await snapshotPaths(workspace.manifests);\n const lockfilePaths = collectLockfilePaths(workspace);\n const lockfilesBefore = await snapshotPaths(lockfilePaths);\n const manifestSizesBefore = await snapshotSizes(workspace.manifests);\n const lockfileSizesBefore = await snapshotSizes(lockfilePaths);\n\n yield {\n type: 'log',\n text:\n plan.kind === 'process'\n ? `${plan.command} ${plan.args.join(' ')}`\n : `${plan.parser}: ${plan.operation}`,\n data: {\n language: plan.profileId,\n operation: plan.operation,\n workspace: workspace.root,\n packages: [...options.packages],\n },\n };\n\n const timeoutController = new AbortController();\n const timer = setTimeout(\n () => timeoutController.abort(new Error('language package plan timed out')),\n plan.timeoutMs,\n );\n timer.unref?.();\n const signal = AbortSignal.any([options.signal, timeoutController.signal]);\n let spawned: SpawnStreamResult | undefined;\n let run: LanguageRunResult | undefined;\n let status: LanguagePackageOutcome['status'] = 'unavailable';\n let error: string | undefined;\n try {\n if (plan.kind !== 'process') {\n return terminalPackageResult(\n options,\n 'unavailable',\n startedAt,\n 'Package operations require an executable plan; internal plans cannot mutate the manifest.',\n );\n }\n const stream = spawnStream({\n cmd: plan.command!,\n args: [...plan.args],\n cwd: plan.cwd,\n signal,\n maxBytes: plan.outputLimitBytes,\n });\n for (;;) {\n const next = await stream.next();\n if (next.done) {\n spawned = next.value;\n break;\n }\n yield next.value;\n }\n } catch (error_) {\n error = error_ instanceof Error ? error_.message : String(error_);\n } finally {\n clearTimeout(timer);\n }\n\n if (spawned) {\n const parsed = parseLanguageDiagnostics(\n plan.parser,\n spawned.stdout,\n spawned.stderr,\n workspace.root,\n );\n const timedOut = timeoutController.signal.aborted && !options.signal.aborted;\n const cancelled = options.signal.aborted;\n const spawnUnavailable = Boolean(\n spawned.error && /ENOENT|not found|cannot find/i.test(spawned.error),\n );\n status = timedOut\n ? 'timed_out'\n : cancelled\n ? 'cancelled'\n : spawnUnavailable\n ? 'unavailable'\n : spawned.exitCode === 0\n ? 'passed'\n : 'failed';\n error ??= spawned.error;\n const raw = [spawned.stdout, spawned.stderr, spawned.error].filter(Boolean).join('\\n');\n run = {\n status,\n language: plan.profileId,\n workspace,\n plan,\n exitCode: spawned.exitCode,\n durationMs: Date.now() - startedAt,\n diagnostics: parsed.diagnostics,\n omittedDiagnostics: parsed.omitted,\n summary: parsed.summary,\n output: normalizeCommandOutput(raw, { maxBytes: plan.outputLimitBytes }),\n truncated: spawned.truncated,\n ...(spawned.spoolPath ? { spoolPath: spawned.spoolPath } : {}),\n ...(spawned.error ? { error: spawned.error } : {}),\n };\n } else {\n status = options.signal.aborted\n ? 'cancelled'\n : timeoutController.signal.aborted\n ? 'timed_out'\n : 'failed';\n }\n\n if (status !== 'passed') {\n return terminalPackageResult(\n options,\n status,\n startedAt,\n error,\n run,\n manifestsBefore,\n lockfilesBefore,\n );\n }\n\n const manifestsAfter = await snapshotPaths(workspace.manifests);\n const lockfilesAfter = await snapshotPaths(lockfilePaths);\n const manifestSizesAfter = await snapshotSizes(workspace.manifests);\n const lockfileSizesAfter = await snapshotSizes(lockfilePaths);\n const manifestsChanged = await changedPaths(\n manifestsBefore,\n manifestsAfter,\n manifestSizesBefore,\n manifestSizesAfter,\n );\n const lockfilesChanged = await changedPaths(\n lockfilesBefore,\n lockfilesAfter,\n lockfileSizesBefore,\n lockfileSizesAfter,\n );\n const reports = parsePackageReports(plan.parser, spawned?.stdout ?? '', spawned?.stderr ?? '');\n const mutations = packageMutationsFromInputs(options.packages, reports.outdated);\n return {\n workspace,\n language: plan.profileId,\n operation: plan.operation,\n status,\n ...(run ? { run } : {}),\n durationMs: Date.now() - startedAt,\n manifestsBefore,\n lockfilesBefore,\n manifestsAfter,\n lockfilesAfter,\n mutations,\n vulnerabilities: reports.vulnerabilities,\n outdated: reports.outdated,\n manifestsChanged: Object.freeze(manifestsChanged),\n lockfilesChanged: Object.freeze(lockfilesChanged),\n };\n}\n\nfunction packageMutationsFromInputs(\n inputs: readonly string[],\n outdated: readonly LanguagePackageMutation[],\n): readonly LanguagePackageMutation[] {\n const outdatedNames = new Set(outdated.map((entry) => entry.name));\n return inputs\n .filter((name) => !outdatedNames.has(name))\n .map<LanguagePackageMutation>((name) => ({ name, requested: name, kind: 'runtime' }));\n}\n\nasync function snapshotPaths(paths: readonly string[]): Promise<readonly string[]> {\n const existing: string[] = [];\n for (const candidate of paths) {\n try {\n const stat = await fs.stat(candidate);\n if (!stat.isFile()) continue;\n existing.push(candidate);\n } catch {\n // Missing path is fine.\n }\n }\n return Object.freeze(existing);\n}\n\nasync function changedPaths(\n before: readonly string[],\n after: readonly string[],\n beforeSizes?: ReadonlyMap<string, number>,\n afterSizes?: ReadonlyMap<string, number>,\n): Promise<string[]> {\n const beforeSet = new Set(before);\n const afterSet = new Set(after);\n const changed = new Set<string>();\n for (const path of after) {\n if (!beforeSet.has(path)) changed.add(path);\n }\n for (const path of before) {\n if (!afterSet.has(path)) changed.add(path);\n }\n if (beforeSizes && afterSizes) {\n for (const path of after) {\n if (beforeSizes.get(path) !== afterSizes.get(path)) changed.add(path);\n }\n }\n return [...changed].sort();\n}\n\nasync function snapshotSizes(paths: readonly string[]): Promise<ReadonlyMap<string, number>> {\n const sizes = new Map<string, number>();\n for (const candidate of paths) {\n try {\n const stat = await fs.stat(candidate);\n if (stat.isFile()) sizes.set(candidate, stat.size);\n } catch {\n // Skip missing files.\n }\n }\n return sizes;\n}\n\nfunction collectLockfilePaths(workspace: DetectedWorkspace): readonly string[] {\n const explicit = workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.path);\n const detected =\n LOCKFILE_NAMES_BY_PROFILE.get(workspace.language)?.map((name) =>\n path.join(workspace.root, name),\n ) ?? [];\n const merged = new Set<string>();\n for (const candidate of [...explicit, ...detected]) merged.add(candidate);\n return Object.freeze([...merged]);\n}\n\nconst LOCKFILE_NAMES_BY_PROFILE: ReadonlyMap<DetectedWorkspace['language'], readonly string[]> =\n new Map([\n ['typescript', ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock', 'bun.lockb']],\n ['javascript', ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock', 'bun.lockb']],\n ['go', ['go.sum']],\n ['rust', ['Cargo.lock']],\n ['php', ['composer.lock']],\n ['csharp', ['packages.lock.json']],\n ]);\n\nfunction terminalPackageResult(\n options: ExecutePackagePlanOptions,\n status: LanguagePackageOutcome['status'],\n startedAt: number,\n error?: string,\n run?: LanguageRunResult,\n manifestsBefore: readonly string[] = [],\n lockfilesBefore: readonly string[] = [],\n): LanguagePackageOutcome {\n return {\n workspace: options.workspace,\n language: options.plan.profileId,\n operation: options.plan.operation,\n status,\n ...(run ? { run } : {}),\n durationMs: Date.now() - startedAt,\n manifestsBefore,\n lockfilesBefore,\n manifestsAfter: manifestsBefore,\n lockfilesAfter: lockfilesBefore,\n manifestsChanged: Object.freeze([]),\n lockfilesChanged: Object.freeze([]),\n mutations: Object.freeze([]),\n vulnerabilities: Object.freeze([]) as readonly LanguagePackageVulnerability[],\n outdated: Object.freeze([]) as readonly LanguagePackageMutation[],\n ...(error ? { error } : {}),\n };\n}\n", "import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { detectLanguageWorkspaces } from './detect.js';\nimport { languageProfileRegistry } from './registry.js';\nimport type {\n CommandPlan,\n DetectedWorkspace,\n LanguageOperation,\n LanguageProfile,\n PlanLanguageOptions,\n PlanLanguageResult,\n ProfileContext,\n} from './types.js';\n\nconst MAX_ARGUMENTS = 128;\nconst MAX_ARGUMENT_LENGTH = 4_096;\nconst PACKAGE_NAME_RE = /^(?:@[a-z0-9._-]+\\/)?[a-z0-9._-]+(?:@[a-z0-9*+._~^<>=|-]+)?$/i;\nconst COMPOSER_PACKAGE_RE = /^[a-z0-9_.-]+\\/[a-z0-9_.-]+(?::[a-z0-9*+._~^<>=|-]+)?$/i;\nconst GO_MODULE_RE = /^(?:[a-z0-9.-]+\\.)+[a-z0-9.-]+\\/[a-z0-9._~+/@-]+$/i;\nconst PYTHON_PACKAGE_RE = /^[a-z0-9._-]+(?:\\[[a-z0-9._,-]+\\])?==[a-z0-9*+._!~-]+$/i;\n\nexport async function planLanguageOperation(\n options: PlanLanguageOptions,\n): Promise<PlanLanguageResult> {\n validateOperationOptions(options.operation, options.operationOptions?.packages);\n const detection = await detectLanguageWorkspaces(options);\n const candidates = detection.workspaces.filter((workspace) =>\n workspace.capabilities.includes(options.operation),\n );\n const selected = selectWorkspace(candidates, options);\n if (selected.status !== 'selected') return selected.result;\n\n const profile = (options.profiles ?? languageProfileRegistry.list()).find(\n (item) => item.id === selected.workspace.language,\n );\n if (!profile) {\n return {\n status: 'not_found',\n reason: `Profile ${selected.workspace.language} is unavailable.`,\n candidates,\n };\n }\n if (\n (profile.id === 'typescript' || profile.id === 'javascript') &&\n options.operation !== 'syntax' &&\n selected.workspace.packageManager === undefined &&\n new Set(\n selected.workspace.evidence\n .filter((evidence) => evidence.kind === 'lockfile')\n .map((evidence) => evidence.value.toLowerCase()),\n ).size > 1\n ) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: 'Conflicting Node lockfiles make the package manager ambiguous.',\n },\n };\n }\n const resolver = profile.operations[options.operation];\n if (!resolver) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: `${profile.displayName} does not define ${options.operation}.`,\n },\n };\n }\n const canonicalCwd = options.cwd\n ? path.isAbsolute(options.cwd)\n ? options.cwd\n : path.resolve(detection.projectRoot, options.cwd)\n : detection.projectRoot;\n const target = options.target\n ? await canonicalTarget(canonicalCwd, options.target, detection.projectRoot)\n : undefined;\n const ctx: ProfileContext = {\n projectRoot: detection.projectRoot,\n workspace: selected.workspace,\n ...(target ? { target } : {}),\n mode: options.mode ?? 'standard',\n options: options.operationOptions ?? {},\n platform: process.platform,\n pathExists: async (candidate) => {\n try {\n await fs.access(path.resolve(detection.projectRoot, candidate));\n return true;\n } catch {\n return false;\n }\n },\n };\n const result = await resolver(ctx);\n if ('status' in result) {\n return { status: 'unavailable', workspace: selected.workspace, unavailable: result };\n }\n const errors = validateCommandPlan(result, profile, detection.projectRoot);\n if (errors.length > 0) {\n return {\n status: 'unavailable',\n workspace: selected.workspace,\n unavailable: {\n status: 'unavailable',\n profileId: profile.id,\n workspaceId: selected.workspace.id,\n operation: options.operation,\n reason: `Generated plan failed validation: ${errors.join('; ')}`,\n },\n };\n }\n return { status: 'planned', workspace: selected.workspace, plan: Object.freeze(result) };\n}\n\nexport function validateCommandPlan(\n plan: CommandPlan,\n profile: LanguageProfile,\n projectRoot: string,\n): string[] {\n const errors: string[] = [];\n if (plan.profileId !== profile.id) errors.push('profile id does not match');\n if (!isInside(plan.cwd, projectRoot)) errors.push('cwd is outside project root');\n if (plan.args.length > MAX_ARGUMENTS) errors.push(`argument count exceeds ${MAX_ARGUMENTS}`);\n if (plan.args.some((arg) => arg.length > MAX_ARGUMENT_LENGTH || /[\\r\\n\\0]/.test(arg))) {\n errors.push('arguments contain an invalid or oversized value');\n }\n if (!Number.isFinite(plan.timeoutMs) || plan.timeoutMs < 1 || plan.timeoutMs > 600_000) {\n errors.push('timeout is outside 1..600000ms');\n }\n if (\n !Number.isFinite(plan.outputLimitBytes) ||\n plan.outputLimitBytes < 1 ||\n plan.outputLimitBytes > 1_000_000\n ) {\n errors.push('output limit is outside 1..1000000 bytes');\n }\n if (plan.kind === 'internal') {\n if (plan.command !== null || plan.args.length !== 0)\n errors.push('internal plans cannot declare a command');\n } else {\n if (!plan.command || !profile.executables.includes(plan.command)) {\n errors.push(`executable \"${plan.command ?? ''}\" is not allowlisted by the profile`);\n }\n }\n if (Object.keys(plan.env).length > 0)\n errors.push('Phase 1 plans cannot override environment variables');\n return errors;\n}\n\nfunction selectWorkspace(\n candidates: readonly DetectedWorkspace[],\n options: PlanLanguageOptions,\n):\n | { status: 'selected'; workspace: DetectedWorkspace }\n | { status: 'result'; result: PlanLanguageResult } {\n if (candidates.length === 0) {\n return {\n status: 'result',\n result: {\n status: 'not_found',\n reason: `No workspace supports ${options.operation}.`,\n candidates: [],\n },\n };\n }\n if (options.workspace) {\n const requested = path.isAbsolute(options.workspace)\n ? path.resolve(options.workspace)\n : path.resolve(options.projectRoot, options.workspace);\n const matches = candidates.filter(\n (item) => item.id === options.workspace || path.resolve(item.root) === requested,\n );\n if (matches.length === 1) return { status: 'selected', workspace: matches[0]! };\n return {\n status: 'result',\n result: {\n status: 'not_found',\n reason: `Requested workspace \"${options.workspace}\" was not detected.`,\n candidates: [...candidates],\n },\n };\n }\n if (options.target) {\n const base = options.cwd\n ? path.isAbsolute(options.cwd)\n ? path.resolve(options.cwd)\n : path.resolve(options.projectRoot, options.cwd)\n : path.resolve(options.projectRoot);\n const target = path.isAbsolute(options.target)\n ? path.resolve(options.target)\n : path.resolve(base, options.target);\n const targeted = candidates\n .filter((item) => item.evidence.some((evidence) => evidence.kind === 'target'))\n .sort(\n (a, b) =>\n workspaceDepth(b.root, options.projectRoot) -\n workspaceDepth(a.root, options.projectRoot) || compareCandidates(a, b),\n );\n if (targeted[0]) return { status: 'selected', workspace: targeted[0] };\n const containing = candidates\n .filter((item) => isInside(target, item.root))\n .sort(\n (a, b) =>\n workspaceDepth(b.root, options.projectRoot) -\n workspaceDepth(a.root, options.projectRoot) || compareCandidates(a, b),\n );\n if (containing[0]) return { status: 'selected', workspace: containing[0] };\n }\n const sorted = [...candidates].sort(compareCandidates);\n const first = sorted[0]!;\n const firstDepth = workspaceDepth(first.root, options.projectRoot);\n const tied = sorted.filter(\n (item) =>\n item.confidence === first.confidence &&\n workspaceDepth(item.root, options.projectRoot) === firstDepth,\n );\n if (tied.length > 1) {\n return {\n status: 'result',\n result: {\n status: 'ambiguous',\n reason:\n 'Multiple workspaces have equal confidence; provide target, language, or workspace.',\n candidates: tied,\n },\n };\n }\n return { status: 'selected', workspace: first };\n}\n\nfunction compareCandidates(a: DetectedWorkspace, b: DetectedWorkspace): number {\n return (\n b.confidence - a.confidence ||\n a.language.localeCompare(b.language) ||\n a.root.localeCompare(b.root)\n );\n}\n\nfunction workspaceDepth(workspaceRoot: string, projectRoot: string): number {\n const relative = path.relative(path.resolve(projectRoot), path.resolve(workspaceRoot));\n return relative === '' ? 0 : relative.split(path.sep).length;\n}\n\nfunction validateOperationOptions(\n operation: LanguageOperation,\n packages?: readonly string[],\n): void {\n if (!operation.startsWith('package-') || !packages) return;\n for (const value of packages) {\n if (!value || value.length > 214 || value.startsWith('-') || /[\\r\\n\\0;&|`$<>\\\\]/.test(value)) {\n throw new Error(`Invalid package identifier \"${value}\"`);\n }\n if (\n value.startsWith('.') ||\n value.startsWith('/') ||\n /^[A-Za-z]:/.test(value) ||\n value.includes('://')\n ) {\n throw new Error(`Package paths and URLs are not supported: \"${value}\"`);\n }\n if (\n !PACKAGE_NAME_RE.test(value) &&\n !COMPOSER_PACKAGE_RE.test(value) &&\n !GO_MODULE_RE.test(value) &&\n !PYTHON_PACKAGE_RE.test(value)\n ) {\n throw new Error(`Invalid package identifier \"${value}\"`);\n }\n }\n}\n\nasync function canonicalTarget(cwd: string, target: string, projectRoot: string): Promise<string> {\n const resolved = path.isAbsolute(target) ? path.resolve(target) : path.resolve(cwd, target);\n let real: string;\n try {\n real = await fs.realpath(resolved);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n const parent = await fs.realpath(path.dirname(resolved));\n real = path.join(parent, path.basename(resolved));\n }\n if (!isInside(real, projectRoot)) throw new Error(`target is outside project root: ${target}`);\n return real;\n}\n\nfunction isInside(candidate: string, root: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(candidate));\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path", "spawn", "isWin", "path", "spawn", "exitCode", "resolve", "path", "fs", "path", "fs", "path", "basename", "candidate", "stat", "relative", "path", "fs", "path", "fs", "path", "isInside", "relative", "timedOut", "cancelled", "emptySummary", "stat", "relative", "stat"]
|
|
7
7
|
}
|