/** * Command Invocation Seam (DESIGN.md ยง2). * * This Module defines the pure invocation contract that separates * command behaviour from process effects. `invokeCommand` owns * invocation-local presentation, notice storage, and error conversion. * The Node Adapter is the only Module that touches process streams, * TTY state, and `process.exitCode`. * * Requirements: NFR-002, NFR-003, NFR-007. */ import type { OutputMode } from "./lib/output.js"; export type TextOutputMode = "compact" | "markdown" | "refs" | "tty"; export type CommandPresentations = Readonly>>; export interface DataCommandResult { readonly kind: "data"; readonly data: T; readonly presentations?: CommandPresentations; readonly exitCode?: number; /** * Pre-projection (pre-`--fields`) rows for capabilities whose journal * skeleton must preserve url+title identities even when the user * projects away those fields in the command output. * * Only the search command populates this; every other command leaves * it absent (undefined is not `unknown`-assignable but it's optional). */ readonly rawRows?: readonly { url?: string; title?: string; }[]; } export interface TextCommandResult { readonly kind: "text"; readonly text: string; readonly exitCode?: number; } export type CommandResult = DataCommandResult | TextCommandResult; export interface CommandContext { readonly stdinIsTTY: boolean; readStdin(maxBytes?: number): Promise; notice(message: string): void; } export interface CommandInvocationAdapter { readonly stdoutIsTTY: boolean; readonly stdinIsTTY: boolean; readonly environmentOutputMode?: string; readStdin(maxBytes?: number): Promise; writeStdout(value: string): void; writeStderr(value: string): void; runQuietly(operation: () => Promise): Promise; setExitCode(value: number): void; } /** * Input handed to the optional save hook (save-artifacts T4). The seam * passes the successful CommandResult, the SAME resolved secrets the * output boundary redacts with, the invocation clock, and the notice * channel - a hook notice rides the existing stderr flush ahead of the * stdout write, so saving never reorders documented output. */ export interface SaveHookContext { readonly result: CommandResult; readonly resolvedSecrets: string[]; readonly now: () => number; readonly notice: (message: string) => void; } /** * Optional post-behavior save hook (save-artifacts T4). Present only for * a save-capable command run with --save; every existing call site omits * it and is byte-identical to the pre-T4 seam. A hook throw rides the * existing catch: notices flush, one error envelope, no stdout. */ export type SaveHook = (context: SaveHookContext) => Promise; /** * Run command behaviour through the invocation seam. * * 1. Create invocation-local context and notice storage. * 2. Run command behaviour through `runQuietly`. * 3. `runQuietly` restores dependency logging before returning. * 4. Flush notices to stderr in encounter order. * 5. Select a presentation override or the base data. * 6. Write one final successful value to stdout. * 7. Convert a thrown error into one structured stderr value. * 8. Return an exit status without terminating the process. * * The trailing newline is appended at the Node Adapter boundary, not * here, so `invokeCommand` itself is process-effect-free. */ export declare function invokeCommand(adapter: CommandInvocationAdapter, behavior: (context: CommandContext) => Promise, outputMode: OutputMode, now?: () => number, secrets?: string[], save?: SaveHook, journal?: SaveHook): Promise; //# sourceMappingURL=command-invocation.d.ts.map