nexus-agents 2.55.0 → 2.56.0
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-HQ43NDJW.js → chunk-BPMQRYGU.js} +6 -109
- package/dist/chunk-BPMQRYGU.js.map +1 -0
- package/dist/chunk-C3FGEDD7.js +2520 -0
- package/dist/chunk-C3FGEDD7.js.map +1 -0
- package/dist/{chunk-KTJIEY77.js → chunk-EJLWDYK7.js} +1985 -3653
- package/dist/chunk-EJLWDYK7.js.map +1 -0
- package/dist/{chunk-JEKPVSC4.js → chunk-KGMC6F5D.js} +357 -13
- package/dist/chunk-KGMC6F5D.js.map +1 -0
- package/dist/chunk-NUBSJGQZ.js +14 -0
- package/dist/chunk-NUBSJGQZ.js.map +1 -0
- package/dist/{chunk-JERFBN73.js → chunk-PCMWLXT4.js} +6 -16
- package/dist/chunk-PCMWLXT4.js.map +1 -0
- package/dist/chunk-R66AWJJ7.js +120 -0
- package/dist/chunk-R66AWJJ7.js.map +1 -0
- package/dist/cli.d.ts +9 -1
- package/dist/cli.js +337 -213
- package/dist/cli.js.map +1 -1
- package/dist/{consensus-vote-NRPXA57O.js → consensus-vote-G6H532ME.js} +3 -2
- package/dist/index.js +35 -32
- package/dist/index.js.map +1 -1
- package/dist/{research-helpers-synthesize-TFZIXBX3.js → research-helpers-synthesize-E6WQLQKP.js} +3 -2
- package/dist/{setup-command-NGAJEWE4.js → setup-command-AV4MODEL.js} +5 -3
- package/dist/setup-custom-api-XAWKRDWV.js +107 -0
- package/dist/setup-custom-api-XAWKRDWV.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-HQ43NDJW.js.map +0 -1
- package/dist/chunk-JEKPVSC4.js.map +0 -1
- package/dist/chunk-JERFBN73.js.map +0 -1
- package/dist/chunk-KTJIEY77.js.map +0 -1
- package/dist/chunk-SY344FS5.js +0 -839
- package/dist/chunk-SY344FS5.js.map +0 -1
- /package/dist/{consensus-vote-NRPXA57O.js.map → consensus-vote-G6H532ME.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-TFZIXBX3.js.map → research-helpers-synthesize-E6WQLQKP.js.map} +0 -0
- /package/dist/{setup-command-NGAJEWE4.js.map → setup-command-AV4MODEL.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup-command.ts","../src/cli/setup-types.ts","../src/cli/setup-environment.ts","../src/cli/setup-mcp.ts","../src/cli/setup-rules.ts","../src/cli/setup-formatting.ts","../src/cli/setup-opencode.ts","../src/cli/setup-gemini.ts","../src/cli/setup-codex.ts","../src/cli/setup-wizard.ts","../src/cli/setup-permissions.ts","../src/cli/verify-command.ts"],"sourcesContent":["/* eslint-disable max-lines -- Cohesive setup command module (governance: 400-600 OK if cohesive) */\n/**\n * nexus-agents setup command\n *\n * Configures Claude CLI integration with nexus-agents MCP server.\n * Generates MCP configuration snippet and .rules/nexus-agents.md.\n *\n * @module cli/setup-command\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n * (Source: Issue #425 - Interactive setup wizard)\n */\n\nimport { existsSync } from 'node:fs';\nimport type { SetupOptions, SetupResult, SetupStep, EnvironmentInfo } from './setup-types.js';\nimport { SetupOptionsSchema } from './setup-types.js';\nimport { getTimeProvider, getErrorMessage } from '../core/index.js';\nimport {\n detectEnvironment,\n generateMcpSnippet,\n generateRulesContent,\n createRulesFile,\n getRulesFilePath,\n formatStatus,\n formatHeader,\n formatCodeBlock,\n isInteractive,\n configureMcpServer,\n // Hook configuration (Issue #416)\n configureHooks,\n generateHookSnippet,\n} from './setup-helpers.js';\nimport type { McpConfigResult, HookConfigResult } from './setup-helpers.js';\nimport { initDataDirectories } from './setup-data-dir.js';\nimport type { DataDirInitResult } from './setup-data-dir.js';\nimport { runConfigInitSync } from './setup-config.js';\nimport { detectOpenCodeCli, configureOpenCode } from './setup-opencode.js';\nimport { detectGeminiCli, configureGemini } from './setup-gemini.js';\nimport { detectCodexCli, configureCodex } from './setup-codex.js';\nimport { VERSION } from '../version.js';\nimport { runWizard } from './setup-wizard.js';\nimport { generatePermissionsSnippet, buildPermissionsBanner } from './setup-permissions.js';\n// #2137: post-setup health gate. Surfaces install-time issues that are easy\n// to miss (better-sqlite3 native build, missing API keys, unwritable data\n// dirs) inline at the end of setup, with copy-pasteable remediation.\nimport { runVerify } from './verify-command.js';\nimport { colors, symbols } from './ansi-output.js';\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\n/**\n * Writes a line to stdout.\n */\nfunction writeLine(text: string): void {\n process.stdout.write(text + '\\n');\n}\n\n/**\n * Writes an empty line.\n */\nfunction writeEmptyLine(): void {\n process.stdout.write('\\n');\n}\n\n/**\n * Prints MCP configuration result section.\n */\nfunction printMcpResult(mcpResult: McpConfigResult, snippet: string | undefined): void {\n writeLine(formatHeader('MCP Configuration'));\n writeLine('─'.repeat(40));\n if (mcpResult.success) {\n writeLine(mcpResult.message);\n writeLine('Run `/mcp` in Claude Code to verify.');\n } else {\n writeLine(`Failed: ${mcpResult.message}`);\n if (snippet !== undefined) {\n writeEmptyLine();\n writeLine('Manual fallback - run:');\n writeEmptyLine();\n writeLine(formatCodeBlock(`claude mcp add-json nexus-agents '${snippet}'`));\n }\n }\n writeEmptyLine();\n}\n\n/**\n * Prints rules file section.\n */\nfunction printRulesFile(rulesPath: string): void {\n writeLine(formatHeader('Rules File'));\n writeLine('─'.repeat(40));\n writeLine(`Created: ${rulesPath}`);\n writeLine('Claude will now have context about nexus-agents tools.');\n writeEmptyLine();\n}\n\n/**\n * Prints hooks configuration result section.\n * (Source: Issue #416)\n */\nfunction printHooksResult(hookResult: HookConfigResult, snippet: string | undefined): void {\n writeLine(formatHeader('Hooks Configuration'));\n writeLine('─'.repeat(40));\n if (hookResult.success) {\n writeLine(hookResult.message);\n writeLine('Hooks will track sessions, metrics, and validate tool use.');\n } else {\n writeLine(`Note: ${hookResult.message}`);\n if (snippet !== undefined) {\n writeEmptyLine();\n writeLine('Manual fallback - add to ~/.claude/settings.json:');\n writeEmptyLine();\n writeLine(formatCodeBlock(snippet));\n }\n }\n writeEmptyLine();\n}\n\n/**\n * Prints warnings section.\n */\nfunction printWarnings(warnings: readonly string[]): void {\n writeLine(formatHeader('Warnings'));\n writeLine('─'.repeat(40));\n for (const warning of warnings) {\n writeLine(`⚠ ${warning}`);\n }\n writeEmptyLine();\n}\n\n/**\n * Prints errors section.\n */\nfunction printErrors(errors: readonly string[]): void {\n writeLine(formatHeader('Errors'));\n writeLine('─'.repeat(40));\n for (const error of errors) {\n writeLine(`✗ ${error}`);\n }\n writeEmptyLine();\n}\n\n/**\n * Prints next steps section.\n */\nfunction printNextSteps(mcpConfigured: boolean, hasMcpSnippet: boolean): void {\n writeLine(formatHeader('Next Steps'));\n writeLine('─'.repeat(40));\n if (hasMcpSnippet && !mcpConfigured) {\n writeLine('1. Configure MCP manually (see above)');\n writeLine('2. Restart Claude Code');\n }\n writeLine('3. Run: nexus-agents doctor');\n writeLine('4. Try: nexus-agents orchestrate \"Hello World\"');\n writeEmptyLine();\n}\n\n/**\n * Prints steps with status indicators.\n */\nfunction printSteps(steps: readonly SetupStep[], verbose: boolean): void {\n for (const step of steps) {\n const status = formatStatus(step.status);\n const duration = step.durationMs !== undefined ? ` (${String(step.durationMs)}ms)` : '';\n writeLine(`${status} ${step.name}${verbose ? duration : ''}`);\n if (step.message !== undefined && (verbose || step.status === 'failed')) {\n writeLine(` ${step.message}`);\n }\n }\n writeEmptyLine();\n}\n\n/**\n * Prints result summary line.\n */\nfunction printSummary(success: boolean): void {\n const summary = success ? '✓ Setup completed successfully!' : '✗ Setup completed with errors';\n writeLine(success ? `\\x1b[32m${summary}\\x1b[0m` : `\\x1b[31m${summary}\\x1b[0m`);\n writeEmptyLine();\n}\n\n// ============================================================================\n// Setup Steps\n// ============================================================================\n\n/**\n * Runs the environment detection step.\n */\nfunction runDetectionStep(projectRoot: string): { env: EnvironmentInfo; step: SetupStep } {\n const time = getTimeProvider();\n const startTime = time.now();\n const env = detectEnvironment(projectRoot);\n\n return {\n env,\n step: {\n name: 'Environment Detection',\n status: 'success',\n message: `Platform: ${env.platform}, Claude CLI: ${env.claudeCli.installed ? (env.claudeCli.version ?? 'installed') : 'not found'}`,\n durationMs: time.now() - startTime,\n },\n };\n}\n\n/** Minimum Node.js major version required. */\nconst REQUIRED_NODE_MAJOR = 22;\n\n/**\n * Runs the prerequisite validation step.\n * Checks Node.js version and warns about missing package managers.\n */\nfunction runPrerequisiteStep(): { step: SetupStep; warnings: readonly string[] } {\n const time = getTimeProvider();\n const startTime = time.now();\n const warnings: string[] = [];\n\n const version = process.version;\n const major = Number(version.slice(1).split('.')[0]);\n const nodeOk = major >= REQUIRED_NODE_MAJOR;\n\n if (!nodeOk) {\n warnings.push(\n `Node.js ${version} detected — v${String(REQUIRED_NODE_MAJOR)}.x+ required. Some features may not work.`\n );\n }\n\n const status = nodeOk ? 'success' : 'warning';\n const message = nodeOk\n ? `Node.js ${version} (meets v${String(REQUIRED_NODE_MAJOR)}.x requirement)`\n : `Node.js ${version} — v${String(REQUIRED_NODE_MAJOR)}.x+ required`;\n\n return {\n step: {\n name: 'Prerequisite Check',\n status,\n message,\n durationMs: time.now() - startTime,\n },\n warnings,\n };\n}\n\n/** MCP step result type. */\ntype McpStepResult = {\n step: SetupStep;\n snippet: string | undefined;\n mcpResult: McpConfigResult | undefined;\n};\n\n/** Creates an MCP step result. */\nfunction makeMcpResult(\n status: SetupStep['status'],\n message: string,\n startTime: number,\n snippet?: string,\n mcpResult?: McpConfigResult\n): McpStepResult {\n return {\n step: {\n name: 'MCP Configuration',\n status,\n message,\n durationMs: getTimeProvider().now() - startTime,\n },\n snippet,\n mcpResult,\n };\n}\n\n/**\n * Runs the MCP configuration step.\n */\nfunction runMcpConfigStep(env: EnvironmentInfo, options: SetupOptions): McpStepResult {\n const startTime = getTimeProvider().now();\n\n if (options.skipMcp) {\n return makeMcpResult('skipped', 'Skipped (--skip-mcp)', startTime);\n }\n\n const useNpx = !env.claudeCli.installed;\n const snippet = generateMcpSnippet(useNpx);\n\n if (!env.claudeCli.installed) {\n const mcpResult: McpConfigResult = {\n success: false,\n alreadyConfigured: false,\n message: 'Claude CLI not installed',\n };\n return makeMcpResult(\n 'warning',\n 'Claude CLI not found - manual configuration required',\n startTime,\n snippet,\n mcpResult\n );\n }\n\n const mcpResult = configureMcpServer(useNpx, options.force, options.scope);\n const status = mcpResult.success\n ? mcpResult.alreadyConfigured\n ? 'skipped'\n : 'success'\n : 'failed';\n return makeMcpResult(\n status,\n mcpResult.message,\n startTime,\n mcpResult.success ? undefined : snippet,\n mcpResult\n );\n}\n\n/** Creates a rules step result. */\nfunction makeRulesResult(\n status: SetupStep['status'],\n message: string,\n startTime: number,\n rulesPath?: string\n): { step: SetupStep; rulesPath: string | undefined } {\n return {\n step: { name: 'Rules File', status, message, durationMs: getTimeProvider().now() - startTime },\n rulesPath,\n };\n}\n\n/** Creates a hooks step result. */\nfunction makeHooksResult(\n status: SetupStep['status'],\n message: string,\n startTime: number,\n hookResult?: HookConfigResult\n): { step: SetupStep; hookSnippet: string | undefined; hookResult: HookConfigResult | undefined } {\n return {\n step: {\n name: 'Hooks Configuration',\n status,\n message,\n durationMs: getTimeProvider().now() - startTime,\n },\n hookSnippet: hookResult?.success === false ? generateHookSnippet() : undefined,\n hookResult,\n };\n}\n\n/**\n * Runs the rules file generation step.\n */\nfunction runRulesStep(\n env: EnvironmentInfo,\n options: SetupOptions\n): { step: SetupStep; rulesPath: string | undefined } {\n const startTime = getTimeProvider().now();\n\n if (options.skipRules) {\n return makeRulesResult('skipped', 'Skipped (--skip-rules)', startTime);\n }\n\n const rulesPath = getRulesFilePath(env.projectInfo.root);\n if (existsSync(rulesPath) && !options.force) {\n return makeRulesResult(\n 'skipped',\n 'Rules file already exists (use --force to overwrite)',\n startTime\n );\n }\n\n try {\n const createdPath = createRulesFile(env.projectInfo.root, options.dryRun);\n const msg = options.dryRun ? `Would create: ${createdPath}` : `Created: ${createdPath}`;\n return makeRulesResult('success', msg, startTime, createdPath);\n } catch (error) {\n const msg = getErrorMessage(error);\n return makeRulesResult('failed', `Failed to create rules file: ${msg}`, startTime);\n }\n}\n\n/**\n * Runs the hooks configuration step.\n * (Source: Issue #416 - Setup command hook configuration)\n */\nfunction runHooksStep(\n env: EnvironmentInfo,\n options: SetupOptions\n): { step: SetupStep; hookSnippet: string | undefined; hookResult: HookConfigResult | undefined } {\n const startTime = getTimeProvider().now();\n\n if (options.skipHooks) {\n return makeHooksResult('skipped', 'Skipped (--skip-hooks)', startTime);\n }\n\n // If Claude CLI is not installed, we can't configure automatically\n if (!env.claudeCli.installed) {\n return makeHooksResult(\n 'warning',\n 'Claude CLI not found - manual hook configuration required',\n startTime,\n {\n success: false,\n alreadyConfigured: false,\n message: 'Claude CLI not installed',\n }\n );\n }\n\n // If dry-run, just report what would happen\n if (options.dryRun) {\n return makeHooksResult(\n 'success',\n 'Would configure nexus-agents hooks in Claude Code settings',\n startTime\n );\n }\n\n // Configure using Claude CLI\n const hookResult = configureHooks(options.force);\n const status = hookResult.success\n ? hookResult.alreadyConfigured\n ? 'skipped'\n : 'success'\n : 'failed';\n\n return makeHooksResult(status, hookResult.message, startTime, hookResult);\n}\n\n/**\n * Runs the OpenCode MCP configuration step (#1253).\n */\nfunction runOpenCodeStep(options: SetupOptions): SetupStep {\n const startTime = getTimeProvider().now();\n if (options.skipOpencode) {\n return {\n name: 'OpenCode MCP',\n status: 'skipped',\n message: 'Skipped (--skip-opencode)',\n durationMs: 0,\n };\n }\n const cliInfo = detectOpenCodeCli();\n if (!cliInfo.installed) {\n return {\n name: 'OpenCode MCP',\n status: 'skipped',\n message: 'OpenCode CLI not installed',\n durationMs: getTimeProvider().now() - startTime,\n };\n }\n const result = configureOpenCode(options.force, options.dryRun);\n return {\n name: 'OpenCode MCP',\n status: result.success ? (result.alreadyConfigured ? 'skipped' : 'success') : 'failed',\n message: result.message,\n durationMs: getTimeProvider().now() - startTime,\n };\n}\n\n/**\n * Runs the Gemini CLI MCP configuration step (#1259).\n */\nfunction runGeminiStep(options: SetupOptions): SetupStep {\n const startTime = getTimeProvider().now();\n if (options.skipGemini) {\n return {\n name: 'Gemini MCP',\n status: 'skipped',\n message: 'Skipped (--skip-gemini)',\n durationMs: 0,\n };\n }\n const cliInfo = detectGeminiCli();\n if (!cliInfo.installed) {\n return {\n name: 'Gemini MCP',\n status: 'skipped',\n message: 'Gemini CLI not installed',\n durationMs: getTimeProvider().now() - startTime,\n };\n }\n const result = configureGemini(options.force, options.dryRun, options.scope);\n return {\n name: 'Gemini MCP',\n status: result.success ? (result.alreadyConfigured ? 'skipped' : 'success') : 'failed',\n message: result.message,\n durationMs: getTimeProvider().now() - startTime,\n };\n}\n\n/**\n * Runs the data directory initialization step (#1249).\n */\nfunction runDataDirStep(options: SetupOptions): { step: SetupStep; result: DataDirInitResult } {\n const startTime = getTimeProvider().now();\n const dataDirResult = initDataDirectories(options.dryRun);\n return {\n step: {\n name: 'Data Directory',\n status: dataDirResult.success\n ? dataDirResult.created.length > 0\n ? 'success'\n : 'skipped'\n : 'failed',\n message: dataDirResult.success\n ? dataDirResult.created.length > 0\n ? `Created ${String(dataDirResult.created.length)} directories`\n : 'All directories already exist'\n : `Failed: ${dataDirResult.error ?? 'Unknown error'}`,\n durationMs: getTimeProvider().now() - startTime,\n },\n result: dataDirResult,\n };\n}\n\n/**\n * Runs the Codex CLI MCP configuration step (#1263).\n */\nfunction runCodexStep(options: SetupOptions): SetupStep {\n const startTime = getTimeProvider().now();\n if (options.skipCodex) {\n return {\n name: 'Codex MCP',\n status: 'skipped',\n message: 'Skipped (--skip-codex)',\n durationMs: 0,\n };\n }\n const cliInfo = detectCodexCli();\n if (!cliInfo.installed) {\n return {\n name: 'Codex MCP',\n status: 'skipped',\n message: 'Codex CLI not installed',\n durationMs: getTimeProvider().now() - startTime,\n };\n }\n const result = configureCodex(options.force, options.dryRun);\n return {\n name: 'Codex MCP',\n status: result.success ? (result.alreadyConfigured ? 'skipped' : 'success') : 'failed',\n message: result.message,\n durationMs: getTimeProvider().now() - startTime,\n };\n}\n\n/**\n * Runs the config file generation step (#1252).\n */\nfunction runConfigStep(projectRoot: string, options: SetupOptions): SetupStep {\n const startTime = getTimeProvider().now();\n if (options.skipConfig) {\n return {\n name: 'Configuration',\n status: 'skipped',\n message: 'Skipped (--skip-config)',\n durationMs: 0,\n };\n }\n const result = runConfigInitSync(projectRoot, options.force, options.dryRun);\n return {\n name: 'Configuration',\n status: result.success ? (result.created ? 'success' : 'skipped') : 'failed',\n message: result.message,\n durationMs: getTimeProvider().now() - startTime,\n };\n}\n\n/** Checks a named step's status, returning a check or issue string. */\nfunction checkStepStatus(steps: readonly SetupStep[], name: string, label: string): string {\n const step = steps.find((s) => s.name === name);\n const ok = step?.status === 'success' || step?.status === 'skipped';\n return ok ? `${label} OK` : `${label} failed`;\n}\n\n/**\n * Runs post-setup validation step (#1271).\n * Checks that critical setup outcomes are in place.\n */\nfunction runValidationStep(steps: readonly SetupStep[]): SetupStep {\n const startTime = getTimeProvider().now();\n\n const mcpSteps = steps.filter((s) => s.name.includes('MCP'));\n const mcpFailed = mcpSteps.filter((s) => s.status === 'failed').length;\n const mcpCheck =\n mcpFailed > 0\n ? `${String(mcpFailed)} MCP config(s) failed`\n : `${String(mcpSteps.length)} MCP configs OK`;\n\n const results = [\n mcpCheck,\n checkStepStatus(steps, 'Data Directory', 'Data dirs'),\n checkStepStatus(steps, 'Configuration', 'Config'),\n ];\n const hasIssues = results.some((r) => r.includes('failed'));\n\n return {\n name: 'Validation',\n status: hasIssues ? 'warning' : 'success',\n message: `${results.join(', ')}. Run \\`nexus-agents doctor\\` for full health check`,\n durationMs: getTimeProvider().now() - startTime,\n };\n}\n\n// ============================================================================\n// Main Command Helpers\n// ============================================================================\n\n/**\n * Adds Claude CLI warnings if not installed.\n */\nfunction addClaudeCliWarnings(warnings: string[], installed: boolean): void {\n if (!installed) {\n warnings.push(\n 'Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code'\n );\n warnings.push('The MCP snippet uses npx to run nexus-agents (works without global install).');\n }\n}\n\n/**\n * Collects errors from failed steps.\n */\nfunction collectErrors(steps: readonly SetupStep[]): string[] {\n return steps.filter((s) => s.status === 'failed').map((s) => s.message ?? `${s.name} failed`);\n}\n\n/** Result context for building final result. */\ninterface SetupResultContext {\n startTime: number;\n steps: SetupStep[];\n warnings: string[];\n mcpResult: McpConfigResult | undefined;\n snippet: string | undefined;\n hookResult: HookConfigResult | undefined;\n hookSnippet: string | undefined;\n rulesPath: string | undefined;\n dataDirResult?: DataDirInitResult;\n}\n\n/** Checks if a config result represents a new (non-existing) success. */\nfunction isNewSuccess(result: McpConfigResult | HookConfigResult | undefined): boolean {\n return result?.success === true && !result.alreadyConfigured;\n}\n\n/** Builds the final setup result from context. */\nfunction buildSetupResult(ctx: SetupResultContext): SetupResult {\n const errors = collectErrors(ctx.steps);\n return {\n success: errors.length === 0,\n steps: ctx.steps,\n warnings: ctx.warnings,\n errors,\n durationMs: getTimeProvider().now() - ctx.startTime,\n ...(isNewSuccess(ctx.mcpResult) && { mcpConfigured: true }),\n ...(ctx.snippet !== undefined && { mcpSnippet: ctx.snippet }),\n ...(isNewSuccess(ctx.hookResult) && { hooksConfigured: true }),\n ...(ctx.hookSnippet !== undefined && { hookSnippet: ctx.hookSnippet }),\n ...(ctx.rulesPath !== undefined && { rulesPath: ctx.rulesPath }),\n ...(ctx.dataDirResult !== undefined && {\n dataDirPath: ctx.dataDirResult.rootPath,\n dataDirsCreated: ctx.dataDirResult.created.length,\n }),\n };\n}\n\n// ============================================================================\n// Main Command\n// ============================================================================\n\n/**\n * Runs the setup command.\n */\nexport function runSetup(options: Partial<SetupOptions> = {}): SetupResult {\n const startTime = getTimeProvider().now();\n const parsedOptions = SetupOptionsSchema.parse(options);\n const projectRoot = process.cwd();\n\n const warnings: string[] = [];\n\n // Step 1: Environment Detection\n const { env, step: detectionStep } = runDetectionStep(projectRoot);\n addClaudeCliWarnings(warnings, env.claudeCli.installed);\n\n // Step 2: Prerequisite Validation\n const { step: prereqStep, warnings: prereqWarnings } = runPrerequisiteStep();\n warnings.push(...prereqWarnings);\n\n // Step 3: MCP Configuration\n const { step: mcpStep, snippet, mcpResult } = runMcpConfigStep(env, parsedOptions);\n\n // Step 4: Rules File\n const { step: rulesStep, rulesPath } = runRulesStep(env, parsedOptions);\n\n // Step 5: Hooks Configuration (Issue #416)\n const { step: hooksStep, hookSnippet, hookResult } = runHooksStep(env, parsedOptions);\n\n // Step 6: Data Directory Initialization (#1249)\n const { step: dataDirStep, result: dataDirResult } = runDataDirStep(parsedOptions);\n\n // Step 7: OpenCode MCP Configuration (#1253)\n const openCodeStep = runOpenCodeStep(parsedOptions);\n\n // Step 8: Gemini MCP Configuration (#1259)\n const geminiStep = runGeminiStep(parsedOptions);\n\n // Step 9: Codex MCP Configuration (#1263)\n const codexStep = runCodexStep(parsedOptions);\n\n const configStep = runConfigStep(projectRoot, parsedOptions); // Step 10\n const steps = [\n detectionStep,\n prereqStep,\n mcpStep,\n rulesStep,\n hooksStep,\n dataDirStep,\n openCodeStep,\n geminiStep,\n codexStep,\n configStep,\n ];\n steps.push(runValidationStep(steps)); // Step 11: Validation (#1271)\n\n return buildSetupResult({\n startTime,\n steps,\n warnings,\n mcpResult,\n snippet,\n hookResult,\n hookSnippet,\n rulesPath,\n dataDirResult,\n });\n}\n\n/** Prints optional detail sections (MCP, hooks, rules, data dir). */\nfunction printDetailSections(result: SetupResult): void {\n if (result.mcpSnippet !== undefined || result.mcpConfigured === true) {\n const mcpResult: McpConfigResult =\n result.mcpConfigured === true\n ? {\n success: true,\n alreadyConfigured: false,\n message: 'Added nexus-agents MCP server to Claude Code',\n }\n : { success: false, alreadyConfigured: false, message: 'Manual configuration required' };\n printMcpResult(mcpResult, result.mcpSnippet);\n }\n if (result.hookSnippet !== undefined || result.hooksConfigured === true) {\n const hookResult: HookConfigResult =\n result.hooksConfigured === true\n ? {\n success: true,\n alreadyConfigured: false,\n message: 'Configured nexus-agents hooks in Claude Code settings',\n }\n : { success: false, alreadyConfigured: false, message: 'Manual configuration required' };\n printHooksResult(hookResult, result.hookSnippet);\n }\n if (result.rulesPath !== undefined) printRulesFile(result.rulesPath);\n if (result.dataDirPath !== undefined) printDataDirSection(result);\n printPermissionsSuggestion();\n}\n\n/** Prints the Claude Code permissions suggestion (#1945). */\nfunction printPermissionsSuggestion(): void {\n const snippet = generatePermissionsSnippet('all');\n const banner = buildPermissionsBanner(snippet);\n writeLine(banner);\n}\n\n/** Prints the data directory section. */\nfunction printDataDirSection(result: SetupResult): void {\n writeLine(formatHeader('Data Directory'));\n writeLine('─'.repeat(40));\n const count = result.dataDirsCreated ?? 0;\n const msg =\n count > 0\n ? `Created ${String(count)} directories under ${result.dataDirPath ?? ''}`\n : `All directories already exist at ${result.dataDirPath ?? ''}`;\n writeLine(msg);\n writeEmptyLine();\n}\n\n/**\n * Prints the setup result.\n */\nexport function printSetupResult(result: SetupResult, verbose: boolean): void {\n writeEmptyLine();\n writeLine(formatHeader(`Nexus Agents Setup v${VERSION}`));\n writeLine('═'.repeat(40));\n writeEmptyLine();\n\n printSteps(result.steps, verbose);\n printDetailSections(result);\n\n if (result.warnings.length > 0) printWarnings(result.warnings);\n if (result.errors.length > 0) printErrors(result.errors);\n printNextSteps(result.mcpConfigured === true, result.mcpSnippet !== undefined);\n printSummary(result.success);\n}\n\n/**\n * Prints the post-setup \"Getting Started\" banner (#2138).\n *\n * Three numbered steps tailored to what setup actually configured. If Claude\n * Code's MCP wiring succeeded we point step 2 at the integrated harness\n * (`/mcp` in Claude); otherwise we suggest the standalone `orchestrate`\n * command. Always shown after a successful setup — printing 3 lines is not\n * worth gating on first-run detection.\n *\n * @param mcpConfigured - True when an MCP harness (Claude/etc.) was wired up.\n */\nfunction printGettingStartedBanner(mcpConfigured: boolean): void {\n writeEmptyLine();\n writeLine(formatHeader('Getting started'));\n writeLine('─'.repeat(40));\n\n writeLine(' 1. nexus-agents hello — guided tour (no API keys needed)');\n if (mcpConfigured) {\n writeLine(' 2. Use through Claude Code — type /mcp in Claude to list tools');\n } else {\n writeLine(' 2. nexus-agents orchestrate \"...\" — run your first task');\n }\n writeLine(' 3. nexus-agents workflow list — explore built-in workflows');\n\n writeEmptyLine();\n writeLine(` ${colors.dim}Docs: https://github.com/williamzujkowski/nexus-agents${colors.reset}`);\n writeLine(` ${colors.dim}Harness wiring: docs/guides/HARNESS_COMPATIBILITY.md${colors.reset}`);\n}\n\n/**\n * Runs the post-setup health gate (#2137).\n *\n * After setup writes its files, this runs the verify checks and prints a\n * structured health summary inline. Returns `true` when no `severity: 'hard'`\n * checks failed — warnings still pass the gate.\n *\n * In `--dry-run` mode, the gate is skipped entirely (the user is previewing,\n * not actually installing).\n */\nasync function runPostSetupHealthGate(dryRun: boolean): Promise<boolean> {\n if (dryRun) return true;\n\n const result = await runVerify();\n const passed = result.checks.filter((c) => c.passed).length;\n const total = result.checks.length;\n\n writeEmptyLine();\n writeLine(formatHeader(`Health check (${String(passed)}/${String(total)} passed)`));\n writeLine('─'.repeat(40));\n\n for (const check of result.checks) {\n let symbol: string;\n if (check.passed) {\n symbol = `${colors.green}${symbols.check}${colors.reset}`;\n } else if (check.severity === 'warn') {\n symbol = `${colors.yellow}${symbols.warn}${colors.reset}`;\n } else {\n symbol = `${colors.red}${symbols.cross}${colors.reset}`;\n }\n writeLine(` ${symbol} ${check.name}: ${check.message}`);\n if (!check.passed && check.fix !== undefined) {\n writeLine(` ${colors.dim}→ Fix: ${check.fix}${colors.reset}`);\n }\n }\n\n writeEmptyLine();\n if (!result.noHardFailures) {\n writeLine(\n `${colors.red}${colors.bold}Action required: fix the blocking issues above before using nexus-agents.${colors.reset}`\n );\n } else if (!result.allPassed) {\n const warnCount = result.checks.filter((c) => !c.passed).length;\n writeLine(\n `${colors.yellow}${colors.bold}Setup complete with ${String(warnCount)} warning(s) — nexus-agents will run but some features are degraded.${colors.reset}`\n );\n } else {\n writeLine(\n `${colors.green}${colors.bold}All health checks passed. nexus-agents is ready.${colors.reset}`\n );\n }\n\n return result.noHardFailures;\n}\n\n/**\n * Setup command entry point (synchronous, non-interactive).\n *\n * @returns Exit code (0 = success, 1 = failure)\n */\nexport function setupCommand(options: Partial<SetupOptions> = {}): number {\n const parsedOptions = SetupOptionsSchema.parse(options);\n\n // Check for non-interactive mode in CI\n if (!isInteractive() && !parsedOptions.nonInteractive) {\n writeLine('Non-interactive environment detected.');\n writeLine('Run with --non-interactive or set CI=true.');\n return 1;\n }\n\n const result = runSetup(options);\n printSetupResult(result, parsedOptions.verbose);\n\n return result.success ? 0 : 1;\n}\n\n/** Extended options including interactive flag. */\nexport interface SetupCommandOptions extends Partial<SetupOptions> {\n interactive?: boolean;\n}\n\n/**\n * Setup command entry point with interactive wizard support.\n * (Source: Issue #425 - Interactive setup wizard)\n *\n * Also runs the post-setup health gate (#2137): after the configuration\n * steps complete, calls into `runVerify()` to surface install-time issues\n * that are easy to miss but break things at runtime (better-sqlite3 native\n * build, data dir writability, missing API keys). Health-gate warnings do\n * NOT fail setup — only `severity: 'hard'` failures do.\n *\n * @returns Exit code (0 = setup + no hard health failures, 1 = either failed)\n */\n/**\n * Runs the interactive wizard branch and returns its exit code.\n * Extracted from `setupCommandAsync` to keep cyclomatic complexity ≤10.\n */\nasync function runInteractiveSetup(options: SetupCommandOptions): Promise<number> {\n const wizardOptions = await runWizard();\n if (wizardOptions === undefined) return 1; // User cancelled.\n\n const mergedOptions = { ...options, ...wizardOptions };\n delete mergedOptions.interactive;\n\n const result = runSetup(mergedOptions);\n printSetupResult(result, mergedOptions.verbose ?? false);\n const healthOk = await runPostSetupHealthGate(mergedOptions.dryRun ?? false);\n if (result.success && !(mergedOptions.dryRun ?? false)) {\n printGettingStartedBanner(result.mcpConfigured === true);\n }\n return result.success && healthOk ? 0 : 1;\n}\n\nexport async function setupCommandAsync(options: SetupCommandOptions = {}): Promise<number> {\n if (options.interactive === true) {\n return runInteractiveSetup(options);\n }\n\n // Sync setup, then run the health gate, then print the getting-started banner.\n const setupResult = runSetupAndPrint(options);\n const healthOk = await runPostSetupHealthGate(options.dryRun ?? false);\n if (setupResult.exitCode === 0 && !(options.dryRun ?? false)) {\n printGettingStartedBanner(setupResult.mcpConfigured);\n }\n // Hard health failures override a successful setup; warnings don't.\n return setupResult.exitCode !== 0 || !healthOk ? 1 : 0;\n}\n\n/**\n * Runs setupCommand and captures both the exit code and the\n * `mcpConfigured` signal we need for the banner. Wraps the existing\n * synchronous path without changing its signature.\n */\nfunction runSetupAndPrint(options: SetupCommandOptions): {\n exitCode: number;\n mcpConfigured: boolean;\n} {\n const parsedOptions = SetupOptionsSchema.parse(options);\n if (!isInteractive() && !parsedOptions.nonInteractive) {\n writeLine('Non-interactive environment detected.');\n writeLine('Run with --non-interactive or set CI=true.');\n return { exitCode: 1, mcpConfigured: false };\n }\n const result = runSetup(options);\n printSetupResult(result, parsedOptions.verbose);\n return { exitCode: result.success ? 0 : 1, mcpConfigured: result.mcpConfigured === true };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { generateMcpSnippet, generateRulesContent, detectEnvironment };\nexport { runWizard } from './setup-wizard.js';\nexport type { SetupOptions, SetupResult };\n// SetupCommandOptions is already exported via interface definition above\nexport type { WizardAnswers, UsageMode } from './setup-wizard.js';\n","/**\n * nexus-agents setup command types\n *\n * Type definitions for the user onboarding automation system.\n *\n * @module cli/setup-types\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n */\n\nimport { z } from 'zod';\nimport type { CommandResult } from '../core/index.js';\n\n/**\n * Setup command options schema.\n */\nexport const SetupOptionsSchema = z.object({\n /** Skip interactive prompts */\n nonInteractive: z.boolean().default(false),\n /** Overwrite existing configurations */\n force: z.boolean().default(false),\n /** Skip MCP configuration */\n skipMcp: z.boolean().default(false),\n /** Skip CLAUDE.md/rules generation */\n skipRules: z.boolean().default(false),\n /** Skip hooks configuration (Issue #416) */\n skipHooks: z.boolean().default(false),\n /** Skip config file generation (#1252) */\n skipConfig: z.boolean().default(false),\n /** Skip OpenCode MCP configuration (#1253) */\n skipOpencode: z.boolean().default(false),\n /** Skip Gemini CLI MCP configuration (#1259) */\n skipGemini: z.boolean().default(false),\n /** Skip Codex CLI MCP configuration (#1263) */\n skipCodex: z.boolean().default(false),\n /** Show what would be done without making changes */\n dryRun: z.boolean().default(false),\n /** Show detailed output */\n verbose: z.boolean().default(false),\n /** Target scope for MCP config */\n scope: z.enum(['user', 'project']).default('user'),\n});\n\nexport type SetupOptions = z.infer<typeof SetupOptionsSchema>;\n\n/**\n * Claude CLI detection result.\n */\nexport interface ClaudeCliInfo {\n readonly installed: boolean;\n readonly version: string | undefined;\n readonly configPath: string;\n readonly mcpJsonPath: string;\n}\n\n/**\n * Existing MCP configuration info.\n */\nexport interface McpConfigInfo {\n readonly exists: boolean;\n readonly path: string;\n readonly hasNexusAgents: boolean;\n readonly servers: readonly string[];\n}\n\n/**\n * MCP server configuration entry.\n */\nexport interface McpServerEntry {\n readonly command: string;\n readonly args?: readonly string[];\n readonly env?: Record<string, string>;\n}\n\n/**\n * MCP JSON configuration format.\n */\nexport interface McpJsonConfig {\n readonly mcpServers?: Record<string, McpServerEntry>;\n}\n\n/**\n * Project type detection.\n */\nexport type ProjectType =\n | 'typescript'\n | 'javascript'\n | 'python'\n | 'rust'\n | 'go'\n | 'java'\n | 'unknown';\n\n/**\n * Project information.\n */\nexport interface ProjectInfo {\n readonly root: string;\n readonly hasPackageJson: boolean;\n readonly hasClaudeMd: boolean;\n readonly hasClaudeRules: boolean;\n readonly hasNexusConfig: boolean;\n readonly projectType: ProjectType;\n readonly packageName?: string;\n}\n\n/**\n * Complete environment information.\n */\nexport interface EnvironmentInfo {\n readonly platform: NodeJS.Platform;\n readonly homeDir: string;\n readonly claudeCli: ClaudeCliInfo;\n readonly existingMcpConfig: McpConfigInfo | undefined;\n readonly projectInfo: ProjectInfo;\n}\n\n/**\n * Setup step status.\n */\nexport interface SetupStep {\n readonly name: string;\n readonly status: 'pending' | 'success' | 'skipped' | 'failed' | 'warning';\n readonly message?: string;\n readonly durationMs?: number;\n}\n\n/**\n * Setup result summary.\n * Extends CommandResult base pattern (Issue #584).\n */\nexport interface SetupResult extends CommandResult {\n /** Setup steps executed */\n readonly steps: readonly SetupStep[];\n /** MCP configuration was successful via Claude CLI */\n readonly mcpConfigured?: boolean;\n /** Fallback MCP snippet for manual configuration */\n readonly mcpSnippet?: string;\n /** Hooks configuration was successful via Claude CLI (Issue #416) */\n readonly hooksConfigured?: boolean;\n /** Fallback hook snippet for manual configuration */\n readonly hookSnippet?: string;\n readonly rulesPath?: string;\n /** Data directory path if initialized (#1249) */\n readonly dataDirPath?: string;\n /** Number of data directories created (#1249) */\n readonly dataDirsCreated?: number;\n readonly warnings: readonly string[];\n readonly errors: readonly string[];\n readonly durationMs: number;\n}\n\n/**\n * Backup information for rollback.\n */\nexport interface BackupInfo {\n readonly type: 'file';\n readonly originalPath: string;\n readonly backupPath: string;\n readonly content: string;\n}\n\n/**\n * Rollback item types.\n */\nexport type RollbackItem =\n | { type: 'file-backup'; backup: BackupInfo }\n | { type: 'file-created'; path: string }\n | { type: 'file-modified'; backup: BackupInfo };\n","/**\n * nexus-agents setup environment detection\n *\n * Environment detection helpers for Claude CLI and project setup.\n *\n * @module cli/setup-environment\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n */\n\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, basename } from 'node:path';\nimport { CLI_SUBPROCESS_TIMEOUTS } from '../config/timeouts.js';\nimport type {\n ClaudeCliInfo,\n McpConfigInfo,\n ProjectInfo,\n ProjectType,\n EnvironmentInfo,\n} from './setup-types.js';\n\n/**\n * Parses Claude CLI version from output.\n */\nfunction parseClaudeVersion(output: string): string | undefined {\n const match = output.match(/(\\d+\\.\\d+\\.\\d+)/);\n return match?.[1];\n}\n\n/**\n * Detects if Claude CLI is installed and available.\n * Uses a 3-second timeout to avoid hanging in slow environments.\n */\nexport function detectClaudeCli(): ClaudeCliInfo {\n const configPath = join(homedir(), '.claude');\n const mcpJsonPath = join(homedir(), '.claude.json');\n\n try {\n const result = execSync('claude --version', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n timeout: CLI_SUBPROCESS_TIMEOUTS.envSetupMs,\n });\n const version = parseClaudeVersion(result);\n\n return {\n installed: true,\n version,\n configPath,\n mcpJsonPath,\n };\n } catch {\n return {\n installed: false,\n version: undefined,\n configPath,\n mcpJsonPath,\n };\n }\n}\n\n/** Extracts MCP servers from direct mcpServers key (project-scoped .mcp.json). */\nfunction extractDirectServers(config: Record<string, unknown>): string[] | undefined {\n const mcpServers = config['mcpServers'] as Record<string, unknown> | undefined;\n if (mcpServers === undefined) return undefined;\n return Object.keys(mcpServers);\n}\n\n/** Extracts MCP servers from projects key (~/.claude.json format). */\nfunction extractProjectServers(config: Record<string, unknown>): string[] | undefined {\n const projects = config['projects'] as Record<string, Record<string, unknown>> | undefined;\n if (projects === undefined) return undefined;\n const allServers = new Set<string>();\n for (const proj of Object.values(projects)) {\n const mcpServers = proj['mcpServers'] as Record<string, unknown> | undefined;\n if (mcpServers !== undefined) Object.keys(mcpServers).forEach((n) => allServers.add(n));\n }\n return [...allServers];\n}\n\n/** Builds McpConfigInfo from a server list. */\nfunction buildMcpInfo(path: string, servers: string[]): McpConfigInfo {\n return { exists: true, path, hasNexusAgents: servers.includes('nexus-agents'), servers };\n}\n\n/**\n * Detects existing MCP configuration.\n *\n * Handles two formats:\n * - `.mcp.json` (project-scoped): `{ mcpServers: { ... } }`\n * - `~/.claude.json` (user-scoped): `{ projects: { [path]: { mcpServers: { ... } } } }`\n */\nexport function detectMcpConfig(mcpJsonPath: string): McpConfigInfo | undefined {\n if (!existsSync(mcpJsonPath)) return undefined;\n try {\n const config = JSON.parse(readFileSync(mcpJsonPath, 'utf-8')) as Record<string, unknown>;\n const direct = extractDirectServers(config);\n if (direct !== undefined) return buildMcpInfo(mcpJsonPath, direct);\n const projected = extractProjectServers(config);\n if (projected !== undefined) return buildMcpInfo(mcpJsonPath, projected);\n return buildMcpInfo(mcpJsonPath, []);\n } catch {\n return buildMcpInfo(mcpJsonPath, []);\n }\n}\n\n/** Checks for TypeScript in package.json devDependencies. */\nfunction hasTypeScriptInPackageJson(root: string): boolean {\n try {\n const content = readFileSync(join(root, 'package.json'), 'utf-8');\n const parsed: unknown = JSON.parse(content);\n const pkg = parsed as Record<string, unknown>;\n const devDeps = pkg['devDependencies'] as Record<string, string> | undefined;\n return devDeps?.['typescript'] !== undefined;\n } catch {\n return false;\n }\n}\n\n/** Mapping of config files to project types. */\nconst CONFIG_FILE_TYPES: readonly [string, ProjectType][] = [\n ['tsconfig.json', 'typescript'],\n ['Cargo.toml', 'rust'],\n ['go.mod', 'go'],\n ['pyproject.toml', 'python'],\n ['setup.py', 'python'],\n ['pom.xml', 'java'],\n ['build.gradle', 'java'],\n];\n\n/**\n * Detects project type based on configuration files.\n */\nexport function detectProjectType(root: string): ProjectType {\n // Check config files\n for (const [file, type] of CONFIG_FILE_TYPES) {\n if (existsSync(join(root, file))) return type;\n }\n\n // Check package.json\n if (existsSync(join(root, 'package.json'))) {\n return hasTypeScriptInPackageJson(root) ? 'typescript' : 'javascript';\n }\n\n return 'unknown';\n}\n\n/**\n * Detects project information.\n */\nexport function detectProjectInfo(root: string): ProjectInfo {\n let packageName: string | undefined;\n\n if (existsSync(join(root, 'package.json'))) {\n try {\n const content = readFileSync(join(root, 'package.json'), 'utf-8');\n const pkg = JSON.parse(content) as Record<string, unknown>;\n const nameValue = pkg['name'];\n packageName = typeof nameValue === 'string' ? nameValue : undefined;\n } catch (parseErr: unknown) {\n // Non-critical: package.json parse failure, fall through to basename\n void parseErr;\n }\n }\n\n return {\n root,\n hasPackageJson: existsSync(join(root, 'package.json')),\n hasClaudeMd: existsSync(join(root, 'CLAUDE.md')),\n // Rules relocated in #2121: canonical is `.rules/`. Still accept the\n // legacy `.claude/rules/` path so detection doesn't break on repos that\n // haven't migrated yet.\n hasClaudeRules: existsSync(join(root, '.rules')) || existsSync(join(root, '.claude', 'rules')),\n hasNexusConfig: existsSync(join(root, 'nexus-agents.yaml')),\n projectType: detectProjectType(root),\n packageName: packageName ?? basename(root),\n };\n}\n\n/**\n * Detects complete environment information.\n */\nexport function detectEnvironment(projectRoot: string): EnvironmentInfo {\n const claudeCli = detectClaudeCli();\n const existingMcpConfig = detectMcpConfig(claudeCli.mcpJsonPath);\n const projectInfo = detectProjectInfo(projectRoot);\n\n return {\n platform: process.platform,\n homeDir: homedir(),\n claudeCli,\n existingMcpConfig,\n projectInfo,\n };\n}\n","/**\n * nexus-agents setup MCP configuration\n *\n * MCP configuration helpers using Claude CLI's `claude mcp` commands.\n *\n * @module cli/setup-mcp\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n */\n\nimport { execSync, execFileSync } from 'node:child_process';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { McpJsonConfig, McpServerEntry } from './setup-types.js';\nimport { getErrorMessage } from '../core/index.js';\n\n/** MCP entry for nexus-agents */\nexport const NEXUS_AGENTS_MCP_ENTRY: McpServerEntry = {\n command: 'nexus-agents',\n args: ['--mode=server'],\n};\n\n/** MCP entry with npx for users who install globally */\nexport const NEXUS_AGENTS_MCP_NPX_ENTRY: McpServerEntry = {\n command: 'npx',\n args: ['-y', 'nexus-agents@latest', '--mode=server'],\n};\n\n/**\n * Result of MCP configuration attempt.\n */\nexport interface McpConfigResult {\n success: boolean;\n alreadyConfigured: boolean;\n message: string;\n}\n\n/**\n * Checks if nexus-agents MCP server is already configured in Claude CLI.\n */\nexport function isMcpServerConfigured(): boolean {\n try {\n const result = execSync('claude mcp get nexus-agents', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result.includes('nexus-agents');\n } catch {\n return false;\n }\n}\n\n/**\n * Maps scope option to Claude CLI `-s` flag value.\n */\nfunction scopeToFlag(scope: 'user' | 'project'): string {\n return scope === 'project' ? 'local' : 'user';\n}\n\n/**\n * Removes existing MCP server configuration if present.\n */\nfunction removeExistingMcpServer(scope: 'user' | 'project' = 'user'): void {\n try {\n execSync(`claude mcp remove nexus-agents -s ${scopeToFlag(scope)}`, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n } catch {\n // Ignore removal errors\n }\n}\n\n/**\n * Adds MCP server to Claude CLI.\n */\nfunction addMcpServer(useNpx: boolean, scope: 'user' | 'project' = 'user'): McpConfigResult {\n const entry = useNpx ? NEXUS_AGENTS_MCP_NPX_ENTRY : NEXUS_AGENTS_MCP_ENTRY;\n const jsonConfig = JSON.stringify(entry);\n const scopeLabel = scope === 'project' ? 'project' : 'global';\n\n try {\n execFileSync(\n 'claude',\n ['mcp', 'add-json', 'nexus-agents', jsonConfig, '-s', scopeToFlag(scope)],\n {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }\n );\n return {\n success: true,\n alreadyConfigured: false,\n message: `Added nexus-agents MCP server to Claude Code (${scopeLabel})`,\n };\n } catch (error) {\n const errorMsg = getErrorMessage(error);\n return {\n success: false,\n alreadyConfigured: false,\n message: `Failed to add MCP server: ${errorMsg}`,\n };\n }\n}\n\n/**\n * Configures nexus-agents MCP server using Claude CLI.\n *\n * Uses `claude mcp add-json` to register the server.\n * @param scope - 'user' for global (~/.claude/mcp.json), 'project' for local (.mcp.json)\n */\nexport function configureMcpServer(\n useNpx: boolean = false,\n force: boolean = false,\n scope: 'user' | 'project' = 'user'\n): McpConfigResult {\n const isConfigured = isMcpServerConfigured();\n\n // Check if already configured\n if (!force && isConfigured) {\n return {\n success: true,\n alreadyConfigured: true,\n message: 'nexus-agents MCP server already configured (use --force to reconfigure)',\n };\n }\n\n // Remove existing if forcing\n if (force && isConfigured) {\n removeExistingMcpServer(scope);\n }\n\n return addMcpServer(useNpx, scope);\n}\n\n/**\n * Generates MCP configuration snippet for manual setup (fallback).\n */\nexport function generateMcpSnippet(useNpx: boolean = false): string {\n const entry = useNpx ? NEXUS_AGENTS_MCP_NPX_ENTRY : NEXUS_AGENTS_MCP_ENTRY;\n const config: McpJsonConfig = {\n mcpServers: {\n 'nexus-agents': entry,\n },\n };\n\n return JSON.stringify(config, null, 2);\n}\n\n/**\n * Generates the full MCP config path based on scope.\n *\n * Claude Code uses:\n * - Project scope: `.mcp.json` in project root\n * - User scope: `~/.claude.json` (stores MCP config under `projects` key)\n */\nexport function getMcpJsonPath(scope: 'user' | 'project', projectRoot: string): string {\n if (scope === 'project') {\n return join(projectRoot, '.mcp.json');\n }\n return join(homedir(), '.claude.json');\n}\n\n// ============================================================================\n// Hook Configuration (Issue #411, #416)\n// ============================================================================\n\n/**\n * Generates hook configuration for Claude CLI settings.json.\n * (Source: Issue #411 - Claude CLI Hook Integration)\n */\nexport function generateHookConfig(): HookSettingsConfig {\n return {\n hooks: {\n SessionStart: [\n {\n hooks: [\n {\n type: 'command',\n command: 'nexus-agents hooks session-start',\n },\n ],\n },\n ],\n PreToolUse: [\n {\n matcher: 'Bash',\n hooks: [\n {\n type: 'command',\n command: 'nexus-agents hooks pre-tool --tool Bash --validate',\n },\n ],\n },\n ],\n PostToolUse: [\n {\n matcher: '*',\n hooks: [\n {\n type: 'command',\n command: 'nexus-agents hooks post-tool --track-metrics',\n },\n ],\n },\n ],\n Stop: [\n {\n hooks: [\n {\n type: 'command',\n command: 'nexus-agents hooks stop --check-tasks',\n },\n ],\n },\n ],\n },\n };\n}\n\n/**\n * Hook command entry structure.\n */\ninterface HookCommandEntry {\n type: 'command';\n command: string;\n}\n\n/**\n * Hook matcher entry structure.\n */\ninterface HookMatcherEntry {\n matcher?: string;\n hooks: HookCommandEntry[];\n}\n\n/**\n * Hook settings configuration structure.\n */\nexport interface HookSettingsConfig {\n hooks: {\n SessionStart?: HookMatcherEntry[];\n SessionEnd?: HookMatcherEntry[];\n PreToolUse?: HookMatcherEntry[];\n PostToolUse?: HookMatcherEntry[];\n Stop?: HookMatcherEntry[];\n };\n}\n\n/**\n * Result of hook configuration attempt.\n */\nexport interface HookConfigResult {\n success: boolean;\n alreadyConfigured: boolean;\n message: string;\n}\n\n/**\n * Checks if hooks are already configured in Claude CLI settings.\n */\nexport function areHooksConfigured(): boolean {\n try {\n const result = execSync('claude config get hooks', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n // If we get output that includes nexus-agents, hooks are configured\n return result.includes('nexus-agents');\n } catch {\n return false;\n }\n}\n\n/**\n * Reads existing hooks from Claude CLI settings.\n * Returns parsed hooks object or undefined if no hooks exist or parse fails.\n */\nexport function getExistingHooks(): HookSettingsConfig['hooks'] | undefined {\n try {\n const result = execSync('claude config get hooks', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n const trimmed = result.trim();\n if (!trimmed || trimmed === 'null' || trimmed === 'undefined') {\n return undefined;\n }\n return JSON.parse(trimmed) as HookSettingsConfig['hooks'];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Merges two hook arrays, combining entries without duplicating nexus-agents hooks.\n */\nfunction mergeHookArrays(\n existing: HookMatcherEntry[] | undefined,\n newHooks: HookMatcherEntry[]\n): HookMatcherEntry[] {\n if (!existing || existing.length === 0) {\n return newHooks;\n }\n\n // Filter out any existing nexus-agents hooks to avoid duplicates\n const filteredExisting = existing.filter((entry) => {\n return !entry.hooks.some((h) => h.command.startsWith('nexus-agents'));\n });\n\n // Combine existing (non-nexus) hooks with new nexus-agents hooks\n return [...filteredExisting, ...newHooks];\n}\n\n/**\n * Merges nexus-agents hooks with existing hooks configuration.\n * Preserves existing user hooks while adding/updating nexus-agents hooks.\n */\nexport function mergeHookConfigs(\n existing: HookSettingsConfig['hooks'] | undefined,\n newConfig: HookSettingsConfig['hooks']\n): HookSettingsConfig['hooks'] {\n if (!existing) {\n return newConfig;\n }\n\n const hookTypes = ['SessionStart', 'SessionEnd', 'PreToolUse', 'PostToolUse', 'Stop'] as const;\n\n const merged: HookSettingsConfig['hooks'] = {};\n\n for (const hookType of hookTypes) {\n const existingHooks = existing[hookType];\n const newHooks = newConfig[hookType];\n\n if (newHooks) {\n merged[hookType] = mergeHookArrays(existingHooks, newHooks);\n } else if (existingHooks) {\n merged[hookType] = existingHooks;\n }\n }\n\n return merged;\n}\n\n/**\n * Configures hooks in Claude CLI settings.\n * Uses `claude config set hooks` to register hook commands.\n * Merges with existing hooks instead of overwriting them (Issue #420).\n */\nexport function configureHooks(force: boolean = false): HookConfigResult {\n const isConfigured = areHooksConfigured();\n\n if (!force && isConfigured) {\n return {\n success: true,\n alreadyConfigured: true,\n message: 'Hooks already configured (use --force to reconfigure)',\n };\n }\n\n const nexusHookConfig = generateHookConfig();\n\n try {\n // Read existing hooks first to merge (Issue #420)\n const existingHooks = getExistingHooks();\n const mergedHooks = mergeHookConfigs(existingHooks, nexusHookConfig.hooks);\n\n // Use claude config set with merged hooks\n const configJson = JSON.stringify(mergedHooks);\n execFileSync('claude', ['config', 'set', 'hooks', configJson], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return {\n success: true,\n alreadyConfigured: false,\n message: existingHooks\n ? 'Merged nexus-agents hooks with existing hooks in Claude Code settings'\n : 'Configured nexus-agents hooks in Claude Code settings',\n };\n } catch (error) {\n const errorMsg = getErrorMessage(error);\n return {\n success: false,\n alreadyConfigured: false,\n message: `Failed to configure hooks: ${errorMsg}`,\n };\n }\n}\n\n/**\n * Generates hook configuration snippet for manual setup.\n */\nexport function generateHookSnippet(): string {\n const config = generateHookConfig();\n return JSON.stringify(config, null, 2);\n}\n","/**\n * nexus-agents setup rules generation\n *\n * Rules file and backup management helpers.\n *\n * @module cli/setup-rules\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n */\n\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { VERSION } from '../version.js';\nimport { getTimeProvider } from '../core/index.js';\nimport type { BackupInfo } from './setup-types.js';\n\n/**\n * Generates the nexus-agents rules file content.\n */\nexport function generateRulesContent(): string {\n return `# Nexus-Agents Integration\n\nThis project uses [nexus-agents](https://github.com/williamzujkowski/nexus-agents) v${VERSION} for multi-agent orchestration.\n\n## MCP Tools Available\n\nWhen running with MCP server mode, these tools are available:\n\n| Tool | Description |\n| ---- | ----------- |\n| \\`orchestrate\\` | Task orchestration with Orchestrator coordination |\n| \\`create_expert\\` | Dynamic expert agent creation |\n| \\`run_workflow\\` | Execute workflow templates |\n| \\`delegate_to_model\\` | Route task to optimal model |\n| \\`list_experts\\` | List available expert types (discoverability) |\n| \\`list_workflows\\` | List available workflow templates |\n\n## Quick Commands\n\n\\`\\`\\`bash\n# Orchestrate a task with specialized experts\nnexus-agents orchestrate \"Implement feature X with tests\"\n\n# List available experts\nnexus-agents expert list\n\n# Run a workflow\nnexus-agents workflow list\nnexus-agents workflow run code-review --input='{\"url\": \"...\"}'\n\n# Check system health\nnexus-agents doctor\n\n# Generate config\nnexus-agents config init\n\\`\\`\\`\n\n## Usage Examples\n\n**Orchestrate a code review:**\n\\`\\`\\`\nUse nexus-agents to review this PR: https://github.com/owner/repo/pull/123\n\\`\\`\\`\n\n**Create a specialized expert:**\n\\`\\`\\`\nCreate a security expert to audit this codebase for vulnerabilities\n\\`\\`\\`\n\n**Run a workflow:**\n\\`\\`\\`\nRun the code-review workflow with the current changes\n\\`\\`\\`\n\n## Configuration\n\n- Config file: \\`./nexus-agents.yaml\\`\n- Generate config: \\`nexus-agents config init\\`\n- Check health: \\`nexus-agents doctor\\`\n\n---\n*Generated by nexus-agents setup v${VERSION}*\n`;\n}\n\n/**\n * Gets the rules file path.\n *\n * As of #2121 rules live at `<root>/.rules/` (harness-neutral location,\n * was `.claude/rules/`). Claude Code finds them via CLAUDE.md references,\n * so the move doesn't break its auto-load. Non-Claude harnesses (OpenCode,\n * Codex, Cursor, etc.) can point at the same directory.\n */\nexport function getRulesFilePath(projectRoot: string): string {\n return join(projectRoot, '.rules', 'nexus-agents.md');\n}\n\n/**\n * Creates the rules file.\n */\nexport function createRulesFile(projectRoot: string, dryRun: boolean): string {\n const rulesPath = getRulesFilePath(projectRoot);\n const content = generateRulesContent();\n\n if (!dryRun) {\n const rulesDir = dirname(rulesPath);\n mkdirSync(rulesDir, { recursive: true });\n writeFileSync(rulesPath, content, 'utf-8');\n }\n\n return rulesPath;\n}\n\n/**\n * Creates a backup of a file.\n */\nexport function backupFile(filePath: string): BackupInfo {\n const content = readFileSync(filePath, 'utf-8');\n const backupPath = `${filePath}.backup.${String(getTimeProvider().now())}`;\n writeFileSync(backupPath, content, 'utf-8');\n\n return {\n type: 'file',\n originalPath: filePath,\n backupPath,\n content,\n };\n}\n\n/**\n * Restores a file from backup.\n */\nexport function restoreBackup(backup: BackupInfo): void {\n writeFileSync(backup.originalPath, backup.content, 'utf-8');\n}\n","/**\n * nexus-agents setup output formatting\n *\n * Output formatting helpers for setup command.\n * Re-exports from consolidated ansi-output.ts for backward compatibility.\n *\n * @module cli/setup-formatting\n * (Source: Issue #363 - Auto-configure Claude CLI integration)\n */\n\n// Re-export consolidated formatters from ansi-output.ts\nexport { formatStatus, formatHeader, formatCodeBlock, colors, symbols } from './ansi-output.js';\n\n/**\n * Checks if running in interactive mode.\n */\nexport function isInteractive(): boolean {\n if (!process.stdout.isTTY) return false;\n if (process.env['CI'] === 'true') return false;\n if (process.env['CONTINUOUS_INTEGRATION'] !== undefined) return false;\n return true;\n}\n","/**\n * OpenCode MCP auto-configuration for setup command.\n *\n * Detects OpenCode CLI and generates opencode.json/.jsonc with nexus-agents MCP server.\n * Supports JSONC (JSON with Comments) via `jsonc-parser` for comment-preserving writes.\n *\n * @module cli/setup-opencode\n * (Source: Issue #1253 - OpenCode MCP auto-configuration, #1255 - JSONC support)\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { execFileSync } from 'node:child_process';\nimport { join, resolve } from 'node:path';\nimport { homedir, platform } from 'node:os';\nimport { parse as jsoncParse, modify, applyEdits } from 'jsonc-parser';\nimport { getErrorMessage } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\n\nconst logger = createLogger({ component: 'setup-opencode' });\n\n/** OpenCode detection result. */\nexport interface OpenCodeCliInfo {\n readonly installed: boolean;\n readonly version: string | undefined;\n}\n\n/** OpenCode MCP configuration result. */\nexport interface OpenCodeConfigResult {\n readonly success: boolean;\n readonly alreadyConfigured: boolean;\n readonly message: string;\n readonly configPath: string;\n}\n\n/** Resolved config file info. */\nexport interface ResolvedConfig {\n readonly path: string;\n readonly isJsonc: boolean;\n readonly exists: boolean;\n}\n\n/**\n * Detects OpenCode CLI installation.\n */\nexport function detectOpenCodeCli(): OpenCodeCliInfo {\n try {\n const cmd = platform() === 'win32' ? 'where' : 'which';\n execFileSync(cmd, ['opencode'], { timeout: 3000, stdio: 'pipe' });\n } catch {\n return { installed: false, version: undefined };\n }\n\n try {\n const output = execFileSync('opencode', ['--version'], {\n timeout: 5000,\n stdio: 'pipe',\n encoding: 'utf-8',\n });\n const match = /(\\d+\\.\\d+\\.\\d+)/.exec(output);\n return { installed: true, version: match?.[1] };\n } catch {\n return { installed: true, version: undefined };\n }\n}\n\n/**\n * Resolves the OpenCode config directory path.\n * OpenCode uses ~/.config/opencode/ on Linux/macOS.\n */\nfunction getOpenCodeConfigDir(): string {\n return join(homedir(), '.config', 'opencode');\n}\n\n/**\n * Resolves the path for nexus-agents CLI command.\n * Uses `npx nexus-agents` for portability.\n */\nfunction getNexusCommand(): readonly string[] {\n return ['npx', 'nexus-agents', '--mode=server'];\n}\n\nconst NEXUS_MCP_ENTRY = {\n type: 'local',\n command: getNexusCommand(),\n enabled: true,\n};\n\n/**\n * Resolves the OpenCode config file in a directory.\n * Prefers .jsonc over .json (matching OpenCode's own priority).\n */\nexport function resolveOpenCodeConfig(dir: string): ResolvedConfig {\n const jsoncPath = join(dir, 'opencode.jsonc');\n if (existsSync(jsoncPath)) {\n return { path: jsoncPath, isJsonc: true, exists: true };\n }\n const jsonPath = join(dir, 'opencode.json');\n if (existsSync(jsonPath)) {\n return { path: jsonPath, isJsonc: false, exists: true };\n }\n return { path: jsonPath, isJsonc: false, exists: false };\n}\n\n/** Checks if nexus-agents is already configured in an existing config. */\nfunction isAlreadyConfigured(resolved: ResolvedConfig): boolean {\n if (!resolved.exists) return false;\n try {\n const raw = readFileSync(resolved.path, 'utf-8');\n const config = jsoncParse(raw) as Record<string, unknown> | null;\n const mcp = config?.['mcp'] as Record<string, unknown> | undefined;\n return mcp?.['nexus-agents'] !== undefined;\n } catch {\n logger.debug('Failed to parse existing OpenCode config, will overwrite');\n return false;\n }\n}\n\n/** Writes nexus-agents MCP entry using comment-preserving edits for JSONC. */\nfunction writeJsoncConfig(configPath: string, raw: string): void {\n let result = raw;\n result = applyEdits(result, modify(result, ['mcp', 'nexus-agents'], NEXUS_MCP_ENTRY, {}));\n result = applyEdits(result, modify(result, ['$schema'], 'https://opencode.ai/config.json', {}));\n writeFileSync(configPath, result, 'utf-8');\n}\n\n/** Writes nexus-agents MCP entry as plain JSON for new configs. */\nfunction writeJsonConfig(configPath: string): void {\n const config = {\n $schema: 'https://opencode.ai/config.json',\n mcp: { 'nexus-agents': NEXUS_MCP_ENTRY },\n };\n writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\n/** Writes the merged config with nexus-agents MCP entry. */\nfunction writeOpenCodeConfig(configDir: string, resolved: ResolvedConfig): void {\n if (!existsSync(configDir)) mkdirSync(configDir, { recursive: true });\n\n if (resolved.exists) {\n const raw = readFileSync(resolved.path, 'utf-8');\n writeJsoncConfig(resolved.path, raw);\n } else {\n writeJsonConfig(resolved.path);\n }\n}\n\n/** Options for configureOpenCode. */\nexport interface ConfigureOpenCodeOptions {\n readonly force: boolean;\n readonly dryRun: boolean;\n readonly projectRoot?: string;\n}\n\n/** Validates projectRoot to prevent path traversal (CWE-22). */\nfunction validateProjectRoot(projectRoot: string): string {\n const resolved = resolve(projectRoot);\n if (!existsSync(resolved)) {\n throw new Error(`Project root does not exist: ${resolved}`);\n }\n return resolved;\n}\n\n/**\n * Configures OpenCode with nexus-agents MCP server.\n * Supports both global (~/.config/opencode/) and project-local configs.\n */\nexport function configureOpenCode(\n force: boolean,\n dryRun: boolean,\n options?: ConfigureOpenCodeOptions\n): OpenCodeConfigResult {\n try {\n return configureOpenCodeInner(force, dryRun, options);\n } catch (error: unknown) {\n const fallbackPath = join(getOpenCodeConfigDir(), 'opencode.json');\n return {\n success: false,\n alreadyConfigured: false,\n message: `Failed to configure OpenCode: ${getErrorMessage(error)}`,\n configPath: fallbackPath,\n };\n }\n}\n\nfunction configureOpenCodeInner(\n force: boolean,\n dryRun: boolean,\n options?: ConfigureOpenCodeOptions\n): OpenCodeConfigResult {\n const configDir =\n options?.projectRoot !== undefined\n ? validateProjectRoot(options.projectRoot)\n : getOpenCodeConfigDir();\n const resolved = resolveOpenCodeConfig(configDir);\n\n if (isAlreadyConfigured(resolved) && !force) {\n return {\n success: true,\n alreadyConfigured: true,\n message: 'nexus-agents already configured in OpenCode',\n configPath: resolved.path,\n };\n }\n if (dryRun) {\n return {\n success: true,\n alreadyConfigured: false,\n message: `Would configure nexus-agents MCP in ${resolved.path}`,\n configPath: resolved.path,\n };\n }\n writeOpenCodeConfig(configDir, resolved);\n return {\n success: true,\n alreadyConfigured: false,\n message: 'Configured nexus-agents MCP in OpenCode',\n configPath: resolved.path,\n };\n}\n","/**\n * Gemini CLI MCP auto-configuration for setup command.\n *\n * Detects Gemini CLI and configures ~/.gemini/settings.json with nexus-agents MCP server.\n *\n * @module cli/setup-gemini\n * (Source: Issue #1259 - Gemini CLI MCP auto-configuration)\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { execFileSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { homedir, platform } from 'node:os';\nimport { getErrorMessage } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\n\nconst logger = createLogger({ component: 'setup-gemini' });\n\n/** Gemini CLI detection result. */\nexport interface GeminiCliInfo {\n readonly installed: boolean;\n readonly version: string | undefined;\n}\n\n/** Gemini MCP configuration result. */\nexport interface GeminiConfigResult {\n readonly success: boolean;\n readonly alreadyConfigured: boolean;\n readonly message: string;\n readonly configPath: string;\n}\n\n/** Gemini MCP server entry format. */\ninterface GeminiMcpEntry {\n readonly command: string;\n readonly args: readonly string[];\n readonly timeout: number;\n}\n\n/**\n * Detects Gemini CLI installation.\n */\nexport function detectGeminiCli(): GeminiCliInfo {\n try {\n const cmd = platform() === 'win32' ? 'where' : 'which';\n execFileSync(cmd, ['gemini'], { timeout: 3000, stdio: 'pipe' });\n } catch {\n return { installed: false, version: undefined };\n }\n\n try {\n const output = execFileSync('gemini', ['--version'], {\n timeout: 5000,\n stdio: 'pipe',\n encoding: 'utf-8',\n });\n const match = /(\\d+\\.\\d+\\.\\d+)/.exec(output);\n return { installed: true, version: match?.[1] };\n } catch {\n return { installed: true, version: undefined };\n }\n}\n\n/** Resolves the Gemini config directory path based on scope. */\nfunction getGeminiConfigDir(scope: 'user' | 'project', projectRoot?: string): string {\n if (scope === 'project' && projectRoot !== undefined) {\n return join(projectRoot, '.gemini');\n }\n return join(homedir(), '.gemini');\n}\n\n/** Returns the nexus-agents MCP entry for Gemini settings.json. */\nfunction getNexusMcpEntry(): GeminiMcpEntry {\n return {\n command: 'npx',\n args: ['nexus-agents', '--mode=server'],\n timeout: 30000,\n };\n}\n\n/** Checks if nexus-agents is already configured in settings.json. */\nfunction isAlreadyConfigured(configPath: string): boolean {\n if (!existsSync(configPath)) return false;\n try {\n const config = JSON.parse(readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const servers = config['mcpServers'] as Record<string, unknown> | undefined;\n return servers?.['nexus-agents'] !== undefined;\n } catch {\n logger.debug('Failed to parse existing Gemini settings.json, will overwrite');\n return false;\n }\n}\n\n/** Reads existing config or returns empty object. */\nfunction readExistingConfig(configPath: string): Record<string, unknown> {\n if (!existsSync(configPath)) return {};\n try {\n return JSON.parse(readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/** Writes the merged config with nexus-agents MCP entry. */\nfunction writeGeminiConfig(configDir: string, configPath: string): void {\n if (!existsSync(configDir)) mkdirSync(configDir, { recursive: true });\n const config = readExistingConfig(configPath);\n const servers = (config['mcpServers'] ?? {}) as Record<string, unknown>;\n servers['nexus-agents'] = getNexusMcpEntry();\n config['mcpServers'] = servers;\n writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * Configures Gemini CLI with nexus-agents MCP server.\n *\n * @param force - Force reconfiguration even if already configured\n * @param dryRun - Preview changes without writing\n * @param scope - 'user' for global (~/.gemini/), 'project' for project-local (.gemini/)\n * @param projectRoot - Project root directory (required for project scope)\n */\nexport function configureGemini(\n force: boolean,\n dryRun: boolean,\n scope: 'user' | 'project' = 'user',\n projectRoot?: string\n): GeminiConfigResult {\n const configDir = getGeminiConfigDir(scope, projectRoot);\n const configPath = join(configDir, 'settings.json');\n\n if (isAlreadyConfigured(configPath) && !force) {\n return {\n success: true,\n alreadyConfigured: true,\n message: 'nexus-agents already configured in Gemini CLI',\n configPath,\n };\n }\n if (dryRun) {\n return {\n success: true,\n alreadyConfigured: false,\n message: `Would configure nexus-agents MCP in ${configPath}`,\n configPath,\n };\n }\n try {\n writeGeminiConfig(configDir, configPath);\n return {\n success: true,\n alreadyConfigured: false,\n message: 'Configured nexus-agents MCP in Gemini CLI',\n configPath,\n };\n } catch (error: unknown) {\n return {\n success: false,\n alreadyConfigured: false,\n message: `Failed to configure Gemini: ${getErrorMessage(error)}`,\n configPath,\n };\n }\n}\n","/**\n * Codex CLI MCP auto-configuration for setup command.\n *\n * Detects Codex CLI and registers nexus-agents MCP server\n * using `codex mcp add` CLI command.\n *\n * @module cli/setup-codex\n * (Source: Issue #1263 - Codex CLI MCP auto-configuration)\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { platform } from 'node:os';\nimport { getErrorMessage } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\n\nconst logger = createLogger({ component: 'setup-codex' });\n\n/** Codex CLI detection result. */\nexport interface CodexCliInfo {\n readonly installed: boolean;\n readonly version: string | undefined;\n}\n\n/** Codex MCP configuration result. */\nexport interface CodexConfigResult {\n readonly success: boolean;\n readonly alreadyConfigured: boolean;\n readonly message: string;\n}\n\n/**\n * Detects Codex CLI installation.\n */\nexport function detectCodexCli(): CodexCliInfo {\n try {\n const cmd = platform() === 'win32' ? 'where' : 'which';\n execFileSync(cmd, ['codex'], { timeout: 3000, stdio: 'pipe' });\n } catch {\n return { installed: false, version: undefined };\n }\n\n try {\n const output = execFileSync('codex', ['--version'], {\n timeout: 5000,\n stdio: 'pipe',\n encoding: 'utf-8',\n });\n const match = /(\\d+\\.\\d+\\.\\d+)/.exec(output);\n return { installed: true, version: match?.[1] };\n } catch {\n return { installed: true, version: undefined };\n }\n}\n\n/**\n * Checks if nexus-agents is already configured in Codex MCP.\n */\nfunction isAlreadyConfigured(): boolean {\n try {\n const output = execFileSync('codex', ['mcp', 'list'], {\n timeout: 5000,\n stdio: 'pipe',\n encoding: 'utf-8',\n });\n return output.includes('nexus-agents');\n } catch {\n return false;\n }\n}\n\n/**\n * Removes existing nexus-agents MCP configuration from Codex.\n */\nfunction removeExisting(): void {\n try {\n execFileSync('codex', ['mcp', 'remove', 'nexus-agents'], {\n timeout: 5000,\n stdio: 'pipe',\n });\n } catch {\n logger.debug('Failed to remove existing Codex MCP config (may not exist)');\n }\n}\n\n/**\n * Adds nexus-agents MCP server to Codex CLI.\n *\n * Uses: codex mcp add nexus-agents -- npx nexus-agents --mode=server\n */\nfunction addMcpServer(): CodexConfigResult {\n try {\n execFileSync(\n 'codex',\n ['mcp', 'add', 'nexus-agents', '--', 'npx', 'nexus-agents', '--mode=server'],\n {\n timeout: 10000,\n stdio: 'pipe',\n }\n );\n return {\n success: true,\n alreadyConfigured: false,\n message: 'Configured nexus-agents MCP in Codex CLI',\n };\n } catch (error: unknown) {\n return {\n success: false,\n alreadyConfigured: false,\n message: `Failed to configure Codex: ${getErrorMessage(error)}`,\n };\n }\n}\n\n/**\n * Configures Codex CLI with nexus-agents MCP server.\n */\nexport function configureCodex(force: boolean, dryRun: boolean): CodexConfigResult {\n if (isAlreadyConfigured() && !force) {\n return {\n success: true,\n alreadyConfigured: true,\n message: 'nexus-agents already configured in Codex CLI',\n };\n }\n\n if (dryRun) {\n return {\n success: true,\n alreadyConfigured: false,\n message: 'Would configure nexus-agents MCP in Codex CLI',\n };\n }\n\n if (force && isAlreadyConfigured()) {\n removeExisting();\n }\n\n return addMcpServer();\n}\n","/**\n * nexus-agents setup interactive wizard\n *\n * Guided setup experience for configuring nexus-agents with Claude CLI.\n * Uses Node.js readline for terminal prompts without external dependencies.\n *\n * @module cli/setup-wizard\n * (Source: Issue #425 - Interactive setup wizard)\n */\n\nimport { createInterface, type Interface } from 'node:readline';\nimport { formatHeader, formatStatus, isInteractive } from './setup-formatting.js';\nimport type { SetupOptions } from './setup-types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Usage mode selection. */\nexport type UsageMode = 'claude-desktop' | 'claude-cli' | 'standalone' | 'all';\n\n/** Wizard answers collected from user. */\nexport interface WizardAnswers {\n usageMode: UsageMode;\n hasApiKeys: boolean;\n configDirectory: string;\n confirmProceed: boolean;\n}\n\n/** Wizard state during execution. */\ninterface WizardState {\n currentStep: number;\n totalSteps: number;\n answers: Partial<WizardAnswers>;\n}\n\n// ============================================================================\n// Readline Helpers\n// ============================================================================\n\n/**\n * Creates a readline interface for prompting.\n */\nfunction createReadline(): Interface {\n return createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n}\n\n/**\n * Prompts for input and returns the answer.\n */\nasync function promptInput(rl: Interface, question: string): Promise<string> {\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Prompts for a yes/no confirmation.\n */\nasync function promptConfirm(\n rl: Interface,\n question: string,\n defaultValue = true\n): Promise<boolean> {\n const defaultHint = defaultValue ? '[Y/n]' : '[y/N]';\n const answer = await promptInput(rl, `${question} ${defaultHint}: `);\n\n if (answer === '') return defaultValue;\n return answer.toLowerCase().startsWith('y');\n}\n\n/**\n * Prints options for selection prompt.\n */\nfunction printOptions(\n options: readonly { value: string; label: string }[],\n defaultIndex: number\n): void {\n for (let i = 0; i < options.length; i++) {\n const option = options[i];\n const marker = i === defaultIndex ? '>' : ' ';\n const label = option?.label ?? '';\n writeLine(` ${marker} ${String(i + 1)}. ${label}`);\n }\n}\n\n/**\n * Gets value from options at index with fallback.\n */\nfunction getOptionValue(\n options: readonly { value: string; label: string }[],\n index: number,\n fallbackIndex: number\n): string {\n const option = options[index];\n if (option !== undefined) {\n return option.value;\n }\n const fallback = options[fallbackIndex];\n return fallback?.value ?? '';\n}\n\n/**\n * Prompts for a selection from a list of options.\n */\nasync function promptSelect(\n rl: Interface,\n question: string,\n options: readonly { value: string; label: string }[],\n defaultIndex = 0\n): Promise<string> {\n writeLine('\\n' + question);\n printOptions(options, defaultIndex);\n\n const answer = await promptInput(rl, `\\nChoice [1-${String(options.length)}]: `);\n\n if (answer === '') {\n return getOptionValue(options, defaultIndex, 0);\n }\n\n const index = parseInt(answer, 10) - 1;\n if (index >= 0 && index < options.length) {\n return getOptionValue(options, index, 0);\n }\n\n return getOptionValue(options, defaultIndex, 0);\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\n/** Writes a line to stdout. */\nfunction writeLine(text: string): void {\n process.stdout.write(text + '\\n');\n}\n\n/** Writes an empty line. */\nfunction writeEmptyLine(): void {\n process.stdout.write('\\n');\n}\n\n/** Prints the wizard header. */\nfunction printWizardHeader(): void {\n writeEmptyLine();\n writeLine(formatHeader('Nexus Agents Setup Wizard'));\n writeLine('='.repeat(40));\n writeLine('This wizard will help you configure nexus-agents.');\n writeEmptyLine();\n}\n\n/** Prints step progress. */\nfunction printStepProgress(state: WizardState, stepName: string): void {\n writeLine(\n `\\n${formatHeader(`Step ${String(state.currentStep)}/${String(state.totalSteps)}: ${stepName}`)}`\n );\n writeLine('-'.repeat(40));\n}\n\n/** Prints completion message. */\nfunction printCompletion(): void {\n writeEmptyLine();\n writeLine(formatStatus('success') + ' Wizard completed! Running setup...');\n writeEmptyLine();\n}\n\n// ============================================================================\n// Wizard Steps\n// ============================================================================\n\n/** Usage mode options. */\nconst USAGE_MODE_OPTIONS: readonly { value: UsageMode; label: string }[] = [\n { value: 'claude-cli', label: 'Claude CLI (terminal-based development)' },\n { value: 'claude-desktop', label: 'Claude Desktop (GUI application)' },\n { value: 'standalone', label: 'Standalone CLI (without Claude integration)' },\n { value: 'all', label: 'All of the above' },\n];\n\n/**\n * Step 1: Ask how the user plans to use nexus-agents.\n */\nasync function askUsageMode(rl: Interface, state: WizardState): Promise<UsageMode> {\n printStepProgress(state, 'Usage Mode');\n writeLine('How will you use nexus-agents?');\n\n const answer = await promptSelect(rl, '', USAGE_MODE_OPTIONS, 0);\n\n return answer as UsageMode;\n}\n\n/**\n * Step 2: Ask about API key configuration.\n */\nasync function askApiKeys(rl: Interface, state: WizardState): Promise<boolean> {\n printStepProgress(state, 'API Keys');\n writeLine('nexus-agents works best with API keys configured.');\n writeLine('Supported providers: Anthropic (Claude), OpenAI, Google (Gemini)');\n writeEmptyLine();\n\n const hasKeys = await promptConfirm(rl, 'Do you have at least one API key configured?', false);\n\n if (!hasKeys) {\n writeEmptyLine();\n writeLine('No worries! You can configure API keys later:');\n writeLine(' - ANTHROPIC_API_KEY for Claude');\n writeLine(' - OPENAI_API_KEY for OpenAI/Codex');\n writeLine(' - GOOGLE_AI_API_KEY for Gemini');\n writeLine('\\nRun `nexus-agents doctor` to check your configuration.');\n }\n\n return hasKeys;\n}\n\n/**\n * Step 3: Ask about configuration directory.\n */\nasync function askConfigDirectory(rl: Interface, state: WizardState): Promise<string> {\n printStepProgress(state, 'Configuration');\n writeLine('Where should nexus-agents store its configuration?');\n writeEmptyLine();\n\n const defaultDir = process.cwd();\n const answer = await promptInput(rl, `Directory [${defaultDir}]: `);\n\n return answer || defaultDir;\n}\n\n/**\n * Step 4: Confirm and proceed.\n */\nasync function askConfirmation(\n rl: Interface,\n state: WizardState,\n answers: Partial<WizardAnswers>\n): Promise<boolean> {\n printStepProgress(state, 'Confirmation');\n writeLine('Setup will configure the following:');\n writeEmptyLine();\n\n const modeLabel =\n USAGE_MODE_OPTIONS.find((o) => o.value === answers.usageMode)?.label ?? 'Unknown';\n const apiKeyStatus = answers.hasApiKeys === true ? 'Configured' : 'Not yet configured';\n const configDir = answers.configDirectory ?? process.cwd();\n writeLine(` Usage mode: ${modeLabel}`);\n writeLine(` API keys: ${apiKeyStatus}`);\n writeLine(` Config directory: ${configDir}`);\n writeEmptyLine();\n\n const skipMcp = answers.usageMode === 'standalone';\n if (!skipMcp) {\n writeLine('Will configure:');\n writeLine(' - MCP server for Claude integration');\n writeLine(' - Rules file (.rules/nexus-agents.md)');\n writeLine(' - Hooks for session tracking');\n } else {\n writeLine('Will configure:');\n writeLine(' - Rules file (.rules/nexus-agents.md)');\n writeLine(' - (Skipping MCP/hooks - not needed for standalone mode)');\n }\n\n writeEmptyLine();\n return promptConfirm(rl, 'Proceed with setup?', true);\n}\n\n// ============================================================================\n// Wizard Runner\n// ============================================================================\n\n/**\n * Runs the interactive setup wizard.\n *\n * @returns Setup options based on wizard answers, or undefined if cancelled\n */\nexport async function runWizard(): Promise<Partial<SetupOptions> | undefined> {\n // Check if interactive mode is available\n if (!isInteractive()) {\n writeLine('Interactive mode not available (TTY required).');\n writeLine('Use --non-interactive flag for automated setup.');\n return undefined;\n }\n\n const rl = createReadline();\n\n try {\n printWizardHeader();\n\n const state: WizardState = {\n currentStep: 1,\n totalSteps: 4,\n answers: {},\n };\n\n // Step 1: Usage mode\n state.answers.usageMode = await askUsageMode(rl, state);\n state.currentStep++;\n\n // Step 2: API keys\n state.answers.hasApiKeys = await askApiKeys(rl, state);\n state.currentStep++;\n\n // Step 3: Config directory\n state.answers.configDirectory = await askConfigDirectory(rl, state);\n state.currentStep++;\n\n // Step 4: Confirmation\n state.answers.confirmProceed = await askConfirmation(rl, state, state.answers);\n state.currentStep++;\n\n if (!state.answers.confirmProceed) {\n writeEmptyLine();\n writeLine('Setup cancelled.');\n return undefined;\n }\n\n printCompletion();\n\n // Convert wizard answers to setup options\n return convertAnswersToOptions(state.answers as WizardAnswers);\n } finally {\n rl.close();\n }\n}\n\n/**\n * Converts wizard answers to setup options.\n */\nfunction convertAnswersToOptions(answers: WizardAnswers): Partial<SetupOptions> {\n const isStandalone = answers.usageMode === 'standalone';\n\n return {\n // Skip MCP and hooks for standalone mode\n skipMcp: isStandalone,\n skipHooks: isStandalone,\n // Always create rules file\n skipRules: false,\n // Use user scope for Claude CLI/Desktop, project for standalone\n scope: isStandalone ? 'project' : 'user',\n // Non-interactive since we collected all info\n nonInteractive: true,\n // Show verbose output to explain what's happening\n verbose: true,\n };\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { isInteractive };\n","/**\n * Claude Code permissions snippet generator (#1945).\n *\n * In \"don't ask\" permission mode, Claude Code hard-rejects MCP tool calls\n * that aren't in the allowlist. For nexus-agents to be usable for agentic\n * dogfooding (orchestrate, create_expert, consensus_vote), the tools must\n * be pre-approved in ~/.claude/settings.json.\n *\n * This module generates a recommended snippet for users to paste into\n * their settings.json. We do NOT auto-write permissions — that would be\n * a security footgun.\n *\n * @module cli/setup-permissions\n */\n\n/** MCP tool names that are safe to pre-approve (read-only or idempotent). */\nconst SAFE_READONLY_TOOLS = [\n 'list_experts',\n 'list_workflows',\n 'weather_report',\n 'memory_query',\n 'memory_stats',\n 'query_trace',\n 'research_query',\n 'research_analyze',\n 'research_discover',\n 'research_synthesize',\n 'repo_analyze',\n 'repo_security_plan',\n 'extract_symbols',\n 'search_codebase',\n] as const;\n\n/** MCP tools that execute tasks but are commonly used for dogfooding. */\nconst SAFE_EXECUTION_TOOLS = [\n 'orchestrate',\n 'create_expert',\n 'execute_expert',\n 'consensus_vote',\n 'delegate_to_model',\n 'run_workflow',\n 'issue_triage',\n 'registry_import',\n] as const;\n\nexport type PermissionLevel = 'readonly' | 'all';\n\n/**\n * Generate a JSON snippet of recommended permissions for Claude Code's\n * `~/.claude/settings.json` to pre-approve nexus-agents MCP tools.\n *\n * Users paste this into the `permissions.allow` array.\n */\nexport function generatePermissionsSnippet(level: PermissionLevel = 'all'): string {\n const tools =\n level === 'readonly'\n ? [...SAFE_READONLY_TOOLS]\n : [...SAFE_READONLY_TOOLS, ...SAFE_EXECUTION_TOOLS];\n\n const permissions = tools.map((t) => `mcp__nexus-agents__${t}`).sort();\n return JSON.stringify(permissions, null, 2);\n}\n\n/**\n * Return a human-readable banner explaining the permissions snippet,\n * for inclusion in `nexus-agents setup` output.\n */\nexport function buildPermissionsBanner(snippet: string): string {\n return [\n '',\n '--- Claude Code Permissions (optional) ---',\n '',\n \"To use nexus-agents MCP tools in 'don't ask' mode (autonomous/headless\",\n 'Claude Code sessions), add these entries to the `permissions.allow` array',\n 'in your `~/.claude/settings.json`:',\n '',\n snippet,\n '',\n 'Without these, each MCP tool call will prompt for approval in interactive',\n 'mode, or be rejected outright in `dangerously-skip-permissions` mode.',\n '',\n 'Reference: https://github.com/williamzujkowski/nexus-agents/issues/1945',\n '',\n ].join('\\n');\n}\n","/**\n * nexus-agents/cli - Verify Command\n *\n * Quick verification that installation works correctly.\n * No API keys required - runs offline checks only.\n *\n * @module cli/verify-command\n * (Source: Issue #253 - Quick verification step after installation)\n */\n\nimport { VERSION } from '../version.js';\nimport { getTimeProvider } from '../core/index.js';\nimport { defaultConfig } from '../config/index.js';\nimport { BUILT_IN_EXPERTS } from '../agents/experts/expert-config.js';\nimport { colors, symbols } from './ansi-output.js';\nimport { checkSqlite, checkDataDirectory, checkApiKeys } from './doctor.js';\n\n/**\n * Verify command options.\n */\nexport interface VerifyOptions {\n readonly verbose: boolean;\n}\n\n/**\n * Severity of a failed check.\n *\n * - `hard`: functionality is broken (e.g. Node version too low, core exports\n * missing). Exit code 1.\n * - `warn`: functionality is degraded but usable (e.g. better-sqlite3 missing\n * → only some memory backends unavailable; no CLI adapters detected →\n * orchestrator still works via API keys). Exit code 0.\n *\n * Unused on passing checks.\n */\nexport type VerifySeverity = 'hard' | 'warn';\n\n/**\n * Single verification check result.\n */\nexport interface VerifyCheck {\n readonly name: string;\n readonly passed: boolean;\n readonly message: string;\n readonly fix?: string;\n /**\n * Severity for failed checks. Defaults to `hard` when omitted. Passing\n * checks ignore this field.\n */\n readonly severity?: VerifySeverity;\n}\n\n/**\n * Complete verification result.\n */\nexport interface VerifyResult {\n readonly version: string;\n readonly nodeVersion: string;\n readonly checks: readonly VerifyCheck[];\n /** True when every check passed. */\n readonly allPassed: boolean;\n /**\n * True when no check failed with `severity: 'hard'`. Drives the exit code:\n * warnings alone do not fail verification (exit 0 with warnings printed).\n */\n readonly noHardFailures: boolean;\n readonly durationMs: number;\n}\n\n/**\n * Checks if Node.js version is supported.\n */\nfunction checkNodeVersion(): VerifyCheck {\n const version = process.version;\n const major = parseInt(version.slice(1).split('.')[0] ?? '0', 10);\n\n if (major >= 22) {\n return {\n name: 'Node.js Version',\n passed: true,\n message: `${version} (LTS)`,\n };\n }\n\n if (major >= 18) {\n return {\n name: 'Node.js Version',\n passed: true,\n message: `${version} (supported, recommend 22.x LTS)`,\n };\n }\n\n return {\n name: 'Node.js Version',\n passed: false,\n message: `${version} (unsupported)`,\n fix: 'Install Node.js 22.x LTS from https://nodejs.org',\n };\n}\n\n/**\n * Checks if package exports are accessible.\n */\nfunction checkPackageExports(): VerifyCheck {\n try {\n // Check if we can access core exports\n const hasVersion = typeof VERSION === 'string' && VERSION.length > 0;\n const hasConfig = typeof defaultConfig === 'object';\n const hasBuiltInExperts = typeof BUILT_IN_EXPERTS === 'object';\n\n if (hasVersion && hasConfig && hasBuiltInExperts) {\n return {\n name: 'Package Exports',\n passed: true,\n message: 'All core modules accessible',\n };\n }\n\n return {\n name: 'Package Exports',\n passed: false,\n message: 'Some modules failed to load',\n fix: 'Try reinstalling: npm install -g nexus-agents',\n };\n } catch {\n return {\n name: 'Package Exports',\n passed: false,\n message: 'Failed to load core modules',\n fix: 'Try reinstalling: npm install -g nexus-agents',\n };\n }\n}\n\n/**\n * Checks if default configuration is accessible.\n */\nfunction checkConfigLoading(): VerifyCheck {\n try {\n const hasModels = typeof defaultConfig.models === 'object';\n const hasSecurity = typeof defaultConfig.security === 'object';\n\n if (hasModels && hasSecurity) {\n return {\n name: 'Configuration',\n passed: true,\n message: 'Default config accessible',\n };\n }\n\n return {\n name: 'Configuration',\n passed: true, // Config errors are not fatal for verification\n message: 'Using default configuration',\n };\n } catch {\n return {\n name: 'Configuration',\n passed: true, // Still works with defaults\n message: 'Using default configuration',\n };\n }\n}\n\n/**\n * Checks expert system availability.\n */\nfunction checkExpertSystem(): VerifyCheck {\n const expertTypes = Object.keys(BUILT_IN_EXPERTS);\n const count = expertTypes.length;\n\n if (count >= 5) {\n return {\n name: 'Expert System',\n passed: true,\n message: `${String(count)} expert types available`,\n };\n }\n\n return {\n name: 'Expert System',\n passed: false,\n message: 'Expert types not loaded',\n fix: 'Try reinstalling: npm install -g nexus-agents',\n };\n}\n\n/**\n * Checks that better-sqlite3 loads. Memory backends (agentic, adaptive, typed,\n * mobimem, decay) are unavailable if it's missing — functional degradation,\n * not a hard failure. Rebuilding the native module or reinstalling usually\n * fixes it.\n */\nasync function checkSqliteAvailability(): Promise<VerifyCheck> {\n const result = await checkSqlite();\n if (result.available) {\n return {\n name: 'SQLite Storage',\n passed: true,\n message: 'better-sqlite3 loaded (memory backends available)',\n };\n }\n return {\n name: 'SQLite Storage',\n passed: false,\n severity: 'warn',\n message: result.error ?? 'better-sqlite3 not available',\n fix: 'Run \"pnpm rebuild better-sqlite3\" or reinstall nexus-agents',\n };\n}\n\n/**\n * Checks that the `~/.nexus-agents/` data directories exist and are writable.\n * `cli-commands.ts::dispatchCommand` initializes them lazily (#1398), so\n * missing dirs are a hard failure (persistence will silently drop writes).\n */\nfunction checkDataDirs(): VerifyCheck {\n const result = checkDataDirectory();\n const unwritable = result.subdirectories.filter((s) => !s.exists || !s.writable);\n if (result.rootExists && unwritable.length === 0) {\n return {\n name: 'Data Directories',\n passed: true,\n message: `${result.rootPath} (all subdirectories writable)`,\n };\n }\n if (!result.rootExists) {\n return {\n name: 'Data Directories',\n passed: false,\n severity: 'warn',\n message: `${result.rootPath} does not exist`,\n fix: 'Run any nexus-agents command — directories auto-initialize on first run',\n };\n }\n return {\n name: 'Data Directories',\n passed: false,\n severity: 'warn',\n message: `${String(unwritable.length)} subdirectory(ies) unwritable: ${unwritable\n .map((s) => s.name)\n .join(', ')}`,\n fix: `Check filesystem permissions on ${result.rootPath}`,\n };\n}\n\n/**\n * Checks that at least one execution path is configured — either an API key\n * (direct adapter) or a CLI binary pre-authenticated. Without either, the\n * orchestrator has nothing to dispatch to.\n */\nfunction checkAdapterAvailability(): VerifyCheck {\n const keys = checkApiKeys();\n const configured = keys.filter((k) => k.configured);\n if (configured.length > 0) {\n return {\n name: 'Adapter Availability',\n passed: true,\n message: `${String(configured.length)} API key(s) configured: ${configured\n .map((k) => k.name)\n .join(', ')}`,\n };\n }\n return {\n name: 'Adapter Availability',\n passed: false,\n severity: 'warn',\n message: 'No API keys configured (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_AI_API_KEY)',\n fix: 'Set at least one API key, or install a CLI (claude/gemini/codex/opencode) and run \"nexus-agents doctor\"',\n };\n}\n\n/**\n * Runs all verification checks.\n */\nexport async function runVerify(): Promise<VerifyResult> {\n const time = getTimeProvider();\n const startTime = time.now();\n\n const checks: VerifyCheck[] = [\n checkNodeVersion(),\n checkPackageExports(),\n checkConfigLoading(),\n checkExpertSystem(),\n await checkSqliteAvailability(),\n checkDataDirs(),\n checkAdapterAvailability(),\n ];\n\n const allPassed = checks.every((c) => c.passed);\n const noHardFailures = checks.every((c) => c.passed || c.severity === 'warn');\n const durationMs = time.now() - startTime;\n\n return {\n version: VERSION,\n nodeVersion: process.version,\n checks,\n allPassed,\n noHardFailures,\n durationMs,\n };\n}\n\n/**\n * Formats a single check result.\n *\n * Failed-but-warn checks render as yellow warnings (degraded). Failed hard\n * checks render as red crosses.\n */\nfunction formatCheck(check: VerifyCheck): string {\n let symbol: string;\n if (check.passed) {\n symbol = `${colors.green}${symbols.check}${colors.reset}`;\n } else if (check.severity === 'warn') {\n symbol = `${colors.yellow}${symbols.warn}${colors.reset}`;\n } else {\n symbol = `${colors.red}${symbols.cross}${colors.reset}`;\n }\n\n let line = ` ${symbol} ${check.name}: ${check.message}`;\n\n if (!check.passed && check.fix !== undefined) {\n line += `\\n ${colors.dim}Fix: ${check.fix}${colors.reset}`;\n }\n\n return line;\n}\n\n/**\n * Prints verification results to stdout.\n */\nexport function printVerifyResult(result: VerifyResult, verbose: boolean): void {\n process.stdout.write('\\n');\n process.stdout.write(`${colors.bold}nexus-agents verify${colors.reset}\\n`);\n process.stdout.write('===================\\n');\n process.stdout.write('\\n');\n process.stdout.write(`Version: ${result.version}\\n`);\n process.stdout.write(`Node.js: ${result.nodeVersion}\\n`);\n process.stdout.write('\\n');\n\n process.stdout.write(`${colors.cyan}Running checks...${colors.reset}\\n`);\n process.stdout.write('\\n');\n\n for (const check of result.checks) {\n process.stdout.write(formatCheck(check) + '\\n');\n }\n\n process.stdout.write('\\n');\n\n const warnCount = result.checks.filter((c) => !c.passed && c.severity === 'warn').length;\n const hardCount = result.checks.filter((c) => !c.passed && c.severity !== 'warn').length;\n\n if (result.allPassed) {\n process.stdout.write(\n `${colors.green}${colors.bold}Installation verified successfully!${colors.reset}\\n`\n );\n process.stdout.write('\\n');\n process.stdout.write(`${colors.cyan}Next steps:${colors.reset}\\n`);\n process.stdout.write(' 1. Run \"nexus-agents doctor\" to check external CLI integrations\\n');\n process.stdout.write(\n ' 2. Run \"nexus-agents review --setup\" to configure GitHub integration\\n'\n );\n process.stdout.write(' 3. Try \"nexus-agents --help\" for all available commands\\n');\n } else if (hardCount === 0) {\n process.stdout.write(\n `${colors.yellow}${colors.bold}Verified with ${String(warnCount)} warning(s) — functional but degraded${colors.reset}\\n`\n );\n process.stdout.write('\\n');\n process.stdout.write('The warnings above indicate reduced functionality but will not\\n');\n process.stdout.write('prevent nexus-agents from running. Fix them when convenient.\\n');\n } else {\n process.stdout.write(\n `${colors.red}${colors.bold}Verification failed: ${String(hardCount)} blocking issue(s), ${String(warnCount)} warning(s)${colors.reset}\\n`\n );\n process.stdout.write('\\n');\n process.stdout.write('Please fix the blocking issues above and try again.\\n');\n }\n\n process.stdout.write('\\n');\n\n if (verbose) {\n process.stdout.write(`${colors.dim}Duration: ${String(result.durationMs)}ms${colors.reset}\\n`);\n process.stdout.write('\\n');\n }\n}\n\n/**\n * Runs the verify command and prints results.\n *\n * Exit codes:\n * - `0`: all checks passed, or only `warn`-severity checks failed (degraded\n * but functional)\n * - `1`: at least one `hard`-severity check failed (broken install)\n */\nexport async function verifyCommand(options: VerifyOptions): Promise<number> {\n const result = await runVerify();\n printVerifyResult(result, options.verbose);\n return result.noHardFailures ? 0 : 1;\n}\n"],"mappings":"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","names":["existsSync","execSync","homedir","join","execSync","execSync","readFileSync","join","join","existsSync","readFileSync","writeFileSync","mkdirSync","execFileSync","join","homedir","execFileSync","join","homedir","existsSync","readFileSync","writeFileSync","mkdirSync","existsSync","readFileSync","writeFileSync","mkdirSync","execFileSync","join","homedir","platform","logger","platform","execFileSync","join","homedir","isAlreadyConfigured","existsSync","readFileSync","mkdirSync","writeFileSync","execFileSync","platform","logger","platform","execFileSync","isAlreadyConfigured","addMcpServer","resolve","writeLine","writeEmptyLine","mcpResult","existsSync"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/security/safe-path.ts
|
|
2
|
+
import { resolve, sep } from "path";
|
|
3
|
+
function resolveInsideRoot(filePath, root = process.cwd()) {
|
|
4
|
+
const resolvedRoot = resolve(root);
|
|
5
|
+
const resolved = resolve(resolvedRoot, filePath);
|
|
6
|
+
if (resolved === resolvedRoot) return resolved;
|
|
7
|
+
if (resolved.startsWith(resolvedRoot + sep)) return resolved;
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
resolveInsideRoot
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=chunk-NUBSJGQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/safe-path.ts"],"sourcesContent":["/**\n * Safe Path — Path traversal guards for scanner-controlled inputs (#1813, #1814)\n *\n * When reading files whose path comes from untrusted input (e.g., SARIF\n * scanner output), we must verify the resolved path stays within the\n * workspace root. Without this, a malicious scanner can cause arbitrary\n * file reads whose contents are exfiltrated via downstream LLM prompts\n * (CWE-22).\n *\n * Shared helper to prevent the finding-triage/fix-generator drift that\n * required two separate fixes.\n *\n * @module security/safe-path\n */\n\nimport { resolve, sep } from 'node:path';\n\n/**\n * Resolve a scanner-supplied path against the workspace root, returning null\n * if it escapes. Null means the caller must fall back to a safe alternative\n * (e.g., scanner-provided snippet) rather than reading the file.\n *\n * @param filePath - Scanner-supplied path (may be relative or absolute)\n * @param root - Workspace root (defaults to process.cwd())\n * @returns Resolved absolute path if inside root, null otherwise\n */\nexport function resolveInsideRoot(filePath: string, root: string = process.cwd()): string | null {\n const resolvedRoot = resolve(root);\n const resolved = resolve(resolvedRoot, filePath);\n if (resolved === resolvedRoot) return resolved;\n if (resolved.startsWith(resolvedRoot + sep)) return resolved;\n return null;\n}\n"],"mappings":";AAeA,SAAS,SAAS,WAAW;AAWtB,SAAS,kBAAkB,UAAkB,OAAe,QAAQ,IAAI,GAAkB;AAC/F,QAAM,eAAe,QAAQ,IAAI;AACjC,QAAM,WAAW,QAAQ,cAAc,QAAQ;AAC/C,MAAI,aAAa,aAAc,QAAO;AACtC,MAAI,SAAS,WAAW,eAAe,GAAG,EAAG,QAAO;AACpD,SAAO;AACT;","names":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveInsideRoot
|
|
3
|
+
} from "./chunk-NUBSJGQZ.js";
|
|
1
4
|
import {
|
|
2
5
|
ParseError,
|
|
3
6
|
SecurityError,
|
|
@@ -6,19 +9,7 @@ import {
|
|
|
6
9
|
|
|
7
10
|
// src/cli/research-helpers-io.ts
|
|
8
11
|
import * as fs from "fs/promises";
|
|
9
|
-
import { join, resolve
|
|
10
|
-
|
|
11
|
-
// src/security/safe-path.ts
|
|
12
|
-
import { resolve, sep } from "path";
|
|
13
|
-
function resolveInsideRoot(filePath, root = process.cwd()) {
|
|
14
|
-
const resolvedRoot = resolve(root);
|
|
15
|
-
const resolved = resolve(resolvedRoot, filePath);
|
|
16
|
-
if (resolved === resolvedRoot) return resolved;
|
|
17
|
-
if (resolved.startsWith(resolvedRoot + sep)) return resolved;
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/cli/research-helpers-io.ts
|
|
12
|
+
import { join, resolve } from "path";
|
|
22
13
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
23
14
|
var REGISTRY_PATH = "docs/research/registry";
|
|
24
15
|
var TECHNIQUES_FILE = "techniques.yaml";
|
|
@@ -32,7 +23,7 @@ function validatePath(constructedPath, allowedRoot) {
|
|
|
32
23
|
return {
|
|
33
24
|
ok: false,
|
|
34
25
|
error: new SecurityError("Path traversal detected: path escapes allowed root directory", {
|
|
35
|
-
context: { constructedPath, allowedRoot:
|
|
26
|
+
context: { constructedPath, allowedRoot: resolve(allowedRoot) }
|
|
36
27
|
})
|
|
37
28
|
};
|
|
38
29
|
}
|
|
@@ -919,7 +910,6 @@ function deduplicateFindings(findings) {
|
|
|
919
910
|
}
|
|
920
911
|
|
|
921
912
|
export {
|
|
922
|
-
resolveInsideRoot,
|
|
923
913
|
REGISTRY_PATH,
|
|
924
914
|
getProjectRoot,
|
|
925
915
|
loadTechniquesRegistry,
|
|
@@ -928,4 +918,4 @@ export {
|
|
|
928
918
|
normalizeTopicToCanonical,
|
|
929
919
|
synthesizeResearch
|
|
930
920
|
};
|
|
931
|
-
//# sourceMappingURL=chunk-
|
|
921
|
+
//# sourceMappingURL=chunk-PCMWLXT4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/research-helpers-io.ts","../src/cli/research-alignment-map.ts","../src/research/topic-aliases.ts","../src/cli/research-helpers-synthesize.ts"],"sourcesContent":["/**\n * Research Registry I/O Operations\n *\n * File operations for loading and saving research registry YAML files.\n * Includes path traversal protection per Issue #353.\n *\n * @see docs/research/RESEARCH_INDEX.md\n * @see Issue #237 (Epic #225)\n * @see Issue #353 (Security - Path traversal fix)\n */\n\nimport * as fs from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { resolveInsideRoot } from '../security/safe-path.js';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { Result } from '../core/index.js';\nimport { SecurityError, getErrorMessage } from '../core/index.js';\nimport { ParseError } from '../core/types/workflow.js';\nimport type { TechniquesRegistry, PapersRegistry } from './research-types.js';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Path to research registry directory relative to project root */\nexport const REGISTRY_PATH = 'docs/research/registry';\n\n/** Filename for techniques registry */\nexport const TECHNIQUES_FILE = 'techniques.yaml';\n\n/** Filename for papers registry */\nexport const PAPERS_FILE = 'papers.yaml';\n\n// =============================================================================\n// PROJECT ROOT\n// =============================================================================\n\n/**\n * Get the project root directory.\n * Note: Returns cwd since registry operations use explicit rootDir parameter\n */\nexport function getProjectRoot(): string {\n return process.cwd();\n}\n\n// =============================================================================\n// PATH VALIDATION\n// =============================================================================\n\n/**\n * Validates that a constructed path stays within the allowed root directory.\n * Prevents path traversal attacks (e.g., ../../../etc/passwd).\n *\n * @param constructedPath - The full path to validate\n * @param allowedRoot - The root directory that paths must be within\n * @returns Result with validated absolute path or SecurityError\n */\nfunction validatePath(constructedPath: string, allowedRoot: string): Result<string, SecurityError> {\n const resolved = resolveInsideRoot(constructedPath, allowedRoot);\n if (resolved === null) {\n return {\n ok: false,\n error: new SecurityError('Path traversal detected: path escapes allowed root directory', {\n context: { constructedPath, allowedRoot: resolve(allowedRoot) },\n }),\n };\n }\n return { ok: true, value: resolved };\n}\n\n// =============================================================================\n// LOAD OPERATIONS\n// =============================================================================\n\n/**\n * Load techniques registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with TechniquesRegistry or SecurityError/ParseError\n */\nexport async function loadTechniquesRegistry(\n rootDir?: string\n): Promise<Result<TechniquesRegistry, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as TechniquesRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load techniques registry: ${message}`) };\n }\n}\n\n/**\n * Load papers registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with PapersRegistry or SecurityError/ParseError\n */\nexport async function loadPapersRegistry(\n rootDir?: string\n): Promise<Result<PapersRegistry, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as PapersRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load papers registry: ${message}`) };\n }\n}\n\n// =============================================================================\n// SAVE OPERATIONS\n// =============================================================================\n\n/**\n * Save techniques registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The techniques registry to save\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function saveTechniquesRegistry(\n registry: TechniquesRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save techniques registry: ${message}`) };\n }\n}\n\n/**\n * Save papers registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The papers registry to save\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function savePapersRegistry(\n registry: PapersRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save papers registry: ${message}`) };\n }\n}\n","/**\n * Research Alignment Map\n *\n * Maps technique names from the research registry to canonical code paths\n * in the nexus-agents codebase. Used by research synthesis to determine\n * which paper techniques are implemented, partially implemented, or new.\n *\n * @module cli/research-alignment-map\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** Implementation status for a mapped technique. */\nexport interface TechniqueMapping {\n readonly status: 'implemented' | 'partial';\n readonly path: string;\n readonly hint?: string | undefined;\n}\n\n/** A feature gate that controls an implementation. */\nexport interface FeatureGate {\n /** Environment variable or config key. */\n readonly envVar: string;\n /** Default value when not explicitly set. */\n readonly defaultValue: string;\n /** Brief description of what the gate controls. */\n readonly description: string;\n /** Related technique names from the alignment map (if any). */\n readonly techniques?: readonly string[];\n}\n\n// =============================================================================\n// MAP\n// =============================================================================\n\n/**\n * Maps technique names to canonical code paths.\n * 'implemented' = full implementation exists matching the technique.\n * 'partial' = related code exists but doesn't fully implement the technique.\n */\nexport const TECHNIQUE_IMPLEMENTATION_MAP: ReadonlyMap<string, TechniqueMapping> = new Map([\n // Routing techniques\n ['linucb-routing', { status: 'implemented', path: 'cli-adapters/linucb-bandit.ts' }],\n ['topsis-routing', { status: 'implemented', path: 'cli-adapters/topsis-router.ts' }],\n [\n 'cascade-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'complexity-based-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'moe-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router.ts',\n hint: '5-stage composite routing selects among specialized CLI experts based on task features',\n },\n ],\n ['two-stage-routing', { status: 'implemented', path: 'cli-adapters/composite-router-stages.ts' }],\n [\n 'capability-instruction-tuning',\n {\n status: 'partial',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'Static capability profiles, not instruction-tuned',\n },\n ],\n [\n 'knn-routing',\n {\n status: 'implemented',\n path: 'routing/stages/knn-routing-stage.ts',\n hint: 'KnnRoutingStage: cosine similarity over keyword vectors, K-nearest experience patterns, weighted by success rate',\n },\n ],\n ['pilot-budget-routing', { status: 'implemented', path: 'cli-adapters/budget-router.ts' }],\n [\n 'tolerance-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router-helpers.ts',\n hint: 'TOPSIS_TOLERANCE_BAND_PERCENT (5%) identifies quality-equivalent candidates after TOPSIS ranking',\n },\n ],\n [\n 'sater-routing',\n {\n status: 'implemented',\n path: 'routing/stages/quality-constraint-stage.ts',\n hint: 'QualityConstraintStage filters models by min quality (0.7), max cost, max latency before selection',\n },\n ],\n [\n 'preference-trained-routing',\n { status: 'implemented', path: 'cli-adapters/preference-router.ts' },\n ],\n [\n 'strmac-state-routing',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory maintains state across calls (profile, experience, action cache) feeding LinUCB + weather bonus stages',\n },\n ],\n [\n 'cross-attention-routing',\n {\n status: 'implemented',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'AttentionMatrix maps task features to capability weights (configurable cross-attention)',\n },\n ],\n\n // Consensus techniques\n ['consensus-protocol', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['majority-voting', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['higher-order-voting', { status: 'implemented', path: 'consensus/higher-order-strategy.ts' }],\n [\n 'anti-conformity-weighting',\n { status: 'implemented', path: 'consensus/higher-order-strategy.ts' },\n ],\n [\n 'agreement-based-cascading',\n {\n status: 'implemented',\n path: 'consensus/engine.ts',\n hint: 'canCascadeEarly() closes proposals when outcome is mathematically determined',\n },\n ],\n [\n 'incremental-quorum',\n {\n status: 'implemented',\n path: 'consensus/incremental-quorum.ts',\n hint: 'Ambiguity detection + voter expansion via VoterExpansionCallback (#1408)',\n },\n ],\n [\n 'aegean-consensus',\n { status: 'partial', path: 'consensus/engine.ts', hint: 'Byzantine tolerance not implemented' },\n ],\n [\n 'cp-wbft-consensus',\n {\n status: 'partial',\n path: 'consensus/engine.ts',\n hint: 'No weighted Byzantine fault tolerance',\n },\n ],\n\n // Memory techniques\n ['adaptive-memory', { status: 'implemented', path: 'memory/adaptive/' }],\n ['mirix-six-type-memory', { status: 'implemented', path: 'memory/typed/' }],\n [\n 'mem0-memory-architecture',\n { status: 'partial', path: 'memory/', hint: 'Multi-backend memory but not mem0 pattern' },\n ],\n [\n 'graph-based-memory',\n {\n status: 'partial',\n path: 'memory/belief/',\n hint: 'Belief triples are graph-like but not full graph DB',\n },\n ],\n ['experience-memory', { status: 'implemented', path: 'memory/session/' }],\n ['hindsight-belief-memory', { status: 'implemented', path: 'memory/belief/' }],\n [\n 'profile-memory',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory stores model preferences per task type and feeds recommendations into composite router via PERSISTENCE_AWARE_FLAGS',\n },\n ],\n [\n 'action-memory',\n {\n status: 'implemented',\n path: 'orchestration/outcomes/',\n hint: 'OutcomeStore records actions+results+context with query-by-category/CLI/time and cross-session persistence',\n },\n ],\n ['reflection-memory', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n [\n 'history-encoding',\n {\n status: 'partial',\n path: 'context/token-counter.ts',\n hint: 'Token counting exists but no learned history encoding',\n },\n ],\n\n // Orchestration techniques\n [\n 'aflow-mcts-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow scaffolding exists but MCTS not implemented',\n },\n ],\n [\n 'dynamic-agent-selection',\n { status: 'implemented', path: 'orchestration/aorchestra/agent-planner.ts' },\n ],\n ['dynamic-subagent-creation', { status: 'implemented', path: 'mcp/tools/create-expert.ts' }],\n ['role-based-protocols', { status: 'implemented', path: 'agents/expert-roles.ts' }],\n [\n 'rule-based-coordination',\n { status: 'implemented', path: 'orchestration/aorchestra/worker-dispatcher.ts' },\n ],\n [\n 'temporal-graph-orchestration',\n {\n status: 'partial',\n path: 'orchestration/graph/',\n hint: 'Graph workflows exist but not temporal-aware',\n },\n ],\n [\n 'model-based-coordination',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/',\n hint: 'Worker dispatch but not model-based coordination theory',\n },\n ],\n [\n 'trinity-roles',\n {\n status: 'partial',\n path: 'agents/expert-roles.ts',\n hint: '10 expert roles, not trinity pattern',\n },\n ],\n [\n 'sew-self-evolving-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow framework but no self-evolution loop',\n },\n ],\n [\n 'scaling-coordination-predictor',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/agent-planner.ts',\n hint: 'Wave sizing but no scaling prediction',\n },\n ],\n\n // Learning techniques\n [\n 'self-refine-loop',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'recursive-improvement',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'rl-orchestrator',\n {\n status: 'implemented',\n path: 'cli-adapters/linucb-bandit.ts',\n hint: 'LinUCB contextual bandit actively selects models via explore-exploit in routing pipeline',\n },\n ],\n ['reflexion-verbal-rl', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n\n // Source-derived techniques (Wave 6 — from open-source project analysis)\n ['failure-lesson-injection', { status: 'implemented', path: 'orchestration/failure-lessons.ts' }],\n [\n 'skill-relevance-matching',\n {\n status: 'implemented',\n path: 'agents/experts/skill-matcher.ts',\n hint: 'Matches task keywords to agent skill descriptions for optimal routing',\n },\n ],\n [\n 'context-rot-prevention',\n {\n status: 'implemented',\n path: 'agents/context-pruner.ts',\n hint: 'Token-efficient context pruning prevents quality degradation in long sessions',\n },\n ],\n [\n 'wave-based-parallel-execution',\n {\n status: 'implemented',\n path: 'orchestration/aorchestra/worker-dispatcher.ts',\n hint: 'AOrchestra worker dispatch with cross-wave context sharing',\n },\n ],\n [\n 'write-time-deduplication',\n {\n status: 'implemented',\n path: 'mcp/tools/memory-write.ts',\n hint: 'Semantic dedup at write time prevents memory bloat',\n },\n ],\n]);\n\n// =============================================================================\n// FEATURE GATE INVENTORY\n// =============================================================================\n\n/** Inventory of feature gates linked to research-aligned techniques. */\nexport const FEATURE_GATE_INVENTORY: readonly FeatureGate[] = [\n {\n envVar: 'NEXUS_V2_MODE',\n defaultValue: 'full',\n description: 'V2 pipeline mode (off/partial/full)',\n techniques: ['two-stage-routing', 'cascade-routing'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA',\n defaultValue: 'true',\n description: 'AOrchestra dynamic agent planning',\n techniques: ['dynamic-agent-selection', 'model-based-coordination'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA_DISPATCH',\n defaultValue: 'true',\n description: 'AOrchestra worker dispatch',\n techniques: ['rule-based-coordination', 'self-refine-loop'],\n },\n {\n envVar: 'NEXUS_PERSIST_LEARNING',\n defaultValue: 'true',\n description: 'Cross-session routing persistence',\n techniques: ['linucb-routing', 'preference-trained-routing', 'experience-memory'],\n },\n {\n envVar: 'NEXUS_REFLECTIVE_MEMORY',\n defaultValue: 'shadow',\n description: 'Reflective memory retrieval (shadow=default, true=full, false=off)',\n techniques: ['reflection-memory', 'adaptive-memory', 'reflexion-verbal-rl'],\n },\n {\n envVar: 'NEXUS_BILLING_MODE',\n defaultValue: 'plan',\n description: 'Cost mode (plan=strongest, api=cost-aware)',\n techniques: ['pilot-budget-routing', 'topsis-routing'],\n },\n {\n envVar: 'NEXUS_WORKER_MAX_CALLS',\n defaultValue: '6',\n description: 'Max model calls per orchestrate',\n techniques: ['self-refine-loop', 'recursive-improvement'],\n },\n { envVar: 'NEXUS_AUTH_ENABLED', defaultValue: 'true', description: 'Server authentication' },\n { envVar: 'NEXUS_EVENTBUS_ENABLED', defaultValue: 'true', description: 'EventBus A2A bridge' },\n {\n envVar: 'NEXUS_RATE_LIMIT_ENABLED',\n defaultValue: 'true',\n description: 'Token-bucket rate limiter',\n },\n {\n envVar: 'NEXUS_CIRCUIT_BREAKER_THRESHOLD',\n defaultValue: '5',\n description: 'Circuit breaker failure threshold',\n },\n {\n envVar: 'NEXUS_V2_POLICY_MODE',\n defaultValue: 'block',\n description: 'Policy enforcement (off/warn/block)',\n },\n { envVar: 'NEXUS_LOG_LEVEL', defaultValue: 'info', description: 'Logging verbosity' },\n {\n envVar: 'NEXUS_DISABLE_SESSIONS',\n defaultValue: 'false',\n description: 'Disable session tracking',\n },\n {\n envVar: 'NEXUS_DISABLE_METRICS',\n defaultValue: 'false',\n description: 'Disable metrics tracking',\n },\n {\n envVar: 'NEXUS_ALLOW_MOCK_ORCHESTRATION',\n defaultValue: 'false',\n description: 'Allow mock orchestration (test/CI)',\n },\n {\n envVar: 'NEXUS_MAX_CONCURRENT_EXPERTS',\n defaultValue: '6',\n description: 'Expert pool semaphore capacity',\n },\n {\n envVar: 'NEXUS_VOTE_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Consensus vote timeout override',\n },\n {\n envVar: 'NEXUS_EXPERT_TIMEOUT_MS',\n defaultValue: '120000',\n description: 'Expert handler timeout override',\n },\n {\n envVar: 'NEXUS_WORKER_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Worker subprocess timeout override',\n },\n];\n","/**\n * Topic alias map for normalizing free-form topic strings to canonical topics.\n *\n * Maps 200+ free-form topic strings found in papers.yaml to 12 canonical topics.\n * Used by normalizeTopicToCanonical() in research-schemas.ts.\n *\n * @module research/topic-aliases\n * @see Issue #1578 — Topic taxonomy normalization\n */\n\n/**\n * Map of free-form topic strings to canonical topics.\n */\nexport const TOPIC_ALIASES: Readonly<Record<string, string>> = {\n // → consensus\n voting: 'consensus',\n 'consensus-voting': 'consensus',\n debate: 'consensus',\n quorum: 'consensus',\n byzantine: 'consensus',\n 'anti-conformity': 'consensus',\n 'agreement-based': 'consensus',\n 'correlation-aware': 'consensus',\n 'LLM consensus and multi-agent voting mechanisms': 'consensus',\n 'tolerance-parameter': 'consensus',\n\n // → routing\n 'model-routing': 'routing',\n 'model routing': 'routing',\n 'llm-routing': 'routing',\n cascade: 'routing',\n 'cascade-routing': 'routing',\n 'cost-optimization': 'routing',\n 'cost-reduction': 'routing',\n 'model-selection': 'routing',\n topsis: 'routing',\n linucb: 'routing',\n 'contextual-bandit': 'routing',\n 'quality-constrained': 'routing',\n 'budget-constraints': 'routing',\n 'unified-routing': 'routing',\n 'query-model-matching': 'routing',\n 'adaptive model routing and selection optimization': 'routing',\n 'multi-model routing optimization': 'routing',\n 'Single-head cross-attention for query-model matching': 'routing',\n 'performance-cost-tradeoff': 'routing',\n 'task-routing': 'routing',\n 'difficulty-estimation': 'routing',\n 'score-based': 'routing',\n 'optimal-weighting': 'routing',\n 'hierarchical-filtering': 'routing',\n 'preference-optimization': 'routing',\n 'preference-data': 'routing',\n dpo: 'routing',\n 'cross-attention': 'routing',\n 'cma-es': 'routing',\n profile: 'routing',\n prediction: 'routing',\n lightweight: 'routing',\n bayesian: 'routing',\n 'quality-diversity': 'routing',\n 'resource-optimization': 'routing',\n 'routing-latency': 'routing',\n optimization: 'routing',\n 'model-merging': 'routing',\n 'model-zoo': 'routing',\n\n // → memory\n 'context-management': 'memory',\n 'context-compression': 'memory',\n 'context-control': 'memory',\n compression: 'memory',\n 'kv-cache': 'memory',\n 'long-context': 'memory',\n 'long-term-memory': 'memory',\n 'episodic-memory': 'memory',\n 'graph-memory': 'memory',\n 'hierarchical-memory': 'memory',\n 'agentic-memory': 'memory',\n 'lifelong-learning': 'memory',\n 'cross-session-learning': 'memory',\n 'continual-learning': 'memory',\n 'self-editing-memory': 'memory',\n 'six-type-memory': 'memory',\n 'belief-memory': 'memory',\n 'belief-state': 'memory',\n 'action-memory': 'memory',\n 'memory-evolution': 'memory',\n 'virtual-context': 'memory',\n paging: 'memory',\n 'prompt-compression': 'memory',\n 'learned-compression': 'memory',\n zettelkasten: 'memory',\n 'knowledge-distillation': 'memory',\n 'history-encoding': 'memory',\n 'ictm-tuple': 'memory',\n 'latent-space': 'memory',\n 'vector-db': 'memory',\n embedding: 'memory',\n 'Taxonomy of context management strategies': 'memory',\n 'Task-specific context compression': 'memory',\n 'Learned compression modules': 'memory',\n rag: 'memory',\n 'retrieval augmented generation': 'memory',\n svd: 'memory',\n 'svd-mutation': 'memory',\n vae: 'memory',\n knn: 'memory',\n experience: 'memory',\n 'state-aware': 'memory',\n 'temporal-graph': 'memory',\n versioning: 'memory',\n\n // → code-generation\n 'code-repair': 'code-generation',\n 'code-agent': 'code-generation',\n 'code-review': 'code-generation',\n 'software-engineering': 'code-generation',\n 'swe-bench': 'code-generation',\n 'self-improvement': 'code-generation',\n 'self-evolving': 'code-generation',\n 'self-debug': 'code-generation',\n 'self-modification': 'code-generation',\n 'skill-library': 'code-generation',\n 'skill-discovery': 'code-generation',\n 'code review benchmarks': 'code-generation',\n 'code generation evaluation': 'code-generation',\n 'execution-feedback': 'code-generation',\n\n // → cli-tools\n mcp: 'cli-tools',\n 'MCP protocol': 'cli-tools',\n 'MCP security': 'cli-tools',\n 'MCP Security': 'cli-tools',\n 'mcp-applications': 'cli-tools',\n 'model-context-protocol': 'cli-tools',\n puppeteer: 'cli-tools',\n streaming: 'cli-tools',\n integration: 'cli-tools',\n\n // → orchestration\n 'multi-agent': 'orchestration',\n 'multi-agent-systems': 'orchestration',\n 'multi-agent orchestration': 'orchestration',\n 'Multi-Agent Orchestration': 'orchestration',\n 'multi-agent-orchestration': 'orchestration',\n 'multi-agent coordination': 'orchestration',\n 'multi-agent-coordination': 'orchestration',\n 'multi-agent-worker-dispatch': 'orchestration',\n 'multi-agent reliability': 'orchestration',\n 'multi-agent-rl': 'orchestration',\n coordination: 'orchestration',\n coordinator: 'orchestration',\n collaboration: 'orchestration',\n 'graph-orchestration': 'orchestration',\n 'agent architecture': 'orchestration',\n 'dynamic-agent-creation': 'orchestration',\n 'specialized-agents': 'orchestration',\n 'thinker-worker-verifier': 'orchestration',\n 'two-agent': 'orchestration',\n 'meta-agent': 'orchestration',\n agents: 'orchestration',\n 'workflow-optimization': 'orchestration',\n 'workflow-generation': 'orchestration',\n 'agent-communication': 'orchestration',\n 'inter-agent': 'orchestration',\n 'gvu-operator': 'orchestration',\n 'rubber-duck': 'orchestration',\n 'parallel-exploration': 'orchestration',\n kubernetes: 'orchestration',\n 'scale-to-zero': 'orchestration',\n edge: 'orchestration',\n llm: 'orchestration',\n multimodal: 'orchestration',\n production: 'orchestration',\n hybrid: 'orchestration',\n 'automatic-discovery': 'orchestration',\n roadmap: 'orchestration',\n\n // → security\n 'prompt injection defense': 'security',\n 'inter-agent-security': 'security',\n 'agent security': 'security',\n compliance: 'security',\n 'formal-verification': 'security',\n 'formal-safety': 'security',\n\n // → evaluation\n benchmark: 'evaluation',\n benchmarking: 'evaluation',\n survey: 'evaluation',\n 'autonomous agent evaluation benchmarks': 'evaluation',\n 'evaluation-methods': 'evaluation',\n 'LLM evaluation': 'evaluation',\n 'hallucination-detection': 'evaluation',\n 'self-evaluation': 'evaluation',\n 'confidence-probe': 'evaluation',\n 'confidence-aware': 'evaluation',\n verifier: 'evaluation',\n observability: 'evaluation',\n theoretical: 'evaluation',\n 'post-deployment': 'evaluation',\n capability: 'evaluation',\n 'knowledge-gaps': 'evaluation',\n helm: 'evaluation',\n\n // → safety\n 'agentic-safety': 'safety',\n 'agentic AI safety': 'safety',\n 'safety-evaluation': 'safety',\n 'reward-modeling': 'safety',\n 'constitutional-ai': 'safety',\n 'hazard-analysis': 'safety',\n stpa: 'safety',\n 'risk-assessment': 'safety',\n 'fault-tolerance': 'safety',\n 'ai-feedback': 'safety',\n rlaif: 'safety',\n 'human-in-the-loop': 'safety',\n feedback: 'safety',\n 'feedback-loop': 'safety',\n 'feedback-learning': 'safety',\n anthropic: 'safety',\n\n // → planning\n 'decision-making': 'planning',\n 'tree-search': 'planning',\n 'tree-structure': 'planning',\n 'multi-tree': 'planning',\n mcts: 'planning',\n backtrack: 'planning',\n hindsight: 'planning',\n 'task-specific': 'planning',\n\n // → tool-use\n 'tool use': 'tool-use',\n 'tool-augmented reasoning and function calling': 'tool-use',\n 'tool routing optimization': 'tool-use',\n 'dynamic-linking': 'tool-use',\n 'Sparse outcome rewards reduce tool calls by 72%': 'tool-use',\n\n // → reasoning\n 'test-time': 'reasoning',\n 'test-time-scaling': 'reasoning',\n 'inference-scaling': 'reasoning',\n 'inference-optimization': 'reasoning',\n 'self-critique': 'reasoning',\n 'self-reflection': 'reasoning',\n 'self-referential': 'reasoning',\n 'self-play': 'reasoning',\n reflexion: 'reasoning',\n reflection: 'reasoning',\n 'reasoning-optimization': 'reasoning',\n 'meta-thinking': 'reasoning',\n scaling: 'reasoning',\n recursive: 'reasoning',\n 'trajectory-abstraction': 'reasoning',\n 'verbal-rl': 'reasoning',\n exploration: 'reasoning',\n 'Reducible uncertainty modeling across agent trajectories': 'reasoning',\n 'Environmental feedback reduces uncertainty at decision gates': 'reasoning',\n 'reinforcement-learning': 'reasoning',\n transformer: 'reasoning',\n ssm: 'reasoning',\n 'sparse-activation': 'reasoning',\n 'behavior-distillation': 'reasoning',\n 'training-free': 'reasoning',\n 'transfer-learning': 'reasoning',\n 'instruction-tuning': 'reasoning',\n 'Dense process rewards improve performance by 22%': 'reasoning',\n 'prompt-optimization': 'reasoning',\n};\n\n/**\n * Normalize a free-form topic string to a canonical topic.\n * Returns the canonical topic if a mapping exists, otherwise the original string.\n */\nexport function normalizeTopicToCanonical(topic: string): string {\n return TOPIC_ALIASES[topic] ?? topic;\n}\n","/**\n * Research Synthesis Helper\n *\n * Groups papers by topic cluster and generates structured synthesis\n * summaries with themes, findings, and implementation opportunities.\n *\n * @module cli/research-helpers-synthesize\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\nimport { loadPapersRegistry } from './research-helpers-io.js';\nimport type { PapersRegistry } from './research-types.js';\nimport type { Result } from '../core/result.js';\nimport { getErrorMessage } from '../core/index.js';\nimport { TECHNIQUE_IMPLEMENTATION_MAP, FEATURE_GATE_INVENTORY } from './research-alignment-map.js';\nimport { normalizeTopicToCanonical } from '../research/topic-aliases.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** A paper entry from the registry, simplified for synthesis. */\nexport interface SynthesisPaper {\n readonly id: string;\n readonly title: string;\n readonly topics: readonly string[];\n readonly tags: readonly string[];\n readonly summary: string;\n readonly keyFindings: readonly string[];\n readonly relevance: string;\n readonly implementationStatus: string;\n readonly techniquesExtracted: readonly string[];\n readonly qualityScore: number;\n readonly evidenceTier: 'high' | 'medium' | 'low';\n}\n\n/** A cluster of related papers grouped by topic. */\nexport interface PaperCluster {\n readonly topic: string;\n readonly papers: readonly SynthesisPaper[];\n readonly paperCount: number;\n}\n\n/** A technique aligned to an existing implementation. */\nexport interface TechniqueAlignment {\n readonly technique: string;\n readonly status: 'implemented' | 'partial' | 'not-started';\n readonly canonicalPath?: string | undefined;\n readonly improvementHint?: string | undefined;\n}\n\n/** Quality distribution within a cluster. */\nexport interface QualityDistribution {\n readonly avgScore: number;\n readonly high: number;\n readonly medium: number;\n readonly low: number;\n}\n\n/** Synthesis output for a single topic cluster. */\nexport interface ClusterSynthesis {\n readonly topic: string;\n readonly paperCount: number;\n readonly papers: readonly string[];\n readonly commonThemes: readonly string[];\n readonly keyInsights: readonly string[];\n readonly techniques: readonly string[];\n readonly implementationOpportunities: readonly string[];\n readonly gaps: readonly string[];\n readonly alignedTechniques: readonly TechniqueAlignment[];\n readonly qualityDistribution: QualityDistribution;\n}\n\n/** Summary of alignment between research and implementation. */\nexport interface AlignmentSummary {\n readonly implemented: number;\n readonly partial: number;\n readonly notStarted: number;\n readonly total: number;\n readonly topOpportunities: readonly string[];\n}\n\n/** Summary of a single feature gate for synthesis output. */\nexport interface FeatureGateStatus {\n readonly envVar: string;\n readonly defaultValue: string;\n readonly description: string;\n readonly linkedTechniqueCount: number;\n}\n\n/** Full synthesis result across all clusters. */\nexport interface SynthesisResult {\n readonly clusters: readonly ClusterSynthesis[];\n readonly totalPapers: number;\n readonly topicCount: number;\n readonly crossCuttingThemes: readonly string[];\n readonly alignmentSummary: AlignmentSummary;\n readonly featureGates: readonly FeatureGateStatus[];\n}\n\n/** Error for synthesis operations. */\nexport interface SynthesisError {\n readonly code: 'LOAD_ERROR' | 'NO_PAPERS';\n readonly message: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Minimum papers in a cluster to generate cross-cutting themes. */\nconst MIN_CROSS_CUTTING_CLUSTER_SIZE = 2;\n\n/** Tags that appear across many topics and indicate cross-cutting themes. */\nconst CROSS_CUTTING_TAG_THRESHOLD = 3;\n\n// =============================================================================\n// PUBLIC API\n// =============================================================================\n\n/**\n * Synthesize the research registry by grouping papers into topic clusters\n * and generating structured summaries.\n *\n * @param topicFilter - Optional topic to filter to a single cluster\n * @returns Structured synthesis result\n */\nexport async function synthesizeResearch(\n topicFilter?: string\n): Promise<Result<SynthesisResult, SynthesisError>> {\n const registryResult = await loadPapersRegistry();\n if (!registryResult.ok) {\n return {\n ok: false,\n error: {\n code: 'LOAD_ERROR',\n message: `Failed to load papers: ${getErrorMessage(registryResult.error)}`,\n },\n };\n }\n\n const papers = extractPapers(registryResult.value);\n if (papers.length === 0) {\n return {\n ok: false,\n error: { code: 'NO_PAPERS', message: 'No papers found in registry' },\n };\n }\n\n const clusters = groupByTopic(papers);\n const filtered =\n topicFilter !== undefined ? clusters.filter((c) => c.topic === topicFilter) : clusters;\n\n const syntheses = filtered.map(synthesizeCluster);\n const crossCutting = findCrossCuttingThemes(filtered);\n const alignmentSummary = buildAlignmentSummary(syntheses);\n const featureGates = buildFeatureGateSummary();\n\n return {\n ok: true,\n value: {\n clusters: syntheses,\n totalPapers: papers.length,\n topicCount: filtered.length,\n crossCuttingThemes: crossCutting,\n alignmentSummary,\n featureGates,\n },\n };\n}\n\n// =============================================================================\n// EXTRACTION\n// =============================================================================\n\n/**\n * Safely convert a field that types say is `readonly string[]` but may be\n * null/undefined at runtime (YAML parsing of empty array fields).\n */\nfunction safeArray(value: readonly string[]): string[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- YAML parsing can yield null despite type\n if (value === null || value === undefined) return [];\n return Array.from(value);\n}\n\n/** Extract papers from the registry structure. */\nfunction extractPapers(registry: PapersRegistry): SynthesisPaper[] {\n return Object.entries(registry.papers).map(([id, p]) => ({\n id,\n title: p.title,\n topics: safeArray(p.topics),\n tags: safeArray(p.tags),\n summary: p.summary.trim(),\n keyFindings: safeArray(p.key_findings),\n relevance: p.relevance,\n implementationStatus: p.implementation_status,\n techniquesExtracted: safeArray(p.techniques_extracted),\n qualityScore: p.quality_score ?? 0,\n evidenceTier: p.evidence_tier ?? 'low',\n }));\n}\n\n// =============================================================================\n// GROUPING\n// =============================================================================\n\n/** Group papers by primary topic into clusters, normalizing free-form topics. */\nfunction groupByTopic(papers: readonly SynthesisPaper[]): PaperCluster[] {\n const topicMap = new Map<string, SynthesisPaper[]>();\n\n for (const paper of papers) {\n for (const rawTopic of paper.topics) {\n const topic = normalizeTopicToCanonical(rawTopic);\n const existing = topicMap.get(topic);\n if (existing !== undefined) {\n existing.push(paper);\n } else {\n topicMap.set(topic, [paper]);\n }\n }\n }\n\n const clusters: PaperCluster[] = [];\n for (const [topic, unsortedPapers] of topicMap) {\n // Sort papers within cluster by quality_score descending (high-quality first)\n const topicPapers = [...unsortedPapers].sort((a, b) => b.qualityScore - a.qualityScore);\n clusters.push({\n topic,\n papers: topicPapers,\n paperCount: topicPapers.length,\n });\n }\n\n return clusters.sort((a, b) => b.paperCount - a.paperCount);\n}\n\n// =============================================================================\n// SYNTHESIS\n// =============================================================================\n\n/** Generate synthesis for a single topic cluster. */\n/** Compute quality score distribution for a set of papers. */\nfunction computeClusterQuality(papers: readonly SynthesisPaper[]): QualityDistribution {\n const scores = papers.map((p) => p.qualityScore);\n const totalScore = scores.reduce((sum, s) => sum + s, 0);\n return {\n avgScore: scores.length > 0 ? Math.round((totalScore / scores.length) * 10) / 10 : 0,\n high: papers.filter((p) => p.evidenceTier === 'high').length,\n medium: papers.filter((p) => p.evidenceTier === 'medium').length,\n low: papers.filter((p) => p.evidenceTier === 'low').length,\n };\n}\n\nfunction synthesizeCluster(cluster: PaperCluster): ClusterSynthesis {\n const allTags = collectFrequencies(cluster.papers.flatMap((p) => [...p.tags]));\n const allTechniques = collectFrequencies(\n cluster.papers.flatMap((p) => [...p.techniquesExtracted])\n );\n const allFindings = cluster.papers.flatMap((p) => [...p.keyFindings]);\n\n // Common themes: tags that appear in 2+ papers\n const commonThemes = [...allTags.entries()]\n .filter(([, count]) => count >= MIN_CROSS_CUTTING_CLUSTER_SIZE)\n .sort((a, b) => b[1] - a[1])\n .map(([tag]) => tag);\n\n // Techniques across the cluster\n const techniques = [...allTechniques.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([tech, count]) => (count > 1 ? `${tech} (${String(count)} papers)` : tech));\n\n // Implementation opportunities: techniques not yet implemented\n const notStarted = cluster.papers\n .filter((p) => p.implementationStatus === 'not-started')\n .flatMap((p) => [...p.techniquesExtracted]);\n const uniqueOpportunities = [...new Set(notStarted)];\n\n // Gaps: topics with few papers or missing techniques\n const gaps: string[] = [];\n if (cluster.paperCount === 1) {\n gaps.push(`Only 1 paper — more research needed on ${cluster.topic}`);\n }\n const highRelevanceUnimplemented = cluster.papers.filter(\n (p) => p.relevance === 'high' && p.implementationStatus === 'not-started'\n );\n if (highRelevanceUnimplemented.length > 0) {\n gaps.push(\n `${String(highRelevanceUnimplemented.length)} high-relevance paper(s) not yet implemented`\n );\n }\n\n // Alignment analysis: map techniques to existing implementations\n const allTechNames = [...allTechniques.keys()];\n const alignedTechniques = analyzeClusterAlignment(allTechNames);\n\n const qualityDistribution = computeClusterQuality(cluster.papers);\n\n // Add quality gap if most papers are low-quality\n if (qualityDistribution.low > qualityDistribution.high + qualityDistribution.medium) {\n gaps.push(\n `Mostly low-evidence papers (${String(qualityDistribution.low)}/${String(cluster.paperCount)}) — findings need stronger validation`\n );\n }\n\n return {\n topic: cluster.topic,\n paperCount: cluster.paperCount,\n papers: cluster.papers.map((p) => p.title),\n commonThemes,\n keyInsights: deduplicateFindings(allFindings).slice(0, 10),\n techniques,\n implementationOpportunities: uniqueOpportunities,\n gaps,\n alignedTechniques,\n qualityDistribution,\n };\n}\n\n/** Find themes that span multiple topic clusters. */\nfunction findCrossCuttingThemes(clusters: readonly PaperCluster[]): string[] {\n const tagToTopics = new Map<string, Set<string>>();\n\n for (const cluster of clusters) {\n for (const paper of cluster.papers) {\n for (const tag of paper.tags) {\n const existing = tagToTopics.get(tag);\n if (existing !== undefined) {\n existing.add(cluster.topic);\n } else {\n tagToTopics.set(tag, new Set([cluster.topic]));\n }\n }\n }\n }\n\n return [...tagToTopics.entries()]\n .filter(([, topics]) => topics.size >= CROSS_CUTTING_TAG_THRESHOLD)\n .sort((a, b) => b[1].size - a[1].size)\n .map(([tag, topics]) => `${tag} (spans: ${[...topics].join(', ')})`);\n}\n\n// =============================================================================\n// ALIGNMENT ANALYSIS\n// =============================================================================\n\n/** Analyze technique alignment for a cluster. */\nfunction analyzeClusterAlignment(techniques: readonly string[]): TechniqueAlignment[] {\n const alignments: TechniqueAlignment[] = [];\n\n for (const tech of techniques) {\n // Strip count annotation like \"technique (2 papers)\"\n const baseTech = tech.replace(/\\s*\\(\\d+\\s*papers?\\)$/, '');\n const mapping = TECHNIQUE_IMPLEMENTATION_MAP.get(baseTech);\n\n if (mapping !== undefined) {\n alignments.push({\n technique: baseTech,\n status: mapping.status,\n canonicalPath: mapping.path,\n ...(mapping.hint !== undefined ? { improvementHint: mapping.hint } : {}),\n });\n } else {\n alignments.push({ technique: baseTech, status: 'not-started' });\n }\n }\n\n return alignments;\n}\n\n/** Build alignment summary across all clusters. */\nfunction buildAlignmentSummary(clusters: readonly ClusterSynthesis[]): AlignmentSummary {\n const allAlignments = clusters.flatMap((c) => c.alignedTechniques);\n const implemented = allAlignments.filter((a) => a.status === 'implemented').length;\n const partial = allAlignments.filter((a) => a.status === 'partial').length;\n const notStarted = allAlignments.filter((a) => a.status === 'not-started').length;\n\n // Top opportunities: partial implementations with hints (most improvable)\n const opportunities = allAlignments\n .filter((a) => a.status === 'partial' && a.improvementHint !== undefined)\n .map((a) => `${a.technique}: ${a.improvementHint ?? ''}`)\n .slice(0, 10);\n\n return {\n implemented,\n partial,\n notStarted,\n total: allAlignments.length,\n topOpportunities: opportunities,\n };\n}\n\n/** Build feature gate summary from the inventory. */\nfunction buildFeatureGateSummary(): FeatureGateStatus[] {\n return FEATURE_GATE_INVENTORY.map((g) => ({\n envVar: g.envVar,\n defaultValue: g.defaultValue,\n description: g.description,\n linkedTechniqueCount: g.techniques?.length ?? 0,\n }));\n}\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\nfunction collectFrequencies(items: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const item of items) {\n counts.set(item, (counts.get(item) ?? 0) + 1);\n }\n return counts;\n}\n\n/** Deduplicate findings by removing near-identical strings. */\nfunction deduplicateFindings(findings: readonly string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const finding of findings) {\n const normalized = finding.toLowerCase().trim();\n if (normalized.length === 0) continue;\n if (seen.has(normalized)) continue;\n seen.add(normalized);\n result.push(finding);\n }\n return result;\n}\n"],"mappings":"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","names":[]}
|