@workos/oagen 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff-DyQF4sel.mjs","names":["extractDeclarationName","declarationKey","path"],"sources":["../src/engine/merge-adapters/url-fingerprint.ts","../src/engine/merge-adapters/dotnet.ts","../src/engine/merge-adapters/elixir.ts","../src/engine/merge-adapters/go.ts","../src/engine/merge-adapters/kotlin.ts","../src/engine/merge-adapters/node.ts","../src/engine/merge-adapters/php.ts","../src/engine/merge-adapters/python.ts","../src/engine/merge-adapters/ruby.ts","../src/engine/merge-adapters/rust.ts","../src/engine/merge-adapters/index.ts","../src/engine/merger.ts","../src/engine/json-merge.ts","../src/engine/writer.ts","../src/engine/generate-files.ts","../src/engine/integrate.ts","../src/engine/orchestrator.ts","../src/engine/registry.ts","../src/differ/classify.ts","../src/differ/models.ts","../src/differ/operations.ts","../src/differ/services.ts","../src/differ/diff.ts"],"sourcesContent":["import type Parser from 'tree-sitter';\nimport type { UrlFingerprintConfig } from './types.js';\n\n/**\n * Extract a URL path fingerprint from a method body using tree-sitter AST traversal.\n *\n * Walks the AST subtree of the member node looking for the first string literal\n * that starts with '/'. Normalizes interpolation expressions to '{}' and format\n * specifiers (%s, %d, etc.) to '{}' for cross-language comparison.\n *\n * @returns A normalized URL fingerprint like \"/organizations/{}\" or undefined if none found.\n */\nexport function extractUrlFingerprint(memberNode: Parser.SyntaxNode, config: UrlFingerprintConfig): string | undefined {\n const stringTypes = new Set(config.stringNodeTypes);\n const contentTypes = new Set(config.contentNodeTypes);\n const interpolationTypes = new Set(config.interpolationNodeTypes);\n const formatFns = config.formatFunctionNames ? new Set(config.formatFunctionNames) : null;\n\n // Iterative DFS through the method's AST subtree\n const stack: Parser.SyntaxNode[] = [memberNode];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n\n if (stringTypes.has(node.type)) {\n const fp = resolveFingerprint(node, contentTypes, interpolationTypes);\n if (fp?.startsWith('/')) return fp;\n }\n\n // For format functions (Go's Sprintf, Rust's format!): check if this call\n // matches and extract the first string argument.\n if (formatFns && isFormatCall(node, formatFns)) {\n const fp = extractFromFormatCall(node, stringTypes, contentTypes, interpolationTypes);\n if (fp?.startsWith('/')) return fp;\n }\n\n // Push children in reverse order so leftmost child is processed first\n for (let i = node.childCount - 1; i >= 0; i--) {\n const child = node.child(i);\n if (child) stack.push(child);\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolve the text content of a string node, normalizing interpolations to '{}'.\n */\nfunction resolveFingerprint(\n stringNode: Parser.SyntaxNode,\n contentTypes: Set<string>,\n interpolationTypes: Set<string>,\n): string | undefined {\n // Leaf string node (no children besides quotes) — strip quotes\n if (stringNode.namedChildCount === 0) {\n return normalizeFormatSpecifiers(stripQuotes(stringNode.text));\n }\n\n // Composite string (has content fragments + interpolation children)\n let result = '';\n for (let i = 0; i < stringNode.childCount; i++) {\n const child = stringNode.child(i)!;\n if (contentTypes.has(child.type)) {\n result += child.text;\n } else if (interpolationTypes.has(child.type)) {\n result += '{}';\n }\n // Skip quote delimiters, interpolation markers, etc.\n }\n\n return result ? normalizeFormatSpecifiers(result) : normalizeFormatSpecifiers(stripQuotes(stringNode.text));\n}\n\n/** Check if a node is a call to one of the format functions (e.g., fmt.Sprintf, format!). */\nfunction isFormatCall(node: Parser.SyntaxNode, formatFns: Set<string>): boolean {\n // Rust macro: format!(...) — tree-sitter may parse as macro_invocation\n if (node.type === 'macro_invocation') {\n const macroName = node.childForFieldName('macro')?.text;\n return !!(macroName && formatFns.has(macroName.replace(/!$/, '')));\n }\n\n if (node.type !== 'call_expression') return false;\n const fnNode = node.childForFieldName('function');\n if (!fnNode) return false;\n\n // Direct call: Sprintf(...) or format!(...)\n if (formatFns.has(fnNode.text)) return true;\n\n // Member call: fmt.Sprintf(...)\n if (fnNode.type === 'selector_expression' || fnNode.type === 'member_expression') {\n const prop = fnNode.childForFieldName('field') ?? fnNode.childForFieldName('property');\n if (prop && formatFns.has(prop.text)) return true;\n }\n return false;\n}\n\n/** Extract the first string argument from a format function call. */\nfunction extractFromFormatCall(\n callNode: Parser.SyntaxNode,\n stringTypes: Set<string>,\n contentTypes: Set<string>,\n interpolationTypes: Set<string>,\n): string | undefined {\n const args = callNode.childForFieldName('arguments');\n if (!args) return undefined;\n\n for (let i = 0; i < args.childCount; i++) {\n const arg = args.child(i)!;\n if (stringTypes.has(arg.type)) {\n return resolveFingerprint(arg, contentTypes, interpolationTypes);\n }\n }\n return undefined;\n}\n\n/** Strip surrounding quote characters from a string literal. */\nfunction stripQuotes(text: string): string {\n // Handle various quote styles: \"...\", '...', `...`, f\"...\", $\"...\", @\"...\"\n const match = text.match(/^(?:f|r|b|@|\\$)?(?:\"\"\"([\\s\\S]*)\"\"\"|'''([\\s\\S]*)'''|\"(.*)\"|'(.*)'|`(.*)`)$/s);\n if (match) return match[1] ?? match[2] ?? match[3] ?? match[4] ?? match[5] ?? text;\n return text;\n}\n\n/** Replace printf-style format specifiers (%s, %d, %v, %f) with {}. */\nfunction normalizeFormatSpecifiers(s: string): string {\n return s.replace(/%[sdvf]/g, '{}');\n}\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst DOTNET_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string_literal', 'interpolated_string_expression'],\n contentNodeTypes: ['string_content', 'string_literal_content'],\n interpolationNodeTypes: ['interpolation'],\n};\n\nconst DECLARATION_TYPES = new Set([\n 'class_declaration',\n 'struct_declaration',\n 'interface_declaration',\n 'enum_declaration',\n 'record_declaration',\n]);\n\nfunction extractDeclarationName(node: Parser.SyntaxNode): string | null {\n if (DECLARATION_TYPES.has(node.type)) {\n const nameNode = node.childForFieldName('name') ?? node.children.find((c) => c.type === 'identifier');\n return nameNode?.text ?? null;\n }\n if (node.type === 'namespace_declaration' || node.type === 'file_scoped_namespace_declaration') {\n const nameNode =\n node.children.find((c) => c.type === 'qualified_name') ?? node.children.find((c) => c.type === 'identifier');\n return nameNode ? `__namespace:${nameNode.text}` : null;\n }\n return null;\n}\n\nfunction collectPrecedingXmlDocComments(\n children: Parser.SyntaxNode[],\n index: number,\n source: string,\n): DocstringInfo | null {\n let lastIdx = -1;\n let firstIdx = -1;\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('///')) {\n if (lastIdx === -1) lastIdx = k;\n firstIdx = k;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n if (firstIdx === -1) return null;\n const first = children[firstIdx];\n const last = children[lastIdx];\n return { text: source.slice(first.startIndex, last.endIndex), startIndex: first.startIndex, endIndex: last.endIndex };\n}\n\n/**\n * Collect declarations from a list of sibling nodes (root level or namespace body).\n */\nfunction collectDeclarations(\n children: Parser.SyntaxNode[],\n source: string,\n statements: MergeStatement[],\n imports: MergeImport[],\n importAnchors: string[],\n importInsertionAnchor: { value?: string },\n): void {\n for (const child of children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'using_directive') {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n if (child.type === 'file_scoped_namespace_declaration') {\n importInsertionAnchor.value = source.slice(child.startIndex, child.endIndex);\n // File-scoped namespace: subsequent declarations are siblings at root\n continue;\n }\n\n if (child.type === 'namespace_declaration') {\n importInsertionAnchor.value = source.slice(child.startIndex, child.endIndex);\n // Block namespace: recurse into declaration_list\n const body = child.children.find((c) => c.type === 'declaration_list');\n if (body) {\n collectDeclarations(body.namedChildren, source, statements, imports, importAnchors, importInsertionAnchor);\n }\n continue;\n }\n\n const name = extractDeclarationName(child);\n statements.push({\n key: name,\n kind: name ? 'declaration' : 'other',\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n}\n\nexport const dotnetMergeAdapter: MergeAdapter = {\n language: 'dotnet',\n grammarModule: 'tree-sitter-c-sharp',\n testFilePatterns: [/Tests?\\.cs$/],\n urlFingerprintConfig: DOTNET_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n const importInsertionAnchor: { value?: string } = {};\n\n collectDeclarations(tree.rootNode.children, source, statements, imports, importAnchors, importInsertionAnchor);\n\n return {\n imports,\n importAnchors,\n importInsertionAnchor: importInsertionAnchor.value,\n statements,\n };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n\n function processChildren(children: Parser.SyntaxNode[]): void {\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n\n // Recurse into namespaces\n if (child.type === 'namespace_declaration') {\n const body = child.children.find((c) => c.type === 'declaration_list');\n if (body) processChildren(body.children);\n continue;\n }\n\n const name = extractDeclarationName(child);\n if (!name || name.startsWith('__namespace:')) continue;\n\n const docstring = collectPrecedingXmlDocComments(children, i, source);\n const members = new Map<string, MemberDocstrings>();\n\n // Extract member docstrings\n const body = child.children.find((c) => c.type === 'declaration_list');\n if (body) {\n const bodyChildren = body.children;\n for (let j = 0; j < bodyChildren.length; j++) {\n const member = bodyChildren[j];\n if (member.type !== 'method_declaration' && member.type !== 'property_declaration') continue;\n // For methods, the second identifier is the name (first is return type)\n const identifiers = member.children.filter((c) => c.type === 'identifier');\n const memberName =\n member.type === 'method_declaration'\n ? identifiers.length >= 2\n ? identifiers[1]!.text\n : identifiers[0]?.text\n : identifiers[0]?.text;\n if (!memberName) continue;\n const memberDoc = collectPrecedingXmlDocComments(bodyChildren, j, source);\n members.set(memberName, {\n docstring: memberDoc,\n declStartIndex: member.startIndex,\n declColumn: member.startPosition.column,\n urlFingerprint: extractUrlFingerprint(member, DOTNET_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n\n result.set(name, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n }\n\n processChildren(tree.rootNode.children);\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst ELIXIR_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string'],\n contentNodeTypes: ['quoted_content'],\n interpolationNodeTypes: ['interpolation'],\n};\n\nfunction isDefmodule(node: Parser.SyntaxNode): boolean {\n return node.type === 'call' && node.children[0]?.text === 'defmodule';\n}\n\nfunction getModuleName(node: Parser.SyntaxNode): string | null {\n if (!isDefmodule(node)) return null;\n const args = node.children.find((c) => c.type === 'arguments');\n if (!args) return null;\n const alias = args.children.find((c) => c.type === 'alias');\n return alias?.text ?? null;\n}\n\nfunction getDoBlock(node: Parser.SyntaxNode): Parser.SyntaxNode | null {\n return node.children.find((c) => c.type === 'do_block') ?? null;\n}\n\n/** Check if a node is an @moduledoc or @doc attribute. */\nfunction isDocAttribute(node: Parser.SyntaxNode): string | null {\n if (node.type !== 'unary_operator') return null;\n const call = node.children.find((c) => c.type === 'call');\n if (!call) return null;\n const id = call.children.find((c) => c.type === 'identifier');\n if (id?.text === 'moduledoc' || id?.text === 'doc') return id.text;\n return null;\n}\n\n/** Check if a node is a def/defp call. */\nfunction getDefName(node: Parser.SyntaxNode): string | null {\n if (node.type !== 'call') return null;\n const id = node.children[0];\n if (!id || (id.text !== 'def' && id.text !== 'defp')) return null;\n const args = node.children.find((c) => c.type === 'arguments');\n if (!args) return null;\n // The function name is either a simple identifier or a call (for functions with params)\n for (const arg of args.namedChildren) {\n if (arg.type === 'identifier') return arg.text;\n if (arg.type === 'call') {\n const nameNode = arg.children.find((c) => c.type === 'identifier');\n return nameNode?.text ?? null;\n }\n }\n return null;\n}\n\n/** Check if a node is an alias/import/require/use call. */\nfunction isImportLike(node: Parser.SyntaxNode): boolean {\n if (node.type !== 'call') return false;\n const id = node.children[0];\n return id?.type === 'identifier' && ['alias', 'import', 'require', 'use'].includes(id.text);\n}\n\nexport const elixirMergeAdapter: MergeAdapter = {\n language: 'elixir',\n grammarModule: 'tree-sitter-elixir',\n testFilePatterns: [/_test\\.exs$/],\n urlFingerprintConfig: ELIXIR_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n // Top-level alias/import/require/use (rare but possible outside modules)\n if (isImportLike(child)) {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n const moduleName = getModuleName(child);\n statements.push({\n key: moduleName,\n kind: moduleName ? 'declaration' : 'other',\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const moduleName = getModuleName(child);\n if (!moduleName) continue;\n\n // Look for @moduledoc inside the do_block\n let docstring: DocstringInfo | null = null;\n const doBlock = getDoBlock(child);\n const members = new Map<string, MemberDocstrings>();\n\n if (doBlock) {\n const bodyChildren = doBlock.children;\n\n // Find @moduledoc\n for (const bodyChild of bodyChildren) {\n if (isDocAttribute(bodyChild) === 'moduledoc') {\n docstring = {\n text: source.slice(bodyChild.startIndex, bodyChild.endIndex),\n startIndex: bodyChild.startIndex,\n endIndex: bodyChild.endIndex,\n };\n break;\n }\n }\n\n // Find @doc + def pairs for member docstrings\n for (let j = 0; j < bodyChildren.length; j++) {\n const bodyChild = bodyChildren[j];\n const defName = getDefName(bodyChild);\n if (!defName) continue;\n\n // Look for preceding @doc attribute\n let memberDoc: DocstringInfo | null = null;\n for (let k = j - 1; k >= 0; k--) {\n const prev = bodyChildren[k];\n if (isDocAttribute(prev) === 'doc') {\n memberDoc = {\n text: source.slice(prev.startIndex, prev.endIndex),\n startIndex: prev.startIndex,\n endIndex: prev.endIndex,\n };\n break;\n }\n if (prev.type === 'comment') continue;\n break;\n }\n\n members.set(defName, {\n docstring: memberDoc,\n declStartIndex: bodyChild.startIndex,\n declColumn: bodyChild.startPosition.column,\n urlFingerprint: extractUrlFingerprint(bodyChild, ELIXIR_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n\n result.set(moduleName, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type { MergeAdapter, MergeStatement, MergeImport, DocstringInfo, SymbolDocstrings } from './types.js';\n\nconst GO_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['interpreted_string_literal'],\n contentNodeTypes: ['interpreted_string_literal_content'],\n interpolationNodeTypes: [],\n formatFunctionNames: ['Sprintf'],\n};\n\nfunction lastIdentifier(text: string): string | null {\n const matches = [...text.matchAll(/[A-Za-z_][A-Za-z0-9_]*/g)];\n return matches.length > 0 ? matches[matches.length - 1]![0] : null;\n}\n\nfunction receiverKey(node: Parser.SyntaxNode): string | null {\n const receiver = node.childForFieldName('receiver');\n if (!receiver) return null;\n return lastIdentifier(receiver.text);\n}\n\nfunction declarationKey(node: Parser.SyntaxNode): string | null {\n switch (node.type) {\n case 'package_clause': {\n const pkg = lastIdentifier(node.text);\n return pkg ? `__package:${pkg}` : '__package:';\n }\n case 'type_declaration': {\n const spec = node.firstNamedChild?.type === 'type_spec' ? node.firstNamedChild : node.namedChildren[0];\n const nameNode = spec?.childForFieldName('name');\n return nameNode?.text ?? null;\n }\n case 'function_declaration': {\n return node.childForFieldName('name')?.text ?? null;\n }\n case 'method_declaration': {\n const name = node.childForFieldName('name')?.text ?? null;\n const receiver = receiverKey(node);\n return name && receiver ? `method:${receiver}.${name}` : name;\n }\n case 'const_declaration':\n case 'var_declaration': {\n return node.text.split(/\\s+/).slice(0, 3).join(' ');\n }\n default:\n return null;\n }\n}\n\nfunction importEntries(node: Parser.SyntaxNode, source: string): MergeImport[] {\n const entries: MergeImport[] = [];\n\n const collect = (spec: Parser.SyntaxNode): void => {\n const path = spec.childForFieldName('path')?.text ?? spec.text;\n const name = spec.childForFieldName('name')?.text ?? '';\n const text = source.slice(spec.startIndex, spec.endIndex);\n entries.push({\n key: `${name}:${path.replace(/^\"|\"$/g, '')}`,\n text,\n });\n };\n\n for (const child of node.namedChildren) {\n if (child.type === 'import_spec') {\n collect(child);\n continue;\n }\n if (child.type === 'import_spec_list') {\n for (const spec of child.namedChildren) {\n if (spec.type === 'import_spec') collect(spec);\n }\n }\n }\n\n return entries;\n}\n\nfunction collectPrecedingGoComments(\n children: Parser.SyntaxNode[],\n index: number,\n source: string,\n): DocstringInfo | null {\n let lastIdx = -1;\n let firstIdx = -1;\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('//')) {\n if (lastIdx === -1) lastIdx = k;\n firstIdx = k;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n if (firstIdx === -1) return null;\n const first = children[firstIdx];\n const last = children[lastIdx];\n return { text: source.slice(first.startIndex, last.endIndex), startIndex: first.startIndex, endIndex: last.endIndex };\n}\n\nexport const goMergeAdapter: MergeAdapter = {\n language: 'go',\n grammarModule: 'tree-sitter-go',\n testFilePatterns: [/_test\\.go$/],\n urlFingerprintConfig: GO_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n let importInsertionAnchor: string | undefined;\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'package_clause') {\n importInsertionAnchor = source.slice(child.startIndex, child.endIndex);\n }\n\n if (child.type === 'import_declaration') {\n imports.push(...importEntries(child, source));\n importAnchors.push(source.slice(child.startIndex, child.endIndex));\n continue;\n }\n\n const key = declarationKey(child);\n statements.push({\n key,\n kind: key ? 'declaration' : 'other',\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, importInsertionAnchor, statements };\n },\n renderImports(imports) {\n if (imports.length === 0) return [];\n if (imports.length === 1) return [`import ${imports[0]!.text}`];\n return [`import (\\n${imports.map((entry) => ` ${entry.text}`).join('\\n')}\\n)`];\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const key = declarationKey(child);\n if (!key || key.startsWith('__package:')) continue;\n\n const docstring = collectPrecedingGoComments(rootChildren, i, source);\n result.set(key, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members: new Map(),\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst KOTLIN_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string_literal'],\n contentNodeTypes: ['string_content'],\n interpolationNodeTypes: ['interpolated_expression'],\n};\n\nfunction extractDeclarationName(node: Parser.SyntaxNode): string | null {\n if (node.type === 'class_declaration') {\n // Handles class, data class, enum class, etc.\n const nameNode = node.children.find((c) => c.type === 'type_identifier');\n return nameNode?.text ?? null;\n }\n if (node.type === 'function_declaration') {\n const nameNode = node.children.find((c) => c.type === 'simple_identifier');\n return nameNode?.text ?? null;\n }\n if (node.type === 'object_declaration') {\n const nameNode = node.children.find((c) => c.type === 'type_identifier');\n return nameNode?.text ?? null;\n }\n if (node.type === 'type_alias') {\n const nameNode = node.children.find((c) => c.type === 'type_identifier');\n return nameNode?.text ?? null;\n }\n if (node.type === 'property_declaration') {\n const nameNode = node.children.find((c) => c.type === 'variable_declaration');\n if (nameNode) {\n const id = nameNode.children.find((c) => c.type === 'simple_identifier');\n return id?.text ?? null;\n }\n }\n return null;\n}\n\nfunction findPrecedingKdoc(children: Parser.SyntaxNode[], index: number, source: string): DocstringInfo | null {\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'multiline_comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('/**')) {\n return { text, startIndex: prev.startIndex, endIndex: prev.endIndex };\n }\n return null;\n }\n if (prev.type === 'line_comment') continue;\n return null;\n }\n return null;\n}\n\nexport const kotlinMergeAdapter: MergeAdapter = {\n language: 'kotlin',\n grammarModule: 'tree-sitter-kotlin',\n testFilePatterns: [/Test\\.kt$/],\n urlFingerprintConfig: KOTLIN_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'multiline_comment' || child.type === 'line_comment') continue;\n\n if (child.type === 'import_list') {\n const fullText = source.slice(child.startIndex, child.endIndex);\n importAnchors.push(fullText);\n for (const imp of child.namedChildren) {\n if (imp.type === 'import_header') {\n const text = source.slice(imp.startIndex, imp.endIndex).trim();\n // Key on the full import path\n const idNode = imp.children.find((c) => c.type === 'identifier');\n const key = idNode?.text ?? text;\n imports.push({ key, text });\n }\n }\n continue;\n }\n\n const name = extractDeclarationName(child);\n statements.push({\n key: name,\n kind: name ? 'declaration' : 'other',\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const name = extractDeclarationName(child);\n if (!name) continue;\n\n const docstring = findPrecedingKdoc(rootChildren, i, source);\n const members = new Map<string, MemberDocstrings>();\n\n // Extract member docstrings for classes\n if (child.type === 'class_declaration') {\n const body = child.children.find((c) => c.type === 'class_body' || c.type === 'enum_class_body');\n if (body) {\n const bodyChildren = body.children;\n for (let j = 0; j < bodyChildren.length; j++) {\n const member = bodyChildren[j];\n const memberName = extractDeclarationName(member);\n if (!memberName) continue;\n const memberDoc = findPrecedingKdoc(bodyChildren, j, source);\n members.set(memberName, {\n docstring: memberDoc,\n declStartIndex: member.startIndex,\n declColumn: member.startPosition.column,\n urlFingerprint: extractUrlFingerprint(member, KOTLIN_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n }\n\n result.set(name, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport { normalizeJsExtension } from '../../utils/naming.js';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DeepMergeSymbol,\n MergeMember,\n DocstringInfo,\n SymbolDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst REEXPORT_PREFIX = '__export:';\n\nfunction extractDeclName(node: Parser.SyntaxNode): string | null {\n const nameNode = node.childForFieldName('name');\n if (nameNode) return nameNode.text;\n\n if (node.type === 'lexical_declaration') {\n const declarator = node.firstNamedChild;\n if (declarator?.type === 'variable_declarator') {\n const name = declarator.childForFieldName('name');\n if (name) return name.text;\n }\n }\n\n return null;\n}\n\nfunction extractNodeKey(node: Parser.SyntaxNode): { key: string | null; kind: MergeStatement['kind'] } {\n if (node.type === 'export_statement') {\n const decl = node.childForFieldName('declaration');\n if (decl) {\n return { key: extractDeclName(decl), kind: 'declaration' };\n }\n\n const source = node.childForFieldName('source');\n if (source) {\n return { key: `${REEXPORT_PREFIX}${normalizeJsExtension(source.text)}`, kind: 'reexport' };\n }\n\n return { key: null, kind: 'other' };\n }\n return { key: extractDeclName(node), kind: extractDeclName(node) ? 'declaration' : 'other' };\n}\n\nfunction extractClassMembers(classBody: Parser.SyntaxNode, source: string): MergeMember[] {\n const members: MergeMember[] = [];\n for (const child of classBody.namedChildren) {\n if (child.type === 'method_definition') {\n const nameNode = child.childForFieldName('name');\n if (nameNode && nameNode.text !== 'constructor') {\n members.push({ key: nameNode.text, text: source.slice(child.startIndex, child.endIndex) });\n }\n } else if (child.type === 'public_field_definition') {\n const nameNode = child.childForFieldName('name');\n if (nameNode) {\n // tree-sitter may exclude the trailing semicolon from\n // public_field_definition nodes — include it if present\n let endIdx = child.endIndex;\n if (source[endIdx] === ';') {\n endIdx += 1;\n }\n members.push({ key: nameNode.text, text: source.slice(child.startIndex, endIdx) });\n }\n }\n }\n return members;\n}\n\nfunction extractInterfaceMembers(body: Parser.SyntaxNode, source: string): MergeMember[] {\n const members: MergeMember[] = [];\n for (const child of body.namedChildren) {\n if (child.type === 'property_signature' || child.type === 'method_signature') {\n const nameNode = child.childForFieldName('name');\n if (nameNode) {\n members.push({ key: nameNode.text, text: source.slice(child.startIndex, child.endIndex) });\n }\n }\n }\n return members;\n}\n\nfunction extractEnumMembers(body: Parser.SyntaxNode, source: string): MergeMember[] {\n const members: MergeMember[] = [];\n for (const child of body.namedChildren) {\n if (child.type === 'enum_assignment') {\n const nameNode = child.childForFieldName('name');\n if (nameNode) {\n members.push({ key: nameNode.text, text: source.slice(child.startIndex, child.endIndex) });\n }\n } else if (child.type === 'property_identifier') {\n members.push({ key: child.text, text: source.slice(child.startIndex, child.endIndex) });\n }\n }\n return members;\n}\n\nfunction isCommentNode(node: Parser.SyntaxNode): boolean {\n // tree-sitter extras (comments) may report the parent node's type\n // instead of 'comment' — check grammarType as fallback\n return node.type === 'comment' || (node as any).grammarType === 'comment';\n}\n\nfunction findPrecedingDocstring(children: Parser.SyntaxNode[], index: number, source: string): DocstringInfo | null {\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (isCommentNode(prev)) {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('/**')) {\n return { text, startIndex: prev.startIndex, endIndex: prev.endIndex };\n }\n return null;\n }\n if (prev.type === ',' || prev.type === ';' || prev.type === '{') continue;\n return null;\n }\n return null;\n}\n\nconst CLASS_MEMBER_TYPES = new Set(['method_definition', 'public_field_definition']);\nconst INTERFACE_MEMBER_TYPES = new Set(['property_signature', 'method_signature']);\nconst ENUM_MEMBER_TYPES = new Set(['enum_assignment', 'property_identifier']);\n\nconst NODE_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string', 'template_string'],\n contentNodeTypes: ['string_fragment'],\n interpolationNodeTypes: ['template_substitution'],\n};\n\nfunction extractBodyMemberDocstrings(\n body: Parser.SyntaxNode,\n source: string,\n memberTypes: Set<string>,\n): Map<\n string,\n { docstring: DocstringInfo | null; declStartIndex: number; declColumn: number; urlFingerprint?: string }\n> {\n const result = new Map<\n string,\n { docstring: DocstringInfo | null; declStartIndex: number; declColumn: number; urlFingerprint?: string }\n >();\n const allChildren = body.children;\n for (let i = 0; i < allChildren.length; i++) {\n const child = allChildren[i];\n if (!memberTypes.has(child.type)) continue;\n let memberName: string | null = null;\n if (child.type === 'property_identifier') {\n memberName = child.text;\n } else {\n const nameNode = child.childForFieldName('name');\n if (nameNode) memberName = nameNode.text;\n }\n if (!memberName || memberName === 'constructor') continue;\n const docstring = findPrecedingDocstring(allChildren, i, source);\n const fp = extractUrlFingerprint(child, NODE_URL_FINGERPRINT_CONFIG);\n result.set(memberName, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n urlFingerprint: fp,\n });\n }\n return result;\n}\n\nexport const nodeMergeAdapter: MergeAdapter = {\n language: 'node',\n grammarModule: 'tree-sitter-typescript/bindings/node/typescript.js',\n normalizeReexport: normalizeJsExtension,\n testFilePatterns: [/\\.(spec|test)\\.[jt]sx?$/],\n urlFingerprintConfig: NODE_URL_FINGERPRINT_CONFIG,\n shouldSkipDeepMerge(_symbolName, existingMemberKeys, newMembers) {\n // If new members reference instance properties (this.X) that don't exist\n // in the target class, the merged code would be broken.\n const newText = newMembers.map((m) => m.text).join('\\n');\n for (const match of newText.matchAll(/this\\.(\\w+)/g)) {\n const propName = match[1];\n if (propName && !existingMemberKeys.has(propName)) {\n return true;\n }\n }\n return false;\n },\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'import_statement') {\n const text = source.slice(child.startIndex, child.endIndex);\n // Key on module path so `import { X }` and `import type { X }` from\n // the same module are treated as duplicates\n const sourceNode = child.childForFieldName('source');\n const modulePath = sourceNode ? normalizeJsExtension(sourceNode.text) : normalizeJsExtension(text.trim());\n imports.push({ key: modulePath, text });\n importAnchors.push(text);\n continue;\n }\n\n const { key, kind } = extractNodeKey(child);\n statements.push({\n key,\n kind,\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractMembers(tree, source) {\n const result = new Map<string, DeepMergeSymbol>();\n\n for (const child of tree.rootNode.children) {\n if (child.type !== 'export_statement') continue;\n const decl = child.childForFieldName('declaration');\n if (!decl) continue;\n\n const nameNode = decl.childForFieldName('name');\n if (!nameNode) continue;\n const symbolName = nameNode.text;\n\n if (decl.type === 'class_declaration') {\n const body = decl.childForFieldName('body');\n if (!body) continue;\n const members = extractClassMembers(body, source);\n const firstMember = body.firstNamedChild;\n const memberIndent = firstMember ? ' '.repeat(firstMember.startPosition.column) : undefined;\n result.set(symbolName, { members, bodyEndLine: body.endPosition.row, memberIndent });\n } else if (decl.type === 'interface_declaration') {\n const body = decl.childForFieldName('body');\n if (!body) continue;\n const members = extractInterfaceMembers(body, source);\n const firstMember = body.firstNamedChild;\n const memberIndent = firstMember ? ' '.repeat(firstMember.startPosition.column) : undefined;\n result.set(symbolName, { members, bodyEndLine: body.endPosition.row, memberIndent });\n } else if (decl.type === 'enum_declaration') {\n const body = decl.childForFieldName('body');\n if (!body) continue;\n const members = extractEnumMembers(body, source);\n const firstMember = body.firstNamedChild;\n const memberIndent = firstMember ? ' '.repeat(firstMember.startPosition.column) : undefined;\n result.set(symbolName, { members, bodyEndLine: body.endPosition.row, memberIndent });\n }\n }\n\n return result;\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n if (child.type !== 'export_statement') continue;\n const decl = child.childForFieldName('declaration');\n if (!decl) continue;\n const nameNode = decl.childForFieldName('name');\n if (!nameNode) continue;\n\n // Find preceding JSDoc for this top-level symbol\n const docstring = findPrecedingDocstring(rootChildren, i, source);\n\n // Extract member-level docstrings\n let members = new Map<string, { docstring: DocstringInfo | null; declStartIndex: number; declColumn: number }>();\n const body = decl.childForFieldName('body');\n if (body) {\n if (decl.type === 'class_declaration') {\n members = extractBodyMemberDocstrings(body, source, CLASS_MEMBER_TYPES);\n } else if (decl.type === 'interface_declaration') {\n members = extractBodyMemberDocstrings(body, source, INTERFACE_MEMBER_TYPES);\n } else if (decl.type === 'enum_declaration') {\n members = extractBodyMemberDocstrings(body, source, ENUM_MEMBER_TYPES);\n }\n }\n\n result.set(nameNode.text, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst PHP_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['encapsed_string', 'string'],\n contentNodeTypes: ['string_content'],\n interpolationNodeTypes: ['variable_name'],\n};\n\nfunction extractPhpDeclarationName(node: Parser.SyntaxNode): string | null {\n switch (node.type) {\n case 'class_declaration':\n case 'interface_declaration':\n case 'trait_declaration':\n case 'enum_declaration':\n case 'function_definition': {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text ?? null;\n }\n case 'namespace_definition': {\n const nameNode = node.childForFieldName('name');\n return nameNode ? `__namespace:${nameNode.text}` : '__namespace:';\n }\n default:\n return null;\n }\n}\n\nfunction findPhpDocstring(children: Parser.SyntaxNode[], index: number, source: string): DocstringInfo | null {\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('/**')) {\n return { text, startIndex: prev.startIndex, endIndex: prev.endIndex };\n }\n return null;\n }\n if (prev.type === ';' || prev.type === '{') continue;\n return null;\n }\n return null;\n}\n\nexport const phpMergeAdapter: MergeAdapter = {\n language: 'php',\n grammarModule: 'tree-sitter-php',\n testFilePatterns: [/Test\\.php$/],\n urlFingerprintConfig: PHP_URL_FINGERPRINT_CONFIG,\n resolveGrammar: (mod) => {\n if (typeof mod === 'object' && mod !== null && 'php' in mod) return (mod as { php: unknown }).php;\n return mod;\n },\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n let importInsertionAnchor: string | undefined;\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'namespace_definition') {\n importInsertionAnchor = source.slice(child.startIndex, child.endIndex);\n }\n\n if (child.type === 'namespace_use_declaration') {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n const declarationName = extractPhpDeclarationName(child);\n const kind: MergeStatement['kind'] = declarationName ? 'declaration' : 'other';\n\n statements.push({\n key: declarationName,\n kind,\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, importInsertionAnchor, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const name = extractPhpDeclarationName(child);\n if (!name || name.startsWith('__namespace:')) continue;\n\n const docstring = findPhpDocstring(rootChildren, i, source);\n const members = new Map<string, MemberDocstrings>();\n\n const body = child.childForFieldName('body');\n if (body) {\n const bodyChildren = body.children;\n for (let j = 0; j < bodyChildren.length; j++) {\n const member = bodyChildren[j];\n if (member.type !== 'method_declaration') continue;\n const memberName = member.childForFieldName('name')?.text;\n if (!memberName) continue;\n const memberDoc = findPhpDocstring(bodyChildren, j, source);\n members.set(memberName, {\n docstring: memberDoc,\n declStartIndex: member.startIndex,\n declColumn: member.startPosition.column,\n urlFingerprint: extractUrlFingerprint(member, PHP_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n\n result.set(name, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst PYTHON_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string'],\n contentNodeTypes: ['string_content'],\n interpolationNodeTypes: ['interpolation'],\n};\n\nfunction extractPythonDeclarationName(node: Parser.SyntaxNode): string | null {\n if (node.type === 'class_definition' || node.type === 'function_definition') {\n const nameNode = node.childForFieldName('name');\n return nameNode?.text ?? null;\n }\n\n // Detect `__all__ = [...]` assignments so they get a key and can be deduplicated\n if (node.type === 'expression_statement') {\n const firstChild = node.firstNamedChild;\n if (firstChild?.type === 'assignment') {\n const left = firstChild.childForFieldName('left');\n if (left?.type === 'identifier' && left.text === '__all__') {\n return '__all__';\n }\n }\n }\n\n return null;\n}\n\nfunction extractPythonDocstring(bodyNode: Parser.SyntaxNode, source: string): DocstringInfo | null {\n // Python docstrings are the first expression_statement in a body block\n // where the expression is a string literal\n for (const child of bodyNode.namedChildren) {\n if (child.type === 'expression_statement') {\n const expr = child.firstNamedChild;\n if (expr?.type === 'string') {\n const text = source.slice(child.startIndex, child.endIndex);\n return { text, startIndex: child.startIndex, endIndex: child.endIndex };\n }\n }\n // Only the FIRST statement can be a docstring\n break;\n }\n return null;\n}\n\nfunction collectPrecedingPythonComments(\n children: Parser.SyntaxNode[],\n index: number,\n source: string,\n): DocstringInfo | null {\n let lastIdx = -1;\n let firstIdx = -1;\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'comment') {\n if (lastIdx === -1) lastIdx = k;\n firstIdx = k;\n } else {\n break;\n }\n }\n if (firstIdx === -1) return null;\n const first = children[firstIdx];\n const last = children[lastIdx];\n return { text: source.slice(first.startIndex, last.endIndex), startIndex: first.startIndex, endIndex: last.endIndex };\n}\n\nexport const pythonMergeAdapter: MergeAdapter = {\n language: 'python',\n grammarModule: 'tree-sitter-python',\n testFilePatterns: [/(?:^|\\/)test_.*\\.py$/, /_test\\.py$/],\n urlFingerprintConfig: PYTHON_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'import_statement' || child.type === 'import_from_statement') {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n const declarationName = extractPythonDeclarationName(child);\n const kind: MergeStatement['kind'] = declarationName ? 'declaration' : 'other';\n\n statements.push({\n key: declarationName,\n kind,\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const name = extractPythonDeclarationName(child);\n if (!name) continue;\n\n // Python: class/function docstrings are inside the body, OR use # comments before\n let docstring: DocstringInfo | null = null;\n const body = child.childForFieldName('body');\n if (body) {\n docstring = extractPythonDocstring(body, source);\n }\n // Fallback: check for # comments before the declaration\n if (!docstring) {\n docstring = collectPrecedingPythonComments(rootChildren, i, source);\n }\n\n const members = new Map<string, MemberDocstrings>();\n\n // Extract method docstrings for classes\n if (child.type === 'class_definition' && body) {\n for (const member of body.namedChildren) {\n if (member.type !== 'function_definition') continue;\n const memberName = member.childForFieldName('name')?.text;\n if (!memberName) continue;\n\n let memberDoc: DocstringInfo | null = null;\n const memberBody = member.childForFieldName('body');\n if (memberBody) {\n memberDoc = extractPythonDocstring(memberBody, source);\n }\n\n members.set(memberName, {\n docstring: memberDoc,\n declStartIndex: member.startIndex,\n declColumn: member.startPosition.column,\n urlFingerprint: extractUrlFingerprint(member, PYTHON_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n\n result.set(name, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type {\n MergeAdapter,\n MergeStatement,\n MergeImport,\n DocstringInfo,\n SymbolDocstrings,\n MemberDocstrings,\n} from './types.js';\nimport { extractUrlFingerprint } from './url-fingerprint.js';\n\nconst RUBY_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string'],\n contentNodeTypes: ['string_content'],\n interpolationNodeTypes: ['interpolation'],\n};\n\nfunction isRequireCall(node: Parser.SyntaxNode): boolean {\n if (node.type !== 'call') return false;\n const method = node.childForFieldName('method');\n if (!method) return false;\n return method.text === 'require' || method.text === 'require_relative';\n}\n\nfunction extractRubyDeclarationName(node: Parser.SyntaxNode): string | null {\n if (node.type !== 'class' && node.type !== 'module') return null;\n const nameNode = node.childForFieldName('name');\n return nameNode?.text ?? null;\n}\n\nfunction collectPrecedingRubyComments(\n children: Parser.SyntaxNode[],\n index: number,\n source: string,\n): DocstringInfo | null {\n let lastIdx = -1;\n let firstIdx = -1;\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n const nodeType = (prev as any).grammarType ?? prev.type;\n if (nodeType === 'comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('#')) {\n if (lastIdx === -1) lastIdx = k;\n firstIdx = k;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n if (firstIdx === -1) return null;\n const first = children[firstIdx];\n const last = children[lastIdx];\n return { text: source.slice(first.startIndex, last.endIndex), startIndex: first.startIndex, endIndex: last.endIndex };\n}\n\nexport const rubyMergeAdapter: MergeAdapter = {\n language: 'ruby',\n grammarModule: 'tree-sitter-ruby',\n testFilePatterns: [/_test\\.rb$/, /_spec\\.rb$/],\n urlFingerprintConfig: RUBY_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n const declarationName = extractRubyDeclarationName(child);\n if (isRequireCall(child)) {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n const kind: MergeStatement['kind'] = declarationName ? 'declaration' : 'other';\n\n statements.push({\n key: declarationName,\n kind,\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const name = extractRubyDeclarationName(child);\n if (!name) continue;\n\n const docstring = collectPrecedingRubyComments(rootChildren, i, source);\n const members = new Map<string, MemberDocstrings>();\n\n // Ruby class/module bodies: comments may appear in class children\n // (before body_statement) or in body_statement children (between methods)\n if (child.type === 'class' || child.type === 'module') {\n const allClassChildren = child.children;\n const body = child.childForFieldName('body');\n\n // Check for comment before body_statement in class children\n // (docstring for the first method)\n let firstMethodDocFromClass: DocstringInfo | null = null;\n for (let j = 0; j < allClassChildren.length; j++) {\n if (allClassChildren[j] === body || allClassChildren[j].type === 'body_statement') {\n firstMethodDocFromClass = collectPrecedingRubyComments(allClassChildren, j, source);\n break;\n }\n }\n\n if (body) {\n const bodyChildren = body.children;\n let firstMethodHandled = false;\n for (let j = 0; j < bodyChildren.length; j++) {\n const member = bodyChildren[j];\n if (member.type !== 'method') continue;\n const memberName = member.childForFieldName('name')?.text;\n if (!memberName) continue;\n\n let memberDoc: DocstringInfo | null;\n if (!firstMethodHandled && firstMethodDocFromClass) {\n memberDoc = firstMethodDocFromClass;\n firstMethodHandled = true;\n } else {\n memberDoc = collectPrecedingRubyComments(bodyChildren, j, source);\n firstMethodHandled = true;\n }\n\n members.set(memberName, {\n docstring: memberDoc,\n declStartIndex: member.startIndex,\n declColumn: member.startPosition.column,\n urlFingerprint: extractUrlFingerprint(member, RUBY_URL_FINGERPRINT_CONFIG),\n });\n }\n }\n }\n\n result.set(name, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members,\n });\n }\n\n return result;\n },\n};\n","import type Parser from 'tree-sitter';\nimport type { MergeAdapter, MergeStatement, MergeImport, DocstringInfo, SymbolDocstrings } from './types.js';\n\nconst RUST_URL_FINGERPRINT_CONFIG = {\n stringNodeTypes: ['string_literal'],\n contentNodeTypes: ['string_content'],\n interpolationNodeTypes: [],\n};\n\nfunction declarationKey(node: Parser.SyntaxNode): string | null {\n switch (node.type) {\n case 'struct_item':\n case 'enum_item':\n case 'function_item':\n case 'trait_item':\n case 'type_item':\n case 'const_item': {\n return node.childForFieldName('name')?.text ?? null;\n }\n case 'impl_item': {\n const typeName = node.childForFieldName('type')?.text ?? 'unknown';\n const traitName = node.childForFieldName('trait')?.text;\n return traitName ? `impl:${traitName}->${typeName}` : `impl:${typeName}`;\n }\n default:\n return null;\n }\n}\n\nfunction collectPrecedingRustDocComments(\n children: Parser.SyntaxNode[],\n index: number,\n source: string,\n): DocstringInfo | null {\n let lastIdx = -1;\n let firstIdx = -1;\n for (let k = index - 1; k >= 0; k--) {\n const prev = children[k];\n if (prev.type === 'line_comment') {\n const text = source.slice(prev.startIndex, prev.endIndex);\n if (text.startsWith('///')) {\n if (lastIdx === -1) lastIdx = k;\n firstIdx = k;\n } else {\n break;\n }\n } else {\n break;\n }\n }\n if (firstIdx === -1) return null;\n const first = children[firstIdx];\n const last = children[lastIdx];\n return { text: source.slice(first.startIndex, last.endIndex), startIndex: first.startIndex, endIndex: last.endIndex };\n}\n\nexport const rustMergeAdapter: MergeAdapter = {\n language: 'rust',\n grammarModule: 'tree-sitter-rust',\n testFilePatterns: [/_test\\.rs$/, /(?:^|\\/)tests\\/.*\\.rs$/],\n urlFingerprintConfig: RUST_URL_FINGERPRINT_CONFIG,\n parseStatements(tree, source) {\n const imports: MergeImport[] = [];\n const importAnchors: string[] = [];\n const statements: MergeStatement[] = [];\n\n for (const child of tree.rootNode.children) {\n if (child.type === 'comment') continue;\n\n if (child.type === 'use_declaration') {\n const text = source.slice(child.startIndex, child.endIndex);\n imports.push({ key: text.trim(), text });\n importAnchors.push(text);\n continue;\n }\n\n const key = declarationKey(child);\n statements.push({\n key,\n kind: key ? 'declaration' : 'other',\n text: source.slice(child.startIndex, child.endIndex),\n });\n }\n\n return { imports, importAnchors, statements };\n },\n renderImports(imports) {\n return imports.map((entry) => entry.text);\n },\n extractDocstrings(tree, source) {\n const result = new Map<string, SymbolDocstrings>();\n const rootChildren = tree.rootNode.children;\n\n for (let i = 0; i < rootChildren.length; i++) {\n const child = rootChildren[i];\n const key = declarationKey(child);\n if (!key) continue;\n\n const docstring = collectPrecedingRustDocComments(rootChildren, i, source);\n result.set(key, {\n docstring,\n declStartIndex: child.startIndex,\n declColumn: child.startPosition.column,\n members: new Map(),\n });\n }\n\n return result;\n },\n};\n","import type { MergeAdapter } from './types.js';\nimport { dotnetMergeAdapter } from './dotnet.js';\nimport { elixirMergeAdapter } from './elixir.js';\nimport { goMergeAdapter } from './go.js';\nimport { kotlinMergeAdapter } from './kotlin.js';\nimport { nodeMergeAdapter } from './node.js';\nimport { phpMergeAdapter } from './php.js';\nimport { pythonMergeAdapter } from './python.js';\nimport { rubyMergeAdapter } from './ruby.js';\nimport { rustMergeAdapter } from './rust.js';\n\nconst adapters = new Map<string, MergeAdapter>([\n ['dotnet', dotnetMergeAdapter],\n ['elixir', elixirMergeAdapter],\n ['go', goMergeAdapter],\n ['kotlin', kotlinMergeAdapter],\n ['node', nodeMergeAdapter],\n ['php', phpMergeAdapter],\n ['python', pythonMergeAdapter],\n ['ruby', rubyMergeAdapter],\n ['rust', rustMergeAdapter],\n]);\n\nexport function getMergeAdapter(language: string): MergeAdapter | undefined {\n return adapters.get(language);\n}\n","/**\n * AST-level file merger using tree-sitter.\n *\n * When generating into a directory that already contains files, the merger\n * parses both the existing and generated content, detects top-level symbols,\n * and only appends symbols that don't already exist. Hand-written code is\n * never modified or removed.\n *\n * Supports any language with a tree-sitter grammar package.\n */\n\nimport Parser from 'tree-sitter';\nimport { getMergeAdapter } from './merge-adapters/index.js';\nimport type { MergeImport, ParsedMergeFile, SymbolDocstrings } from './merge-adapters/types.js';\n\n// Cache parser instances per language\nconst parserCache = new Map<string, Parser>();\n\nimport { safeParse } from '../utils/tree-sitter.js';\n\n// --- @oagen-ignore region helpers ---\n\ninterface IgnoredRegion {\n startIndex: number;\n endIndex: number;\n}\n\nfunction findIgnoredRegions(source: string): IgnoredRegion[] {\n const regions: IgnoredRegion[] = [];\n const startTag = '@oagen-ignore-start';\n const endTag = '@oagen-ignore-end';\n let searchFrom = 0;\n\n while (true) {\n const startIdx = source.indexOf(startTag, searchFrom);\n if (startIdx === -1) break;\n const endIdx = source.indexOf(endTag, startIdx + startTag.length);\n if (endIdx === -1) break; // Unclosed — silently ignore\n regions.push({ startIndex: startIdx, endIndex: endIdx + endTag.length });\n searchFrom = endIdx + endTag.length;\n }\n\n return regions;\n}\n\nfunction buildIgnoredSymbolNames(docstrings: Map<string, SymbolDocstrings>, regions: IgnoredRegion[]): Set<string> {\n if (regions.length === 0) return new Set();\n const ignored = new Set<string>();\n for (const [name, info] of docstrings) {\n if (regions.some((r) => info.declStartIndex >= r.startIndex && info.declStartIndex <= r.endIndex)) {\n ignored.add(name);\n }\n }\n return ignored;\n}\n\n/**\n * Check if a tree-sitter grammar is configured for the given language.\n */\nexport function hasGrammar(language: string): boolean {\n return getMergeAdapter(language) !== undefined;\n}\n\nasync function getParser(language: string): Promise<Parser> {\n const cached = parserCache.get(language);\n if (cached) return cached;\n\n const adapter = getMergeAdapter(language);\n if (!adapter) {\n throw new Error(\n `No tree-sitter grammar configured for language \"${language}\". ` +\n `Add a merge adapter and install the corresponding tree-sitter grammar package.`,\n );\n }\n\n const mod = await import(adapter.grammarModule);\n const exported = adapter.resolveGrammar ? adapter.resolveGrammar(mod) : mod;\n const grammar = (exported as { default?: unknown }).default ?? exported;\n const parser = new Parser();\n parser.setLanguage(grammar);\n parserCache.set(language, parser);\n return parser;\n}\n\ninterface ParsedSymbols {\n names: Set<string>;\n /** Trimmed text of unnamed top-level statements (for text-based dedup) */\n unnamedTexts: Set<string>;\n}\n\n/**\n * Extract all top-level symbol names (and unnamed statement texts) from source code.\n */\nexport async function extractTopLevelSymbols(source: string, language: string): Promise<ParsedSymbols> {\n const parser = await getParser(language);\n const adapter = getMergeAdapter(language);\n if (!adapter) {\n throw new Error(`No merge adapter configured for language \"${language}\"`);\n }\n if (typeof source !== 'string') {\n throw new Error(`extractTopLevelSymbols: expected string source, got ${typeof source}`);\n }\n const tree = safeParse(parser, source);\n const names = new Set<string>();\n const unnamedTexts = new Set<string>();\n const parsed = adapter.parseStatements(tree, source);\n\n for (const imp of parsed.imports) {\n names.add(imp.key);\n }\n for (const statement of parsed.statements) {\n if (statement.key) {\n names.add(statement.key);\n } else {\n unnamedTexts.add(statement.text.trim());\n }\n }\n\n return { names, unnamedTexts };\n}\n\n/** Convenience wrapper that returns only the name set. */\nexport async function extractTopLevelNames(source: string, language: string): Promise<Set<string>> {\n return (await extractTopLevelSymbols(source, language)).names;\n}\n\n/**\n * Extract top-level statements from generated source with their names\n * and exact text span.\n */\nasync function extractStatements(source: string, language: string): Promise<ParsedMergeFile> {\n const parser = await getParser(language);\n const adapter = getMergeAdapter(language);\n if (!adapter) {\n throw new Error(`No merge adapter configured for language \"${language}\"`);\n }\n const tree = safeParse(parser, source);\n return adapter.parseStatements(tree, source);\n}\n\nexport interface MergeResult {\n content: string;\n added: number;\n preserved: number;\n changed: boolean;\n}\n\n/**\n * Merge generated content into an existing file.\n *\n * - Parses both files with tree-sitter\n * - Detects which top-level symbols already exist\n * - Appends only new symbols\n * - Never modifies or removes existing code\n * - Adds auto-generated header if not present\n */\nexport async function mergeIntoExisting(\n existingContent: string,\n generatedContent: string,\n language: string,\n header: string,\n): Promise<MergeResult> {\n const adapter = getMergeAdapter(language);\n if (!adapter) {\n throw new Error(`No merge adapter configured for language \"${language}\"`);\n }\n\n // Parse existing file once — extract both symbols and statements from the same AST pass\n const existingStatements = await extractStatements(existingContent, language);\n const generatedStatements = await extractStatements(generatedContent, language);\n\n const existingKeys = new Set<string>();\n const existingUnnamedTexts = new Set<string>();\n const existingImportKeys = new Set<string>();\n const existingReexports = new Set<string>();\n let lastImportEndIndex = -1;\n\n // Collect import keys AND imported identifiers (to prevent adding declarations\n // that clash with already-imported names)\n const existingImportedNames = new Set<string>();\n for (const imp of existingStatements.imports) {\n existingImportKeys.add(imp.key);\n // Extract identifiers from import text: import { Foo, Bar } from '...'\n const braceMatch = imp.text.match(/\\{([^}]+)\\}/);\n if (braceMatch) {\n for (const name of braceMatch[1].split(',')) {\n const trimmed = name.replace(/\\btype\\b/, '').trim();\n if (trimmed) existingImportedNames.add(trimmed);\n }\n }\n }\n for (const anchor of existingStatements.importAnchors) {\n const linesBefore = existingContent.slice(0, existingContent.indexOf(anchor)).split('\\n').length - 1;\n const stmtLines = anchor.split('\\n').length;\n lastImportEndIndex = linesBefore + stmtLines - 1;\n }\n if (lastImportEndIndex === -1 && existingStatements.importInsertionAnchor) {\n const linesBefore =\n existingContent.slice(0, existingContent.indexOf(existingStatements.importInsertionAnchor)).split('\\n').length -\n 1;\n const stmtLines = existingStatements.importInsertionAnchor.split('\\n').length;\n lastImportEndIndex = linesBefore + stmtLines - 1;\n }\n\n for (const stmt of existingStatements.statements) {\n if (stmt.kind === 'reexport') {\n existingReexports.add(adapter.normalizeReexport ? adapter.normalizeReexport(stmt.text.trim()) : stmt.text.trim());\n }\n if (stmt.key) {\n existingKeys.add(stmt.key);\n } else {\n existingUnnamedTexts.add(stmt.text.trim());\n }\n }\n\n const headerLine = header.trim();\n\n const newImports: MergeImport[] = [];\n const toAppend: string[] = [];\n let preserved = 0;\n\n for (const imp of generatedStatements.imports) {\n if (imp.text.trim() === headerLine) continue;\n if (existingImportKeys.has(imp.key)) {\n // The existing file already imports from this module path.\n // Check if the generated import adds identifiers not present in\n // the existing import — if so, create a supplemental import with\n // only the new identifiers. The supplemental participates in the\n // usage-based filter (below) so unused identifiers are dropped.\n const braceMatch = imp.text.match(/\\{([^}]+)\\}/);\n if (braceMatch) {\n const names = braceMatch[1]\n .split(',')\n .map((n) => n.replace(/\\btype\\b/, '').trim())\n .filter(Boolean);\n const newNames = names.filter((n) => !existingImportedNames.has(n) && !existingKeys.has(n));\n if (newNames.length > 0) {\n const isTypeImport = imp.text.trimStart().startsWith('import type');\n const prefix = isTypeImport ? 'import type' : 'import';\n const sourceMatch = imp.text.match(/from\\s+(['\"][^'\"]+['\"]);?/);\n if (sourceMatch) {\n newImports.push({\n key: imp.key + '#supplemental',\n text: `${prefix} { ${newNames.join(', ')} } from ${sourceMatch[1]};`,\n });\n }\n }\n }\n preserved++;\n continue;\n }\n // Strip out identifiers that are already imported from another path.\n // This prevents duplicates when the generated file uses a specific path\n // (e.g., '../interfaces/organization.interface') while the existing file\n // imports the same names from a barrel (e.g., '../interfaces').\n const braceMatch = imp.text.match(/\\{([^}]+)\\}/);\n if (braceMatch) {\n const names = braceMatch[1]\n .split(',')\n .map((n) => n.replace(/\\btype\\b/, '').trim())\n .filter(Boolean);\n // Check against both existing imports AND existing top-level declarations\n const isAlreadyDefined = (n: string) => existingImportedNames.has(n) || existingKeys.has(n);\n if (names.length > 0 && names.every(isAlreadyDefined)) {\n preserved++;\n continue;\n }\n // If only SOME identifiers are already defined, strip them out and keep only new ones\n if (names.some(isAlreadyDefined)) {\n const newNames = names.filter((n) => !isAlreadyDefined(n));\n if (newNames.length === 0) {\n preserved++;\n continue;\n }\n // Rebuild the import with only new identifiers\n const isTypeImport = imp.text.trimStart().startsWith('import type');\n const prefix = isTypeImport ? 'import type' : 'import';\n const sourceMatch = imp.text.match(/from\\s+(['\"][^'\"]+['\"]);?/);\n if (sourceMatch) {\n const newText = `${prefix} { ${newNames.join(', ')} } from ${sourceMatch[1]};`;\n newImports.push({ key: imp.key, text: newText });\n continue;\n }\n }\n }\n newImports.push(imp);\n }\n\n for (const stmt of generatedStatements.statements) {\n // Skip the header comment\n if (stmt.text.trim() === headerLine) continue;\n\n // Skip re-export statements that duplicate existing re-exports\n // (e.g., generated uses .js extension but existing doesn't).\n // Allow genuinely new re-exports through.\n if (stmt.kind === 'reexport') {\n const normalizedText = adapter.normalizeReexport ? adapter.normalizeReexport(stmt.text.trim()) : stmt.text.trim();\n if (existingReexports.has(normalizedText) || (stmt.key !== null && existingKeys.has(stmt.key))) {\n preserved++;\n continue;\n }\n }\n\n if (stmt.key && (existingKeys.has(stmt.key) || existingImportedNames.has(stmt.key))) {\n preserved++;\n continue;\n }\n\n if (!stmt.key) {\n if (existingUnnamedTexts.has(stmt.text.trim())) {\n preserved++;\n continue;\n }\n }\n\n toAppend.push(stmt.text);\n }\n\n if (newImports.length === 0 && toAppend.length === 0) {\n // No top-level changes — check for deep merge before returning\n if (!adapter.extractMembers) {\n // Still need to check docstring refresh below\n }\n }\n\n let result = existingContent;\n\n // Append new top-level symbols first (so deep merge can see them)\n if (toAppend.length > 0) {\n result = result.trimEnd() + '\\n\\n' + toAppend.join('\\n\\n') + '\\n';\n }\n\n // Deep merge pass: add new members to existing symbols\n // Runs after import/symbol merge so line numbers are based on the updated content\n let deepAdded = 0;\n const insertions: { line: number; text: string }[] = [];\n if (adapter.extractMembers) {\n const parser = await getParser(language);\n const resultTree = safeParse(parser, result);\n const generatedTree = safeParse(parser, generatedContent);\n const resultSymbols = adapter.extractMembers(resultTree, result);\n const generatedSymbols = adapter.extractMembers(generatedTree, generatedContent);\n\n // Build ignored symbol set from @oagen-ignore-start/@oagen-ignore-end regions\n const existingTree = safeParse(parser, existingContent);\n const existingDocs = adapter.extractDocstrings(existingTree, existingContent);\n const deepIgnoredRegions = findIgnoredRegions(existingContent);\n const deepIgnoredSymbols = buildIgnoredSymbolNames(existingDocs, deepIgnoredRegions);\n\n for (const [symbolName, genSymbol] of generatedSymbols) {\n if (deepIgnoredSymbols.has(symbolName)) continue;\n const existSymbol = resultSymbols.get(symbolName);\n if (!existSymbol) continue; // New symbol — handled by top-level append\n\n const existingMemberKeys = new Set(existSymbol.members.map((m) => m.key));\n const newMembers = genSymbol.members.filter((m) => !existingMemberKeys.has(m.key));\n\n if (newMembers.length > 0) {\n // Let the adapter decide whether to skip deep merge (e.g., when new members\n // reference dependencies the existing symbol doesn't provide)\n if (adapter.shouldSkipDeepMerge?.(symbolName, existingMemberKeys, newMembers)) {\n continue;\n }\n\n const indent = existSymbol.memberIndent ?? ' ';\n const insertText = newMembers.map((m) => indent + m.text).join('\\n');\n insertions.push({ line: existSymbol.bodyEndLine, text: insertText });\n deepAdded += newMembers.length;\n }\n }\n\n if (insertions.length > 0) {\n // Apply bottom-up to avoid offset shifting\n insertions.sort((a, b) => b.line - a.line);\n const resultLines = result.split('\\n');\n for (const ins of insertions) {\n resultLines.splice(ins.line, 0, ins.text);\n }\n result = resultLines.join('\\n');\n }\n }\n\n // Insert new imports only when new symbols or members were actually added.\n // This prevents orphaned imports for generated code that wasn't merged in.\n // Additionally, filter imports to only include identifiers actually used in the\n // appended/inserted code — prevents orphaned imports for generated code that\n // referenced types used in other (non-appended) generated functions.\n if (newImports.length > 0 && (toAppend.length > 0 || deepAdded > 0)) {\n // Build text of all new code that was actually added (appended + deep-merged members)\n const addedParts: string[] = [...toAppend];\n if (insertions) {\n for (const ins of insertions) {\n addedParts.push(ins.text);\n }\n }\n const addedCodeText = addedParts.join('\\n');\n\n // Filter imports to only those whose identifiers appear in the added code\n const filteredImports = newImports.filter((imp) => {\n const braceMatch = imp.text.match(/\\{([^}]+)\\}/);\n if (!braceMatch) return true; // Keep non-destructured imports (e.g., default imports)\n const names = braceMatch[1]\n .split(',')\n .map((n) => n.replace(/\\btype\\b/, '').trim())\n .filter(Boolean);\n // Keep the import if any of its identifiers appear in the added code\n return names.some((name) => addedCodeText.includes(name));\n });\n\n if (filteredImports.length > 0) {\n const renderedImports = adapter.renderImports\n ? adapter.renderImports(filteredImports)\n : filteredImports.map((entry) => entry.text);\n const lines = result.split('\\n');\n const insertIdx = lastImportEndIndex + 1;\n lines.splice(insertIdx, 0, ...renderedImports);\n result = lines.join('\\n');\n }\n }\n\n // Docstring refresh pass: update existing docstrings to match generated content\n let docstringUpdates = 0;\n {\n const parser = await getParser(language);\n const resultTree = safeParse(parser, result);\n const generatedTree = safeParse(parser, generatedContent);\n const resultDocs = adapter.extractDocstrings(resultTree, result);\n const generatedDocs = adapter.extractDocstrings(generatedTree, generatedContent);\n const docIgnoredRegions = findIgnoredRegions(result);\n const docIgnoredSymbols = buildIgnoredSymbolNames(resultDocs, docIgnoredRegions);\n\n const edits: { start: number; end: number; newText: string }[] = [];\n\n for (const [symbolName, genInfo] of generatedDocs) {\n const existInfo = resultDocs.get(symbolName);\n if (!existInfo) continue;\n if (docIgnoredSymbols.has(symbolName)) continue;\n\n // Skip header comments being treated as docstrings\n const genDoc = genInfo.docstring && genInfo.docstring.text.trim() !== headerLine ? genInfo.docstring : null;\n\n // Top-level docstring\n if (genDoc) {\n if (existInfo.docstring) {\n const isPreserved = existInfo.docstring.text.includes('@oagen-ignore');\n if (!isPreserved && existInfo.docstring.text !== genDoc.text) {\n edits.push({\n start: existInfo.docstring.startIndex,\n end: existInfo.docstring.endIndex,\n newText: genDoc.text,\n });\n docstringUpdates++;\n }\n } else {\n const lineStart = existInfo.declStartIndex - existInfo.declColumn;\n const indent = ' '.repeat(existInfo.declColumn);\n edits.push({\n start: lineStart,\n end: lineStart,\n newText: indent + genDoc.text + '\\n',\n });\n docstringUpdates++;\n }\n }\n\n // Member-level docstrings — first pass: match by name\n const matchedExistMembers = new Set<string>();\n for (const [memberName, genMember] of genInfo.members) {\n const existMember = existInfo.members.get(memberName);\n if (!existMember || !genMember.docstring) continue;\n matchedExistMembers.add(memberName);\n\n if (existMember.docstring) {\n const isPreserved = existMember.docstring.text.includes('@oagen-ignore');\n if (!isPreserved && existMember.docstring.text !== genMember.docstring.text) {\n edits.push({\n start: existMember.docstring.startIndex,\n end: existMember.docstring.endIndex,\n newText: genMember.docstring.text,\n });\n docstringUpdates++;\n }\n } else {\n const lineStart = existMember.declStartIndex - existMember.declColumn;\n const indent = ' '.repeat(existMember.declColumn);\n edits.push({\n start: lineStart,\n end: lineStart,\n newText: indent + genMember.docstring.text + '\\n',\n });\n docstringUpdates++;\n }\n }\n\n // Member-level docstrings — second pass: URL fingerprint fallback\n // Match generated members to existing members by URL pattern when\n // name-based matching fails (e.g., generated \"find\" vs existing \"getOrganization\"\n // both call this.workos.get('/organizations/${id}')).\n for (const [_genName, genMember] of genInfo.members) {\n if (!genMember.docstring || !genMember.urlFingerprint) continue;\n // Find unmatched existing member with the same URL fingerprint\n for (const [existName, existMember] of existInfo.members) {\n if (matchedExistMembers.has(existName)) continue;\n if (!existMember.urlFingerprint || existMember.urlFingerprint !== genMember.urlFingerprint) continue;\n if (existMember.docstring) {\n const isPreserved = existMember.docstring.text.includes('@oagen-ignore');\n if (isPreserved) continue;\n if (existMember.docstring.text !== genMember.docstring.text) {\n edits.push({\n start: existMember.docstring.startIndex,\n end: existMember.docstring.endIndex,\n newText: genMember.docstring.text,\n });\n docstringUpdates++;\n }\n } else {\n const lineStart = existMember.declStartIndex - existMember.declColumn;\n const indent = ' '.repeat(existMember.declColumn);\n edits.push({\n start: lineStart,\n end: lineStart,\n newText: indent + genMember.docstring.text + '\\n',\n });\n docstringUpdates++;\n }\n matchedExistMembers.add(existName);\n break; // Only match one existing member per generated member\n }\n }\n }\n\n if (edits.length > 0) {\n edits.sort((a, b) => b.start - a.start);\n for (const edit of edits) {\n result = result.slice(0, edit.start) + edit.newText + result.slice(edit.end);\n }\n }\n }\n\n const importsActuallyAdded =\n toAppend.length > 0 || deepAdded > 0\n ? adapter.renderImports\n ? adapter.renderImports(newImports).length\n : newImports.length\n : 0;\n const topLevelAdded = importsActuallyAdded + toAppend.length;\n const totalAdded = topLevelAdded + deepAdded;\n\n if (totalAdded === 0 && docstringUpdates === 0) {\n return { content: existingContent, added: 0, preserved, changed: false };\n }\n\n return {\n content: result,\n added: totalAdded,\n preserved,\n changed: true,\n };\n}\n","/**\n * Deep merge two parsed JSON values.\n *\n * - Objects: recursively merge, preserving existing keys not in generated\n * - Arrays: generated replaces existing entirely (generated owns array contents)\n * - Primitives: generated wins\n */\nexport function deepMergeJson(existing: unknown, generated: unknown): unknown {\n if (\n typeof existing === 'object' &&\n existing !== null &&\n !Array.isArray(existing) &&\n typeof generated === 'object' &&\n generated !== null &&\n !Array.isArray(generated)\n ) {\n const merged: Record<string, unknown> = { ...(existing as Record<string, unknown>) };\n for (const [key, value] of Object.entries(generated as Record<string, unknown>)) {\n if (key in merged) {\n merged[key] = deepMergeJson(merged[key], value);\n } else {\n merged[key] = value;\n }\n }\n return merged;\n }\n\n // Arrays and primitives: generated wins\n return generated;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { GeneratedFile } from './types.js';\nimport { mergeIntoExisting, hasGrammar } from './merger.js';\nimport { deepMergeJson } from './json-merge.js';\nimport { getMergeAdapter } from './merge-adapters/index.js';\n\nexport interface WriteOptions {\n /** The emitter language (e.g., \"node\", \"ruby\"). Used to select the\n * tree-sitter grammar for AST-level merging. */\n language?: string;\n /** The auto-generated file header string. */\n header?: string;\n}\n\nexport interface WriteResult {\n written: string[];\n merged: string[];\n skipped: string[];\n identical: string[];\n ignored: string[];\n}\n\n/**\n * Write generated files to disk with AST-level merging.\n *\n * When a file already exists:\n * - skipIfExists → leave it alone entirely\n * - AST merge available → parse both, append only new symbols\n * - No grammar → skip (never clobber hand-written code)\n *\n * New files are always written in full.\n */\nexport async function writeFiles(\n files: GeneratedFile[],\n outputDir: string,\n options?: WriteOptions,\n): Promise<WriteResult> {\n const result: WriteResult = { written: [], merged: [], skipped: [], identical: [], ignored: [] };\n const sorted = [...files].sort((a, b) => a.path.localeCompare(b.path));\n const language = options?.language;\n const header = options?.header ?? '';\n\n for (const file of sorted) {\n const fullPath = path.join(outputDir, file.path);\n\n // Check if file already exists\n let existingContent: string | null = null;\n try {\n existingContent = await fs.readFile(fullPath, 'utf-8');\n } catch {\n // File doesn't exist\n }\n\n // New file → write in full\n if (existingContent === null) {\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, file.content, 'utf-8');\n result.written.push(file.path);\n continue;\n }\n\n // skipIfExists → hard skip, no merge (but ensure header is present)\n if (file.skipIfExists) {\n if (header && !existingContent.startsWith(header)) {\n await fs.writeFile(fullPath, header + '\\n\\n' + existingContent, 'utf-8');\n }\n result.skipped.push(file.path);\n continue;\n }\n\n // @oagen-ignore-file → skip entirely (existing file opts out of all generation)\n if (existingContent.includes('@oagen-ignore-file')) {\n result.ignored.push(file.path);\n continue;\n }\n\n // Don't merge test files into existing test files — generated tests are designed\n // for the standalone generated SDK and will have wrong signatures/fixtures when\n // merged into hand-written tests.\n const adapter = language ? getMergeAdapter(language) : undefined;\n const isTestFile = adapter?.testFilePatterns\n ? adapter.testFilePatterns.some((p) => p.test(file.path))\n : isDefaultTestFile(file.path);\n if (isTestFile) {\n result.skipped.push(file.path);\n continue;\n }\n\n // Identical content → no-op\n if (existingContent === file.content) {\n result.identical.push(file.path);\n continue;\n }\n\n // Force overwrite — skip merge logic entirely\n if (file.overwriteExisting) {\n await fs.writeFile(fullPath, file.content, 'utf-8');\n result.written.push(file.path);\n continue;\n }\n\n // JSON files → deep merge preserving existing keys\n if (file.path.endsWith('.json')) {\n try {\n const existingJson = JSON.parse(existingContent);\n const generatedJson = JSON.parse(file.content);\n const merged = deepMergeJson(existingJson, generatedJson);\n const mergedContent = JSON.stringify(merged, null, 2) + '\\n';\n if (mergedContent === existingContent) {\n result.identical.push(file.path);\n } else {\n await fs.writeFile(fullPath, mergedContent, 'utf-8');\n result.merged.push(file.path);\n }\n } catch {\n // Parse failed — fall back to overwrite\n await fs.writeFile(fullPath, file.content, 'utf-8');\n result.written.push(file.path);\n }\n continue;\n }\n\n // Source files with grammar → AST-level merge\n if (language && hasGrammar(language)) {\n try {\n const mergeResult = await mergeIntoExisting(existingContent, file.content, language, header);\n\n // Ensure header is present on merged content\n let finalContent = mergeResult.content;\n if (header && !finalContent.startsWith(header)) {\n finalContent = header + '\\n\\n' + finalContent;\n }\n\n if (!mergeResult.changed && finalContent === existingContent) {\n result.identical.push(file.path);\n continue;\n }\n\n await fs.writeFile(fullPath, finalContent, 'utf-8');\n result.merged.push(file.path);\n continue;\n } catch (err) {\n // AST merge failed (e.g. tree-sitter grammar ABI issue) — fall back to overwrite\n console.warn(\n `[oagen] AST merge failed for ${file.path}, falling back to overwrite.${err instanceof Error ? ` ${err.message}` : ''}`,\n );\n await fs.writeFile(fullPath, file.content, 'utf-8');\n result.written.push(file.path);\n continue;\n }\n }\n\n // No grammar available → skip to avoid clobbering\n result.skipped.push(file.path);\n }\n\n return result;\n}\n\n/** Comprehensive fallback when no adapter is available. */\nfunction isDefaultTestFile(filePath: string): boolean {\n return (\n /\\.(spec|test)\\.[jt]sx?$/.test(filePath) ||\n filePath.endsWith('_test.go') ||\n filePath.endsWith('_test.rb') ||\n filePath.endsWith('_spec.rb') ||\n /(?:^|\\/)test_.*\\.py$/.test(filePath) ||\n filePath.endsWith('_test.py') ||\n filePath.endsWith('Test.php') ||\n filePath.endsWith('_test.rs') ||\n /(?:^|\\/)tests\\/.*\\.rs$/.test(filePath)\n );\n}\n","import type { ApiSpec } from '../ir/types.js';\nimport type { Emitter, EmitterContext, GeneratedFile } from './types.js';\nimport type { ApiSurface, OverlayLookup } from '../compat/types.js';\nimport { toSnakeCase } from '../utils/naming.js';\n\nexport function buildEmitterContext(\n spec: ApiSpec,\n options: {\n namespace: string;\n outputDir: string;\n apiSurface?: ApiSurface;\n overlayLookup?: OverlayLookup;\n },\n): EmitterContext {\n return {\n namespace: toSnakeCase(options.namespace),\n namespacePascal: options.namespace,\n spec,\n outputDir: options.outputDir,\n apiSurface: options.apiSurface,\n overlayLookup: options.overlayLookup,\n };\n}\n\n/** Collect all generated files from an emitter (no headers, no path prefixes). */\nexport function generateAllFiles(spec: ApiSpec, emitter: Emitter, ctx: EmitterContext): GeneratedFile[] {\n return [\n ...emitter.generateModels(spec.models, ctx),\n ...emitter.generateEnums(spec.enums, ctx),\n ...emitter.generateResources(spec.services, ctx),\n ...emitter.generateClient(spec, ctx),\n ...emitter.generateErrors(ctx),\n ...emitter.generateConfig(ctx),\n ...(emitter.generateTypeSignatures?.(spec, ctx) ?? []),\n ...emitter.generateTests(spec, ctx),\n ...(emitter.generateManifest?.(spec, ctx) ?? []),\n ];\n}\n\n/** Apply file header to generated files, respecting headerPlacement and JSON files. */\nexport function applyFileHeaders(files: GeneratedFile[], header: string): GeneratedFile[] {\n return files.map((f) => ({\n ...f,\n content:\n !header || f.path.endsWith('.json') || f.headerPlacement === 'skip' ? f.content : header + '\\n\\n' + f.content,\n skipIfExists: f.skipIfExists ?? false,\n }));\n}\n\nexport function generateFiles(\n spec: ApiSpec,\n emitter: Emitter,\n options: {\n namespace: string;\n outputDir: string;\n apiSurface?: ApiSurface;\n overlayLookup?: OverlayLookup;\n },\n): { files: GeneratedFile[]; ctx: EmitterContext; header: string } {\n const ctx = buildEmitterContext(spec, options);\n const files = generateAllFiles(spec, emitter, ctx);\n const header = emitter.fileHeader();\n return { files: applyFileHeaders(files, header), ctx, header };\n}\n","import type { GeneratedFile } from './types.js';\nimport { writeFiles, type WriteResult } from './writer.js';\n\nexport function mapFilesForTargetIntegration(files: GeneratedFile[], language: string): GeneratedFile[] {\n const langPrefix = `${language}/`;\n return files\n .filter((f) => f.integrateTarget !== false) // integrateTarget: false files are standalone-only\n .map((f) => {\n const stripped = f.path.startsWith(langPrefix) ? f.path.replace(langPrefix, '') : f.path;\n return {\n ...f,\n skipIfExists: false, // Always merge in target — never hard-skip\n path: stripped,\n };\n });\n}\n\nexport async function integrateGeneratedFiles(opts: {\n files: GeneratedFile[];\n language: string;\n targetDir: string;\n header: string;\n}): Promise<WriteResult> {\n return writeFiles(mapFilesForTargetIntegration(opts.files, opts.language), opts.targetDir, {\n language: opts.language,\n header: opts.header,\n });\n}\n","import type { ApiSpec } from '../ir/types.js';\nimport type { Emitter, GeneratedFile } from './types.js';\nimport type { ApiSurface, OverlayLookup } from '../compat/types.js';\nimport { writeFiles } from './writer.js';\nimport { generateFiles } from './generate-files.js';\nimport { integrateGeneratedFiles } from './integrate.js';\n\nexport async function generate(\n spec: ApiSpec,\n emitter: Emitter,\n options: {\n namespace: string;\n dryRun?: boolean;\n outputDir: string;\n target?: string;\n apiSurface?: ApiSurface;\n overlayLookup?: OverlayLookup;\n },\n): Promise<GeneratedFile[]> {\n const { files: withHeaders, header } = generateFiles(spec, emitter, options);\n\n if (options.dryRun) {\n if (options.target) {\n console.log(`\\nTarget integration (${options.target}):`);\n for (const f of withHeaders) {\n console.log(` ${f.path}`);\n }\n }\n return withHeaders;\n }\n\n const writeResult = await writeFiles(withHeaders, options.outputDir, {\n language: emitter.language,\n header,\n });\n\n if (writeResult.merged.length > 0) {\n console.log(`Merged into ${writeResult.merged.length} existing files (additive only)`);\n }\n if (writeResult.ignored.length > 0) {\n console.log(`Ignored ${writeResult.ignored.length} files (@oagen-ignore-file)`);\n }\n\n // Target integration pass\n if (options.target) {\n const targetResult = await integrateGeneratedFiles({\n files: withHeaders,\n language: emitter.language,\n targetDir: options.target,\n header,\n });\n\n if (targetResult.written.length > 0) {\n console.log(`Target: created ${targetResult.written.length} new files`);\n }\n if (targetResult.merged.length > 0) {\n console.log(`Target: merged into ${targetResult.merged.length} existing files (additive only)`);\n }\n if (targetResult.skipped.length > 0) {\n console.log(`Target: skipped ${targetResult.skipped.length} files (excluded or no grammar)`);\n }\n }\n\n return withHeaders;\n}\n","import { RegistryError } from '../errors.js';\nimport type { Emitter } from './types.js';\n\nconst emitters = new Map<string, Emitter>();\n\nexport function registerEmitter(emitter: Emitter): void {\n emitters.set(emitter.language, emitter);\n}\n\nexport function getEmitter(language: string): Emitter {\n const emitter = emitters.get(language);\n if (!emitter) {\n const available = [...emitters.keys()].join(', ') || '(none)';\n throw new RegistryError(\n `Unknown language: ${language}. Available: ${available}`,\n `Register an emitter for \"${language}\" via registerEmitter() or check your oagen.config.ts plugin configuration.`,\n );\n }\n return emitter;\n}\n","import type { FieldChange, ParamChange } from './types.js';\n\nexport function classifyFieldChange(kind: FieldChange['kind'], fieldName: string, isRequired?: boolean): FieldChange {\n switch (kind) {\n case 'field-added':\n return {\n kind,\n fieldName,\n classification: isRequired ? 'breaking' : 'additive',\n };\n case 'field-removed':\n return { kind, fieldName, classification: 'breaking' };\n case 'field-type-changed':\n return { kind, fieldName, classification: 'breaking' };\n case 'field-required-changed':\n return {\n kind,\n fieldName,\n classification: isRequired ? 'breaking' : 'additive',\n details: isRequired ? 'optional → required' : 'required → optional',\n };\n case 'field-access-changed':\n return { kind, fieldName, classification: 'breaking' };\n }\n}\n\nexport function classifyParamChange(kind: ParamChange['kind'], paramName: string, isRequired?: boolean): ParamChange {\n switch (kind) {\n case 'param-added':\n return {\n kind,\n paramName,\n classification: isRequired ? 'breaking' : 'additive',\n };\n case 'param-removed':\n return { kind, paramName, classification: 'breaking' };\n case 'param-type-changed':\n return { kind, paramName, classification: 'breaking' };\n case 'param-required-changed':\n return {\n kind,\n paramName,\n classification: isRequired ? 'breaking' : 'additive',\n };\n }\n}\n","import type { Model, TypeRef } from '../ir/types.js';\nimport { assertNever } from '../ir/types.js';\nimport type { Change, FieldChange } from './types.js';\nimport { classifyFieldChange } from './classify.js';\n\nexport function diffModels(oldModels: Model[], newModels: Model[]): Change[] {\n const changes: Change[] = [];\n const oldByName = new Map(oldModels.map((m) => [m.name, m]));\n const newByName = new Map(newModels.map((m) => [m.name, m]));\n\n for (const [name] of newByName) {\n if (!oldByName.has(name)) {\n changes.push({ kind: 'model-added', name, classification: 'additive' });\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push({ kind: 'model-removed', name, classification: 'breaking' });\n }\n }\n\n for (const [name, newModel] of newByName) {\n const oldModel = oldByName.get(name);\n if (!oldModel) continue;\n\n const fieldChanges = diffFields(oldModel, newModel);\n if (fieldChanges.length > 0) {\n const hasBreaking = fieldChanges.some((fc) => fc.classification === 'breaking');\n changes.push({\n kind: 'model-modified',\n name,\n fieldChanges,\n classification: hasBreaking ? 'breaking' : 'additive',\n });\n }\n }\n\n return changes;\n}\n\nfunction diffFields(oldModel: Model, newModel: Model): FieldChange[] {\n const changes: FieldChange[] = [];\n const oldByName = new Map(oldModel.fields.map((f) => [f.name, f]));\n const newByName = new Map(newModel.fields.map((f) => [f.name, f]));\n\n for (const [name, field] of newByName) {\n if (!oldByName.has(name)) {\n changes.push(classifyFieldChange('field-added', name, field.required));\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push(classifyFieldChange('field-removed', name));\n }\n }\n\n for (const [name, newField] of newByName) {\n const oldField = oldByName.get(name);\n if (!oldField) continue;\n\n if (!typeRefsEqual(oldField.type, newField.type)) {\n changes.push({\n kind: 'field-type-changed',\n fieldName: name,\n classification: 'breaking',\n details: `type changed`,\n });\n }\n\n if (oldField.required !== newField.required) {\n changes.push(classifyFieldChange('field-required-changed', name, newField.required));\n }\n\n if (!!oldField.readOnly !== !!newField.readOnly || !!oldField.writeOnly !== !!newField.writeOnly) {\n changes.push(classifyFieldChange('field-access-changed', name));\n }\n }\n\n return changes;\n}\n\nexport function typeRefsEqual(a: TypeRef, b: TypeRef): boolean {\n if (a.kind !== b.kind) return false;\n\n switch (a.kind) {\n case 'primitive':\n return b.kind === 'primitive' && a.type === b.type && (a.format ?? '') === ((b as typeof a).format ?? '');\n case 'array':\n return b.kind === 'array' && typeRefsEqual(a.items, b.items);\n case 'model':\n return b.kind === 'model' && a.name === b.name;\n case 'enum':\n return b.kind === 'enum' && a.name === b.name;\n case 'literal':\n return b.kind === 'literal' && a.value === b.value;\n case 'nullable':\n return b.kind === 'nullable' && typeRefsEqual(a.inner, b.inner);\n case 'union': {\n if (b.kind !== 'union') return false;\n if (a.variants.length !== b.variants.length) return false;\n if (!a.variants.every((v, i) => typeRefsEqual(v, b.variants[i]))) return false;\n // Compare discriminator\n if (!a.discriminator && !b.discriminator) return true;\n if (!a.discriminator || !b.discriminator) return false;\n if (a.discriminator.property !== b.discriminator.property) return false;\n const aKeys = Object.keys(a.discriminator.mapping).sort();\n const bKeys = Object.keys(b.discriminator.mapping).sort();\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every((k, i) => k === bKeys[i] && a.discriminator!.mapping[k] === b.discriminator!.mapping[k]);\n }\n case 'map':\n return b.kind === 'map' && typeRefsEqual(a.valueType, b.valueType);\n }\n return assertNever(a);\n}\n","import type { ErrorResponse, Operation } from '../ir/types.js';\nimport type { Change, ParamChange } from './types.js';\nimport { classifyParamChange } from './classify.js';\nimport { typeRefsEqual } from './models.js';\n\nexport function diffOperations(serviceName: string, oldOps: Operation[], newOps: Operation[]): Change[] {\n const changes: Change[] = [];\n const oldByName = new Map(oldOps.map((o) => [o.name, o]));\n const newByName = new Map(newOps.map((o) => [o.name, o]));\n\n for (const [name] of newByName) {\n if (!oldByName.has(name)) {\n changes.push({\n kind: 'operation-added',\n serviceName,\n operationName: name,\n classification: 'additive',\n });\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push({\n kind: 'operation-removed',\n serviceName,\n operationName: name,\n classification: 'breaking',\n });\n }\n }\n\n for (const [name, newOp] of newByName) {\n const oldOp = oldByName.get(name);\n if (!oldOp) continue;\n\n const paramChanges = diffParams(oldOp, newOp);\n const responseChanged = !typeRefsEqual(oldOp.response, newOp.response);\n const requestBodyChanged = !requestBodiesEqual(oldOp.requestBody, newOp.requestBody);\n const httpMethodChanged = oldOp.httpMethod !== newOp.httpMethod;\n const pathChanged = oldOp.path !== newOp.path;\n const paginatedChanged = !!oldOp.pagination !== !!newOp.pagination;\n const injectIdempotencyKeyChanged = oldOp.injectIdempotencyKey !== newOp.injectIdempotencyKey;\n const errorsDiff = classifyErrorsChange(oldOp.errors, newOp.errors);\n const errorsChanged = errorsDiff !== 'none';\n\n const hasChanges =\n paramChanges.length > 0 ||\n responseChanged ||\n requestBodyChanged ||\n httpMethodChanged ||\n pathChanged ||\n paginatedChanged ||\n injectIdempotencyKeyChanged ||\n errorsChanged;\n\n if (hasChanges) {\n // paginated: false→true is additive (SDK gains pagination helper)\n // paginated: true→false is breaking (SDK loses pagination helper)\n const paginatedBreaking = paginatedChanged && !newOp.pagination;\n // injectIdempotencyKey: false→true is additive (SDK gains idempotency key)\n // injectIdempotencyKey: true→false is breaking (SDK loses idempotency key)\n const injectIdempotencyKeyBreaking = injectIdempotencyKeyChanged && !newOp.injectIdempotencyKey;\n const errorsBreaking = errorsDiff === 'breaking';\n\n const hasBreaking =\n responseChanged ||\n requestBodyChanged ||\n httpMethodChanged ||\n pathChanged ||\n paginatedBreaking ||\n injectIdempotencyKeyBreaking ||\n errorsBreaking ||\n paramChanges.some((pc) => pc.classification === 'breaking');\n changes.push({\n kind: 'operation-modified',\n serviceName,\n operationName: name,\n paramChanges,\n responseChanged,\n requestBodyChanged,\n httpMethodChanged,\n pathChanged,\n paginatedChanged,\n injectIdempotencyKeyChanged,\n errorsChanged,\n classification: hasBreaking ? 'breaking' : 'additive',\n });\n }\n }\n\n return changes;\n}\n\nfunction requestBodiesEqual(a: Operation['requestBody'], b: Operation['requestBody']): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return typeRefsEqual(a, b);\n}\n\nfunction classifyErrorsChange(\n oldErrors: ErrorResponse[],\n newErrors: ErrorResponse[],\n): 'none' | 'additive' | 'breaking' {\n const oldByCode = new Map(oldErrors.map((e) => [e.statusCode, e]));\n const newByCode = new Map(newErrors.map((e) => [e.statusCode, e]));\n\n let hasAdditive = false;\n let hasBreaking = false;\n\n // New error codes added → additive (SDK gains new error classes)\n for (const code of newByCode.keys()) {\n if (!oldByCode.has(code)) hasAdditive = true;\n }\n\n // Old error codes removed → breaking (SDK loses error classes)\n for (const code of oldByCode.keys()) {\n if (!newByCode.has(code)) hasBreaking = true;\n }\n\n // Shared error codes with changed types → breaking\n for (const [code, newErr] of newByCode) {\n const oldErr = oldByCode.get(code);\n if (!oldErr) continue;\n if (!oldErr.type && !newErr.type) continue;\n if (!oldErr.type || !newErr.type || !typeRefsEqual(oldErr.type, newErr.type)) {\n hasBreaking = true;\n }\n }\n\n if (hasBreaking) return 'breaking';\n if (hasAdditive) return 'additive';\n return 'none';\n}\n\nfunction diffParams(oldOp: Operation, newOp: Operation): ParamChange[] {\n const changes: ParamChange[] = [];\n const allOldParams = [...oldOp.pathParams, ...oldOp.queryParams, ...oldOp.headerParams];\n const allNewParams = [...newOp.pathParams, ...newOp.queryParams, ...newOp.headerParams];\n const oldByName = new Map(allOldParams.map((p) => [p.name, p]));\n const newByName = new Map(allNewParams.map((p) => [p.name, p]));\n\n for (const [name, param] of newByName) {\n if (!oldByName.has(name)) {\n changes.push(classifyParamChange('param-added', name, param.required));\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push(classifyParamChange('param-removed', name));\n }\n }\n\n for (const [name, newParam] of newByName) {\n const oldParam = oldByName.get(name);\n if (!oldParam) continue;\n\n if (!typeRefsEqual(oldParam.type, newParam.type)) {\n changes.push(classifyParamChange('param-type-changed', name));\n }\n\n if (oldParam.required !== newParam.required) {\n changes.push(classifyParamChange('param-required-changed', name, newParam.required));\n }\n }\n\n return changes;\n}\n","import type { Service } from '../ir/types.js';\nimport type { Change } from './types.js';\nimport { diffOperations } from './operations.js';\n\nexport function diffServices(oldServices: Service[], newServices: Service[]): Change[] {\n const changes: Change[] = [];\n const oldByName = new Map(oldServices.map((s) => [s.name, s]));\n const newByName = new Map(newServices.map((s) => [s.name, s]));\n\n for (const [name] of newByName) {\n if (!oldByName.has(name)) {\n changes.push({ kind: 'service-added', name, classification: 'additive' });\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push({ kind: 'service-removed', name, classification: 'breaking' });\n }\n }\n\n for (const [name, newService] of newByName) {\n const oldService = oldByName.get(name);\n if (!oldService) continue;\n\n changes.push(...diffOperations(name, oldService.operations, newService.operations));\n }\n\n return changes;\n}\n","import type { ApiSpec, Enum } from '../ir/types.js';\nimport type { Change, DiffReport, EnumValueChange } from './types.js';\nimport { diffModels } from './models.js';\nimport { diffServices } from './services.js';\n\nexport function diffSpecs(oldSpec: ApiSpec, newSpec: ApiSpec): DiffReport {\n const changes: Change[] = [\n ...diffModels(oldSpec.models, newSpec.models),\n ...diffEnums(oldSpec.enums, newSpec.enums),\n ...diffServices(oldSpec.services, newSpec.services),\n ];\n\n return {\n oldVersion: oldSpec.version,\n newVersion: newSpec.version,\n changes,\n summary: summarize(changes),\n };\n}\n\nfunction diffEnums(oldEnums: Enum[], newEnums: Enum[]): Change[] {\n const changes: Change[] = [];\n const oldByName = new Map(oldEnums.map((e) => [e.name, e]));\n const newByName = new Map(newEnums.map((e) => [e.name, e]));\n\n for (const [name] of newByName) {\n if (!oldByName.has(name)) {\n changes.push({ kind: 'enum-added', name, classification: 'additive' });\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push({ kind: 'enum-removed', name, classification: 'breaking' });\n }\n }\n\n for (const [name, newEnum] of newByName) {\n const oldEnum = oldByName.get(name);\n if (!oldEnum) continue;\n\n const valueChanges = diffEnumValues(oldEnum, newEnum);\n if (valueChanges.length > 0) {\n const hasBreaking = valueChanges.some((vc) => vc.classification === 'breaking');\n changes.push({\n kind: 'enum-modified',\n name,\n valueChanges,\n classification: hasBreaking ? 'breaking' : 'additive',\n });\n }\n }\n\n return changes;\n}\n\nfunction diffEnumValues(oldEnum: Enum, newEnum: Enum): EnumValueChange[] {\n const changes: EnumValueChange[] = [];\n const oldByName = new Map(oldEnum.values.map((v) => [v.name, v]));\n const newByName = new Map(newEnum.values.map((v) => [v.name, v]));\n\n for (const [name] of newByName) {\n if (!oldByName.has(name)) {\n changes.push({ kind: 'value-added', valueName: name, classification: 'additive' });\n }\n }\n\n for (const [name] of oldByName) {\n if (!newByName.has(name)) {\n changes.push({ kind: 'value-removed', valueName: name, classification: 'breaking' });\n }\n }\n\n for (const [name, newVal] of newByName) {\n const oldVal = oldByName.get(name);\n if (!oldVal) continue;\n\n if (oldVal.value !== newVal.value) {\n changes.push({\n kind: 'value-changed',\n valueName: name,\n classification: 'breaking',\n details: `value changed from '${oldVal.value}' to '${newVal.value}'`,\n });\n }\n }\n\n return changes;\n}\n\nfunction summarize(changes: Change[]) {\n let added = 0;\n let removed = 0;\n let modified = 0;\n let breaking = 0;\n let additive = 0;\n\n for (const c of changes) {\n if (c.kind.endsWith('-added')) added++;\n else if (c.kind.endsWith('-removed')) removed++;\n else if (c.kind.endsWith('-modified')) modified++;\n\n if (c.classification === 'breaking') breaking++;\n else additive++;\n }\n\n return { added, removed, modified, breaking, additive };\n}\n"],"mappings":"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"}