nexus-agents 2.26.0 → 2.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SM37N7GX.js → chunk-ARNVVQ5W.js} +8 -6
- package/dist/chunk-ARNVVQ5W.js.map +1 -0
- package/dist/{chunk-2FKBWTRT.js → chunk-BOWNZMPH.js} +259 -93
- package/dist/{chunk-2FKBWTRT.js.map → chunk-BOWNZMPH.js.map} +1 -1
- package/dist/{chunk-EBU4ZD7I.js → chunk-L3LQ3RP5.js} +945 -889
- package/dist/chunk-L3LQ3RP5.js.map +1 -0
- package/dist/{chunk-NO5JYJ4X.js → chunk-LCDOP543.js} +2 -2
- package/dist/{chunk-JWIQNGJQ.js → chunk-LCHCASB7.js} +2 -2
- package/dist/{chunk-6G4LDOMR.js → chunk-PGNRXCYY.js} +3 -3
- package/dist/{chunk-E2IN5SXP.js → chunk-UVQ7R4C4.js} +11 -9
- package/dist/chunk-UVQ7R4C4.js.map +1 -0
- package/dist/{chunk-KPVWS427.js → chunk-X33QNBGA.js} +3 -3
- package/dist/cli.js +12 -12
- package/dist/cli.js.map +1 -1
- package/dist/doctor-deep-I2J5CRFG.js +13 -0
- package/dist/index.d.ts +5 -19
- package/dist/index.js +26 -7
- package/dist/index.js.map +1 -1
- package/dist/{setup-command-HB3UVJKC.js → setup-command-VNF3KTCJ.js} +6 -6
- package/dist/setup-config-VQSWWJ5O.js +9 -0
- package/package.json +5 -5
- package/dist/chunk-E2IN5SXP.js.map +0 -1
- package/dist/chunk-EBU4ZD7I.js.map +0 -1
- package/dist/chunk-SM37N7GX.js.map +0 -1
- package/dist/doctor-deep-FJA7WOFV.js +0 -13
- package/dist/setup-config-PIUIJKF6.js +0 -9
- /package/dist/{chunk-NO5JYJ4X.js.map → chunk-LCDOP543.js.map} +0 -0
- /package/dist/{chunk-JWIQNGJQ.js.map → chunk-LCHCASB7.js.map} +0 -0
- /package/dist/{chunk-6G4LDOMR.js.map → chunk-PGNRXCYY.js.map} +0 -0
- /package/dist/{chunk-KPVWS427.js.map → chunk-X33QNBGA.js.map} +0 -0
- /package/dist/{doctor-deep-FJA7WOFV.js.map → doctor-deep-I2J5CRFG.js.map} +0 -0
- /package/dist/{setup-command-HB3UVJKC.js.map → setup-command-VNF3KTCJ.js.map} +0 -0
- /package/dist/{setup-config-PIUIJKF6.js.map → setup-config-VQSWWJ5O.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
CLI_TIMEOUTS,
|
|
5
5
|
CODEX_MCP_TIMEOUTS,
|
|
6
6
|
getCliTimeout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LCDOP543.js";
|
|
8
8
|
import {
|
|
9
9
|
CLI_VERSION_REQUIREMENTS,
|
|
10
10
|
DEFAULT_CAPABILITIES,
|
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
getRandomProvider,
|
|
23
23
|
getTimeProvider,
|
|
24
24
|
ok
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-BOWNZMPH.js";
|
|
26
26
|
|
|
27
27
|
// src/version.ts
|
|
28
|
-
var VERSION = true ? "2.26.
|
|
28
|
+
var VERSION = true ? "2.26.1" : "dev";
|
|
29
29
|
|
|
30
30
|
// src/utils/async-utils.ts
|
|
31
31
|
function sleep(ms) {
|
|
@@ -1728,7 +1728,8 @@ var CodexResponseParser = class {
|
|
|
1728
1728
|
const usage = this.extractUsageFromEvent(record);
|
|
1729
1729
|
if (usage !== null) setUsage(usage);
|
|
1730
1730
|
}
|
|
1731
|
-
} catch {
|
|
1731
|
+
} catch (lineErr) {
|
|
1732
|
+
void lineErr;
|
|
1732
1733
|
}
|
|
1733
1734
|
}
|
|
1734
1735
|
/**
|
|
@@ -2199,7 +2200,8 @@ var OpenCodeResponseParser = class {
|
|
|
2199
2200
|
this.emitLegacyUsage(record, setUsage);
|
|
2200
2201
|
break;
|
|
2201
2202
|
}
|
|
2202
|
-
} catch {
|
|
2203
|
+
} catch (lineErr) {
|
|
2204
|
+
void lineErr;
|
|
2203
2205
|
}
|
|
2204
2206
|
}
|
|
2205
2207
|
// --- Real v1.2.x format handlers ---
|
|
@@ -2844,4 +2846,4 @@ export {
|
|
|
2844
2846
|
startStdioServer,
|
|
2845
2847
|
closeServer
|
|
2846
2848
|
};
|
|
2847
|
-
//# sourceMappingURL=chunk-
|
|
2849
|
+
//# sourceMappingURL=chunk-ARNVVQ5W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/utils/async-utils.ts","../src/cli-adapters/cli-timeout-helpers.ts","../src/cli-adapters/cli-timeout-profiles.ts","../src/cli-adapters/base-adapter.ts","../src/cli-adapters/capacity-tracker.ts","../src/cli-adapters/subprocess-adapter.ts","../src/utils/type-coercion.ts","../src/cli-adapters/parsers/claude-parser.ts","../src/cli-adapters/adapters/claude-adapter.ts","../src/cli-adapters/parsers/gemini-parser-resilient-helpers.ts","../src/cli-adapters/parsers/gemini-parser-resilient.ts","../src/cli-adapters/circuit-breaker-types.ts","../src/cli-adapters/circuit-breaker.ts","../src/cli-adapters/adapters/gemini-adapter-helpers.ts","../src/cli-adapters/adapters/gemini-adapter.ts","../src/cli-adapters/parsers/codex-parser.ts","../src/cli-adapters/adapters/codex-adapter-helpers.ts","../src/cli-adapters/adapters/codex-adapter.ts","../src/cli-adapters/adapters/codex-mcp-adapter.ts","../src/cli-adapters/adapters/codex-mcp-adapter-helpers.ts","../src/cli-adapters/parsers/opencode-parser.ts","../src/cli-adapters/adapters/opencode-adapter.ts","../src/cli-adapters/cli-detection-cache.ts","../src/cli-adapters/factory.ts","../src/mcp/server.ts","../src/mcp/task-store.ts","../src/utils/text-utils.ts"],"sourcesContent":["/**\n * nexus-agents - Version constant\n *\n * Injected at build time via tsup define from package.json.\n * Do NOT edit this value manually — it is replaced during build.\n */\n\ndeclare const __NEXUS_VERSION__: string;\n\nexport const VERSION: string = typeof __NEXUS_VERSION__ !== 'undefined' ? __NEXUS_VERSION__ : 'dev';\n","import { getErrorMessage } from '../core/index.js';\n\n/**\n * Async Utilities\n *\n * Centralized async helper functions for delay, timeout, and promise utilities.\n * Consolidates 9+ duplicate sleep/delay implementations across the codebase.\n *\n * @module utils/async-utils\n * (Source: LOOP H-K consolidation)\n */\n\n// ============================================================================\n// Delay / Sleep\n// ============================================================================\n\n/**\n * Creates a promise that resolves after the specified delay.\n * Alias: `delay` (both names are exported for compatibility)\n *\n * @param ms - Delay in milliseconds\n * @returns Promise that resolves after the delay\n *\n * @example\n * ```typescript\n * await sleep(1000); // Wait 1 second\n * await delay(500); // Wait 500ms (alias)\n * ```\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Alias for `sleep()` - provided for compatibility with existing code.\n */\nexport const delay = sleep;\n\n// ============================================================================\n// Timeout Wrapper\n// ============================================================================\n\n/**\n * Result type for withTimeout operations.\n */\nexport type TimeoutResult<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: string };\n\n/**\n * Wraps a promise with a timeout.\n * Returns an error result if the timeout is exceeded.\n *\n * @param promise - The promise to wrap\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Error message if timeout is exceeded\n * @returns A result object with either the value or an error\n *\n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Request timed out after 5s'\n * );\n *\n * if (result.ok) {\n * console.log(result.value);\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage: string\n): Promise<TimeoutResult<T>> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n return { ok: true, value: result };\n } catch (error) {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n\n// ============================================================================\n// Promise Utilities\n// ============================================================================\n\n/**\n * Executes promises in sequence, one at a time.\n *\n * @param tasks - Array of functions that return promises\n * @returns Array of results in order\n *\n * @example\n * ```typescript\n * const results = await sequence([\n * () => fetch('/api/1'),\n * () => fetch('/api/2'),\n * ]);\n * ```\n */\nexport async function sequence<T>(tasks: ReadonlyArray<() => Promise<T>>): Promise<T[]> {\n const results: T[] = [];\n for (const task of tasks) {\n results.push(await task());\n }\n return results;\n}\n","/**\n * CLI Timeout Helpers\n *\n * Task complexity estimation for timeout selection.\n * Separated from timeout values (which live in config/timeouts.ts).\n *\n * @module cli-adapters/cli-timeout-helpers\n * (Source: Issue #984 — Centralize timeout configuration)\n */\n\nimport type { TaskComplexity } from '../config/timeouts.js';\n\n/**\n * Estimate task complexity from task description.\n *\n * Heuristics based on testing:\n * - Simple: Single function, quick query, < 5 files\n * - Standard: Multi-file changes, moderate analysis\n * - Complex: Codebase-wide, deep analysis, architecture\n *\n * @param taskDescription - Description of the task\n * @returns Estimated complexity\n */\nexport function estimateTaskComplexity(taskDescription: string): TaskComplexity {\n const lower = taskDescription.toLowerCase();\n\n // Complex indicators\n const complexIndicators = [\n 'codebase',\n 'architecture',\n 'refactor',\n 'all files',\n 'entire',\n 'comprehensive',\n 'deep analysis',\n 'system-wide',\n ];\n if (complexIndicators.some((indicator) => lower.includes(indicator))) {\n return 'complex';\n }\n\n // Simple indicators\n const simpleIndicators = ['single', 'quick', 'one function', 'simple', 'small', 'brief', 'short'];\n if (simpleIndicators.some((indicator) => lower.includes(indicator))) {\n return 'simple';\n }\n\n // Default to standard\n return 'standard';\n}\n","/**\n * CLI Timeout Profiles - Configurable timeouts per CLI tool.\n *\n * Delegates to `config/timeouts.ts` (canonical source, Issue #984).\n * This file provides backward-compatible re-exports.\n *\n * @module cli-adapters/cli-timeout-profiles\n * (Source: Issue #357, CLI delegation testing 2026-01-18)\n */\n\nimport {\n CLI_TIMEOUTS,\n getCliTimeout,\n type TaskComplexity,\n type TimeoutProfile,\n} from '../config/timeouts.js';\nimport { estimateTaskComplexity as _estimateTaskComplexity } from './cli-timeout-helpers.js';\n\n// Re-export types for backward compatibility\nexport type { TimeoutProfile, TaskComplexity };\n\n/** Per-CLI timeout profiles. Canonical source: `config/timeouts.ts`. */\nexport const CLI_TIMEOUT_PROFILES: Record<string, TimeoutProfile> = {\n claude: CLI_TIMEOUTS.claude,\n gemini: CLI_TIMEOUTS.gemini,\n codex: CLI_TIMEOUTS.codex,\n};\n\n/** Default timeout profile. Canonical source: `config/timeouts.ts`. */\nexport const DEFAULT_TIMEOUT_PROFILE: TimeoutProfile = CLI_TIMEOUTS.default;\n\n/** Get timeout for a task. Canonical source: `config/timeouts.ts`. */\nexport function getTimeoutForTask(cli: string, complexity: TaskComplexity): number {\n return getCliTimeout(cli, complexity);\n}\n\n/** Estimate task complexity from description. Canonical: `cli-timeout-helpers.ts`. */\nexport function estimateTaskComplexity(taskDescription: string): TaskComplexity {\n return _estimateTaskComplexity(taskDescription);\n}\n\n/** Get timeout with automatic complexity estimation. */\nexport function getTimeoutForTaskAuto(cli: string, taskDescription: string): number {\n const complexity = _estimateTaskComplexity(taskDescription);\n return getCliTimeout(cli, complexity);\n}\n","/**\n * nexus-agents/cli-adapters - Base Adapter\n *\n * Abstract base class for CLI adapters with common functionality.\n * Provides version checking, health checks, and error handling.\n *\n * SubprocessCliAdapter extracted to subprocess-adapter.ts per Issue #272.\n *\n * (Source: cli-project_plan.md v2.1.0)\n */\n\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport semver from 'semver';\nimport { CLI_SUBPROCESS_TIMEOUTS, BACKOFF_CONFIG } from '../config/timeouts.js';\n\nimport type { Result } from '../core/index.js';\nimport { err, getTimeProvider } from '../core/index.js';\nimport type { ILogger } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\n\nimport type {\n ICliAdapter,\n CliName,\n CliTransport,\n CliTask,\n CliResponse,\n CliError,\n CliErrorCode,\n HealthStatus,\n CapacityStatus,\n ModelInfo,\n CapabilityProfile,\n ExecutionOptions,\n VersionStatus,\n TokenUsage,\n} from './types.js';\nimport { CLI_VERSION_REQUIREMENTS, DEFAULT_CAPABILITIES } from './types.js';\nimport { getTimeoutForTaskAuto } from './cli-timeout-profiles.js';\nimport { CapacityTracker, createCapacityTracker } from './capacity-tracker.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Default execution options.\n *\n * Timeout reduced from 120s to 60s per Issue #280 to prevent\n * cascading timeouts in multi-agent voting scenarios.\n */\nconst DEFAULT_OPTIONS: Required<ExecutionOptions> = {\n timeoutMs: 60_000, // 1 minute (reduced from 2 minutes per Issue #280)\n allowRetry: true,\n maxRetries: 1, // Reduced from 2 to prevent 3+ minute total wait\n trackUsage: true,\n onProgress: undefined,\n};\n\n/**\n * Abstract base class for CLI adapters.\n * Provides common functionality for version checking, health, and error handling.\n */\nexport abstract class BaseCliAdapter implements ICliAdapter {\n abstract readonly name: CliName;\n abstract readonly transport: CliTransport;\n\n protected readonly logger: ILogger;\n protected capacityTracker: CapacityTracker | null = null;\n protected initialized = false;\n protected lastHealthCheck?: HealthStatus;\n protected cachedVersion?: string;\n\n constructor(logger?: ILogger) {\n this.logger = logger ?? createLogger({ component: 'cli-adapter' });\n }\n\n /**\n * Initializes the capacity tracker.\n * Called by subclasses after name is set.\n */\n protected initCapacityTracker(): void {\n this.capacityTracker = createCapacityTracker(this.name);\n }\n\n /**\n * Gets the capability profile for this CLI.\n */\n get capabilities(): CapabilityProfile {\n return DEFAULT_CAPABILITIES[this.name];\n }\n\n /**\n * Abstract method for executing a task.\n * Implemented by concrete adapters.\n */\n abstract executeTask(\n task: CliTask,\n options: Required<ExecutionOptions>\n ): Promise<Result<CliResponse, CliError>>;\n\n /**\n * Abstract method for getting model info.\n * Implemented by concrete adapters.\n */\n abstract getModelInfo(): ModelInfo;\n\n /**\n * Abstract method for initialization.\n * Implemented by concrete adapters.\n */\n abstract initialize(): Promise<void>;\n\n /**\n * Abstract method for cleanup.\n * Implemented by concrete adapters.\n */\n abstract dispose(): Promise<void>;\n\n /**\n * Executes a task with error handling and retries.\n *\n * Timeout priority (highest to lowest):\n * 1. options.timeoutMs - explicit execution option\n * 2. task.timeoutMs - task-level setting\n * 3. getTimeoutForTaskAuto() - computed from task complexity and CLI\n */\n async execute(task: CliTask, options?: ExecutionOptions): Promise<Result<CliResponse, CliError>> {\n const effectiveTimeout = this.computeTimeout(task, options);\n const opts = { ...DEFAULT_OPTIONS, ...options, timeoutMs: effectiveTimeout };\n\n if (!this.initialized) {\n await this.initialize();\n }\n\n this.logger.debug('Executing task', {\n cli: this.name,\n contentLength: task.content.length,\n model: task.model,\n timeoutMs: effectiveTimeout,\n });\n\n return this.executeWithRetry(task, opts);\n }\n\n /**\n * Computes effective timeout for a task.\n */\n private computeTimeout(task: CliTask, options?: ExecutionOptions): number {\n if (options?.timeoutMs !== undefined) return options.timeoutMs;\n if (task.timeoutMs !== undefined) return task.timeoutMs;\n return getTimeoutForTaskAuto(this.name, task.content);\n }\n\n /**\n * Executes task with retry logic.\n */\n private async executeWithRetry(\n task: CliTask,\n opts: Required<ExecutionOptions>\n ): Promise<Result<CliResponse, CliError>> {\n let lastError: CliError | undefined;\n const maxAttempts = opts.allowRetry ? opts.maxRetries + 1 : 1;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const result = await this.executeTask(task, opts);\n\n if (result.ok) {\n this.recordUsage(result.value);\n this.logger.info('Task executed successfully', {\n cli: this.name,\n attempt,\n durationMs: result.value.durationMs,\n tokensUsed: result.value.usage?.totalTokens,\n });\n return result;\n }\n\n lastError = result.error;\n\n if (this.isTerminalAttempt(result.error, attempt, maxAttempts)) {\n this.logger.warn('Task execution failed', {\n cli: this.name,\n attempt,\n error: result.error.message,\n retryable: result.error.retryable,\n });\n return result;\n }\n\n this.logger.debug('Retrying task execution', {\n cli: this.name,\n attempt,\n nextAttempt: attempt + 1,\n });\n\n await this.delay(Math.pow(BACKOFF_CONFIG.exponentBase, attempt) * BACKOFF_CONFIG.baseDelayMs);\n }\n\n return err(lastError ?? this.createError('UNKNOWN', 'Unknown error'));\n }\n\n /**\n * Checks if this attempt should be the final one.\n */\n private isTerminalAttempt(error: CliError, attempt: number, maxAttempts: number): boolean {\n return !error.retryable || attempt === maxAttempts;\n }\n\n /**\n * Performs a health check.\n */\n async healthCheck(): Promise<HealthStatus> {\n try {\n const version = await this.getVersion();\n const versionStatus = this.checkVersionCompatibility(version);\n\n const message = this.getVersionMessage(versionStatus, version);\n const status: HealthStatus = {\n healthy: versionStatus !== 'unsupported' && versionStatus !== 'breaking',\n version,\n versionStatus,\n lastChecked: new Date(getTimeProvider().now()),\n ...(message !== undefined && { message }),\n };\n\n this.lastHealthCheck = status;\n return status;\n } catch (error) {\n return {\n healthy: false,\n version: 'unknown',\n versionStatus: 'unsupported',\n message: error instanceof Error ? error.message : 'Health check failed',\n lastChecked: new Date(getTimeProvider().now()),\n };\n }\n }\n\n /**\n * Gets CLI version.\n */\n async getVersion(): Promise<string> {\n if (this.cachedVersion !== undefined && this.cachedVersion !== '') {\n return this.cachedVersion;\n }\n\n try {\n const { stdout } = await execAsync(`${this.name} --version`, {\n timeout: CLI_SUBPROCESS_TIMEOUTS.spawnMs,\n });\n\n // Extract version number from output\n const version = this.parseVersion(stdout.trim());\n this.cachedVersion = version;\n return version;\n } catch (cause: unknown) {\n throw new Error(`Failed to get ${this.name} version`, { cause });\n }\n }\n\n /**\n * Gets current capacity status based on tracked usage.\n * Uses usage-based tracking since CLI subprocess execution\n * doesn't expose HTTP rate limit headers.\n *\n * @see Issue #456 - Real API rate limit tracking\n */\n getCapacity(): Promise<CapacityStatus> {\n if (this.capacityTracker === null) {\n // Fallback for uninitialized tracker\n return Promise.resolve({\n remainingTokens: Number.MAX_SAFE_INTEGER,\n remainingRequests: Number.MAX_SAFE_INTEGER,\n resetTime: new Date(getTimeProvider().now() + 3600_000),\n utilizationPercent: 0,\n exhausted: false,\n });\n }\n return Promise.resolve(this.capacityTracker.getCapacity());\n }\n\n /**\n * Records usage from a response for capacity tracking.\n */\n protected recordUsage(response: CliResponse): void {\n if (this.capacityTracker !== null) {\n this.capacityTracker.recordUsage(response.usage);\n }\n }\n\n /**\n * Parses version from CLI output.\n */\n protected parseVersion(output: string): string {\n // Handle common version formats:\n // \"2.0.76 (Claude Code)\"\n // \"0.22.5\"\n // \"codex-cli 0.77.0\"\n const match = /(\\d+\\.\\d+\\.\\d+)/.exec(output);\n return match?.[1] ?? '0.0.0';\n }\n\n /**\n * Checks version compatibility.\n */\n protected checkVersionCompatibility(version: string): VersionStatus {\n const requirements = CLI_VERSION_REQUIREMENTS[this.name];\n\n const validVersion = semver.valid(version);\n if (validVersion === null) {\n return 'unsupported';\n }\n\n const isLtMinimum = semver.lt(validVersion, requirements.minimum);\n if (isLtMinimum) {\n return 'unsupported';\n }\n\n const hasBreaking = requirements.breaking.some((v) => semver.gte(validVersion, v));\n if (hasBreaking) {\n return 'breaking';\n }\n\n const isLtRecommended = semver.lt(validVersion, requirements.recommended);\n if (isLtRecommended) {\n return 'outdated';\n }\n\n return 'supported';\n }\n\n /**\n * Gets version status message.\n */\n protected getVersionMessage(status: VersionStatus, version: string): string | undefined {\n const requirements = CLI_VERSION_REQUIREMENTS[this.name];\n\n switch (status) {\n case 'unsupported':\n return `Version ${version} is not supported. Minimum: ${requirements.minimum}`;\n case 'breaking':\n return `Version ${version} has known compatibility issues`;\n case 'outdated':\n return `Consider upgrading to ${requirements.recommended}`;\n case 'supported':\n return undefined;\n }\n }\n\n /**\n * Creates a CLI error.\n */\n protected createError(code: CliErrorCode, message: string, cause?: Error): CliError {\n const retryable = ['RATE_LIMITED', 'TIMEOUT', 'CONNECTION_ERROR'].includes(code);\n\n return {\n code,\n message,\n cli: this.name,\n retryable,\n ...(cause !== undefined && { cause }),\n };\n }\n\n /**\n * Normalizes CLI response to common format.\n */\n protected normalizeResponse(\n text: string,\n usage?: TokenUsage,\n extra?: Partial<CliResponse>\n ): CliResponse {\n return {\n text,\n ...(usage !== undefined && { usage }),\n ...extra,\n };\n }\n\n /**\n * Delays for the specified milliseconds.\n */\n protected delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * nexus-agents/cli-adapters - Capacity Tracker\n *\n * Usage-based capacity tracking for CLI adapters.\n * Tracks cumulative token/request usage to estimate remaining capacity.\n *\n * Since CLI subprocess execution doesn't expose HTTP rate limit headers,\n * this tracker estimates capacity based on usage patterns.\n *\n * @see Issue #456 - Real API rate limit tracking\n */\n\nimport type { CliName, TokenUsage, CapacityStatus } from './types-core.js';\nimport { getTimeProvider } from '../core/index.js';\nimport { clampPercent } from '../utils/math-utils.js';\n\n/**\n * Default rate limits per CLI provider (tokens per minute).\n * These are conservative estimates based on typical API tiers.\n * Override via environment variables: NEXUS_<CLI>_TOKEN_LIMIT\n */\nexport const DEFAULT_TOKEN_LIMITS: Record<CliName, number> = {\n claude: 100_000, // Claude API Build tier\n gemini: 1_000_000, // Gemini Pro generous limits\n codex: 500_000, // OpenAI tier 1\n opencode: 500_000, // Multi-provider proxy\n};\n\n/**\n * Default request limits per CLI provider (requests per minute).\n * Override via environment variables: NEXUS_<CLI>_REQUEST_LIMIT\n */\nexport const DEFAULT_REQUEST_LIMITS: Record<CliName, number> = {\n claude: 50, // Claude API Build tier\n gemini: 60, // Gemini Pro\n codex: 500, // OpenAI tier 1\n opencode: 300, // Multi-provider proxy\n};\n\n/**\n * Rate limit window in milliseconds (1 minute).\n */\nexport const RATE_LIMIT_WINDOW_MS = 60_000;\n\n/**\n * Configuration for capacity tracker.\n */\nexport interface CapacityTrackerConfig {\n /** Maximum tokens per window */\n readonly tokenLimit: number;\n /** Maximum requests per window */\n readonly requestLimit: number;\n /** Window duration in milliseconds */\n readonly windowMs: number;\n}\n\n/**\n * Tracked usage entry with timestamp.\n */\ninterface UsageEntry {\n readonly timestamp: number;\n readonly tokens: number;\n}\n\n/**\n * Creates default configuration for a CLI from environment or defaults.\n */\nexport function getDefaultConfig(cli: CliName): CapacityTrackerConfig {\n const envPrefix = `NEXUS_${cli.toUpperCase()}`;\n const tokenEnv = process.env[`${envPrefix}_TOKEN_LIMIT`];\n const requestEnv = process.env[`${envPrefix}_REQUEST_LIMIT`];\n\n return {\n tokenLimit:\n tokenEnv !== undefined && tokenEnv !== ''\n ? parseInt(tokenEnv, 10)\n : DEFAULT_TOKEN_LIMITS[cli],\n requestLimit:\n requestEnv !== undefined && requestEnv !== ''\n ? parseInt(requestEnv, 10)\n : DEFAULT_REQUEST_LIMITS[cli],\n windowMs: RATE_LIMIT_WINDOW_MS,\n };\n}\n\n/**\n * Capacity tracker for CLI adapters.\n *\n * Tracks cumulative usage within a sliding window to estimate\n * remaining capacity when HTTP headers are not available.\n *\n * @example\n * ```typescript\n * const tracker = new CapacityTracker(getDefaultConfig('claude'));\n *\n * // Record usage after each request\n * tracker.recordUsage({ inputTokens: 1000, outputTokens: 500 });\n *\n * // Get current capacity status\n * const status = tracker.getCapacity();\n * if (status.exhausted) {\n * // Wait before next request\n * }\n * ```\n */\nexport class CapacityTracker {\n private readonly config: CapacityTrackerConfig;\n private readonly usageHistory: UsageEntry[];\n private requestCount: number;\n private windowStart: number;\n\n constructor(config: CapacityTrackerConfig) {\n this.config = config;\n this.usageHistory = [];\n this.requestCount = 0;\n this.windowStart = getTimeProvider().now();\n }\n\n /**\n * Records token usage from a completed request.\n */\n recordUsage(usage: TokenUsage | undefined): void {\n const now = getTimeProvider().now();\n this.pruneOldEntries(now);\n\n this.requestCount++;\n\n if (usage !== undefined) {\n const tokens = usage.totalTokens ?? usage.inputTokens + usage.outputTokens;\n this.usageHistory.push({\n timestamp: now,\n tokens,\n });\n }\n }\n\n /**\n * Gets current capacity status based on tracked usage.\n */\n getCapacity(): CapacityStatus {\n const now = getTimeProvider().now();\n this.pruneOldEntries(now);\n\n const usedTokens = this.usageHistory.reduce((sum, entry) => sum + entry.tokens, 0);\n const remainingTokens = Math.max(0, this.config.tokenLimit - usedTokens);\n const remainingRequests = Math.max(0, this.config.requestLimit - this.requestCount);\n\n const tokenUtilization = (usedTokens / this.config.tokenLimit) * 100;\n const requestUtilization = (this.requestCount / this.config.requestLimit) * 100;\n const utilizationPercent = clampPercent(Math.max(tokenUtilization, requestUtilization));\n\n const exhausted = remainingTokens === 0 || remainingRequests === 0;\n const resetTime = new Date(this.windowStart + this.config.windowMs);\n\n return {\n remainingTokens,\n remainingRequests,\n resetTime,\n utilizationPercent: Math.round(utilizationPercent * 100) / 100,\n exhausted,\n };\n }\n\n /**\n * Gets time until the rate limit window resets.\n */\n getTimeUntilReset(): number {\n const now = getTimeProvider().now();\n const resetTime = this.windowStart + this.config.windowMs;\n return Math.max(0, resetTime - now);\n }\n\n /**\n * Resets all tracked usage (for testing or manual reset).\n */\n reset(): void {\n this.usageHistory.length = 0;\n this.requestCount = 0;\n this.windowStart = getTimeProvider().now();\n }\n\n /**\n * Updates configuration (e.g., after receiving actual rate limit info).\n */\n updateConfig(partial: Partial<CapacityTrackerConfig>): void {\n Object.assign(this.config, partial);\n }\n\n /**\n * Gets current configuration.\n */\n getConfig(): Readonly<CapacityTrackerConfig> {\n return { ...this.config };\n }\n\n /**\n * Removes entries older than the window duration.\n */\n private pruneOldEntries(now: number): void {\n const cutoff = now - this.config.windowMs;\n\n // If window has fully elapsed, reset everything\n if (this.windowStart < cutoff) {\n this.usageHistory.length = 0;\n this.requestCount = 0;\n this.windowStart = now;\n return;\n }\n\n // Remove old entries from history\n let firstEntry = this.usageHistory[0];\n while (firstEntry !== undefined && firstEntry.timestamp < cutoff) {\n this.usageHistory.shift();\n firstEntry = this.usageHistory[0];\n }\n }\n}\n\n/**\n * Creates a capacity tracker for a specific CLI.\n */\nexport function createCapacityTracker(cli: CliName): CapacityTracker {\n return new CapacityTracker(getDefaultConfig(cli));\n}\n","/**\n * nexus-agents/cli-adapters - Subprocess Adapter\n *\n * Base class for subprocess-based CLI adapters.\n * Used by ClaudeCliAdapter and GeminiCliAdapter.\n *\n * Extracted from base-adapter.ts per Issue #272 (file size limits).\n */\n\nimport { spawn } from 'node:child_process';\n\nimport type { Result } from '../core/index.js';\nimport { ok, err, getTimeProvider } from '../core/index.js';\n\nimport type {\n CliTransport,\n CliTask,\n CliResponse,\n CliError,\n ExecutionOptions,\n ICliResponseParser,\n} from './types.js';\nimport { BaseCliAdapter } from './base-adapter.js';\n\n/** Rate-limit indicator patterns in CLI stdout (case-insensitive). */\nconst RATE_LIMIT_PATTERNS = [\n 'rate limit',\n '429',\n 'too many requests',\n 'quota exceeded',\n 'usage limit',\n];\n\n/** Checks if raw stdout contains rate-limit indicators (#1320). */\nfunction isRateLimitOutput(stdout: string): boolean {\n const lower = stdout.toLowerCase();\n return RATE_LIMIT_PATTERNS.some((pattern) => lower.includes(pattern));\n}\n\n/**\n * Command configuration returned by getCommand.\n */\nexport interface CommandConfig {\n command: string;\n args: string[];\n /** Optional stdin content (prompt passed via stdin instead of args) */\n stdin?: string;\n}\n\n/**\n * Base class for subprocess-based CLI adapters.\n * Used by ClaudeCliAdapter and GeminiCliAdapter.\n */\nexport abstract class SubprocessCliAdapter extends BaseCliAdapter {\n readonly transport: CliTransport = 'subprocess';\n\n protected abstract readonly parser: ICliResponseParser;\n\n /**\n * Gets CLI command and arguments for execution.\n * If stdin is provided, it will be written to the process stdin.\n */\n protected abstract getCommand(task: CliTask): CommandConfig;\n\n /**\n * Executes a task via subprocess using spawn for proper argument handling.\n * Using spawn avoids shell escaping issues with multi-line content.\n * If stdin is provided in command config, it is written to process stdin.\n */\n async executeTask(\n task: CliTask,\n options: Required<ExecutionOptions>\n ): Promise<Result<CliResponse, CliError>> {\n const cmdConfig = this.getCommand(task);\n const startTime = getTimeProvider().now();\n\n return new Promise((resolve) => {\n const child = spawn(cmdConfig.command, cmdConfig.args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n const onProgress = options.onProgress;\n const state = this.setupChildProcessHandlers(\n child,\n startTime,\n options.timeoutMs,\n resolve,\n onProgress\n );\n\n // Write stdin content if provided and close stdin\n if (cmdConfig.stdin !== undefined) {\n child.stdin.write(cmdConfig.stdin);\n }\n child.stdin.end();\n\n // Reference state to prevent unused variable warning\n void state;\n });\n }\n\n /**\n * Sets up child process event handlers for output collection and error handling.\n */\n private setupChildProcessHandlers(\n child: ReturnType<typeof spawn>,\n startTime: number,\n timeoutMs: number,\n resolve: (result: Result<CliResponse, CliError>) => void,\n onProgress?: () => void\n ): { stdout: string; stderr: string; resolved: boolean } {\n const state = { stdout: '', stderr: '', resolved: false };\n\n const resolveOnce = (result: Result<CliResponse, CliError>): void => {\n if (!state.resolved) {\n state.resolved = true;\n resolve(result);\n }\n };\n\n // stdio: ['pipe', 'pipe', 'pipe'] guarantees non-null streams\n if (child.stdout !== null) {\n child.stdout.on('data', (data: Buffer) => {\n state.stdout += data.toString();\n onProgress?.();\n });\n }\n if (child.stderr !== null) {\n child.stderr.on('data', (data: Buffer) => {\n state.stderr += data.toString();\n });\n }\n\n child.on('error', (error: Error) => {\n resolveOnce(this.handleSubprocessError(error));\n });\n\n child.on('close', (code: number | null) => {\n if (code !== 0 && state.stdout === '') {\n const msg = state.stderr !== '' ? state.stderr : `Process exited with code ${String(code)}`;\n resolveOnce(err(this.createError('EXECUTION_ERROR', msg)));\n return;\n }\n resolveOnce(this.handleSubprocessOutput(state.stdout, state.stderr, startTime));\n });\n\n const timeoutId = setTimeout(() => {\n child.kill('SIGTERM');\n resolveOnce(err(this.createError('TIMEOUT', 'Execution timed out')));\n }, timeoutMs);\n\n child.on('close', () => {\n clearTimeout(timeoutId);\n });\n\n return state;\n }\n\n /**\n * Handles successful subprocess output.\n */\n private handleSubprocessOutput(\n stdout: string,\n stderr: string,\n startTime: number\n ): Result<CliResponse, CliError> {\n if (stderr !== '' && stdout === '') {\n return err(this.createError('EXECUTION_ERROR', stderr));\n }\n\n const text = this.parser.extractResponse(stdout);\n if (text === null) {\n // Check for rate-limit indicators in raw stdout (#1320)\n if (isRateLimitOutput(stdout)) {\n const snippet = stdout.slice(0, 200).trim();\n return err(this.createError('RATE_LIMITED', snippet));\n }\n const snippet = stdout.slice(0, 200).trim();\n return err(this.createError('PARSE_ERROR', `Failed to parse response: ${snippet}`));\n }\n\n const usage = this.parser.extractUsage(stdout);\n const sessionId = this.parser.extractSessionId(stdout);\n\n return ok(\n this.normalizeResponse(text, usage ?? undefined, {\n durationMs: getTimeProvider().now() - startTime,\n raw: stdout,\n ...(sessionId !== null && { sessionId }),\n })\n );\n }\n\n /**\n * Handles subprocess execution errors.\n */\n private handleSubprocessError(error: unknown): Result<CliResponse, CliError> {\n if (!(error instanceof Error)) {\n return err(this.createError('EXECUTION_ERROR', 'Unknown error'));\n }\n\n if (error.message.includes('ETIMEDOUT') || error.message.includes('timeout')) {\n return err(this.createError('TIMEOUT', 'Execution timed out', error));\n }\n\n if (error.message.includes('ENOENT')) {\n return err(this.createError('NOT_FOUND', `${this.name} CLI not found`, error));\n }\n\n return err(this.createError('EXECUTION_ERROR', error.message, error));\n }\n\n /**\n * Initializes the adapter and capacity tracker.\n */\n initialize(): Promise<void> {\n this.initCapacityTracker();\n this.initialized = true;\n return Promise.resolve();\n }\n\n /**\n * Disposes the adapter (no-op for subprocess).\n */\n dispose(): Promise<void> {\n this.initialized = false;\n return Promise.resolve();\n }\n}\n","/**\n * nexus-agents/utils - Type Coercion Utilities\n *\n * Safe type coercion helpers for parsing and validating unknown values.\n * Consolidates patterns used across parsers, validators, and adapters.\n *\n * @module utils/type-coercion\n */\n\n/**\n * Safely casts value to Record if it's a non-null, non-array object.\n *\n * @param value - Value to check\n * @returns Record if valid object, null otherwise\n *\n * @example\n * const data = asRecord(parsed);\n * if (data !== null) {\n * const name = asString(data.name);\n * }\n */\nexport function asRecord(value: unknown): Record<string, unknown> | null {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return null;\n}\n\n/**\n * Type guard version of asRecord for use in conditionals.\n *\n * @param value - Value to check\n * @returns True if value is a non-null, non-array object\n *\n * @example\n * if (isRecord(data)) {\n * console.log(data.field);\n * }\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Safely extracts a string value.\n *\n * @param value - Value to check\n * @returns String if valid, null otherwise\n */\nexport function asString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * Safely extracts a number value.\n *\n * @param value - Value to check\n * @returns Number if valid (not NaN, not Infinity), null otherwise\n */\nexport function asNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n return null;\n}\n\n/**\n * Safely extracts a boolean value.\n *\n * @param value - Value to check\n * @returns Boolean if valid, null otherwise\n */\nexport function asBoolean(value: unknown): boolean | null {\n return typeof value === 'boolean' ? value : null;\n}\n\n/**\n * Safely extracts an array value.\n *\n * @param value - Value to check\n * @returns Array if valid, null otherwise\n */\nexport function asArray(value: unknown): unknown[] | null {\n return Array.isArray(value) ? value : null;\n}\n\n/**\n * Extracts a string field from a record.\n *\n * @param record - Record to extract from\n * @param key - Field key\n * @returns String value or undefined if not found/invalid\n */\nexport function extractStringField(\n record: Record<string, unknown>,\n key: string\n): string | undefined {\n const value = record[key];\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Extracts a number field from a record.\n *\n * @param record - Record to extract from\n * @param key - Field key\n * @returns Number value or null if not found/invalid\n */\nexport function extractNumberField(record: Record<string, unknown>, key: string): number | null {\n const value = record[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\n/**\n * Extracts a boolean field from a record.\n *\n * @param record - Record to extract from\n * @param key - Field key\n * @returns Boolean value or undefined if not found/invalid\n */\nexport function extractBooleanField(\n record: Record<string, unknown>,\n key: string\n): boolean | undefined {\n const value = record[key];\n return typeof value === 'boolean' ? value : undefined;\n}\n\n/**\n * Extracts a nested record field from a record.\n *\n * @param record - Record to extract from\n * @param key - Field key\n * @returns Nested record or null if not found/invalid\n */\nexport function extractRecordField(\n record: Record<string, unknown>,\n key: string\n): Record<string, unknown> | null {\n return asRecord(record[key]);\n}\n\n/**\n * Safely parses JSON with fallback to null.\n *\n * @param raw - Raw JSON string\n * @returns Parsed value or null if invalid\n */\nexport function safeJsonParse(raw: string): unknown {\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\n/**\n * Safely parses JSON and returns as Record.\n *\n * @param raw - Raw JSON string\n * @returns Parsed record or null if invalid\n */\nexport function safeJsonParseRecord(raw: string): Record<string, unknown> | null {\n const parsed = safeJsonParse(raw);\n return asRecord(parsed);\n}\n","/**\n * nexus-agents/cli-adapters - Claude CLI Response Parser\n *\n * Defensive parser for Claude CLI JSON output.\n * Handles version 2.0.x output format.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: docs/research/cli-integration-architecture.md)\n */\n\nimport type { ICliResponseParser, TokenUsage } from '../types.js';\nimport { asRecord, extractNumberField } from '../../utils/type-coercion.js';\n\n/**\n * Claude CLI response structure.\n * (Source: CLI testing 2026-01-04)\n */\nexport interface ClaudeCliResponse {\n readonly type: 'result';\n readonly subtype?: 'success' | 'error';\n readonly is_error: boolean;\n readonly duration_ms?: number;\n readonly result: string;\n readonly session_id?: string;\n readonly total_cost_usd?: number;\n readonly usage?: {\n readonly input_tokens: number;\n readonly output_tokens: number;\n readonly cache_creation_input_tokens?: number;\n readonly cache_read_input_tokens?: number;\n };\n readonly modelUsage?: Record<\n string,\n {\n readonly inputTokens: number;\n readonly outputTokens: number;\n readonly cacheReadInputTokens?: number;\n readonly cacheCreationInputTokens?: number;\n readonly costUSD?: number;\n readonly contextWindow?: number;\n }\n >;\n}\n\n/**\n * Parser for Claude CLI JSON output.\n * Implements defensive parsing - only requires essential fields.\n */\nexport class ClaudeResponseParser implements ICliResponseParser<ClaudeCliResponse> {\n readonly name = 'claude-parser';\n readonly supportedVersionRange = '>=2.0.0 <3.0.0';\n\n /**\n * Parses complete Claude CLI response.\n */\n parse(raw: string): ClaudeCliResponse | null {\n try {\n const data: unknown = JSON.parse(raw);\n\n if (!this.isValidResponse(data)) {\n return null;\n }\n\n return data;\n } catch {\n return null;\n }\n }\n\n /**\n * Extracts just the response text (most stable field).\n * Returns null if the response contains an error.\n */\n extractResponse(raw: string): string | null {\n try {\n const data: unknown = JSON.parse(raw);\n const record = asRecord(data);\n if (record === null) return null;\n\n // Check for API errors (is_error: true indicates an error occurred)\n if (record.is_error === true) {\n return null;\n }\n\n const result = record.result;\n if (typeof result === 'string') {\n return result;\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Extracts token usage from response.\n */\n extractUsage(raw: string): TokenUsage | null {\n try {\n const data: unknown = JSON.parse(raw);\n const record = asRecord(data);\n if (record === null) return null;\n\n const usageRecord = asRecord(record.usage);\n if (usageRecord === null) return null;\n\n const inputTokens = extractNumberField(usageRecord, 'input_tokens');\n const outputTokens = extractNumberField(usageRecord, 'output_tokens');\n\n if (inputTokens === null || outputTokens === null) {\n return null;\n }\n\n const cachedInputTokens = extractNumberField(usageRecord, 'cache_read_input_tokens');\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n ...(cachedInputTokens !== null && { cachedInputTokens }),\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Extracts session ID for resumption.\n */\n extractSessionId(raw: string): string | null {\n try {\n const data: unknown = JSON.parse(raw);\n const record = asRecord(data);\n if (record === null) return null;\n\n const sessionId = record.session_id;\n if (typeof sessionId === 'string') {\n return sessionId;\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Type guard for valid response structure.\n */\n private isValidResponse(data: unknown): data is ClaudeCliResponse {\n const record = asRecord(data);\n if (record === null) return false;\n\n // Only require the essential field\n return typeof record.result === 'string';\n }\n}\n","/**\n * nexus-agents/cli-adapters - Claude CLI Adapter\n *\n * Subprocess-based adapter for Claude CLI.\n * Uses JSON output format for stable parsing.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: docs/research/cli-integration-architecture.md)\n */\n\nimport type {\n ICliResponseParser,\n CliTask,\n ModelInfo,\n CliName,\n BaseAdapterOptions,\n} from '../types.js';\nimport { SubprocessCliAdapter, type CommandConfig } from '../subprocess-adapter.js';\nimport { ClaudeResponseParser } from '../parsers/claude-parser.js';\nimport { DEFAULT_MODEL_CAPABILITIES } from '../../config/model-capabilities.js';\nimport {\n getDefaultModelForCli,\n getCliModelName,\n buildModelInfo,\n} from '../../config/model-config-helpers.js';\n\n/**\n * Maps internal model names to Claude CLI aliases.\n * CLI accepts: 'sonnet', 'opus', 'haiku' or full names like 'claude-sonnet-4-5-20250929'\n * Built from canonical registry + legacy names for backward compatibility.\n */\nconst MODEL_TO_CLI_ALIAS: Record<string, string> = buildClaudeAliasMap();\n\n/** Builds alias map from canonical registry + legacy versioned names. */\nfunction buildClaudeAliasMap(): Record<string, string> {\n const map: Record<string, string> = {};\n for (const model of DEFAULT_MODEL_CAPABILITIES.models) {\n if (model.cliName === 'claude' && model.cliAlias !== undefined) {\n // Allow direct alias pass-through\n map[model.cliAlias] = model.cliAlias;\n }\n }\n // Legacy versioned names → short CLI aliases\n map['claude-sonnet-4'] = 'sonnet';\n map['claude-sonnet-4-5-20250929'] = 'sonnet';\n map['claude-opus-4'] = 'opus';\n map['claude-opus-4-6'] = 'opus';\n map['claude-opus-4-5-20251101'] = 'opus';\n map['claude-haiku-3'] = 'haiku';\n map['claude-haiku-4-5-20251001'] = 'haiku';\n return map;\n}\n\n/** Legacy fallback values for Claude models not in the canonical registry. */\nconst CLAUDE_LEGACY_DEFAULTS = {\n displayNames: {\n 'claude-opus-4': 'Claude Opus 4',\n 'claude-sonnet-4': 'Claude Sonnet 4',\n 'claude-haiku-3': 'Claude Haiku 3',\n 'claude-opus-4-5-20251101': 'Claude Opus 4.5',\n opus: 'Claude Opus 4.6',\n sonnet: 'Claude Sonnet 4.6',\n haiku: 'Claude Haiku 4.5',\n } as Readonly<Record<string, string>>,\n inputCosts: {\n 'claude-opus-4': 15.0,\n 'claude-opus-4-5-20251101': 5.0,\n 'claude-sonnet-4': 3.0,\n 'claude-haiku-3': 0.25,\n opus: 5.0,\n sonnet: 3.0,\n haiku: 1.0,\n } as Readonly<Record<string, number>>,\n outputCosts: {\n 'claude-opus-4': 75.0,\n 'claude-opus-4-5-20251101': 25.0,\n 'claude-sonnet-4': 15.0,\n 'claude-haiku-3': 1.25,\n opus: 25.0,\n sonnet: 15.0,\n haiku: 5.0,\n } as Readonly<Record<string, number>>,\n inputCost: 5.0,\n outputCost: 25.0,\n} as const;\n\n/**\n * Claude CLI adapter using subprocess transport.\n * Executes: claude -p --output-format json \"<task>\"\n */\nexport class ClaudeCliAdapter extends SubprocessCliAdapter {\n readonly name: CliName = 'claude';\n protected readonly parser: ICliResponseParser = new ClaudeResponseParser();\n\n private readonly model: string;\n\n constructor(options?: BaseAdapterOptions) {\n super(options?.logger);\n this.model = options?.model ?? getCliModelName(getDefaultModelForCli('claude'));\n }\n\n /**\n * Gets Claude model information.\n * buildModelInfo matches both cliModelName and cliAlias, so a single\n * call handles 'opus', 'sonnet', 'haiku', and full model names.\n * Falls back to legacy lookup for unrecognized models.\n */\n getModelInfo(): ModelInfo {\n const fromRegistry = buildModelInfo('claude', this.model);\n if (fromRegistry !== undefined) return fromRegistry;\n\n return {\n id: this.model,\n name: CLAUDE_LEGACY_DEFAULTS.displayNames[this.model] ?? this.model,\n contextWindow: 200_000,\n maxOutput: 64_000,\n costPerMillionInput:\n CLAUDE_LEGACY_DEFAULTS.inputCosts[this.model] ?? CLAUDE_LEGACY_DEFAULTS.inputCost,\n costPerMillionOutput:\n CLAUDE_LEGACY_DEFAULTS.outputCosts[this.model] ?? CLAUDE_LEGACY_DEFAULTS.outputCost,\n };\n }\n\n /**\n * Gets CLI command and arguments for execution.\n * Uses stdin for the prompt to avoid argument escaping issues,\n * especially important when using --add-dir.\n */\n protected getCommand(task: CliTask): CommandConfig {\n const args: string[] = ['-p', '--output-format', 'json'];\n\n // Add model - convert internal names to CLI aliases\n const internalModel = task.model ?? this.model;\n const cliModel = MODEL_TO_CLI_ALIAS[internalModel] ?? internalModel;\n args.push('--model', cliModel);\n\n // Add system prompt if provided\n if (task.systemPrompt !== undefined && task.systemPrompt !== '') {\n args.push('--system-prompt', task.systemPrompt);\n }\n\n // Add session for continuation\n if (task.sessionId !== undefined && task.sessionId !== '') {\n args.push('--resume', task.sessionId);\n }\n\n // Add working directory for file access (e.g., SWE-bench)\n const workDir = task.options?.['workDir'];\n if (typeof workDir === 'string' && workDir.length > 0) {\n args.push('--add-dir', workDir);\n }\n\n // Note: maxTokens is intentionally not passed to Claude CLI.\n // The Claude CLI does not support --max-tokens. Use --max-budget-usd instead.\n // The CLI handles token limits internally based on model configuration.\n\n // Pass prompt via stdin to avoid argument escaping issues\n return { command: 'claude', args, stdin: task.content };\n }\n}\n","/**\n * nexus-agents/cli-adapters - Resilient Gemini Parser Helpers\n *\n * Utility functions for parsing Gemini CLI output.\n *\n * (Source: Issue #366 - Gemini CLI timeout and parser improvements)\n */\n\nimport type { TokenUsage } from '../types.js';\nimport type { TokenTotals } from './gemini-parser-resilient-types.js';\nimport { asRecord, extractStringField, extractNumberField } from '../../utils/type-coercion.js';\n\n// Re-export for backward compatibility\nexport { asRecord, extractStringField };\n\n/**\n * Aggregates token counts from model stats.\n */\nexport function aggregateModelTokens(models: Record<string, unknown>): TokenTotals {\n let totalInput = 0;\n let totalOutput = 0;\n let totalCached = 0;\n\n for (const modelStats of Object.values(models)) {\n const modelRecord = asRecord(modelStats);\n if (modelRecord === null) continue;\n\n const tokens = asRecord(modelRecord.tokens);\n if (tokens === null) continue;\n\n const input = extractNumberField(tokens, 'input');\n const candidates = extractNumberField(tokens, 'candidates');\n const cached = extractNumberField(tokens, 'cached');\n\n if (input !== null) totalInput += input;\n if (candidates !== null) totalOutput += candidates;\n if (cached !== null) totalCached += cached;\n }\n\n return { input: totalInput, output: totalOutput, cached: totalCached };\n}\n\n/**\n * Extracts token usage from a parsed record.\n */\nexport function extractUsageFromRecord(record: Record<string, unknown>): TokenUsage | undefined {\n const stats = asRecord(record.stats);\n if (stats === null) return undefined;\n\n const models = asRecord(stats.models);\n if (models === null) return undefined;\n\n const totals = aggregateModelTokens(models);\n if (totals.input === 0 && totals.output === 0) return undefined;\n\n return {\n inputTokens: totals.input,\n outputTokens: totals.output,\n totalTokens: totals.input + totals.output,\n ...(totals.cached > 0 && { cachedInputTokens: totals.cached }),\n };\n}\n\n/**\n * Extracts session ID from text patterns.\n */\nexport function extractSessionIdFromText(raw: string): string | null {\n const patterns = [/session[_-]?id[:\\s]+[\"']?([a-zA-Z0-9_-]+)[\"']?/i, /gem_([a-zA-Z0-9]+)/];\n\n for (const pattern of patterns) {\n const match = pattern.exec(raw);\n const captured = match?.[1];\n if (captured !== undefined) {\n return captured.startsWith('gem_') ? captured : `gem_${captured}`;\n }\n }\n\n return null;\n}\n\n/**\n * Extracts text content from markdown, removing code blocks and formatting.\n */\nexport function extractTextFromMarkdown(raw: string): string {\n let content = raw;\n\n // Remove code blocks\n content = content.replace(/```[\\s\\S]*?```/g, '');\n\n // Remove markdown formatting\n content = content.replace(/#{1,6}\\s+/g, '');\n content = content.replace(/\\*{1,2}([^*]+)\\*{1,2}/g, '$1');\n content = content.replace(/_([^_]+)_/g, '$1');\n\n return content.trim();\n}\n\n/**\n * Extracts a clean error message from raw output.\n */\nexport function extractErrorMessage(raw: string): string {\n const lines = raw.split('\\n').filter((line) => line.trim().length > 0);\n\n // Look for error: prefix\n for (const line of lines) {\n const lower = line.toLowerCase();\n if (lower.includes('error:')) {\n return line.replace(/.*error:\\s*/i, '').trim();\n }\n }\n\n // Return first non-empty line as fallback\n return lines[0]?.trim() ?? 'Unknown error';\n}\n\n/**\n * Checks if output appears to be an error message.\n */\nexport function isLikelyErrorOutput(raw: string): boolean {\n const lower = raw.toLowerCase();\n const errorIndicators = ['error:', 'exception:', 'traceback', 'stack trace', 'fatal:', 'panic:'];\n\n // Check if output starts with error indicators\n for (const indicator of errorIndicators) {\n if (lower.startsWith(indicator)) return true;\n }\n\n // Check if it's a short error message\n if (raw.length < 200) {\n const errorKeywords = ['failed', 'error', 'cannot', 'unable to'];\n const hasErrorKeyword = errorKeywords.some((kw) => lower.includes(kw));\n const hasNoContent = !lower.includes('the ') && !lower.includes('this ');\n if (hasErrorKeyword && hasNoContent) return true;\n }\n\n return false;\n}\n","/**\n * nexus-agents/cli-adapters - Resilient Gemini CLI Response Parser\n *\n * Enhanced parser with multiple fallback strategies for handling\n * various Gemini CLI output formats including:\n * - Standard JSON output\n * - Plain text responses\n * - Multi-line outputs with markdown\n * - Error messages and exit codes\n *\n * (Source: Issue #366 - Gemini CLI timeout and parser improvements)\n */\n\nimport type { ICliResponseParser, TokenUsage } from '../types.js';\nimport type { GeminiCliResponse } from './gemini-parser.js';\nimport type { ResilientParseResult, GeminiErrorInfo } from './gemini-parser-resilient-types.js';\nimport {\n asRecord,\n extractStringField,\n extractUsageFromRecord,\n extractSessionIdFromText,\n extractTextFromMarkdown,\n extractErrorMessage,\n isLikelyErrorOutput,\n} from './gemini-parser-resilient-helpers.js';\n\n// Re-export types for backward compatibility\nexport type {\n ResilientParseResult,\n ParseStrategy,\n GeminiErrorInfo,\n} from './gemini-parser-resilient-types.js';\n\n/**\n * Resilient parser for Gemini CLI output.\n * Implements multiple fallback strategies for robust parsing.\n */\nexport class ResilientGeminiParser implements ICliResponseParser<GeminiCliResponse> {\n readonly name = 'gemini-resilient-parser';\n readonly supportedVersionRange = '>=0.20.0 <1.0.0';\n\n /**\n * Parses Gemini CLI output using multiple strategies.\n * Tries JSON first, then falls back to text extraction.\n */\n parse(raw: string): GeminiCliResponse | null {\n const result = this.parseResilient(raw);\n if (result === null) return null;\n\n // Build the response object, only including optional fields when present\n const response: GeminiCliResponse = {\n response: result.response,\n };\n\n // Add stats if usage info is available\n if (result.usage !== undefined) {\n return {\n ...response,\n ...(result.sessionId !== undefined && { session_id: result.sessionId }),\n stats: {\n models: {\n 'gemini-unknown': {\n tokens: {\n input: result.usage.inputTokens,\n candidates: result.usage.outputTokens,\n },\n },\n },\n },\n };\n }\n\n // No usage - just add session_id if it exists\n if (result.sessionId !== undefined) {\n return { ...response, session_id: result.sessionId };\n }\n\n return response;\n }\n\n /**\n * Parses with full metadata about parsing strategy.\n */\n parseResilient(raw: string): ResilientParseResult | null {\n // Strategy 1: Standard JSON parsing\n const jsonResult = this.tryParseJson(raw);\n if (jsonResult !== null) return jsonResult;\n\n // Strategy 2: Extract JSON from mixed output\n const extractedJson = this.tryExtractJson(raw);\n if (extractedJson !== null) return extractedJson;\n\n // Strategy 3: Extract from markdown code blocks\n const markdownResult = this.tryExtractFromMarkdown(raw);\n if (markdownResult !== null) return markdownResult;\n\n // Strategy 4: Plain text fallback\n const plainTextResult = this.tryPlainText(raw);\n if (plainTextResult !== null) return plainTextResult;\n\n return null;\n }\n\n /**\n * Extracts just the response text with fallback strategies.\n */\n extractResponse(raw: string): string | null {\n const result = this.parseResilient(raw);\n return result?.response ?? null;\n }\n\n /**\n * Extracts token usage if available.\n */\n extractUsage(raw: string): TokenUsage | null {\n // Try JSON parsing first for structured usage data\n const jsonResult = this.tryParseJson(raw);\n if (jsonResult?.usage) return jsonResult.usage;\n\n const extractedJson = this.tryExtractJson(raw);\n if (extractedJson?.usage) return extractedJson.usage;\n\n return null;\n }\n\n /**\n * Extracts session ID if present.\n */\n extractSessionId(raw: string): string | null {\n // Try JSON parsing first\n const jsonResult = this.tryParseJson(raw);\n if (jsonResult?.sessionId !== undefined && jsonResult.sessionId !== '') {\n return jsonResult.sessionId;\n }\n\n const extractedJson = this.tryExtractJson(raw);\n if (extractedJson?.sessionId !== undefined && extractedJson.sessionId !== '') {\n return extractedJson.sessionId;\n }\n\n // Try to extract session ID from text patterns\n return extractSessionIdFromText(raw);\n }\n\n /**\n * Detects and extracts error information from output.\n */\n extractError(raw: string): GeminiErrorInfo | null {\n const lower = raw.toLowerCase();\n\n if (lower.includes('timeout') || lower.includes('timed out')) {\n return { type: 'timeout', message: extractErrorMessage(raw) };\n }\n\n if (lower.includes('authentication') || lower.includes('unauthorized')) {\n return { type: 'auth', message: extractErrorMessage(raw) };\n }\n\n if (lower.includes('rate limit') || lower.includes('quota exceeded')) {\n return { type: 'rate-limit', message: extractErrorMessage(raw) };\n }\n\n if (lower.includes('error') || lower.includes('failed')) {\n return { type: 'api-error', message: extractErrorMessage(raw) };\n }\n\n return null;\n }\n\n // -------------------------------------------------------------------------\n // Private Strategy Methods\n // -------------------------------------------------------------------------\n\n private tryParseJson(raw: string): ResilientParseResult | null {\n try {\n const data: unknown = JSON.parse(raw);\n const record = asRecord(data);\n if (record === null) return null;\n\n const response = record.response;\n if (typeof response !== 'string') return null;\n\n const sessionId = extractStringField(record, 'session_id');\n const usage = extractUsageFromRecord(record);\n\n const result: ResilientParseResult = {\n response,\n parseStrategy: 'json',\n raw,\n };\n\n if (sessionId !== undefined) {\n (result as { sessionId?: string }).sessionId = sessionId;\n }\n if (usage !== undefined) {\n (result as { usage?: TokenUsage }).usage = usage;\n }\n\n return result;\n } catch {\n return null;\n }\n }\n\n private tryExtractJson(raw: string): ResilientParseResult | null {\n // Look for JSON object patterns in the output\n const jsonPatterns = [\n /\\{[\\s\\S]*\"response\"\\s*:\\s*\"[\\s\\S]*\"\\s*[\\s\\S]*\\}/,\n /\\{[\\s\\S]*\"response\"\\s*:\\s*'[\\s\\S]*'\\s*[\\s\\S]*\\}/,\n ];\n\n for (const pattern of jsonPatterns) {\n const match = pattern.exec(raw);\n if (match !== null) {\n const jsonStr = match[0];\n const result = this.tryParseJson(jsonStr);\n if (result !== null) {\n return { ...result, parseStrategy: 'json-extracted', raw };\n }\n }\n }\n\n return null;\n }\n\n private tryExtractFromMarkdown(raw: string): ResilientParseResult | null {\n // Extract content from markdown code blocks\n const codeBlockPattern = /```(?:json)?\\s*([\\s\\S]*?)```/g;\n let match: RegExpExecArray | null = codeBlockPattern.exec(raw);\n\n while (match !== null) {\n const captured = match[1];\n if (captured !== undefined) {\n const content = captured.trim();\n\n // Try to parse as JSON\n const jsonResult = this.tryParseJson(content);\n if (jsonResult !== null) {\n return { ...jsonResult, parseStrategy: 'markdown-code-block', raw };\n }\n }\n\n match = codeBlockPattern.exec(raw);\n }\n\n // If no JSON found in code blocks, treat entire content as response\n // but only if it looks like substantive output\n if (raw.includes('```')) {\n const cleanedContent = extractTextFromMarkdown(raw);\n if (cleanedContent.length > 0) {\n return {\n response: cleanedContent,\n parseStrategy: 'markdown-code-block',\n raw,\n };\n }\n }\n\n return null;\n }\n\n private tryPlainText(raw: string): ResilientParseResult | null {\n const trimmed = raw.trim();\n\n // Skip if empty or looks like an error\n if (trimmed.length === 0) return null;\n\n // Skip if it looks like just error output\n if (isLikelyErrorOutput(trimmed)) return null;\n\n // Accept as plain text response\n return {\n response: trimmed,\n parseStrategy: 'plain-text',\n raw,\n };\n }\n}\n\n/**\n * Creates a resilient Gemini parser instance.\n */\nexport function createResilientGeminiParser(): ResilientGeminiParser {\n return new ResilientGeminiParser();\n}\n","/**\n * nexus-agents/cli-adapters - Circuit Breaker Types\n *\n * Type definitions and error classes for the circuit breaker pattern.\n *\n * (Source: Issue #81 - Circuit breaker for CLI failures)\n */\n\nimport { NexusError, ErrorCode } from '../core/errors.js';\nimport type { CliName } from './types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Circuit breaker states.\n */\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\n/**\n * Categories of failures for circuit breaker decisions.\n */\nexport type FailureCategory =\n | 'timeout' // CLI didn't respond in time\n | 'crash' // Process crashed or exited unexpectedly\n | 'authentication' // OAuth/auth failure\n | 'rate_limit' // Rate limit exceeded\n | 'connection' // MCP connection failed\n | 'unknown'; // Uncategorized failure\n\n/**\n * Configuration options for circuit breaker.\n */\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit (default: 5) */\n readonly failureThreshold: number;\n /** Time in ms before attempting recovery (default: 30000) */\n readonly resetTimeoutMs: number;\n /** Successful calls needed in half-open to close (default: 2) */\n readonly halfOpenSuccessThreshold: number;\n /** Whether to count timeouts as failures (default: true) */\n readonly countTimeoutsAsFailures: boolean;\n /** Whether to count auth failures as failures (default: false) */\n readonly countAuthFailuresAsFailures: boolean;\n /** Maximum number of requests allowed in half-open state (default: 3) */\n readonly halfOpenMaxRequests: number;\n}\n\n/**\n * Circuit breaker state snapshot.\n */\nexport interface CircuitBreakerSnapshot {\n /** Current state */\n readonly state: CircuitState;\n /** Total failure count since last closed */\n readonly failureCount: number;\n /** Success count in half-open state */\n readonly successCount: number;\n /** Timestamp of last failure */\n readonly lastFailureTime: number | null;\n /** Timestamp of last state change */\n readonly lastStateChange: number;\n /** Requests in current half-open window */\n readonly halfOpenRequests: number;\n /** Configuration */\n readonly config: CircuitBreakerConfig;\n}\n\n/**\n * Event emitted on circuit state changes.\n */\nexport interface CircuitStateChangeEvent {\n /** CLI name */\n readonly cliName: CliName;\n /** Previous state */\n readonly previousState: CircuitState;\n /** New state */\n readonly newState: CircuitState;\n /** Timestamp of change */\n readonly timestamp: number;\n /** Failure count at time of change */\n readonly failureCount: number;\n /** Reason for state change */\n readonly reason: string;\n}\n\n/**\n * Event listener for circuit state changes.\n */\nexport type CircuitStateChangeListener = (event: CircuitStateChangeEvent) => void;\n\n/**\n * Interface for circuit breaker operations.\n */\nexport interface ICircuitBreaker {\n /**\n * Executes a function with circuit breaker protection.\n */\n execute<T>(fn: () => Promise<T>): Promise<import('../core/index.js').Result<T, CircuitError>>;\n\n /**\n * Gets the current circuit state.\n */\n getState(): CircuitState;\n\n /**\n * Gets a full snapshot of circuit breaker state.\n */\n getSnapshot(): CircuitBreakerSnapshot;\n\n /**\n * Manually resets the circuit breaker to closed state.\n */\n reset(): void;\n\n /**\n * Records a failure manually (for external failure detection).\n */\n recordFailure(category: FailureCategory): void;\n\n /**\n * Records a success manually (for external success detection).\n */\n recordSuccess(): void;\n}\n\n// ============================================================================\n// Error Codes\n// ============================================================================\n\n/**\n * Error codes specific to circuit breaker.\n */\nexport const CircuitErrorCode = {\n CIRCUIT_OPEN: 'CIRCUIT_OPEN',\n CIRCUIT_HALF_OPEN_REJECTED: 'CIRCUIT_HALF_OPEN_REJECTED',\n EXECUTION_FAILED: 'EXECUTION_FAILED',\n} as const;\n\nexport type CircuitErrorCode = (typeof CircuitErrorCode)[keyof typeof CircuitErrorCode];\n\n// ============================================================================\n// Error Class\n// ============================================================================\n\n/**\n * Error thrown when circuit breaker blocks a request.\n */\nexport class CircuitError extends NexusError {\n readonly circuitErrorCode: CircuitErrorCode;\n readonly cliName: CliName;\n readonly circuitState: CircuitState;\n readonly failureCategory?: FailureCategory;\n\n constructor(\n message: string,\n options: {\n circuitErrorCode: CircuitErrorCode;\n cliName: CliName;\n circuitState: CircuitState;\n failureCategory?: FailureCategory;\n cause?: Error;\n }\n ) {\n const baseOptions: { code: ErrorCode; cause?: Error; context: Record<string, unknown> } = {\n code: ErrorCode.INTERNAL_ERROR,\n context: {\n circuitErrorCode: options.circuitErrorCode,\n cliName: options.cliName,\n circuitState: options.circuitState,\n },\n };\n if (options.cause !== undefined) {\n baseOptions.cause = options.cause;\n }\n if (options.failureCategory !== undefined) {\n baseOptions.context['failureCategory'] = options.failureCategory;\n }\n super(message, baseOptions);\n this.name = 'CircuitError';\n this.circuitErrorCode = options.circuitErrorCode;\n this.cliName = options.cliName;\n this.circuitState = options.circuitState;\n if (options.failureCategory !== undefined) {\n this.failureCategory = options.failureCategory;\n }\n }\n}\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\n/**\n * Default circuit breaker configuration.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeoutMs: 30_000,\n halfOpenSuccessThreshold: 2,\n countTimeoutsAsFailures: true,\n countAuthFailuresAsFailures: false,\n halfOpenMaxRequests: 3,\n} as const;\n\n// ============================================================================\n// Error Categorization Patterns\n// ============================================================================\n\n/**\n * Pattern matchers for categorizing errors.\n */\nconst TIMEOUT_PATTERNS = ['timeout', 'timed out'];\nconst AUTH_PATTERNS = ['auth', 'unauthorized', 'forbidden', 'oauth'];\nconst RATE_LIMIT_PATTERNS = ['rate limit', 'too many requests', '429'];\nconst CONNECTION_PATTERNS = ['connection', 'econnrefused', 'enotfound', 'mcp'];\nconst CRASH_PATTERNS = ['crash', 'exited', 'killed', 'sigterm', 'sigkill'];\n\n/**\n * Checks if text contains any of the patterns.\n */\nfunction matchesPatterns(text: string, patterns: string[]): boolean {\n return patterns.some((pattern) => text.includes(pattern));\n}\n\n/**\n * Categorizes an error into a failure category.\n */\nexport function categorizeError(error: unknown): FailureCategory {\n if (!(error instanceof Error)) {\n return 'unknown';\n }\n\n const message = error.message.toLowerCase();\n const name = error.name.toLowerCase();\n const combined = `${message} ${name}`;\n\n if (matchesPatterns(combined, TIMEOUT_PATTERNS)) return 'timeout';\n if (matchesPatterns(combined, AUTH_PATTERNS)) return 'authentication';\n if (matchesPatterns(combined, RATE_LIMIT_PATTERNS)) return 'rate_limit';\n if (matchesPatterns(combined, CONNECTION_PATTERNS)) return 'connection';\n if (matchesPatterns(combined, CRASH_PATTERNS)) return 'crash';\n\n return 'unknown';\n}\n","/**\n * nexus-agents/cli-adapters - Circuit Breaker Implementation\n *\n * Implements the circuit breaker pattern to handle CLI failures gracefully\n * and prevent cascade failures in the multi-CLI mesh.\n *\n * (Source: Issue #81 - Circuit breaker for CLI failures)\n * (Source: Martin Fowler's Circuit Breaker pattern)\n */\n\nimport type { Result } from '../core/index.js';\nimport { getErrorMessage, err, ok, getTimeProvider } from '../core/index.js';\n\nimport type { CliName, CliErrorCode } from './types.js';\nimport {\n CircuitError,\n CircuitErrorCode,\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n categorizeError,\n type CircuitState,\n type FailureCategory,\n type CircuitBreakerConfig,\n type CircuitBreakerSnapshot,\n type CircuitStateChangeEvent,\n type CircuitStateChangeListener,\n type ICircuitBreaker,\n} from './circuit-breaker-types.js';\n\n// Re-export all types for convenience\nexport {\n CircuitError,\n CircuitErrorCode,\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n categorizeError,\n type CircuitState,\n type FailureCategory,\n type CircuitBreakerConfig,\n type CircuitBreakerSnapshot,\n type CircuitStateChangeEvent,\n type CircuitStateChangeListener,\n type ICircuitBreaker,\n} from './circuit-breaker-types.js';\n\n// ============================================================================\n// Circuit Breaker Implementation\n// ============================================================================\n\n/**\n * Circuit breaker implementation for CLI adapters.\n *\n * Provides protection against cascading failures by:\n * 1. Tracking failure counts\n * 2. Opening circuit when threshold exceeded\n * 3. Allowing gradual recovery through half-open state\n */\nexport class CliCircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = 'closed';\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number | null = null;\n private lastStateChange: number;\n private halfOpenRequests = 0;\n private readonly listeners: Set<CircuitStateChangeListener> = new Set();\n\n constructor(\n private readonly cliName: CliName,\n private readonly config: CircuitBreakerConfig = DEFAULT_CIRCUIT_BREAKER_CONFIG\n ) {\n this.lastStateChange = getTimeProvider().now();\n }\n\n /**\n * Executes a function with circuit breaker protection.\n */\n async execute<T>(fn: () => Promise<T>): Promise<Result<T, CircuitError>> {\n const canExecute = this.canExecute();\n if (!canExecute.ok) {\n return canExecute;\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return ok(result);\n } catch (error) {\n const category = categorizeError(error);\n if (this.shouldCountFailure(category)) {\n this.onFailure(category);\n }\n return err(this.createExecutionError(error, category));\n }\n }\n\n getState(): CircuitState {\n this.checkStateTransition();\n return this.state;\n }\n\n getSnapshot(): CircuitBreakerSnapshot {\n this.checkStateTransition();\n return {\n state: this.state,\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime,\n lastStateChange: this.lastStateChange,\n halfOpenRequests: this.halfOpenRequests,\n config: this.config,\n };\n }\n\n reset(): void {\n const previousState = this.state;\n this.state = 'closed';\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = null;\n this.halfOpenRequests = 0;\n this.lastStateChange = getTimeProvider().now();\n\n if (previousState !== 'closed') {\n this.emitStateChange(previousState, 'closed', 'Manual reset');\n }\n }\n\n recordFailure(category: FailureCategory): void {\n if (this.shouldCountFailure(category)) {\n this.onFailure(category);\n }\n }\n\n recordSuccess(): void {\n this.onSuccess();\n }\n\n addStateChangeListener(listener: CircuitStateChangeListener): void {\n this.listeners.add(listener);\n }\n\n removeStateChangeListener(listener: CircuitStateChangeListener): void {\n this.listeners.delete(listener);\n }\n\n // -------------------------------------------------------------------------\n // Private Methods\n // -------------------------------------------------------------------------\n\n private canExecute(): Result<true, CircuitError> {\n this.checkStateTransition();\n\n if (this.state === 'closed') {\n return ok(true);\n }\n\n if (this.state === 'open') {\n return err(\n new CircuitError(`Circuit is open for CLI: ${this.cliName}`, {\n circuitErrorCode: CircuitErrorCode.CIRCUIT_OPEN,\n cliName: this.cliName,\n circuitState: this.state,\n })\n );\n }\n\n // half-open state\n if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {\n return err(\n new CircuitError(`Circuit half-open request limit reached for CLI: ${this.cliName}`, {\n circuitErrorCode: CircuitErrorCode.CIRCUIT_HALF_OPEN_REJECTED,\n cliName: this.cliName,\n circuitState: this.state,\n })\n );\n }\n this.halfOpenRequests++;\n return ok(true);\n }\n\n private checkStateTransition(): void {\n if (this.state === 'open' && this.lastFailureTime !== null) {\n const elapsed = getTimeProvider().now() - this.lastFailureTime;\n if (elapsed >= this.config.resetTimeoutMs) {\n this.transitionTo('half-open', 'Reset timeout elapsed');\n }\n }\n }\n\n private onSuccess(): void {\n if (this.state === 'closed') {\n this.failureCount = 0;\n } else if (this.state === 'half-open') {\n this.successCount++;\n if (this.successCount >= this.config.halfOpenSuccessThreshold) {\n const reason = `${String(this.successCount)} consecutive successes in half-open state`;\n this.transitionTo('closed', reason);\n }\n }\n }\n\n private onFailure(category: FailureCategory): void {\n this.failureCount++;\n this.lastFailureTime = getTimeProvider().now();\n\n if (this.state === 'closed' && this.failureCount >= this.config.failureThreshold) {\n const reason = `Failure threshold (${String(this.config.failureThreshold)}) exceeded`;\n this.transitionTo('open', reason);\n } else if (this.state === 'half-open') {\n this.transitionTo('open', `Failure during half-open recovery (category: ${category})`);\n }\n }\n\n private transitionTo(newState: CircuitState, reason: string): void {\n const previousState = this.state;\n this.state = newState;\n this.lastStateChange = getTimeProvider().now();\n\n if (newState === 'closed') {\n this.failureCount = 0;\n this.successCount = 0;\n this.halfOpenRequests = 0;\n } else if (newState === 'half-open') {\n this.successCount = 0;\n this.halfOpenRequests = 0;\n }\n\n this.emitStateChange(previousState, newState, reason);\n }\n\n private emitStateChange(\n previousState: CircuitState,\n newState: CircuitState,\n reason: string\n ): void {\n const event: CircuitStateChangeEvent = {\n cliName: this.cliName,\n previousState,\n newState,\n timestamp: this.lastStateChange,\n failureCount: this.failureCount,\n reason,\n };\n\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // Ignore listener errors to prevent cascade\n }\n }\n }\n\n private shouldCountFailure(category: FailureCategory): boolean {\n if (category === 'timeout') return this.config.countTimeoutsAsFailures;\n if (category === 'authentication') return this.config.countAuthFailuresAsFailures;\n return true;\n }\n\n private createExecutionError(error: unknown, category: FailureCategory): CircuitError {\n const message = getErrorMessage(error);\n const cause = error instanceof Error ? error : new Error(String(error));\n return new CircuitError(`CLI execution failed: ${message}`, {\n circuitErrorCode: CircuitErrorCode.EXECUTION_FAILED,\n cliName: this.cliName,\n circuitState: this.state,\n failureCategory: category,\n cause,\n });\n }\n}\n\n// ============================================================================\n// Registry\n// ============================================================================\n\n/**\n * Registry for managing per-CLI circuit breakers.\n */\nexport class CircuitBreakerRegistry {\n private readonly breakers: Map<CliName, CliCircuitBreaker> = new Map();\n private readonly globalListeners: Set<CircuitStateChangeListener> = new Set();\n\n constructor(private readonly defaultConfig: Partial<CircuitBreakerConfig> = {}) {}\n\n getBreaker(cliName: CliName, config?: Partial<CircuitBreakerConfig>): CliCircuitBreaker {\n let breaker = this.breakers.get(cliName);\n\n if (!breaker) {\n const mergedConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...this.defaultConfig,\n ...config,\n };\n breaker = new CliCircuitBreaker(cliName, mergedConfig);\n\n for (const listener of this.globalListeners) {\n breaker.addStateChangeListener(listener);\n }\n\n this.breakers.set(cliName, breaker);\n }\n\n return breaker;\n }\n\n isOpen(cliName: CliName): boolean {\n return this.breakers.get(cliName)?.getState() === 'open';\n }\n\n getAllSnapshots(): Map<CliName, CircuitBreakerSnapshot> {\n const snapshots = new Map<CliName, CircuitBreakerSnapshot>();\n for (const [name, breaker] of this.breakers) {\n snapshots.set(name, breaker.getSnapshot());\n }\n return snapshots;\n }\n\n resetAll(): void {\n for (const breaker of this.breakers.values()) {\n breaker.reset();\n }\n }\n\n reset(cliName: CliName): void {\n this.breakers.get(cliName)?.reset();\n }\n\n addGlobalStateChangeListener(listener: CircuitStateChangeListener): void {\n this.globalListeners.add(listener);\n for (const breaker of this.breakers.values()) {\n breaker.addStateChangeListener(listener);\n }\n }\n\n removeGlobalStateChangeListener(listener: CircuitStateChangeListener): void {\n this.globalListeners.delete(listener);\n for (const breaker of this.breakers.values()) {\n breaker.removeStateChangeListener(listener);\n }\n }\n\n getHealthyClis(): CliName[] {\n const healthy: CliName[] = [];\n for (const [name, breaker] of this.breakers) {\n if (breaker.getState() === 'closed') {\n healthy.push(name);\n }\n }\n return healthy;\n }\n\n getUnhealthyClis(): CliName[] {\n const unhealthy: CliName[] = [];\n for (const [name, breaker] of this.breakers) {\n const state = breaker.getState();\n if (state === 'open' || state === 'half-open') {\n unhealthy.push(name);\n }\n }\n return unhealthy;\n }\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Maps CLI error codes to failure categories.\n */\nexport function mapCliErrorToCategory(errorCode: CliErrorCode): FailureCategory {\n const mapping: Record<string, FailureCategory> = {\n TIMEOUT: 'timeout',\n NOT_AUTHENTICATED: 'authentication',\n RATE_LIMITED: 'rate_limit',\n CONNECTION_ERROR: 'connection',\n };\n return mapping[errorCode] ?? 'unknown';\n}\n\n/**\n * Creates a circuit breaker registry with metrics logging.\n */\nexport function createCircuitBreakerRegistryWithMetrics(\n logger: { info: (message: string, context?: Record<string, unknown>) => void },\n config?: Partial<CircuitBreakerConfig>\n): CircuitBreakerRegistry {\n const registry = new CircuitBreakerRegistry(config);\n\n registry.addGlobalStateChangeListener((event) => {\n logger.info('Circuit breaker state change', {\n cliName: event.cliName,\n previousState: event.previousState,\n newState: event.newState,\n failureCount: event.failureCount,\n reason: event.reason,\n timestamp: new Date(event.timestamp).toISOString(),\n });\n });\n\n return registry;\n}\n\n// ============================================================================\n// Capacity Monitor Integration\n// ============================================================================\n\n/**\n * Configuration for capacity monitor integration.\n */\nexport interface CapacityMonitorIntegrationConfig {\n /** Token threshold below which to trip circuit (default: 1000) */\n readonly criticalTokenThreshold?: number;\n /** Provider name to CLI name mapping */\n readonly providerToCliMapping?: Record<string, CliName>;\n}\n\nconst DEFAULT_CAPACITY_INTEGRATION_CONFIG: Required<CapacityMonitorIntegrationConfig> = {\n criticalTokenThreshold: 1000,\n providerToCliMapping: {\n anthropic: 'claude',\n openai: 'codex',\n google: 'gemini',\n },\n} as const;\n\n/**\n * Integrates a CapacityMonitor with CircuitBreakerRegistry to trip circuits\n * when provider capacity is critically low.\n *\n * This addresses Issue #543: Wire up onLowCapacity callback.\n *\n * @param monitor - The capacity monitor to integrate\n * @param registry - The circuit breaker registry\n * @param config - Optional configuration\n * @param logger - Optional logger for diagnostics\n * @returns Unsubscribe function to remove the callback\n *\n * @example\n * ```typescript\n * const monitor = createCapacityMonitor();\n * const registry = new CircuitBreakerRegistry();\n *\n * // Wire up capacity signals to circuit breaker\n * const unsubscribe = integrateCapacityMonitorWithCircuitBreaker(\n * monitor,\n * registry,\n * { criticalTokenThreshold: 500 }\n * );\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport function integrateCapacityMonitorWithCircuitBreaker(\n monitor: {\n onLowCapacity: (callback: (provider: string, remaining: number) => void) => () => void;\n },\n registry: CircuitBreakerRegistry,\n config?: CapacityMonitorIntegrationConfig,\n logger?: { warn: (message: string, context?: Record<string, unknown>) => void }\n): () => void {\n const mergedConfig = { ...DEFAULT_CAPACITY_INTEGRATION_CONFIG, ...config };\n\n return monitor.onLowCapacity((provider: string, remaining: number) => {\n // Map provider name to CLI name\n const cliName = mergedConfig.providerToCliMapping[provider];\n if (cliName === undefined) {\n logger?.warn('Unknown provider for capacity monitoring', { provider, remaining });\n return;\n }\n\n // Trip the circuit if capacity is critically low\n if (remaining < mergedConfig.criticalTokenThreshold) {\n const breaker = registry.getBreaker(cliName);\n breaker.recordFailure('rate_limit');\n logger?.warn('Circuit tripped due to low capacity', {\n provider,\n cliName,\n remaining,\n threshold: mergedConfig.criticalTokenThreshold,\n });\n }\n });\n}\n","/**\n * nexus-agents/cli-adapters - Gemini CLI Adapter Helpers\n *\n * CLI-specific helper functions for retry logic and error handling.\n * Model info lookups consolidated into config/model-config-helpers.ts (#886).\n */\n\nimport { getRandomProvider } from '../../core/index.js';\nimport type { CliError, CliName } from '../types.js';\nimport type { FailureCategory } from '../circuit-breaker-types.js';\n\n// -----------------------------------------------------------------------------\n// Fallback Defaults (for unknown models not in canonical registry)\n// -----------------------------------------------------------------------------\n\n/**\n * Fallback defaults for Gemini models not in the canonical registry.\n * All current models are in model-capabilities.ts and served by\n * buildModelInfo('gemini', model). This provides sensible defaults\n * when an unknown model name is encountered at runtime.\n *\n * @see config/model-capabilities.ts — single source of truth for current models\n */\nexport const GEMINI_LEGACY_DEFAULTS = {\n displayNames: {} as Readonly<Record<string, string>>,\n contextWindows: {} as Readonly<Record<string, number>>,\n inputCosts: {} as Readonly<Record<string, number>>,\n outputCosts: {} as Readonly<Record<string, number>>,\n contextWindow: 1_000_000,\n inputCost: 0.15,\n outputCost: 0.6,\n} as const;\n\n// -----------------------------------------------------------------------------\n// Retry Logic\n// -----------------------------------------------------------------------------\n\n/** Error codes that can be retried. */\nconst RETRYABLE_ERROR_CODES: ReadonlySet<CliError['code']> = new Set([\n 'TIMEOUT',\n 'RATE_LIMITED',\n 'CONNECTION_ERROR',\n]);\n\n/**\n * Calculates exponential backoff delay with jitter.\n *\n * @param attempt - Current attempt number (1-indexed)\n * @param baseDelayMs - Base delay in milliseconds\n * @param maxDelayMs - Maximum delay cap in milliseconds\n * @returns Delay in milliseconds with jitter applied\n */\nexport function calculateBackoffDelay(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number\n): number {\n const exponentialDelay = baseDelayMs * Math.pow(2, attempt - 1);\n const jitter = getRandomProvider().random() * 0.3 * exponentialDelay;\n const delay = exponentialDelay + jitter;\n\n return Math.min(delay, maxDelayMs);\n}\n\n/** Determines if an error code is retryable. */\nexport function isRetryableError(code: CliError['code']): boolean {\n return RETRYABLE_ERROR_CODES.has(code);\n}\n\n// -----------------------------------------------------------------------------\n// Error Categorization\n// -----------------------------------------------------------------------------\n\n/**\n * Categorizes a CLI error for circuit breaker tracking.\n * Returns a FailureCategory compatible with the circuit breaker.\n */\nexport function categorizeError(error: CliError): FailureCategory {\n switch (error.code) {\n case 'TIMEOUT':\n return 'timeout';\n case 'RATE_LIMITED':\n return 'rate_limit';\n case 'NOT_AUTHENTICATED':\n return 'authentication';\n case 'CONNECTION_ERROR':\n return 'connection';\n default:\n return 'unknown';\n }\n}\n\n// -----------------------------------------------------------------------------\n// Error Factory\n// -----------------------------------------------------------------------------\n\n/** Creates a circuit breaker open error. */\nexport function createCircuitOpenError(cli: CliName): CliError {\n return {\n code: 'EXECUTION_ERROR',\n message: `Circuit breaker is open - ${cli} CLI temporarily unavailable`,\n cli,\n retryable: false,\n };\n}\n\n// -----------------------------------------------------------------------------\n// Utility Functions\n// -----------------------------------------------------------------------------\n\n// Re-export from canonical source for backward compatibility\nexport { delay } from '../../utils/async-utils.js';\n","/**\n * nexus-agents/cli-adapters - Gemini CLI Adapter\n *\n * Subprocess-based adapter for Gemini CLI with:\n * - Tiered timeout profiles based on task complexity\n * - Resilient JSON parsing with fallback strategies\n * - Exponential backoff retry logic\n * - Circuit breaker integration for sustained failures\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: Issue #366 - Gemini CLI timeout and parser improvements)\n * (Source: Issue #389 - Merged enhanced adapter back to canonical)\n */\n\nimport type { Result, ILogger } from '../../core/index.js';\nimport { ok, err, createLogger, getTimeProvider } from '../../core/index.js';\nimport type {\n ICliResponseParser,\n CliTask,\n CliResponse,\n CliError,\n ModelInfo,\n CliName,\n ExecutionOptions,\n BaseAdapterOptions,\n} from '../types.js';\nimport { SubprocessCliAdapter, type CommandConfig } from '../subprocess-adapter.js';\nimport { ResilientGeminiParser } from '../parsers/gemini-parser-resilient.js';\nimport {\n getTimeoutForTask,\n estimateTaskComplexity,\n type TaskComplexity,\n} from '../cli-timeout-profiles.js';\nimport {\n CliCircuitBreaker,\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n type CircuitBreakerConfig,\n type CircuitBreakerSnapshot,\n} from '../circuit-breaker.js';\nimport {\n GEMINI_LEGACY_DEFAULTS,\n calculateBackoffDelay,\n isRetryableError,\n categorizeError,\n createCircuitOpenError,\n delay,\n} from './gemini-adapter-helpers.js';\nimport {\n DEFAULT_MODEL_PER_CLI,\n DEFAULT_MODEL_CAPABILITIES,\n} from '../../config/model-capabilities.js';\nimport { buildModelInfo } from '../../config/model-config-helpers.js';\n\n/** Derive the CLI model name for the default Gemini model from the canonical registry. */\nconst DEFAULT_GEMINI_CLI_MODEL: string =\n DEFAULT_MODEL_CAPABILITIES.models.find((m) => m.id === DEFAULT_MODEL_PER_CLI.gemini)\n ?.cliModelName ?? DEFAULT_MODEL_PER_CLI.gemini;\n\n/** Configuration for Gemini adapter. Extends BaseAdapterOptions with retry/circuit breaker. */\nexport interface GeminiConfig extends BaseAdapterOptions {\n /** Maximum retry attempts (default: 3) */\n readonly maxRetries?: number;\n /** Base delay for exponential backoff in ms (default: 1000) */\n readonly baseDelayMs?: number;\n /** Maximum delay for backoff in ms (default: 30000) */\n readonly maxDelayMs?: number;\n /** Circuit breaker configuration */\n readonly circuitBreakerConfig?: Partial<CircuitBreakerConfig>;\n /** Enable circuit breaker (default: true) */\n readonly enableCircuitBreaker?: boolean;\n}\n\n/** Retry context for tracking retry state. */\ninterface RetryContext {\n readonly attempt: number;\n readonly maxAttempts: number;\n readonly lastError?: CliError;\n readonly totalDelayMs: number;\n}\n\n/** Execution result with metadata. */\nexport interface GeminiExecutionResult {\n readonly response: CliResponse;\n readonly retryCount: number;\n readonly totalDurationMs: number;\n readonly complexity: TaskComplexity;\n readonly circuitState: 'closed' | 'open' | 'half-open';\n}\n\nconst DEFAULT_CONFIG: Required<Omit<GeminiConfig, 'logger' | 'circuitBreakerConfig'>> = {\n model: DEFAULT_GEMINI_CLI_MODEL,\n maxRetries: 3,\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n enableCircuitBreaker: true,\n};\n\n/**\n * Gemini CLI adapter with reliability features.\n *\n * Includes tiered timeouts, resilient parsing, retry logic, and circuit breaker.\n */\nexport class GeminiCliAdapter extends SubprocessCliAdapter {\n readonly name: CliName = 'gemini';\n protected readonly parser: ICliResponseParser;\n\n private readonly model: string;\n private readonly maxRetries: number;\n private readonly baseDelayMs: number;\n private readonly maxDelayMs: number;\n private readonly circuitBreaker: CliCircuitBreaker | null;\n private readonly adapterLogger: ILogger;\n\n constructor(options?: GeminiConfig) {\n const mergedConfig = { ...DEFAULT_CONFIG, ...options };\n super(options?.logger);\n\n this.model = mergedConfig.model;\n this.maxRetries = mergedConfig.maxRetries;\n this.baseDelayMs = mergedConfig.baseDelayMs;\n this.maxDelayMs = mergedConfig.maxDelayMs;\n this.parser = new ResilientGeminiParser();\n this.adapterLogger = options?.logger ?? createLogger({ component: 'gemini-adapter' });\n\n // Initialize circuit breaker if enabled\n if (mergedConfig.enableCircuitBreaker) {\n const cbConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...options?.circuitBreakerConfig,\n };\n this.circuitBreaker = new CliCircuitBreaker('gemini', cbConfig);\n } else {\n this.circuitBreaker = null;\n }\n }\n\n /**\n * Gets Gemini model information.\n * Resolves from canonical registry when possible, falls back to legacy lookup.\n * Note: maxOutput is capped at 8_192 (Gemini CLI constraint).\n */\n getModelInfo(): ModelInfo {\n const fromRegistry = buildModelInfo('gemini', this.model);\n if (fromRegistry !== undefined) {\n return { ...fromRegistry, maxOutput: 8_192 };\n }\n return {\n id: this.model,\n name: GEMINI_LEGACY_DEFAULTS.displayNames[this.model] ?? this.model,\n contextWindow:\n GEMINI_LEGACY_DEFAULTS.contextWindows[this.model] ?? GEMINI_LEGACY_DEFAULTS.contextWindow,\n maxOutput: 8_192,\n costPerMillionInput:\n GEMINI_LEGACY_DEFAULTS.inputCosts[this.model] ?? GEMINI_LEGACY_DEFAULTS.inputCost,\n costPerMillionOutput:\n GEMINI_LEGACY_DEFAULTS.outputCosts[this.model] ?? GEMINI_LEGACY_DEFAULTS.outputCost,\n };\n }\n\n /**\n * Executes a task with reliability features.\n */\n override async execute(\n task: CliTask,\n options?: ExecutionOptions\n ): Promise<Result<CliResponse, CliError>> {\n const result = await this.executeWithMetadata(task, options);\n\n if (result.ok) {\n return ok(result.value.response);\n }\n\n return err(result.error);\n }\n\n /**\n * Executes with full metadata about retry attempts and circuit state.\n */\n async executeWithMetadata(\n task: CliTask,\n options?: ExecutionOptions\n ): Promise<Result<GeminiExecutionResult, CliError>> {\n const circuitCheckResult = this.checkCircuitBreaker();\n if (circuitCheckResult !== null) {\n return err(circuitCheckResult);\n }\n\n const startTime = getTimeProvider().now();\n const complexity = estimateTaskComplexity(task.content);\n const effectiveOptions = this.buildExecutionOptions(task.content, options);\n\n const result = await this.executeWithRetryTracking(task, effectiveOptions);\n\n return this.buildExecutionResult(result, startTime, complexity);\n }\n\n /**\n * Gets current circuit breaker snapshot.\n */\n getCircuitBreakerSnapshot(): CircuitBreakerSnapshot | null {\n return this.circuitBreaker?.getSnapshot() ?? null;\n }\n\n /**\n * Resets the circuit breaker to closed state.\n */\n resetCircuitBreaker(): void {\n this.circuitBreaker?.reset();\n }\n\n /**\n * Gets CLI command and arguments for execution.\n */\n protected override getCommand(task: CliTask): CommandConfig {\n const args: string[] = [];\n\n // Add the task content as positional argument\n args.push(task.content);\n\n // Add output format\n args.push('-o', 'json');\n\n // Add model (always present due to default)\n const model = task.model ?? this.model;\n args.push('-m', model);\n\n // Add session for continuation\n if (task.sessionId !== undefined && task.sessionId !== '') {\n args.push('--resume', task.sessionId);\n }\n\n // Note: Sandbox mode (-s) removed - causes npm permission issues\n // and \"rebuilt dependencies successfully\" contamination\n\n return { command: 'gemini', args };\n }\n\n private checkCircuitBreaker(): CliError | null {\n if (this.circuitBreaker === null) {\n return null;\n }\n if (this.circuitBreaker.getState() === 'open') {\n return createCircuitOpenError('gemini');\n }\n return null;\n }\n\n private buildExecutionOptions(\n taskContent: string,\n options?: ExecutionOptions\n ): Required<ExecutionOptions> {\n const complexity = estimateTaskComplexity(taskContent);\n const timeoutMs = options?.timeoutMs ?? getTimeoutForTask(this.name, complexity);\n\n return {\n timeoutMs,\n allowRetry: options?.allowRetry ?? true,\n maxRetries: options?.maxRetries ?? this.maxRetries,\n trackUsage: options?.trackUsage ?? true,\n onProgress: options?.onProgress,\n };\n }\n\n private buildExecutionResult(\n result: Result<{ response: CliResponse; retryCount: number }, CliError>,\n startTime: number,\n complexity: TaskComplexity\n ): Result<GeminiExecutionResult, CliError> {\n const totalDurationMs = getTimeProvider().now() - startTime;\n const circuitState = this.circuitBreaker?.getState() ?? 'closed';\n\n if (result.ok) {\n this.circuitBreaker?.recordSuccess();\n return ok({\n response: result.value.response,\n retryCount: result.value.retryCount,\n totalDurationMs,\n complexity,\n circuitState,\n });\n }\n\n return err(result.error);\n }\n\n private async executeWithRetryTracking(\n task: CliTask,\n options: Required<ExecutionOptions>\n ): Promise<Result<{ response: CliResponse; retryCount: number }, CliError>> {\n const maxAttempts = options.allowRetry ? options.maxRetries + 1 : 1;\n let retryContext: RetryContext = {\n attempt: 0,\n maxAttempts,\n totalDelayMs: 0,\n };\n\n while (retryContext.attempt < maxAttempts) {\n retryContext = { ...retryContext, attempt: retryContext.attempt + 1 };\n\n this.logRetryAttempt(retryContext, task);\n\n const result = await this.executeTask(task, options);\n\n if (result.ok) {\n return ok({ response: result.value, retryCount: retryContext.attempt - 1 });\n }\n\n const error = result.error;\n retryContext = { ...retryContext, lastError: error };\n\n // Record failure with circuit breaker\n if (this.circuitBreaker !== null) {\n this.circuitBreaker.recordFailure(categorizeError(error));\n }\n\n // Check if error is retryable\n if (!this.shouldRetry(error, retryContext)) {\n return err(error);\n }\n\n // Calculate and apply backoff delay\n const delayMs = calculateBackoffDelay(\n retryContext.attempt,\n this.baseDelayMs,\n this.maxDelayMs\n );\n retryContext = { ...retryContext, totalDelayMs: retryContext.totalDelayMs + delayMs };\n\n this.logRetryDelay(retryContext, delayMs);\n await delay(delayMs);\n }\n\n return err(retryContext.lastError ?? this.createError('UNKNOWN', 'Max retries exceeded'));\n }\n\n private shouldRetry(error: CliError, context: RetryContext): boolean {\n // Don't retry if we've exhausted attempts\n if (context.attempt >= context.maxAttempts) {\n return false;\n }\n\n // Don't retry terminal errors\n if (!error.retryable) {\n return false;\n }\n\n // Don't retry if circuit breaker is open\n if (this.circuitBreaker?.getState() === 'open') {\n return false;\n }\n\n // Retry timeouts, rate limits, and connection errors\n return isRetryableError(error.code);\n }\n\n private logRetryAttempt(context: RetryContext, task: CliTask): void {\n if (context.attempt === 1) {\n this.adapterLogger.debug('Executing Gemini task', {\n contentLength: task.content.length,\n model: task.model ?? this.model,\n });\n } else {\n this.adapterLogger.info('Retrying Gemini task', {\n attempt: context.attempt,\n maxAttempts: context.maxAttempts,\n lastError: context.lastError?.code,\n });\n }\n }\n\n private logRetryDelay(context: RetryContext, delayMs: number): void {\n this.adapterLogger.debug('Backoff delay before retry', {\n attempt: context.attempt,\n delayMs: Math.round(delayMs),\n totalDelayMs: Math.round(context.totalDelayMs),\n });\n }\n}\n\n/** Creates a Gemini CLI adapter with reliability features. */\nexport function createGeminiAdapter(options?: GeminiConfig): GeminiCliAdapter {\n return new GeminiCliAdapter(options);\n}\n","/**\n * nexus-agents/cli-adapters - Codex CLI Response Parser\n *\n * Defensive parser for Codex CLI NDJSON output.\n * Handles version 0.7x.x output format.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: docs/research/cli-integration-architecture.md)\n */\n\nimport type { ICliResponseParser, TokenUsage } from '../types.js';\nimport { asRecord, extractNumberField } from '../../utils/type-coercion.js';\n\n/**\n * Codex CLI NDJSON event types.\n */\nexport type CodexEventType =\n | 'thread.started'\n | 'turn.started'\n | 'item.completed'\n | 'turn.completed';\n\n/**\n * Base Codex event structure.\n */\nexport interface CodexEvent {\n readonly type: CodexEventType;\n}\n\n/**\n * Thread started event.\n */\nexport interface CodexThreadStarted extends CodexEvent {\n readonly type: 'thread.started';\n readonly thread_id: string;\n}\n\n/**\n * Item completed event (contains response or reasoning).\n */\nexport interface CodexItemCompleted extends CodexEvent {\n readonly type: 'item.completed';\n readonly item: {\n readonly id: string;\n readonly type: string;\n readonly text: string;\n };\n}\n\n/**\n * Turn completed event (contains usage).\n */\nexport interface CodexTurnCompleted extends CodexEvent {\n readonly type: 'turn.completed';\n readonly usage?: {\n readonly input_tokens: number;\n readonly cached_input_tokens?: number;\n readonly output_tokens: number;\n };\n}\n\n/**\n * Aggregated Codex response from NDJSON stream.\n */\nexport interface CodexCliResponse {\n readonly threadId?: string;\n readonly messages: readonly string[];\n readonly reasoning: readonly string[];\n readonly usage?: TokenUsage;\n}\n\n/**\n * Parser for Codex CLI NDJSON output.\n * Implements defensive parsing - processes stream of events.\n */\nexport class CodexResponseParser implements ICliResponseParser<CodexCliResponse> {\n readonly name = 'codex-parser';\n readonly supportedVersionRange = '>=0.70.0 <1.0.0';\n\n /**\n * Parses complete Codex CLI NDJSON stream.\n */\n parse(raw: string): CodexCliResponse | null {\n const lines = raw.trim().split('\\n');\n let threadId: string | undefined;\n const messages: string[] = [];\n const reasoning: string[] = [];\n let usage: TokenUsage | undefined;\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n this.processLine(\n line,\n messages,\n reasoning,\n (id) => (threadId = id),\n (u) => (usage = u)\n );\n }\n\n if (messages.length === 0 && reasoning.length === 0) {\n return null;\n }\n\n return {\n messages,\n reasoning,\n ...(threadId !== undefined && { threadId }),\n ...(usage !== undefined && { usage }),\n };\n }\n\n /**\n * Processes a single NDJSON line.\n */\n private processLine(\n line: string,\n messages: string[],\n reasoning: string[],\n setThreadId: (id: string) => void,\n setUsage: (usage: TokenUsage) => void\n ): void {\n try {\n const event: unknown = JSON.parse(line);\n const record = asRecord(event);\n if (record === null) return;\n\n const eventType = record.type;\n\n if (eventType === 'thread.started') {\n const tid = record.thread_id;\n if (typeof tid === 'string') setThreadId(tid);\n } else if (eventType === 'item.completed') {\n this.processItemCompleted(record, messages, reasoning);\n } else if (eventType === 'turn.completed') {\n const usage = this.extractUsageFromEvent(record);\n if (usage !== null) setUsage(usage);\n }\n } catch (lineErr: unknown) {\n // Skip malformed NDJSON lines — capture for debuggability\n void lineErr;\n }\n }\n\n /**\n * Extracts just the response text (most stable field).\n * Concatenates all agent_message items.\n */\n extractResponse(raw: string): string | null {\n const parsed = this.parse(raw);\n if (parsed === null || parsed.messages.length === 0) {\n return null;\n }\n\n return parsed.messages.join('\\n');\n }\n\n /**\n * Extracts token usage from NDJSON stream.\n */\n extractUsage(raw: string): TokenUsage | null {\n const lines = raw.trim().split('\\n');\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n\n try {\n const event: unknown = JSON.parse(line);\n const record = asRecord(event);\n if (record === null) continue;\n\n if (record.type === 'turn.completed') {\n return this.extractUsageFromEvent(record);\n }\n } catch {\n continue;\n }\n }\n\n return null;\n }\n\n /**\n * Extracts session ID (thread_id) for resumption.\n */\n extractSessionId(raw: string): string | null {\n const lines = raw.trim().split('\\n');\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n\n try {\n const event: unknown = JSON.parse(line);\n const record = asRecord(event);\n if (record === null) continue;\n\n if (record.type === 'thread.started') {\n const threadId = record.thread_id;\n if (typeof threadId === 'string') {\n return threadId;\n }\n }\n } catch {\n continue;\n }\n }\n\n return null;\n }\n\n /**\n * Processes an item.completed event.\n */\n private processItemCompleted(\n record: Record<string, unknown>,\n messages: string[],\n reasoning: string[]\n ): void {\n const item = asRecord(record.item);\n if (item === null) return;\n\n const itemType = item.type;\n const text = item.text;\n\n if (typeof text !== 'string') return;\n\n if (itemType === 'agent_message') {\n messages.push(text);\n } else if (itemType === 'reasoning') {\n reasoning.push(text);\n }\n }\n\n /**\n * Extracts usage from a turn.completed event.\n */\n private extractUsageFromEvent(record: Record<string, unknown>): TokenUsage | null {\n const usage = asRecord(record.usage);\n if (usage === null) return null;\n\n const inputTokens = extractNumberField(usage, 'input_tokens');\n const outputTokens = extractNumberField(usage, 'output_tokens');\n\n if (inputTokens === null || outputTokens === null) {\n return null;\n }\n\n const cachedInputTokens = extractNumberField(usage, 'cached_input_tokens');\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n ...(cachedInputTokens !== null && { cachedInputTokens }),\n };\n }\n}\n","/**\n * nexus-agents/cli-adapters - Codex CLI Adapter Helpers\n *\n * CLI-specific helper functions for Codex subprocess adapter.\n * Model info lookups consolidated into config/model-config-helpers.ts (#886).\n */\n\nimport type { CliError, CliName, TokenUsage, CliResponse } from '../types.js';\n\n// -----------------------------------------------------------------------------\n// Legacy Fallback Defaults (for non-canonical models)\n// -----------------------------------------------------------------------------\n\n/** Legacy fallback values for Codex models not in the canonical registry. */\nexport const CODEX_LEGACY_DEFAULTS = {\n displayNames: {\n o3: 'O3',\n 'o3-mini': 'O3 Mini',\n 'o4-mini': 'O4 Mini',\n } as Readonly<Record<string, string>>,\n inputCosts: {\n o3: 10.0,\n 'o3-mini': 1.1,\n 'o4-mini': 1.1,\n } as Readonly<Record<string, number>>,\n outputCosts: {\n o3: 40.0,\n 'o3-mini': 4.4,\n 'o4-mini': 4.4,\n } as Readonly<Record<string, number>>,\n contextWindow: 400_000,\n maxOutput: 100_000,\n inputCost: 1.1,\n outputCost: 4.4,\n} as const;\n\n// -----------------------------------------------------------------------------\n// Error Handling\n// -----------------------------------------------------------------------------\n\n/** Error codes that are retryable. */\nconst RETRYABLE_ERROR_CODES: ReadonlySet<CliError['code']> = new Set([\n 'RATE_LIMITED',\n 'TIMEOUT',\n 'CONNECTION_ERROR',\n]);\n\n/** Creates a CLI error with appropriate retryable flag. */\nexport function createCodexError(\n code: CliError['code'],\n message: string,\n cli: CliName,\n cause?: Error\n): CliError {\n const retryable = RETRYABLE_ERROR_CODES.has(code);\n\n return {\n code,\n message,\n cli,\n retryable,\n ...(cause !== undefined && { cause }),\n };\n}\n\n// -----------------------------------------------------------------------------\n// Response Normalization\n// -----------------------------------------------------------------------------\n\n/** Normalizes CLI response to common format. */\nexport function normalizeCodexResponse(\n text: string,\n usage?: TokenUsage,\n extra?: Partial<CliResponse>\n): CliResponse {\n return {\n text,\n ...(usage !== undefined && { usage }),\n ...extra,\n };\n}\n\n// Re-export from canonical source for backward compatibility\nexport { delay } from '../../utils/async-utils.js';\n","/**\n * nexus-agents/cli-adapters - Codex CLI Adapter\n *\n * Subprocess-based adapter for Codex CLI.\n * Extends SubprocessCliAdapter to reuse retry logic, health checks,\n * version detection, and capacity tracking.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: Issue #1140 — Migrated to SubprocessCliAdapter base class)\n *\n * SECURITY: All spawn() calls use array-based args without shell: true.\n * User task content is passed as a single argv element (no shell interpolation).\n */\n\nimport type {\n ICliResponseParser,\n CliTask,\n ModelInfo,\n CliName,\n BaseAdapterOptions,\n} from '../types.js';\nimport { SubprocessCliAdapter, type CommandConfig } from '../subprocess-adapter.js';\nimport { CodexResponseParser } from '../parsers/codex-parser.js';\nimport { CODEX_LEGACY_DEFAULTS } from './codex-adapter-helpers.js';\nimport {\n getDefaultModelForCli,\n getCliModelName,\n buildModelInfo,\n} from '../../config/model-config-helpers.js';\n\n// Re-export CLI-specific helpers for backward compatibility\nexport { createCodexError, normalizeCodexResponse, delay } from './codex-adapter-helpers.js';\n\n/**\n * Codex CLI adapter using subprocess transport.\n *\n * Extends SubprocessCliAdapter which provides:\n * - Retry logic with exponential backoff\n * - Health checks with version compatibility\n * - Capacity tracking\n * - Subprocess spawn with timeout handling\n */\nexport class CodexCliAdapter extends SubprocessCliAdapter {\n readonly name: CliName = 'codex';\n protected readonly parser: ICliResponseParser = new CodexResponseParser();\n\n private readonly model: string;\n\n constructor(options?: BaseAdapterOptions) {\n super(options?.logger);\n this.model = options?.model ?? getCliModelName(getDefaultModelForCli('codex'));\n }\n\n /**\n * Gets Codex model information.\n * Resolves from canonical registry when possible, falls back to legacy lookup.\n */\n getModelInfo(): ModelInfo {\n const fromRegistry = buildModelInfo('codex', this.model);\n if (fromRegistry !== undefined) return fromRegistry;\n return {\n id: this.model,\n name: CODEX_LEGACY_DEFAULTS.displayNames[this.model] ?? this.model,\n contextWindow: CODEX_LEGACY_DEFAULTS.contextWindow,\n maxOutput: CODEX_LEGACY_DEFAULTS.maxOutput,\n costPerMillionInput:\n CODEX_LEGACY_DEFAULTS.inputCosts[this.model] ?? CODEX_LEGACY_DEFAULTS.inputCost,\n costPerMillionOutput:\n CODEX_LEGACY_DEFAULTS.outputCosts[this.model] ?? CODEX_LEGACY_DEFAULTS.outputCost,\n };\n }\n\n /**\n * Gets CLI command and arguments for execution.\n * Task content is passed as a positional argument (not via stdin).\n */\n protected getCommand(task: CliTask): CommandConfig {\n const args: string[] = ['exec'];\n\n // Add JSON output\n args.push('--json');\n\n // Add model only if specified (use CLI default otherwise)\n const model = task.model ?? this.model;\n if (model !== '') {\n args.push('-m', model);\n }\n\n // Add sandbox mode for safety (read-only by default)\n args.push('-s', 'read-only');\n\n // Skip git repo check for standalone prompts\n args.push('--skip-git-repo-check');\n\n // Add the task content (no JSON.stringify needed without shell: true)\n args.push(task.content);\n\n return { command: 'codex', args };\n }\n}\n","/**\n * nexus-agents/cli-adapters - Codex MCP Adapter\n *\n * MCP-based adapter for Codex CLI. Preferred transport for Codex integration.\n * Extends BaseCliAdapter to reuse retry logic, health checks, version\n * detection, and capacity tracking.\n *\n * (Source: Issue #1140 — Migrated to BaseCliAdapter base class)\n *\n * SECURITY: All spawn() calls use array-based args without shell interpolation.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport type {\n CliName,\n CliTransport,\n CliTask,\n CliResponse,\n CliError,\n ModelInfo,\n ExecutionOptions,\n BaseAdapterOptions,\n} from '../types.js';\nimport type { Result } from '../../core/index.js';\nimport { getErrorMessage, ok, err, getTimeProvider, createLogger } from '../../core/index.js';\nimport { BaseCliAdapter } from '../base-adapter.js';\n\nimport {\n CODEX_LEGACY_DEFAULTS,\n type McpToolResult,\n extractTextFromContent,\n createTimeout,\n determineErrorCode,\n} from './codex-mcp-adapter-helpers.js';\nimport {\n getDefaultModelForCli,\n getCliModelName,\n buildModelInfo,\n} from '../../config/model-config-helpers.js';\n\n/**\n * Codex CLI adapter using MCP transport.\n *\n * Extends BaseCliAdapter which provides:\n * - Retry logic with exponential backoff\n * - Health checks with version compatibility\n * - Capacity tracking\n * - Error creation helpers\n */\nexport class CodexMcpAdapter extends BaseCliAdapter {\n readonly name: CliName = 'codex';\n readonly transport: CliTransport = 'mcp';\n\n private readonly model: string;\n private client: Client | undefined;\n private mcpTransport: StdioClientTransport | undefined;\n private connected = false;\n\n constructor(options?: BaseAdapterOptions) {\n super(options?.logger ?? createLogger({ component: 'codex-mcp-adapter' }));\n this.model = options?.model ?? getCliModelName(getDefaultModelForCli('codex'));\n }\n\n /**\n * Gets Codex model information.\n * Resolves from canonical registry when possible, falls back to legacy lookup.\n */\n getModelInfo(): ModelInfo {\n const fromRegistry = buildModelInfo('codex', this.model);\n if (fromRegistry !== undefined) return fromRegistry;\n return {\n id: this.model,\n name: CODEX_LEGACY_DEFAULTS.displayNames[this.model] ?? this.model,\n contextWindow: CODEX_LEGACY_DEFAULTS.contextWindow,\n maxOutput: CODEX_LEGACY_DEFAULTS.maxOutput,\n costPerMillionInput:\n CODEX_LEGACY_DEFAULTS.inputCosts[this.model] ?? CODEX_LEGACY_DEFAULTS.inputCost,\n costPerMillionOutput:\n CODEX_LEGACY_DEFAULTS.outputCosts[this.model] ?? CODEX_LEGACY_DEFAULTS.outputCost,\n };\n }\n\n /**\n * Initializes the MCP connection to Codex.\n */\n async initialize(): Promise<void> {\n if (this.connected) {\n return;\n }\n\n this.initCapacityTracker();\n this.logger.debug('Initializing Codex MCP connection');\n\n try {\n this.mcpTransport = new StdioClientTransport({\n command: 'codex',\n args: ['mcp-server'],\n stderr: 'pipe',\n });\n\n this.client = new Client({ name: 'nexus-agents', version: '2.0.0' }, { capabilities: {} });\n await this.client.connect(this.mcpTransport);\n this.connected = true;\n this.initialized = true;\n this.logger.info('Codex MCP connection established');\n } catch (error) {\n this.connected = false;\n const connectionError = error instanceof Error ? error : new Error('Connection failed');\n this.logger.error('Failed to initialize Codex MCP connection', connectionError);\n throw error;\n }\n }\n\n /**\n * Executes a task via MCP client.\n * Called by BaseCliAdapter.execute() with retry handling.\n */\n async executeTask(\n _task: CliTask,\n options: Required<ExecutionOptions>\n ): Promise<Result<CliResponse, CliError>> {\n const startTime = getTimeProvider().now();\n\n if (this.client === undefined) {\n return err(this.createError('CONNECTION_ERROR', 'MCP client not initialized'));\n }\n\n try {\n const result = await Promise.race([\n this.callCodexTool(_task),\n createTimeout(options.timeoutMs),\n ]);\n\n if (result === null) {\n return err(this.createError('TIMEOUT', 'Execution timed out'));\n }\n\n return this.parseToolResult(result, startTime);\n } catch (error) {\n return this.handleExecutionError(error);\n }\n }\n\n /**\n * Calls the codex or codex-reply tool on Codex MCP server.\n * @see https://developers.openai.com/codex/mcp/\n */\n private async callCodexTool(task: CliTask): Promise<McpToolResult> {\n if (this.client === undefined) {\n throw new Error('Client not initialized');\n }\n\n const isReply = task.sessionId !== undefined && task.sessionId !== '';\n const toolName = isReply ? 'codex-reply' : 'codex';\n\n const baseArgs = {\n prompt: task.content,\n ...(task.model !== undefined && { model: task.model }),\n };\n\n const args = isReply\n ? { ...baseArgs, threadId: task.sessionId }\n : {\n ...baseArgs,\n sandbox: 'read-only' as const,\n 'approval-policy': 'on-failure' as const,\n };\n\n const result = await this.client.callTool({\n name: toolName,\n arguments: args,\n });\n\n return result as McpToolResult;\n }\n\n /**\n * Parses MCP tool result to CLI response.\n */\n private parseToolResult(result: McpToolResult, startTime: number): Result<CliResponse, CliError> {\n if (result.isError === true) {\n const errorText = extractTextFromContent(result.content);\n return err(this.createError('EXECUTION_ERROR', errorText ?? 'Tool execution failed'));\n }\n\n const text = extractTextFromContent(result.content);\n if (text === null) {\n return err(this.createError('PARSE_ERROR', 'No text content in response'));\n }\n\n return ok({\n text,\n durationMs: getTimeProvider().now() - startTime,\n raw: result,\n });\n }\n\n /**\n * Handles execution errors.\n */\n private handleExecutionError(error: unknown): Result<CliResponse, CliError> {\n const message = getErrorMessage(error);\n const errorCode = determineErrorCode(message);\n\n if (errorCode === 'CONNECTION_ERROR') {\n this.connected = false;\n }\n\n return err(this.createError(errorCode, message, error as Error));\n }\n\n /**\n * Disposes the adapter and closes MCP connection.\n */\n async dispose(): Promise<void> {\n if (this.mcpTransport !== undefined) {\n this.logger.debug('Closing Codex MCP connection');\n await this.mcpTransport.close();\n this.mcpTransport = undefined;\n }\n this.client = undefined;\n this.connected = false;\n this.initialized = false;\n }\n}\n","/**\n * nexus-agents/cli-adapters - Codex MCP Adapter Helpers\n *\n * CLI-specific helper functions for Codex MCP adapter.\n * Model info lookups consolidated into config/model-config-helpers.ts (#886).\n *\n * (Source: cli-project_plan.md v2.1.0, Issue #90)\n */\n\nimport type { ExecutionOptions, CliError, CliName } from '../types.js';\nimport { CODEX_MCP_TIMEOUTS } from '../../config/timeouts.js';\n\n// Re-export legacy defaults from the subprocess helpers (DRY)\nexport { CODEX_LEGACY_DEFAULTS } from './codex-adapter-helpers.js';\n\n/**\n * Default execution options for Codex MCP.\n * Timeout and retry values derived from config/timeouts.ts (#1220).\n */\nexport const DEFAULT_CODEX_MCP_OPTIONS: Required<ExecutionOptions> = {\n timeoutMs: CODEX_MCP_TIMEOUTS.defaultMs,\n allowRetry: true,\n maxRetries: CODEX_MCP_TIMEOUTS.maxRetries,\n trackUsage: true,\n onProgress: undefined,\n};\n\n/**\n * MCP tool call result structure.\n */\nexport interface McpToolResult {\n content?: Array<{ type: string; text?: string }>;\n isError?: boolean;\n}\n\n// -----------------------------------------------------------------------------\n// Error Handling\n// -----------------------------------------------------------------------------\n\n/** Error codes that are retryable. */\nconst RETRYABLE_ERROR_CODES: ReadonlyArray<CliError['code']> = [\n 'RATE_LIMITED',\n 'TIMEOUT',\n 'CONNECTION_ERROR',\n];\n\n/** Checks if an error code is retryable. */\nexport function isRetryableErrorCode(code: CliError['code']): boolean {\n return RETRYABLE_ERROR_CODES.includes(code);\n}\n\n/** Creates a CLI error object. */\nexport function createCliError(\n code: CliError['code'],\n message: string,\n cli: CliName,\n cause?: Error\n): CliError {\n return {\n code,\n message,\n cli,\n retryable: isRetryableErrorCode(code),\n ...(cause !== undefined && { cause }),\n };\n}\n\n// -----------------------------------------------------------------------------\n// Content Extraction\n// -----------------------------------------------------------------------------\n\n/** Extracts text from MCP content array. */\nexport function extractTextFromContent(\n content?: Array<{ type: string; text?: string }>\n): string | null {\n if (content === undefined || content.length === 0) {\n return null;\n }\n\n const textContents = content\n .filter((c) => c.type === 'text' && c.text !== undefined)\n .map((c) => c.text as string);\n\n return textContents.length > 0 ? textContents.join('\\n') : null;\n}\n\n// Re-export from canonical source for backward compatibility\nexport { delay } from '../../utils/async-utils.js';\n\n/** Creates a timeout promise that resolves to null. */\nexport function createTimeout(ms: number): Promise<null> {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(null);\n }, ms);\n });\n}\n\n/** Determines error code from error message. */\nexport function determineErrorCode(message: string): CliError['code'] {\n if (message.includes('ENOENT') || message.includes('not found')) {\n return 'NOT_FOUND';\n }\n\n if (message.includes('timeout') || message.includes('ETIMEDOUT')) {\n return 'TIMEOUT';\n }\n\n if (message.includes('connection') || message.includes('disconnect')) {\n return 'CONNECTION_ERROR';\n }\n\n return 'EXECUTION_ERROR';\n}\n\n/** Parses version string from codex --version output. */\nexport function parseVersionFromOutput(output: string): string {\n const match = /(\\d+\\.\\d+\\.\\d+)/.exec(output.trim());\n return match?.[1] ?? '0.0.0';\n}\n","/**\n * nexus-agents/cli-adapters - OpenCode CLI Response Parser\n *\n * Defensive parser for OpenCode CLI JSON output.\n * Handles `opencode run --format json` NDJSON event stream.\n *\n * Real opencode v1.2.x NDJSON format (verified via E2E testing):\n * {\"type\":\"step_start\",\"sessionID\":\"ses_...\",\"part\":{\"type\":\"step-start\",...}}\n * {\"type\":\"text\",\"sessionID\":\"ses_...\",\"part\":{\"type\":\"text\",\"text\":\"Hello!\",...}}\n * {\"type\":\"step_finish\",\"sessionID\":\"ses_...\",\"part\":{\"type\":\"step-finish\",\"tokens\":{...},...}}\n *\n * (Source: Issue #1124, #1244, opencode.ai/docs/cli/)\n */\n\nimport type { ICliResponseParser, TokenUsage } from '../types.js';\nimport { asRecord, extractNumberField } from '../../utils/type-coercion.js';\n\n/**\n * OpenCode CLI NDJSON event types.\n * Includes both real v1.2.x types and legacy assumed types for compatibility.\n */\nexport type OpenCodeEventType =\n // Real opencode v1.2.x event types\n | 'step_start'\n | 'text'\n | 'step_finish'\n // Legacy assumed types (maintained for backward compatibility)\n | 'session.start'\n | 'message.start'\n | 'message.delta'\n | 'message.complete'\n | 'session.complete';\n\n/**\n * Aggregated OpenCode response from NDJSON stream.\n */\nexport interface OpenCodeCliResponse {\n readonly sessionId?: string;\n readonly content: string;\n readonly usage?: TokenUsage;\n}\n\n/**\n * Parser for OpenCode CLI JSON output.\n * Handles NDJSON event stream from `opencode run --format json`.\n *\n * Supports both real opencode v1.2.x format and legacy assumed format.\n */\nexport class OpenCodeResponseParser implements ICliResponseParser<OpenCodeCliResponse> {\n readonly name = 'opencode-parser';\n readonly supportedVersionRange = '>=1.0.0 <2.0.0';\n\n /**\n * Parses complete OpenCode CLI NDJSON stream.\n */\n parse(raw: string): OpenCodeCliResponse | null {\n const lines = raw.trim().split('\\n');\n let sessionId: string | undefined;\n const contentParts: string[] = [];\n let usage: TokenUsage | undefined;\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n this.processLine(\n line,\n contentParts,\n (id) => (sessionId = id),\n (u) => (usage = u)\n );\n }\n\n if (contentParts.length === 0) {\n // Fallback: try parsing as plain JSON (non-streaming mode)\n return this.parsePlainJson(raw);\n }\n\n const content = contentParts.join('');\n return {\n content,\n ...(sessionId !== undefined && { sessionId }),\n ...(usage !== undefined && { usage }),\n };\n }\n\n /**\n * Extracts just the response text.\n */\n extractResponse(raw: string): string | null {\n const parsed = this.parse(raw);\n if (parsed === null || parsed.content === '') {\n return null;\n }\n return parsed.content;\n }\n\n /**\n * Extracts token usage from response.\n */\n extractUsage(raw: string): TokenUsage | null {\n const lines = raw.trim().split('\\n');\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n try {\n const event: unknown = JSON.parse(line);\n const record = asRecord(event);\n if (record === null) continue;\n\n // Real format: step_finish with nested part.tokens\n if (record.type === 'step_finish') {\n const usage = this.extractUsageFromPart(record);\n if (usage !== null) return usage;\n }\n\n // Legacy format: session.complete or message.complete with usage field\n if (record.type === 'session.complete' || record.type === 'message.complete') {\n const usage = this.extractUsageFromRecord(record);\n if (usage !== null) return usage;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n }\n\n /**\n * Extracts session ID for resumption.\n */\n extractSessionId(raw: string): string | null {\n const lines = raw.trim().split('\\n');\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n const sid = this.extractSessionIdFromLine(line);\n if (sid !== null) return sid;\n }\n\n return null;\n }\n\n /** Extracts session ID from a single NDJSON line. */\n private extractSessionIdFromLine(line: string): string | null {\n try {\n const record = asRecord(JSON.parse(line) as unknown);\n if (record === null) return null;\n\n // Real format: sessionID at top level (step_start, text, step_finish)\n if (typeof record.sessionID === 'string') return record.sessionID;\n\n // Legacy format: session_id/sessionId in session events\n const sid = record.session_id ?? record.sessionId;\n if (typeof sid === 'string') return sid;\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Processes a single NDJSON line.\n * Handles both real v1.2.x format and legacy assumed format.\n */\n private processLine(\n line: string,\n contentParts: string[],\n setSessionId: (id: string) => void,\n setUsage: (usage: TokenUsage) => void\n ): void {\n try {\n const record = asRecord(JSON.parse(line) as unknown);\n if (record === null) return;\n\n switch (record.type) {\n // --- Real opencode v1.2.x event types ---\n case 'step_start':\n this.handleRealSessionId(record, setSessionId);\n break;\n case 'text':\n this.handleRealSessionId(record, setSessionId);\n this.pushRealTextContent(record, contentParts);\n break;\n case 'step_finish':\n this.handleRealSessionId(record, setSessionId);\n this.emitRealUsage(record, setUsage);\n break;\n\n // --- Legacy assumed event types ---\n case 'session.start':\n this.handleLegacySessionStart(record, setSessionId);\n break;\n case 'message.delta':\n this.pushLegacyTextContent(record, contentParts);\n break;\n case 'message.complete':\n this.pushLegacyTextContent(record, contentParts);\n this.emitLegacyUsage(record, setUsage);\n break;\n case 'session.complete':\n this.emitLegacyUsage(record, setUsage);\n break;\n }\n } catch (lineErr: unknown) {\n // Skip malformed NDJSON lines — capture for debuggability\n void lineErr;\n }\n }\n\n // --- Real v1.2.x format handlers ---\n\n /** Extracts sessionID from top-level field (real format). */\n private handleRealSessionId(\n record: Record<string, unknown>,\n setSessionId: (id: string) => void\n ): void {\n if (typeof record.sessionID === 'string') setSessionId(record.sessionID);\n }\n\n /** Extracts text from nested part.text field (real format). */\n private pushRealTextContent(record: Record<string, unknown>, parts: string[]): void {\n const part = asRecord(record.part);\n if (part === null) return;\n\n if (typeof part.text === 'string') parts.push(part.text);\n }\n\n /** Extracts usage from nested part.tokens field (real format). */\n private emitRealUsage(\n record: Record<string, unknown>,\n setUsage: (usage: TokenUsage) => void\n ): void {\n const usage = this.extractUsageFromPart(record);\n if (usage !== null) setUsage(usage);\n }\n\n /** Extracts usage from part.tokens (real opencode v1.2.x format). */\n private extractUsageFromPart(record: Record<string, unknown>): TokenUsage | null {\n const part = asRecord(record.part);\n if (part === null) return null;\n\n const tokens = asRecord(part.tokens);\n if (tokens === null) return null;\n\n const inputTokens = extractNumberField(tokens, 'input');\n const outputTokens = extractNumberField(tokens, 'output');\n\n if (inputTokens === null || outputTokens === null) return null;\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n };\n }\n\n // --- Legacy format handlers ---\n\n /** Extracts session ID from a session event record (legacy format). */\n private handleLegacySessionStart(\n record: Record<string, unknown>,\n setSessionId: (id: string) => void\n ): void {\n const sid = record.session_id ?? record.sessionId;\n if (typeof sid === 'string') setSessionId(sid);\n }\n\n /** Pushes text content from a message event (legacy format). */\n private pushLegacyTextContent(record: Record<string, unknown>, parts: string[]): void {\n const text = record.content ?? record.delta ?? record.text;\n if (typeof text === 'string') parts.push(text);\n }\n\n /** Emits usage from a record (legacy format). */\n private emitLegacyUsage(\n record: Record<string, unknown>,\n setUsage: (usage: TokenUsage) => void\n ): void {\n const usage = this.extractUsageFromRecord(record);\n if (usage !== null) setUsage(usage);\n }\n\n /**\n * Fallback parser for plain JSON output (non-streaming).\n */\n private parsePlainJson(raw: string): OpenCodeCliResponse | null {\n try {\n const data: unknown = JSON.parse(raw);\n const record = asRecord(data);\n if (record === null) return null;\n\n // Try common response field names\n const content = record.content ?? record.result ?? record.text ?? record.output;\n if (typeof content !== 'string') return null;\n\n const usage = this.extractUsageFromRecord(record);\n const sid = record.session_id ?? record.sessionId;\n\n return {\n content,\n ...(typeof sid === 'string' && { sessionId: sid }),\n ...(usage !== null && { usage }),\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Extracts usage from a record with usage/token fields (legacy format).\n */\n private extractUsageFromRecord(record: Record<string, unknown>): TokenUsage | null {\n const usage = asRecord(record.usage);\n if (usage === null) return null;\n\n const inputTokens =\n extractNumberField(usage, 'input_tokens') ?? extractNumberField(usage, 'inputTokens');\n const outputTokens =\n extractNumberField(usage, 'output_tokens') ?? extractNumberField(usage, 'outputTokens');\n\n if (inputTokens === null || outputTokens === null) return null;\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n };\n }\n}\n","/**\n * nexus-agents/cli-adapters - OpenCode CLI Adapter\n *\n * Subprocess-based adapter for OpenCode CLI.\n * Uses `opencode run --format json` for stable parsing.\n *\n * (Source: Issue #1124, opencode.ai/docs/cli/)\n */\n\nimport type {\n ICliResponseParser,\n CliTask,\n ModelInfo,\n CliName,\n BaseAdapterOptions,\n} from '../types.js';\nimport { SubprocessCliAdapter, type CommandConfig } from '../subprocess-adapter.js';\nimport { OpenCodeResponseParser } from '../parsers/opencode-parser.js';\nimport {\n getDefaultModelForCli,\n getCliModelName,\n buildModelInfo,\n} from '../../config/model-config-helpers.js';\n\n/** Strict allowlist for OpenCode --variant flag values. */\nconst ALLOWED_VARIANTS = ['high', 'max', 'minimal'];\n\n/**\n * OpenCode CLI adapter using subprocess transport.\n * Executes: opencode run --format json \"<task>\"\n */\nexport class OpenCodeCliAdapter extends SubprocessCliAdapter {\n readonly name: CliName = 'opencode';\n protected readonly parser: ICliResponseParser = new OpenCodeResponseParser();\n\n private readonly model: string;\n\n constructor(options?: BaseAdapterOptions) {\n super(options?.logger);\n this.model = options?.model ?? getCliModelName(getDefaultModelForCli('opencode'));\n }\n\n /**\n * Gets OpenCode model information from canonical registry.\n */\n getModelInfo(): ModelInfo {\n const fromRegistry = buildModelInfo('opencode', this.model);\n if (fromRegistry !== undefined) return fromRegistry;\n\n return {\n id: this.model,\n name: `OpenCode (${this.model})`,\n contextWindow: 200_000,\n maxOutput: 64_000,\n costPerMillionInput: 3.0,\n costPerMillionOutput: 15.0,\n };\n }\n\n /**\n * Gets CLI command and arguments for execution.\n * Uses `opencode run` with JSON format for stable parsing.\n */\n protected getCommand(task: CliTask): CommandConfig {\n const args: string[] = ['run', '--format', 'json'];\n\n // Add model selection\n const internalModel = task.model ?? this.model;\n args.push('--model', internalModel);\n\n // Add working directory if specified\n const workDir = task.options?.['workDir'];\n if (typeof workDir === 'string' && workDir.length > 0) {\n args.push('--dir', workDir);\n }\n\n // Add reasoning variant if specified (strict allowlist)\n const variant = task.options?.['variant'];\n if (typeof variant === 'string' && ALLOWED_VARIANTS.includes(variant)) {\n args.push('--variant', variant);\n }\n\n // Add thinking flag if specified (boolean only)\n if (task.options?.['thinking'] === true) {\n args.push('--thinking');\n }\n\n // Pass prompt as positional argument\n args.push(task.content);\n\n return { command: 'opencode', args };\n }\n}\n\n/**\n * Factory function for creating OpenCode adapter.\n */\nexport function createOpenCodeAdapter(options?: BaseAdapterOptions): OpenCodeCliAdapter {\n return new OpenCodeCliAdapter(options);\n}\n","/**\n * nexus-agents/cli-adapters - CLI Detection Cache\n *\n * Caches CLI health check results to avoid repeated subprocess calls.\n * Invalidates on circuit breaker trips or manual invalidation.\n *\n * @module cli-adapters/cli-detection-cache\n * (Source: Issue #165, Proposal adapter-architecture-review.md)\n */\n\nimport { z } from 'zod';\nimport { createLogger } from '../core/logger.js';\nimport type { ILogger } from '../core/index.js';\nimport { getTimeProvider } from '../core/index.js';\nimport type { CliName, HealthStatus, VersionStatus } from './types.js';\n\n/**\n * Cached health result for a CLI.\n */\nexport interface CliHealthResult {\n /** Whether the CLI is healthy and available */\n readonly healthy: boolean;\n /** CLI version detected */\n readonly version: string;\n /** Version compatibility status */\n readonly versionStatus: VersionStatus;\n /** When this result was captured */\n readonly checkedAt: Date;\n /** Optional status message */\n readonly message?: string | undefined;\n}\n\n/**\n * Configuration for the CLI detection cache.\n */\nexport interface CliDetectionCacheConfig {\n /** Time-to-live in milliseconds (default: 5 minutes) */\n readonly ttlMs: number;\n /** Logger instance */\n readonly logger?: ILogger | undefined;\n}\n\n/**\n * Zod schema for cache configuration validation.\n */\nexport const CliDetectionCacheConfigSchema = z.object({\n ttlMs: z.number().min(1000).max(3600_000).default(300_000),\n});\n\n/**\n * Default cache configuration.\n */\nexport const DEFAULT_CACHE_CONFIG: CliDetectionCacheConfig = {\n ttlMs: 300_000, // 5 minutes\n};\n\n/**\n * Interface for CLI detection cache.\n * Allows dependency injection for testing.\n */\nexport interface ICliDetectionCache {\n /** Get cached health result for a CLI */\n get(cli: CliName): CliHealthResult | undefined;\n\n /** Set health result for a CLI */\n set(cli: CliName, result: CliHealthResult): void;\n\n /** Check if cache entry is stale */\n isStale(cli: CliName): boolean;\n\n /** Invalidate cache for a specific CLI or all CLIs */\n invalidate(cli?: CliName): void;\n\n /** Get all cached results */\n getAll(): ReadonlyMap<CliName, CliHealthResult>;\n\n /** Get cache statistics */\n getStats(): CacheStats;\n}\n\n/**\n * Cache statistics for observability.\n */\nexport interface CacheStats {\n /** Number of cached entries */\n readonly size: number;\n /** Cache hits since last reset */\n readonly hits: number;\n /** Cache misses since last reset */\n readonly misses: number;\n /** Hit rate (0-1) */\n readonly hitRate: number;\n /** When stats were last reset */\n readonly lastReset: Date;\n}\n\n/**\n * CLI detection cache implementation.\n * Thread-safe for Node.js single-threaded execution.\n */\nexport class CliDetectionCache implements ICliDetectionCache {\n private readonly config: CliDetectionCacheConfig;\n private readonly logger: ILogger;\n private readonly cache: Map<CliName, CliHealthResult> = new Map();\n private hits = 0;\n private misses = 0;\n private lastReset: Date = new Date(getTimeProvider().now());\n\n constructor(config?: Partial<CliDetectionCacheConfig>) {\n const validated = CliDetectionCacheConfigSchema.parse({\n ttlMs: config?.ttlMs ?? DEFAULT_CACHE_CONFIG.ttlMs,\n });\n this.config = { ...validated, logger: config?.logger };\n this.logger = config?.logger ?? createLogger({ component: 'CliDetectionCache' });\n\n this.logger.debug('CliDetectionCache initialized', { ttlMs: this.config.ttlMs });\n }\n\n get(cli: CliName): CliHealthResult | undefined {\n const result = this.cache.get(cli);\n\n if (result === undefined) {\n this.misses++;\n this.logger.debug('Cache miss', { cli });\n return undefined;\n }\n\n if (this.isStale(cli)) {\n this.misses++;\n this.logger.debug('Cache stale', { cli, checkedAt: result.checkedAt });\n return undefined;\n }\n\n this.hits++;\n this.logger.debug('Cache hit', { cli, healthy: result.healthy });\n return result;\n }\n\n set(cli: CliName, result: CliHealthResult): void {\n this.cache.set(cli, result);\n this.logger.debug('Cache updated', {\n cli,\n healthy: result.healthy,\n version: result.version,\n });\n }\n\n isStale(cli: CliName): boolean {\n const result = this.cache.get(cli);\n if (result === undefined) return true;\n\n const age = getTimeProvider().now() - result.checkedAt.getTime();\n return age > this.config.ttlMs;\n }\n\n invalidate(cli?: CliName): void {\n if (cli !== undefined) {\n this.cache.delete(cli);\n this.logger.info('Cache invalidated', { cli });\n } else {\n this.cache.clear();\n this.logger.info('Cache cleared');\n }\n }\n\n getAll(): ReadonlyMap<CliName, CliHealthResult> {\n return this.cache;\n }\n\n getStats(): CacheStats {\n const total = this.hits + this.misses;\n return {\n size: this.cache.size,\n hits: this.hits,\n misses: this.misses,\n hitRate: total > 0 ? this.hits / total : 0,\n lastReset: this.lastReset,\n };\n }\n\n /**\n * Resets cache statistics.\n */\n resetStats(): void {\n this.hits = 0;\n this.misses = 0;\n this.lastReset = new Date(getTimeProvider().now());\n this.logger.debug('Cache stats reset');\n }\n\n /**\n * Converts HealthStatus to CliHealthResult for caching.\n */\n static fromHealthStatus(status: HealthStatus): CliHealthResult {\n return {\n healthy: status.healthy,\n version: status.version,\n versionStatus: status.versionStatus,\n checkedAt: status.lastChecked,\n message: status.message,\n };\n }\n}\n\n/**\n * Creates a CLI detection cache instance.\n *\n * @param config - Optional cache configuration\n * @returns CLI detection cache\n *\n * @example\n * ```typescript\n * const cache = createCliDetectionCache({ ttlMs: 60_000 }); // 1 minute TTL\n * const result = cache.get('claude');\n * if (!result) {\n * const health = await adapter.healthCheck();\n * cache.set('claude', CliDetectionCache.fromHealthStatus(health));\n * }\n * ```\n */\nexport function createCliDetectionCache(\n config?: Partial<CliDetectionCacheConfig>\n): ICliDetectionCache {\n return new CliDetectionCache(config);\n}\n","/**\n * nexus-agents/cli-adapters - Adapter Factory\n *\n * Factory for creating CLI adapters based on configuration.\n * Supports optional caching of CLI health check results.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: Issue #90 - Codex MCP adapter)\n * (Source: Issue #165 - CLI detection cache)\n */\n\nimport type { ICliAdapter, CliName, CliTransport } from './types.js';\nimport { getTimeProvider } from '../core/index.js';\nimport { ClaudeCliAdapter } from './adapters/claude-adapter.js';\nimport { GeminiCliAdapter } from './adapters/gemini-adapter.js';\nimport { CodexCliAdapter } from './adapters/codex-adapter.js';\nimport { CodexMcpAdapter } from './adapters/codex-mcp-adapter.js';\nimport { OpenCodeCliAdapter } from './adapters/opencode-adapter.js';\nimport type { ILogger } from '../core/index.js';\nimport type { ICliDetectionCache } from './cli-detection-cache.js';\nimport { CliDetectionCache } from './cli-detection-cache.js';\n\n/**\n * Configuration for creating a CLI adapter.\n */\nexport interface CliAdapterConfig {\n /** Which CLI to use */\n readonly cli: CliName;\n /** Optional model override */\n readonly model?: string;\n /** Optional logger */\n readonly logger?: ILogger;\n /** Preferred transport (for Codex: 'mcp' or 'subprocess') */\n readonly transport?: CliTransport;\n}\n\n/**\n * Creates a CLI adapter based on configuration.\n *\n * @param config - Adapter configuration\n * @returns The configured CLI adapter\n * @throws Error if CLI name is not supported\n *\n * @example\n * ```typescript\n * const adapter = createCliAdapter({ cli: 'claude', model: 'claude-opus-4' });\n * const result = await adapter.execute({ content: 'Hello!' });\n * ```\n */\nexport function createCliAdapter(config: CliAdapterConfig): ICliAdapter {\n const options = {\n ...(config.model !== undefined && { model: config.model }),\n ...(config.logger !== undefined && { logger: config.logger }),\n };\n\n switch (config.cli) {\n case 'claude':\n return new ClaudeCliAdapter(options);\n\n case 'gemini':\n return new GeminiCliAdapter(options);\n\n case 'codex':\n return createCodexAdapter(config.transport, options);\n\n case 'opencode':\n return new OpenCodeCliAdapter(options);\n\n default: {\n const exhaustiveCheck: never = config.cli;\n throw new Error(`Unsupported CLI: ${String(exhaustiveCheck)}`);\n }\n }\n}\n\n/**\n * Creates a Codex adapter with preferred transport.\n * Defaults to MCP transport (most stable).\n *\n * @param transport - Preferred transport ('mcp' or 'subprocess')\n * @param options - Adapter options\n * @returns Codex CLI adapter\n */\nfunction createCodexAdapter(\n transport: CliTransport | undefined,\n options: { model?: string; logger?: ILogger }\n): ICliAdapter {\n // Default to MCP transport (preferred per Issue #90)\n if (transport === 'subprocess') {\n return new CodexCliAdapter(options);\n }\n return new CodexMcpAdapter(options);\n}\n\n/**\n * Creates all available CLI adapters.\n * Uses MCP transport for Codex by default (preferred).\n *\n * @param logger - Optional shared logger\n * @param codexTransport - Transport for Codex (default: 'mcp')\n * @returns Map of CLI name to adapter\n */\nexport function createAllAdapters(\n logger?: ILogger,\n codexTransport: CliTransport = 'mcp'\n): Map<CliName, ICliAdapter> {\n const adapters = new Map<CliName, ICliAdapter>();\n const options = logger !== undefined ? { logger } : undefined;\n\n adapters.set('claude', new ClaudeCliAdapter(options));\n adapters.set('gemini', new GeminiCliAdapter(options));\n adapters.set('codex', createCodexAdapter(codexTransport, options ?? {}));\n adapters.set('opencode', new OpenCodeCliAdapter(options));\n\n return adapters;\n}\n\n/**\n * Checks if a CLI is available by running a health check.\n * Uses cache if provided to avoid repeated subprocess calls.\n *\n * @param cli - CLI name to check\n * @param cache - Optional cache to use\n * @returns True if CLI is healthy\n */\nexport async function isCliAvailable(cli: CliName, cache?: ICliDetectionCache): Promise<boolean> {\n // Check cache first\n if (cache !== undefined) {\n const cached = cache.get(cli);\n if (cached !== undefined) {\n return cached.healthy;\n }\n }\n\n try {\n const adapter = createCliAdapter({ cli });\n const health = await adapter.healthCheck();\n\n // Store in cache if provided\n if (cache !== undefined) {\n cache.set(cli, CliDetectionCache.fromHealthStatus(health));\n }\n\n return health.healthy;\n } catch {\n // Store negative result in cache\n if (cache !== undefined) {\n cache.set(cli, {\n healthy: false,\n version: 'unknown',\n versionStatus: 'unsupported',\n checkedAt: new Date(getTimeProvider().now()),\n message: 'Health check failed',\n });\n }\n return false;\n }\n}\n\n/**\n * Gets all available CLIs by running health checks.\n * Uses cache if provided to avoid repeated subprocess calls.\n *\n * @param cache - Optional cache to use\n * @returns Array of available CLI names\n */\nexport async function getAvailableClis(cache?: ICliDetectionCache): Promise<CliName[]> {\n const clis: CliName[] = ['claude', 'gemini', 'codex', 'opencode'];\n\n // Check all CLIs in parallel to avoid sequential timeout penalties\n const results = await Promise.allSettled(\n clis.map(async (cli) => ({ cli, available: await isCliAvailable(cli, cache) }))\n );\n\n return results\n .filter(\n (r): r is PromiseFulfilledResult<{ cli: CliName; available: boolean }> =>\n r.status === 'fulfilled' && r.value.available\n )\n .map((r) => r.value.cli);\n}\n","/**\n * nexus-agents/mcp - MCP Server\n *\n * Main MCP server implementation for Nexus Agents orchestration.\n * Provides factory functions to create and start the server with\n * stdio or custom transports.\n *\n * (Source: MCP Protocol 2025-11-25)\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\n\nimport {\n getErrorMessage,\n createLogger,\n type Result,\n ok,\n err,\n type ILogger,\n} from '../core/index.js';\nimport { VERSION } from '../version.js';\nimport { getTaskStore } from './task-store.js';\n\n/**\n * Server configuration options.\n */\nexport interface ServerConfig {\n /** Server name (default: \"nexus-agents\") */\n readonly name?: string;\n /** Server version (default: package version) */\n readonly version?: string;\n /** Logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Server creation result containing the server and logger.\n */\nexport interface ServerInstance {\n /** The MCP server instance */\n readonly server: McpServer;\n /** The logger instance for this server */\n readonly logger: ILogger;\n}\n\n/**\n * Error type for server operations.\n */\nexport interface ServerError {\n code: 'SERVER_CREATION_FAILED' | 'SERVER_START_FAILED' | 'SERVER_STOP_FAILED';\n message: string;\n cause?: Error;\n}\n\nconst DEFAULT_SERVER_NAME = 'nexus-agents';\n\n/**\n * Creates a ServerError with the given code, message, and optional cause.\n */\nfunction createServerError(\n code: ServerError['code'],\n message: string,\n error: unknown\n): ServerError {\n const serverError: ServerError = { code, message };\n if (error instanceof Error) {\n serverError.cause = error;\n }\n return serverError;\n}\n\n/**\n * Creates a new MCP server instance.\n *\n * @param config - Optional server configuration\n * @returns Result containing the server instance or an error\n *\n * @example\n * ```typescript\n * const result = createServer({ name: 'my-server' });\n * if (result.ok) {\n * const { server, logger } = result.value;\n * // Register tools on server\n * }\n * ```\n */\nexport function createServer(config?: ServerConfig): Result<ServerInstance, ServerError> {\n const serverName = config?.name ?? DEFAULT_SERVER_NAME;\n const serverVersion = config?.version ?? VERSION;\n const logger = config?.logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n logger.info('Creating MCP server', {\n name: serverName,\n version: serverVersion,\n });\n\n const server = new McpServer(\n {\n name: serverName,\n version: serverVersion,\n },\n {\n capabilities: {\n logging: {},\n prompts: {},\n resources: {},\n tasks: {},\n },\n taskStore: getTaskStore(),\n }\n );\n\n logger.debug('MCP server created successfully');\n\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create MCP server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_CREATION_FAILED',\n `Failed to create MCP server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Connects the server to a transport.\n *\n * @param server - The MCP server instance\n * @param transport - The transport to connect to\n * @param logger - Logger for the operation\n * @returns Result indicating success or failure\n */\nexport async function connectTransport(\n server: McpServer,\n transport: Transport,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n log.info('Connecting server to transport');\n await server.connect(transport);\n log.debug('Server connected to transport successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to connect to transport', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to connect to transport: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Starts the MCP server with stdio transport.\n *\n * This is the main entry point for running the server as a standalone process.\n * The server will communicate over stdin/stdout using the MCP protocol.\n *\n * @param config - Optional server configuration\n * @returns Result indicating success or failure\n *\n * @example\n * ```typescript\n * const result = await startStdioServer();\n * if (!result.ok) {\n * console.error('Failed to start server:', result.error.message);\n * process.exit(1);\n * }\n * ```\n */\nexport async function startStdioServer(\n config?: ServerConfig\n): Promise<Result<ServerInstance, ServerError>> {\n const serverResult = createServer(config);\n if (!serverResult.ok) {\n return serverResult;\n }\n\n const { server, logger } = serverResult.value;\n\n try {\n logger.info('Starting stdio transport');\n const transport = new StdioServerTransport();\n\n const connectResult = await connectTransport(server, transport, logger);\n if (!connectResult.ok) {\n return connectResult;\n }\n\n logger.info('MCP server running with stdio transport');\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to start stdio server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to start stdio server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Gracefully closes the server connection.\n *\n * @param server - The MCP server to close\n * @param logger - Optional logger\n * @returns Result indicating success or failure\n */\nexport async function closeServer(\n server: McpServer,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n log.info('Closing MCP server');\n await server.close();\n log.info('MCP server closed successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to close server', error instanceof Error ? error : undefined);\n return err(\n createServerError('SERVER_STOP_FAILED', `Failed to close server: ${errorMessage}`, error)\n );\n }\n}\n","/**\n * Nexus-Agents Task Store — wraps SDK InMemoryTaskStore with security controls.\n *\n * Provides:\n * - TTL enforcement (max 10 minutes per task)\n * - Capacity cap (max 50 tasks, FIFO eviction when exceeded)\n * - Singleton access via `getTaskStore()`\n * - Periodic cleanup of expired tasks\n *\n * @module mcp/task-store\n * (Source: Issue #1298 — Layer 2 MCP Tasks async execution)\n */\n\nimport { InMemoryTaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport type { TaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport { createLogger } from '../core/index.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Maximum TTL for any task (10 minutes). */\nexport const MAX_TASK_TTL_MS = 600_000;\n\n/** Default TTL applied when none specified (5 minutes). */\nexport const DEFAULT_TASK_TTL_MS = 300_000;\n\n/** Maximum number of tasks before FIFO eviction. */\nexport const MAX_TASK_CAPACITY = 50;\n\n/** Interval for periodic cleanup of expired tasks (60 seconds). */\nconst CLEANUP_INTERVAL_MS = 60_000;\n\n// ============================================================================\n// Singleton\n// ============================================================================\n\nconst logger = createLogger({ component: 'task-store' });\n\nlet singletonStore: InMemoryTaskStore | undefined;\nlet cleanupTimer: ReturnType<typeof setInterval> | undefined;\n\n/**\n * Returns the singleton InMemoryTaskStore, creating it on first call.\n *\n * The SDK's InMemoryTaskStore handles TTL cleanup internally.\n * We enforce our MAX_TASK_TTL_MS via `clampTaskTtl()` at task creation\n * (done by the ToolTaskHandler, not the store itself).\n */\nexport function getTaskStore(): TaskStore {\n if (singletonStore === undefined) {\n singletonStore = new InMemoryTaskStore();\n logger.info('Task store created', { maxCapacity: MAX_TASK_CAPACITY });\n\n // Periodic cleanup: evict oldest tasks if capacity exceeded\n cleanupTimer = setInterval(() => {\n evictExcessTasks();\n }, CLEANUP_INTERVAL_MS);\n\n // Prevent cleanup timer from keeping Node alive\n if (typeof cleanupTimer === 'object' && 'unref' in cleanupTimer) {\n cleanupTimer.unref();\n }\n }\n return singletonStore;\n}\n\n/**\n * Clamps a requested TTL to the maximum allowed value.\n * Returns DEFAULT_TASK_TTL_MS if no TTL is specified or null.\n */\nexport function clampTaskTtl(requestedTtl?: number | null): number {\n if (requestedTtl === undefined || requestedTtl === null) {\n return DEFAULT_TASK_TTL_MS;\n }\n if (requestedTtl > MAX_TASK_TTL_MS) {\n logger.warn('Task TTL clamped to maximum', {\n requested: requestedTtl,\n max: MAX_TASK_TTL_MS,\n });\n return MAX_TASK_TTL_MS;\n }\n return requestedTtl;\n}\n\n/**\n * Evicts oldest tasks when capacity is exceeded (FIFO).\n * Best-effort — logs warnings but does not throw.\n */\nfunction evictExcessTasks(): void {\n if (singletonStore === undefined) return;\n\n const allTasks = singletonStore.getAllTasks();\n if (allTasks.length <= MAX_TASK_CAPACITY) return;\n\n // Sort by creation time ascending (oldest first)\n const sorted = [...allTasks].sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n );\n\n const evictCount = sorted.length - MAX_TASK_CAPACITY;\n for (let i = 0; i < evictCount; i++) {\n const task = sorted[i];\n if (task === undefined) continue;\n singletonStore\n .updateTaskStatus(task.taskId, 'cancelled', 'Evicted: capacity exceeded')\n .catch((err: unknown) => {\n logger.debug('Failed to evict task', {\n taskId: task.taskId,\n error: String(err),\n });\n });\n }\n\n logger.info('Evicted excess tasks', { evicted: evictCount, total: sorted.length });\n}\n\n/**\n * Shuts down the task store and cleanup timer.\n * Call during server shutdown. Safe to call multiple times.\n * @internal\n */\nexport function shutdownTaskStore(): void {\n if (cleanupTimer !== undefined) {\n clearInterval(cleanupTimer);\n cleanupTimer = undefined;\n }\n if (singletonStore !== undefined) {\n singletonStore.cleanup();\n singletonStore = undefined;\n logger.info('Task store shut down');\n }\n}\n\n/** Resets the singleton for testing. @internal */\nexport function resetTaskStore(): void {\n shutdownTaskStore();\n}\n","/**\n * nexus-agents/utils - Text Processing Utilities\n *\n * Shared utility functions for text tokenization and processing.\n * Consolidates duplicate code from multiple modules per ADR-0013.\n *\n * Used by:\n * - context/agentic-memory-extraction.ts\n * - context/adaptive-memory-helpers.ts\n * - cli-adapters/daao-feature-extraction.ts\n * - cli-adapters/agreement-cascade-helpers.ts\n *\n * @module utils/text-utils\n * @see docs/adr/0013-memory-helpers-consolidation.md\n */\n\n// ============================================================================\n// Stopwords\n// ============================================================================\n\n/**\n * Common English stopwords to filter from keyword extraction.\n */\nexport const STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'are',\n 'as',\n 'at',\n 'be',\n 'by',\n 'for',\n 'from',\n 'has',\n 'he',\n 'in',\n 'is',\n 'it',\n 'its',\n 'of',\n 'on',\n 'or',\n 'that',\n 'the',\n 'to',\n 'was',\n 'were',\n 'will',\n 'with',\n 'this',\n 'but',\n 'they',\n 'have',\n 'had',\n 'what',\n 'when',\n 'where',\n 'who',\n 'which',\n 'why',\n 'how',\n 'all',\n 'each',\n 'every',\n 'both',\n 'few',\n 'more',\n 'most',\n 'other',\n 'some',\n 'such',\n 'no',\n 'nor',\n 'not',\n 'only',\n 'own',\n 'same',\n 'so',\n 'than',\n 'too',\n 'very',\n 'can',\n 'just',\n 'should',\n 'now',\n 'i',\n 'you',\n 'we',\n 'me',\n 'my',\n 'your',\n 'our',\n 'their',\n 'him',\n 'her',\n 'them',\n 'his',\n 'hers',\n 'able',\n]);\n\n// ============================================================================\n// Tokenization\n// ============================================================================\n\n/**\n * Tokenize text into normalized words.\n *\n * Process:\n * 1. Convert to lowercase\n * 2. Replace non-alphanumeric characters with spaces\n * 3. Split on whitespace\n * 4. Filter tokens by minimum length\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of normalized tokens\n */\nexport function tokenize(text: string, minLength = 2): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length >= minLength);\n}\n\n/**\n * Tokenize text and return as a Set for fast lookups.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Set of normalized tokens\n */\nexport function tokenizeToSet(text: string, minLength = 2): Set<string> {\n return new Set(tokenize(text, minLength));\n}\n\n/**\n * Tokenize text with stopword filtering.\n *\n * @param text - Input text to tokenize\n * @param minLength - Minimum token length (default: 2)\n * @returns Array of tokens with stopwords removed\n */\nexport function tokenizeFiltered(text: string, minLength = 2): string[] {\n return tokenize(text, minLength).filter((t) => !STOPWORDS.has(t));\n}\n\n// ============================================================================\n// Value Stringification\n// ============================================================================\n\n/**\n * Convert a value to string for text processing.\n *\n * @param value - Value to stringify\n * @returns String representation\n */\nexport function stringifyValue(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value === null || value === undefined) return '';\n return JSON.stringify(value);\n}\n\n// ============================================================================\n// String Capitalization\n// ============================================================================\n\n/**\n * Capitalize the first character of a string.\n *\n * @param str - Input string\n * @returns String with first character uppercased\n * @example capitalize('hello') // 'Hello'\n */\nexport function capitalize(str: string): string {\n if (str.length === 0) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Capitalize the first character of each word in a string.\n *\n * @param str - Input string\n * @returns String with each word capitalized\n * @example capitalizeWords('hello world') // 'Hello World'\n */\nexport function capitalizeWords(str: string): string {\n return str\n .split(' ')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n/**\n * Convert a kebab-case string to Title Case.\n *\n * @param str - Kebab-case string\n * @returns Title Case string with hyphens replaced by spaces\n * @example capitalizeKebab('hello-world') // 'Hello World'\n */\nexport function capitalizeKebab(str: string): string {\n return str\n .split('-')\n .map((word) => capitalize(word))\n .join(' ');\n}\n\n// ============================================================================\n// Text Truncation\n// ============================================================================\n\n/**\n * Truncate text to a maximum length with a suffix.\n *\n * @param text - Input text\n * @param maxLength - Maximum length including suffix\n * @param suffix - Suffix to append when truncated (default: '...')\n * @returns Truncated text with suffix if needed\n * @example truncateText('hello world', 8) // 'hello...'\n */\nexport function truncateText(text: string, maxLength: number, suffix = '...'): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength - suffix.length) + suffix;\n}\n\n/**\n * Truncate text and include byte count information.\n * Commonly used for output truncation in CLI tools.\n *\n * @param text - Input text\n * @param maxLength - Maximum length before truncation marker\n * @returns Truncated text with byte count info\n * @example truncateWithInfo('hello world...', 5) // 'hello\\n... [truncated 9 bytes]'\n */\nexport function truncateWithInfo(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n const truncatedBytes = text.length - maxLength;\n return `${text.slice(0, maxLength)}\\n... [truncated ${String(truncatedBytes)} bytes]`;\n}\n\n/**\n * Truncate to the first sentence or a maximum length.\n * Useful for extracting descriptions from longer text.\n *\n * @param text - Input text\n * @param maxLength - Maximum length (default: 150)\n * @returns First sentence or truncated text\n * @example truncateSentence('Hello world. More text.', 150) // 'Hello world.'\n */\nexport function truncateSentence(text: string, maxLength = 150): string {\n // Find first sentence ending\n const sentenceEnd = text.search(/[.!?](?:\\s|$)/);\n if (sentenceEnd !== -1 && sentenceEnd < maxLength) {\n return text.slice(0, sentenceEnd + 1).trim();\n }\n // Fall back to truncation\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength).trim() + '...';\n}\n\n// ============================================================================\n// Line Splitting\n// ============================================================================\n\n/**\n * Split text into lines.\n * Handles both Unix (\\n) and Windows (\\r\\n) line endings.\n *\n * @param text - Input text to split\n * @returns Array of lines (may include empty strings)\n * @example splitLines('a\\nb\\nc') // ['a', 'b', 'c']\n * @example splitLines('a\\n\\nb') // ['a', '', 'b']\n */\nexport function splitLines(text: string): string[] {\n return text.split(/\\r?\\n/);\n}\n\n/**\n * Split text into non-empty lines.\n * Filters out empty lines and whitespace-only lines.\n *\n * @param text - Input text to split\n * @returns Array of non-empty lines\n * @example splitNonEmptyLines('a\\n\\nb\\n \\nc') // ['a', 'b', 'c']\n */\nexport function splitNonEmptyLines(text: string): string[] {\n return text\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\n/**\n * Split text into trimmed lines, preserving empty lines.\n * Trims each line but keeps empty lines in the output.\n *\n * @param text - Input text to split\n * @returns Array of trimmed lines\n * @example splitTrimmedLines(' a \\n\\n b ') // ['a', '', 'b']\n */\nexport function splitTrimmedLines(text: string): string[] {\n return text.split(/\\r?\\n/).map((line) => line.trim());\n}\n\n// ============================================================================\n// Sentence/Word Splitting\n// ============================================================================\n\n/**\n * Count the number of sentences in text.\n * Counts sentence-ending punctuation followed by space or end of string.\n *\n * @param text - Input text\n * @returns Number of sentences\n * @example countSentences('Hello world. How are you?') // 2\n */\nexport function countSentences(text: string): number {\n const matches = text.match(/[.!?]+(?:\\s|$)/g);\n return matches !== null ? matches.length : 0;\n}\n\n/**\n * Split text into sentences.\n * Splits on sentence-ending punctuation followed by space.\n *\n * @param text - Input text\n * @returns Array of sentences (trimmed)\n * @example splitSentences('Hello world. How are you?') // ['Hello world.', 'How are you?']\n */\nexport function splitSentences(text: string): string[] {\n // Split on sentence endings followed by space, keeping the punctuation\n return text\n .split(/(?<=[.!?])\\s+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Count the number of words in text.\n * Splits on whitespace and counts non-empty tokens.\n *\n * @param text - Input text\n * @returns Number of words\n * @example countWords('Hello world') // 2\n */\nexport function countWords(text: string): number {\n return text\n .trim()\n .split(/\\s+/)\n .filter((w) => w.length > 0).length;\n}\n"],"mappings":"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","names":["estimateTaskComplexity","logger","snippet","RATE_LIMIT_PATTERNS","delay","categorizeError","estimateTaskComplexity","categorizeError","logger","err","logger"]}
|