@nanocollective/nanocoder
Version:
A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter
181 lines • 6.93 kB
TypeScript
import { EventEmitter } from 'node:events';
/**
* Result object returned after a CLI process completes execution.
*/
export interface CLITestResult {
/** Exit code of the process, or null if terminated by signal */
exitCode: number | null;
/** Signal that terminated the process, or null if exited normally */
signal: NodeJS.Signals | null;
/** Captured stdout output */
stdout: string;
/** Captured stderr output */
stderr: string;
/** Whether the process was killed due to timeout */
timedOut: boolean;
/** Duration in milliseconds from start to exit */
duration: number;
/** Whether the process was killed (by timeout, signal, or kill()) */
killed: boolean;
}
/**
* Options for configuring CLI test execution.
*/
export interface CLITestOptions {
/** Command-line arguments to pass to the CLI */
args?: string[];
/** Environment variables to set (can override defaults when placed after inheritEnv) */
env?: Record<string, string>;
/** Timeout in milliseconds before killing the process (default: 30000) */
timeout?: number;
/** Working directory for the process */
cwd?: string;
/** Data to write to stdin before closing it */
stdin?: string;
/** Whether to inherit parent process environment variables (default: true) */
inheritEnv?: boolean;
/** Send a signal to the process after a delay */
sendSignal?: {
signal: NodeJS.Signals;
delayMs: number;
};
/** Additional arguments to pass to Node.js */
nodeArgs?: string[];
}
/**
* Gets the path to the CLI entry point.
* Prefers the compiled dist/cli.js, falls back to source/cli.tsx.
* @returns Absolute path to the CLI entry point
* @throws Error if neither path exists
*/
export declare function getCLIPath(): string;
/**
* Checks if the CLI path requires tsx to execute (TypeScript source files).
* @param cliPath - Path to the CLI file
* @returns true if the file is .ts or .tsx
*/
export declare function needsTsx(cliPath: string): boolean;
/**
* A test harness for spawning and controlling CLI processes.
* Extends EventEmitter and emits 'stdout', 'stderr', 'exit', and 'signal-sent' events.
*
* @example
* ```typescript
* const harness = createCLITestHarness();
* const result = await harness.run({ args: ['run', 'hello world'] });
* assertExitCode(result, 0);
* ```
*/
export declare class CLITestHarness extends EventEmitter {
private process;
private startTime;
private result;
private stdoutChunks;
private stderrChunks;
private timeoutId;
private signalTimeoutId;
private _timedOut;
private stdoutListener;
private stderrListener;
/**
* Spawns the CLI process with the given options and waits for it to exit.
* @param options - Configuration options for the CLI execution
* @returns Promise that resolves with the test result
* @throws Error if called while a process is already running
*/
run(options?: CLITestOptions): Promise<CLITestResult>;
/**
* Sends a signal to the running process.
* @param signal - The signal to send (e.g., 'SIGINT', 'SIGTERM')
* @returns true if the signal was sent, false if no process is running
*/
sendSignal(signal: NodeJS.Signals): boolean;
/**
* Writes data to the process's stdin.
* @param data - The string data to write
* @returns true if data was written, false if no process or stdin is unavailable
*/
writeToStdin(data: string): boolean;
/**
* Closes the process's stdin stream.
* @returns true if stdin was closed, false if no process or stdin is unavailable
*/
closeStdin(): boolean;
/**
* Kills the running process with the specified signal.
* @param signal - The signal to use (default: 'SIGTERM')
* @returns true if the process was killed, false if no process is running
*/
kill(signal?: NodeJS.Signals): boolean;
/**
* Checks if a process is currently running.
* @returns true if a process is running and has not exited
*/
isRunning(): boolean;
/**
* Gets the current accumulated stdout output.
* @returns The stdout output collected so far
*/
getCurrentStdout(): string;
getCurrentStderr(): string;
/**
* Waits for output matching a pattern to appear in the process output.
* @param pattern - String or RegExp to match against output
* @param options - Options for timeout and which stream(s) to check
* @returns Promise that resolves with the matched string
* @throws Error if timeout is reached before pattern is found
*/
waitForOutput(pattern: RegExp | string, options?: {
timeout?: number;
stream?: 'stdout' | 'stderr' | 'both';
}): Promise<string>;
private cleanup;
private buildResult;
}
/**
* Creates a new CLITestHarness instance.
* @returns A new CLITestHarness ready to run tests
*/
export declare function createCLITestHarness(): CLITestHarness;
/**
* Asserts that the process exited with the expected exit code.
* @param result - The CLI test result to check
* @param expectedCode - The expected exit code
* @throws Error if the exit code doesn't match
*/
export declare function assertExitCode(result: CLITestResult, expectedCode: number): void;
/**
* Asserts that the process was terminated by the expected signal.
* @param result - The CLI test result to check
* @param expectedSignal - The expected termination signal
* @throws Error if the signal doesn't match
*/
export declare function assertSignal(result: CLITestResult, expectedSignal: NodeJS.Signals): void;
/**
* Asserts that the process timed out.
* @param result - The CLI test result to check
* @throws Error if the process did not time out
*/
export declare function assertTimedOut(result: CLITestResult): void;
/**
* Asserts that stdout contains the expected pattern.
* @param result - The CLI test result to check
* @param pattern - String or RegExp to match against stdout
* @throws Error if the pattern is not found in stdout
*/
export declare function assertStdoutContains(result: CLITestResult, pattern: string | RegExp): void;
/**
* Asserts that stderr contains the expected pattern.
* @param result - The CLI test result to check
* @param pattern - String or RegExp to match against stderr
* @throws Error if the pattern is not found in stderr
*/
export declare function assertStderrContains(result: CLITestResult, pattern: string | RegExp): void;
/**
* Asserts that the process completed within the specified time.
* @param result - The CLI test result to check
* @param maxDurationMs - Maximum allowed duration in milliseconds
* @throws Error if the process took longer than the specified time
*/
export declare function assertCompletedWithin(result: CLITestResult, maxDurationMs: number): void;
//# sourceMappingURL=cli-test-harness.d.ts.map