nexus-agents 2.71.0 → 2.72.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-MKSYEBST.js → adaptive-memory-UPE76IP6.js} +5 -5
- package/dist/{chunk-DWLATKBK.js → child-mcp-config-5HRJGLCR.js} +6 -4
- package/dist/child-mcp-config-5HRJGLCR.js.map +1 -0
- package/dist/{chunk-ZPPX2K57.js → chunk-2KB63QGE.js} +2 -2
- package/dist/{chunk-L2LQ3TSV.js → chunk-2MD5MWCK.js} +2 -2
- package/dist/{chunk-ANC3HU6F.js → chunk-345KMHWH.js} +6 -6
- package/dist/chunk-345KMHWH.js.map +1 -0
- package/dist/{chunk-NER7H3RJ.js → chunk-3FIDMWFC.js} +2 -2
- package/dist/{chunk-POQQ7A5E.js → chunk-53K3KEKT.js} +51 -707
- package/dist/chunk-53K3KEKT.js.map +1 -0
- package/dist/chunk-5MHIWRKB.js +691 -0
- package/dist/chunk-5MHIWRKB.js.map +1 -0
- package/dist/{chunk-VGZJIR22.js → chunk-5WQ3SRSE.js} +2 -2
- package/dist/{chunk-TOYPY5XA.js → chunk-A35XORXU.js} +73 -10
- package/dist/chunk-A35XORXU.js.map +1 -0
- package/dist/chunk-BVETPIOQ.js +556 -0
- package/dist/chunk-BVETPIOQ.js.map +1 -0
- package/dist/{chunk-7LHQBMBM.js → chunk-C3JGKBL2.js} +25 -12
- package/dist/{chunk-7LHQBMBM.js.map → chunk-C3JGKBL2.js.map} +1 -1
- package/dist/{chunk-OF7CYMMA.js → chunk-DA5UDQYW.js} +2 -2
- package/dist/{chunk-XATH462F.js → chunk-ES6GFP35.js} +186 -34
- package/dist/chunk-ES6GFP35.js.map +1 -0
- package/dist/chunk-GOT7OAL5.js +59 -0
- package/dist/chunk-GOT7OAL5.js.map +1 -0
- package/dist/{chunk-LJT65EA7.js → chunk-I7ORMAO7.js} +2 -2
- package/dist/{chunk-AGVLFRN7.js → chunk-J4VR2WNI.js} +2998 -7188
- package/dist/chunk-J4VR2WNI.js.map +1 -0
- package/dist/{chunk-LMRKHQG5.js → chunk-L6N2S3UB.js} +2 -2
- package/dist/{chunk-7OBFO4GF.js → chunk-O4KUCF5S.js} +125 -40
- package/dist/chunk-O4KUCF5S.js.map +1 -0
- package/dist/chunk-P5OFZWDW.js +303 -0
- package/dist/chunk-P5OFZWDW.js.map +1 -0
- package/dist/{chunk-MJHOSM5U.js → chunk-QECRZ3YA.js} +2 -2
- package/dist/{chunk-WYSHXPKK.js → chunk-QL4HCYRD.js} +4 -44
- package/dist/chunk-QL4HCYRD.js.map +1 -0
- package/dist/{chunk-E66KFRSJ.js → chunk-TF3GROMO.js} +2 -2
- package/dist/{chunk-U3HZQTUF.js → chunk-TQFRPFMG.js} +2 -2
- package/dist/{chunk-KJCSRP34.js → chunk-V7ATY4BG.js} +3 -3
- package/dist/{chunk-32RIOULO.js → chunk-VPC3YNFR.js} +2 -2
- package/dist/{chunk-3BKVYSY6.js → chunk-VTVKC4FS.js} +4 -4
- package/dist/{chunk-U6BK5DQU.js → chunk-YOREAPF6.js} +315 -31
- package/dist/chunk-YOREAPF6.js.map +1 -0
- package/dist/cli-circuit-breaker-GFF2RLBZ.js +14 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.js +1038 -1581
- package/dist/cli.js.map +1 -1
- package/dist/{composite-router-AYVJPIOS.js → composite-router-33F3F74I.js} +4 -4
- package/dist/{consensus-vote-EXWACBMR.js → consensus-vote-5V4KVHBE.js} +12 -11
- package/dist/doctor-deep-AHDTNURD.js +13 -0
- package/dist/expert-bridge-DMDHHDEU.js +11 -0
- package/dist/factory-FVD7PZ6S.js +15 -0
- package/dist/{factory-KMBWFIX2.js → factory-VQS3HJ7V.js} +6 -6
- package/dist/index.d.ts +997 -3517
- package/dist/index.js +74 -807
- package/dist/index.js.map +1 -1
- package/dist/init-opencode-EIOIPVWL.js +158 -0
- package/dist/init-opencode-EIOIPVWL.js.map +1 -0
- package/dist/issue-triage-HJUJWGAD.js +16 -0
- package/dist/{learning-persistence-FILWP3IR.js → learning-persistence-N6ILD2HX.js} +3 -3
- package/dist/{mobimem-77W5ED4Z.js → mobimem-BOJFXQ7B.js} +4 -4
- package/dist/{nexus-data-dir-M6DYKIHJ.js → nexus-data-dir-77UO7N6J.js} +2 -2
- package/dist/{registry-command-BBLIXULQ.js → registry-command-NCWUJKAF.js} +4 -4
- package/dist/{repo-security-plan-7SNM7JQN.js → repo-security-plan-3J45VAD6.js} +5 -5
- package/dist/research-helpers-synthesize-UGQHZZJN.js +12 -0
- package/dist/{routing-memory-DCIZEEVC.js → routing-memory-NO7QEH7T.js} +4 -4
- package/dist/{session-memory-5TSAASQW.js → session-memory-DOXLEWEU.js} +5 -5
- package/dist/{setup-command-5VGIQETA.js → setup-command-BWUFMZ7U.js} +10 -10
- package/dist/setup-config-E3JZYSLR.js +11 -0
- package/dist/{setup-custom-api-IQX3GD2D.js → setup-custom-api-DHJ5DRH2.js} +6 -6
- package/dist/{weather-report-NETGWTJX.js → weather-report-FNN4OX3N.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-7OBFO4GF.js.map +0 -1
- package/dist/chunk-AGVLFRN7.js.map +0 -1
- package/dist/chunk-ANC3HU6F.js.map +0 -1
- package/dist/chunk-DWLATKBK.js.map +0 -1
- package/dist/chunk-FDNWRZNJ.js +0 -22
- package/dist/chunk-FDNWRZNJ.js.map +0 -1
- package/dist/chunk-POQQ7A5E.js.map +0 -1
- package/dist/chunk-TOYPY5XA.js.map +0 -1
- package/dist/chunk-U6BK5DQU.js.map +0 -1
- package/dist/chunk-WYSHXPKK.js.map +0 -1
- package/dist/chunk-XATH462F.js.map +0 -1
- package/dist/cli-circuit-breaker-2CJ6NV52.js +0 -14
- package/dist/doctor-deep-BJFDBGPO.js +0 -13
- package/dist/expert-bridge-75WNNWI4.js +0 -11
- package/dist/factory-H5BYL4V5.js +0 -15
- package/dist/issue-triage-4SEP4WID.js +0 -16
- package/dist/mcp-config-OCWIXE2Y.js +0 -13
- package/dist/research-helpers-synthesize-7CI2FJE5.js +0 -12
- package/dist/setup-config-EA5RDIO2.js +0 -11
- package/dist/weather-report-NETGWTJX.js.map +0 -1
- /package/dist/{adaptive-memory-MKSYEBST.js.map → adaptive-memory-UPE76IP6.js.map} +0 -0
- /package/dist/{chunk-ZPPX2K57.js.map → chunk-2KB63QGE.js.map} +0 -0
- /package/dist/{chunk-L2LQ3TSV.js.map → chunk-2MD5MWCK.js.map} +0 -0
- /package/dist/{chunk-NER7H3RJ.js.map → chunk-3FIDMWFC.js.map} +0 -0
- /package/dist/{chunk-VGZJIR22.js.map → chunk-5WQ3SRSE.js.map} +0 -0
- /package/dist/{chunk-OF7CYMMA.js.map → chunk-DA5UDQYW.js.map} +0 -0
- /package/dist/{chunk-LJT65EA7.js.map → chunk-I7ORMAO7.js.map} +0 -0
- /package/dist/{chunk-LMRKHQG5.js.map → chunk-L6N2S3UB.js.map} +0 -0
- /package/dist/{chunk-MJHOSM5U.js.map → chunk-QECRZ3YA.js.map} +0 -0
- /package/dist/{chunk-E66KFRSJ.js.map → chunk-TF3GROMO.js.map} +0 -0
- /package/dist/{chunk-U3HZQTUF.js.map → chunk-TQFRPFMG.js.map} +0 -0
- /package/dist/{chunk-KJCSRP34.js.map → chunk-V7ATY4BG.js.map} +0 -0
- /package/dist/{chunk-32RIOULO.js.map → chunk-VPC3YNFR.js.map} +0 -0
- /package/dist/{chunk-3BKVYSY6.js.map → chunk-VTVKC4FS.js.map} +0 -0
- /package/dist/{cli-circuit-breaker-2CJ6NV52.js.map → cli-circuit-breaker-GFF2RLBZ.js.map} +0 -0
- /package/dist/{composite-router-AYVJPIOS.js.map → composite-router-33F3F74I.js.map} +0 -0
- /package/dist/{consensus-vote-EXWACBMR.js.map → consensus-vote-5V4KVHBE.js.map} +0 -0
- /package/dist/{doctor-deep-BJFDBGPO.js.map → doctor-deep-AHDTNURD.js.map} +0 -0
- /package/dist/{expert-bridge-75WNNWI4.js.map → expert-bridge-DMDHHDEU.js.map} +0 -0
- /package/dist/{factory-H5BYL4V5.js.map → factory-FVD7PZ6S.js.map} +0 -0
- /package/dist/{factory-KMBWFIX2.js.map → factory-VQS3HJ7V.js.map} +0 -0
- /package/dist/{issue-triage-4SEP4WID.js.map → issue-triage-HJUJWGAD.js.map} +0 -0
- /package/dist/{learning-persistence-FILWP3IR.js.map → learning-persistence-N6ILD2HX.js.map} +0 -0
- /package/dist/{mcp-config-OCWIXE2Y.js.map → mobimem-BOJFXQ7B.js.map} +0 -0
- /package/dist/{mobimem-77W5ED4Z.js.map → nexus-data-dir-77UO7N6J.js.map} +0 -0
- /package/dist/{registry-command-BBLIXULQ.js.map → registry-command-NCWUJKAF.js.map} +0 -0
- /package/dist/{nexus-data-dir-M6DYKIHJ.js.map → repo-security-plan-3J45VAD6.js.map} +0 -0
- /package/dist/{repo-security-plan-7SNM7JQN.js.map → research-helpers-synthesize-UGQHZZJN.js.map} +0 -0
- /package/dist/{research-helpers-synthesize-7CI2FJE5.js.map → routing-memory-NO7QEH7T.js.map} +0 -0
- /package/dist/{routing-memory-DCIZEEVC.js.map → session-memory-DOXLEWEU.js.map} +0 -0
- /package/dist/{session-memory-5TSAASQW.js.map → setup-command-BWUFMZ7U.js.map} +0 -0
- /package/dist/{setup-command-5VGIQETA.js.map → setup-config-E3JZYSLR.js.map} +0 -0
- /package/dist/{setup-custom-api-IQX3GD2D.js.map → setup-custom-api-DHJ5DRH2.js.map} +0 -0
- /package/dist/{setup-config-EA5RDIO2.js.map → weather-report-FNN4OX3N.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/base-adapter.ts","../src/adapters/streaming-types.ts","../src/adapters/stream-operators-helpers.ts","../src/adapters/stream-operators.ts","../src/adapters/streaming.ts"],"sourcesContent":["/**\n * nexus-agents/adapters - Base Adapter\n *\n * Abstract base class that all model adapters extend.\n * Provides common functionality for token counting, logging, error transformation,\n * and capability checking.\n */\n\nimport type {\n Result,\n IModelAdapter,\n CompletionRequest,\n CompletionResponse,\n StreamChunk,\n ILogger,\n ModelCapability,\n} from '../core/index.js';\nimport { getErrorMessage } from '../core/index.js';\nimport { isRateLimitLikeError } from './rate-limit-detector.js';\n\nimport {\n ok,\n err,\n ConfigError,\n ModelError,\n ErrorCode,\n createLogger,\n getTokenEstimator,\n type NexusErrorOptions,\n} from '../core/index.js';\n\n/**\n * Configuration options for BaseAdapter.\n */\nexport interface BaseAdapterConfig {\n /** Provider identifier (e.g., 'anthropic', 'openai') */\n providerId: string;\n /** Model identifier (e.g., 'claude-sonnet-4', 'gpt-4o') */\n modelId: string;\n /** Capabilities this model supports */\n capabilities: readonly ModelCapability[];\n /** Optional custom logger */\n logger?: ILogger;\n /** API key for authentication (optional, may come from environment) */\n apiKey?: string;\n /** Base URL for the API (optional, uses provider default) */\n baseUrl?: string;\n /** Request timeout in milliseconds */\n timeout?: number;\n /** Maximum number of retries for failed requests */\n maxRetries?: number;\n}\n\n/**\n * Extended ModelError that supports specific error codes.\n *\n * While ModelError from core uses MODEL_ERROR by default, this subclass\n * allows adapters to specify more granular error codes like\n * MODEL_RATE_LIMITED, MODEL_TIMEOUT, etc.\n *\n * Extends ModelError so `instanceof ModelError` checks pass naturally\n * without requiring `as unknown as ModelError` casts.\n */\nexport class AdapterModelError extends ModelError {\n constructor(message: string, options: NexusErrorOptions) {\n super(message, options);\n this.name = 'ModelError';\n }\n}\n\n// ============================================================================\n// API Key Validation Helpers (#1446 — DRY extraction)\n// ============================================================================\n\n/**\n * Returns true if the given API key is missing or blank.\n */\nexport function isApiKeyMissing(apiKey: string | undefined): boolean {\n return apiKey === undefined || apiKey === '' || apiKey.trim() === '';\n}\n\n/**\n * Validates API key presence in constructor — throws ConfigError if missing.\n * Use in adapter constructors where throwing is appropriate.\n */\nexport function requireApiKey(\n apiKey: string | undefined,\n providerName: string,\n modelId: string\n): void {\n if (isApiKeyMissing(apiKey)) {\n throw new ConfigError(`${providerName} API key is required`, {\n context: { providerId: providerName.toLowerCase(), modelId },\n });\n }\n}\n\n/**\n * Validates API key presence — returns Result for validate-style methods.\n * Use in adapter validateConfig() methods that return Result.\n */\nexport function validateApiKeyPresence(\n apiKey: string | undefined,\n providerId: string,\n modelId: string\n): Result<void, ConfigError> {\n if (isApiKeyMissing(apiKey)) {\n return err(\n new ConfigError(`${providerId} API key is required`, {\n context: { providerId, modelId },\n })\n );\n }\n return ok(undefined);\n}\n\n/**\n * Abstract base class for model adapters.\n *\n * Provides default implementations for common adapter functionality while\n * leaving the core API interaction methods abstract for provider-specific\n * implementations.\n *\n * @example\n * ```typescript\n * class ClaudeAdapter extends BaseAdapter {\n * constructor(config: ClaudeAdapterConfig) {\n * super({\n * providerId: 'anthropic',\n * modelId: config.modelId,\n * capabilities: [ModelCapability.COMPLETION, ModelCapability.STREAMING],\n * apiKey: config.apiKey,\n * });\n * }\n *\n * async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n * this.logRequest(request);\n * // Provider-specific implementation...\n * }\n *\n * async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n * this.logRequest(request);\n * // Provider-specific streaming implementation...\n * }\n * }\n * ```\n */\nexport abstract class BaseAdapter implements IModelAdapter {\n readonly providerId: string;\n readonly modelId: string;\n readonly capabilities: readonly ModelCapability[];\n\n /** Logger for request/response logging */\n protected readonly logger: ILogger;\n\n /** Configuration for the adapter */\n protected readonly config: BaseAdapterConfig;\n\n /**\n * Creates a new BaseAdapter instance.\n *\n * @param config - Adapter configuration\n */\n constructor(config: BaseAdapterConfig) {\n this.providerId = config.providerId;\n this.modelId = config.modelId;\n this.capabilities = config.capabilities;\n this.config = config;\n this.logger =\n config.logger ??\n createLogger({\n adapter: config.providerId,\n model: config.modelId,\n });\n }\n\n /**\n * Send a completion request to the model.\n * Must be implemented by concrete adapter classes.\n *\n * @param request - The completion request\n * @returns Result with response or ModelError\n */\n abstract complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>>;\n\n /**\n * Stream a completion request from the model.\n * Must be implemented by concrete adapter classes.\n *\n * @param request - The completion request\n * @yields StreamChunk objects as they arrive\n */\n abstract stream(request: CompletionRequest): AsyncIterable<StreamChunk>;\n\n /**\n * Count tokens in text using the unified TokenEstimator.\n *\n * This provides a reasonable estimate for most use cases.\n * Concrete adapters may override this with provider-specific tokenizers.\n *\n * @param text - Text to count tokens for\n * @returns Approximate token count\n */\n countTokens(text: string): Promise<number> {\n return Promise.resolve(getTokenEstimator().estimateText(text));\n }\n\n /**\n * Validate adapter configuration.\n *\n * Checks that required configuration fields are present and valid.\n * Concrete adapters may override to add provider-specific validation.\n *\n * @returns Ok if valid, ConfigError if invalid\n */\n validateConfig(): Result<void, ConfigError> {\n const errors: string[] = [];\n\n if (!this.providerId || this.providerId.trim() === '') {\n errors.push('Provider ID is required');\n }\n\n if (!this.modelId || this.modelId.trim() === '') {\n errors.push('Model ID is required');\n }\n\n if (this.config.timeout !== undefined && this.config.timeout <= 0) {\n errors.push('Timeout must be positive');\n }\n\n if (this.config.maxRetries !== undefined && this.config.maxRetries < 0) {\n errors.push('Max retries cannot be negative');\n }\n\n if (errors.length > 0) {\n return err(\n new ConfigError(`Invalid adapter configuration: ${errors.join('; ')}`, {\n context: {\n providerId: this.providerId,\n modelId: this.modelId,\n errors,\n },\n })\n );\n }\n\n return ok(undefined);\n }\n\n /**\n * Check if this adapter supports a specific capability.\n *\n * @param capability - The capability to check for\n * @returns True if the capability is supported\n */\n hasCapability(capability: ModelCapability): boolean {\n return this.capabilities.includes(capability);\n }\n\n /**\n * Log details about an outgoing request.\n * Sanitizes sensitive information before logging.\n *\n * @param request - The completion request to log\n */\n protected logRequest(request: CompletionRequest): void {\n const messageCount = request.messages.length;\n const hasTools = request.tools !== undefined && request.tools.length > 0;\n const toolCount = request.tools?.length ?? 0;\n\n this.logger.debug('Sending completion request', {\n messageCount,\n hasSystemPrompt: request.systemPrompt !== undefined,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n hasTools,\n toolCount,\n responseFormat: request.responseFormat?.type,\n stopSequences: request.stop?.length ?? 0,\n });\n }\n\n /**\n * Log details about a received response.\n *\n * @param response - The completion response to log\n */\n protected logResponse(response: CompletionResponse): void {\n this.logger.debug('Received completion response', {\n contentBlocks: response.content.length,\n stopReason: response.stopReason,\n inputTokens: response.usage.inputTokens,\n outputTokens: response.usage.outputTokens,\n totalTokens: response.usage.totalTokens,\n model: response.model,\n });\n }\n\n /**\n * Transform a provider-specific error into a standardized ModelError.\n *\n * Maps common error patterns to appropriate error codes:\n * - Rate limiting (429, quota exceeded)\n * - Timeouts (ETIMEDOUT, ESOCKETTIMEDOUT)\n * - Authentication (401, 403)\n * - Model unavailable (503, 502)\n *\n * @param error - The original error from the provider\n * @returns A standardized ModelError\n */\n protected transformError(error: unknown): ModelError {\n if (error instanceof ModelError) {\n return error;\n }\n\n const errorMessage = getErrorMessage(error);\n const errorCode = this.determineErrorCode(error);\n\n const modelError = this.createModelError(errorMessage, errorCode, error);\n\n this.logger.error('Model adapter error', modelError, {\n errorCode,\n providerId: this.providerId,\n modelId: this.modelId,\n });\n\n return modelError;\n }\n\n /**\n * Create a ModelError with appropriate error code.\n */\n private createModelError(\n message: string,\n errorCode: (typeof ErrorCode)[keyof typeof ErrorCode],\n originalError: unknown\n ): ModelError {\n const fullMessage = `${this.providerId}/${this.modelId}: ${message}`;\n\n // Build options object conditionally to satisfy exactOptionalPropertyTypes\n const options: NexusErrorOptions = {\n code: errorCode,\n context: {\n providerId: this.providerId,\n modelId: this.modelId,\n },\n };\n\n // Only set cause if originalError is an Error\n if (originalError instanceof Error) {\n options.cause = originalError;\n }\n\n // AdapterModelError extends ModelError — no cast needed\n return new AdapterModelError(fullMessage, options);\n }\n\n /**\n * Determine the appropriate error code based on error characteristics.\n */\n private determineErrorCode(error: unknown): (typeof ErrorCode)[keyof typeof ErrorCode] {\n if (!(error instanceof Error)) {\n return ErrorCode.MODEL_ERROR;\n }\n\n const message = error.message.toLowerCase();\n const errorObj = error as { status?: number; code?: string };\n\n // Check for rate limiting (canonical detection from rate-limit-detector)\n if (isRateLimitLikeError(error)) {\n return ErrorCode.MODEL_RATE_LIMITED;\n }\n\n // Check for timeout\n if (this.isTimeoutError(message, errorObj)) {\n return ErrorCode.MODEL_TIMEOUT;\n }\n\n // Check for model unavailable\n if (this.isUnavailableError(message, errorObj)) {\n return ErrorCode.MODEL_UNAVAILABLE;\n }\n\n return ErrorCode.MODEL_ERROR;\n }\n\n /**\n * Check if error indicates a timeout.\n */\n private isTimeoutError(message: string, errorObj: { status?: number; code?: string }): boolean {\n const timeoutPatterns = ['timeout', 'etimedout', 'esockettimedout'];\n return (\n errorObj.code === 'ETIMEDOUT' ||\n errorObj.code === 'ESOCKETTIMEDOUT' ||\n timeoutPatterns.some((pattern) => message.includes(pattern))\n );\n }\n\n /**\n * Check if error indicates model unavailability.\n */\n private isUnavailableError(\n message: string,\n errorObj: { status?: number; code?: string }\n ): boolean {\n const unavailablePatterns = ['unavailable', 'service unavailable', 'overloaded'];\n return (\n errorObj.status === 502 ||\n errorObj.status === 503 ||\n unavailablePatterns.some((pattern) => message.includes(pattern))\n );\n }\n}\n","/**\n * nexus-agents/adapters - Streaming Types and Core Utilities\n *\n * Shared types, errors, and core streaming primitives used by both\n * streaming.ts and stream-operators.ts to avoid circular dependencies.\n */\n\nimport { type Result, ok, err } from '../core/index.js';\nimport { NexusError, ErrorCode } from '../core/index.js';\n\n/**\n * Error thrown when a stream operation fails.\n */\nexport class StreamError extends NexusError {\n constructor(message: string, options?: { cause?: Error; context?: Record<string, unknown> }) {\n super(message, { code: ErrorCode.INTERNAL_ERROR, ...options });\n this.name = 'StreamError';\n }\n}\n\n/**\n * Error thrown when a stream is cancelled.\n */\nexport class StreamCancelledError extends NexusError {\n constructor(reason?: string) {\n super(reason ?? 'Stream was cancelled', { code: ErrorCode.INTERNAL_ERROR });\n this.name = 'StreamCancelledError';\n }\n}\n\n/**\n * State of a stream controller.\n */\nexport type StreamState = 'idle' | 'streaming' | 'paused' | 'cancelled' | 'completed' | 'error';\n\n/**\n * Options for creating a stream.\n */\nexport interface CreateStreamOptions {\n /** AbortSignal for cancellation support */\n signal?: AbortSignal;\n /** Maximum buffer size for backpressure (default: 100) */\n maxBufferSize?: number;\n}\n\n/**\n * Controller for managing stream lifecycle.\n * Provides push/complete/error methods and cancellation support.\n */\nexport class StreamController<T> {\n private readonly chunks: T[] = [];\n private readonly waiters: Array<{\n resolve: (result: IteratorResult<T, void>) => void;\n reject: (error: Error) => void;\n }> = [];\n\n private _state: StreamState = 'idle';\n private _error: Error | undefined;\n private readonly maxBufferSize: number;\n private readonly abortHandler: (() => void) | undefined;\n private readonly abortSignal: AbortSignal | undefined;\n\n /**\n * Creates a new StreamController.\n * @param options - Stream creation options\n */\n constructor(options: CreateStreamOptions = {}) {\n this.maxBufferSize = options.maxBufferSize ?? 100;\n\n if (options.signal) {\n this.abortSignal = options.signal;\n this.abortHandler = (): void => {\n this.cancel('AbortSignal triggered');\n };\n options.signal.addEventListener('abort', this.abortHandler);\n }\n }\n\n /**\n * Current state of the stream.\n */\n get state(): StreamState {\n return this._state;\n }\n\n /**\n * Whether the stream is still active (can receive chunks).\n */\n get isActive(): boolean {\n return this._state === 'idle' || this._state === 'streaming' || this._state === 'paused';\n }\n\n /**\n * Current buffer size.\n */\n get bufferSize(): number {\n return this.chunks.length;\n }\n\n /**\n * Push a chunk to the stream.\n * @param chunk - The chunk to push\n * @returns Result indicating success or backpressure\n */\n push(chunk: T): Result<void, StreamError> {\n if (!this.isActive) {\n return err(new StreamError(`Cannot push to stream in state: ${this._state}`));\n }\n\n if (this._state === 'idle') {\n this._state = 'streaming';\n }\n\n // If there's a waiting consumer, deliver directly\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter.resolve({ done: false, value: chunk });\n return ok(undefined);\n }\n\n // Check backpressure\n if (this.chunks.length >= this.maxBufferSize) {\n this._state = 'paused';\n return err(\n new StreamError('Buffer full - backpressure applied', {\n context: { bufferSize: this.chunks.length, maxBufferSize: this.maxBufferSize },\n })\n );\n }\n\n this.chunks.push(chunk);\n return ok(undefined);\n }\n\n /**\n * Complete the stream successfully.\n */\n complete(): void {\n if (!this.isActive) {\n return;\n }\n\n this._state = 'completed';\n this.removeAbortListener();\n this.resolveAllWaiters();\n }\n\n /**\n * Complete the stream with an error.\n * @param error - The error that occurred\n */\n error(error: Error): void {\n if (!this.isActive) {\n return;\n }\n\n this._state = 'error';\n this._error = error;\n this.removeAbortListener();\n this.rejectAllWaiters(error);\n }\n\n /**\n * Cancel the stream.\n * @param reason - Optional reason for cancellation\n */\n cancel(reason?: string): void {\n if (!this.isActive) {\n return;\n }\n\n this._state = 'cancelled';\n this._error = new StreamCancelledError(reason);\n this.removeAbortListener();\n this.rejectAllWaiters(this._error);\n }\n\n /**\n * Get the AsyncIterable for consuming the stream.\n */\n getIterable(): AsyncIterable<T> {\n // Store reference to controller methods for closure\n const nextChunk = (): Promise<IteratorResult<T, void>> => this.nextChunk();\n const cancel = (reason: string): void => {\n this.cancel(reason);\n };\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return {\n async next(): Promise<IteratorResult<T, void>> {\n return nextChunk();\n },\n return(): Promise<IteratorResult<T, void>> {\n cancel('Iterator returned');\n return Promise.resolve({ done: true, value: undefined });\n },\n };\n },\n };\n }\n\n private async nextChunk(): Promise<IteratorResult<T, void>> {\n // If we have buffered chunks, return one\n const chunk = this.chunks.shift();\n if (chunk !== undefined) {\n // Resume if we were paused and buffer is now below threshold\n if (this._state === 'paused' && this.chunks.length < this.maxBufferSize / 2) {\n this._state = 'streaming';\n }\n return { done: false, value: chunk };\n }\n\n // Check terminal states\n if (this._state === 'completed') {\n return { done: true, value: undefined };\n }\n\n if (this._state === 'cancelled' || this._state === 'error') {\n throw this._error ?? new StreamCancelledError();\n }\n\n // Wait for next chunk\n return new Promise((resolve, reject) => {\n this.waiters.push({ resolve, reject });\n });\n }\n\n private removeAbortListener(): void {\n if (this.abortSignal && this.abortHandler) {\n this.abortSignal.removeEventListener('abort', this.abortHandler);\n }\n }\n\n private resolveAllWaiters(): void {\n for (const waiter of this.waiters) {\n waiter.resolve({ done: true, value: undefined });\n }\n this.waiters.length = 0;\n }\n\n private rejectAllWaiters(error: Error): void {\n for (const waiter of this.waiters) {\n waiter.reject(error);\n }\n this.waiters.length = 0;\n }\n}\n\n/**\n * Creates a controllable stream.\n * @param options - Stream creation options\n * @returns Tuple of [controller, iterable]\n */\nexport function createStream<T>(\n options: CreateStreamOptions = {}\n): [StreamController<T>, AsyncIterable<T>] {\n const controller = new StreamController<T>(options);\n return [controller, controller.getIterable()];\n}\n","/**\n * nexus-agents/adapters - Stream Operators Helpers\n *\n * Helper functions for stream operations extracted for maintainability.\n */\n\nimport { type Result, ok, err } from '../core/index.js';\nimport { StreamError, StreamCancelledError } from './streaming-types.js';\n\n/**\n * Takes the first N chunks from a stream.\n * @param stream - The source stream\n * @param count - Number of chunks to take\n * @param options - Options including optional AbortSignal\n * @returns Stream of first N chunks\n */\nexport async function* take<T>(\n stream: AsyncIterable<T>,\n count: number,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n if (count <= 0) {\n return;\n }\n\n let taken = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('take aborted');\n }\n\n yield chunk;\n taken++;\n\n if (taken >= count) {\n return;\n }\n }\n}\n\n/**\n * Skips the first N chunks from a stream.\n * @param stream - The source stream\n * @param count - Number of chunks to skip\n * @param options - Options including optional AbortSignal\n * @returns Stream with first N chunks skipped\n */\nexport async function* skip<T>(\n stream: AsyncIterable<T>,\n count: number,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n let skipped = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('skip aborted');\n }\n\n if (skipped < count) {\n skipped++;\n continue;\n }\n\n yield chunk;\n }\n}\n\n/**\n * Concatenates multiple streams sequentially.\n * @param streams - The streams to concatenate\n * @param options - Options including optional AbortSignal\n * @returns Concatenated stream\n */\nexport async function* concatStreams<T>(\n streams: AsyncIterable<T>[],\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n for (const stream of streams) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('concat aborted');\n }\n\n yield* stream;\n }\n}\n\n/**\n * Creates a stream from an array of values.\n * @param values - The values to stream\n * @param options - Options including optional delay between chunks\n * @returns Stream of values\n */\nexport async function* fromArray<T>(\n values: T[],\n options: { delayMs?: number; signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n for (const value of values) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('fromArray aborted');\n }\n\n if (options.delayMs !== undefined && options.delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, options.delayMs));\n }\n\n yield value;\n }\n}\n\n/**\n * Taps into a stream without modifying it (for side effects like logging).\n * @param stream - The source stream\n * @param fn - Side effect function called for each chunk\n * @param options - Options including optional AbortSignal\n * @returns Original stream unchanged\n */\nexport async function* tapStream<T>(\n stream: AsyncIterable<T>,\n fn: (chunk: T, index: number) => void | Promise<void>,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n let index = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('tap aborted');\n }\n\n await fn(chunk, index);\n yield chunk;\n index++;\n }\n}\n\n/**\n * Reduces a stream to a single value.\n * @param stream - The source stream\n * @param reducer - Reducer function\n * @param initialValue - Initial accumulator value\n * @param options - Options including optional AbortSignal\n * @returns Result containing the final value or error\n */\nexport async function reduceStream<T, U>(\n stream: AsyncIterable<T>,\n reducer: (accumulator: U, chunk: T, index: number) => U | Promise<U>,\n initialValue: U,\n options: { signal?: AbortSignal } = {}\n): Promise<Result<U, StreamError>> {\n let accumulator = initialValue;\n let index = 0;\n\n try {\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n return err(new StreamError('Reduce aborted'));\n }\n\n accumulator = await reducer(accumulator, chunk, index);\n index++;\n }\n\n return ok(accumulator);\n } catch (error) {\n return err(\n new StreamError('Failed to reduce stream', {\n cause: error instanceof Error ? error : new Error(String(error)),\n })\n );\n }\n}\n","/**\n * nexus-agents/adapters - Stream Operators\n *\n * Stream transformation operators for AsyncIterables.\n * Provides filter, map, merge, concat, buffer, and other stream operations.\n */\n\nimport { TimeoutError } from '../core/index.js';\nimport {\n StreamError,\n StreamCancelledError,\n createStream,\n type CreateStreamOptions,\n} from './streaming-types.js';\n\n// Re-export helper functions for backward compatibility\nexport {\n take,\n skip,\n concatStreams,\n fromArray,\n tapStream,\n reduceStream,\n} from './stream-operators-helpers.js';\n\n/**\n * Transforms stream chunks using a mapping function.\n * @param stream - The source stream\n * @param fn - Transformation function\n * @param options - Options including optional AbortSignal\n * @returns Transformed stream\n */\nexport async function* transformStream<T, U>(\n stream: AsyncIterable<T>,\n fn: (chunk: T, index: number) => U | Promise<U>,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<U> {\n let index = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('Transform aborted');\n }\n\n yield await fn(chunk, index);\n index++;\n }\n}\n\n/**\n * Merges multiple streams into a single stream.\n * Chunks are yielded as they arrive from any source.\n * @param streams - The streams to merge\n * @param options - Options including optional AbortSignal\n * @returns Merged stream\n */\nexport async function* mergeStreams<T>(\n streams: AsyncIterable<T>[],\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n if (streams.length === 0) {\n return;\n }\n\n const streamOptions: CreateStreamOptions = {};\n if (options.signal) {\n streamOptions.signal = options.signal;\n }\n const [controller, merged] = createStream<T>(streamOptions);\n let activeCount = streams.length;\n\n // Start consuming all streams in parallel\n const consumers = streams.map(async (stream, streamIndex) => {\n try {\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n break;\n }\n controller.push(chunk);\n }\n } catch (error) {\n if (error instanceof StreamCancelledError) {\n // Propagate cancellation\n controller.cancel(`Stream ${String(streamIndex)} was cancelled`);\n return;\n }\n controller.error(error instanceof Error ? error : new Error(String(error)));\n return;\n } finally {\n activeCount--;\n if (activeCount === 0) {\n controller.complete();\n }\n }\n });\n\n // Start all consumers without blocking (Issue #541)\n // Each consumer has try-catch that forwards errors to controller.error(),\n // so Promise.all should always resolve. Add defensive catch for edge cases.\n Promise.all(consumers).catch((error: unknown) => {\n // This should not happen since each consumer catches its own errors,\n // but handle it defensively to prevent silent failures.\n controller.error(error instanceof Error ? error : new StreamError(String(error)));\n });\n\n yield* merged;\n}\n\n/**\n * Takes chunks from a stream until a predicate returns true.\n * @param stream - The source stream\n * @param predicate - Function that returns true to stop taking\n * @param options - Options including whether to include the matching chunk\n * @returns Stream of chunks up to (and optionally including) the match\n */\nexport async function* takeUntil<T>(\n stream: AsyncIterable<T>,\n predicate: (chunk: T, index: number) => boolean | Promise<boolean>,\n options: { signal?: AbortSignal; inclusive?: boolean } = {}\n): AsyncIterable<T> {\n let index = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('takeUntil aborted');\n }\n\n const shouldStop = await predicate(chunk, index);\n\n if (shouldStop) {\n if (options.inclusive === true) {\n yield chunk;\n }\n return;\n }\n\n yield chunk;\n index++;\n }\n}\n\n/**\n * Filters stream chunks based on a predicate.\n * @param stream - The source stream\n * @param predicate - Function that returns true to keep the chunk\n * @param options - Options including optional AbortSignal\n * @returns Filtered stream\n */\nexport async function* filterStream<T>(\n stream: AsyncIterable<T>,\n predicate: (chunk: T, index: number) => boolean | Promise<boolean>,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n let index = 0;\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('filter aborted');\n }\n\n if (await predicate(chunk, index)) {\n yield chunk;\n }\n\n index++;\n }\n}\n\n/**\n * Adds a timeout to a stream. If no chunk is received within the timeout,\n * the stream throws a TimeoutError.\n * @param stream - The source stream\n * @param timeoutMs - Timeout in milliseconds\n * @param options - Options including optional AbortSignal\n * @returns Stream with timeout applied\n */\nexport async function* withTimeout<T>(\n stream: AsyncIterable<T>,\n timeoutMs: number,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T> {\n const iterator = stream[Symbol.asyncIterator]();\n\n try {\n let running = true;\n while (running) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('withTimeout aborted');\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n const result = await Promise.race([\n iterator.next().then((res) => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n return res;\n }),\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new TimeoutError(`Stream timed out after ${String(timeoutMs)}ms`, {\n context: { timeoutMs },\n })\n );\n }, timeoutMs);\n }),\n ]);\n\n if (result.done === true) {\n running = false;\n } else {\n yield result.value;\n }\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n }\n } finally {\n // Ensure the iterator is properly closed\n if (iterator.return !== undefined) {\n await iterator.return();\n }\n }\n}\n\n/**\n * Buffers stream chunks into groups of a specified size.\n * @param stream - The source stream\n * @param size - Buffer size\n * @param options - Options including optional AbortSignal\n * @returns Stream of chunk arrays\n */\nexport async function* bufferStream<T>(\n stream: AsyncIterable<T>,\n size: number,\n options: { signal?: AbortSignal } = {}\n): AsyncIterable<T[]> {\n if (size <= 0) {\n throw new StreamError('Buffer size must be positive');\n }\n\n let buffer: T[] = [];\n\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n throw new StreamCancelledError('buffer aborted');\n }\n\n buffer.push(chunk);\n\n if (buffer.length >= size) {\n yield buffer;\n buffer = [];\n }\n }\n\n // Yield remaining chunks\n if (buffer.length > 0) {\n yield buffer;\n }\n}\n","/**\n * nexus-agents/adapters - Streaming Utilities\n *\n * AsyncIterator-based streaming utilities for model responses.\n * Provides stream creation, backpressure handling, cancellation support,\n * and chunk collection helpers.\n *\n * For stream transformation operators (map, filter, merge, etc.),\n * see ./stream-operators.ts\n */\n\nimport { type Result, ok, err } from '../core/index.js';\n\n// Re-export core streaming types and utilities from shared module\nexport {\n StreamError,\n StreamCancelledError,\n StreamController,\n createStream,\n type StreamState,\n type CreateStreamOptions,\n} from './streaming-types.js';\n\n// Import for use in this file\nimport { StreamError, StreamCancelledError } from './streaming-types.js';\n\n/**\n * Default cap on collected chunks — prevents unbounded memory growth when\n * callers forget to pass `maxChunks`. Callers that genuinely need no cap\n * must opt in explicitly with `{ maxChunks: Infinity }`. (#1913 Class F)\n */\nexport const DEFAULT_COLLECT_STREAM_MAX_CHUNKS = 100_000;\n\n/**\n * Collects all chunks from a stream into an array.\n *\n * @param stream - The stream to collect\n * @param options - Options including optional AbortSignal.\n * `maxChunks` defaults to {@link DEFAULT_COLLECT_STREAM_MAX_CHUNKS} to\n * prevent unbounded memory growth on forgotten limits. Pass\n * `Infinity` explicitly for truly unbounded collection.\n * @returns Result containing collected chunks or error\n */\nexport async function collectStream<T>(\n stream: AsyncIterable<T>,\n options: { signal?: AbortSignal; maxChunks?: number } = {}\n): Promise<Result<T[], StreamError>> {\n const chunks: T[] = [];\n const maxChunks = options.maxChunks ?? DEFAULT_COLLECT_STREAM_MAX_CHUNKS;\n\n try {\n for await (const chunk of stream) {\n if (options.signal?.aborted === true) {\n return err(new StreamError('Collection aborted'));\n }\n\n chunks.push(chunk);\n\n if (chunks.length >= maxChunks) {\n break;\n }\n }\n\n return ok(chunks);\n } catch (error) {\n if (error instanceof StreamCancelledError) {\n return err(new StreamError('Stream was cancelled during collection', { cause: error }));\n }\n return err(\n new StreamError('Failed to collect stream', {\n cause: error instanceof Error ? error : new Error(String(error)),\n })\n );\n }\n}\n\n// Re-export all stream operators for convenience\nexport {\n transformStream,\n mergeStreams,\n takeUntil,\n take,\n skip,\n filterStream,\n withTimeout,\n bufferStream,\n concatStreams,\n fromArray,\n tapStream,\n reduceStream,\n} from './stream-operators.js';\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
ConfigError,
|
|
3
3
|
err,
|
|
4
4
|
ok
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-O4KUCF5S.js";
|
|
6
6
|
|
|
7
7
|
// src/adapters/sdk/types.ts
|
|
8
8
|
var PROVIDER_ENV_KEYS = {
|
|
@@ -117,4 +117,4 @@ export {
|
|
|
117
117
|
CUSTOM_API_ALLOW_PRIVATE_ENV,
|
|
118
118
|
validateCustomApiBaseUrl
|
|
119
119
|
};
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
120
|
+
//# sourceMappingURL=chunk-5WQ3SRSE.js.map
|
|
@@ -4,13 +4,74 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
ParseError,
|
|
6
6
|
SecurityError,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
err,
|
|
8
|
+
getErrorMessage,
|
|
9
|
+
ok
|
|
10
|
+
} from "./chunk-O4KUCF5S.js";
|
|
9
11
|
|
|
10
12
|
// src/cli/research-helpers-io.ts
|
|
13
|
+
import * as fs2 from "fs/promises";
|
|
14
|
+
import { join, resolve as resolve2 } from "path";
|
|
15
|
+
import { parse as parseYaml, stringify as stringifyYaml2 } from "yaml";
|
|
16
|
+
|
|
17
|
+
// src/cli/research-scaffold.ts
|
|
11
18
|
import * as fs from "fs/promises";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
19
|
+
import { existsSync } from "fs";
|
|
20
|
+
import { dirname, resolve } from "path";
|
|
21
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
22
|
+
var SCHEMA_VERSION = "1.0";
|
|
23
|
+
var ANNOUNCED = /* @__PURE__ */ new Set();
|
|
24
|
+
function announceOnce(path, kind) {
|
|
25
|
+
if (ANNOUNCED.has(path)) return;
|
|
26
|
+
ANNOUNCED.add(path);
|
|
27
|
+
process.stderr.write(
|
|
28
|
+
`[scaffold] Created empty ${kind} at ${path}; add entries via 'nexus-agents research add' or research_add MCP tool.
|
|
29
|
+
`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function scaffoldDisabled() {
|
|
33
|
+
const v = process.env["NEXUS_NO_SCAFFOLD"];
|
|
34
|
+
return v === "1" || v === "true";
|
|
35
|
+
}
|
|
36
|
+
function emptyPapersYaml() {
|
|
37
|
+
return stringifyYaml({ schema_version: SCHEMA_VERSION, papers: {} });
|
|
38
|
+
}
|
|
39
|
+
function emptyTechniquesYaml() {
|
|
40
|
+
return stringifyYaml({ schema_version: SCHEMA_VERSION, techniques: {} });
|
|
41
|
+
}
|
|
42
|
+
async function ensureRegistryFile(rootDir, filename) {
|
|
43
|
+
const filePath = resolve(rootDir, REGISTRY_PATH, filename);
|
|
44
|
+
if (existsSync(filePath)) return ok(filePath);
|
|
45
|
+
if (scaffoldDisabled()) {
|
|
46
|
+
return err(
|
|
47
|
+
new ParseError(
|
|
48
|
+
`Registry file missing: ${filePath}. Scaffolding disabled (NEXUS_NO_SCAFFOLD=1). Create the file manually or unset the env var.`
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (!existsSync(resolve(rootDir, "docs"))) {
|
|
53
|
+
return err(
|
|
54
|
+
new ParseError(
|
|
55
|
+
`Registry file missing: ${filePath}. ${rootDir}/docs/ does not exist; refusing to create a Nexus subtree in a non-documented root. Run 'nexus-agents init' first, or create ${rootDir}/docs/ manually.`
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await fs.mkdir(dirname(filePath), { recursive: true });
|
|
61
|
+
const content = filename === PAPERS_FILE ? emptyPapersYaml() : emptyTechniquesYaml();
|
|
62
|
+
await fs.writeFile(filePath, content, "utf-8");
|
|
63
|
+
announceOnce(filePath, filename);
|
|
64
|
+
return ok(filePath);
|
|
65
|
+
} catch (e) {
|
|
66
|
+
return err(
|
|
67
|
+
new ParseError(
|
|
68
|
+
`Failed to scaffold ${filename} at ${filePath}: ${getErrorMessage(e)}. Set NEXUS_NO_SCAFFOLD=1 and create manually if scaffolding is unwanted.`
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/cli/research-helpers-io.ts
|
|
14
75
|
var REGISTRY_PATH = "docs/research/registry";
|
|
15
76
|
var TECHNIQUES_FILE = "techniques.yaml";
|
|
16
77
|
var PAPERS_FILE = "papers.yaml";
|
|
@@ -23,7 +84,7 @@ function validatePath(constructedPath, allowedRoot) {
|
|
|
23
84
|
return {
|
|
24
85
|
ok: false,
|
|
25
86
|
error: new SecurityError("Path traversal detected: path escapes allowed root directory", {
|
|
26
|
-
context: { constructedPath, allowedRoot:
|
|
87
|
+
context: { constructedPath, allowedRoot: resolve2(allowedRoot) }
|
|
27
88
|
})
|
|
28
89
|
};
|
|
29
90
|
}
|
|
@@ -36,8 +97,9 @@ async function loadTechniquesRegistry(rootDir) {
|
|
|
36
97
|
if (!pathValidation.ok) {
|
|
37
98
|
return pathValidation;
|
|
38
99
|
}
|
|
100
|
+
await ensureRegistryFile(root, TECHNIQUES_FILE);
|
|
39
101
|
try {
|
|
40
|
-
const content = await
|
|
102
|
+
const content = await fs2.readFile(pathValidation.value, "utf-8");
|
|
41
103
|
return { ok: true, value: parseYaml(content) };
|
|
42
104
|
} catch (error) {
|
|
43
105
|
const message = getErrorMessage(error);
|
|
@@ -51,8 +113,9 @@ async function loadPapersRegistry(rootDir) {
|
|
|
51
113
|
if (!pathValidation.ok) {
|
|
52
114
|
return pathValidation;
|
|
53
115
|
}
|
|
116
|
+
await ensureRegistryFile(root, PAPERS_FILE);
|
|
54
117
|
try {
|
|
55
|
-
const content = await
|
|
118
|
+
const content = await fs2.readFile(pathValidation.value, "utf-8");
|
|
56
119
|
return { ok: true, value: parseYaml(content) };
|
|
57
120
|
} catch (error) {
|
|
58
121
|
const message = getErrorMessage(error);
|
|
@@ -67,8 +130,8 @@ async function savePapersRegistry(registry, rootDir) {
|
|
|
67
130
|
return pathValidation;
|
|
68
131
|
}
|
|
69
132
|
try {
|
|
70
|
-
const content =
|
|
71
|
-
await
|
|
133
|
+
const content = stringifyYaml2(registry, { lineWidth: 100 });
|
|
134
|
+
await fs2.writeFile(pathValidation.value, content, "utf-8");
|
|
72
135
|
return { ok: true, value: void 0 };
|
|
73
136
|
} catch (error) {
|
|
74
137
|
const message = getErrorMessage(error);
|
|
@@ -918,4 +981,4 @@ export {
|
|
|
918
981
|
normalizeTopicToCanonical,
|
|
919
982
|
synthesizeResearch
|
|
920
983
|
};
|
|
921
|
-
//# sourceMappingURL=chunk-
|
|
984
|
+
//# sourceMappingURL=chunk-A35XORXU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/research-helpers-io.ts","../src/cli/research-scaffold.ts","../src/cli/research-alignment-map.ts","../src/research/topic-aliases.ts","../src/cli/research-helpers-synthesize.ts"],"sourcesContent":["/**\n * Research Registry I/O Operations\n *\n * File operations for loading and saving research registry YAML files.\n * Includes path traversal protection per Issue #353.\n *\n * @see docs/research/RESEARCH_INDEX.md\n * @see Issue #237 (Epic #225)\n * @see Issue #353 (Security - Path traversal fix)\n */\n\nimport * as fs from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { resolveInsideRoot } from '../security/safe-path.js';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { Result } from '../core/index.js';\nimport { SecurityError, getErrorMessage } from '../core/index.js';\nimport { ParseError } from '../core/types/workflow.js';\nimport type { TechniquesRegistry, PapersRegistry } from './research-types.js';\nimport { ensureRegistryFile } from './research-scaffold.js';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Path to research registry directory relative to project root */\nexport const REGISTRY_PATH = 'docs/research/registry';\n\n/** Filename for techniques registry */\nexport const TECHNIQUES_FILE = 'techniques.yaml';\n\n/** Filename for papers registry */\nexport const PAPERS_FILE = 'papers.yaml';\n\n// =============================================================================\n// PROJECT ROOT\n// =============================================================================\n\n/**\n * Get the project root directory.\n * Note: Returns cwd since registry operations use explicit rootDir parameter\n */\nexport function getProjectRoot(): string {\n return process.cwd();\n}\n\n// =============================================================================\n// PATH VALIDATION\n// =============================================================================\n\n/**\n * Validates that a constructed path stays within the allowed root directory.\n * Prevents path traversal attacks (e.g., ../../../etc/passwd).\n *\n * @param constructedPath - The full path to validate\n * @param allowedRoot - The root directory that paths must be within\n * @returns Result with validated absolute path or SecurityError\n */\nfunction validatePath(constructedPath: string, allowedRoot: string): Result<string, SecurityError> {\n const resolved = resolveInsideRoot(constructedPath, allowedRoot);\n if (resolved === null) {\n return {\n ok: false,\n error: new SecurityError('Path traversal detected: path escapes allowed root directory', {\n context: { constructedPath, allowedRoot: resolve(allowedRoot) },\n }),\n };\n }\n return { ok: true, value: resolved };\n}\n\n// =============================================================================\n// LOAD OPERATIONS\n// =============================================================================\n\n/**\n * Load techniques registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with TechniquesRegistry or SecurityError/ParseError\n */\nexport async function loadTechniquesRegistry(\n rootDir?: string\n): Promise<Result<TechniquesRegistry, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n // #2470: try to scaffold an empty techniques.yaml on first run so research_*\n // workflows don't error on a fresh install. No-op when file exists.\n // When scaffold refuses (e.g. <rootDir>/docs/ doesn't exist, or\n // NEXUS_NO_SCAFFOLD=1), fall through and let readFile produce the original\n // ENOENT error — that's the existing contract.\n await ensureRegistryFile(root, TECHNIQUES_FILE);\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as TechniquesRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load techniques registry: ${message}`) };\n }\n}\n\n/**\n * Load papers registry from YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with PapersRegistry or SecurityError/ParseError\n */\nexport async function loadPapersRegistry(\n rootDir?: string\n): Promise<Result<PapersRegistry, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n // #2470: try to scaffold an empty papers.yaml on first run so research_*\n // workflows don't error on a fresh install. No-op when file exists; falls\n // through silently when scaffold refuses (no docs/ root, or NEXUS_NO_SCAFFOLD).\n await ensureRegistryFile(root, PAPERS_FILE);\n\n try {\n const content = await fs.readFile(pathValidation.value, 'utf-8');\n return { ok: true, value: parseYaml(content) as PapersRegistry };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to load papers registry: ${message}`) };\n }\n}\n\n// =============================================================================\n// SAVE OPERATIONS\n// =============================================================================\n\n/**\n * Save techniques registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The techniques registry to save\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function saveTechniquesRegistry(\n registry: TechniquesRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, TECHNIQUES_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save techniques registry: ${message}`) };\n }\n}\n\n/**\n * Save papers registry to YAML file.\n * Validates path to prevent directory traversal attacks.\n *\n * @param registry - The papers registry to save\n * @param rootDir - Project root directory (defaults to cwd)\n * @returns Result with void on success or SecurityError/ParseError on failure\n */\nexport async function savePapersRegistry(\n registry: PapersRegistry,\n rootDir?: string\n): Promise<Result<void, SecurityError | ParseError>> {\n const root = rootDir ?? process.cwd();\n const filePath = join(root, REGISTRY_PATH, PAPERS_FILE);\n\n const pathValidation = validatePath(filePath, root);\n if (!pathValidation.ok) {\n return pathValidation;\n }\n\n try {\n const content = stringifyYaml(registry, { lineWidth: 100 });\n await fs.writeFile(pathValidation.value, content, 'utf-8');\n return { ok: true, value: undefined };\n } catch (error) {\n const message = getErrorMessage(error);\n return { ok: false, error: new ParseError(`Failed to save papers registry: ${message}`) };\n }\n}\n","/**\n * research-scaffold — auto-create empty research registry files when missing.\n *\n * On a fresh install or in a sandboxed environment where the project doesn't\n * have `docs/research/registry/`, the research workflows previously errored\n * with `Failed to load papers registry: ENOENT`. The user has no idea what\n * to do.\n *\n * This module provides `ensureResearchRegistry()`: idempotent scaffolding\n * that creates empty YAML registries on ENOENT, announces what it did to\n * stderr (so the operator knows), and returns the path that's now safe to\n * read.\n *\n * Source: Issue #2470 (epic #2467 child).\n */\n\nimport * as fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { stringify as stringifyYaml } from 'yaml';\n\nimport type { Result } from '../core/index.js';\nimport { ok, err, getErrorMessage } from '../core/index.js';\nimport { ParseError } from '../core/types/workflow.js';\n\nimport { REGISTRY_PATH, PAPERS_FILE, TECHNIQUES_FILE } from './research-helpers-io.js';\n\n/**\n * Names of the registry files this scaffolder knows how to create.\n * `sources.yaml` and `alignments.yaml` live alongside but are populated by\n * different code paths; this scaffolder only owns the two YAML registries\n * that block `research_query` / `research_synthesize` on a fresh install.\n */\ntype ScaffoldedFile = typeof PAPERS_FILE | typeof TECHNIQUES_FILE;\n\nconst SCHEMA_VERSION = '1.0';\n\nconst ANNOUNCED = new Set<string>();\n\nfunction announceOnce(path: string, kind: ScaffoldedFile): void {\n // De-dupe so that running multiple research commands in one session\n // produces one announcement per scaffolded file, not per call.\n if (ANNOUNCED.has(path)) return;\n ANNOUNCED.add(path);\n process.stderr.write(\n `[scaffold] Created empty ${kind} at ${path}; add entries via 'nexus-agents research add' or research_add MCP tool.\\n`\n );\n}\n\n/**\n * Operator opt-out. When set, scaffolding errors loudly with an actionable\n * message instead of silently writing files. Useful for CI and for\n * environments that want strict \"fail when state is wrong\" semantics.\n */\nfunction scaffoldDisabled(): boolean {\n const v = process.env['NEXUS_NO_SCAFFOLD'];\n return v === '1' || v === 'true';\n}\n\nfunction emptyPapersYaml(): string {\n return stringifyYaml({ schema_version: SCHEMA_VERSION, papers: {} });\n}\n\nfunction emptyTechniquesYaml(): string {\n return stringifyYaml({ schema_version: SCHEMA_VERSION, techniques: {} });\n}\n\n/**\n * Create the registry directory + an empty YAML file if either is missing.\n * Idempotent: existing files are left untouched.\n *\n * Scaffolds only when `<rootDir>/docs/` already exists. That guard keeps\n * tests, vitest's package cwd, and random scratch directories from getting\n * a `docs/research/` subtree implicitly. Operators on a real project root\n * (which always has `docs/`, either from cloning the repo or running\n * `nexus-agents init`) still get the auto-create behavior the issue asks for.\n *\n * Returns the resolved file path on success, or a ParseError when scaffolding\n * is disabled / refused (so the caller can pass the error through unchanged\n * for backwards compat with existing call sites).\n */\nexport async function ensureRegistryFile(\n rootDir: string,\n filename: ScaffoldedFile\n): Promise<Result<string, ParseError>> {\n const filePath = resolve(rootDir, REGISTRY_PATH, filename);\n\n if (existsSync(filePath)) return ok(filePath);\n\n if (scaffoldDisabled()) {\n return err(\n new ParseError(\n `Registry file missing: ${filePath}. Scaffolding disabled (NEXUS_NO_SCAFFOLD=1). Create the file manually or unset the env var.`\n )\n );\n }\n\n // Refuse to create a docs/ subtree in directories that aren't already\n // documented project roots. The presence of `<rootDir>/docs/` is the\n // strong signal we use.\n if (!existsSync(resolve(rootDir, 'docs'))) {\n return err(\n new ParseError(\n `Registry file missing: ${filePath}. ${rootDir}/docs/ does not exist; ` +\n `refusing to create a Nexus subtree in a non-documented root. ` +\n `Run 'nexus-agents init' first, or create ${rootDir}/docs/ manually.`\n )\n );\n }\n\n try {\n await fs.mkdir(dirname(filePath), { recursive: true });\n const content = filename === PAPERS_FILE ? emptyPapersYaml() : emptyTechniquesYaml();\n await fs.writeFile(filePath, content, 'utf-8');\n announceOnce(filePath, filename);\n return ok(filePath);\n } catch (e: unknown) {\n return err(\n new ParseError(\n `Failed to scaffold ${filename} at ${filePath}: ${getErrorMessage(e)}. Set NEXUS_NO_SCAFFOLD=1 and create manually if scaffolding is unwanted.`\n )\n );\n }\n}\n\n/**\n * Convenience: scaffold both papers.yaml and techniques.yaml. Used by the\n * research workflow startup paths that need both registries available.\n */\nexport async function ensureResearchRegistry(rootDir?: string): Promise<Result<void, ParseError>> {\n const root = rootDir ?? process.cwd();\n const papers = await ensureRegistryFile(root, PAPERS_FILE);\n if (!papers.ok) return papers;\n const techniques = await ensureRegistryFile(root, TECHNIQUES_FILE);\n if (!techniques.ok) return techniques;\n return ok(undefined);\n}\n\n/**\n * Test-only reset of the announcement de-dupe set. Production code never\n * needs this; tests do because Vitest reuses process state across files.\n */\nexport function _resetAnnouncedForTests(): void {\n ANNOUNCED.clear();\n}\n","/**\n * Research Alignment Map\n *\n * Maps technique names from the research registry to canonical code paths\n * in the nexus-agents codebase. Used by research synthesis to determine\n * which paper techniques are implemented, partially implemented, or new.\n *\n * @module cli/research-alignment-map\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** Implementation status for a mapped technique. */\nexport interface TechniqueMapping {\n readonly status: 'implemented' | 'partial';\n readonly path: string;\n readonly hint?: string | undefined;\n}\n\n/** A feature gate that controls an implementation. */\nexport interface FeatureGate {\n /** Environment variable or config key. */\n readonly envVar: string;\n /** Default value when not explicitly set. */\n readonly defaultValue: string;\n /** Brief description of what the gate controls. */\n readonly description: string;\n /** Related technique names from the alignment map (if any). */\n readonly techniques?: readonly string[];\n}\n\n// =============================================================================\n// MAP\n// =============================================================================\n\n/**\n * Maps technique names to canonical code paths.\n * 'implemented' = full implementation exists matching the technique.\n * 'partial' = related code exists but doesn't fully implement the technique.\n */\nexport const TECHNIQUE_IMPLEMENTATION_MAP: ReadonlyMap<string, TechniqueMapping> = new Map([\n // Routing techniques\n ['linucb-routing', { status: 'implemented', path: 'cli-adapters/linucb-bandit.ts' }],\n ['topsis-routing', { status: 'implemented', path: 'cli-adapters/topsis-router.ts' }],\n [\n 'cascade-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'complexity-based-routing',\n { status: 'implemented', path: 'routing/stages/confidence-cascade-stage.ts' },\n ],\n [\n 'moe-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router.ts',\n hint: '5-stage composite routing selects among specialized CLI experts based on task features',\n },\n ],\n ['two-stage-routing', { status: 'implemented', path: 'cli-adapters/composite-router-stages.ts' }],\n [\n 'capability-instruction-tuning',\n {\n status: 'partial',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'Static capability profiles, not instruction-tuned',\n },\n ],\n [\n 'knn-routing',\n {\n status: 'implemented',\n path: 'routing/stages/knn-routing-stage.ts',\n hint: 'KnnRoutingStage: cosine similarity over keyword vectors, K-nearest experience patterns, weighted by success rate',\n },\n ],\n ['pilot-budget-routing', { status: 'implemented', path: 'cli-adapters/budget-router.ts' }],\n [\n 'tolerance-routing',\n {\n status: 'implemented',\n path: 'cli-adapters/composite-router-helpers.ts',\n hint: 'TOPSIS_TOLERANCE_BAND_PERCENT (5%) identifies quality-equivalent candidates after TOPSIS ranking',\n },\n ],\n [\n 'sater-routing',\n {\n status: 'implemented',\n path: 'routing/stages/quality-constraint-stage.ts',\n hint: 'QualityConstraintStage filters models by min quality (0.7), max cost, max latency before selection',\n },\n ],\n [\n 'preference-trained-routing',\n { status: 'implemented', path: 'cli-adapters/preference-router.ts' },\n ],\n [\n 'strmac-state-routing',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory maintains state across calls (profile, experience, action cache) feeding LinUCB + weather bonus stages',\n },\n ],\n [\n 'cross-attention-routing',\n {\n status: 'implemented',\n path: 'routing/stages/capability-match-stage.ts',\n hint: 'AttentionMatrix maps task features to capability weights (configurable cross-attention)',\n },\n ],\n\n // Consensus techniques\n ['consensus-protocol', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['majority-voting', { status: 'implemented', path: 'consensus/engine.ts' }],\n ['higher-order-voting', { status: 'implemented', path: 'consensus/higher-order-strategy.ts' }],\n [\n 'anti-conformity-weighting',\n { status: 'implemented', path: 'consensus/higher-order-strategy.ts' },\n ],\n [\n 'agreement-based-cascading',\n {\n status: 'implemented',\n path: 'consensus/engine.ts',\n hint: 'canCascadeEarly() closes proposals when outcome is mathematically determined',\n },\n ],\n [\n 'incremental-quorum',\n {\n status: 'implemented',\n path: 'consensus/incremental-quorum.ts',\n hint: 'Ambiguity detection + voter expansion via VoterExpansionCallback (#1408)',\n },\n ],\n [\n 'aegean-consensus',\n { status: 'partial', path: 'consensus/engine.ts', hint: 'Byzantine tolerance not implemented' },\n ],\n [\n 'cp-wbft-consensus',\n {\n status: 'partial',\n path: 'consensus/engine.ts',\n hint: 'No weighted Byzantine fault tolerance',\n },\n ],\n\n // Memory techniques\n ['adaptive-memory', { status: 'implemented', path: 'memory/adaptive/' }],\n ['mirix-six-type-memory', { status: 'implemented', path: 'memory/typed/' }],\n [\n 'mem0-memory-architecture',\n { status: 'partial', path: 'memory/', hint: 'Multi-backend memory but not mem0 pattern' },\n ],\n [\n 'graph-based-memory',\n {\n status: 'partial',\n path: 'memory/belief/',\n hint: 'Belief triples are graph-like but not full graph DB',\n },\n ],\n ['experience-memory', { status: 'implemented', path: 'memory/session/' }],\n ['hindsight-belief-memory', { status: 'implemented', path: 'memory/belief/' }],\n [\n 'profile-memory',\n {\n status: 'implemented',\n path: 'context/routing-memory.ts',\n hint: 'RoutingMemory stores model preferences per task type and feeds recommendations into composite router via PERSISTENCE_AWARE_FLAGS',\n },\n ],\n [\n 'action-memory',\n {\n status: 'implemented',\n path: 'orchestration/outcomes/',\n hint: 'OutcomeStore records actions+results+context with query-by-category/CLI/time and cross-session persistence',\n },\n ],\n ['reflection-memory', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n [\n 'history-encoding',\n {\n status: 'partial',\n path: 'context/token-counter.ts',\n hint: 'Token counting exists but no learned history encoding',\n },\n ],\n\n // Orchestration techniques\n [\n 'aflow-mcts-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow scaffolding exists but MCTS not implemented',\n },\n ],\n [\n 'dynamic-agent-selection',\n { status: 'implemented', path: 'orchestration/aorchestra/agent-planner.ts' },\n ],\n ['dynamic-subagent-creation', { status: 'implemented', path: 'mcp/tools/create-expert.ts' }],\n ['role-based-protocols', { status: 'implemented', path: 'agents/expert-roles.ts' }],\n [\n 'rule-based-coordination',\n { status: 'implemented', path: 'orchestration/aorchestra/worker-dispatcher.ts' },\n ],\n [\n 'temporal-graph-orchestration',\n {\n status: 'partial',\n path: 'orchestration/graph/',\n hint: 'Graph workflows exist but not temporal-aware',\n },\n ],\n [\n 'model-based-coordination',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/',\n hint: 'Worker dispatch but not model-based coordination theory',\n },\n ],\n [\n 'trinity-roles',\n {\n status: 'partial',\n path: 'agents/expert-roles.ts',\n hint: '10 expert roles, not trinity pattern',\n },\n ],\n [\n 'sew-self-evolving-workflows',\n {\n status: 'partial',\n path: 'workflows/aflow/',\n hint: 'AFlow framework but no self-evolution loop',\n },\n ],\n [\n 'scaling-coordination-predictor',\n {\n status: 'partial',\n path: 'orchestration/aorchestra/agent-planner.ts',\n hint: 'Wave sizing but no scaling prediction',\n },\n ],\n\n // Learning techniques\n [\n 'self-refine-loop',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'recursive-improvement',\n {\n status: 'implemented',\n path: 'mcp/tools/orchestrate-dispatch.ts',\n },\n ],\n [\n 'rl-orchestrator',\n {\n status: 'implemented',\n path: 'cli-adapters/linucb-bandit.ts',\n hint: 'LinUCB contextual bandit actively selects models via explore-exploit in routing pipeline',\n },\n ],\n ['reflexion-verbal-rl', { status: 'implemented', path: 'mcp/tools/orchestrate-reflection.ts' }],\n\n // Source-derived techniques (Wave 6 — from open-source project analysis)\n ['failure-lesson-injection', { status: 'implemented', path: 'orchestration/failure-lessons.ts' }],\n [\n 'skill-relevance-matching',\n {\n status: 'implemented',\n path: 'agents/experts/skill-matcher.ts',\n hint: 'Matches task keywords to agent skill descriptions for optimal routing',\n },\n ],\n [\n 'context-rot-prevention',\n {\n status: 'implemented',\n path: 'agents/context-pruner.ts',\n hint: 'Token-efficient context pruning prevents quality degradation in long sessions',\n },\n ],\n [\n 'wave-based-parallel-execution',\n {\n status: 'implemented',\n path: 'orchestration/aorchestra/worker-dispatcher.ts',\n hint: 'AOrchestra worker dispatch with cross-wave context sharing',\n },\n ],\n [\n 'write-time-deduplication',\n {\n status: 'implemented',\n path: 'mcp/tools/memory-write.ts',\n hint: 'Semantic dedup at write time prevents memory bloat',\n },\n ],\n]);\n\n// =============================================================================\n// FEATURE GATE INVENTORY\n// =============================================================================\n\n/** Inventory of feature gates linked to research-aligned techniques. */\nexport const FEATURE_GATE_INVENTORY: readonly FeatureGate[] = [\n {\n envVar: 'NEXUS_V2_MODE',\n defaultValue: 'full',\n description: 'V2 pipeline mode (off/partial/full)',\n techniques: ['two-stage-routing', 'cascade-routing'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA',\n defaultValue: 'true',\n description: 'AOrchestra dynamic agent planning',\n techniques: ['dynamic-agent-selection', 'model-based-coordination'],\n },\n {\n envVar: 'NEXUS_AORCHESTRA_DISPATCH',\n defaultValue: 'true',\n description: 'AOrchestra worker dispatch',\n techniques: ['rule-based-coordination', 'self-refine-loop'],\n },\n {\n envVar: 'NEXUS_PERSIST_LEARNING',\n defaultValue: 'true',\n description: 'Cross-session routing persistence',\n techniques: ['linucb-routing', 'preference-trained-routing', 'experience-memory'],\n },\n {\n envVar: 'NEXUS_REFLECTIVE_MEMORY',\n defaultValue: 'shadow',\n description: 'Reflective memory retrieval (shadow=default, true=full, false=off)',\n techniques: ['reflection-memory', 'adaptive-memory', 'reflexion-verbal-rl'],\n },\n {\n envVar: 'NEXUS_BILLING_MODE',\n defaultValue: 'plan',\n description: 'Cost mode (plan=strongest, api=cost-aware)',\n techniques: ['pilot-budget-routing', 'topsis-routing'],\n },\n {\n envVar: 'NEXUS_WORKER_MAX_CALLS',\n defaultValue: '6',\n description: 'Max model calls per orchestrate',\n techniques: ['self-refine-loop', 'recursive-improvement'],\n },\n { envVar: 'NEXUS_AUTH_ENABLED', defaultValue: 'true', description: 'Server authentication' },\n { envVar: 'NEXUS_EVENTBUS_ENABLED', defaultValue: 'true', description: 'EventBus A2A bridge' },\n {\n envVar: 'NEXUS_RATE_LIMIT_ENABLED',\n defaultValue: 'true',\n description: 'Token-bucket rate limiter',\n },\n {\n envVar: 'NEXUS_CIRCUIT_BREAKER_THRESHOLD',\n defaultValue: '5',\n description: 'Circuit breaker failure threshold',\n },\n {\n envVar: 'NEXUS_V2_POLICY_MODE',\n defaultValue: 'block',\n description: 'Policy enforcement (off/warn/block)',\n },\n { envVar: 'NEXUS_LOG_LEVEL', defaultValue: 'info', description: 'Logging verbosity' },\n {\n envVar: 'NEXUS_DISABLE_SESSIONS',\n defaultValue: 'false',\n description: 'Disable session tracking',\n },\n {\n envVar: 'NEXUS_DISABLE_METRICS',\n defaultValue: 'false',\n description: 'Disable metrics tracking',\n },\n {\n envVar: 'NEXUS_ALLOW_MOCK_ORCHESTRATION',\n defaultValue: 'false',\n description: 'Allow mock orchestration (test/CI)',\n },\n {\n envVar: 'NEXUS_MAX_CONCURRENT_EXPERTS',\n defaultValue: '6',\n description: 'Expert pool semaphore capacity',\n },\n {\n envVar: 'NEXUS_VOTE_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Consensus vote timeout override',\n },\n {\n envVar: 'NEXUS_EXPERT_TIMEOUT_MS',\n defaultValue: '120000',\n description: 'Expert handler timeout override',\n },\n {\n envVar: 'NEXUS_WORKER_TIMEOUT_MS',\n defaultValue: '60000',\n description: 'Worker subprocess timeout override',\n },\n];\n","/**\n * Topic alias map for normalizing free-form topic strings to canonical topics.\n *\n * Maps 200+ free-form topic strings found in papers.yaml to 12 canonical topics.\n * Used by normalizeTopicToCanonical() in research-schemas.ts.\n *\n * @module research/topic-aliases\n * @see Issue #1578 — Topic taxonomy normalization\n */\n\n/**\n * Map of free-form topic strings to canonical topics.\n */\nexport const TOPIC_ALIASES: Readonly<Record<string, string>> = {\n // → consensus\n voting: 'consensus',\n 'consensus-voting': 'consensus',\n debate: 'consensus',\n quorum: 'consensus',\n byzantine: 'consensus',\n 'anti-conformity': 'consensus',\n 'agreement-based': 'consensus',\n 'correlation-aware': 'consensus',\n 'LLM consensus and multi-agent voting mechanisms': 'consensus',\n 'tolerance-parameter': 'consensus',\n\n // → routing\n 'model-routing': 'routing',\n 'model routing': 'routing',\n 'llm-routing': 'routing',\n cascade: 'routing',\n 'cascade-routing': 'routing',\n 'cost-optimization': 'routing',\n 'cost-reduction': 'routing',\n 'model-selection': 'routing',\n topsis: 'routing',\n linucb: 'routing',\n 'contextual-bandit': 'routing',\n 'quality-constrained': 'routing',\n 'budget-constraints': 'routing',\n 'unified-routing': 'routing',\n 'query-model-matching': 'routing',\n 'adaptive model routing and selection optimization': 'routing',\n 'multi-model routing optimization': 'routing',\n 'Single-head cross-attention for query-model matching': 'routing',\n 'performance-cost-tradeoff': 'routing',\n 'task-routing': 'routing',\n 'difficulty-estimation': 'routing',\n 'score-based': 'routing',\n 'optimal-weighting': 'routing',\n 'hierarchical-filtering': 'routing',\n 'preference-optimization': 'routing',\n 'preference-data': 'routing',\n dpo: 'routing',\n 'cross-attention': 'routing',\n 'cma-es': 'routing',\n profile: 'routing',\n prediction: 'routing',\n lightweight: 'routing',\n bayesian: 'routing',\n 'quality-diversity': 'routing',\n 'resource-optimization': 'routing',\n 'routing-latency': 'routing',\n optimization: 'routing',\n 'model-merging': 'routing',\n 'model-zoo': 'routing',\n\n // → memory\n 'context-management': 'memory',\n 'context-compression': 'memory',\n 'context-control': 'memory',\n compression: 'memory',\n 'kv-cache': 'memory',\n 'long-context': 'memory',\n 'long-term-memory': 'memory',\n 'episodic-memory': 'memory',\n 'graph-memory': 'memory',\n 'hierarchical-memory': 'memory',\n 'agentic-memory': 'memory',\n 'lifelong-learning': 'memory',\n 'cross-session-learning': 'memory',\n 'continual-learning': 'memory',\n 'self-editing-memory': 'memory',\n 'six-type-memory': 'memory',\n 'belief-memory': 'memory',\n 'belief-state': 'memory',\n 'action-memory': 'memory',\n 'memory-evolution': 'memory',\n 'virtual-context': 'memory',\n paging: 'memory',\n 'prompt-compression': 'memory',\n 'learned-compression': 'memory',\n zettelkasten: 'memory',\n 'knowledge-distillation': 'memory',\n 'history-encoding': 'memory',\n 'ictm-tuple': 'memory',\n 'latent-space': 'memory',\n 'vector-db': 'memory',\n embedding: 'memory',\n 'Taxonomy of context management strategies': 'memory',\n 'Task-specific context compression': 'memory',\n 'Learned compression modules': 'memory',\n rag: 'memory',\n 'retrieval augmented generation': 'memory',\n svd: 'memory',\n 'svd-mutation': 'memory',\n vae: 'memory',\n knn: 'memory',\n experience: 'memory',\n 'state-aware': 'memory',\n 'temporal-graph': 'memory',\n versioning: 'memory',\n\n // → code-generation\n 'code-repair': 'code-generation',\n 'code-agent': 'code-generation',\n 'code-review': 'code-generation',\n 'software-engineering': 'code-generation',\n 'swe-bench': 'code-generation',\n 'self-improvement': 'code-generation',\n 'self-evolving': 'code-generation',\n 'self-debug': 'code-generation',\n 'self-modification': 'code-generation',\n 'skill-library': 'code-generation',\n 'skill-discovery': 'code-generation',\n 'code review benchmarks': 'code-generation',\n 'code generation evaluation': 'code-generation',\n 'execution-feedback': 'code-generation',\n\n // → cli-tools\n mcp: 'cli-tools',\n 'MCP protocol': 'cli-tools',\n 'MCP security': 'cli-tools',\n 'MCP Security': 'cli-tools',\n 'mcp-applications': 'cli-tools',\n 'model-context-protocol': 'cli-tools',\n puppeteer: 'cli-tools',\n streaming: 'cli-tools',\n integration: 'cli-tools',\n\n // → orchestration\n 'multi-agent': 'orchestration',\n 'multi-agent-systems': 'orchestration',\n 'multi-agent orchestration': 'orchestration',\n 'Multi-Agent Orchestration': 'orchestration',\n 'multi-agent-orchestration': 'orchestration',\n 'multi-agent coordination': 'orchestration',\n 'multi-agent-coordination': 'orchestration',\n 'multi-agent-worker-dispatch': 'orchestration',\n 'multi-agent reliability': 'orchestration',\n 'multi-agent-rl': 'orchestration',\n coordination: 'orchestration',\n coordinator: 'orchestration',\n collaboration: 'orchestration',\n 'graph-orchestration': 'orchestration',\n 'agent architecture': 'orchestration',\n 'dynamic-agent-creation': 'orchestration',\n 'specialized-agents': 'orchestration',\n 'thinker-worker-verifier': 'orchestration',\n 'two-agent': 'orchestration',\n 'meta-agent': 'orchestration',\n agents: 'orchestration',\n 'workflow-optimization': 'orchestration',\n 'workflow-generation': 'orchestration',\n 'agent-communication': 'orchestration',\n 'inter-agent': 'orchestration',\n 'gvu-operator': 'orchestration',\n 'rubber-duck': 'orchestration',\n 'parallel-exploration': 'orchestration',\n kubernetes: 'orchestration',\n 'scale-to-zero': 'orchestration',\n edge: 'orchestration',\n llm: 'orchestration',\n multimodal: 'orchestration',\n production: 'orchestration',\n hybrid: 'orchestration',\n 'automatic-discovery': 'orchestration',\n roadmap: 'orchestration',\n\n // → security\n 'prompt injection defense': 'security',\n 'inter-agent-security': 'security',\n 'agent security': 'security',\n compliance: 'security',\n 'formal-verification': 'security',\n 'formal-safety': 'security',\n\n // → evaluation\n benchmark: 'evaluation',\n benchmarking: 'evaluation',\n survey: 'evaluation',\n 'autonomous agent evaluation benchmarks': 'evaluation',\n 'evaluation-methods': 'evaluation',\n 'LLM evaluation': 'evaluation',\n 'hallucination-detection': 'evaluation',\n 'self-evaluation': 'evaluation',\n 'confidence-probe': 'evaluation',\n 'confidence-aware': 'evaluation',\n verifier: 'evaluation',\n observability: 'evaluation',\n theoretical: 'evaluation',\n 'post-deployment': 'evaluation',\n capability: 'evaluation',\n 'knowledge-gaps': 'evaluation',\n helm: 'evaluation',\n\n // → safety\n 'agentic-safety': 'safety',\n 'agentic AI safety': 'safety',\n 'safety-evaluation': 'safety',\n 'reward-modeling': 'safety',\n 'constitutional-ai': 'safety',\n 'hazard-analysis': 'safety',\n stpa: 'safety',\n 'risk-assessment': 'safety',\n 'fault-tolerance': 'safety',\n 'ai-feedback': 'safety',\n rlaif: 'safety',\n 'human-in-the-loop': 'safety',\n feedback: 'safety',\n 'feedback-loop': 'safety',\n 'feedback-learning': 'safety',\n anthropic: 'safety',\n\n // → planning\n 'decision-making': 'planning',\n 'tree-search': 'planning',\n 'tree-structure': 'planning',\n 'multi-tree': 'planning',\n mcts: 'planning',\n backtrack: 'planning',\n hindsight: 'planning',\n 'task-specific': 'planning',\n\n // → tool-use\n 'tool use': 'tool-use',\n 'tool-augmented reasoning and function calling': 'tool-use',\n 'tool routing optimization': 'tool-use',\n 'dynamic-linking': 'tool-use',\n 'Sparse outcome rewards reduce tool calls by 72%': 'tool-use',\n\n // → reasoning\n 'test-time': 'reasoning',\n 'test-time-scaling': 'reasoning',\n 'inference-scaling': 'reasoning',\n 'inference-optimization': 'reasoning',\n 'self-critique': 'reasoning',\n 'self-reflection': 'reasoning',\n 'self-referential': 'reasoning',\n 'self-play': 'reasoning',\n reflexion: 'reasoning',\n reflection: 'reasoning',\n 'reasoning-optimization': 'reasoning',\n 'meta-thinking': 'reasoning',\n scaling: 'reasoning',\n recursive: 'reasoning',\n 'trajectory-abstraction': 'reasoning',\n 'verbal-rl': 'reasoning',\n exploration: 'reasoning',\n 'Reducible uncertainty modeling across agent trajectories': 'reasoning',\n 'Environmental feedback reduces uncertainty at decision gates': 'reasoning',\n 'reinforcement-learning': 'reasoning',\n transformer: 'reasoning',\n ssm: 'reasoning',\n 'sparse-activation': 'reasoning',\n 'behavior-distillation': 'reasoning',\n 'training-free': 'reasoning',\n 'transfer-learning': 'reasoning',\n 'instruction-tuning': 'reasoning',\n 'Dense process rewards improve performance by 22%': 'reasoning',\n 'prompt-optimization': 'reasoning',\n};\n\n/**\n * Normalize a free-form topic string to a canonical topic.\n * Returns the canonical topic if a mapping exists, otherwise the original string.\n */\nexport function normalizeTopicToCanonical(topic: string): string {\n return TOPIC_ALIASES[topic] ?? topic;\n}\n","/**\n * Research Synthesis Helper\n *\n * Groups papers by topic cluster and generates structured synthesis\n * summaries with themes, findings, and implementation opportunities.\n *\n * @module cli/research-helpers-synthesize\n * (Source: Issue #1386 — Research Synthesis Pipeline)\n */\n\nimport { loadPapersRegistry } from './research-helpers-io.js';\nimport type { PapersRegistry } from './research-types.js';\nimport type { Result } from '../core/result.js';\nimport { getErrorMessage } from '../core/index.js';\nimport { TECHNIQUE_IMPLEMENTATION_MAP, FEATURE_GATE_INVENTORY } from './research-alignment-map.js';\nimport { normalizeTopicToCanonical } from '../research/topic-aliases.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** A paper entry from the registry, simplified for synthesis. */\nexport interface SynthesisPaper {\n readonly id: string;\n readonly title: string;\n readonly topics: readonly string[];\n readonly tags: readonly string[];\n readonly summary: string;\n readonly keyFindings: readonly string[];\n readonly relevance: string;\n readonly implementationStatus: string;\n readonly techniquesExtracted: readonly string[];\n readonly qualityScore: number;\n readonly evidenceTier: 'high' | 'medium' | 'low';\n}\n\n/** A cluster of related papers grouped by topic. */\nexport interface PaperCluster {\n readonly topic: string;\n readonly papers: readonly SynthesisPaper[];\n readonly paperCount: number;\n}\n\n/** A technique aligned to an existing implementation. */\nexport interface TechniqueAlignment {\n readonly technique: string;\n readonly status: 'implemented' | 'partial' | 'not-started';\n readonly canonicalPath?: string | undefined;\n readonly improvementHint?: string | undefined;\n}\n\n/** Quality distribution within a cluster. */\nexport interface QualityDistribution {\n readonly avgScore: number;\n readonly high: number;\n readonly medium: number;\n readonly low: number;\n}\n\n/** Synthesis output for a single topic cluster. */\nexport interface ClusterSynthesis {\n readonly topic: string;\n readonly paperCount: number;\n readonly papers: readonly string[];\n readonly commonThemes: readonly string[];\n readonly keyInsights: readonly string[];\n readonly techniques: readonly string[];\n readonly implementationOpportunities: readonly string[];\n readonly gaps: readonly string[];\n readonly alignedTechniques: readonly TechniqueAlignment[];\n readonly qualityDistribution: QualityDistribution;\n}\n\n/** Summary of alignment between research and implementation. */\nexport interface AlignmentSummary {\n readonly implemented: number;\n readonly partial: number;\n readonly notStarted: number;\n readonly total: number;\n readonly topOpportunities: readonly string[];\n}\n\n/** Summary of a single feature gate for synthesis output. */\nexport interface FeatureGateStatus {\n readonly envVar: string;\n readonly defaultValue: string;\n readonly description: string;\n readonly linkedTechniqueCount: number;\n}\n\n/** Full synthesis result across all clusters. */\nexport interface SynthesisResult {\n readonly clusters: readonly ClusterSynthesis[];\n readonly totalPapers: number;\n readonly topicCount: number;\n readonly crossCuttingThemes: readonly string[];\n readonly alignmentSummary: AlignmentSummary;\n readonly featureGates: readonly FeatureGateStatus[];\n}\n\n/** Error for synthesis operations. */\nexport interface SynthesisError {\n readonly code: 'LOAD_ERROR' | 'NO_PAPERS';\n readonly message: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Minimum papers in a cluster to generate cross-cutting themes. */\nconst MIN_CROSS_CUTTING_CLUSTER_SIZE = 2;\n\n/** Tags that appear across many topics and indicate cross-cutting themes. */\nconst CROSS_CUTTING_TAG_THRESHOLD = 3;\n\n// =============================================================================\n// PUBLIC API\n// =============================================================================\n\n/**\n * Synthesize the research registry by grouping papers into topic clusters\n * and generating structured summaries.\n *\n * @param topicFilter - Optional topic to filter to a single cluster\n * @returns Structured synthesis result\n */\nexport async function synthesizeResearch(\n topicFilter?: string\n): Promise<Result<SynthesisResult, SynthesisError>> {\n const registryResult = await loadPapersRegistry();\n if (!registryResult.ok) {\n return {\n ok: false,\n error: {\n code: 'LOAD_ERROR',\n message: `Failed to load papers: ${getErrorMessage(registryResult.error)}`,\n },\n };\n }\n\n const papers = extractPapers(registryResult.value);\n if (papers.length === 0) {\n return {\n ok: false,\n error: { code: 'NO_PAPERS', message: 'No papers found in registry' },\n };\n }\n\n const clusters = groupByTopic(papers);\n const filtered =\n topicFilter !== undefined ? clusters.filter((c) => c.topic === topicFilter) : clusters;\n\n const syntheses = filtered.map(synthesizeCluster);\n const crossCutting = findCrossCuttingThemes(filtered);\n const alignmentSummary = buildAlignmentSummary(syntheses);\n const featureGates = buildFeatureGateSummary();\n\n return {\n ok: true,\n value: {\n clusters: syntheses,\n totalPapers: papers.length,\n topicCount: filtered.length,\n crossCuttingThemes: crossCutting,\n alignmentSummary,\n featureGates,\n },\n };\n}\n\n// =============================================================================\n// EXTRACTION\n// =============================================================================\n\n/**\n * Safely convert a field that types say is `readonly string[]` but may be\n * null/undefined at runtime (YAML parsing of empty array fields).\n */\nfunction safeArray(value: readonly string[]): string[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- YAML parsing can yield null despite type\n if (value === null || value === undefined) return [];\n return Array.from(value);\n}\n\n/** Extract papers from the registry structure. */\nfunction extractPapers(registry: PapersRegistry): SynthesisPaper[] {\n return Object.entries(registry.papers).map(([id, p]) => ({\n id,\n title: p.title,\n topics: safeArray(p.topics),\n tags: safeArray(p.tags),\n summary: p.summary.trim(),\n keyFindings: safeArray(p.key_findings),\n relevance: p.relevance,\n implementationStatus: p.implementation_status,\n techniquesExtracted: safeArray(p.techniques_extracted),\n qualityScore: p.quality_score ?? 0,\n evidenceTier: p.evidence_tier ?? 'low',\n }));\n}\n\n// =============================================================================\n// GROUPING\n// =============================================================================\n\n/** Group papers by primary topic into clusters, normalizing free-form topics. */\nfunction groupByTopic(papers: readonly SynthesisPaper[]): PaperCluster[] {\n const topicMap = new Map<string, SynthesisPaper[]>();\n\n for (const paper of papers) {\n for (const rawTopic of paper.topics) {\n const topic = normalizeTopicToCanonical(rawTopic);\n const existing = topicMap.get(topic);\n if (existing !== undefined) {\n existing.push(paper);\n } else {\n topicMap.set(topic, [paper]);\n }\n }\n }\n\n const clusters: PaperCluster[] = [];\n for (const [topic, unsortedPapers] of topicMap) {\n // Sort papers within cluster by quality_score descending (high-quality first)\n const topicPapers = [...unsortedPapers].sort((a, b) => b.qualityScore - a.qualityScore);\n clusters.push({\n topic,\n papers: topicPapers,\n paperCount: topicPapers.length,\n });\n }\n\n return clusters.sort((a, b) => b.paperCount - a.paperCount);\n}\n\n// =============================================================================\n// SYNTHESIS\n// =============================================================================\n\n/** Generate synthesis for a single topic cluster. */\n/** Compute quality score distribution for a set of papers. */\nfunction computeClusterQuality(papers: readonly SynthesisPaper[]): QualityDistribution {\n const scores = papers.map((p) => p.qualityScore);\n const totalScore = scores.reduce((sum, s) => sum + s, 0);\n return {\n avgScore: scores.length > 0 ? Math.round((totalScore / scores.length) * 10) / 10 : 0,\n high: papers.filter((p) => p.evidenceTier === 'high').length,\n medium: papers.filter((p) => p.evidenceTier === 'medium').length,\n low: papers.filter((p) => p.evidenceTier === 'low').length,\n };\n}\n\nfunction synthesizeCluster(cluster: PaperCluster): ClusterSynthesis {\n const allTags = collectFrequencies(cluster.papers.flatMap((p) => [...p.tags]));\n const allTechniques = collectFrequencies(\n cluster.papers.flatMap((p) => [...p.techniquesExtracted])\n );\n const allFindings = cluster.papers.flatMap((p) => [...p.keyFindings]);\n\n // Common themes: tags that appear in 2+ papers\n const commonThemes = [...allTags.entries()]\n .filter(([, count]) => count >= MIN_CROSS_CUTTING_CLUSTER_SIZE)\n .sort((a, b) => b[1] - a[1])\n .map(([tag]) => tag);\n\n // Techniques across the cluster\n const techniques = [...allTechniques.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([tech, count]) => (count > 1 ? `${tech} (${String(count)} papers)` : tech));\n\n // Implementation opportunities: techniques not yet implemented\n const notStarted = cluster.papers\n .filter((p) => p.implementationStatus === 'not-started')\n .flatMap((p) => [...p.techniquesExtracted]);\n const uniqueOpportunities = [...new Set(notStarted)];\n\n // Gaps: topics with few papers or missing techniques\n const gaps: string[] = [];\n if (cluster.paperCount === 1) {\n gaps.push(`Only 1 paper — more research needed on ${cluster.topic}`);\n }\n const highRelevanceUnimplemented = cluster.papers.filter(\n (p) => p.relevance === 'high' && p.implementationStatus === 'not-started'\n );\n if (highRelevanceUnimplemented.length > 0) {\n gaps.push(\n `${String(highRelevanceUnimplemented.length)} high-relevance paper(s) not yet implemented`\n );\n }\n\n // Alignment analysis: map techniques to existing implementations\n const allTechNames = [...allTechniques.keys()];\n const alignedTechniques = analyzeClusterAlignment(allTechNames);\n\n const qualityDistribution = computeClusterQuality(cluster.papers);\n\n // Add quality gap if most papers are low-quality\n if (qualityDistribution.low > qualityDistribution.high + qualityDistribution.medium) {\n gaps.push(\n `Mostly low-evidence papers (${String(qualityDistribution.low)}/${String(cluster.paperCount)}) — findings need stronger validation`\n );\n }\n\n return {\n topic: cluster.topic,\n paperCount: cluster.paperCount,\n papers: cluster.papers.map((p) => p.title),\n commonThemes,\n keyInsights: deduplicateFindings(allFindings).slice(0, 10),\n techniques,\n implementationOpportunities: uniqueOpportunities,\n gaps,\n alignedTechniques,\n qualityDistribution,\n };\n}\n\n/** Find themes that span multiple topic clusters. */\nfunction findCrossCuttingThemes(clusters: readonly PaperCluster[]): string[] {\n const tagToTopics = new Map<string, Set<string>>();\n\n for (const cluster of clusters) {\n for (const paper of cluster.papers) {\n for (const tag of paper.tags) {\n const existing = tagToTopics.get(tag);\n if (existing !== undefined) {\n existing.add(cluster.topic);\n } else {\n tagToTopics.set(tag, new Set([cluster.topic]));\n }\n }\n }\n }\n\n return [...tagToTopics.entries()]\n .filter(([, topics]) => topics.size >= CROSS_CUTTING_TAG_THRESHOLD)\n .sort((a, b) => b[1].size - a[1].size)\n .map(([tag, topics]) => `${tag} (spans: ${[...topics].join(', ')})`);\n}\n\n// =============================================================================\n// ALIGNMENT ANALYSIS\n// =============================================================================\n\n/** Analyze technique alignment for a cluster. */\nfunction analyzeClusterAlignment(techniques: readonly string[]): TechniqueAlignment[] {\n const alignments: TechniqueAlignment[] = [];\n\n for (const tech of techniques) {\n // Strip count annotation like \"technique (2 papers)\"\n const baseTech = tech.replace(/\\s*\\(\\d+\\s*papers?\\)$/, '');\n const mapping = TECHNIQUE_IMPLEMENTATION_MAP.get(baseTech);\n\n if (mapping !== undefined) {\n alignments.push({\n technique: baseTech,\n status: mapping.status,\n canonicalPath: mapping.path,\n ...(mapping.hint !== undefined ? { improvementHint: mapping.hint } : {}),\n });\n } else {\n alignments.push({ technique: baseTech, status: 'not-started' });\n }\n }\n\n return alignments;\n}\n\n/** Build alignment summary across all clusters. */\nfunction buildAlignmentSummary(clusters: readonly ClusterSynthesis[]): AlignmentSummary {\n const allAlignments = clusters.flatMap((c) => c.alignedTechniques);\n const implemented = allAlignments.filter((a) => a.status === 'implemented').length;\n const partial = allAlignments.filter((a) => a.status === 'partial').length;\n const notStarted = allAlignments.filter((a) => a.status === 'not-started').length;\n\n // Top opportunities: partial implementations with hints (most improvable)\n const opportunities = allAlignments\n .filter((a) => a.status === 'partial' && a.improvementHint !== undefined)\n .map((a) => `${a.technique}: ${a.improvementHint ?? ''}`)\n .slice(0, 10);\n\n return {\n implemented,\n partial,\n notStarted,\n total: allAlignments.length,\n topOpportunities: opportunities,\n };\n}\n\n/** Build feature gate summary from the inventory. */\nfunction buildFeatureGateSummary(): FeatureGateStatus[] {\n return FEATURE_GATE_INVENTORY.map((g) => ({\n envVar: g.envVar,\n defaultValue: g.defaultValue,\n description: g.description,\n linkedTechniqueCount: g.techniques?.length ?? 0,\n }));\n}\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\nfunction collectFrequencies(items: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const item of items) {\n counts.set(item, (counts.get(item) ?? 0) + 1);\n }\n return counts;\n}\n\n/** Deduplicate findings by removing near-identical strings. */\nfunction deduplicateFindings(findings: readonly string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const finding of findings) {\n const normalized = finding.toLowerCase().trim();\n if (normalized.length === 0) continue;\n if (seen.has(normalized)) continue;\n seen.add(normalized);\n result.push(finding);\n }\n return result;\n}\n"],"mappings":"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","names":["fs","resolve","stringifyYaml","resolve","stringifyYaml"]}
|