nexus-agents 2.29.0 → 2.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adaptive-memory-RST6DZYR.js +15 -0
- package/dist/chunk-2UR7YN6T.js +700 -0
- package/dist/chunk-2UR7YN6T.js.map +1 -0
- package/dist/{chunk-KGDG6PWZ.js → chunk-2UUUKVNR.js} +2 -2
- package/dist/{chunk-5VZLXMO7.js → chunk-3EVVQ32X.js} +6 -6
- package/dist/{chunk-WSK4VSXP.js → chunk-3GXDN4AX.js} +2 -2
- package/dist/{chunk-ZBZJHXRT.js → chunk-4AGPR6XZ.js} +19 -347
- package/dist/chunk-4AGPR6XZ.js.map +1 -0
- package/dist/{chunk-7F6HYUIY.js → chunk-4HA5PAL7.js} +16 -97
- package/dist/chunk-4HA5PAL7.js.map +1 -0
- package/dist/chunk-7SKAKA4I.js +90 -0
- package/dist/chunk-7SKAKA4I.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-C2C5ONFR.js +195 -0
- package/dist/chunk-C2C5ONFR.js.map +1 -0
- package/dist/{chunk-S3BKWNST.js → chunk-CGWRJ4EM.js} +614 -1428
- package/dist/chunk-CGWRJ4EM.js.map +1 -0
- package/dist/chunk-ED6VQWNG.js +63 -0
- package/dist/chunk-ED6VQWNG.js.map +1 -0
- package/dist/{chunk-IMWYKX4H.js → chunk-ELIFTCYM.js} +443 -398
- package/dist/chunk-ELIFTCYM.js.map +1 -0
- package/dist/chunk-FYJVXQHX.js +944 -0
- package/dist/chunk-FYJVXQHX.js.map +1 -0
- package/dist/{chunk-DAMRMAM2.js → chunk-FZFZ77UJ.js} +12127 -14458
- package/dist/chunk-FZFZ77UJ.js.map +1 -0
- package/dist/chunk-IECE6DBS.js +1585 -0
- package/dist/chunk-IECE6DBS.js.map +1 -0
- package/dist/chunk-LLGUX44Z.js +356 -0
- package/dist/chunk-LLGUX44Z.js.map +1 -0
- package/dist/chunk-MRU6L7YJ.js +931 -0
- package/dist/chunk-MRU6L7YJ.js.map +1 -0
- package/dist/{chunk-T7PU3NPQ.js → chunk-N5SY7V45.js} +7 -5
- package/dist/{chunk-T7PU3NPQ.js.map → chunk-N5SY7V45.js.map} +1 -1
- package/dist/{chunk-POBO4G2P.js → chunk-OOIPRRPX.js} +100 -10
- package/dist/chunk-OOIPRRPX.js.map +1 -0
- package/dist/{chunk-I6YDS23R.js → chunk-SRECH7OQ.js} +2 -2
- package/dist/{chunk-HH5LVGEE.js → chunk-VKRMXD62.js} +4 -4
- package/dist/{chunk-HWDBNDUX.js → chunk-XU3NADFE.js} +2 -2
- package/dist/chunk-YSTJEMQX.js +122 -0
- package/dist/chunk-YSTJEMQX.js.map +1 -0
- package/dist/cli-circuit-breaker-5FAODXVY.js +13 -0
- package/dist/cli.js +118 -67
- package/dist/cli.js.map +1 -1
- package/dist/codebase-search-CZUA37RU.js +9 -0
- package/dist/{composite-router-YPRWVTRB.js → composite-router-FNW7ZWL7.js} +2 -2
- package/dist/{consensus-vote-DBE6RNZG.js → consensus-vote-757YULIP.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-LMCEAFU4.js} +3 -3
- package/dist/expert-bridge-L2D4OXOR.js +10 -0
- package/dist/{expert-config-FHNBQRX2.js → expert-config-A5CHKUGI.js} +2 -2
- package/dist/{factory-PCHGQ3ZG.js → factory-ELEDP2WD.js} +4 -3
- package/dist/{factory-O5C7ZBZO.js → factory-IDTIBX6B.js} +5 -4
- package/dist/index.d.ts +507 -42
- package/dist/index.js +331 -78
- package/dist/index.js.map +1 -1
- package/dist/issue-triage-SJPKJLXH.js +15 -0
- package/dist/{mcp-config-AUZQPUBY.js → mcp-config-2OXIOMJ6.js} +3 -3
- package/dist/mobimem-5S3VLNSU.js +13 -0
- package/dist/mobimem-5S3VLNSU.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-MUFDGWSQ.js +17 -0
- package/dist/repo-security-plan-MUFDGWSQ.js.map +1 -0
- package/dist/research-helpers-synthesize-OBQJ5BGX.js +10 -0
- package/dist/research-helpers-synthesize-OBQJ5BGX.js.map +1 -0
- package/dist/{routing-memory-QY3XMU2R.js → routing-memory-3QBQTS4A.js} +2 -2
- package/dist/routing-memory-3QBQTS4A.js.map +1 -0
- package/dist/{session-memory-3MBCE5KS.js → session-memory-VXWLOFRC.js} +3 -3
- package/dist/session-memory-VXWLOFRC.js.map +1 -0
- package/dist/{setup-command-IQ4MD3FT.js → setup-command-E6MXO5RZ.js} +7 -6
- package/dist/setup-command-E6MXO5RZ.js.map +1 -0
- package/dist/{setup-config-5YUPLDXF.js → setup-config-O5F3AZBL.js} +3 -3
- package/dist/setup-config-O5F3AZBL.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-MUGSIOU5.js} +2 -2
- package/dist/weather-report-MUGSIOU5.js.map +1 -0
- package/package.json +14 -13
- 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-RST6DZYR.js.map} +0 -0
- /package/dist/{chunk-KGDG6PWZ.js.map → chunk-2UUUKVNR.js.map} +0 -0
- /package/dist/{chunk-5VZLXMO7.js.map → chunk-3EVVQ32X.js.map} +0 -0
- /package/dist/{chunk-WSK4VSXP.js.map → chunk-3GXDN4AX.js.map} +0 -0
- /package/dist/{chunk-I6YDS23R.js.map → chunk-SRECH7OQ.js.map} +0 -0
- /package/dist/{chunk-HH5LVGEE.js.map → chunk-VKRMXD62.js.map} +0 -0
- /package/dist/{chunk-HWDBNDUX.js.map → chunk-XU3NADFE.js.map} +0 -0
- /package/dist/{consensus-vote-DBE6RNZG.js.map → cli-circuit-breaker-5FAODXVY.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-FNW7ZWL7.js.map} +0 -0
- /package/dist/{factory-O5C7ZBZO.js.map → consensus-vote-757YULIP.js.map} +0 -0
- /package/dist/{factory-PCHGQ3ZG.js.map → doctor-deep-LMCEAFU4.js.map} +0 -0
- /package/dist/{mcp-config-AUZQPUBY.js.map → expert-bridge-L2D4OXOR.js.map} +0 -0
- /package/dist/{routing-memory-QY3XMU2R.js.map → expert-config-A5CHKUGI.js.map} +0 -0
- /package/dist/{session-memory-3MBCE5KS.js.map → factory-ELEDP2WD.js.map} +0 -0
- /package/dist/{setup-command-IQ4MD3FT.js.map → factory-IDTIBX6B.js.map} +0 -0
- /package/dist/{setup-config-5YUPLDXF.js.map → issue-triage-SJPKJLXH.js.map} +0 -0
- /package/dist/{weather-report-CC2C4KAX.js.map → mcp-config-2OXIOMJ6.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
|
createLogger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ELIFTCYM.js";
|
|
4
4
|
|
|
5
5
|
// src/swe-bench/mcp-config.ts
|
|
6
6
|
import { writeFile, mkdtemp, rm } from "fs/promises";
|
|
@@ -58,4 +58,4 @@ export {
|
|
|
58
58
|
generateMcpConfig,
|
|
59
59
|
getDefaultAllowedTools
|
|
60
60
|
};
|
|
61
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-2UUUKVNR.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-633WH2ML.js";
|
|
4
4
|
import {
|
|
5
5
|
createAllAdapters
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4AGPR6XZ.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-ELIFTCYM.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.1" : "dev";
|
|
28
28
|
|
|
29
29
|
// src/cli/setup-data-dir.ts
|
|
30
30
|
import { mkdirSync, existsSync as existsSync2 } from "fs";
|
|
@@ -757,7 +757,7 @@ async function runDoctorFix(result) {
|
|
|
757
757
|
writeLine2("\u2500".repeat(40));
|
|
758
758
|
let fixCount = 0;
|
|
759
759
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
760
|
-
const { runSetup } = await import("./setup-command-
|
|
760
|
+
const { runSetup } = await import("./setup-command-E6MXO5RZ.js");
|
|
761
761
|
const setupResult = runSetup({
|
|
762
762
|
skipMcp: true,
|
|
763
763
|
skipRules: true,
|
|
@@ -771,7 +771,7 @@ async function runDoctorFix(result) {
|
|
|
771
771
|
}
|
|
772
772
|
}
|
|
773
773
|
if (!result.configFile.found) {
|
|
774
|
-
const { runConfigInitSync } = await import("./setup-config-
|
|
774
|
+
const { runConfigInitSync } = await import("./setup-config-O5F3AZBL.js");
|
|
775
775
|
const configResult = runConfigInitSync(process.cwd(), false, false);
|
|
776
776
|
if (configResult.success && configResult.created) {
|
|
777
777
|
writeLine2(`\u2713 Generated config: ${configResult.path}`);
|
|
@@ -835,4 +835,4 @@ export {
|
|
|
835
835
|
startStdioServer,
|
|
836
836
|
closeServer
|
|
837
837
|
};
|
|
838
|
-
//# sourceMappingURL=chunk-
|
|
838
|
+
//# sourceMappingURL=chunk-3EVVQ32X.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getErrorMessage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ELIFTCYM.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-3GXDN4AX.js.map
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CliCircuitBreaker,
|
|
3
|
+
DEFAULT_CIRCUIT_BREAKER_CONFIG
|
|
4
|
+
} from "./chunk-LLGUX44Z.js";
|
|
1
5
|
import {
|
|
2
6
|
CLI_SUBPROCESS_TIMEOUTS,
|
|
3
7
|
CLI_TIMEOUTS,
|
|
@@ -6,8 +10,6 @@ import {
|
|
|
6
10
|
DEFAULT_CAPABILITIES,
|
|
7
11
|
DEFAULT_MODEL_CAPABILITIES,
|
|
8
12
|
DEFAULT_MODEL_PER_CLI,
|
|
9
|
-
ErrorCode,
|
|
10
|
-
NexusError,
|
|
11
13
|
buildModelInfo,
|
|
12
14
|
clampPercent,
|
|
13
15
|
createLogger,
|
|
@@ -22,7 +24,7 @@ import {
|
|
|
22
24
|
getTimeProvider,
|
|
23
25
|
isRateLimitText,
|
|
24
26
|
ok
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-ELIFTCYM.js";
|
|
26
28
|
|
|
27
29
|
// src/cli-adapters/subprocess-adapter.ts
|
|
28
30
|
import { spawn } from "child_process";
|
|
@@ -51,7 +53,19 @@ function estimateTaskComplexity(taskDescription) {
|
|
|
51
53
|
if (complexIndicators.some((indicator) => lower.includes(indicator))) {
|
|
52
54
|
return "complex";
|
|
53
55
|
}
|
|
54
|
-
const simpleIndicators = [
|
|
56
|
+
const simpleIndicators = [
|
|
57
|
+
"single",
|
|
58
|
+
"quick",
|
|
59
|
+
"one function",
|
|
60
|
+
"simple",
|
|
61
|
+
"small",
|
|
62
|
+
"brief",
|
|
63
|
+
"short",
|
|
64
|
+
"run tests",
|
|
65
|
+
"test suite",
|
|
66
|
+
"exploration",
|
|
67
|
+
"explore"
|
|
68
|
+
];
|
|
55
69
|
if (simpleIndicators.some((indicator) => lower.includes(indicator))) {
|
|
56
70
|
return "simple";
|
|
57
71
|
}
|
|
@@ -1375,345 +1389,6 @@ var ResilientGeminiParser = class {
|
|
|
1375
1389
|
}
|
|
1376
1390
|
};
|
|
1377
1391
|
|
|
1378
|
-
// src/cli-adapters/circuit-breaker-types.ts
|
|
1379
|
-
var CircuitErrorCode = {
|
|
1380
|
-
CIRCUIT_OPEN: "CIRCUIT_OPEN",
|
|
1381
|
-
CIRCUIT_HALF_OPEN_REJECTED: "CIRCUIT_HALF_OPEN_REJECTED",
|
|
1382
|
-
EXECUTION_FAILED: "EXECUTION_FAILED"
|
|
1383
|
-
};
|
|
1384
|
-
var CircuitError = class extends NexusError {
|
|
1385
|
-
circuitErrorCode;
|
|
1386
|
-
cliName;
|
|
1387
|
-
circuitState;
|
|
1388
|
-
failureCategory;
|
|
1389
|
-
constructor(message, options) {
|
|
1390
|
-
const baseOptions = {
|
|
1391
|
-
code: ErrorCode.INTERNAL_ERROR,
|
|
1392
|
-
context: {
|
|
1393
|
-
circuitErrorCode: options.circuitErrorCode,
|
|
1394
|
-
cliName: options.cliName,
|
|
1395
|
-
circuitState: options.circuitState
|
|
1396
|
-
}
|
|
1397
|
-
};
|
|
1398
|
-
if (options.cause !== void 0) {
|
|
1399
|
-
baseOptions.cause = options.cause;
|
|
1400
|
-
}
|
|
1401
|
-
if (options.failureCategory !== void 0) {
|
|
1402
|
-
baseOptions.context["failureCategory"] = options.failureCategory;
|
|
1403
|
-
}
|
|
1404
|
-
super(message, baseOptions);
|
|
1405
|
-
this.name = "CircuitError";
|
|
1406
|
-
this.circuitErrorCode = options.circuitErrorCode;
|
|
1407
|
-
this.cliName = options.cliName;
|
|
1408
|
-
this.circuitState = options.circuitState;
|
|
1409
|
-
if (options.failureCategory !== void 0) {
|
|
1410
|
-
this.failureCategory = options.failureCategory;
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
};
|
|
1414
|
-
var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
|
|
1415
|
-
failureThreshold: 5,
|
|
1416
|
-
resetTimeoutMs: 3e4,
|
|
1417
|
-
halfOpenSuccessThreshold: 2,
|
|
1418
|
-
countTimeoutsAsFailures: true,
|
|
1419
|
-
countAuthFailuresAsFailures: false,
|
|
1420
|
-
countRateLimitsAsFailures: true,
|
|
1421
|
-
halfOpenMaxRequests: 3
|
|
1422
|
-
};
|
|
1423
|
-
var TIMEOUT_PATTERNS = ["timeout", "timed out"];
|
|
1424
|
-
var AUTH_PATTERNS = ["auth", "unauthorized", "forbidden", "oauth"];
|
|
1425
|
-
var RATE_LIMIT_PATTERNS = ["rate limit", "too many requests", "429"];
|
|
1426
|
-
var CONNECTION_PATTERNS = [
|
|
1427
|
-
"connection",
|
|
1428
|
-
"econnrefused",
|
|
1429
|
-
"enotfound",
|
|
1430
|
-
"mcp",
|
|
1431
|
-
"eaddrinuse",
|
|
1432
|
-
"address already in use"
|
|
1433
|
-
];
|
|
1434
|
-
var CRASH_PATTERNS = ["crash", "exited", "killed", "sigterm", "sigkill"];
|
|
1435
|
-
function matchesPatterns(text, patterns) {
|
|
1436
|
-
return patterns.some((pattern) => text.includes(pattern));
|
|
1437
|
-
}
|
|
1438
|
-
function categorizeError2(error) {
|
|
1439
|
-
if (!(error instanceof Error)) {
|
|
1440
|
-
return "unknown";
|
|
1441
|
-
}
|
|
1442
|
-
const message = error.message.toLowerCase();
|
|
1443
|
-
const name = error.name.toLowerCase();
|
|
1444
|
-
const combined = `${message} ${name}`;
|
|
1445
|
-
if (matchesPatterns(combined, TIMEOUT_PATTERNS)) return "timeout";
|
|
1446
|
-
if (matchesPatterns(combined, AUTH_PATTERNS)) return "authentication";
|
|
1447
|
-
if (matchesPatterns(combined, RATE_LIMIT_PATTERNS)) return "rate_limit";
|
|
1448
|
-
if (matchesPatterns(combined, CONNECTION_PATTERNS)) return "connection";
|
|
1449
|
-
if (matchesPatterns(combined, CRASH_PATTERNS)) return "crash";
|
|
1450
|
-
return "unknown";
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
// src/cli-adapters/circuit-breaker.ts
|
|
1454
|
-
var CliCircuitBreaker = class {
|
|
1455
|
-
constructor(cliName, config = DEFAULT_CIRCUIT_BREAKER_CONFIG) {
|
|
1456
|
-
this.cliName = cliName;
|
|
1457
|
-
this.config = config;
|
|
1458
|
-
this.lastStateChange = getTimeProvider().now();
|
|
1459
|
-
}
|
|
1460
|
-
state = "closed";
|
|
1461
|
-
failureCount = 0;
|
|
1462
|
-
successCount = 0;
|
|
1463
|
-
lastFailureTime = null;
|
|
1464
|
-
lastStateChange;
|
|
1465
|
-
halfOpenRequests = 0;
|
|
1466
|
-
listeners = /* @__PURE__ */ new Set();
|
|
1467
|
-
/**
|
|
1468
|
-
* Executes a function with circuit breaker protection.
|
|
1469
|
-
*/
|
|
1470
|
-
async execute(fn) {
|
|
1471
|
-
const canExecute = this.canExecute();
|
|
1472
|
-
if (!canExecute.ok) {
|
|
1473
|
-
return canExecute;
|
|
1474
|
-
}
|
|
1475
|
-
try {
|
|
1476
|
-
const result = await fn();
|
|
1477
|
-
this.onSuccess();
|
|
1478
|
-
return ok(result);
|
|
1479
|
-
} catch (error) {
|
|
1480
|
-
const category = categorizeError2(error);
|
|
1481
|
-
if (this.shouldCountFailure(category)) {
|
|
1482
|
-
this.onFailure(category);
|
|
1483
|
-
}
|
|
1484
|
-
return err(this.createExecutionError(error, category));
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
getState() {
|
|
1488
|
-
this.checkStateTransition();
|
|
1489
|
-
return this.state;
|
|
1490
|
-
}
|
|
1491
|
-
getSnapshot() {
|
|
1492
|
-
this.checkStateTransition();
|
|
1493
|
-
return {
|
|
1494
|
-
state: this.state,
|
|
1495
|
-
failureCount: this.failureCount,
|
|
1496
|
-
successCount: this.successCount,
|
|
1497
|
-
lastFailureTime: this.lastFailureTime,
|
|
1498
|
-
lastStateChange: this.lastStateChange,
|
|
1499
|
-
halfOpenRequests: this.halfOpenRequests,
|
|
1500
|
-
config: this.config
|
|
1501
|
-
};
|
|
1502
|
-
}
|
|
1503
|
-
reset() {
|
|
1504
|
-
const previousState = this.state;
|
|
1505
|
-
this.state = "closed";
|
|
1506
|
-
this.failureCount = 0;
|
|
1507
|
-
this.successCount = 0;
|
|
1508
|
-
this.lastFailureTime = null;
|
|
1509
|
-
this.halfOpenRequests = 0;
|
|
1510
|
-
this.lastStateChange = getTimeProvider().now();
|
|
1511
|
-
if (previousState !== "closed") {
|
|
1512
|
-
this.emitStateChange(previousState, "closed", "Manual reset");
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
recordFailure(category) {
|
|
1516
|
-
if (this.shouldCountFailure(category)) {
|
|
1517
|
-
this.onFailure(category);
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
recordSuccess() {
|
|
1521
|
-
this.onSuccess();
|
|
1522
|
-
}
|
|
1523
|
-
addStateChangeListener(listener) {
|
|
1524
|
-
this.listeners.add(listener);
|
|
1525
|
-
}
|
|
1526
|
-
removeStateChangeListener(listener) {
|
|
1527
|
-
this.listeners.delete(listener);
|
|
1528
|
-
}
|
|
1529
|
-
// -------------------------------------------------------------------------
|
|
1530
|
-
// Private Methods
|
|
1531
|
-
// -------------------------------------------------------------------------
|
|
1532
|
-
canExecute() {
|
|
1533
|
-
this.checkStateTransition();
|
|
1534
|
-
if (this.state === "closed") {
|
|
1535
|
-
return ok(true);
|
|
1536
|
-
}
|
|
1537
|
-
if (this.state === "open") {
|
|
1538
|
-
return err(
|
|
1539
|
-
new CircuitError(`Circuit is open for CLI: ${this.cliName}`, {
|
|
1540
|
-
circuitErrorCode: CircuitErrorCode.CIRCUIT_OPEN,
|
|
1541
|
-
cliName: this.cliName,
|
|
1542
|
-
circuitState: this.state
|
|
1543
|
-
})
|
|
1544
|
-
);
|
|
1545
|
-
}
|
|
1546
|
-
if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {
|
|
1547
|
-
return err(
|
|
1548
|
-
new CircuitError(`Circuit half-open request limit reached for CLI: ${this.cliName}`, {
|
|
1549
|
-
circuitErrorCode: CircuitErrorCode.CIRCUIT_HALF_OPEN_REJECTED,
|
|
1550
|
-
cliName: this.cliName,
|
|
1551
|
-
circuitState: this.state
|
|
1552
|
-
})
|
|
1553
|
-
);
|
|
1554
|
-
}
|
|
1555
|
-
this.halfOpenRequests++;
|
|
1556
|
-
return ok(true);
|
|
1557
|
-
}
|
|
1558
|
-
checkStateTransition() {
|
|
1559
|
-
if (this.state === "open" && this.lastFailureTime !== null) {
|
|
1560
|
-
const elapsed = getTimeProvider().now() - this.lastFailureTime;
|
|
1561
|
-
if (elapsed >= this.config.resetTimeoutMs) {
|
|
1562
|
-
this.transitionTo("half-open", "Reset timeout elapsed");
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
onSuccess() {
|
|
1567
|
-
if (this.state === "closed") {
|
|
1568
|
-
this.failureCount = 0;
|
|
1569
|
-
} else if (this.state === "half-open") {
|
|
1570
|
-
this.successCount++;
|
|
1571
|
-
if (this.successCount >= this.config.halfOpenSuccessThreshold) {
|
|
1572
|
-
const reason = `${String(this.successCount)} consecutive successes in half-open state`;
|
|
1573
|
-
this.transitionTo("closed", reason);
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
onFailure(category) {
|
|
1578
|
-
this.failureCount++;
|
|
1579
|
-
this.lastFailureTime = getTimeProvider().now();
|
|
1580
|
-
if (this.state === "closed" && this.failureCount >= this.config.failureThreshold) {
|
|
1581
|
-
const reason = `Failure threshold (${String(this.config.failureThreshold)}) exceeded`;
|
|
1582
|
-
this.transitionTo("open", reason);
|
|
1583
|
-
} else if (this.state === "half-open") {
|
|
1584
|
-
this.transitionTo("open", `Failure during half-open recovery (category: ${category})`);
|
|
1585
|
-
}
|
|
1586
|
-
}
|
|
1587
|
-
transitionTo(newState, reason) {
|
|
1588
|
-
const previousState = this.state;
|
|
1589
|
-
this.state = newState;
|
|
1590
|
-
this.lastStateChange = getTimeProvider().now();
|
|
1591
|
-
if (newState === "closed") {
|
|
1592
|
-
this.failureCount = 0;
|
|
1593
|
-
this.successCount = 0;
|
|
1594
|
-
this.halfOpenRequests = 0;
|
|
1595
|
-
} else if (newState === "half-open") {
|
|
1596
|
-
this.successCount = 0;
|
|
1597
|
-
this.halfOpenRequests = 0;
|
|
1598
|
-
}
|
|
1599
|
-
this.emitStateChange(previousState, newState, reason);
|
|
1600
|
-
}
|
|
1601
|
-
emitStateChange(previousState, newState, reason) {
|
|
1602
|
-
const event = {
|
|
1603
|
-
cliName: this.cliName,
|
|
1604
|
-
previousState,
|
|
1605
|
-
newState,
|
|
1606
|
-
timestamp: this.lastStateChange,
|
|
1607
|
-
failureCount: this.failureCount,
|
|
1608
|
-
reason
|
|
1609
|
-
};
|
|
1610
|
-
for (const listener of this.listeners) {
|
|
1611
|
-
try {
|
|
1612
|
-
listener(event);
|
|
1613
|
-
} catch {
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
shouldCountFailure(category) {
|
|
1618
|
-
if (category === "timeout") return this.config.countTimeoutsAsFailures;
|
|
1619
|
-
if (category === "authentication") return this.config.countAuthFailuresAsFailures;
|
|
1620
|
-
if (category === "rate_limit") return this.config.countRateLimitsAsFailures;
|
|
1621
|
-
return true;
|
|
1622
|
-
}
|
|
1623
|
-
createExecutionError(error, category) {
|
|
1624
|
-
const message = getErrorMessage(error);
|
|
1625
|
-
const cause = error instanceof Error ? error : new Error(String(error));
|
|
1626
|
-
return new CircuitError(`CLI execution failed: ${message}`, {
|
|
1627
|
-
circuitErrorCode: CircuitErrorCode.EXECUTION_FAILED,
|
|
1628
|
-
cliName: this.cliName,
|
|
1629
|
-
circuitState: this.state,
|
|
1630
|
-
failureCategory: category,
|
|
1631
|
-
cause
|
|
1632
|
-
});
|
|
1633
|
-
}
|
|
1634
|
-
};
|
|
1635
|
-
var CircuitBreakerRegistry = class {
|
|
1636
|
-
constructor(defaultConfig = {}) {
|
|
1637
|
-
this.defaultConfig = defaultConfig;
|
|
1638
|
-
}
|
|
1639
|
-
breakers = /* @__PURE__ */ new Map();
|
|
1640
|
-
globalListeners = /* @__PURE__ */ new Set();
|
|
1641
|
-
getBreaker(cliName, config) {
|
|
1642
|
-
let breaker = this.breakers.get(cliName);
|
|
1643
|
-
if (!breaker) {
|
|
1644
|
-
const mergedConfig = {
|
|
1645
|
-
...DEFAULT_CIRCUIT_BREAKER_CONFIG,
|
|
1646
|
-
...this.defaultConfig,
|
|
1647
|
-
...config
|
|
1648
|
-
};
|
|
1649
|
-
breaker = new CliCircuitBreaker(cliName, mergedConfig);
|
|
1650
|
-
for (const listener of this.globalListeners) {
|
|
1651
|
-
breaker.addStateChangeListener(listener);
|
|
1652
|
-
}
|
|
1653
|
-
this.breakers.set(cliName, breaker);
|
|
1654
|
-
}
|
|
1655
|
-
return breaker;
|
|
1656
|
-
}
|
|
1657
|
-
isOpen(cliName) {
|
|
1658
|
-
return this.breakers.get(cliName)?.getState() === "open";
|
|
1659
|
-
}
|
|
1660
|
-
getAllSnapshots() {
|
|
1661
|
-
const snapshots = /* @__PURE__ */ new Map();
|
|
1662
|
-
for (const [name, breaker] of this.breakers) {
|
|
1663
|
-
snapshots.set(name, breaker.getSnapshot());
|
|
1664
|
-
}
|
|
1665
|
-
return snapshots;
|
|
1666
|
-
}
|
|
1667
|
-
resetAll() {
|
|
1668
|
-
for (const breaker of this.breakers.values()) {
|
|
1669
|
-
breaker.reset();
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
reset(cliName) {
|
|
1673
|
-
this.breakers.get(cliName)?.reset();
|
|
1674
|
-
}
|
|
1675
|
-
addGlobalStateChangeListener(listener) {
|
|
1676
|
-
this.globalListeners.add(listener);
|
|
1677
|
-
for (const breaker of this.breakers.values()) {
|
|
1678
|
-
breaker.addStateChangeListener(listener);
|
|
1679
|
-
}
|
|
1680
|
-
}
|
|
1681
|
-
removeGlobalStateChangeListener(listener) {
|
|
1682
|
-
this.globalListeners.delete(listener);
|
|
1683
|
-
for (const breaker of this.breakers.values()) {
|
|
1684
|
-
breaker.removeStateChangeListener(listener);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
getHealthyClis() {
|
|
1688
|
-
const healthy = [];
|
|
1689
|
-
for (const [name, breaker] of this.breakers) {
|
|
1690
|
-
if (breaker.getState() === "closed") {
|
|
1691
|
-
healthy.push(name);
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
return healthy;
|
|
1695
|
-
}
|
|
1696
|
-
getUnhealthyClis() {
|
|
1697
|
-
const unhealthy = [];
|
|
1698
|
-
for (const [name, breaker] of this.breakers) {
|
|
1699
|
-
const state = breaker.getState();
|
|
1700
|
-
if (state === "open" || state === "half-open") {
|
|
1701
|
-
unhealthy.push(name);
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
return unhealthy;
|
|
1705
|
-
}
|
|
1706
|
-
};
|
|
1707
|
-
function mapCliErrorToCategory(errorCode) {
|
|
1708
|
-
const mapping = {
|
|
1709
|
-
TIMEOUT: "timeout",
|
|
1710
|
-
NOT_AUTHENTICATED: "authentication",
|
|
1711
|
-
RATE_LIMITED: "rate_limit",
|
|
1712
|
-
CONNECTION_ERROR: "connection"
|
|
1713
|
-
};
|
|
1714
|
-
return mapping[errorCode] ?? "unknown";
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
1392
|
// src/cli-adapters/adapters/gemini-adapter-helpers.ts
|
|
1718
1393
|
var GEMINI_LEGACY_DEFAULTS = {
|
|
1719
1394
|
displayNames: {},
|
|
@@ -2986,9 +2661,6 @@ export {
|
|
|
2986
2661
|
extractNumberField,
|
|
2987
2662
|
ClaudeResponseParser,
|
|
2988
2663
|
ClaudeCliAdapter,
|
|
2989
|
-
CircuitError,
|
|
2990
|
-
CircuitBreakerRegistry,
|
|
2991
|
-
mapCliErrorToCategory,
|
|
2992
2664
|
GeminiCliAdapter,
|
|
2993
2665
|
CodexResponseParser,
|
|
2994
2666
|
CodexCliAdapter,
|
|
@@ -3003,4 +2675,4 @@ export {
|
|
|
3003
2675
|
isCliAvailable,
|
|
3004
2676
|
getAvailableClis
|
|
3005
2677
|
};
|
|
3006
|
-
//# sourceMappingURL=chunk-
|
|
2678
|
+
//# sourceMappingURL=chunk-4AGPR6XZ.js.map
|