export declare function getShellConfig(): { shell: string; args: string[]; }; export declare function detectRuntimeShell(): string | undefined; export declare function sanitizeBinaryOutput(text: string): string; export declare function killProcessTree(pid: number): void; /** * Undo a `powershell -Command "…"` wrapper the caller did not need. * * On Windows `exec` ALREADY runs the command in PowerShell (see * getShellConfig). A command that wraps itself in another one therefore runs * nested — and the outer shell parses the double-quoted argument FIRST, which * means it expands every `$name` in it before the inner shell ever sees it. * Undefined outer variables expand to nothing, so the inner script silently * loses its variables: * * sent by the koi: foreach ($d in @('a','b')) { … } * PowerShell ran: foreach ( in @('a','b')) { … } * → "Missing variable name after foreach" * * sent by the koi: @{n='L';e={$_.Line.Trim()}} * PowerShell ran: @{n='L';e={.Line.Trim()}} * → "An expression was expected after '('" * * Traced on the owner's machine 2026-08-17: five failures in one session, all * of them this, all of them looking like the model writing bad PowerShell when * the script it wrote was correct. Unwrapping is strictly better than the * nested run in every case — same shell, same script, one less parse. */ export declare function unwrapNestedPowerShell(command: string): string; /** * Drop a `2>&1` redirection that PowerShell turns into a failure. * * In Windows PowerShell, redirecting a NATIVE command's stderr into the * pipeline wraps every stderr line in a NativeCommandError ErrorRecord and * makes the whole pipeline exit non-zero — even when the program succeeded. * Measured here with a program that prints to both streams and exits 0: * * node -e "console.error(1);console.log(2)" 2>&1 | Out-String * → exit 1, stdout polluted with "node : 1 / At line:1 char:1 / + ..." * same command without the 2>&1 * → exit 0, stdout "2" * * That is what turned a passing `pnpm test 2>&1 | Out-String` into * "tools.exec failed: node.exe : $ tsx --import ./tests/test-env.ts ...". * The test suite was fine; the shell editorialised. * * Removing it loses nothing: exec captures stderr separately and reports both * streams already, which is the reason to merge them in the first place. */ export declare function dropPowerShellStderrMerge(command: string): { command: string; changed: boolean; }; /** * Is this command "throw a URL at the user's default browser"? * * `Start-Process https://…` on Windows, `open https://…` on macOS, * `xdg-open` on Linux, `cmd /c start https://…`. All of them put a page on * screen and hand back nothing: no DOM, no elements, no way to click. A koi * that reaches for one has given up on the task while appearing to do it. * * Deliberately narrow. It matches only a launcher whose argument is a URL, so * `Start-Process notepad`, `open ./report.pdf` and `git open` are untouched — * opening a FILE for someone is a real thing to want. */ export declare function isShellOpenUrl(command: string): boolean;