@kairos-sdk/core 0.3.2 → 0.4.5

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/uuid.ts","../src/errors/base.ts","../src/errors/api-error.ts","../src/errors/provider-error.ts","../src/utils/retry.ts","../src/providers/n8n/api-client.ts","../src/providers/n8n/types.ts","../src/providers/n8n/stripper.ts","../src/validation/registry.ts","../src/validation/validator.ts","../src/telemetry/collector.ts","../src/telemetry/types.ts","../src/telemetry/reader.ts","../src/telemetry/event-reader.ts","../src/telemetry/pattern-analyzer.ts","../src/validation/rule-metadata.ts","../src/utils/logger.ts","../src/library/scorer.ts","../src/library/cluster.ts","../src/library/file-library.ts","../src/utils/thresholds.ts"],"sourcesContent":["export function generateUUID(): string {\n return crypto.randomUUID()\n}\n","export class KairosError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message)\n this.name = 'KairosError'\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n }\n}\n","import { KairosError } from './base.js'\n\nexport class ApiError extends KairosError {\n constructor(\n message: string,\n public readonly statusCode: number,\n cause?: unknown,\n ) {\n super(message, cause)\n this.name = 'ApiError'\n }\n}\n","import { KairosError } from './base.js'\n\nexport class ProviderError extends KairosError {\n constructor(message: string, cause?: unknown) {\n super(message, cause)\n this.name = 'ProviderError'\n }\n}\n","export async function withRetry<T>(\n fn: () => Promise<T>,\n maxAttempts: number,\n delayMs: number,\n shouldRetry?: (err: unknown) => boolean,\n): Promise<T> {\n let lastError: unknown\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (attempt > 0) {\n const jitter = Math.random() * delayMs * 0.5\n await new Promise((resolve) => setTimeout(resolve, delayMs * 2 ** (attempt - 1) + jitter))\n }\n try {\n return await fn()\n } catch (err) {\n lastError = err\n if (shouldRetry && !shouldRetry(err)) throw err\n }\n }\n throw lastError\n}\n\nexport function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer))\n}\n","import type { N8nWorkflow, Tag } from '../../types/workflow.js'\nimport type { WorkflowListItem, ExecutionSummary, ExecutionDetail } from '../../types/result.js'\nimport type { ExecutionFilter } from '../../types/options.js'\nimport type { ILogger } from '../../utils/logger.js'\nimport { ApiError } from '../../errors/api-error.js'\nimport { ProviderError } from '../../errors/provider-error.js'\nimport { withRetry, fetchWithTimeout } from '../../utils/retry.js'\nimport type {\n N8nWorkflowResponse,\n N8nWorkflowListResponse,\n N8nExecutionResponse,\n N8nExecutionListResponse,\n N8nTagResponse,\n N8nTagListResponse,\n N8nNodeTypeInfo,\n N8nNodeTypeListResponse,\n} from './types.js'\n\nconst EXECUTION_LIMIT_CAP = 100\nconst REQUEST_TIMEOUT_MS = 30_000\nconst RETRY_ATTEMPTS = 3\nconst RETRY_DELAY_MS = 1000\n\nexport class N8nApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly logger: ILogger,\n ) {}\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl.replace(/\\/$/, '')}/api/v1${path}`\n this.logger.debug(`n8n ${method} ${path}`)\n\n const isSafe = method === 'GET'\n if (!isSafe) {\n return this.singleRequest<T>(url, method, path, body)\n }\n\n return withRetry(\n () => this.singleRequest<T>(url, method, path, body),\n RETRY_ATTEMPTS,\n RETRY_DELAY_MS,\n (err) => err instanceof ProviderError || (err instanceof ApiError && err.statusCode === 429),\n )\n }\n\n private async singleRequest<T>(url: string, method: string, path: string, body?: unknown): Promise<T> {\n let response: Response\n try {\n response = await fetchWithTimeout(url, {\n method,\n headers: {\n 'X-N8N-API-KEY': this.apiKey,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n }, REQUEST_TIMEOUT_MS)\n } catch (err) {\n throw new ProviderError(`Network error calling n8n API: ${path}`, err)\n }\n\n if (!response.ok) {\n let errorBody: unknown\n try {\n errorBody = await response.json()\n } catch {\n errorBody = await response.text().catch(() => '')\n }\n this.logger.error(`n8n API error ${response.status} on ${method} ${path}`, {\n status: response.status,\n body: String(errorBody),\n })\n throw new ApiError(\n `n8n API returned ${response.status} for ${method} ${path}: ${JSON.stringify(errorBody)}`,\n response.status,\n errorBody,\n )\n }\n\n if (response.status === 204) return undefined as T\n return response.json() as Promise<T>\n }\n\n async createWorkflow(workflow: N8nWorkflow): Promise<N8nWorkflowResponse> {\n return this.request<N8nWorkflowResponse>('POST', '/workflows', workflow)\n }\n\n async updateWorkflow(id: string, workflow: N8nWorkflow): Promise<N8nWorkflowResponse> {\n return this.request<N8nWorkflowResponse>('PUT', `/workflows/${id}`, workflow)\n }\n\n async getWorkflow(id: string): Promise<N8nWorkflowResponse> {\n return this.request<N8nWorkflowResponse>('GET', `/workflows/${id}`)\n }\n\n async listWorkflows(): Promise<WorkflowListItem[]> {\n const all: WorkflowListItem[] = []\n let path = '/workflows?limit=250'\n\n for (;;) {\n const response: N8nWorkflowListResponse = await this.request<N8nWorkflowListResponse>('GET', path)\n for (const w of response.data) {\n all.push({\n id: w.id,\n name: w.name,\n active: w.active,\n createdAt: w.createdAt,\n updatedAt: w.updatedAt,\n ...(w.tags !== undefined ? { tags: w.tags } : {}),\n })\n }\n if (!response.nextCursor) break\n path = `/workflows?limit=250&cursor=${response.nextCursor}`\n }\n\n return all\n }\n\n async deleteWorkflow(id: string): Promise<void> {\n await this.request<void>('DELETE', `/workflows/${id}`)\n }\n\n async activateWorkflow(id: string): Promise<void> {\n await this.request<void>('POST', `/workflows/${id}/activate`)\n }\n\n async deactivateWorkflow(id: string): Promise<void> {\n await this.request<void>('POST', `/workflows/${id}/deactivate`)\n }\n\n async getExecutions(workflowId?: string, filter?: ExecutionFilter): Promise<ExecutionSummary[]> {\n const params = new URLSearchParams()\n if (workflowId) params.set('workflowId', workflowId)\n if (filter?.status) params.set('status', filter.status)\n const limit = Math.min(filter?.limit ?? 20, EXECUTION_LIMIT_CAP)\n params.set('limit', String(limit))\n if (filter?.cursor) params.set('cursor', filter.cursor)\n\n const qs = params.toString()\n const response = await this.request<N8nExecutionListResponse>('GET', `/executions${qs ? `?${qs}` : ''}`)\n return response.data.map(this.mapExecution)\n }\n\n async getExecution(id: string): Promise<ExecutionDetail> {\n const response = await this.request<N8nExecutionResponse>('GET', `/executions/${id}`)\n return { ...this.mapExecution(response), data: response.data, workflowData: response.workflowData }\n }\n\n async listTags(): Promise<Tag[]> {\n const all: Tag[] = []\n let path = '/tags?limit=250'\n\n for (;;) {\n const response: N8nTagListResponse = await this.request<N8nTagListResponse>('GET', path)\n for (const t of response.data) {\n all.push({ id: t.id, name: t.name })\n }\n if (!response.nextCursor) break\n path = `/tags?limit=250&cursor=${response.nextCursor}`\n }\n\n return all\n }\n\n async createTag(name: string): Promise<Tag> {\n const response = await this.request<N8nTagResponse>('POST', '/tags', { name })\n return { id: response.id, name: response.name }\n }\n\n async tagWorkflow(workflowId: string, tagIds: string[]): Promise<void> {\n await this.request<void>('PUT', `/workflows/${workflowId}/tags`, tagIds.map((id) => ({ id })))\n }\n\n async untagWorkflow(workflowId: string, tagIds: string[]): Promise<void> {\n const current = await this.getWorkflow(workflowId)\n const remaining = (current.tags ?? [])\n .filter((t) => !tagIds.includes(t.id))\n .map((t) => ({ id: t.id }))\n await this.request<void>('PUT', `/workflows/${workflowId}/tags`, remaining)\n }\n\n async getNodeTypes(): Promise<N8nNodeTypeInfo[]> {\n try {\n const response = await this.request<N8nNodeTypeListResponse>('GET', '/node-types')\n return response.data ?? response as unknown as N8nNodeTypeInfo[]\n } catch {\n return []\n }\n }\n\n private mapExecution(e: N8nExecutionResponse): ExecutionSummary {\n return {\n id: e.id,\n workflowId: e.workflowId,\n status: e.status,\n startedAt: e.startedAt,\n ...(e.stoppedAt !== undefined ? { stoppedAt: e.stoppedAt } : {}),\n mode: e.mode,\n }\n }\n}\n","import type { N8nNode, N8nConnections, N8nSettings, Tag } from '../../types/workflow.js'\n\nexport interface N8nWorkflowResponse {\n id: string\n name: string\n active: boolean\n nodes: N8nNode[]\n connections: N8nConnections\n settings?: N8nSettings\n tags?: Tag[]\n createdAt: string\n updatedAt: string\n versionId?: string\n meta?: Record<string, unknown>\n pinData?: Record<string, unknown>\n staticData?: unknown\n triggerCount?: number\n shared?: boolean\n isArchived?: boolean\n}\n\nexport interface N8nWorkflowListResponse {\n data: N8nWorkflowResponse[]\n nextCursor: string | null\n}\n\nexport interface N8nExecutionResponse {\n id: string\n workflowId: string\n status: 'success' | 'error' | 'waiting' | 'running' | 'canceled'\n startedAt: string\n stoppedAt?: string\n mode: string\n data?: unknown\n workflowData?: unknown\n}\n\nexport interface N8nExecutionListResponse {\n data: N8nExecutionResponse[]\n nextCursor: string | null\n}\n\nexport interface N8nTagResponse {\n id: string\n name: string\n createdAt?: string\n updatedAt?: string\n}\n\nexport interface N8nTagListResponse {\n data: N8nTagResponse[]\n nextCursor: string | null\n}\n\nexport interface N8nNodeTypeInfo {\n name: string\n displayName: string\n version: number | number[]\n description?: string\n group?: string[]\n credentials?: Array<{ name: string; required?: boolean }>\n}\n\nexport interface N8nNodeTypeListResponse {\n data: N8nNodeTypeInfo[]\n}\n\nexport const FORBIDDEN_ON_CREATE = [\n 'id',\n 'createdAt',\n 'updatedAt',\n 'versionId',\n 'meta',\n 'isArchived',\n 'activeVersionId',\n 'activeVersion',\n 'active',\n 'pinData',\n 'triggerCount',\n 'shared',\n 'staticData',\n] as const\n\nexport const FORBIDDEN_ON_UPDATE = FORBIDDEN_ON_CREATE.filter((f) => f !== 'id')\n\nexport type ForbiddenField = (typeof FORBIDDEN_ON_CREATE)[number]\n","import type { N8nWorkflow } from '../../types/workflow.js'\nimport { FORBIDDEN_ON_CREATE, FORBIDDEN_ON_UPDATE } from './types.js'\n\nexport class N8nFieldStripper {\n stripForCreate(workflow: N8nWorkflow): N8nWorkflow {\n return this.strip(workflow, FORBIDDEN_ON_CREATE as readonly string[])\n }\n\n stripForUpdate(workflow: N8nWorkflow): N8nWorkflow {\n return this.strip(workflow, FORBIDDEN_ON_UPDATE as readonly string[])\n }\n\n private strip(workflow: N8nWorkflow, forbidden: readonly string[]): N8nWorkflow {\n const result = { ...workflow } as unknown as Record<string, unknown>\n for (const field of forbidden) {\n delete result[field]\n }\n return result as unknown as N8nWorkflow\n }\n}\n","export interface NodeDefinition {\n type: string\n safeTypeVersions: number[]\n requiredParams: string[]\n credentialType?: string\n isTrigger?: boolean\n}\n\nexport const DEFAULT_REGISTRY: NodeDefinition[] = [\n // Trigger nodes\n { type: 'n8n-nodes-base.manualTrigger', safeTypeVersions: [1], requiredParams: [], isTrigger: true },\n { type: 'n8n-nodes-base.scheduleTrigger', safeTypeVersions: [1, 1.1, 1.2], requiredParams: [], isTrigger: true },\n { type: 'n8n-nodes-base.webhook', safeTypeVersions: [1, 1.1, 2], requiredParams: ['httpMethod', 'path'], isTrigger: true },\n { type: 'n8n-nodes-base.formTrigger', safeTypeVersions: [1, 2, 2.1, 2.2], requiredParams: [], isTrigger: true },\n { type: 'n8n-nodes-base.emailReadImap', safeTypeVersions: [2], requiredParams: [], credentialType: 'imap', isTrigger: true },\n { type: 'n8n-nodes-base.errorTrigger', safeTypeVersions: [1], requiredParams: [], isTrigger: true },\n { type: 'n8n-nodes-base.executeWorkflowTrigger', safeTypeVersions: [1, 1.1], requiredParams: [], isTrigger: true },\n { type: 'n8n-nodes-base.gmailTrigger', safeTypeVersions: [1, 1.1, 1.2], requiredParams: [], credentialType: 'gmailOAuth2', isTrigger: true },\n { type: 'n8n-nodes-base.googleDriveTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'googleDriveOAuth2Api', isTrigger: true },\n { type: 'n8n-nodes-base.googleSheetsTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'googleSheetsTriggerOAuth2Api', isTrigger: true },\n { type: 'n8n-nodes-base.slackTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'slackApi', isTrigger: true },\n { type: 'n8n-nodes-base.telegramTrigger', safeTypeVersions: [1, 1.1, 1.2], requiredParams: [], credentialType: 'telegramApi', isTrigger: true },\n { type: 'n8n-nodes-base.githubTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'githubApi', isTrigger: true },\n { type: 'n8n-nodes-base.stripeTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'stripeApi', isTrigger: true },\n { type: 'n8n-nodes-base.airtableTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'airtableTokenApi', isTrigger: true },\n { type: 'n8n-nodes-base.notionTrigger', safeTypeVersions: [1], requiredParams: [], credentialType: 'notionApi', isTrigger: true },\n { type: '@n8n/n8n-nodes-langchain.chatTrigger', safeTypeVersions: [1, 1.1], requiredParams: [], isTrigger: true },\n\n // Core logic nodes\n { type: 'n8n-nodes-base.code', safeTypeVersions: [1, 2], requiredParams: [] },\n { type: 'n8n-nodes-base.httpRequest', safeTypeVersions: [1, 2, 3, 4, 4.1, 4.2], requiredParams: ['url'] },\n { type: 'n8n-nodes-base.set', safeTypeVersions: [1, 2, 3, 3.1, 3.2, 3.3, 3.4], requiredParams: [] },\n { type: 'n8n-nodes-base.if', safeTypeVersions: [1, 2, 2.1, 2.2], requiredParams: [] },\n { type: 'n8n-nodes-base.switch', safeTypeVersions: [1, 2, 3, 3.1, 3.2], requiredParams: [] },\n { type: 'n8n-nodes-base.filter', safeTypeVersions: [1, 2, 2.1, 2.2], requiredParams: [] },\n { type: 'n8n-nodes-base.merge', safeTypeVersions: [1, 2, 2.1, 3], requiredParams: [] },\n { type: 'n8n-nodes-base.splitInBatches', safeTypeVersions: [1, 2, 3], requiredParams: [] },\n { type: 'n8n-nodes-base.wait', safeTypeVersions: [1, 1.1], requiredParams: [] },\n { type: 'n8n-nodes-base.executeWorkflow', safeTypeVersions: [1, 1.1, 1.2], requiredParams: [] },\n { type: 'n8n-nodes-base.respondToWebhook', safeTypeVersions: [1, 1.1], requiredParams: [] },\n { type: 'n8n-nodes-base.noOp', safeTypeVersions: [1], requiredParams: [] },\n { type: 'n8n-nodes-base.stopAndError', safeTypeVersions: [1], requiredParams: [] },\n { type: 'n8n-nodes-base.splitOut', safeTypeVersions: [1], requiredParams: [] },\n { type: 'n8n-nodes-base.aggregate', safeTypeVersions: [1], requiredParams: [] },\n { type: 'n8n-nodes-base.stickyNote', safeTypeVersions: [1], requiredParams: [] },\n\n // Email / messaging\n { type: 'n8n-nodes-base.emailSend', safeTypeVersions: [1, 2, 2.1], requiredParams: [], credentialType: 'smtp' },\n { type: 'n8n-nodes-base.slack', safeTypeVersions: [1, 2, 2.1, 2.2], requiredParams: [], credentialType: 'slackOAuth2Api' },\n { type: 'n8n-nodes-base.telegram', safeTypeVersions: [1, 1.1, 1.2], requiredParams: [], credentialType: 'telegramApi' },\n { type: 'n8n-nodes-base.discord', safeTypeVersions: [1, 2], requiredParams: [], credentialType: 'discordWebhookApi' },\n\n // Google\n { type: 'n8n-nodes-base.gmail', safeTypeVersions: [1, 2, 2.1], requiredParams: [], credentialType: 'gmailOAuth2' },\n { type: 'n8n-nodes-base.googleSheets', safeTypeVersions: [1, 2, 3, 4, 4.1, 4.2, 4.3, 4.4, 4.5], requiredParams: [], credentialType: 'googleSheetsOAuth2Api' },\n { type: 'n8n-nodes-base.googleDrive', safeTypeVersions: [1, 2, 3], requiredParams: [], credentialType: 'googleDriveOAuth2Api' },\n { type: 'n8n-nodes-base.googleCalendar', safeTypeVersions: [1, 1.1, 1.2, 1.3], requiredParams: [], credentialType: 'googleCalendarOAuth2Api' },\n\n // Project management / CRM\n { type: 'n8n-nodes-base.notion', safeTypeVersions: [1, 2, 2.1, 2.2], requiredParams: [], credentialType: 'notionApi' },\n { type: 'n8n-nodes-base.airtable', safeTypeVersions: [1, 2, 2.1], requiredParams: [], credentialType: 'airtableTokenApi' },\n { type: 'n8n-nodes-base.github', safeTypeVersions: [1, 1.1], requiredParams: [], credentialType: 'githubApi' },\n { type: 'n8n-nodes-base.jira', safeTypeVersions: [1], requiredParams: [], credentialType: 'jiraSoftwareCloudApi' },\n { type: 'n8n-nodes-base.hubspot', safeTypeVersions: [1, 2, 2.1], requiredParams: [], credentialType: 'hubspotOAuth2Api' },\n\n // Databases\n { type: 'n8n-nodes-base.postgres', safeTypeVersions: [1, 2, 2.1, 2.2, 2.3, 2.4, 2.5], requiredParams: [], credentialType: 'postgres' },\n { type: 'n8n-nodes-base.mySql', safeTypeVersions: [1, 2, 2.1, 2.2, 2.3, 2.4], requiredParams: [], credentialType: 'mySql' },\n { type: 'n8n-nodes-base.redis', safeTypeVersions: [1], requiredParams: [], credentialType: 'redis' },\n { type: 'n8n-nodes-base.supabase', safeTypeVersions: [1], requiredParams: [], credentialType: 'supabaseApi' },\n\n // Cloud\n { type: 'n8n-nodes-base.awsS3', safeTypeVersions: [1, 2], requiredParams: [], credentialType: 'aws' },\n\n // Payment / commerce\n { type: 'n8n-nodes-base.stripe', safeTypeVersions: [1], requiredParams: [], credentialType: 'stripeApi' },\n\n // AI / LangChain root nodes\n { type: '@n8n/n8n-nodes-langchain.agent', safeTypeVersions: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.chainLlm', safeTypeVersions: [1, 1.1, 1.2, 1.3, 1.4, 1.5], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.chainRetrievalQa', safeTypeVersions: [1, 1.1, 1.2, 1.3, 1.4], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.openAi', safeTypeVersions: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8], requiredParams: [], credentialType: 'openAiApi' },\n { type: '@n8n/n8n-nodes-langchain.anthropic', safeTypeVersions: [1], requiredParams: [], credentialType: 'anthropicApi' },\n { type: '@n8n/n8n-nodes-langchain.informationExtractor', safeTypeVersions: [1], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.textClassifier', safeTypeVersions: [1], requiredParams: [] },\n\n // AI / LangChain sub-nodes (models)\n { type: '@n8n/n8n-nodes-langchain.lmChatOpenAi', safeTypeVersions: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7], requiredParams: [], credentialType: 'openAiApi' },\n { type: '@n8n/n8n-nodes-langchain.lmChatAnthropic', safeTypeVersions: [1, 1.1, 1.2, 1.3], requiredParams: [], credentialType: 'anthropicApi' },\n { type: '@n8n/n8n-nodes-langchain.lmChatGoogleGemini', safeTypeVersions: [1], requiredParams: [], credentialType: 'googlePalmApi' },\n\n // AI / LangChain sub-nodes (memory, tools, etc.)\n { type: '@n8n/n8n-nodes-langchain.memoryBufferWindow', safeTypeVersions: [1, 1.1, 1.2, 1.3], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.toolWorkflow', safeTypeVersions: [1, 1.1, 1.2, 1.3], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.toolCode', safeTypeVersions: [1, 1.1], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.toolHttpRequest', safeTypeVersions: [1, 1.1], requiredParams: [] },\n { type: '@n8n/n8n-nodes-langchain.toolCalculator', safeTypeVersions: [1], requiredParams: [] },\n]\n\nexport class NodeRegistry {\n private readonly byType: Map<string, NodeDefinition>\n\n constructor(definitions: NodeDefinition[] = DEFAULT_REGISTRY) {\n this.byType = new Map(definitions.map((d) => [d.type, d]))\n }\n\n get(type: string): NodeDefinition | undefined {\n return this.byType.get(type)\n }\n\n isTrigger(type: string): boolean {\n return this.byType.get(type)?.isTrigger === true\n }\n\n isKnown(type: string): boolean {\n return this.byType.has(type)\n }\n\n isVersionSafe(type: string, version: number): boolean {\n const def = this.byType.get(type)\n if (!def) return true\n return def.safeTypeVersions.includes(version)\n }\n\n getRequiredParams(type: string): string[] {\n return this.byType.get(type)?.requiredParams ?? []\n }\n}\n","import type { N8nWorkflow, N8nNode } from '../types/workflow.js'\nimport type { ValidationIssue, ValidationResult } from './types.js'\nimport { NodeRegistry, DEFAULT_REGISTRY } from './registry.js'\nimport { FORBIDDEN_ON_CREATE } from '../providers/n8n/types.js'\n\nconst AI_CONNECTION_TYPES = [\n 'ai_languageModel',\n 'ai_memory',\n 'ai_tool',\n 'ai_outputParser',\n 'ai_embedding',\n 'ai_document',\n 'ai_textSplitter',\n 'ai_retriever',\n 'ai_vectorStore',\n]\n\nconst TRIGGER_TYPE_PATTERNS = [/trigger/i, /Trigger$/]\n\nconst NODE_TYPE_PATTERN = /^(@[a-z0-9-]+\\/[a-z0-9-]+\\.|n8n-nodes-[a-z0-9-]+\\.)[a-zA-Z][a-zA-Z0-9-]+$/\n\nexport class N8nValidator {\n private readonly registry: NodeRegistry\n\n constructor(registry: NodeRegistry = new NodeRegistry(DEFAULT_REGISTRY)) {\n this.registry = registry\n }\n\n validate(workflow: N8nWorkflow): ValidationResult {\n const issues: ValidationIssue[] = []\n\n this.checkRule1(workflow, issues)\n this.checkRule2(workflow, issues)\n this.checkRule3(workflow, issues)\n this.checkRule4(workflow, issues)\n this.checkRule5(workflow, issues)\n this.checkRule6(workflow, issues)\n this.checkRule7(workflow, issues)\n this.checkRule8(workflow, issues)\n this.checkRule9(workflow, issues)\n this.checkRule10(workflow, issues)\n this.checkRule11(workflow, issues)\n this.checkRule12(workflow, issues)\n this.checkRule13(workflow, issues)\n this.checkRule14(workflow, issues)\n this.checkRule15(workflow, issues)\n this.checkRule16(workflow, issues)\n this.checkRule17(workflow, issues)\n this.checkRule18(workflow, issues)\n this.checkRule19(workflow, issues)\n this.checkRule20(workflow, issues)\n this.checkRule21(workflow, issues)\n this.checkRule22(workflow, issues)\n this.checkRule23(workflow, issues)\n this.checkRule24(workflow, issues)\n this.checkRule25(workflow, issues)\n this.checkRule26(workflow, issues)\n\n // Enrich issues with nodeType by looking up nodeId\n if (Array.isArray(workflow.nodes)) {\n const nodeById = new Map(workflow.nodes.map(n => [n.id, n.type]))\n for (const issue of issues) {\n if (issue.nodeId && !issue.nodeType) {\n const nt = nodeById.get(issue.nodeId)\n if (nt) issue.nodeType = nt\n }\n }\n }\n\n const errors = issues.filter((i) => i.severity === 'error')\n return { valid: errors.length === 0, issues }\n }\n\n private err(issues: ValidationIssue[], rule: number, message: string, nodeId?: string, nodeType?: string): void {\n const issue: ValidationIssue = { rule, severity: 'error', message }\n if (nodeId !== undefined) issue.nodeId = nodeId\n if (nodeType !== undefined) issue.nodeType = nodeType\n issues.push(issue)\n }\n\n private warn(issues: ValidationIssue[], rule: number, message: string, nodeId?: string, nodeType?: string): void {\n const issue: ValidationIssue = { rule, severity: 'warn', message }\n if (nodeId !== undefined) issue.nodeId = nodeId\n if (nodeType !== undefined) issue.nodeType = nodeType\n issues.push(issue)\n }\n\n private isTriggerNode(node: N8nNode): boolean {\n if (this.registry.isTrigger(node.type)) return true\n return TRIGGER_TYPE_PATTERNS.some((p) => p.test(node.type))\n }\n\n // Rule 1: name is a non-empty string\n private checkRule1(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (typeof w.name !== 'string' || w.name.trim() === '') {\n this.err(issues, 1, 'Workflow name is required and must be a non-empty string')\n }\n }\n\n // Rule 2: nodes is an array with at least one element\n private checkRule2(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes) || w.nodes.length === 0) {\n this.err(issues, 2, 'Workflow must have at least one node')\n }\n }\n\n // Rule 3: every node has a non-empty id\n private checkRule3(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.id !== 'string' || node.id.trim() === '') {\n this.err(issues, 3, `Node \"${node.name ?? 'unknown'}\" is missing a valid id`, node.id)\n }\n }\n }\n\n // Rule 4: node ids are unique\n private checkRule4(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const seen = new Set<string>()\n for (const node of w.nodes) {\n if (!node.id) continue\n if (seen.has(node.id)) {\n this.err(issues, 4, `Duplicate node id: \"${node.id}\"`, node.id)\n }\n seen.add(node.id)\n }\n }\n\n // Rule 5: every node has a non-empty type string\n private checkRule5(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.type !== 'string' || node.type.trim() === '') {\n this.err(issues, 5, `Node \"${node.name ?? node.id}\" is missing a type`, node.id)\n }\n }\n }\n\n // Rule 6: every node has a positive typeVersion number\n private checkRule6(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.typeVersion !== 'number' || node.typeVersion <= 0) {\n this.err(issues, 6, `Node \"${node.name}\" has invalid typeVersion: ${String(node.typeVersion)}`, node.id)\n }\n }\n }\n\n // Rule 7: every node has a valid [x, y] position\n private checkRule7(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n const pos = node.position\n if (\n !Array.isArray(pos) ||\n pos.length !== 2 ||\n typeof pos[0] !== 'number' ||\n typeof pos[1] !== 'number'\n ) {\n this.err(issues, 7, `Node \"${node.name}\" has invalid position (must be [x, y])`, node.id)\n }\n }\n }\n\n // Rule 8: every node has a non-empty name\n private checkRule8(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.name !== 'string' || node.name.trim() === '') {\n this.err(issues, 8, `Node with id \"${node.id}\" is missing a name`, node.id)\n }\n }\n }\n\n // Rule 9: connections is a plain object\n private checkRule9(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (typeof w.connections !== 'object' || w.connections === null || Array.isArray(w.connections)) {\n this.err(issues, 9, 'connections must be a plain object (use {} for single-node workflows)')\n }\n }\n\n // Rule 10: every connection target node name exists in nodes\n private checkRule10(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes) || typeof w.connections !== 'object' || w.connections === null) return\n const nodeNames = new Set(w.nodes.map((n) => n.name))\n for (const [sourceName, outputs] of Object.entries(w.connections)) {\n if (!nodeNames.has(sourceName)) {\n this.err(issues, 10, `Connection source \"${sourceName}\" does not exist in nodes`)\n continue\n }\n if (typeof outputs !== 'object' || outputs === null) continue\n for (const portGroup of Object.values(outputs)) {\n if (!Array.isArray(portGroup)) continue\n for (const targets of portGroup) {\n if (!Array.isArray(targets)) continue\n for (const target of targets) {\n const t = target as { node?: string }\n if (typeof t?.node === 'string' && !nodeNames.has(t.node)) {\n this.err(issues, 10, `Connection target \"${t.node}\" does not exist in nodes`)\n }\n }\n }\n }\n }\n }\n\n // Rule 11 (WARN): every non-trigger node has at least one incoming connection\n private checkRule11(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes) || typeof w.connections !== 'object' || w.connections === null) return\n const reachable = new Set<string>()\n // Track nodes that are sources of ai_* connections — they are purposefully\n // connectionless on main; they feed the agent as sub-nodes.\n const aiSubNodeSources = new Set<string>()\n for (const [sourceName, outputs] of Object.entries(w.connections)) {\n if (typeof outputs !== 'object' || outputs === null) continue\n let hasAiPort = false\n for (const [portName, portGroup] of Object.entries(outputs)) {\n if (!Array.isArray(portGroup)) continue\n const isAiPort = portName.startsWith('ai_')\n if (isAiPort) hasAiPort = true\n for (const targets of portGroup) {\n if (!Array.isArray(targets)) continue\n for (const target of targets) {\n const t = target as { node?: string }\n if (typeof t?.node === 'string') reachable.add(t.node)\n }\n }\n }\n if (hasAiPort) aiSubNodeSources.add(sourceName)\n }\n for (const node of w.nodes) {\n if (node.type.includes('stickyNote')) continue\n if (this.isTriggerNode(node)) continue\n if (aiSubNodeSources.has(node.name)) continue\n if (!reachable.has(node.name)) {\n this.warn(issues, 11, `Node \"${node.name}\" has no incoming connections and may never execute`, node.id)\n }\n }\n }\n\n // Rule 12: forbidden fields absent from workflow root\n private checkRule12(w: N8nWorkflow, issues: ValidationIssue[]): void {\n const wObj = w as unknown as Record<string, unknown>\n for (const field of FORBIDDEN_ON_CREATE) {\n if (field in wObj) {\n this.err(issues, 12, `Forbidden field \"${field}\" present in workflow — remove it before deploying`)\n }\n }\n }\n\n // Rule 13: settings, if present, is a plain object\n private checkRule13(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (w.settings !== undefined) {\n if (typeof w.settings !== 'object' || w.settings === null || Array.isArray(w.settings)) {\n this.err(issues, 13, 'workflow.settings must be a plain object')\n }\n }\n }\n\n // Rule 14: at least one trigger node is present\n private checkRule14(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const hasTrigger = w.nodes.some((n) => this.isTriggerNode(n))\n if (!hasTrigger) {\n this.err(issues, 14, 'Workflow must contain at least one trigger node')\n }\n }\n\n // Rule 15: node type string matches expected format\n private checkRule15(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.type !== 'string') continue\n if (!NODE_TYPE_PATTERN.test(node.type)) {\n this.err(issues, 15, `Node \"${node.name}\" has malformed type string: \"${node.type}\"`, node.id)\n }\n }\n }\n\n // Rule 16: node names are unique within the workflow\n private checkRule16(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const seen = new Set<string>()\n for (const node of w.nodes) {\n if (!node.name) continue\n if (seen.has(node.name)) {\n this.err(issues, 16, `Duplicate node name: \"${node.name}\"`, node.id)\n }\n seen.add(node.name)\n }\n }\n\n // Rule 17: credentials shape — each entry has id and name\n private checkRule17(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (!node.credentials) continue\n for (const [credType, credRef] of Object.entries(node.credentials)) {\n if (typeof credRef !== 'object' || credRef === null) {\n this.err(issues, 17, `Node \"${node.name}\" credential \"${credType}\" must be an object with id and name`, node.id)\n continue\n }\n const ref = credRef as unknown as Record<string, unknown>\n if (\n typeof ref['id'] !== 'string' || ref['id'].trim() === '' ||\n typeof ref['name'] !== 'string' || ref['name'].trim() === ''\n ) {\n this.err(issues, 17, `Node \"${node.name}\" credential \"${credType}\" must have non-empty string id and name fields`, node.id)\n }\n }\n }\n }\n\n // Rule 18 (ERROR): AI connections must originate from sub-nodes, not the agent/chain root\n private checkRule18(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (typeof w.connections !== 'object' || w.connections === null) return\n const agentTypes = new Set([\n '@n8n/n8n-nodes-langchain.agent',\n '@n8n/n8n-nodes-langchain.chainLlm',\n '@n8n/n8n-nodes-langchain.chainRetrievalQa',\n '@n8n/n8n-nodes-langchain.chainSummarization',\n ])\n if (!Array.isArray(w.nodes)) return\n const nodesByName = new Map(w.nodes.map((n) => [n.name, n]))\n\n for (const [sourceName, outputs] of Object.entries(w.connections)) {\n const sourceNode = nodesByName.get(sourceName)\n if (!sourceNode) continue\n if (!agentTypes.has(sourceNode.type)) continue\n if (typeof outputs !== 'object' || outputs === null) continue\n for (const connType of AI_CONNECTION_TYPES) {\n if (connType in outputs) {\n this.err(\n issues,\n 18,\n `Node \"${sourceName}\" uses AI connection type \"${connType}\" as a SOURCE — AI sub-nodes should be the source, not the agent/chain root`,\n sourceNode.id,\n )\n }\n }\n }\n }\n\n // Rule 19 (WARN): typeVersion is within known safe range for registered node types\n private checkRule19(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.type !== 'string' || typeof node.typeVersion !== 'number') continue\n if (!this.registry.isVersionSafe(node.type, node.typeVersion)) {\n this.warn(\n issues,\n 19,\n `Node \"${node.name}\" uses typeVersion ${node.typeVersion} for type \"${node.type}\" which is not in the known safe list`,\n node.id,\n )\n }\n }\n }\n\n // Rule 20 (WARN): cycle detection — no node should be reachable from itself\n // Exempts splitInBatches loops which are an intentional n8n pattern\n private checkRule20(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes) || typeof w.connections !== 'object' || w.connections === null) return\n\n const splitBatchNodes = new Set(\n w.nodes.filter((n) => n.type.includes('splitInBatches')).map((n) => n.name),\n )\n\n const adj = new Map<string, string[]>()\n for (const [sourceName, outputs] of Object.entries(w.connections)) {\n if (typeof outputs !== 'object' || outputs === null) continue\n const targets: string[] = []\n for (const portGroup of Object.values(outputs)) {\n if (!Array.isArray(portGroup)) continue\n for (const conns of portGroup) {\n if (!Array.isArray(conns)) continue\n for (const conn of conns) {\n const t = conn as { node?: string }\n if (typeof t?.node === 'string') {\n if (splitBatchNodes.has(t.node)) continue\n targets.push(t.node)\n }\n }\n }\n }\n adj.set(sourceName, targets)\n }\n\n const WHITE = 0, GRAY = 1, BLACK = 2\n const color = new Map<string, number>()\n for (const node of w.nodes) color.set(node.name, WHITE)\n\n const dfs = (name: string): boolean => {\n color.set(name, GRAY)\n for (const neighbor of adj.get(name) ?? []) {\n const c = color.get(neighbor)\n if (c === GRAY) return true\n if (c === WHITE && dfs(neighbor)) return true\n }\n color.set(name, BLACK)\n return false\n }\n\n for (const node of w.nodes) {\n if (color.get(node.name) === WHITE && dfs(node.name)) {\n this.warn(issues, 20, 'Workflow contains a connection cycle — this may cause infinite loops')\n return\n }\n }\n }\n\n // Rule 22 (WARN): check requiredParams from registry\n private checkRule22(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.type !== 'string') continue\n const required = this.registry.getRequiredParams(node.type)\n if (required.length === 0) continue\n const params = (node.parameters ?? {}) as Record<string, unknown>\n for (const param of required) {\n const value = params[param]\n if (value === undefined || value === null || value === '') {\n this.warn(\n issues,\n 22,\n `Node \"${node.name}\" (${node.type}) is missing required parameter \"${param}\"`,\n node.id,\n )\n }\n }\n }\n }\n\n // Rule 23 (WARN): unknown node types not in registry\n private checkRule23(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n for (const node of w.nodes) {\n if (typeof node.type !== 'string') continue\n if (node.type.includes('stickyNote')) continue\n if (!NODE_TYPE_PATTERN.test(node.type)) continue\n if (!this.registry.isKnown(node.type)) {\n this.warn(\n issues,\n 23,\n `Node \"${node.name}\" uses unknown type \"${node.type}\" — it may not exist in n8n`,\n node.id,\n )\n }\n }\n }\n\n // Rule 24 (WARN): deprecated accessor syntax in expressions\n private checkRule24(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const deprecated = /\\$node\\s*\\[/\n for (const node of w.nodes) {\n for (const expr of this.extractExpressions(node.parameters)) {\n if (deprecated.test(expr)) {\n this.warn(\n issues,\n 24,\n `Node \"${node.name}\" uses deprecated accessor $node[\"...\"] — use $('NodeName').item.json.field instead`,\n node.id,\n )\n break\n }\n }\n }\n }\n\n // Rule 25 (WARN): wrong item index assumptions in expressions\n private checkRule25(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const itemIndex = /\\$json\\s*\\.\\s*items\\s*\\[/\n for (const node of w.nodes) {\n for (const expr of this.extractExpressions(node.parameters)) {\n if (itemIndex.test(expr)) {\n this.warn(\n issues,\n 25,\n `Node \"${node.name}\" accesses $json.items[n] — n8n flattens items automatically, use $json.field directly`,\n node.id,\n )\n break\n }\n }\n }\n }\n\n // Rule 26 (WARN): missing .first() or .all() on node references\n private checkRule26(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n const bareRef = /\\$\\(\\s*'[^']+'\\s*\\)\\s*\\.json/\n for (const node of w.nodes) {\n for (const expr of this.extractExpressions(node.parameters)) {\n if (bareRef.test(expr)) {\n this.warn(\n issues,\n 26,\n `Node \"${node.name}\" references $('NodeName').json without .first() or .all() — use $('NodeName').first().json.field`,\n node.id,\n )\n break\n }\n }\n }\n }\n\n private extractExpressions(params: Record<string, unknown>): string[] {\n const expressions: string[] = []\n const walk = (val: unknown): void => {\n if (typeof val === 'string') {\n if (val.includes('={{') || val.includes('$node') || val.includes(\"$('\")) {\n expressions.push(val)\n }\n } else if (Array.isArray(val)) {\n for (const item of val) walk(item)\n } else if (val !== null && typeof val === 'object') {\n for (const v of Object.values(val as Record<string, unknown>)) walk(v)\n }\n }\n walk(params)\n return expressions\n }\n\n // Rule 21 (WARN): webhook with responseMode=\"responseNode\" must have respondToWebhook node\n private checkRule21(w: N8nWorkflow, issues: ValidationIssue[]): void {\n if (!Array.isArray(w.nodes)) return\n\n const webhooksNeedingResponse = w.nodes.filter((n) => {\n if (!n.type.includes('webhook')) return false\n const params = n.parameters as Record<string, unknown> | undefined\n return params?.responseMode === 'responseNode'\n })\n\n if (webhooksNeedingResponse.length === 0) return\n\n const hasRespondNode = w.nodes.some((n) => n.type.includes('respondToWebhook'))\n if (!hasRespondNode) {\n for (const wh of webhooksNeedingResponse) {\n this.warn(\n issues,\n 21,\n `Webhook \"${wh.name}\" uses responseMode \"responseNode\" but no respondToWebhook node exists in the workflow`,\n wh.id,\n )\n }\n }\n }\n}\n","import { appendFile, mkdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { generateUUID } from '../utils/uuid.js'\nimport type { TelemetryEvent } from './types.js'\nimport { TELEMETRY_SCHEMA_VERSION } from './types.js'\n\nexport class TelemetryCollector {\n private readonly dir: string\n readonly sessionId: string\n private dirReady: Promise<void> | null = null\n\n constructor(dir?: string) {\n this.dir = dir ?? join(homedir(), '.kairos', 'telemetry')\n this.sessionId = generateUUID()\n }\n\n async emit(eventType: TelemetryEvent['eventType'], data: Record<string, unknown>, runId?: string): Promise<void> {\n const event: TelemetryEvent = {\n schemaVersion: TELEMETRY_SCHEMA_VERSION,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n ...(runId ? { runId } : {}),\n eventType,\n data,\n }\n\n if (!this.dirReady) {\n this.dirReady = mkdir(this.dir, { recursive: true }).then(() => {})\n }\n await this.dirReady\n const filename = new Date().toISOString().slice(0, 10) + '.jsonl'\n const filepath = join(this.dir, filename)\n await appendFile(filepath, JSON.stringify(event) + '\\n', 'utf-8')\n }\n}\n","import type { ValidationIssue } from '../errors/validation-error.js'\n\nexport interface TelemetryEvent {\n schemaVersion: number\n timestamp: string\n sessionId: string\n runId?: string\n eventType: 'build_start' | 'generation_attempt' | 'build_complete'\n data: Record<string, unknown>\n}\n\nexport const TELEMETRY_SCHEMA_VERSION = 2\n\nexport interface AttemptMetadata {\n attempt: number\n temperature: number\n durationMs: number\n tokensInput: number\n tokensOutput: number\n validationPassed: boolean\n issues: ValidationIssue[]\n}\n\nexport interface BuildStartData {\n description: string\n model: string\n dryRun: boolean\n}\n\nexport interface GenerationAttemptData {\n description: string\n attempt: number\n temperature: number\n durationMs: number\n tokensInput: number\n tokensOutput: number\n validationPassed: boolean\n issueCount: number\n issues: Array<{ rule: number; severity: 'error' | 'warn'; message: string; nodeId?: string | null; nodeType?: string | null }>\n workflowType?: string | null\n}\n\nexport interface BuildCompleteData {\n description: string\n success: boolean\n totalAttempts: number\n totalDurationMs: number\n totalTokensInput: number\n totalTokensOutput: number\n workflowName: string | null\n workflowId: string | null\n dryRun: boolean\n credentialsNeeded: number\n warnedRules: number[]\n workflowType?: string | null\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { readTelemetryEvents } from './event-reader.js'\n\nexport interface RuleFailureRate {\n rule: number\n failureCount: number\n totalBuilds: number\n rate: number\n commonMessage: string\n}\n\nexport class TelemetryReader {\n private readonly dir: string\n private cache: RuleFailureRate[] | null = null\n private cacheTime = 0\n\n constructor(dir?: string) {\n this.dir = dir ?? join(homedir(), '.kairos', 'telemetry')\n }\n\n async getFailureRates(days = 30): Promise<RuleFailureRate[]> {\n const now = Date.now()\n if (this.cache && now - this.cacheTime < 5 * 60 * 1000) {\n return this.cache\n }\n\n const events = await this.readRecentEvents(days)\n\n const buildSessions = new Set(\n events\n .filter((e) => e.eventType === 'build_complete')\n .map((e) => e.sessionId),\n )\n const MIN_BUILDS_FOR_RATES = 3\n if (buildSessions.size < MIN_BUILDS_FOR_RATES) return []\n\n const ruleSessions = new Map<number, { sessions: Set<string>; messages: Map<string, number> }>()\n\n for (const event of events) {\n if (event.eventType !== 'generation_attempt') continue\n if (!buildSessions.has(event.sessionId)) continue\n const data = event.data as { validationPassed?: boolean; issues?: Array<{ rule: number; message: string }> }\n if (data.validationPassed || !data.issues) continue\n\n for (const issue of data.issues) {\n const entry = ruleSessions.get(issue.rule) ?? { sessions: new Set(), messages: new Map() }\n entry.sessions.add(event.sessionId)\n entry.messages.set(issue.message, (entry.messages.get(issue.message) ?? 0) + 1)\n ruleSessions.set(issue.rule, entry)\n }\n }\n\n const rates: RuleFailureRate[] = []\n for (const [rule, entry] of ruleSessions) {\n let topMessage = ''\n let topCount = 0\n for (const [msg, count] of entry.messages) {\n if (count > topCount) {\n topMessage = msg\n topCount = count\n }\n }\n rates.push({\n rule,\n failureCount: entry.sessions.size,\n totalBuilds: buildSessions.size,\n rate: entry.sessions.size / buildSessions.size,\n commonMessage: topMessage,\n })\n }\n\n rates.sort((a, b) => b.rate - a.rate)\n this.cache = rates\n this.cacheTime = now\n return rates\n }\n\n private async readRecentEvents(days: number) {\n return readTelemetryEvents(this.dir, days)\n }\n}\n","import { readdir } from 'node:fs/promises'\nimport { createReadStream } from 'node:fs'\nimport { join } from 'node:path'\nimport { createInterface } from 'node:readline'\n\nexport interface RawTelemetryEvent {\n eventType: string\n sessionId: string\n runId?: string\n data: Record<string, unknown>\n fileDate: string\n}\n\nexport async function readTelemetryEvents(dir: string, days: number): Promise<RawTelemetryEvent[]> {\n let files: string[]\n try {\n files = await readdir(dir)\n } catch {\n return []\n }\n\n const cutoff = new Date()\n cutoff.setDate(cutoff.getDate() - days)\n const cutoffStr = cutoff.toISOString().slice(0, 10)\n\n const todayStr = new Date().toISOString().slice(0, 10)\n const datePattern = /^\\d{4}-\\d{2}-\\d{2}\\.jsonl$/\n const recentFiles = files\n .filter(f => datePattern.test(f) && f >= cutoffStr && f <= `${todayStr}.jsonl`)\n .sort()\n\n const events: RawTelemetryEvent[] = []\n for (const file of recentFiles) {\n const fileDate = file.replace('.jsonl', '')\n try {\n const rl = createInterface({\n input: createReadStream(join(dir, file), 'utf-8'),\n crlfDelay: Infinity,\n })\n for await (const line of rl) {\n if (!line.trim()) continue\n try {\n events.push({ ...JSON.parse(line), fileDate })\n } catch { /* skip malformed */ }\n }\n } catch { /* skip unreadable */ }\n }\n return events\n}\n","import { writeFile, readFile as fsReadFile, appendFile, mkdir, rename } from 'node:fs/promises'\nimport { readTelemetryEvents } from './event-reader.js'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { RULE_MITIGATIONS, RULE_PIPELINE_STAGES, VALIDATOR_RULE_IDS, type PipelineStage } from '../validation/rule-metadata.js'\n\nexport interface CredentialFailure {\n type: string\n count: number\n}\n\nexport type PatternState = 'draft' | 'confirmed' | 'resolved'\nexport type PatternTrend = 'new' | 'worsening' | 'stable' | 'improving'\nexport type { PipelineStage } from '../validation/rule-metadata.js'\n\nexport interface ScoringFactors {\n rawConfidence: number\n impact: number\n recency: number\n stickinessBoost: number\n}\n\nexport interface Pattern {\n rule: number\n failureCount: number\n confidence: number\n compositeScore: number\n scoringFactors: ScoringFactors\n state: PatternState\n trend: PatternTrend\n pipelineStage: PipelineStage\n exampleMessages: string[]\n mitigation: string | null\n resolvedAt?: string\n regressed?: boolean\n workflowTypeBreakdown?: Record<string, number>\n}\n\nexport interface DriftAlert {\n type: 'stale_pattern' | 'uncovered_rule' | 'missing_mitigation' | 'missing_stage_mapping'\n rule: number\n message: string\n}\n\nexport interface DriftReport {\n healthy: boolean\n alerts: DriftAlert[]\n coveredRules: number\n totalRules: number\n}\n\nexport interface WarningEffectiveness {\n rule: number\n timesWarned: number\n timesWarnedAndPassed: number\n timesWarnedAndFailed: number\n effectivenessRate: number\n}\n\nexport interface SessionSummary {\n sessionId: string\n date: string\n description: string\n workflowType: string | null\n attempts: number\n success: boolean\n failedRules: number[]\n workflowName: string | null\n}\n\nexport interface PatternAnalysis {\n schemaVersion: number\n generatedAt: string\n summary: {\n totalBuilds: number\n totalAttempts: number\n firstTryPassRate: number\n correctionRate: number\n singleAttemptFailRate: number\n avgDurationMs: number\n totalTokensInput: number\n totalTokensOutput: number\n attemptDistribution?: Record<number, number>\n }\n topFailureRules: Pattern[]\n failingCredentialTypes: CredentialFailure[]\n drift: DriftReport\n warningEffectiveness: WarningEffectiveness[]\n ruleCoOccurrence?: Array<{ rules: [number, number]; count: number }>\n}\n\nconst PATTERN_SCHEMA_VERSION = 2\n\n\nexport class PatternAnalyzer {\n private readonly telemetryDir: string\n private readonly outputDir: string\n private _cachedEvents: Awaited<ReturnType<typeof readTelemetryEvents>> | null = null\n\n constructor(telemetryDir?: string) {\n const defaultDir = join(homedir(), '.kairos', 'telemetry')\n this.telemetryDir = telemetryDir ?? defaultDir\n this.outputDir = telemetryDir\n ? join(telemetryDir, '..')\n : join(homedir(), '.kairos')\n }\n\n private async loadPreviousPatterns(): Promise<Pattern[]> {\n try {\n const raw = await fsReadFile(join(this.outputDir, 'patterns.json'), 'utf-8')\n const prev = JSON.parse(raw) as PatternAnalysis & { schemaVersion?: number }\n const version = prev.schemaVersion ?? 0\n const patterns = prev.topFailureRules ?? []\n if (version === PATTERN_SCHEMA_VERSION) return patterns\n return this.migratePatterns(patterns, version)\n } catch {\n return []\n }\n }\n\n private migratePatterns(patterns: Pattern[], fromVersion: number): Pattern[] {\n let migrated = patterns\n if (fromVersion < 1) {\n migrated = migrated.map(p => ({\n ...p,\n compositeScore: p.compositeScore ?? 0,\n scoringFactors: p.scoringFactors ?? { rawConfidence: 0, impact: 0, recency: 0, stickinessBoost: 0 },\n pipelineStage: p.pipelineStage ?? ('node_generation' as PipelineStage),\n }))\n }\n if (fromVersion < 2) {\n migrated = migrated.map(p => {\n const sf = p.scoringFactors ?? { rawConfidence: 0, impact: 0, recency: 0, stickinessBoost: 0 }\n return {\n ...p,\n scoringFactors: {\n ...sf,\n stickinessBoost: sf.stickinessBoost ?? (sf as unknown as Record<string, number>)['validationBoost'] ?? 0,\n },\n }\n })\n }\n return migrated\n }\n\n async analyze(days = 30): Promise<PatternAnalysis> {\n const previousPatterns = await this.loadPreviousPatterns()\n const events = await this.readAllEvents(days)\n this._cachedEvents = events\n\n const starts = events.filter(e => e.eventType === 'build_start')\n const attempts = events.filter(e => e.eventType === 'generation_attempt')\n\n const passed = attempts.filter(a =>\n (a.data as { validationPassed?: boolean }).validationPassed === true\n )\n const failed = attempts.filter(a =>\n (a.data as { validationPassed?: boolean }).validationPassed === false\n )\n\n const ruleFailures = new Map<number, { count: number; sessions: Set<string>; recencyWeights: number[]; allMessages: string[]; workflowTypes: Map<string, number> }>()\n const credentialFailures = new Map<string, number>()\n\n for (const a of failed) {\n const weight = this.recencyWeight(a.fileDate)\n const buildId = a.runId ?? a.sessionId\n const data = a.data as { issues?: Array<{ rule: number; severity?: string; message: string }>; workflowType?: string | null }\n for (const issue of data.issues ?? []) {\n if (issue.severity === 'warn') continue\n const entry = ruleFailures.get(issue.rule) ?? { count: 0, sessions: new Set<string>(), recencyWeights: [], allMessages: [], workflowTypes: new Map<string, number>() }\n entry.count++\n entry.sessions.add(buildId)\n entry.recencyWeights.push(weight)\n entry.allMessages.push(issue.message)\n if (data.workflowType) {\n entry.workflowTypes.set(data.workflowType, (entry.workflowTypes.get(data.workflowType) ?? 0) + 1)\n }\n ruleFailures.set(issue.rule, entry)\n\n if (issue.rule === 17) {\n const credPatterns = [\n /credential\\s+\"([^\"]+)\"/,\n /credentialType[:\\s]+\"?([^\"'\\s]+)\"?/,\n /missing\\s+credential\\s+(?:for\\s+)?[\"']?([^\"'\\s]+)/i,\n ]\n let credType = 'unknown'\n for (const re of credPatterns) {\n const m = issue.message.match(re)\n if (m?.[1]) { credType = m[1]; break }\n }\n credentialFailures.set(credType, (credentialFailures.get(credType) ?? 0) + 1)\n }\n }\n }\n\n // Event-weighted midpoint: find date where ~50% of failed events occurred before it\n const failedByDate = new Map<string, number>()\n for (const a of failed) {\n failedByDate.set(a.fileDate, (failedByDate.get(a.fileDate) ?? 0) + 1)\n }\n const sortedFailDates = [...failedByDate.entries()].sort((a, b) => a[0].localeCompare(b[0]))\n const hasTrendData = sortedFailDates.length >= 3\n let midDate = ''\n if (hasTrendData) {\n const halfTotal = failed.length / 2\n let cumulative = 0\n for (const [date, count] of sortedFailDates) {\n cumulative += count\n if (cumulative >= halfTotal) { midDate = date; break }\n }\n }\n const ruleTrends = new Map<number, { older: number; newer: number }>()\n if (hasTrendData) {\n for (const a of failed) {\n const data = a.data as { issues?: Array<{ rule: number }> }\n const isNewer = a.fileDate > midDate\n for (const issue of data.issues ?? []) {\n const entry = ruleTrends.get(issue.rule) ?? { older: 0, newer: 0 }\n if (isNewer) entry.newer++\n else entry.older++\n ruleTrends.set(issue.rule, entry)\n }\n }\n }\n\n const sessions = new Map<string, typeof attempts>()\n for (const a of attempts) {\n const buildId = a.runId ?? a.sessionId\n const list = sessions.get(buildId) ?? []\n list.push(a)\n sessions.set(buildId, list)\n }\n\n let firstTryPass = 0\n let correctionNeeded = 0\n let singleAttemptFail = 0\n for (const sessionAttempts of sessions.values()) {\n const lastAttempt = sessionAttempts[sessionAttempts.length - 1]!\n const lastPassed = (lastAttempt.data as { validationPassed?: boolean }).validationPassed === true\n\n if (sessionAttempts.length === 1 && lastPassed) {\n firstTryPass++\n } else if (sessionAttempts.length > 1 && lastPassed) {\n correctionNeeded++\n } else {\n singleAttemptFail++\n }\n }\n\n const durations = attempts\n .map(a => (a.data as { durationMs?: number }).durationMs)\n .filter((d): d is number => typeof d === 'number' && d > 0)\n const avgDuration = durations.length > 0\n ? durations.reduce((s, d) => s + d, 0) / durations.length\n : 0\n\n const totalInput = attempts.reduce((s, a) =>\n s + ((a.data as { tokensInput?: number }).tokensInput ?? 0), 0)\n const totalOutput = attempts.reduce((s, a) =>\n s + ((a.data as { tokensOutput?: number }).tokensOutput ?? 0), 0)\n\n const totalSessions = Math.max(sessions.size, 1)\n\n // Stickiness: rules that persist across consecutive failed attempts within a build (LLM can't self-correct)\n const stickinessCount = new Map<number, number>()\n for (const sessionAttempts of sessions.values()) {\n if (sessionAttempts.length < 2) continue\n for (let i = 0; i < sessionAttempts.length - 1; i++) {\n const curr = sessionAttempts[i]!.data as { validationPassed?: boolean; issues?: Array<{ rule: number }> }\n const next = sessionAttempts[i + 1]!.data as { validationPassed?: boolean; issues?: Array<{ rule: number }> }\n if (curr.validationPassed !== false || next.validationPassed !== false) continue\n const currRules = new Set((curr.issues ?? []).map(iss => iss.rule))\n const nextRules = new Set((next.issues ?? []).map(iss => iss.rule))\n for (const rule of currRules) {\n if (nextRules.has(rule)) {\n stickinessCount.set(rule, (stickinessCount.get(rule) ?? 0) + 1)\n }\n }\n }\n }\n\n const CONFIRMED_THRESHOLD = 3\n const BUILDS_SINCE_LAST_FAILURE_THRESHOLD = 5\n const RESOLVED_TTL_DAYS = 90\n\n const activePatterns: Pattern[] = [...ruleFailures.entries()]\n .map(([rule, entry]) => {\n const t = ruleTrends.get(rule) ?? { older: 0, newer: 0 }\n const rawConfidence = Math.min(entry.sessions.size / totalSessions, 1)\n const state = (entry.count >= CONFIRMED_THRESHOLD ? 'confirmed' : 'draft') as PatternState\n const avgRecency = entry.recencyWeights.length > 0\n ? entry.recencyWeights.reduce((s, w) => s + w, 0) / entry.recencyWeights.length\n : 1\n const stickiness = stickinessCount.get(rule) ?? 0\n const { compositeScore, factors } = this.computeCompositeScore(rawConfidence, entry.count, state, avgRecency, stickiness)\n\n const pattern: Pattern = {\n rule,\n failureCount: entry.count,\n confidence: Math.round(rawConfidence * 1000) / 1000,\n compositeScore,\n scoringFactors: factors,\n state,\n trend: this.classifyTrend(t.older, t.newer),\n pipelineStage: RULE_PIPELINE_STAGES[rule] ?? 'node_generation' as PipelineStage,\n exampleMessages: this.deduplicateMessages(entry.allMessages),\n mitigation: RULE_MITIGATIONS[rule] ?? null,\n }\n\n if (entry.workflowTypes.size > 0) {\n pattern.workflowTypeBreakdown = Object.fromEntries(entry.workflowTypes)\n }\n\n return pattern\n })\n .sort((a, b) => b.compositeScore - a.compositeScore)\n\n const activeRules = new Set(activePatterns.map(p => p.rule))\n\n // Detect regressions: previously resolved rules that are failing again\n for (const p of activePatterns) {\n const prev = previousPatterns.find(pp => pp.rule === p.rule)\n if (prev?.state === 'resolved') {\n p.trend = 'worsening' as PatternTrend\n p.regressed = true\n }\n }\n\n // Per-rule last failure date for resolved threshold\n const ruleLastFailureDate = new Map<number, string>()\n for (const a of failed) {\n const data = a.data as { issues?: Array<{ rule: number }> }\n for (const issue of data.issues ?? []) {\n const existing = ruleLastFailureDate.get(issue.rule)\n if (!existing || a.fileDate > existing) {\n ruleLastFailureDate.set(issue.rule, a.fileDate)\n }\n }\n }\n\n // Newly resolved: previously confirmed, no longer failing, enough builds since last failure\n const newlyResolved: Pattern[] = previousPatterns\n .filter(p => {\n if (p.state !== 'confirmed' || activeRules.has(p.rule)) return false\n const lastFailDate = ruleLastFailureDate.get(p.rule) ?? ''\n const buildsSince = starts.filter(s => s.fileDate > lastFailDate).length\n return buildsSince >= BUILDS_SINCE_LAST_FAILURE_THRESHOLD\n })\n .map(p => ({\n ...p,\n state: 'resolved' as PatternState,\n trend: 'improving' as PatternTrend,\n pipelineStage: p.pipelineStage ?? RULE_PIPELINE_STAGES[p.rule] ?? 'node_generation' as PipelineStage,\n confidence: 0,\n compositeScore: 0,\n scoringFactors: { rawConfidence: 0, impact: 0, recency: 0, stickinessBoost: 0 },\n failureCount: 0,\n resolvedAt: new Date().toISOString(),\n }))\n\n // Carry forward resolved patterns within TTL\n const ttlCutoff = new Date()\n ttlCutoff.setDate(ttlCutoff.getDate() - RESOLVED_TTL_DAYS)\n const ttlCutoffStr = ttlCutoff.toISOString()\n\n const carriedResolved: Pattern[] = previousPatterns\n .filter(p => p.state === 'resolved' && !activeRules.has(p.rule)\n && (!p.resolvedAt || p.resolvedAt >= ttlCutoffStr))\n .map(p => ({ ...p }))\n\n // Carry forward confirmed patterns not yet meeting resolved threshold\n const newlyResolvedRules = new Set(newlyResolved.map(p => p.rule))\n const pendingResolution: Pattern[] = previousPatterns\n .filter(p => p.state === 'confirmed' && !activeRules.has(p.rule)\n && !newlyResolvedRules.has(p.rule))\n .map(p => ({ ...p }))\n\n const deduped = [\n ...newlyResolved,\n ...carriedResolved.filter(p => !newlyResolvedRules.has(p.rule)),\n ...pendingResolution,\n ]\n\n const patterns = [...activePatterns, ...deduped]\n\n const credTypes: CredentialFailure[] = [...credentialFailures.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([type, count]) => ({ type, count }))\n\n const drift = this.detectDrift(patterns)\n\n // Warning effectiveness: track how often warned rules were prevented\n const warnEffMap = new Map<number, { warned: number; passed: number; failed: number }>()\n const buildCompletes = events.filter(e => e.eventType === 'build_complete')\n for (const bc of buildCompletes) {\n const bcData = bc.data as { warnedRules?: number[] }\n const warned = bcData.warnedRules ?? []\n if (warned.length === 0) continue\n\n const sessionFailedRules = new Set<number>()\n const sessionAttempts = sessions.get(bc.runId ?? bc.sessionId) ?? []\n for (const a of sessionAttempts) {\n const ad = a.data as { validationPassed?: boolean; issues?: Array<{ rule: number }> }\n if (ad.validationPassed === false) {\n for (const issue of ad.issues ?? []) {\n sessionFailedRules.add(issue.rule)\n }\n }\n }\n\n for (const rule of warned) {\n const entry = warnEffMap.get(rule) ?? { warned: 0, passed: 0, failed: 0 }\n entry.warned++\n if (sessionFailedRules.has(rule)) entry.failed++\n else entry.passed++\n warnEffMap.set(rule, entry)\n }\n }\n\n const warningEffectiveness: WarningEffectiveness[] = [...warnEffMap.entries()]\n .map(([rule, e]) => ({\n rule,\n timesWarned: e.warned,\n timesWarnedAndPassed: e.passed,\n timesWarnedAndFailed: e.failed,\n effectivenessRate: e.warned > 0 ? Math.round((e.passed / e.warned) * 1000) / 1000 : 0,\n }))\n .sort((a, b) => b.timesWarned - a.timesWarned)\n\n // A-3: Rule co-occurrence\n const coOccurrenceMap = new Map<string, number>()\n for (const a of failed) {\n const data = a.data as { issues?: Array<{ rule: number }> }\n const rules = [...new Set((data.issues ?? []).map(i => i.rule))].sort((x, y) => x - y)\n for (let i = 0; i < rules.length; i++) {\n for (let j = i + 1; j < rules.length; j++) {\n const key = `${rules[i]},${rules[j]}`\n coOccurrenceMap.set(key, (coOccurrenceMap.get(key) ?? 0) + 1)\n }\n }\n }\n const ruleCoOccurrence = [...coOccurrenceMap.entries()]\n .filter(([, count]) => count >= 3)\n .map(([key, count]) => {\n const [a, b] = key.split(',').map(Number)\n return { rules: [a!, b!] as [number, number], count }\n })\n .sort((a, b) => b.count - a.count)\n\n // A-5: Session depth (attempt distribution)\n const attemptDistribution: Record<number, number> = {}\n for (const sessionAttempts of sessions.values()) {\n const depth = sessionAttempts.length\n attemptDistribution[depth] = (attemptDistribution[depth] ?? 0) + 1\n }\n\n return {\n schemaVersion: PATTERN_SCHEMA_VERSION,\n generatedAt: new Date().toISOString(),\n summary: {\n totalBuilds: starts.length,\n totalAttempts: attempts.length,\n firstTryPassRate: Math.round((firstTryPass / totalSessions) * 1000) / 1000,\n correctionRate: Math.round((correctionNeeded / totalSessions) * 1000) / 1000,\n singleAttemptFailRate: Math.round((singleAttemptFail / totalSessions) * 1000) / 1000,\n avgDurationMs: Math.round(avgDuration),\n totalTokensInput: totalInput,\n totalTokensOutput: totalOutput,\n attemptDistribution,\n },\n topFailureRules: patterns,\n failingCredentialTypes: credTypes,\n drift,\n warningEffectiveness,\n ruleCoOccurrence,\n }\n }\n\n async analyzeAndSave(days = 30): Promise<PatternAnalysis> {\n const analysis = await this.analyze(days)\n await mkdir(this.outputDir, { recursive: true })\n const outputPath = join(this.outputDir, 'patterns.json')\n const tmpPath = `${outputPath}.tmp`\n await writeFile(tmpPath, JSON.stringify(analysis, null, 2), 'utf-8')\n await rename(tmpPath, outputPath)\n\n const historySummary = {\n timestamp: analysis.generatedAt,\n totalBuilds: analysis.summary.totalBuilds,\n firstTryPassRate: analysis.summary.firstTryPassRate,\n correctionRate: analysis.summary.correctionRate,\n singleAttemptFailRate: analysis.summary.singleAttemptFailRate,\n activePatternCount: analysis.topFailureRules.filter(p => p.state !== 'resolved').length,\n topRules: analysis.topFailureRules.filter(p => p.state !== 'resolved').slice(0, 5)\n .map(p => ({ rule: p.rule, compositeScore: p.compositeScore, state: p.state })),\n }\n const historyPath = join(this.outputDir, 'pattern-history.jsonl')\n await appendFile(historyPath, JSON.stringify(historySummary) + '\\n', 'utf-8')\n\n const sessions = await this.buildSessionSummaries(days)\n const sessionHistoryPath = join(this.outputDir, 'session-history.json')\n const sessionHistoryTmp = `${sessionHistoryPath}.tmp`\n await writeFile(sessionHistoryTmp, JSON.stringify(sessions, null, 2), 'utf-8')\n await rename(sessionHistoryTmp, sessionHistoryPath)\n\n return analysis\n }\n\n async getSessions(limit = 20): Promise<SessionSummary[]> {\n try {\n const raw = await fsReadFile(join(this.outputDir, 'session-history.json'), 'utf-8')\n const all = JSON.parse(raw) as SessionSummary[]\n return all.slice(-limit)\n } catch { return [] }\n }\n\n private async buildSessionSummaries(days = 30): Promise<SessionSummary[]> {\n const events = this._cachedEvents ?? await this.readAllEvents(days)\n const buildCompletes = events.filter(e => e.eventType === 'build_complete')\n const attemptsByBuild = new Map<string, typeof events>()\n for (const e of events.filter(e => e.eventType === 'generation_attempt')) {\n const buildId = e.runId ?? e.sessionId\n const list = attemptsByBuild.get(buildId) ?? []\n list.push(e)\n attemptsByBuild.set(buildId, list)\n }\n\n const summaries: SessionSummary[] = buildCompletes.map(bc => {\n const data = bc.data as {\n description?: string\n success?: boolean\n totalAttempts?: number\n workflowName?: string | null\n workflowType?: string | null\n }\n\n const sessionAttempts = attemptsByBuild.get(bc.runId ?? bc.sessionId) ?? []\n const failedRules = Array.from(new Set(\n sessionAttempts.flatMap(a => {\n const ad = a.data as { validationPassed?: boolean; issues?: Array<{ rule: number }> }\n if (ad.validationPassed !== false) return []\n return (ad.issues ?? []).map(i => i.rule)\n })\n ))\n\n return {\n sessionId: bc.sessionId,\n date: bc.fileDate,\n description: data.description ?? '',\n workflowType: data.workflowType ?? null,\n attempts: data.totalAttempts ?? 1,\n success: data.success ?? false,\n failedRules,\n workflowName: data.workflowName ?? null,\n }\n })\n\n return summaries.sort((a, b) => a.date.localeCompare(b.date))\n }\n\n async getHistory(limit = 20): Promise<unknown[]> {\n try {\n const raw = await fsReadFile(join(this.outputDir, 'pattern-history.jsonl'), 'utf-8')\n return raw.trim().split('\\n').filter(Boolean).map(l => JSON.parse(l)).slice(-limit)\n } catch { return [] }\n }\n\n static fromEnv(): PatternAnalyzer {\n const dir = process.env['KAIROS_TELEMETRY']\n return dir && dir !== 'true' && dir !== 'false'\n ? new PatternAnalyzer(dir)\n : new PatternAnalyzer()\n }\n\n private detectDrift(patterns: Pattern[]): DriftReport {\n const VALIDATOR_RULES = VALIDATOR_RULE_IDS\n const validatorRuleSet = new Set(VALIDATOR_RULES)\n const alerts: DriftAlert[] = []\n\n for (const p of patterns) {\n if (p.state !== 'resolved' && !validatorRuleSet.has(p.rule)) {\n alerts.push({\n type: 'stale_pattern',\n rule: p.rule,\n message: `Pattern references Rule ${p.rule} which does not exist in the current validator (rules 1-26)`,\n })\n }\n }\n\n for (const rule of VALIDATOR_RULES) {\n if (!(rule in RULE_MITIGATIONS)) {\n alerts.push({\n type: 'missing_mitigation',\n rule,\n message: `Rule ${rule} has no mitigation text — if it fails, the system can't advise the LLM how to fix it`,\n })\n }\n if (!(rule in RULE_PIPELINE_STAGES)) {\n alerts.push({\n type: 'missing_stage_mapping',\n rule,\n message: `Rule ${rule} has no pipeline stage mapping — failures won't be grouped correctly`,\n })\n }\n }\n\n const coveredRules = VALIDATOR_RULES.filter(r => r in RULE_MITIGATIONS && r in RULE_PIPELINE_STAGES).length\n\n return {\n healthy: alerts.length === 0,\n alerts,\n coveredRules,\n totalRules: VALIDATOR_RULES.length,\n }\n }\n\n private computeCompositeScore(\n rawConfidence: number,\n sampleSize: number,\n state: PatternState,\n avgRecency: number,\n stickiness: number,\n ): { compositeScore: number; factors: ScoringFactors } {\n const stateWeights: Record<PatternState, number> = { draft: 0.3, confirmed: 0.8, resolved: 0.1 }\n const stateWeight = stateWeights[state]\n const impact = (1 - Math.exp(-sampleSize / 5)) * stateWeight\n const stickinessBoost = Math.min(0.15, stickiness * 0.05)\n const compositeScore = Math.min(Math.round((rawConfidence * impact * avgRecency * (1 + stickinessBoost)) * 1000) / 1000, 1)\n\n return {\n compositeScore,\n factors: {\n rawConfidence: Math.round(rawConfidence * 1000) / 1000,\n impact: Math.round(impact * 1000) / 1000,\n recency: Math.round(avgRecency * 1000) / 1000,\n stickinessBoost: Math.round(stickinessBoost * 1000) / 1000,\n },\n }\n }\n\n private classifyTrend(older: number, newer: number): PatternTrend {\n const total = older + newer\n if (total === 0) return 'stable'\n if (older === 0) return 'new'\n const newerRatio = newer / total\n if (newerRatio >= 0.65) return 'worsening'\n if (newerRatio <= 0.35) return 'improving'\n return 'stable'\n }\n\n private deduplicateMessages(messages: string[], maxCount = 3): string[] {\n const normalize = (msg: string) =>\n msg\n .replace(/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/gi, '...')\n .replace(/\\bnode\\s+\"[^\"]+\"/g, 'node \"...\"')\n .replace(/\\s+/g, ' ')\n .trim()\n\n const seen = new Set<string>()\n const unique: string[] = []\n for (const msg of messages) {\n const key = normalize(msg)\n if (!seen.has(key) && unique.length < maxCount) {\n seen.add(key)\n unique.push(msg)\n }\n }\n return unique\n }\n\n private recencyWeight(fileDate: string, halfLifeDays = 30): number {\n const daysAgo = Math.max(0, (Date.now() - new Date(fileDate + 'T12:00:00Z').getTime()) / (1000 * 60 * 60 * 24))\n return Math.max(0.1, Math.exp(-Math.LN2 * daysAgo / halfLifeDays))\n }\n\n private async readAllEvents(days: number) {\n return readTelemetryEvents(this.telemetryDir, days)\n }\n}\n","export type PipelineStage = 'node_generation' | 'credential_injection' | 'connection_wiring' | 'workflow_structure' | 'expression_syntax'\n\nexport const VALIDATOR_RULE_IDS: number[] = Array.from({ length: 26 }, (_, i) => i + 1)\n\nexport const RULE_PIPELINE_STAGES: Record<number, PipelineStage> = {\n 1: 'node_generation',\n 2: 'node_generation',\n 3: 'node_generation',\n 4: 'node_generation',\n 5: 'node_generation',\n 6: 'node_generation',\n 7: 'node_generation',\n 8: 'node_generation',\n 9: 'connection_wiring',\n 10: 'connection_wiring',\n 11: 'connection_wiring',\n 12: 'workflow_structure',\n 13: 'node_generation',\n 14: 'workflow_structure',\n 15: 'node_generation',\n 16: 'node_generation',\n 17: 'credential_injection',\n 18: 'connection_wiring',\n 19: 'node_generation',\n 20: 'connection_wiring',\n 21: 'workflow_structure',\n 22: 'workflow_structure',\n 23: 'node_generation',\n 24: 'expression_syntax',\n 25: 'expression_syntax',\n 26: 'expression_syntax',\n}\n\nexport interface RuleExample {\n bad: string\n good: string\n}\n\nexport const RULE_EXAMPLES: Record<number, RuleExample> = {\n 17: {\n bad: '\"credentials\": { \"slackOAuth2Api\": \"my-token\" }',\n good: '\"credentials\": { \"slackOAuth2Api\": { \"id\": \"placeholder-id\", \"name\": \"My Slack OAuth\" } }',\n },\n 24: {\n bad: '$node[\"Fetch Data\"].json.email',\n good: \"$('Fetch Data').item.json.email\",\n },\n 25: {\n bad: '$json.items[0].email',\n good: '$json.email',\n },\n 26: {\n bad: \"$('Fetch Data').json.email\",\n good: \"$('Fetch Data').first().json.email\",\n },\n}\n\nexport const RULE_MITIGATIONS: Record<number, string> = {\n 1: 'Provide a non-empty workflow name string',\n 2: 'Include at least one node in the nodes array',\n 3: 'Every node must have a unique UUID v4 string as its id field',\n 4: 'Ensure all node ids are unique — no two nodes can share the same id',\n 5: 'Every node must have a non-empty type string',\n 6: 'Every node must have a positive integer typeVersion',\n 7: 'Every node must have a position array of exactly [x, y] numbers',\n 8: 'Every node must have a non-empty name string',\n 9: 'connections must be a plain object (use {} if no connections)',\n 10: 'Every node name in connections (source and target) must exactly match a name in the nodes array',\n 11: 'Every non-trigger node should have at least one incoming connection',\n 12: 'Remove forbidden fields: id, active, createdAt, updatedAt, versionId, meta, tags — these are server-assigned',\n 13: 'workflow.settings must be a plain object if present',\n 14: 'Include at least one trigger node (e.g. scheduleTrigger, webhookTrigger, manualTrigger, or service-specific)',\n 15: 'Node type strings must be fully qualified: \"n8n-nodes-base.httpRequest\" not just \"httpRequest\"',\n 16: 'All node names must be unique within the workflow',\n 17: 'Each credential entry must be keyed by credential type with an object value: { \"slackOAuth2Api\": { \"id\": \"placeholder-id\", \"name\": \"My Credential\" } } — the key is the credential type, the value has id and name strings',\n 18: 'AI sub-nodes (languageModel, memory, tool) must be the CONNECTION SOURCE pointing TO the agent — not the reverse',\n 19: 'Use known safe typeVersion values for each node type',\n 20: 'Remove connection cycles — ensure no node can reach itself through the connection graph',\n 21: 'When using webhook with responseMode \"responseNode\", include a respondToWebhook node in the flow',\n 22: 'Ensure all required parameters are set for each node type (e.g. webhook needs httpMethod and path)',\n 23: 'Use node types that exist in the n8n registry — check with kairos_sync',\n 24: 'Use modern accessor syntax: $(\"NodeName\").item.json.field instead of deprecated $node[\"NodeName\"].json.field',\n 25: 'Access item fields directly with $json.field — n8n flattens items automatically, do not use $json.items[0]',\n 26: 'Use $(\"NodeName\").first().json.field or $(\"NodeName\").all() — bare $(\"NodeName\").json without .first() or .all() throws at runtime',\n}\n","export interface ILogger {\n debug(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n error(msg: string, meta?: Record<string, unknown>): void\n}\n\nexport const nullLogger: ILogger = {\n debug() {},\n info() {},\n warn() {},\n error() {},\n}\n","import type { StoredWorkflow } from './types.js'\n\nconst WEIGHTS = {\n tfidf: 0.35,\n nodeFingerprint: 0.30,\n outcome: 0.20,\n deploy: 0.15,\n}\n\nconst NODE_KEYWORDS: Record<string, string[]> = {\n slack: ['slack', 'slackApi'],\n email: ['gmail', 'sendEmail', 'emailSend', 'emailReadImap'],\n webhook: ['webhook', 'webhookTrigger'],\n schedule: ['scheduleTrigger', 'cron'],\n http: ['httpRequest'],\n sheets: ['googleSheets'],\n github: ['github', 'githubTrigger'],\n telegram: ['telegram', 'telegramTrigger'],\n ai: ['agent', 'openAi', 'lmChatOpenAi', 'lmChatAnthropic', 'chainLlm', 'chainSummarization'],\n memory: ['memoryBufferWindow', 'memoryXata', 'memoryPostgres'],\n vector: ['vectorStoreInMemory', 'vectorStorePinecone', 'vectorStoreQdrant'],\n database: ['postgres', 'mySql', 'redis', 'mongoDb'],\n airtable: ['airtable'],\n notion: ['notion'],\n s3: ['awsS3'],\n code: ['code'],\n merge: ['merge'],\n switch: ['switch'],\n if: ['if'],\n wait: ['wait'],\n rss: ['rssFeedRead', 'rssFeedReadTrigger'],\n form: ['formTrigger'],\n set: ['set'],\n split: ['splitInBatches'],\n filter: ['filter'],\n telegram_trigger: ['telegramTrigger'],\n stripe: ['stripe'],\n}\n\nfunction extractQueryFingerprint(description: string): Set<string> {\n const lower = description.toLowerCase()\n const matches = new Set<string>()\n\n for (const [keyword, nodeTypes] of Object.entries(NODE_KEYWORDS)) {\n if (lower.includes(keyword)) {\n for (const nt of nodeTypes) matches.add(nt)\n }\n }\n\n if (/\\bevery\\b|\\bdaily\\b|\\bhourly\\b|\\bweekly\\b|\\bmonthly\\b|\\bcron\\b|\\bschedule\\b|\\bat \\d/.test(lower)) {\n matches.add('scheduleTrigger')\n }\n if (/\\bwebhook\\b|\\breceive\\b.*\\bpost\\b|\\bpost\\b.*\\brequest\\b/.test(lower)) {\n matches.add('webhook')\n }\n if (/\\bchat\\b|\\bchatbot\\b|\\bconversation\\b/.test(lower)) {\n matches.add('chatTrigger')\n }\n if (/\\bai\\b|\\bllm\\b|\\bgpt\\b|\\bclaude\\b|\\bagent\\b|\\bsummariz/.test(lower)) {\n matches.add('agent')\n }\n\n return matches\n}\n\nfunction extractWorkflowFingerprint(w: StoredWorkflow): Set<string> {\n const fp = new Set<string>()\n for (const node of w.workflow.nodes) {\n const bare = node.type.split('.').pop() ?? ''\n fp.add(bare)\n }\n return fp\n}\n\nfunction jaccardSimilarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0\n let intersection = 0\n for (const item of a) {\n if (b.has(item)) intersection++\n }\n const union = a.size + b.size - intersection\n return union > 0 ? intersection / union : 0\n}\n\nfunction outcomeScore(w: StoredWorkflow): number {\n const stats = w.outcomeStats\n if (!stats || stats.totalUses === 0) return 0.5\n\n const passRate = stats.firstTryPasses / stats.totalUses\n const avgAttempts = stats.totalAttempts / stats.totalUses\n const attemptPenalty = Math.max(0, 1 - (avgAttempts - 1) * 0.3)\n\n return passRate * 0.6 + attemptPenalty * 0.4\n}\n\nfunction deployScore(w: StoredWorkflow): number {\n return 1 + Math.log(w.deployCount + 1) * 0.1\n}\n\nexport interface ScoredEntry {\n workflow: StoredWorkflow\n score: number\n signals: {\n tfidf: number\n nodeFingerprint: number\n outcome: number\n deploy: number\n }\n}\n\nexport function hybridScore(\n queryTokens: string[],\n queryDescription: string,\n workflows: StoredWorkflow[],\n docTokenArrays: string[][],\n idf: Map<string, number>,\n): ScoredEntry[] {\n const queryFp = extractQueryFingerprint(queryDescription)\n const ceiling = queryTokens.reduce((sum, qt) => sum + (idf.get(qt) ?? 0), 0) || 1\n\n return workflows.map((w, i) => {\n const docTokens = docTokenArrays[i]!\n let tfidfRaw = 0\n const docFreq = new Map<string, number>()\n for (const t of docTokens) {\n docFreq.set(t, (docFreq.get(t) ?? 0) + 1)\n }\n for (const qt of queryTokens) {\n const tf = docTokens.length > 0 ? (docFreq.get(qt) ?? 0) / docTokens.length : 0\n const idfVal = idf.get(qt) ?? 0\n tfidfRaw += tf * idfVal\n }\n const tfidf = Math.min(tfidfRaw / ceiling, 1)\n\n const workflowFp = extractWorkflowFingerprint(w)\n const nodeFingerprint = queryFp.size > 0 ? jaccardSimilarity(queryFp, workflowFp) : 0\n\n const outcome = outcomeScore(w)\n const deploy = Math.min(deployScore(w), 1.5) / 1.5\n\n const score = Math.min(\n WEIGHTS.tfidf * tfidf +\n WEIGHTS.nodeFingerprint * nodeFingerprint +\n WEIGHTS.outcome * outcome +\n WEIGHTS.deploy * deploy,\n 1,\n )\n\n return {\n workflow: w,\n score,\n signals: { tfidf, nodeFingerprint, outcome, deploy },\n }\n })\n}\n","import type { StoredWorkflow } from './types.js'\n\nexport interface WorkflowCluster {\n pattern: string\n fingerprint: string[]\n members: StoredWorkflow[]\n avgFirstTryPassRate: number\n avgAttempts: number\n commonFailedRules: Array<{ rule: number; frequency: number }>\n}\n\nfunction getFingerprint(w: StoredWorkflow): string[] {\n return w.workflow.nodes\n .map((n) => n.type.split('.').pop() ?? '')\n .sort()\n}\n\nfunction fingerprintKey(fp: string[]): string {\n return fp.join('|')\n}\n\nfunction describePattern(fp: string[]): string {\n const triggers = fp.filter((n) => /trigger/i.test(n))\n const outputs = fp.filter((n) => /slack|gmail|email|telegram|sheets|airtable|notion/i.test(n))\n const ai = fp.filter((n) => /agent|openai|anthropic|chain|memory/i.test(n))\n const core = fp.filter((n) => /httpRequest|code|merge|switch|if|set|filter/i.test(n))\n\n const parts: string[] = []\n if (triggers.length > 0) parts.push(triggers[0]!)\n if (ai.length > 0) parts.push('AI')\n if (core.length > 0) parts.push(core.slice(0, 2).join('+'))\n if (outputs.length > 0) parts.push(outputs[0]!)\n\n return parts.length > 0 ? parts.join(' → ') : fp.slice(0, 3).join(' → ')\n}\n\nexport function clusterWorkflows(workflows: StoredWorkflow[]): WorkflowCluster[] {\n const groups = new Map<string, StoredWorkflow[]>()\n\n for (const w of workflows) {\n const fp = getFingerprint(w)\n const key = fingerprintKey(fp)\n\n const existing = groups.get(key)\n if (existing) {\n existing.push(w)\n } else {\n groups.set(key, [w])\n }\n }\n\n const clusters: WorkflowCluster[] = []\n\n for (const [, members] of groups) {\n if (members.length === 0) continue\n\n const fp = getFingerprint(members[0]!)\n const withStats = members.filter((m) => m.outcomeStats && m.outcomeStats.totalUses > 0)\n\n let avgFirstTryPassRate = 0\n let avgAttempts = 0\n\n if (withStats.length > 0) {\n avgFirstTryPassRate = withStats.reduce((sum, m) => {\n const s = m.outcomeStats!\n return sum + s.firstTryPasses / s.totalUses\n }, 0) / withStats.length\n\n avgAttempts = withStats.reduce((sum, m) => {\n const s = m.outcomeStats!\n return sum + s.totalAttempts / s.totalUses\n }, 0) / withStats.length\n }\n\n const ruleCounts = new Map<number, number>()\n let totalFailureInstances = 0\n for (const m of withStats) {\n const rules = m.outcomeStats!.failedRules\n for (const [rule, count] of Object.entries(rules)) {\n const r = parseInt(rule, 10)\n ruleCounts.set(r, (ruleCounts.get(r) ?? 0) + count)\n totalFailureInstances += count\n }\n }\n\n const commonFailedRules = [...ruleCounts.entries()]\n .map(([rule, count]) => ({\n rule,\n frequency: totalFailureInstances > 0 ? count / totalFailureInstances : 0,\n }))\n .filter((r) => r.frequency >= 0.1)\n .sort((a, b) => b.frequency - a.frequency)\n\n clusters.push({\n pattern: describePattern(fp),\n fingerprint: fp,\n members,\n avgFirstTryPassRate,\n avgAttempts,\n commonFailedRules,\n })\n }\n\n return clusters.sort((a, b) => b.members.length - a.members.length)\n}\n\nexport function rerank(\n candidates: Array<{ workflow: StoredWorkflow; score: number }>,\n clusters: WorkflowCluster[],\n): Array<{ workflow: StoredWorkflow; score: number; clusterPattern?: string }> {\n const clusterMap = new Map<string, WorkflowCluster>()\n for (const cluster of clusters) {\n for (const member of cluster.members) {\n clusterMap.set(member.id, cluster)\n }\n }\n\n return candidates\n .map((c) => {\n const cluster = clusterMap.get(c.workflow.id)\n let boost = 0\n\n if (cluster && cluster.avgFirstTryPassRate > 0) {\n boost = (cluster.avgFirstTryPassRate - 0.5) * 0.1\n }\n\n if (cluster && cluster.commonFailedRules.length > 0) {\n boost -= cluster.commonFailedRules.length * 0.02\n }\n\n return {\n workflow: c.workflow,\n score: Math.max(0, Math.min(1, c.score + boost)),\n ...(cluster ? { clusterPattern: cluster.pattern } : {}),\n }\n })\n .sort((a, b) => b.score - a.score)\n}\n","import { readFile, writeFile, rename, mkdir, stat } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport type { N8nWorkflow } from '../types/workflow.js'\nimport type {\n IWorkflowLibrary,\n WorkflowMatch,\n StoredWorkflow,\n WorkflowMetadataInput,\n LibraryFilters,\n SearchOptions,\n OutcomeData,\n} from './types.js'\nimport { generateUUID } from '../utils/uuid.js'\nimport { scoreToMode } from '../utils/thresholds.js'\nimport { hybridScore } from './scorer.js'\nimport { clusterWorkflows, rerank } from './cluster.js'\n\nexport function tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length > 2)\n}\n\nexport function buildSearchCorpus(w: StoredWorkflow): string {\n const nodeTokens = w.workflow.nodes.map((n) => {\n const bare = n.type.split('.').pop() ?? ''\n const spaced = bare.replace(/([A-Z])/g, ' $1').trim().toLowerCase()\n return `${bare} ${spaced}`\n })\n return `${w.description} ${w.workflow.name} ${w.tags.join(' ')} ${nodeTokens.join(' ')}`\n}\n\nconst MAX_LIBRARY_SIZE = 500\n\n/**\n * Internal per-file format: everything from StoredWorkflow except the workflow field,\n * plus two cache fields used to rebuild search corpus without loading workflow files.\n */\ntype StoredWorkflowMeta = Omit<StoredWorkflow, 'workflow'> & {\n workflowName: string // n8n workflow name (copied at save time for search)\n cachedNodeTypes: string[] // full node type strings (e.g. \"n8n-nodes-base.slack\")\n}\n\nfunction isValidMeta(item: unknown): item is StoredWorkflowMeta {\n return (\n typeof item === 'object' &&\n item !== null &&\n typeof (item as Record<string, unknown>).id === 'string' &&\n typeof (item as Record<string, unknown>).description === 'string' &&\n typeof (item as Record<string, unknown>).workflowName === 'string' &&\n Array.isArray((item as Record<string, unknown>).cachedNodeTypes)\n )\n}\n\nfunction isValidOldEntry(item: unknown): item is StoredWorkflow {\n return (\n typeof item === 'object' &&\n item !== null &&\n typeof (item as Record<string, unknown>).id === 'string' &&\n typeof (item as Record<string, unknown>).description === 'string' &&\n typeof (item as Record<string, unknown>).workflow === 'object' &&\n (item as Record<string, unknown>).workflow !== null &&\n Array.isArray(\n ((item as Record<string, unknown>).workflow as Record<string, unknown>).nodes,\n )\n )\n}\n\nexport class FileLibrary implements IWorkflowLibrary {\n private readonly dir: string\n private meta: StoredWorkflowMeta[] = []\n private initPromise: Promise<void> | null = null\n private writeQueue: Promise<void> = Promise.resolve()\n\n constructor(dir?: string) {\n this.dir = dir ?? join(homedir(), '.kairos', 'library')\n }\n\n private get workflowsDir(): string {\n return join(this.dir, 'workflows')\n }\n\n private workflowFilePath(id: string): string {\n return join(this.workflowsDir, `${id}.json`)\n }\n\n async initialize(): Promise<void> {\n if (!this.initPromise) {\n this.initPromise = this.doInitialize()\n }\n return this.initPromise\n }\n\n private async doInitialize(): Promise<void> {\n await mkdir(this.dir, { recursive: true })\n const indexPath = join(this.dir, 'index.json')\n\n // New format has a 'workflows/' subdirectory; old format does not\n let workflowsDirExists = false\n try {\n await stat(this.workflowsDir)\n workflowsDirExists = true\n } catch {\n // Directory absent — old format or fresh start\n }\n\n if (workflowsDirExists) {\n // New per-file format: index.json holds lightweight meta only\n try {\n const raw = await readFile(indexPath, 'utf-8')\n const parsed: unknown = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n this.meta = parsed.filter(isValidMeta)\n }\n } catch {\n this.meta = []\n }\n } else {\n // Attempt to read old monolithic format\n try {\n const raw = await readFile(indexPath, 'utf-8')\n const parsed: unknown = JSON.parse(raw)\n if (Array.isArray(parsed) && parsed.length > 0 && isValidOldEntry(parsed[0])) {\n await this.migrateFromMonolithic(parsed.filter(isValidOldEntry))\n return\n }\n } catch {\n // No index.json — fresh start\n }\n this.meta = []\n await mkdir(this.workflowsDir, { recursive: true })\n }\n }\n\n /**\n * One-time transparent migration from v0.4.x monolithic index.json.\n * Splits each stored workflow into a per-file workflow JSON and a lightweight\n * meta entry. Rewrites index.json in the new format.\n */\n private async migrateFromMonolithic(oldEntries: StoredWorkflow[]): Promise<void> {\n await mkdir(this.workflowsDir, { recursive: true })\n\n const newMeta: StoredWorkflowMeta[] = []\n for (const entry of oldEntries) {\n const wfPath = this.workflowFilePath(entry.id)\n const tmpPath = `${wfPath}.tmp`\n await writeFile(tmpPath, JSON.stringify(entry.workflow), 'utf-8')\n await rename(tmpPath, wfPath)\n\n const { workflow, ...metaFields } = entry\n newMeta.push({\n ...metaFields,\n workflowName: workflow.name,\n cachedNodeTypes: workflow.nodes.map((n) => n.type),\n })\n }\n\n this.meta = newMeta\n // Write new lightweight index.json (no workflow fields)\n await this.persistNow()\n }\n\n private async loadWorkflowFile(id: string): Promise<N8nWorkflow | null> {\n try {\n const raw = await readFile(this.workflowFilePath(id), 'utf-8')\n return JSON.parse(raw) as N8nWorkflow\n } catch {\n return null\n }\n }\n\n private async writeWorkflowFile(id: string, workflow: N8nWorkflow): Promise<void> {\n const wfPath = this.workflowFilePath(id)\n const tmpPath = `${wfPath}.tmp`\n await writeFile(tmpPath, JSON.stringify(workflow), 'utf-8')\n await rename(tmpPath, wfPath)\n }\n\n /**\n * Build a lightweight StoredWorkflow shell from a meta entry for use in\n * scoring / clustering. Only node.type is populated in each node — no other\n * node fields are used by hybridScore or clusterWorkflows.\n */\n private makeSearchShell(m: StoredWorkflowMeta): StoredWorkflow {\n return {\n ...m,\n workflow: {\n name: m.workflowName,\n nodes: m.cachedNodeTypes.map((type) => ({\n id: '',\n name: '',\n type,\n typeVersion: 1,\n position: [0, 0] as [number, number],\n parameters: {},\n })),\n connections: {},\n },\n } as StoredWorkflow\n }\n\n async search(description: string, options?: SearchOptions): Promise<WorkflowMatch[]> {\n const filteredMeta = this.meta.filter((m) => m.trustLevel !== 'blocked')\n if (filteredMeta.length === 0) return []\n\n const limit = options?.limit ?? 3\n const queryTokens = tokenize(description)\n if (queryTokens.length === 0) return []\n\n // Build lightweight shells — no file I/O, all data comes from cached meta\n const shells = filteredMeta.map((m) => this.makeSearchShell(m))\n\n const docTokenArrays = shells.map((w) => tokenize(buildSearchCorpus(w)))\n const docTokenSets = docTokenArrays.map((tokens) => new Set(tokens))\n\n const docCount = shells.length\n const idf = new Map<string, number>()\n const allTokens = new Set(queryTokens)\n for (const token of allTokens) {\n const docsWithToken = docTokenSets.filter((d) => d.has(token)).length\n idf.set(token, Math.log((docCount + 1) / (docsWithToken + 1)) + 1)\n }\n\n const scored = hybridScore(queryTokens, description, shells, docTokenArrays, idf)\n .filter((m) => m.score > 0)\n .sort((a, b) => b.score - a.score)\n\n const clusters = clusterWorkflows(shells)\n const reranked = rerank(scored, clusters).slice(0, limit)\n\n if (reranked.length === 0) return []\n\n // Update timesRetrieved in meta before persisting\n for (const r of reranked) {\n const m = this.meta.find((m) => m.id === r.workflow.id)\n if (m) m.timesRetrieved = (m.timesRetrieved ?? 0) + 1\n }\n this.persist()\n\n // Lazy-load full workflow files for the top matches only\n const results = await Promise.all(\n reranked.map(async (r) => {\n const m = this.meta.find((meta) => meta.id === r.workflow.id)!\n const workflow = await this.loadWorkflowFile(r.workflow.id)\n if (!workflow) return null\n return {\n workflow: { ...m, workflow } as StoredWorkflow,\n score: r.score,\n mode: scoreToMode(r.score),\n } as WorkflowMatch\n }),\n )\n\n return results.filter((r): r is WorkflowMatch => r !== null)\n }\n\n async save(workflow: N8nWorkflow, metadata: WorkflowMetadataInput): Promise<string> {\n const id = generateUUID()\n\n // Write workflow file first (data before index entry — crash-safe WAL pattern)\n await this.writeWorkflowFile(id, workflow)\n\n const failurePatterns = this.deduplicateFailurePatterns(metadata.failurePatterns)\n const meta: StoredWorkflowMeta = {\n id,\n description: metadata.description,\n tags: metadata.tags ?? [],\n platform: metadata.platform ?? 'n8n',\n deployCount: 0,\n createdAt: new Date().toISOString(),\n workflowName: workflow.name,\n cachedNodeTypes: workflow.nodes.map((n) => n.type),\n ...(failurePatterns?.length ? { failurePatterns } : {}),\n ...(metadata.sourceWorkflowIds?.length ? { sourceWorkflowIds: metadata.sourceWorkflowIds } : {}),\n ...(metadata.generationMode ? { generationMode: metadata.generationMode } : {}),\n ...(metadata.topMatchScore != null ? { topMatchScore: metadata.topMatchScore } : {}),\n ...(metadata.generationAttempts != null ? { generationAttempts: metadata.generationAttempts } : {}),\n ...(metadata.credentialsNeeded?.length ? { credentialsNeeded: metadata.credentialsNeeded } : {}),\n ...(metadata.sourceKind ? { sourceKind: metadata.sourceKind } : {}),\n ...(metadata.sourceId ? { sourceId: metadata.sourceId } : {}),\n ...(metadata.sourceUrl ? { sourceUrl: metadata.sourceUrl } : {}),\n ...(metadata.trustLevel ? { trustLevel: metadata.trustLevel } : {}),\n }\n\n this.meta.push(meta)\n if (this.meta.length > MAX_LIBRARY_SIZE) {\n // Sort by deployCount desc but always keep the newly-added entry\n this.meta.sort((a, b) => {\n if (a.id === id) return -1\n if (b.id === id) return 1\n return (b.deployCount ?? 0) - (a.deployCount ?? 0)\n })\n this.meta = this.meta.slice(0, MAX_LIBRARY_SIZE)\n }\n\n await this.persist()\n return id\n }\n\n async recordDeployment(id: string): Promise<void> {\n const m = this.meta.find((m) => m.id === id)\n if (m) {\n m.deployCount++\n m.lastDeployedAt = new Date().toISOString()\n await this.persist()\n }\n }\n\n async recordOutcome(id: string, outcome: OutcomeData): Promise<void> {\n const m = this.meta.find((m) => m.id === id)\n if (!m) return\n\n if (outcome.mode === 'direct') {\n m.timesUsedAsDirect = (m.timesUsedAsDirect ?? 0) + 1\n } else {\n m.timesUsedAsReference = (m.timesUsedAsReference ?? 0) + 1\n }\n\n const stats = m.outcomeStats ?? { totalUses: 0, totalAttempts: 0, firstTryPasses: 0, failedRules: {} }\n stats.totalUses++\n stats.totalAttempts += outcome.attempts\n if (outcome.firstTryPass) stats.firstTryPasses++\n for (const rule of outcome.failedRules) {\n const key = String(rule)\n stats.failedRules[key] = (stats.failedRules[key] ?? 0) + 1\n }\n m.outcomeStats = stats\n\n await this.persist()\n }\n\n async drain(): Promise<void> {\n await this.writeQueue\n }\n\n async get(id: string): Promise<StoredWorkflow | null> {\n const m = this.meta.find((m) => m.id === id)\n if (!m) return null\n const workflow = await this.loadWorkflowFile(id)\n if (!workflow) return null\n return { ...m, workflow } as StoredWorkflow\n }\n\n async list(filters?: LibraryFilters): Promise<StoredWorkflow[]> {\n let filtered = this.meta\n if (filters?.platform) {\n filtered = filtered.filter((m) => m.platform === filters.platform)\n }\n if (filters?.tags && filters.tags.length > 0) {\n filtered = filtered.filter((m) => filters.tags!.some((t) => m.tags.includes(t)))\n }\n\n const results = await Promise.all(\n filtered.map(async (m) => {\n const workflow = await this.loadWorkflowFile(m.id)\n if (!workflow) return null\n return { ...m, workflow } as StoredWorkflow\n }),\n )\n\n return results.filter((r): r is StoredWorkflow => r !== null)\n }\n\n private deduplicateFailurePatterns(\n patterns?: Array<{ rule: number; message: string }>,\n ): StoredWorkflow['failurePatterns'] | undefined {\n if (!patterns?.length) return undefined\n const map = new Map<number, { rule: number; message: string; occurrences: number }>()\n for (const fp of patterns) {\n const existing = map.get(fp.rule)\n if (existing) {\n existing.occurrences++\n } else {\n map.set(fp.rule, { rule: fp.rule, message: fp.message, occurrences: 1 })\n }\n }\n return [...map.values()]\n }\n\n /**\n * Direct write used only during migration (before writeQueue is needed).\n */\n private async persistNow(): Promise<void> {\n const indexPath = join(this.dir, 'index.json')\n const tmpPath = `${indexPath}.tmp`\n await writeFile(tmpPath, JSON.stringify(this.meta, null, 2), 'utf-8')\n await rename(tmpPath, indexPath)\n }\n\n private persist(): Promise<void> {\n this.writeQueue = this.writeQueue.then(async () => {\n const indexPath = join(this.dir, 'index.json')\n\n // Re-read disk state to preserve concurrent additions from other processes\n let onDisk: StoredWorkflowMeta[] = []\n try {\n const raw = await readFile(indexPath, 'utf-8')\n const parsed: unknown = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n onDisk = parsed.filter(isValidMeta)\n }\n } catch { /* index.json doesn't exist yet */ }\n\n // Our in-memory state wins for IDs we manage; add any entries added by other processes\n const ourIds = new Set(this.meta.map((m) => m.id))\n const external = onDisk.filter((m) => !ourIds.has(m.id))\n let merged = [...this.meta, ...external]\n if (merged.length > MAX_LIBRARY_SIZE) {\n merged.sort((a, b) => (b.deployCount ?? 0) - (a.deployCount ?? 0))\n merged = merged.slice(0, MAX_LIBRARY_SIZE)\n }\n\n const tmpPath = `${indexPath}.tmp`\n await writeFile(tmpPath, JSON.stringify(merged, null, 2), 'utf-8')\n await rename(tmpPath, indexPath)\n })\n return this.writeQueue\n }\n}\n","export const DIRECT_THRESHOLD = 0.92\nexport const REFERENCE_THRESHOLD = 0.72\n\nexport function scoreToMode(score: number): 'direct' | 'reference' | 'scratch' {\n if (score >= DIRECT_THRESHOLD) return 'direct'\n if (score >= REFERENCE_THRESHOLD) return 'reference'\n return 'scratch'\n}\n"],"mappings":"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","names":["homedir","join","join","join","homedir","appendFile","mkdir","join","homedir","join","homedir","mkdir","appendFile","e","writeFile","rename","mkdir","join","homedir","join","homedir","mkdir","writeFile","rename","m"]}