/** * @fileoverview `roy-agent` CLI path resolver — Task #2895 (v2 PATH-first). * * ## User direction * * User correction (Task #2895 v2): "task-show的实现机制估计是有问题 * 的,需要用系统的roy-agent命令行,而不需要去特定地方找roy-agent * 所需的bin啥的呀" * * Translation: "task-show's implementation mechanism is likely wrong — * it should use the system `roy-agent` CLI, not look for the binary in * specific source-layout locations." * * ## Background (Task #2893) * * v2.5.8 added a fallback HTML page so the `AdapterError: CLI exited * with code 1 and no parseable JSON envelope` error no longer bubbles * to the user. The fallback was visible because the underlying CLI * call **still exits 1**. * * The previous resolution logic preferred hardcoded paths: * 1. `cfg.royAgentCliPath` * 2. `$ROY_AGENT_CLI` * 3. `/../roy-agent/packages/cli/dist/bin/roy-agent.js` * (sibling-repo / monorepo source layout) * 4. `roy-agent` on PATH * * When the user runs `roy-agent run` inside the `roy-agent` monorepo, * step #3 picks the monorepo `roy-agent.js` source file. Without a * locally-built `better_sqlite3.node` binding, that source crashes on * startup with exit 1 and 100+ KiB of stderr — yielding the * `AdapterError` users see. * * ## Resolution order (this module — Task #2895 v2) * * 1. PATH `roy-agent` (`which`-style lookup, executable-bit check). * The bundled `@ai-setting/roy-agent-standalone@1.7.6` binary * ships with native bindings embedded — always works regardless * of cwd / install layout. * 2. Explicit override (`cfg.royAgentCliPath`) when the file exists. * Advanced users only. * 3. `$ROY_AGENT_CLI` env var when the file exists. * 4. Dev hardcoded paths — ONLY when `NODE_ENV !== 'production'`. * Lets plugin authors iterate on the `roy-agent` monorepo without * installing the standalone binary globally. * 5. None of the above → soft fallback: return the literal string * `"roy-agent"` (the OS spawn will look it up via `$PATH` at exec * time) and emit a one-time `process.stderr` warning. This * preserves the v2.5.8 sendIndex failsafe UX (the existing * `AdapterError` will trigger the fallback HTML page with the * Retry button) **without** throwing out of the plugin * constructor — a hard throw would prevent the HTTP server from * ever starting, which is strictly worse than letting users see * the retry-friendly fallback page. Operators who want a quieter * experience can install `@ai-setting/roy-agent-standalone` * globally so step #1 finds it. * * Pure functions only — exported for unit tests. */ /** * Locate `roy-agent` on `$PATH`. Returns the first hit or `undefined` * when no executable named `roy-agent` is discoverable. * * Pure function — exported for tests. Behaviour: * - Splits `$PATH` on `path.delimiter` (POSIX `:` / Windows `;`). * - For each directory, checks `/roy-agent`. * - Accepts either a regular file or a symlink to one. * - Skips directories that don't exist (no throw). * * This is a *Node-side* check (fs.statSync), not a shell `which`. On Linux/macOS we additionally require the executable bit to be * set; on Windows we accept anything that's a file or symlink since * executable-bit semantics are looser there. The plugin runs on * Linux/macOS in practice (verified by the user's report). */ export declare function findRoyAgentOnPath(pathEnv: string | undefined): string | undefined; export interface ResolveRoyAgentCliPathOptions { /** Path-style overrides (test seam). Falls back to `process.cwd()`. */ cwd?: string; /** Path-style overrides (test seam). Falls back to `process.env.PATH`. */ pathEnv?: string; /** Path-style overrides (test seam). Falls back to `process.env.ROY_AGENT_CLI`. */ royAgentCliEnv?: string; /** * Path-style overrides (test seam). Falls back to * `process.env.NODE_ENV`. When `"production"`, the hardcoded * dev paths are skipped entirely. */ nodeEnv?: string | undefined; } /** * Resolve the `roy-agent` executable used by the operations / * tasks-tree / chat pipelines. See the file-level JSDoc for the * full resolution algorithm. * * Pure function — accepts an `options` parameter so tests can inject * `cwd` / `pathEnv` / `royAgentCliEnv` / `nodeEnv` without mutating * `process.*`. Production callers omit the parameter and let it * default to the live `process` snapshot. */ export declare function resolveRoyAgentCliPath(override: string | undefined, options?: ResolveRoyAgentCliPathOptions): string; //# sourceMappingURL=cli-path-resolver.d.ts.map