nexus-agents 2.29.0 → 2.29.2
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/adaptive-memory-5VP5WWTE.js +15 -0
- package/dist/chunk-5COIDGQJ.js +1585 -0
- package/dist/chunk-5COIDGQJ.js.map +1 -0
- package/dist/{chunk-HWDBNDUX.js → chunk-63AJLNKU.js} +2 -2
- package/dist/chunk-66NNHMVB.js +195 -0
- package/dist/chunk-66NNHMVB.js.map +1 -0
- package/dist/chunk-AP2FD37C.js +127 -0
- package/dist/chunk-AP2FD37C.js.map +1 -0
- package/dist/chunk-BC3M4VLP.js +359 -0
- package/dist/chunk-BC3M4VLP.js.map +1 -0
- package/dist/chunk-BQ4YXGGQ.js +127 -0
- package/dist/chunk-BQ4YXGGQ.js.map +1 -0
- package/dist/{chunk-ZBZJHXRT.js → chunk-CW2Z773T.js} +19 -347
- package/dist/chunk-CW2Z773T.js.map +1 -0
- package/dist/chunk-DDQGAVQA.js +944 -0
- package/dist/chunk-DDQGAVQA.js.map +1 -0
- package/dist/chunk-ED6VQWNG.js +63 -0
- package/dist/chunk-ED6VQWNG.js.map +1 -0
- package/dist/{chunk-7F6HYUIY.js → chunk-EPMBGZQX.js} +16 -97
- package/dist/chunk-EPMBGZQX.js.map +1 -0
- package/dist/chunk-GX436VRU.js +931 -0
- package/dist/chunk-GX436VRU.js.map +1 -0
- package/dist/{chunk-IMWYKX4H.js → chunk-HSOPD265.js} +444 -399
- package/dist/chunk-HSOPD265.js.map +1 -0
- package/dist/{chunk-S3BKWNST.js → chunk-J245RJGW.js} +680 -1436
- package/dist/chunk-J245RJGW.js.map +1 -0
- package/dist/{chunk-I6YDS23R.js → chunk-KQIDTE52.js} +2 -2
- package/dist/{chunk-POBO4G2P.js → chunk-LDIN2PLV.js} +250 -110
- package/dist/chunk-LDIN2PLV.js.map +1 -0
- package/dist/{chunk-KGDG6PWZ.js → chunk-LKDHAJJB.js} +2 -2
- package/dist/{chunk-T7PU3NPQ.js → chunk-NKGTEJYU.js} +7 -5
- package/dist/{chunk-T7PU3NPQ.js.map → chunk-NKGTEJYU.js.map} +1 -1
- package/dist/chunk-QGODFK36.js +122 -0
- package/dist/chunk-QGODFK36.js.map +1 -0
- package/dist/{chunk-DAMRMAM2.js → chunk-QSNAFOE6.js} +12369 -14499
- package/dist/chunk-QSNAFOE6.js.map +1 -0
- package/dist/chunk-TL2GJMJ5.js +700 -0
- package/dist/chunk-TL2GJMJ5.js.map +1 -0
- package/dist/{chunk-WSK4VSXP.js → chunk-V6MSPUQF.js} +2 -2
- package/dist/chunk-VZ2YOQWU.js +90 -0
- package/dist/chunk-VZ2YOQWU.js.map +1 -0
- package/dist/{chunk-5VZLXMO7.js → chunk-WSYJN7BI.js} +7 -6
- package/dist/chunk-WSYJN7BI.js.map +1 -0
- package/dist/chunk-Y477EGI4.js +356 -0
- package/dist/chunk-Y477EGI4.js.map +1 -0
- package/dist/{chunk-HH5LVGEE.js → chunk-Z4OZ25VS.js} +4 -4
- package/dist/cli-circuit-breaker-6EJO3PPU.js +13 -0
- package/dist/cli.js +123 -68
- package/dist/cli.js.map +1 -1
- package/dist/codebase-search-CZUA37RU.js +9 -0
- package/dist/{composite-router-YPRWVTRB.js → composite-router-JD7URTC2.js} +2 -2
- package/dist/{consensus-vote-DBE6RNZG.js → consensus-vote-COW34Q2Y.js} +7 -5
- package/dist/{dist-7PQR2BQB.js → dist-CV74KUT7.js} +1302 -805
- package/dist/dist-CV74KUT7.js.map +1 -0
- package/dist/{doctor-deep-AWE7SRU6.js → doctor-deep-4A4X5X6U.js} +3 -3
- package/dist/expert-bridge-J36C7VES.js +10 -0
- package/dist/{expert-config-FHNBQRX2.js → expert-config-MQ5OJE3U.js} +2 -2
- package/dist/{factory-O5C7ZBZO.js → factory-4Z4RSUYE.js} +5 -4
- package/dist/{factory-PCHGQ3ZG.js → factory-NHORX63J.js} +4 -3
- package/dist/index.d.ts +507 -42
- package/dist/index.js +331 -78
- package/dist/index.js.map +1 -1
- package/dist/issue-triage-TIG3RKXF.js +15 -0
- package/dist/{mcp-config-AUZQPUBY.js → mcp-config-ETY7GFGW.js} +3 -3
- package/dist/mobimem-5PAAMVFR.js +13 -0
- package/dist/mobimem-5PAAMVFR.js.map +1 -0
- package/dist/repo-analyze-HWMXSK5C.js +24 -0
- package/dist/repo-analyze-HWMXSK5C.js.map +1 -0
- package/dist/repo-security-plan-KQB3ZJTE.js +17 -0
- package/dist/repo-security-plan-KQB3ZJTE.js.map +1 -0
- package/dist/research-helpers-synthesize-ZMERZZ5B.js +10 -0
- package/dist/research-helpers-synthesize-ZMERZZ5B.js.map +1 -0
- package/dist/{routing-memory-QY3XMU2R.js → routing-memory-3ES3OHLM.js} +2 -2
- package/dist/routing-memory-3ES3OHLM.js.map +1 -0
- package/dist/{session-memory-3MBCE5KS.js → session-memory-E2OE2CYR.js} +3 -3
- package/dist/session-memory-E2OE2CYR.js.map +1 -0
- package/dist/{setup-command-IQ4MD3FT.js → setup-command-CMCQRBJF.js} +7 -6
- package/dist/setup-command-CMCQRBJF.js.map +1 -0
- package/dist/{setup-config-5YUPLDXF.js → setup-config-KITOPV7V.js} +3 -3
- package/dist/setup-config-KITOPV7V.js.map +1 -0
- package/dist/shared-memory-AEO2HJLC.js +8 -0
- package/dist/shared-memory-AEO2HJLC.js.map +1 -0
- package/dist/symbol-extractor-UEBANFSN.js +10 -0
- package/dist/symbol-extractor-UEBANFSN.js.map +1 -0
- package/dist/{weather-report-CC2C4KAX.js → weather-report-KUSVNXDZ.js} +2 -2
- package/dist/weather-report-KUSVNXDZ.js.map +1 -0
- package/package.json +14 -13
- package/dist/chunk-5VZLXMO7.js.map +0 -1
- package/dist/chunk-7F6HYUIY.js.map +0 -1
- package/dist/chunk-DAMRMAM2.js.map +0 -1
- package/dist/chunk-IMWYKX4H.js.map +0 -1
- package/dist/chunk-POBO4G2P.js.map +0 -1
- package/dist/chunk-S3BKWNST.js.map +0 -1
- package/dist/chunk-ZBZJHXRT.js.map +0 -1
- package/dist/dist-7PQR2BQB.js.map +0 -1
- /package/dist/{composite-router-YPRWVTRB.js.map → adaptive-memory-5VP5WWTE.js.map} +0 -0
- /package/dist/{chunk-HWDBNDUX.js.map → chunk-63AJLNKU.js.map} +0 -0
- /package/dist/{chunk-I6YDS23R.js.map → chunk-KQIDTE52.js.map} +0 -0
- /package/dist/{chunk-KGDG6PWZ.js.map → chunk-LKDHAJJB.js.map} +0 -0
- /package/dist/{chunk-WSK4VSXP.js.map → chunk-V6MSPUQF.js.map} +0 -0
- /package/dist/{chunk-HH5LVGEE.js.map → chunk-Z4OZ25VS.js.map} +0 -0
- /package/dist/{consensus-vote-DBE6RNZG.js.map → cli-circuit-breaker-6EJO3PPU.js.map} +0 -0
- /package/dist/{doctor-deep-AWE7SRU6.js.map → codebase-search-CZUA37RU.js.map} +0 -0
- /package/dist/{expert-config-FHNBQRX2.js.map → composite-router-JD7URTC2.js.map} +0 -0
- /package/dist/{factory-O5C7ZBZO.js.map → consensus-vote-COW34Q2Y.js.map} +0 -0
- /package/dist/{factory-PCHGQ3ZG.js.map → doctor-deep-4A4X5X6U.js.map} +0 -0
- /package/dist/{mcp-config-AUZQPUBY.js.map → expert-bridge-J36C7VES.js.map} +0 -0
- /package/dist/{routing-memory-QY3XMU2R.js.map → expert-config-MQ5OJE3U.js.map} +0 -0
- /package/dist/{session-memory-3MBCE5KS.js.map → factory-4Z4RSUYE.js.map} +0 -0
- /package/dist/{setup-command-IQ4MD3FT.js.map → factory-NHORX63J.js.map} +0 -0
- /package/dist/{setup-config-5YUPLDXF.js.map → issue-triage-TIG3RKXF.js.map} +0 -0
- /package/dist/{weather-report-CC2C4KAX.js.map → mcp-config-ETY7GFGW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp/tools/scanner-registry-fetcher.ts","../src/mcp/tools/repo-security-plan-fallback.ts","../src/mcp/tools/repo-security-plan.ts"],"sourcesContent":["/**\n * nexus-agents/mcp - Scanner Registry Fetcher\n *\n * Fetches the scanner-registry.json manifest from the\n * vulnerability-scanner-registry GitHub Releases at runtime.\n * Uses a TTL cache and falls back to embedded data on failure.\n *\n * @module mcp/tools/scanner-registry-fetcher\n * (Source: Consensus vote — externalize scanner registry, 6-0 unanimous)\n */\n\nimport { z } from 'zod';\nimport { createLogger } from '../../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A scanner entry from the registry manifest. */\nexport interface RegistryScanner {\n readonly name: string;\n readonly displayName: string;\n readonly categories: readonly string[];\n readonly license: string;\n readonly pricingModel: string;\n readonly relationships?: readonly RegistryRelationship[] | undefined;\n}\n\n/** A relationship edge between scanners. */\nexport interface RegistryRelationship {\n readonly target: string;\n readonly type: 'uses' | 'supersedes' | 'bundles' | 'competes-with';\n}\n\n/** Language matrix: category → scanner names. */\nexport interface LanguageMatrixEntry {\n readonly sast?: readonly string[] | undefined;\n readonly sca?: readonly string[] | undefined;\n readonly secrets?: readonly string[] | undefined;\n readonly container?: readonly string[] | undefined;\n readonly iac?: readonly string[] | undefined;\n readonly dast?: readonly string[] | undefined;\n}\n\n/** The full registry manifest shape. */\nexport interface ScannerRegistryManifest {\n readonly version: string;\n readonly generatedAt: string;\n readonly scanners: readonly RegistryScanner[];\n readonly languageMatrix: Readonly<Record<string, LanguageMatrixEntry>>;\n}\n\n// ============================================================================\n// Zod Schema for Validation\n// ============================================================================\n\nconst RelationshipSchema = z.object({\n target: z.string().min(1),\n type: z.enum(['uses', 'supersedes', 'bundles', 'competes-with']),\n});\n\nconst ScannerSchema = z.object({\n name: z.string().min(1),\n displayName: z.string().min(1),\n categories: z.array(z.string().min(1)),\n license: z.string().min(1),\n pricingModel: z.string().min(1),\n relationships: z.array(RelationshipSchema).optional(),\n});\n\nconst LanguageMatrixEntrySchema = z\n .object({\n sast: z.array(z.string()).optional(),\n sca: z.array(z.string()).optional(),\n secrets: z.array(z.string()).optional(),\n container: z.array(z.string()).optional(),\n iac: z.array(z.string()).optional(),\n dast: z.array(z.string()).optional(),\n })\n .loose();\n\nconst ManifestSchema = z.object({\n version: z.string().min(1),\n generatedAt: z.string().min(1),\n scanners: z.array(ScannerSchema),\n languageMatrix: z.record(z.string().max(50), LanguageMatrixEntrySchema),\n});\n\n// ============================================================================\n// Cache\n// ============================================================================\n\ninterface CacheEntry {\n manifest: ScannerRegistryManifest;\n fetchedAt: number;\n releaseTag: string;\n}\n\nconst CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour\nlet cachedEntry: CacheEntry | null = null;\n\n/** Inflight fetch promise for probe coalescing (#1448). */\nlet inflightFetch: Promise<ScannerRegistryManifest | null> | undefined;\n\n/** Clear the cache and inflight state (for testing). */\nexport function clearRegistryCache(): void {\n cachedEntry = null;\n inflightFetch = undefined;\n}\n\n// ============================================================================\n// Fetcher\n// ============================================================================\n\nconst REGISTRY_REPO = 'williamzujkowski/vulnerability-scanner-registry';\nconst FETCH_TIMEOUT_MS = 10_000;\n\n/** Promisified execFile signature used by fetcher helpers. */\ntype ExecFileAsync = (\n file: string,\n args: readonly string[],\n options: { timeout?: number; maxBuffer?: number }\n) => Promise<{ stdout: string; stderr: string }>;\n\nconst logger = createLogger({ component: 'scanner-registry-fetcher' });\n\n/** Get the latest release tag name (lightweight check, no download). */\nasync function getLatestReleaseTag(execFileAsync: ExecFileAsync): Promise<string | null> {\n const { stdout } = await execFileAsync(\n 'gh',\n ['release', 'view', '--repo', REGISTRY_REPO, '--json', 'tagName', '--jq', '.tagName'],\n { timeout: FETCH_TIMEOUT_MS }\n );\n return stdout.trim() || null;\n}\n\n/** Download and parse the full manifest. */\nasync function downloadManifest(\n execFileAsync: ExecFileAsync\n): Promise<ScannerRegistryManifest | null> {\n const { stdout } = await execFileAsync(\n 'gh',\n [\n 'release',\n 'download',\n '--repo',\n REGISTRY_REPO,\n '--pattern',\n 'scanner-registry.json',\n '--output',\n '-',\n ],\n { timeout: FETCH_TIMEOUT_MS, maxBuffer: 1024 * 1024 }\n );\n\n let jsonData: unknown;\n try {\n jsonData = JSON.parse(stdout);\n } catch {\n logger.warn('Registry manifest is not valid JSON', {\n stdoutLength: stdout.length,\n preview: stdout.slice(0, 100),\n });\n return null;\n }\n\n const parsed = ManifestSchema.safeParse(jsonData);\n if (!parsed.success) {\n logger.warn('Registry manifest failed schema validation', {\n errors: parsed.error.issues.slice(0, 3),\n });\n return null;\n }\n\n logger.info('Fetched scanner registry manifest', {\n version: parsed.data.version,\n scanners: parsed.data.scanners.length,\n languages: Object.keys(parsed.data.languageMatrix).length,\n });\n return parsed.data;\n}\n\n/**\n * Fetch the scanner registry manifest from GitHub Releases.\n * If we have a cached version and the release tag hasn't changed,\n * just refreshes the cache timer (no download).\n */\nasync function fetchManifestFromGitHub(): Promise<ScannerRegistryManifest | null> {\n try {\n const { execFile } = await import('node:child_process');\n const { promisify } = await import('node:util');\n const execFileAsync = promisify(execFile);\n\n const tag = await getLatestReleaseTag(execFileAsync);\n if (tag === null) {\n logger.warn('No releases found in scanner registry');\n return null;\n }\n\n // If cached version matches the latest tag, refresh timer only\n if (cachedEntry !== null && cachedEntry.releaseTag === tag) {\n logger.debug('Scanner registry unchanged, refreshing cache timer', { tag });\n cachedEntry = { ...cachedEntry, fetchedAt: Date.now() };\n return cachedEntry.manifest;\n }\n\n // New release — download full manifest\n const manifest = await downloadManifest(execFileAsync);\n if (manifest !== null) {\n cachedEntry = { manifest, fetchedAt: Date.now(), releaseTag: tag };\n }\n return manifest;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.debug('Failed to fetch scanner registry', { error: msg });\n return null;\n }\n}\n\n/**\n * Get the scanner registry, fetching from GitHub if cache is stale.\n * Returns null if no cached data and fetch fails.\n */\nexport async function getRegistryManifest(): Promise<ScannerRegistryManifest | null> {\n // Check cache\n if (cachedEntry !== null) {\n const age = Date.now() - cachedEntry.fetchedAt;\n if (age < CACHE_TTL_MS) {\n return cachedEntry.manifest;\n }\n }\n\n // Coalesce concurrent fetches — only one inflight request at a time (#1448)\n inflightFetch ??= fetchManifestFromGitHub().finally(() => {\n inflightFetch = undefined;\n });\n const manifest = await inflightFetch;\n if (manifest !== null) {\n return manifest;\n }\n\n // Return stale cache if available\n if (cachedEntry !== null) {\n logger.warn('Using stale cached registry manifest');\n return cachedEntry.manifest;\n }\n\n return null;\n}\n\n/**\n * Extract scanners from manifest into the format expected by plan builder.\n */\nexport function extractScannerEntries(\n manifest: ScannerRegistryManifest\n): readonly RegistryScanner[] {\n return manifest.scanners;\n}\n\n/**\n * Extract language matrix, normalizing to consistent category keys.\n */\nexport function extractLanguageMatrix(\n manifest: ScannerRegistryManifest\n): Readonly<Record<string, LanguageMatrixEntry>> {\n return manifest.languageMatrix;\n}\n","/**\n * nexus-agents/mcp - Fallback Scanner Data\n *\n * Embedded snapshot of the vulnerability-scanner-registry manifest.\n * Used when the live registry fetch fails (network issues, gh CLI\n * unavailable, etc.). Updated periodically from the canonical\n * registry at github.com/williamzujkowski/vulnerability-scanner-registry.\n *\n * @module mcp/tools/repo-security-plan-fallback\n * (Source: Consensus vote — externalize scanner registry, 6-0 unanimous)\n */\n\nimport type { ScannerData } from './repo-security-plan.js';\n\n// ============================================================================\n// Fallback Scanner Entries (27 scanners)\n// ============================================================================\n\nconst FALLBACK_SCANNERS: ScannerData['scanners'] = [\n {\n name: 'semgrep',\n displayName: 'Semgrep',\n categories: ['sast', 'secrets'],\n license: 'LGPL-2.1',\n pricingModel: 'freemium',\n },\n {\n name: 'codeql',\n displayName: 'CodeQL',\n categories: ['sast'],\n license: 'MIT',\n pricingModel: 'freemium',\n },\n {\n name: 'bandit',\n displayName: 'Bandit',\n categories: ['sast'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'gosec',\n displayName: 'Gosec',\n categories: ['sast'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'brakeman',\n displayName: 'Brakeman',\n categories: ['sast'],\n license: 'MIT',\n pricingModel: 'free',\n },\n {\n name: 'phpstan',\n displayName: 'PHPStan',\n categories: ['sast'],\n license: 'MIT',\n pricingModel: 'freemium',\n },\n {\n name: 'shellcheck',\n displayName: 'ShellCheck',\n categories: ['sast'],\n license: 'GPL-3.0',\n pricingModel: 'free',\n },\n {\n name: 'cppcheck',\n displayName: 'Cppcheck',\n categories: ['sast'],\n license: 'GPL-3.0',\n pricingModel: 'free',\n },\n {\n name: 'detekt',\n displayName: 'detekt',\n categories: ['sast'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'spotbugs',\n displayName: 'SpotBugs',\n categories: ['sast'],\n license: 'LGPL-2.1',\n pricingModel: 'free',\n },\n {\n name: 'eslint-security',\n displayName: 'eslint-plugin-security',\n categories: ['sast'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'sonarqube',\n displayName: 'SonarQube',\n categories: ['sast', 'sca'],\n license: 'LGPL-3.0',\n pricingModel: 'freemium',\n },\n {\n name: 'osv-scanner',\n displayName: 'OSV-Scanner',\n categories: ['sca', 'container', 'iac', 'sbom'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'grype',\n displayName: 'Grype',\n categories: ['sca', 'container'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'snyk',\n displayName: 'Snyk',\n categories: ['sca', 'sast', 'container'],\n license: 'Proprietary',\n pricingModel: 'freemium',\n },\n {\n name: 'npm-audit',\n displayName: 'npm audit',\n categories: ['sca'],\n license: 'Artistic-2.0',\n pricingModel: 'free',\n },\n {\n name: 'pip-audit',\n displayName: 'pip-audit',\n categories: ['sca'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'cargo-audit',\n displayName: 'cargo-audit',\n categories: ['sca'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'bundler-audit',\n displayName: 'bundler-audit',\n categories: ['sca'],\n license: 'GPL-3.0',\n pricingModel: 'free',\n },\n {\n name: 'govulncheck',\n displayName: 'govulncheck',\n categories: ['sca'],\n license: 'BSD-3-Clause',\n pricingModel: 'free',\n },\n {\n name: 'owasp-dependency-check',\n displayName: 'OWASP Dependency-Check',\n categories: ['sca'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'gitleaks',\n displayName: 'Gitleaks',\n categories: ['secrets'],\n license: 'MIT',\n pricingModel: 'free',\n },\n {\n name: 'trufflehog',\n displayName: 'TruffleHog',\n categories: ['secrets'],\n license: 'AGPL-3.0',\n pricingModel: 'freemium',\n },\n {\n name: 'checkov',\n displayName: 'Checkov',\n categories: ['iac', 'sca'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'tfsec',\n displayName: 'tfsec',\n categories: ['iac'],\n license: 'MIT',\n pricingModel: 'free',\n },\n {\n name: 'owasp-zap',\n displayName: 'OWASP ZAP',\n categories: ['dast', 'api'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'syft',\n displayName: 'Syft',\n categories: ['sbom'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n {\n name: 'grype-image',\n displayName: 'Grype (image scan)',\n categories: ['image-currency', 'container'],\n license: 'Apache-2.0',\n pricingModel: 'free',\n },\n];\n\n// ============================================================================\n// Fallback Language Map (16 languages)\n// ============================================================================\n\nconst FALLBACK_LANGUAGE_MAP: ScannerData['languageMap'] = {\n TypeScript: {\n sast: ['semgrep', 'eslint-security', 'codeql'],\n sca: ['npm-audit', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n JavaScript: {\n sast: ['semgrep', 'eslint-security', 'codeql'],\n sca: ['npm-audit', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n Python: {\n sast: ['bandit', 'semgrep', 'codeql'],\n sca: ['pip-audit', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n Java: {\n sast: ['codeql', 'semgrep', 'spotbugs'],\n sca: ['owasp-dependency-check', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n Go: {\n sast: ['gosec', 'semgrep', 'codeql'],\n sca: ['govulncheck', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n Ruby: {\n sast: ['brakeman', 'semgrep', 'codeql'],\n sca: ['bundler-audit', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n PHP: {\n sast: ['phpstan', 'semgrep'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n 'C#': {\n sast: ['codeql', 'semgrep'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n C: {\n sast: ['cppcheck', 'codeql', 'semgrep'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n 'C++': {\n sast: ['cppcheck', 'codeql', 'semgrep'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n Rust: {\n sast: ['semgrep'],\n sca: ['cargo-audit', 'osv-scanner'],\n secrets: ['gitleaks'],\n },\n Kotlin: {\n sast: ['detekt', 'semgrep', 'codeql'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n Swift: {\n sast: ['codeql', 'semgrep'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n Scala: {\n sast: ['semgrep', 'spotbugs'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n Shell: {\n sast: ['shellcheck', 'semgrep'],\n sca: [],\n secrets: ['gitleaks'],\n },\n HCL: {\n sast: ['checkov', 'tfsec'],\n sca: ['osv-scanner'],\n secrets: ['gitleaks'],\n },\n};\n\n// ============================================================================\n// Exported Fallback\n// ============================================================================\n\n/** Embedded scanner data snapshot used when live registry is unavailable. */\nexport const FALLBACK_SCANNER_DATA: ScannerData = {\n scanners: FALLBACK_SCANNERS,\n languageMap: FALLBACK_LANGUAGE_MAP,\n source: 'fallback',\n};\n","/**\n * nexus-agents/mcp - Repository Security Plan Logic\n *\n * Generates a language-aware security scanning pipeline recommendation\n * by composing repo_analyze output with scanner registry data.\n * Fetches fresh data from vulnerability-scanner-registry GitHub Releases;\n * falls back to embedded snapshot if fetch fails.\n *\n * @module mcp/tools/repo-security-plan\n * (Source: Issue #1079, externalization vote 6-0 unanimous)\n */\n\nimport type { RepoAnalysis } from './repo-analyze-types.js';\nimport type {\n RepoSecurityPlanInput,\n RepoSecurityPlan,\n ScannerRecommendation,\n ConflictWarning,\n CoverageAnalysis,\n} from './repo-security-plan-types.js';\nimport { analyzeGitHubRepo } from './repo-analyze.js';\nimport { getRegistryManifest } from './scanner-registry-fetcher.js';\nimport type { RegistryScanner, LanguageMatrixEntry } from './scanner-registry-fetcher.js';\nimport { FALLBACK_SCANNER_DATA } from './repo-security-plan-fallback.js';\nimport { createLogger } from '../../core/index.js';\n\nconst logger = createLogger({ component: 'repo-security-plan' });\n\n// ============================================================================\n// Scanner Data Interface (common shape for fetched + fallback)\n// ============================================================================\n\n/** Internal scanner entry used by plan builder. */\nexport interface ScannerEntry {\n readonly name: string;\n readonly displayName: string;\n readonly categories: readonly string[];\n readonly license: string;\n readonly pricingModel: string;\n readonly supersedes?: readonly string[];\n}\n\n/** Language mapping: category → scanner names. */\ninterface LanguageMapping {\n readonly sast: readonly string[];\n readonly sca: readonly string[];\n readonly secrets: readonly string[];\n}\n\n/** Resolved scanner data for plan building. */\nexport interface ScannerData {\n readonly scanners: readonly ScannerEntry[];\n readonly languageMap: Readonly<Record<string, LanguageMapping>>;\n readonly source: 'registry' | 'fallback';\n}\n\n// Re-export for consumers\nexport { FALLBACK_SCANNER_DATA } from './repo-security-plan-fallback.js';\n\n// ============================================================================\n// Registry → ScannerData Conversion\n// ============================================================================\n\nfunction convertRegistryScanner(s: RegistryScanner): ScannerEntry {\n const supersedes = s.relationships?.filter((r) => r.type === 'supersedes').map((r) => r.target);\n return {\n name: s.name,\n displayName: s.displayName,\n categories: s.categories,\n license: s.license,\n pricingModel: s.pricingModel,\n ...(supersedes !== undefined && supersedes.length > 0 ? { supersedes } : {}),\n };\n}\n\n/** Known PascalCase language names from GitHub API. Handles registry keys like \"typescript\" → \"TypeScript\". */\nconst LANGUAGE_PASCAL_MAP: Readonly<Record<string, string>> = {\n typescript: 'TypeScript',\n javascript: 'JavaScript',\n python: 'Python',\n java: 'Java',\n csharp: 'C#',\n 'c#': 'C#',\n cpp: 'C++',\n 'c++': 'C++',\n go: 'Go',\n rust: 'Rust',\n ruby: 'Ruby',\n php: 'PHP',\n swift: 'Swift',\n kotlin: 'Kotlin',\n scala: 'Scala',\n hcl: 'HCL',\n shell: 'Shell',\n dockerfile: 'Dockerfile',\n};\n\nfunction normalizeLangName(lang: string): string {\n const lower = lang.toLowerCase();\n return LANGUAGE_PASCAL_MAP[lower] ?? lang.charAt(0).toUpperCase() + lang.slice(1);\n}\n\nfunction convertLanguageMatrix(\n matrix: Readonly<Record<string, LanguageMatrixEntry>>\n): Record<string, LanguageMapping> {\n const result: Record<string, LanguageMapping> = {};\n for (const [lang, entry] of Object.entries(matrix)) {\n // Normalize language name to PascalCase (GitHub API returns PascalCase like \"TypeScript\")\n const normalized = normalizeLangName(lang);\n result[normalized] = {\n sast: entry.sast ?? [],\n sca: entry.sca ?? [],\n secrets: entry.secrets ?? [],\n };\n }\n return result;\n}\n\n/** Resolve scanner data: fetch from registry, fall back to embedded. */\nexport async function resolveScannerData(): Promise<ScannerData> {\n const manifest = await getRegistryManifest();\n if (manifest !== null) {\n logger.info('Using live scanner registry', {\n version: manifest.version,\n scanners: manifest.scanners.length,\n });\n return {\n scanners: manifest.scanners.map(convertRegistryScanner),\n languageMap: convertLanguageMatrix(manifest.languageMatrix),\n source: 'registry',\n };\n }\n\n logger.info('Using fallback scanner data');\n return FALLBACK_SCANNER_DATA;\n}\n\n// ============================================================================\n// CI Snippet Generation (GitHub Actions only for v1)\n// ============================================================================\n\nconst CI_SNIPPETS: Readonly<Record<string, string>> = {\n semgrep: '- uses: semgrep/semgrep-action@v1\\n with:\\n config: auto',\n codeql: '- uses: github/codeql-action/analyze@v3',\n grype: '- uses: anchore/scan-action@v4\\n with:\\n path: .',\n 'grype-image':\n '- uses: anchore/scan-action@v4\\n with:\\n image: ${{ env.IMAGE_TAG }}\\n severity: CRITICAL,HIGH\\n exit-code: 1',\n gitleaks: '- uses: gitleaks/gitleaks-action@v2',\n bandit: '- run: pip install bandit && bandit -r . -f json',\n gosec: '- uses: securego/gosec@master\\n with:\\n args: ./...',\n checkov: '- uses: bridgecrewio/checkov-action@master',\n 'osv-scanner': '- uses: google/osv-scanner-action@v1',\n snyk: '- uses: snyk/actions/node@master # adjust for language',\n shellcheck: '- uses: ludeeus/action-shellcheck@master',\n};\n\nfunction generateCiSnippet(name: string, ci: string | null): string | null {\n if (ci !== 'github-actions') return null;\n return CI_SNIPPETS[name] ?? null;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction findScanner(name: string, scanners: readonly ScannerEntry[]): ScannerEntry | undefined {\n return scanners.find((s) => s.name === name);\n}\n\nfunction isAlreadyUsed(name: string, existing: readonly string[]): boolean {\n return existing.some((t) => t.toLowerCase().includes(name.toLowerCase()));\n}\n\n/** Context passed to recommendation collectors. */\ninterface RecContext {\n readonly existing: readonly string[];\n readonly ciProvider: string | null;\n readonly language: string | null;\n readonly categoryFilter: ReadonlySet<string> | null;\n readonly maxScanners: number;\n readonly scanners: readonly ScannerEntry[];\n}\n\n/** Options for collecting recommendations in a single category. */\ninterface CategoryRecOptions {\n readonly names: readonly string[];\n readonly category: string;\n readonly rationale: (entry: ScannerEntry) => string;\n readonly priority: 'critical' | 'recommended';\n readonly ctx: RecContext;\n}\n\n/** Collect recommendations for a single category. */\nfunction collectCategoryRecs(recs: ScannerRecommendation[], opts: CategoryRecOptions): void {\n for (const name of opts.names) {\n if (recs.length >= opts.ctx.maxScanners) break;\n if (isAlreadyUsed(name, opts.ctx.existing)) continue;\n const entry = findScanner(name, opts.ctx.scanners);\n if (!entry) continue;\n if (opts.ctx.categoryFilter && !opts.ctx.categoryFilter.has(opts.category)) continue;\n const isFirst = opts.category === 'sast' && recs.length === 0;\n recs.push({\n name,\n displayName: entry.displayName,\n category: opts.category,\n license: entry.license,\n pricingModel: entry.pricingModel,\n rationale: opts.rationale(entry),\n priority: isFirst ? 'critical' : opts.priority,\n ciSnippet: generateCiSnippet(name, opts.ctx.ciProvider),\n });\n }\n}\n\n/** Collect language-specific recommendations (SAST + SCA + secrets). */\nfunction collectLanguageRecs(\n langMap: LanguageMapping,\n recs: ScannerRecommendation[],\n ctx: RecContext\n): void {\n const lang = ctx.language ?? 'unknown';\n collectCategoryRecs(recs, {\n names: langMap.sast,\n category: 'sast',\n rationale: (e) => `${e.displayName} provides SAST for ${lang}`,\n priority: 'recommended',\n ctx,\n });\n collectCategoryRecs(recs, {\n names: langMap.sca,\n category: 'sca',\n rationale: (e) => `${e.displayName} provides SCA for ${lang} dependencies`,\n priority: 'critical',\n ctx,\n });\n collectCategoryRecs(recs, {\n names: langMap.secrets,\n category: 'secrets',\n rationale: () => 'Detects leaked credentials and API keys in source code',\n priority: 'critical',\n ctx,\n });\n}\n\n/** Try to add a single scanner if not already present. */\nfunction tryAddScanner(\n scannerName: string,\n category: string,\n rationale: string,\n recs: ScannerRecommendation[],\n ctx: RecContext\n): void {\n if (recs.length >= ctx.maxScanners) return;\n if (ctx.categoryFilter && !ctx.categoryFilter.has(category)) return;\n if (isAlreadyUsed(scannerName, ctx.existing)) return;\n if (recs.some((r) => r.name === scannerName)) return;\n const entry = findScanner(scannerName, ctx.scanners);\n if (!entry) return;\n recs.push({\n name: scannerName,\n displayName: entry.displayName,\n category,\n license: entry.license,\n pricingModel: entry.pricingModel,\n rationale,\n priority: 'recommended',\n ciSnippet: generateCiSnippet(scannerName, ctx.ciProvider),\n });\n}\n\n// ============================================================================\n// Conflict Detection\n// ============================================================================\n\nfunction detectConflicts(\n recs: readonly ScannerRecommendation[],\n scanners: readonly ScannerEntry[]\n): readonly ConflictWarning[] {\n const warnings: ConflictWarning[] = [];\n const names = new Set(recs.map((r) => r.name));\n detectSuperseded(names, scanners, warnings);\n detectRedundant(recs, warnings);\n return warnings;\n}\n\nfunction detectSuperseded(\n names: ReadonlySet<string>,\n scanners: readonly ScannerEntry[],\n warnings: ConflictWarning[]\n): void {\n for (const scanner of scanners) {\n if (!names.has(scanner.name)) continue;\n if (!scanner.supersedes) continue;\n for (const old of scanner.supersedes) {\n if (names.has(old)) {\n warnings.push({\n scanners: [old, scanner.name],\n type: 'superseded',\n recommendation: `${scanner.displayName} supersedes ${old}. Remove ${old}.`,\n });\n }\n }\n }\n}\n\nfunction detectRedundant(\n recs: readonly ScannerRecommendation[],\n warnings: ConflictWarning[]\n): void {\n const catMap = new Map<string, string[]>();\n for (const rec of recs) {\n const arr = catMap.get(rec.category) ?? [];\n arr.push(rec.name);\n catMap.set(rec.category, arr);\n }\n for (const [cat, scanners] of catMap) {\n if (scanners.length > 2) {\n const count = String(scanners.length);\n warnings.push({\n scanners,\n type: 'redundant',\n recommendation: `${count} scanners for ${cat}. Consider keeping top 2.`,\n });\n }\n }\n}\n\n// ============================================================================\n// Coverage Analysis\n// ============================================================================\n\nconst ALL_CATEGORIES = ['sast', 'dast', 'sca', 'secrets', 'container', 'iac', 'image-currency'];\n\nfunction buildCoverage(\n recs: readonly ScannerRecommendation[],\n existing: readonly string[],\n scanners: readonly ScannerEntry[]\n): readonly CoverageAnalysis[] {\n return ALL_CATEGORIES.map((cat) => {\n const found = recs.filter((r) => r.category === cat).map((r) => r.name);\n const existingMatch = existing.some((t) =>\n scanners.some((s) => s.categories.includes(cat) && t.toLowerCase().includes(s.name))\n );\n return { category: cat, covered: found.length > 0 || existingMatch, scanners: found };\n });\n}\n\n// ============================================================================\n// Plan Assembly\n// ============================================================================\n\n/** Options for buildPlanFromAnalysis (allows optional fields for testability). */\ninterface BuildPlanOptions {\n readonly repo: string;\n readonly categories?: readonly string[] | undefined;\n readonly maxScanners?: number | undefined;\n}\n\n/** Generate a security scanning plan for a repository (fetches live data). */\nexport async function generateSecurityPlan(\n input: RepoSecurityPlanInput\n): Promise<RepoSecurityPlan> {\n const [analysis, data] = await Promise.all([\n analyzeGitHubRepo({ repo: input.repo, depth: 'deep' }),\n resolveScannerData(),\n ]);\n return buildPlanFromAnalysis(analysis, input, data);\n}\n\n/** Collect infrastructure-specific scanner recommendations. */\nfunction collectInfraRecs(\n analysis: RepoAnalysis,\n recs: ScannerRecommendation[],\n ctx: RecContext\n): void {\n if (analysis.hasDockerfile) {\n tryAddScanner(\n 'grype',\n 'container',\n 'Dockerfile detected — scan container images for vulnerabilities',\n recs,\n ctx\n );\n tryAddScanner('grype-image', 'image-currency', buildImageCurrencyRationale(), recs, ctx);\n }\n if (analysis.hasHelmCharts) {\n tryAddScanner(\n 'checkov',\n 'iac',\n 'Helm charts detected — scan IaC for misconfigurations',\n recs,\n ctx\n );\n }\n}\n\n/**\n * Build the rationale string for periodic container base image CVE scanning.\n * Extracted to keep collectInfraRecs within the 50-line function limit.\n */\nfunction buildImageCurrencyRationale(): string {\n return (\n 'Dockerfile detected — periodically scan built images with ' +\n '`grype image --severity CRITICAL,HIGH` to detect CVEs introduced by stale base images. ' +\n 'Pin base images to specific version tags (e.g., node:22.4.0-alpine3.20) rather than ' +\n ':latest to get reproducible scans and predictable CVE surface area. ' +\n 'Alpine-based images typically have a smaller CVE surface than Debian/Ubuntu equivalents ' +\n 'due to musl libc and a minimal package set, but verify with grype before assuming.'\n );\n}\n\n/** Pure function: build plan from analysis + scanner data (testable). */\nexport function buildPlanFromAnalysis(\n analysis: RepoAnalysis,\n input: BuildPlanOptions,\n data?: ScannerData\n): RepoSecurityPlan {\n const resolved = data ?? FALLBACK_SCANNER_DATA;\n const ctx: RecContext = {\n existing: analysis.securityTooling,\n ciProvider: analysis.ciProvider,\n language: analysis.language,\n categoryFilter: input.categories ? new Set(input.categories) : null,\n maxScanners: input.maxScanners ?? 10,\n scanners: resolved.scanners,\n };\n\n const recs: ScannerRecommendation[] = [];\n const normalizedLang = analysis.language !== null ? normalizeLangName(analysis.language) : null;\n const langMap = normalizedLang !== null ? resolved.languageMap[normalizedLang] : undefined;\n if (langMap) collectLanguageRecs(langMap, recs, ctx);\n collectInfraRecs(analysis, recs, ctx);\n\n const conflicts = detectConflicts(recs, resolved.scanners);\n const coverage = buildCoverage(recs, analysis.securityTooling, resolved.scanners);\n const uncovered = coverage.filter((c) => !c.covered).map((c) => c.category);\n\n return {\n repo: analysis.name,\n language: analysis.language,\n framework: analysis.framework,\n ciProvider: analysis.ciProvider,\n existingTooling: analysis.securityTooling,\n recommendations: recs,\n conflicts,\n coverage,\n gapsSummary: [\n ...analysis.gaps,\n ...(uncovered.length > 0 ? [`Uncovered categories: ${uncovered.join(', ')}`] : []),\n ],\n };\n}\n"],"mappings":"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","names":["logger"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getErrorMessage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HSOPD265.js";
|
|
4
4
|
|
|
5
5
|
// src/cli/setup-config.ts
|
|
6
6
|
import { existsSync, writeFileSync } from "fs";
|
|
@@ -59,4 +59,4 @@ function runConfigInitSync(projectRoot, force, dryRun) {
|
|
|
59
59
|
export {
|
|
60
60
|
runConfigInitSync
|
|
61
61
|
};
|
|
62
|
-
//# sourceMappingURL=chunk-
|
|
62
|
+
//# sourceMappingURL=chunk-V6MSPUQF.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger,
|
|
3
|
+
err,
|
|
4
|
+
ok
|
|
5
|
+
} from "./chunk-HSOPD265.js";
|
|
6
|
+
|
|
7
|
+
// src/scm/token-resolver.ts
|
|
8
|
+
import { execFile } from "child_process";
|
|
9
|
+
import { promisify } from "util";
|
|
10
|
+
var execFileAsync = promisify(execFile);
|
|
11
|
+
var logger = createLogger({ component: "TokenResolver" });
|
|
12
|
+
var ENV_VARS = {
|
|
13
|
+
github: ["GITHUB_TOKEN", "GH_TOKEN"],
|
|
14
|
+
gitlab: ["GITLAB_TOKEN", "GL_TOKEN"],
|
|
15
|
+
gitea: ["GITEA_TOKEN"]
|
|
16
|
+
};
|
|
17
|
+
var CLI_AUTH_COMMANDS = {
|
|
18
|
+
github: ["gh", "auth", "token"],
|
|
19
|
+
gitlab: ["glab", "auth", "token"],
|
|
20
|
+
gitea: []
|
|
21
|
+
};
|
|
22
|
+
var CLI_AUTH_TIMEOUT_MS = 5e3;
|
|
23
|
+
function resolveFromEnv(platform, customEnvVar) {
|
|
24
|
+
if (customEnvVar !== void 0) {
|
|
25
|
+
const val = process.env[customEnvVar];
|
|
26
|
+
if (val !== void 0 && val !== "") {
|
|
27
|
+
return { value: val, strategy: "env", platform };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const envVar of ENV_VARS[platform]) {
|
|
31
|
+
const val = process.env[envVar];
|
|
32
|
+
if (val !== void 0 && val !== "") {
|
|
33
|
+
return { value: val, strategy: "env", platform };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
async function resolveFromCli(platform) {
|
|
39
|
+
const cmd = CLI_AUTH_COMMANDS[platform];
|
|
40
|
+
if (cmd.length === 0) return void 0;
|
|
41
|
+
const [bin, ...args] = cmd;
|
|
42
|
+
if (bin === void 0) return void 0;
|
|
43
|
+
try {
|
|
44
|
+
const { stdout } = await execFileAsync(bin, args, {
|
|
45
|
+
timeout: CLI_AUTH_TIMEOUT_MS
|
|
46
|
+
});
|
|
47
|
+
const token = stdout.trim();
|
|
48
|
+
if (token !== "") {
|
|
49
|
+
return { value: token, strategy: "cli", platform };
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
logger.debug("CLI auth token resolution failed", { platform });
|
|
53
|
+
}
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
async function resolveToken(config) {
|
|
57
|
+
const platform = config?.platform ?? "github";
|
|
58
|
+
if (config?.token !== void 0 && config.token !== "") {
|
|
59
|
+
return ok({ value: config.token, strategy: "config", platform });
|
|
60
|
+
}
|
|
61
|
+
const envToken = resolveFromEnv(platform, config?.envVar);
|
|
62
|
+
if (envToken !== void 0) {
|
|
63
|
+
logger.debug("Token resolved from environment", { platform, strategy: "env" });
|
|
64
|
+
return ok(envToken);
|
|
65
|
+
}
|
|
66
|
+
const cliToken = await resolveFromCli(platform);
|
|
67
|
+
if (cliToken !== void 0) {
|
|
68
|
+
logger.debug("Token resolved from CLI auth", { platform, strategy: "cli" });
|
|
69
|
+
return ok(cliToken);
|
|
70
|
+
}
|
|
71
|
+
const envVarList = ENV_VARS[platform].join(" or ");
|
|
72
|
+
return err(
|
|
73
|
+
new Error(
|
|
74
|
+
`No ${platform} token found. Set ${envVarList} environment variable, or authenticate via CLI (${CLI_AUTH_COMMANDS[platform].join(" ")}).`
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function hasToken(platform = "github") {
|
|
79
|
+
return resolveFromEnv(platform) !== void 0;
|
|
80
|
+
}
|
|
81
|
+
function getTokenEnvVars(platform = "github") {
|
|
82
|
+
return ENV_VARS[platform];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
resolveToken,
|
|
87
|
+
hasToken,
|
|
88
|
+
getTokenEnvVars
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=chunk-VZ2YOQWU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scm/token-resolver.ts"],"sourcesContent":["/**\n * nexus-agents/scm - Centralized Token Resolver\n *\n * Single source of truth for SCM token resolution. Priority:\n * 1. Explicit config (token passed directly)\n * 2. Environment variables (GITHUB_TOKEN, GH_TOKEN, GITLAB_TOKEN)\n * 3. CLI auth (gh auth token, glab auth token)\n *\n * @module scm/token-resolver\n * (Source: Issue #1136 — Centralized SCM Provider Module)\n */\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport type { Result } from '../core/index.js';\nimport { ok, err, createLogger } from '../core/index.js';\nimport type { ScmToken, ScmPlatform, TokenResolverConfig } from './types.js';\n\nconst execFileAsync = promisify(execFile);\nconst logger = createLogger({ component: 'TokenResolver' });\n\n/** Environment variable names per platform. */\nconst ENV_VARS: Record<ScmPlatform, readonly string[]> = {\n github: ['GITHUB_TOKEN', 'GH_TOKEN'],\n gitlab: ['GITLAB_TOKEN', 'GL_TOKEN'],\n gitea: ['GITEA_TOKEN'],\n} as const;\n\n/** CLI commands to fetch auth tokens per platform. */\nconst CLI_AUTH_COMMANDS: Record<ScmPlatform, readonly string[]> = {\n github: ['gh', 'auth', 'token'],\n gitlab: ['glab', 'auth', 'token'],\n gitea: [],\n} as const;\n\n/** CLI auth timeout in ms. */\nconst CLI_AUTH_TIMEOUT_MS = 5_000;\n\n/**\n * Resolves a token from environment variables.\n */\nfunction resolveFromEnv(platform: ScmPlatform, customEnvVar?: string): ScmToken | undefined {\n // Custom env var takes priority\n if (customEnvVar !== undefined) {\n const val = process.env[customEnvVar];\n if (val !== undefined && val !== '') {\n return { value: val, strategy: 'env', platform };\n }\n }\n\n // Check platform-specific env vars\n for (const envVar of ENV_VARS[platform]) {\n const val = process.env[envVar];\n if (val !== undefined && val !== '') {\n return { value: val, strategy: 'env', platform };\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolves a token from CLI auth.\n */\nasync function resolveFromCli(platform: ScmPlatform): Promise<ScmToken | undefined> {\n const cmd = CLI_AUTH_COMMANDS[platform];\n if (cmd.length === 0) return undefined;\n\n const [bin, ...args] = cmd;\n if (bin === undefined) return undefined;\n\n try {\n const { stdout } = await execFileAsync(bin, args, {\n timeout: CLI_AUTH_TIMEOUT_MS,\n });\n const token = stdout.trim();\n if (token !== '') {\n return { value: token, strategy: 'cli', platform };\n }\n } catch {\n logger.debug('CLI auth token resolution failed', { platform });\n }\n\n return undefined;\n}\n\n/**\n * Resolves an SCM token using the priority chain:\n * 1. Explicit config\n * 2. Environment variables\n * 3. CLI auth\n *\n * @param config - Token resolution configuration\n * @returns Resolved token or error\n */\nexport async function resolveToken(config?: TokenResolverConfig): Promise<Result<ScmToken, Error>> {\n const platform = config?.platform ?? 'github';\n\n // Priority 1: Explicit config\n if (config?.token !== undefined && config.token !== '') {\n return ok({ value: config.token, strategy: 'config' as const, platform });\n }\n\n // Priority 2: Environment variables\n const envToken = resolveFromEnv(platform, config?.envVar);\n if (envToken !== undefined) {\n logger.debug('Token resolved from environment', { platform, strategy: 'env' });\n return ok(envToken);\n }\n\n // Priority 3: CLI auth\n const cliToken = await resolveFromCli(platform);\n if (cliToken !== undefined) {\n logger.debug('Token resolved from CLI auth', { platform, strategy: 'cli' });\n return ok(cliToken);\n }\n\n const envVarList = ENV_VARS[platform].join(' or ');\n return err(\n new Error(\n `No ${platform} token found. Set ${envVarList} environment variable, ` +\n `or authenticate via CLI (${CLI_AUTH_COMMANDS[platform].join(' ')}).`\n )\n );\n}\n\n/**\n * Synchronous check: is any token available for the given platform?\n * Only checks environment variables (no CLI auth, which is async).\n */\nexport function hasToken(platform: ScmPlatform = 'github'): boolean {\n return resolveFromEnv(platform) !== undefined;\n}\n\n/**\n * Returns the list of environment variable names for a platform.\n * Useful for documentation and error messages.\n */\nexport function getTokenEnvVars(platform: ScmPlatform = 'github'): readonly string[] {\n return ENV_VARS[platform];\n}\n"],"mappings":";;;;;;;AAYA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAK1B,IAAM,gBAAgB,UAAU,QAAQ;AACxC,IAAM,SAAS,aAAa,EAAE,WAAW,gBAAgB,CAAC;AAG1D,IAAM,WAAmD;AAAA,EACvD,QAAQ,CAAC,gBAAgB,UAAU;AAAA,EACnC,QAAQ,CAAC,gBAAgB,UAAU;AAAA,EACnC,OAAO,CAAC,aAAa;AACvB;AAGA,IAAM,oBAA4D;AAAA,EAChE,QAAQ,CAAC,MAAM,QAAQ,OAAO;AAAA,EAC9B,QAAQ,CAAC,QAAQ,QAAQ,OAAO;AAAA,EAChC,OAAO,CAAC;AACV;AAGA,IAAM,sBAAsB;AAK5B,SAAS,eAAe,UAAuB,cAA6C;AAE1F,MAAI,iBAAiB,QAAW;AAC9B,UAAM,MAAM,QAAQ,IAAI,YAAY;AACpC,QAAI,QAAQ,UAAa,QAAQ,IAAI;AACnC,aAAO,EAAE,OAAO,KAAK,UAAU,OAAO,SAAS;AAAA,IACjD;AAAA,EACF;AAGA,aAAW,UAAU,SAAS,QAAQ,GAAG;AACvC,UAAM,MAAM,QAAQ,IAAI,MAAM;AAC9B,QAAI,QAAQ,UAAa,QAAQ,IAAI;AACnC,aAAO,EAAE,OAAO,KAAK,UAAU,OAAO,SAAS;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAe,eAAe,UAAsD;AAClF,QAAM,MAAM,kBAAkB,QAAQ;AACtC,MAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,MAAI,QAAQ,OAAW,QAAO;AAE9B,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,cAAc,KAAK,MAAM;AAAA,MAChD,SAAS;AAAA,IACX,CAAC;AACD,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,UAAU,IAAI;AAChB,aAAO,EAAE,OAAO,OAAO,UAAU,OAAO,SAAS;AAAA,IACnD;AAAA,EACF,QAAQ;AACN,WAAO,MAAM,oCAAoC,EAAE,SAAS,CAAC;AAAA,EAC/D;AAEA,SAAO;AACT;AAWA,eAAsB,aAAa,QAAgE;AACjG,QAAM,WAAW,QAAQ,YAAY;AAGrC,MAAI,QAAQ,UAAU,UAAa,OAAO,UAAU,IAAI;AACtD,WAAO,GAAG,EAAE,OAAO,OAAO,OAAO,UAAU,UAAmB,SAAS,CAAC;AAAA,EAC1E;AAGA,QAAM,WAAW,eAAe,UAAU,QAAQ,MAAM;AACxD,MAAI,aAAa,QAAW;AAC1B,WAAO,MAAM,mCAAmC,EAAE,UAAU,UAAU,MAAM,CAAC;AAC7E,WAAO,GAAG,QAAQ;AAAA,EACpB;AAGA,QAAM,WAAW,MAAM,eAAe,QAAQ;AAC9C,MAAI,aAAa,QAAW;AAC1B,WAAO,MAAM,gCAAgC,EAAE,UAAU,UAAU,MAAM,CAAC;AAC1E,WAAO,GAAG,QAAQ;AAAA,EACpB;AAEA,QAAM,aAAa,SAAS,QAAQ,EAAE,KAAK,MAAM;AACjD,SAAO;AAAA,IACL,IAAI;AAAA,MACF,MAAM,QAAQ,qBAAqB,UAAU,mDACf,kBAAkB,QAAQ,EAAE,KAAK,GAAG,CAAC;AAAA,IACrE;AAAA,EACF;AACF;AAMO,SAAS,SAAS,WAAwB,UAAmB;AAClE,SAAO,eAAe,QAAQ,MAAM;AACtC;AAMO,SAAS,gBAAgB,WAAwB,UAA6B;AACnF,SAAO,SAAS,QAAQ;AAC1B;","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-633WH2ML.js";
|
|
4
4
|
import {
|
|
5
5
|
createAllAdapters
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CW2Z773T.js";
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_CAPABILITIES,
|
|
9
9
|
DEFAULT_MODEL_CAPABILITIES,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
ok,
|
|
16
16
|
symbols,
|
|
17
17
|
writeLine
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-HSOPD265.js";
|
|
19
19
|
import {
|
|
20
20
|
LEARNING_DIR,
|
|
21
21
|
OUTCOMES_FILE,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-CLYZ7FWP.js";
|
|
25
25
|
|
|
26
26
|
// src/version.ts
|
|
27
|
-
var VERSION = true ? "2.29.
|
|
27
|
+
var VERSION = true ? "2.29.2" : "dev";
|
|
28
28
|
|
|
29
29
|
// src/cli/setup-data-dir.ts
|
|
30
30
|
import { mkdirSync, existsSync as existsSync2 } from "fs";
|
|
@@ -170,6 +170,7 @@ async function startStdioServer(config) {
|
|
|
170
170
|
}
|
|
171
171
|
const { server, logger: logger2 } = serverResult.value;
|
|
172
172
|
try {
|
|
173
|
+
logger2.setDestination?.("stderr");
|
|
173
174
|
logger2.info("Starting stdio transport");
|
|
174
175
|
const transport = new StdioServerTransport();
|
|
175
176
|
const connectResult = await connectTransport(server, transport, logger2);
|
|
@@ -757,7 +758,7 @@ async function runDoctorFix(result) {
|
|
|
757
758
|
writeLine2("\u2500".repeat(40));
|
|
758
759
|
let fixCount = 0;
|
|
759
760
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
760
|
-
const { runSetup } = await import("./setup-command-
|
|
761
|
+
const { runSetup } = await import("./setup-command-CMCQRBJF.js");
|
|
761
762
|
const setupResult = runSetup({
|
|
762
763
|
skipMcp: true,
|
|
763
764
|
skipRules: true,
|
|
@@ -771,7 +772,7 @@ async function runDoctorFix(result) {
|
|
|
771
772
|
}
|
|
772
773
|
}
|
|
773
774
|
if (!result.configFile.found) {
|
|
774
|
-
const { runConfigInitSync } = await import("./setup-config-
|
|
775
|
+
const { runConfigInitSync } = await import("./setup-config-KITOPV7V.js");
|
|
775
776
|
const configResult = runConfigInitSync(process.cwd(), false, false);
|
|
776
777
|
if (configResult.success && configResult.created) {
|
|
777
778
|
writeLine2(`\u2713 Generated config: ${configResult.path}`);
|
|
@@ -835,4 +836,4 @@ export {
|
|
|
835
836
|
startStdioServer,
|
|
836
837
|
closeServer
|
|
837
838
|
};
|
|
838
|
-
//# sourceMappingURL=chunk-
|
|
839
|
+
//# sourceMappingURL=chunk-WSYJN7BI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/cli/setup-data-dir.ts","../src/cli/doctor.ts","../src/mcp/server.ts","../src/mcp/task-store.ts","../src/cli/doctor-formatting.ts"],"sourcesContent":["/**\n * nexus-agents - Version constant\n *\n * Injected at build time via tsup define from package.json.\n * Do NOT edit this value manually — it is replaced during build.\n */\n\ndeclare const __NEXUS_VERSION__: string;\n\nexport const VERSION: string = typeof __NEXUS_VERSION__ !== 'undefined' ? __NEXUS_VERSION__ : 'dev';\n","/**\n * nexus-agents data directory initialization\n *\n * Pre-creates ~/.nexus-agents/ directory structure with proper permissions.\n * Used by `nexus-agents setup` to ensure data directories exist before first use.\n *\n * @module cli/setup-data-dir\n * (Source: Issue #1249 - Developer experience improvements)\n */\n\nimport { mkdirSync, existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { DATA_SUBDIRECTORIES } from './doctor.js';\n\n/** Root data directory path. */\nexport const NEXUS_DATA_DIR = join(homedir(), '.nexus-agents');\n\n/** Subdirectories requiring restricted permissions (owner-only). */\nconst RESTRICTED_DIRS = new Set(['auth']);\n\n/**\n * Result of data directory initialization.\n */\nexport interface DataDirInitResult {\n readonly success: boolean;\n readonly rootPath: string;\n readonly created: readonly string[];\n readonly alreadyExisted: readonly string[];\n readonly error: string | null;\n}\n\n/**\n * Creates the ~/.nexus-agents/ directory structure.\n * Sets restrictive permissions (0o700) on auth/ directory.\n *\n * @param dryRun - If true, reports what would be created without creating.\n * @returns Result of initialization.\n */\nexport function initDataDirectories(dryRun: boolean = false): DataDirInitResult {\n const created: string[] = [];\n const alreadyExisted: string[] = [];\n\n try {\n ensureDir(NEXUS_DATA_DIR, dryRun, created, alreadyExisted);\n\n for (const subdir of DATA_SUBDIRECTORIES) {\n const mode = RESTRICTED_DIRS.has(subdir) ? 0o700 : undefined;\n ensureDir(join(NEXUS_DATA_DIR, subdir), dryRun, created, alreadyExisted, mode);\n }\n\n return { success: true, rootPath: NEXUS_DATA_DIR, created, alreadyExisted, error: null };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n return { success: false, rootPath: NEXUS_DATA_DIR, created, alreadyExisted, error: msg };\n }\n}\n\n/** Creates a single directory if it doesn't exist, tracking the result. */\nfunction ensureDir(\n dirPath: string,\n dryRun: boolean,\n created: string[],\n alreadyExisted: string[],\n mode?: number\n): void {\n if (existsSync(dirPath)) {\n alreadyExisted.push(dirPath);\n return;\n }\n if (!dryRun) {\n mkdirSync(dirPath, { recursive: true, ...(mode !== undefined ? { mode } : {}) });\n }\n created.push(dirPath);\n}\n","/* eslint-disable max-lines -- Cohesive doctor command module (governance: 400-600 OK if cohesive) */\n/**\n * nexus-agents doctor command\n *\n * Health check utility for CLI integration validation.\n * Verifies CLI installations, versions, authentication, Node.js version,\n * API keys, configuration files, and MCP server readiness.\n *\n * (Source: Issue #91, cli-project_plan.md DevEx amendment)\n * (Source: Issue #422 - Doctor command validations)\n */\n\nimport { existsSync, readFileSync, accessSync, constants as fsConstants } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { getTimeProvider, getErrorMessage } from '../core/index.js';\nimport {\n isPersistenceEnabled,\n LEARNING_DIR,\n OUTCOMES_FILE,\n RULES_FILE,\n} from '../config/learning-persistence.js';\nimport { createAllAdapters } from '../cli-adapters/factory.js';\nimport type { CliName, HealthStatus, CapacityStatus } from '../cli-adapters/types.js';\nimport { DEFAULT_MODEL_CAPABILITIES } from '../config/model-capabilities.js';\nimport { createServer } from '../mcp/server.js';\nimport { printDoctorResults } from './doctor-formatting.js';\n\n/** Required Node.js major version. */\nconst REQUIRED_NODE_MAJOR = 22;\n\n/** API key environment variable names. */\nconst API_KEY_VARS = ['ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'GOOGLE_AI_API_KEY'] as const;\n\n/** Configuration file paths to check (in order of priority). */\nconst CONFIG_FILE_PATHS = ['./nexus-agents.yaml', './nexus-agents.yml'] as const;\n\n/**\n * Check result for a single CLI.\n */\nexport interface CliCheckResult {\n readonly name: CliName;\n readonly installed: boolean;\n readonly version: string;\n readonly versionStatus: 'supported' | 'outdated' | 'unsupported' | 'breaking';\n readonly authenticated: boolean;\n readonly authMethod?: string;\n readonly capacity?: CapacityStatus;\n readonly error?: string;\n readonly fix?: string;\n}\n\n/**\n * Node.js version check result.\n */\nexport interface NodeVersionCheck {\n readonly version: string;\n readonly major: number;\n readonly supported: boolean;\n}\n\n/**\n * API key check result.\n */\nexport interface ApiKeyCheck {\n readonly name: string;\n readonly configured: boolean;\n}\n\n/**\n * Configuration file check result.\n */\nexport interface ConfigFileCheck {\n readonly found: boolean;\n readonly path: string | null;\n}\n\n/**\n * Model availability advisory entry (#890).\n */\nexport interface ModelAdvisory {\n readonly modelId: string;\n readonly displayName: string;\n readonly cliName: string;\n readonly available: boolean;\n readonly reason: string;\n}\n\n/**\n * Learning persistence health check result (#1017).\n */\nexport interface LearningPersistenceCheck {\n readonly enabled: boolean;\n readonly dirExists: boolean;\n readonly dirWritable: boolean;\n readonly outcomeCount: number;\n readonly ruleCount: number;\n readonly rulesLastSaved: string | null;\n readonly error: string | null;\n}\n\n/**\n * Registry advisory summary (#890).\n */\nexport interface RegistryAdvisory {\n readonly totalModels: number;\n readonly availableModels: number;\n readonly unavailableModels: number;\n readonly models: readonly ModelAdvisory[];\n /** Days since the registry was last updated. */\n readonly registryAgeDays: number;\n /** True if the registry is >30 days old and may have stale model data. */\n readonly registryStale: boolean;\n}\n\n/**\n * SQLite (better-sqlite3) availability check (#1249).\n */\nexport interface SqliteCheck {\n readonly available: boolean;\n readonly error: string | null;\n}\n\n/**\n * Data directory health check (#1249).\n * Reports status of ~/.nexus-agents/ and its subdirectories.\n */\nexport interface DataDirectoryCheck {\n readonly rootExists: boolean;\n readonly rootPath: string;\n readonly subdirectories: readonly DataSubdirStatus[];\n}\n\n/**\n * Status of a single data subdirectory.\n */\nexport interface DataSubdirStatus {\n readonly name: string;\n readonly path: string;\n readonly exists: boolean;\n readonly writable: boolean;\n}\n\n/** Standard data subdirectories under ~/.nexus-agents/. */\nexport const DATA_SUBDIRECTORIES = [\n 'memory',\n 'memory/beliefs',\n 'learning',\n 'sessions',\n 'audit',\n 'voting',\n 'auth',\n 'research',\n 'checkpoints',\n] as const;\n\n/**\n * Complete doctor check results.\n */\nexport interface DoctorResult {\n readonly clis: CliCheckResult[];\n readonly nodeVersion: NodeVersionCheck;\n readonly apiKeys: ApiKeyCheck[];\n readonly configFile: ConfigFileCheck;\n readonly mcpServerReady: boolean;\n readonly mcpClientReady: boolean;\n /** Model registry advisory — which models are available (#890). */\n readonly registryAdvisory: RegistryAdvisory;\n /** Learning persistence health check (#1017). */\n readonly learningPersistence: LearningPersistenceCheck;\n /** SQLite (better-sqlite3) availability (#1249). */\n readonly sqliteCheck: SqliteCheck;\n /** Data directory health (#1249). */\n readonly dataDirectory: DataDirectoryCheck;\n readonly allHealthy: boolean;\n readonly timestamp: Date;\n}\n\n/**\n * Gets the CLI install/upgrade fix command.\n */\nfunction getFixCommand(name: CliName, issue: 'install' | 'upgrade' | 'auth'): string {\n const commands: Record<CliName, Record<string, string>> = {\n claude: {\n install: 'npm install -g @anthropic-ai/claude-code',\n upgrade: 'npm update -g @anthropic-ai/claude-code',\n auth: 'claude auth login',\n },\n gemini: {\n install: 'npm install -g @google/gemini-cli',\n upgrade: 'npm update -g @google/gemini-cli',\n auth: 'gemini auth login',\n },\n codex: {\n install: 'npm install -g @openai/codex',\n upgrade: 'npm update -g @openai/codex',\n auth: 'codex auth login',\n },\n opencode: {\n install: 'npm install -g opencode-ai',\n upgrade: 'npm update -g opencode-ai',\n auth: 'opencode auth login',\n },\n };\n return commands[name][issue] ?? '';\n}\n\n/**\n * Creates a result for when a CLI is not found.\n */\nfunction createNotFoundResult(name: CliName, errorMsg: string): CliCheckResult {\n return {\n name,\n installed: false,\n version: 'N/A',\n versionStatus: 'unsupported',\n authenticated: false,\n error: errorMsg,\n fix: getFixCommand(name, 'install'),\n };\n}\n\n/**\n * Determines the authentication method based on CLI name.\n * CLIs use their own auth mechanisms - we report the method type\n * rather than assuming a specific one like 'OAuth'.\n */\nfunction detectAuthMethod(name: CliName): string {\n const authMethods: Record<CliName, string> = {\n claude: 'CLI auth',\n gemini: 'ADC/CLI auth',\n codex: 'CLI auth',\n opencode: 'CLI auth',\n };\n return authMethods[name];\n}\n\n/**\n * Creates a result from a successful health check.\n */\nfunction createHealthyResult(\n name: CliName,\n health: HealthStatus,\n capacity?: CapacityStatus\n): CliCheckResult {\n const authenticated = health.healthy;\n\n const result: CliCheckResult = {\n name,\n installed: true,\n version: health.version,\n versionStatus: health.versionStatus,\n authenticated,\n ...(authenticated && { authMethod: detectAuthMethod(name) }),\n ...(capacity !== undefined && { capacity }),\n };\n\n if (health.message !== undefined && health.message !== '') {\n return { ...result, error: health.message };\n }\n if (!authenticated) {\n return { ...result, fix: getFixCommand(name, 'auth') };\n }\n if (health.versionStatus === 'outdated') {\n return { ...result, fix: getFixCommand(name, 'upgrade') };\n }\n\n return result;\n}\n\n/**\n * Runs health check on a single CLI adapter.\n */\nasync function checkCli(name: CliName): Promise<CliCheckResult> {\n const adapters = createAllAdapters();\n const adapter = adapters.get(name);\n\n if (!adapter) {\n return createNotFoundResult(name, 'Adapter not available');\n }\n\n try {\n const health: HealthStatus = await adapter.healthCheck();\n let capacity: CapacityStatus | undefined;\n\n try {\n capacity = await adapter.getCapacity();\n } catch (capErr: unknown) {\n // Capacity check is optional — some adapters don't support it\n void capErr; // Logged at debug via adapter internals\n }\n\n return createHealthyResult(name, health, capacity);\n } catch (error) {\n const message = getErrorMessage(error);\n const isNotFound = message.includes('ENOENT') || message.includes('not found');\n return createNotFoundResult(name, isNotFound ? 'Not found in PATH' : message);\n }\n}\n\n/**\n * Checks the Node.js version against the required version.\n */\nfunction checkNodeVersion(): NodeVersionCheck {\n const version = process.version;\n const major = Number(version.slice(1).split('.')[0]);\n return {\n version,\n major,\n supported: major >= REQUIRED_NODE_MAJOR,\n };\n}\n\n/**\n * Checks which API keys are configured in the environment.\n * Does NOT expose the actual key values - only reports presence.\n */\nfunction checkApiKeys(): ApiKeyCheck[] {\n return API_KEY_VARS.map((name) => ({\n name,\n configured: typeof process.env[name] === 'string' && process.env[name] !== '',\n }));\n}\n\n/**\n * Checks for the existence of a configuration file.\n */\nfunction checkConfigFile(): ConfigFileCheck {\n for (const configPath of CONFIG_FILE_PATHS) {\n if (existsSync(configPath)) {\n return { found: true, path: configPath };\n }\n }\n return { found: false, path: null };\n}\n\n/**\n * Validates that the MCP server can be created successfully.\n * This is a lightweight check that verifies server instantiation works.\n */\nfunction checkMcpServerReady(): boolean {\n try {\n const result = createServer({ name: 'nexus-agents-doctor-check' });\n return result.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds model registry advisory based on detected CLI availability (#890).\n */\nfunction buildRegistryAdvisory(cliResults: CliCheckResult[]): RegistryAdvisory {\n const installedClis = new Set(cliResults.filter((c) => c.installed).map((c) => c.name));\n\n const models: ModelAdvisory[] = DEFAULT_MODEL_CAPABILITIES.models\n .filter((m) => m.cliName !== undefined)\n .map((m) => {\n const cliName = m.cliName ?? '';\n const available = cliName.length > 0 && installedClis.has(cliName as CliName);\n const reason = available ? `${cliName} CLI is installed` : `${cliName} CLI is not installed`;\n return { modelId: m.id, displayName: m.displayName, cliName, available, reason };\n });\n\n // Registry staleness check (#1549)\n const STALE_THRESHOLD_DAYS = 30;\n const updatedAt = new Date(DEFAULT_MODEL_CAPABILITIES.updatedAt);\n const nowMs = getTimeProvider().now();\n const ageDays = Math.floor((nowMs - updatedAt.getTime()) / (1000 * 60 * 60 * 24));\n\n return {\n totalModels: models.length,\n availableModels: models.filter((m) => m.available).length,\n unavailableModels: models.filter((m) => !m.available).length,\n models,\n registryAgeDays: ageDays,\n registryStale: ageDays > STALE_THRESHOLD_DAYS,\n };\n}\n\n/** Counts non-empty lines in a JSONL file. Returns 0 if file doesn't exist. */\nfunction countJsonlLines(filePath: string): number {\n if (!existsSync(filePath)) return 0;\n return readFileSync(filePath, 'utf-8')\n .split('\\n')\n .filter((l) => l.trim().length > 0).length;\n}\n\n/** Reads rules snapshot metadata. Returns count and savedAt. */\nfunction readRulesMetadata(filePath: string): { count: number; savedAt: string | null } {\n if (!existsSync(filePath)) return { count: 0, savedAt: null };\n try {\n const raw = JSON.parse(readFileSync(filePath, 'utf-8')) as Record<string, unknown>;\n const rules = raw['rules'];\n const saved = raw['savedAt'];\n return {\n count: Array.isArray(rules) ? rules.length : 0,\n savedAt: typeof saved === 'string' ? saved : null,\n };\n } catch {\n return { count: 0, savedAt: null };\n }\n}\n\n/** Checks if a directory exists and is writable. */\nfunction checkDirAccess(dir: string): { exists: boolean; writable: boolean } {\n const exists = existsSync(dir);\n if (!exists) return { exists: false, writable: false };\n try {\n accessSync(dir, fsConstants.W_OK);\n return { exists: true, writable: true };\n } catch {\n return { exists: true, writable: false };\n }\n}\n\nconst DISABLED_CHECK: LearningPersistenceCheck = {\n enabled: false,\n dirExists: false,\n dirWritable: false,\n outcomeCount: 0,\n ruleCount: 0,\n rulesLastSaved: null,\n error: null,\n};\n\n/** Checks learning persistence health (#1017). */\nfunction checkLearningPersistence(): LearningPersistenceCheck {\n if (!isPersistenceEnabled()) return DISABLED_CHECK;\n try {\n const { exists: dirExists, writable: dirWritable } = checkDirAccess(LEARNING_DIR);\n const outcomeCount = countJsonlLines(OUTCOMES_FILE);\n const { count: ruleCount, savedAt: rulesLastSaved } = readRulesMetadata(RULES_FILE);\n return {\n enabled: true,\n dirExists,\n dirWritable,\n outcomeCount,\n ruleCount,\n rulesLastSaved,\n error: null,\n };\n } catch (error: unknown) {\n return {\n enabled: true,\n dirExists: false,\n dirWritable: false,\n outcomeCount: 0,\n ruleCount: 0,\n rulesLastSaved: null,\n error: getErrorMessage(error),\n };\n }\n}\n\n/**\n * Checks if better-sqlite3 is available (#1249).\n * Memory backends (agentic, adaptive, typed, mobimem, decay) require it.\n */\nasync function checkSqlite(): Promise<SqliteCheck> {\n try {\n await import('better-sqlite3');\n return { available: true, error: null };\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n const isNotFound = msg.includes('Cannot find') || msg.includes('MODULE_NOT_FOUND');\n return {\n available: false,\n error: isNotFound\n ? 'better-sqlite3 not installed — 5 memory backends unavailable'\n : `better-sqlite3 load error: ${msg}`,\n };\n }\n}\n\n/**\n * Checks the ~/.nexus-agents/ data directory health (#1249).\n */\nfunction checkDataDirectory(): DataDirectoryCheck {\n const rootPath = join(homedir(), '.nexus-agents');\n const rootExists = existsSync(rootPath);\n\n const subdirectories: DataSubdirStatus[] = DATA_SUBDIRECTORIES.map((name) => {\n const fullPath = join(rootPath, name);\n const exists = existsSync(fullPath);\n return { name, path: fullPath, exists, writable: exists && isWritable(fullPath) };\n });\n\n return { rootExists, rootPath, subdirectories };\n}\n\n/** Checks if a directory is writable by the current user. */\nfunction isWritable(dirPath: string): boolean {\n try {\n accessSync(dirPath, fsConstants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Runs the complete doctor check.\n */\nexport async function runDoctor(): Promise<DoctorResult> {\n const clis = await Promise.all([\n checkCli('claude'),\n checkCli('gemini'),\n checkCli('codex'),\n checkCli('opencode'),\n ]);\n const nodeVersion = checkNodeVersion();\n const apiKeys = checkApiKeys();\n const configFile = checkConfigFile();\n const mcpServerReady = checkMcpServerReady();\n const codexCheck = clis.find((c) => c.name === 'codex');\n const mcpClientReady = codexCheck?.installed ?? false;\n const registryAdvisory = buildRegistryAdvisory(clis);\n const learningPersistence = checkLearningPersistence();\n const sqliteCheck = await checkSqlite();\n const dataDirectory = checkDataDirectory();\n\n // At least one API key configured or one CLI authenticated\n const hasAuthMethod =\n apiKeys.some((k) => k.configured) || clis.some((c) => c.installed && c.authenticated);\n\n const allHealthy =\n nodeVersion.supported &&\n hasAuthMethod &&\n mcpServerReady &&\n clis.every((c) => c.installed && c.authenticated && c.versionStatus !== 'unsupported');\n\n return {\n clis,\n nodeVersion,\n apiKeys,\n configFile,\n mcpServerReady,\n mcpClientReady,\n registryAdvisory,\n learningPersistence,\n sqliteCheck,\n dataDirectory,\n allHealthy,\n timestamp: new Date(getTimeProvider().now()),\n };\n}\n\n/** Doctor command options. */\nexport interface DoctorOptions {\n /** Auto-fix safe issues (run setup, generate config). */\n readonly fix?: boolean;\n}\n\n/**\n * Runs the doctor command and prints results.\n * Returns exit code (0 = healthy, 1 = issues found).\n */\nexport async function doctorCommand(options: DoctorOptions = {}): Promise<number> {\n const result = await runDoctor();\n printDoctorResults(result);\n\n if (options.fix === true) {\n await runDoctorFix(result);\n }\n\n return result.allHealthy ? 0 : 1;\n}\n\n/**\n * Auto-fixes safe issues found by doctor (#1254).\n * Only runs our own code — never execs external package managers.\n */\nasync function runDoctorFix(result: DoctorResult): Promise<void> {\n const writeLine = (text: string): void => {\n process.stdout.write(text + '\\n');\n };\n\n writeLine('');\n writeLine('\\x1b[1mAuto-fix\\x1b[0m');\n writeLine('─'.repeat(40));\n\n let fixCount = 0;\n\n // Fix: data directories (missing or not writable)\n if (\n !result.dataDirectory.rootExists ||\n result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)\n ) {\n const { runSetup } = await import('./setup-command.js');\n const setupResult = runSetup({\n skipMcp: true,\n skipRules: true,\n skipHooks: true,\n skipConfig: true,\n skipOpencode: true,\n });\n if (setupResult.success) {\n writeLine('✓ Created missing data directories');\n fixCount++;\n }\n }\n\n // Fix: config file\n if (!result.configFile.found) {\n const { runConfigInitSync } = await import('./setup-config.js');\n const configResult = runConfigInitSync(process.cwd(), false, false);\n if (configResult.success && configResult.created) {\n writeLine(`✓ Generated config: ${configResult.path}`);\n fixCount++;\n }\n }\n\n // Display-only: better-sqlite3\n if (!result.sqliteCheck.available) {\n writeLine('');\n writeLine('⚠ better-sqlite3 not installed (manual step required):');\n writeLine(' npm install -g better-sqlite3');\n }\n\n if (fixCount > 0) {\n writeLine('');\n writeLine(\n `\\x1b[32m${String(fixCount)} issue(s) fixed.\\x1b[0m Re-run \\x1b[1mnexus-agents doctor\\x1b[0m to verify.`\n );\n } else {\n writeLine('No auto-fixable issues found.');\n }\n writeLine('');\n}\n\n// Re-export printDoctorResults for backward compatibility\nexport { printDoctorResults } from './doctor-formatting.js';\n","/**\n * nexus-agents/mcp - MCP Server\n *\n * Main MCP server implementation for Nexus Agents orchestration.\n * Provides factory functions to create and start the server with\n * stdio or custom transports.\n *\n * (Source: MCP Protocol 2025-11-25)\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\n\nimport {\n getErrorMessage,\n createLogger,\n type Result,\n ok,\n err,\n type ILogger,\n} from '../core/index.js';\nimport { VERSION } from '../version.js';\nimport { getTaskStore } from './task-store.js';\nimport { initDataDirectories } from '../cli/setup-data-dir.js';\n\n/**\n * Server configuration options.\n */\nexport interface ServerConfig {\n /** Server name (default: \"nexus-agents\") */\n readonly name?: string;\n /** Server version (default: package version) */\n readonly version?: string;\n /** Logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Server creation result containing the server and logger.\n */\nexport interface ServerInstance {\n /** The MCP server instance */\n readonly server: McpServer;\n /** The logger instance for this server */\n readonly logger: ILogger;\n}\n\n/**\n * Error type for server operations.\n */\nexport interface ServerError {\n code: 'SERVER_CREATION_FAILED' | 'SERVER_START_FAILED' | 'SERVER_STOP_FAILED';\n message: string;\n cause?: Error;\n}\n\nconst DEFAULT_SERVER_NAME = 'nexus-agents';\n\n/**\n * Creates a ServerError with the given code, message, and optional cause.\n */\nfunction createServerError(\n code: ServerError['code'],\n message: string,\n error: unknown\n): ServerError {\n const serverError: ServerError = { code, message };\n if (error instanceof Error) {\n serverError.cause = error;\n }\n return serverError;\n}\n\n/**\n * Creates a new MCP server instance.\n *\n * @param config - Optional server configuration\n * @returns Result containing the server instance or an error\n *\n * @example\n * ```typescript\n * const result = createServer({ name: 'my-server' });\n * if (result.ok) {\n * const { server, logger } = result.value;\n * // Register tools on server\n * }\n * ```\n */\nexport function createServer(config?: ServerConfig): Result<ServerInstance, ServerError> {\n const serverName = config?.name ?? DEFAULT_SERVER_NAME;\n const serverVersion = config?.version ?? VERSION;\n const logger = config?.logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n // Ensure data directories exist on first MCP server startup (#1398)\n initDataDirectories();\n\n logger.info('Creating MCP server', {\n name: serverName,\n version: serverVersion,\n });\n\n const server = new McpServer(\n {\n name: serverName,\n version: serverVersion,\n },\n {\n capabilities: {\n logging: {},\n prompts: {},\n resources: {},\n tasks: {},\n },\n taskStore: getTaskStore(),\n }\n );\n\n logger.debug('MCP server created successfully');\n\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to create MCP server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_CREATION_FAILED',\n `Failed to create MCP server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Connects the server to a transport.\n *\n * @param server - The MCP server instance\n * @param transport - The transport to connect to\n * @param logger - Logger for the operation\n * @returns Result indicating success or failure\n */\nexport async function connectTransport(\n server: McpServer,\n transport: Transport,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n log.info('Connecting server to transport');\n await server.connect(transport);\n log.debug('Server connected to transport successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to connect to transport', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to connect to transport: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Starts the MCP server with stdio transport.\n *\n * This is the main entry point for running the server as a standalone process.\n * The server will communicate over stdin/stdout using the MCP protocol.\n *\n * @param config - Optional server configuration\n * @returns Result indicating success or failure\n *\n * @example\n * ```typescript\n * const result = await startStdioServer();\n * if (!result.ok) {\n * console.error('Failed to start server:', result.error.message);\n * process.exit(1);\n * }\n * ```\n */\nexport async function startStdioServer(\n config?: ServerConfig\n): Promise<Result<ServerInstance, ServerError>> {\n const serverResult = createServer(config);\n if (!serverResult.ok) {\n return serverResult;\n }\n\n const { server, logger } = serverResult.value;\n\n try {\n // Defense-in-depth: stdio transport owns stdout for JSON-RPC frames.\n logger.setDestination?.('stderr');\n logger.info('Starting stdio transport');\n const transport = new StdioServerTransport();\n\n const connectResult = await connectTransport(server, transport, logger);\n if (!connectResult.ok) {\n return connectResult;\n }\n\n logger.info('MCP server running with stdio transport');\n return ok({ server, logger });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n logger.error('Failed to start stdio server', error instanceof Error ? error : undefined);\n return err(\n createServerError(\n 'SERVER_START_FAILED',\n `Failed to start stdio server: ${errorMessage}`,\n error\n )\n );\n }\n}\n\n/**\n * Gracefully closes the server connection.\n *\n * @param server - The MCP server to close\n * @param logger - Optional logger\n * @returns Result indicating success or failure\n */\nexport async function closeServer(\n server: McpServer,\n logger?: ILogger\n): Promise<Result<void, ServerError>> {\n const log = logger ?? createLogger({ component: 'mcp-server' });\n\n try {\n log.info('Closing MCP server');\n await server.close();\n log.info('MCP server closed successfully');\n return ok(undefined);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n log.error('Failed to close server', error instanceof Error ? error : undefined);\n return err(\n createServerError('SERVER_STOP_FAILED', `Failed to close server: ${errorMessage}`, error)\n );\n }\n}\n","/**\n * Nexus-Agents Task Store — wraps SDK InMemoryTaskStore with security controls.\n *\n * Provides:\n * - TTL enforcement (max 10 minutes per task)\n * - Capacity cap (max 50 tasks, FIFO eviction when exceeded)\n * - Singleton access via `getTaskStore()`\n * - Periodic cleanup of expired tasks\n *\n * @module mcp/task-store\n * (Source: Issue #1298 — Layer 2 MCP Tasks async execution)\n */\n\nimport { InMemoryTaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport type { TaskStore } from '@modelcontextprotocol/sdk/experimental/tasks';\nimport { createLogger } from '../core/index.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Maximum TTL for any task (10 minutes). */\nexport const MAX_TASK_TTL_MS = 600_000;\n\n/** Default TTL applied when none specified (5 minutes). */\nexport const DEFAULT_TASK_TTL_MS = 300_000;\n\n/** Maximum number of tasks before FIFO eviction. */\nexport const MAX_TASK_CAPACITY = 50;\n\n/** Interval for periodic cleanup of expired tasks (60 seconds). */\nconst CLEANUP_INTERVAL_MS = 60_000;\n\n// ============================================================================\n// Singleton\n// ============================================================================\n\nconst logger = createLogger({ component: 'task-store' });\n\nlet singletonStore: InMemoryTaskStore | undefined;\nlet cleanupTimer: ReturnType<typeof setInterval> | undefined;\n\n/**\n * Returns the singleton InMemoryTaskStore, creating it on first call.\n *\n * The SDK's InMemoryTaskStore handles TTL cleanup internally.\n * We enforce our MAX_TASK_TTL_MS via `clampTaskTtl()` at task creation\n * (done by the ToolTaskHandler, not the store itself).\n */\nexport function getTaskStore(): TaskStore {\n if (singletonStore === undefined) {\n singletonStore = new InMemoryTaskStore();\n logger.info('Task store created', { maxCapacity: MAX_TASK_CAPACITY });\n\n // Periodic cleanup: evict oldest tasks if capacity exceeded\n cleanupTimer = setInterval(() => {\n evictExcessTasks();\n }, CLEANUP_INTERVAL_MS);\n\n // Prevent cleanup timer from keeping Node alive\n if (typeof cleanupTimer === 'object' && 'unref' in cleanupTimer) {\n cleanupTimer.unref();\n }\n }\n return singletonStore;\n}\n\n/**\n * Clamps a requested TTL to the maximum allowed value.\n * Returns DEFAULT_TASK_TTL_MS if no TTL is specified or null.\n */\nexport function clampTaskTtl(requestedTtl?: number | null): number {\n if (requestedTtl === undefined || requestedTtl === null) {\n return DEFAULT_TASK_TTL_MS;\n }\n if (requestedTtl > MAX_TASK_TTL_MS) {\n logger.warn('Task TTL clamped to maximum', {\n requested: requestedTtl,\n max: MAX_TASK_TTL_MS,\n });\n return MAX_TASK_TTL_MS;\n }\n return requestedTtl;\n}\n\n/**\n * Evicts oldest tasks when capacity is exceeded (FIFO).\n * Best-effort — logs warnings but does not throw.\n */\nfunction evictExcessTasks(): void {\n if (singletonStore === undefined) return;\n\n const allTasks = singletonStore.getAllTasks();\n if (allTasks.length <= MAX_TASK_CAPACITY) return;\n\n // Sort by creation time ascending (oldest first)\n const sorted = [...allTasks].sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n );\n\n const evictCount = sorted.length - MAX_TASK_CAPACITY;\n for (let i = 0; i < evictCount; i++) {\n const task = sorted[i];\n if (task === undefined) continue;\n singletonStore\n .updateTaskStatus(task.taskId, 'cancelled', 'Evicted: capacity exceeded')\n .catch((err: unknown) => {\n logger.debug('Failed to evict task', {\n taskId: task.taskId,\n error: String(err),\n });\n });\n }\n\n logger.info('Evicted excess tasks', { evicted: evictCount, total: sorted.length });\n}\n\n/**\n * Shuts down the task store and cleanup timer.\n * Call during server shutdown. Safe to call multiple times.\n * @internal\n */\nexport function shutdownTaskStore(): void {\n if (cleanupTimer !== undefined) {\n clearInterval(cleanupTimer);\n cleanupTimer = undefined;\n }\n if (singletonStore !== undefined) {\n singletonStore.cleanup();\n singletonStore = undefined;\n logger.info('Task store shut down');\n }\n}\n\n/** Resets the singleton for testing. @internal */\nexport function resetTaskStore(): void {\n shutdownTaskStore();\n}\n","/**\n * nexus-agents doctor command - Formatting utilities\n *\n * Terminal output formatting for doctor command results.\n * Extracted to comply with 400-line file limit.\n *\n * (Source: Issue #422 - Doctor command validations)\n */\n\nimport { DEFAULT_CAPABILITIES } from '../cli-adapters/types.js';\nimport type { CapacityStatus } from '../cli-adapters/types.js';\nimport type {\n CliCheckResult,\n NodeVersionCheck,\n ApiKeyCheck,\n ConfigFileCheck,\n RegistryAdvisory,\n LearningPersistenceCheck,\n SqliteCheck,\n DataDirectoryCheck,\n DoctorResult,\n} from './doctor.js';\nimport { colors, symbols, writeLine } from './ansi-output.js';\nimport { capitalize } from '../utils/text-utils.js';\n\n/** Required Node.js major version (for warning message). */\nconst REQUIRED_NODE_MAJOR = 22;\n\n/**\n * Formats a status symbol with color.\n */\nfunction formatStatus(healthy: boolean, warn = false): string {\n if (healthy) return `${colors.green}${symbols.check}${colors.reset}`;\n if (warn) return `${colors.yellow}${symbols.warn}${colors.reset}`;\n return `${colors.red}${symbols.cross}${colors.reset}`;\n}\n\n/**\n * Formats version status with color.\n */\nfunction formatVersionStatus(status: string): string {\n switch (status) {\n case 'supported':\n return `${colors.green}supported${colors.reset}`;\n case 'outdated':\n return `${colors.yellow}outdated${colors.reset}`;\n case 'unsupported':\n case 'breaking':\n return `${colors.red}${status}${colors.reset}`;\n default:\n return status;\n }\n}\n\n/**\n * Formats capacity as percentage string.\n */\nfunction formatCapacity(capacity?: CapacityStatus): string {\n if (capacity === undefined) return 'Unknown';\n const remaining = 100 - capacity.utilizationPercent;\n const remainingStr = String(remaining);\n if (remaining > 80) return `${colors.green}${remainingStr}% remaining${colors.reset}`;\n if (remaining > 20) return `${colors.yellow}${remainingStr}% remaining${colors.reset}`;\n return `${colors.red}${remainingStr}% remaining${colors.reset}`;\n}\n\n/**\n * Prints details for an installed CLI.\n */\nfunction printInstalledCliDetails(cli: CliCheckResult): void {\n writeLine(` Version: ${cli.version} (${formatVersionStatus(cli.versionStatus)})`);\n\n const authText = cli.authenticated\n ? `${colors.green}${cli.authMethod ?? 'Authenticated'}${colors.reset}`\n : `${colors.red}Not authenticated${colors.reset}`;\n writeLine(` Auth: ${authText}`);\n\n if (cli.capacity !== undefined) {\n writeLine(` Capacity: ${formatCapacity(cli.capacity)}`);\n }\n}\n\n/**\n * Prints a single CLI result.\n */\nfunction printCliResult(cli: CliCheckResult): void {\n const status = cli.installed && cli.authenticated;\n const warn = cli.installed && (!cli.authenticated || cli.versionStatus === 'outdated');\n\n writeLine(\n `${formatStatus(status, warn)} ${colors.bold}${capitalize(cli.name)} CLI${colors.reset}`\n );\n\n if (cli.installed) {\n printInstalledCliDetails(cli);\n } else {\n const errorText = cli.error ?? 'Not installed';\n writeLine(` ${colors.red}Error: ${errorText}${colors.reset}`);\n }\n\n if (cli.fix !== undefined && cli.fix !== '') {\n writeLine(` ${colors.dim}Fix: ${cli.fix}${colors.reset}`);\n }\n\n writeLine('');\n}\n\n/**\n * Prints capability summary for installed CLIs.\n */\nfunction printCapabilities(clis: CliCheckResult[]): void {\n const installedClis = clis.filter((c) => c.installed);\n\n if (installedClis.length === 0) {\n writeLine(`${formatStatus(false)} No CLIs installed`);\n return;\n }\n\n const caps = DEFAULT_CAPABILITIES;\n const bestReasoning = installedClis.reduce((best, c) =>\n caps[c.name].reasoning > caps[best.name].reasoning ? c : best\n );\n const bestContext = installedClis.reduce((best, c) =>\n caps[c.name].contextWindow > caps[best.name].contextWindow ? c : best\n );\n const bestSpeed = installedClis.reduce((best, c) =>\n caps[c.name].speed > caps[best.name].speed ? c : best\n );\n\n const contextTokensK = (caps[bestContext.name].contextWindow / 1000).toFixed(0);\n\n writeLine(\n `${formatStatus(true)} Complex reasoning: ${colors.bold}${capitalize(bestReasoning.name)}${colors.reset}`\n );\n writeLine(\n `${formatStatus(true)} Large context: ${colors.bold}${capitalize(bestContext.name)}${colors.reset} (${contextTokensK}K tokens)`\n );\n writeLine(\n `${formatStatus(true)} Fast execution: ${colors.bold}${capitalize(bestSpeed.name)}${colors.reset}`\n );\n}\n\n/**\n * Prints Node.js version check result.\n */\nfunction printNodeVersionCheck(check: NodeVersionCheck): void {\n const versionText = check.supported\n ? `${colors.green}${check.version}${colors.reset}`\n : `${colors.yellow}${check.version}${colors.reset}`;\n writeLine(`${formatStatus(check.supported, !check.supported)} Node.js version: ${versionText}`);\n if (!check.supported) {\n writeLine(\n ` ${colors.dim}Warning: Node.js ${String(REQUIRED_NODE_MAJOR)}.x LTS required${colors.reset}`\n );\n }\n}\n\n/**\n * Prints API key configuration check results.\n */\nfunction printApiKeysCheck(keys: ApiKeyCheck[]): void {\n const configuredCount = keys.filter((k) => k.configured).length;\n const configuredNames = keys.filter((k) => k.configured).map((k) => k.name);\n const hasAny = configuredCount > 0;\n\n writeLine(\n `${formatStatus(hasAny, !hasAny)} API keys configured: ${String(configuredCount)} of ${String(keys.length)}`\n );\n if (hasAny) {\n writeLine(` ${colors.dim}Keys: ${configuredNames.join(', ')}${colors.reset}`);\n } else {\n writeLine(\n ` ${colors.dim}Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY${colors.reset}`\n );\n }\n}\n\n/**\n * Prints configuration file check result.\n */\nfunction printConfigFileCheck(check: ConfigFileCheck): void {\n if (check.found && check.path !== null) {\n writeLine(`${formatStatus(true)} Configuration loaded: ${check.path}`);\n } else {\n writeLine(`${formatStatus(false, true)} Configuration file: Not found`);\n writeLine(` ${colors.dim}Run: nexus-agents config init${colors.reset}`);\n }\n}\n\n/**\n * Prints model registry advisory (#890).\n */\nfunction printRegistryAdvisory(advisory: RegistryAdvisory): void {\n const allAvailable = advisory.unavailableModels === 0;\n const countText = `${String(advisory.availableModels)} of ${String(advisory.totalModels)}`;\n writeLine(`${formatStatus(allAvailable, !allAvailable)} Models available: ${countText}`);\n if (advisory.unavailableModels > 0) {\n const missing = advisory.models.filter((m) => !m.available);\n for (const m of missing) {\n writeLine(` ${colors.dim}${m.displayName} — ${m.reason}${colors.reset}`);\n }\n }\n // Registry staleness warning (#1549)\n const ageText = `${String(advisory.registryAgeDays)} days old`;\n if (advisory.registryStale) {\n writeLine(\n `${colors.yellow}${symbols.warn}${colors.reset} Model registry is ${ageText} — may have stale model data`\n );\n writeLine(` ${colors.dim}Run: npx tsx scripts/probe-models.ts${colors.reset}`);\n } else {\n writeLine(`${formatStatus(true)} Model registry: ${ageText}`);\n }\n}\n\n/**\n * Prints learning persistence health check (#1017).\n */\nfunction printLearningPersistence(check: LearningPersistenceCheck): void {\n if (!check.enabled) {\n writeLine(`${formatStatus(true)} Learning persistence: ${colors.dim}Disabled${colors.reset}`);\n writeLine(` ${colors.dim}Set NEXUS_PERSIST_LEARNING=true to enable${colors.reset}`);\n return;\n }\n\n const healthy = check.dirExists && check.dirWritable && check.error === null;\n writeLine(`${formatStatus(healthy, !healthy)} Learning persistence: Enabled`);\n\n if (check.error !== null) {\n writeLine(` ${colors.red}Error: ${check.error}${colors.reset}`);\n return;\n }\n\n const dirStatus = check.dirExists\n ? check.dirWritable\n ? `${colors.green}writable${colors.reset}`\n : `${colors.red}not writable${colors.reset}`\n : `${colors.yellow}not created yet${colors.reset}`;\n writeLine(` Data directory: ${dirStatus}`);\n writeLine(` Outcomes: ${String(check.outcomeCount)} recorded`);\n writeLine(` Distilled rules: ${String(check.ruleCount)} active`);\n if (check.rulesLastSaved !== null) {\n writeLine(` Rules last saved: ${check.rulesLastSaved}`);\n }\n}\n\n/**\n * Prints SQLite (better-sqlite3) availability check (#1249).\n */\nfunction printSqliteCheck(check: SqliteCheck): void {\n if (check.available) {\n writeLine(\n `${formatStatus(true)} SQLite (better-sqlite3): ${colors.green}Available${colors.reset}`\n );\n } else {\n writeLine(\n `${formatStatus(false, true)} SQLite (better-sqlite3): ${colors.yellow}Not available${colors.reset}`\n );\n writeLine(\n ` ${colors.dim}Memory backends (agentic, adaptive, typed) require it${colors.reset}`\n );\n writeLine(` ${colors.dim}Fix: npm install -g better-sqlite3${colors.reset}`);\n }\n}\n\n/**\n * Prints data directory health check (#1249).\n */\nfunction printDataDirectory(check: DataDirectoryCheck): void {\n if (check.rootExists) {\n const existCount = check.subdirectories.filter((d) => d.exists).length;\n const totalCount = check.subdirectories.length;\n const allExist = existCount === totalCount;\n const allWritable = check.subdirectories.every((d) => !d.exists || d.writable);\n const healthy = allExist && allWritable;\n writeLine(\n `${formatStatus(healthy, !healthy)} Data directory: ${check.rootPath} (${String(existCount)}/${String(totalCount)} subdirs)`\n );\n if (!allExist) {\n const missing = check.subdirectories.filter((d) => !d.exists);\n for (const dir of missing) {\n writeLine(` ${colors.dim}Missing: ${dir.name}/${colors.reset}`);\n }\n writeLine(` ${colors.dim}Fix: nexus-agents setup${colors.reset}`);\n }\n if (!allWritable) {\n const readonly_ = check.subdirectories.filter((d) => d.exists && !d.writable);\n for (const dir of readonly_) {\n writeLine(` ${colors.yellow}Not writable: ${dir.name}/${colors.reset}`);\n }\n }\n } else {\n writeLine(\n `${formatStatus(false, true)} Data directory: ${colors.yellow}Not created${colors.reset}`\n );\n writeLine(` ${colors.dim}Run: nexus-agents setup${colors.reset}`);\n }\n}\n\n/** Prints the summary line with issue count. */\nfunction printDoctorSummary(result: DoctorResult): void {\n const unhealthyCount = result.clis.filter((c) => !c.installed || !c.authenticated).length;\n const nodeIssue = result.nodeVersion.supported ? 0 : 1;\n const totalIssues = unhealthyCount + nodeIssue + (result.mcpServerReady ? 0 : 1);\n const summary = result.allHealthy\n ? `${colors.green}${colors.bold}Status: Ready${colors.reset}`\n : `${colors.yellow}${colors.bold}Summary: ${String(totalIssues)} issue(s) found${colors.reset}`;\n writeLine(summary);\n writeLine('');\n}\n\n/**\n * Prints the doctor results to stdout.\n */\nexport function printDoctorResults(result: DoctorResult): void {\n writeLine('');\n writeLine(`${colors.bold}Nexus Agents Doctor${colors.reset}`);\n writeLine('===================');\n writeLine('');\n\n writeLine(`${colors.cyan}Checking environment...${colors.reset}`);\n writeLine('');\n printNodeVersionCheck(result.nodeVersion);\n printApiKeysCheck(result.apiKeys);\n printConfigFileCheck(result.configFile);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking CLI installations...${colors.reset}`);\n writeLine('');\n for (const cli of result.clis) {\n printCliResult(cli);\n }\n\n writeLine(`${colors.cyan}Checking MCP configuration...${colors.reset}`);\n writeLine('');\n writeLine(\n `${formatStatus(result.mcpServerReady)} MCP Server mode: ${result.mcpServerReady ? 'Ready' : 'Not ready'}`\n );\n writeLine(\n `${formatStatus(result.mcpClientReady)} MCP Client mode: ${result.mcpClientReady ? 'Ready (Codex mcp-server)' : 'Not ready (Codex not installed)'}`\n );\n writeLine('');\n\n writeLine(`${colors.cyan}Checking capabilities...${colors.reset}`);\n writeLine('');\n printCapabilities(result.clis);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking model registry...${colors.reset}`);\n writeLine('');\n printRegistryAdvisory(result.registryAdvisory);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking learning subsystem...${colors.reset}`);\n writeLine('');\n printLearningPersistence(result.learningPersistence);\n writeLine('');\n\n writeLine(`${colors.cyan}Checking data storage...${colors.reset}`);\n writeLine('');\n printSqliteCheck(result.sqliteCheck);\n printDataDirectory(result.dataDirectory);\n writeLine('');\n\n printDoctorSummary(result);\n}\n"],"mappings":"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","names":["existsSync","homedir","join","err","logger","REQUIRED_NODE_MAJOR","writeLine","join","homedir","existsSync"]}
|