export interface PlatformCommand { command: string; args: string[]; } export interface PlatformCommandRuntime { nodeExecutable?: string; npmExecPath?: string; pathValue?: string; cwd?: string; fileExists?: (path: string) => boolean; /** * Override the resolved OpenLore CLI entry. `null` forces the portable npx form. * Distinct from `fileExists`, which exists only to locate the npm CLI on Windows. */ openloreCliEntry?: string | null; } /** * Return a child-process invocation that can launch Node package-manager shims * on the selected platform. Windows `.cmd` files require a shell, so avoid that * boundary entirely: run the npm CLI entry point through the already-running, * absolute Node executable. Other commands and platforms pass through unchanged. */ export declare function resolvePlatformCommand(command: string, args?: readonly string[], platform?: NodeJS.Platform, runtime?: PlatformCommandRuntime): PlatformCommand; /** * Why the `""` form cannot carry `part` through a POSIX shell, or `null` when it can. * * Double quotes do NOT make a POSIX shell literal — inside them a backslash still escapes * `$`, a backtick, `"` and another backslash, and `$`/backtick still expand. So the quoted * form is right for ordinary Windows paths and WRONG for four shapes, two of which are * worse than the bug it fixes: * * - an embedded `"` ENDS the quoted run, so the remainder of the line executes as code; * - a TRAILING backslash escapes our own closing quote, swallowing every later argument; * - an unescaped `$…` or backtick is SUBSTITUTED — the very thing `quotePosix` above uses * single quotes to prevent, so the Windows branch must not be weaker for the same input; * - `\$`, `` \` ``, `\"` and `\\` (a UNC prefix, `C:\$Recycle.Bin`) lose the backslash and * mangle the path, which is #483's own `Cannot find module`, one turn at a time. * * There is no single string that means the same thing to cmd.exe AND to a POSIX shell for * those, so this REFUSES rather than emitting a line that silently fails or runs code. The * scanner mirrors bash's documented rule and is pinned against a real `bash` in * platform-command.posix-oracle.test.ts (change: harden-windows-hook-quoting). * * NOT covered, deliberately: cmd.exe expands `%VAR%` even inside double quotes and no string * form suppresses it. A literal `%` path round-trips under the Git Bash that actually runs * our hooks, so refusing it would break a working install to appease a shell we do not target. */ export declare function windowsQuotingHazard(part: string): string | null; /** * The first part of `invocation` that cannot be formatted for Windows, or `null`. * * Exported for the callers that must NOT take the throw below: an install adapter refuses * just the one config field and reports why, and `openlore update` prints its generic * instructions, rather than either crashing a whole run over an unwritable path. */ export declare function windowsCommandHazard(invocation: PlatformCommand): { part: string; reason: string; } | null; /** * Format a resolved fixed-argv invocation for dry-run output and config command fields. * * The result is a STRING a host runs through a shell (an agent hook command), so the * quoting has to match that shell. Since fix-windows-console-flash-from-npx-shim these * strings carry absolute filesystem paths on every platform — including the user's home * directory — so a path is no longer safely assumed to be free of shell metacharacters. * * `platform` is REQUIRED, not defaulted: a caller that resolved an invocation FOR another * platform must format it for that same platform, and a default silently got that wrong. */ export declare function formatPlatformCommand(invocation: PlatformCommand, platform: NodeJS.Platform): string; /** * Does `value` look like OpenLore's own CLI entry point — the path * `resolveOpenloreCommand` writes into a host config? * * Kept beside the emitter on purpose: uninstall identifies a marker-less entry by * this shape, and the two must never drift apart. */ export declare function isOpenloreCliEntryPath(value: string): boolean; /** * OpenLore's own CLI entry point, or `null` when it must not be wired into a config. * * `null` covers two cases, both of which fall back to the portable `npx` form: * running from TypeScript source (no built sibling), and running out of an npx cache * (a path that is deleted behind us). */ export declare function openloreCliEntry(runtime?: PlatformCommandRuntime): string | null; /** * Resolve an invocation of OpenLore's OWN CLI for a host config file (MCP server * entry, agent hook, …). * * `npx --yes openlore ` is portable but wrong on Windows. * `resolvePlatformCommand` above removes the shim for `npx` ITSELF, yet npx then * launches the TARGET package's bin through its own shim: * * cmd.exe /d /s /c openlore orient --inject * * — a real, visible console window (plus a `conhost.exe`) every time the command * runs. For a `UserPromptSubmit` hook that is one window per agent turn, which is * what made the app unusable on Windows. * * `openlore install` IS openlore, so the CLI entry beside this module is the very * build the user just invoked. Wire that directly with the absolute Node executable: * no shim, no `cmd.exe`, and one process hop fewer on every invocation. * * TRADE-OFF: this writes an absolute path, so it binds the config to this install * location. A global npm install keeps that path across upgrades; a moved or removed * install needs `openlore install` re-run, where the `npx` form would have re-fetched. * That is the deliberate price of not opening a window on every turn. */ export declare function resolveOpenloreCommand(args: readonly string[], platform?: NodeJS.Platform, runtime?: PlatformCommandRuntime): PlatformCommand; //# sourceMappingURL=platform-command.d.ts.map