types.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /**
  2. * CodeGraph Type Definitions
  3. *
  4. * Core types for the semantic knowledge graph system.
  5. */
  6. // =============================================================================
  7. // Union Types
  8. // =============================================================================
  9. /**
  10. * Types of nodes in the knowledge graph.
  11. *
  12. * Defined as a runtime-iterable `as const` array so the same source
  13. * of truth backs both the TS type and any runtime validation
  14. * (e.g. the search query parser).
  15. *
  16. * The ARRAY ORDER is part of the native kernel's wire contract (kinds cross
  17. * the boundary as indexes — see src/extraction/kernel/layout.ts); append new
  18. * kinds, never reorder.
  19. */
  20. export const NODE_KINDS = [
  21. 'file',
  22. 'module',
  23. 'class',
  24. 'struct',
  25. 'interface',
  26. 'trait',
  27. 'protocol',
  28. 'function',
  29. 'method',
  30. 'property',
  31. 'field',
  32. 'variable',
  33. 'constant',
  34. 'enum',
  35. 'enum_member',
  36. 'type_alias',
  37. 'namespace',
  38. 'parameter',
  39. 'import',
  40. 'export',
  41. 'route',
  42. 'component',
  43. 'union',
  44. ] as const;
  45. export type NodeKind = (typeof NODE_KINDS)[number];
  46. /**
  47. * Types of edges (relationships) between nodes.
  48. *
  49. * Runtime-iterable like NODE_KINDS. The ARRAY ORDER is part of the native
  50. * kernel's wire contract (kinds cross the boundary as indexes — see
  51. * src/extraction/kernel/layout.ts); append new kinds, never reorder.
  52. */
  53. export const EDGE_KINDS = [
  54. 'contains', // Parent contains child (file→class, class→method)
  55. 'calls', // Function/method calls another
  56. 'imports', // File imports from another
  57. 'exports', // File exports a symbol
  58. 'extends', // Class/interface extends another
  59. 'implements', // Class implements interface
  60. 'references', // Generic reference to another symbol
  61. 'type_of', // Variable/parameter has type
  62. 'returns', // Function returns type
  63. 'instantiates', // Creates instance of class
  64. 'overrides', // Method overrides parent method
  65. 'decorates', // Decorator applied to symbol
  66. ] as const;
  67. export type EdgeKind = (typeof EDGE_KINDS)[number];
  68. /**
  69. * Supported programming languages. See NODE_KINDS for why this is a
  70. * runtime-iterable const array.
  71. */
  72. export const LANGUAGES = [
  73. 'typescript',
  74. 'javascript',
  75. 'tsx',
  76. 'jsx',
  77. 'arkts',
  78. 'python',
  79. 'go',
  80. 'rust',
  81. 'java',
  82. 'c',
  83. 'cpp',
  84. 'csharp',
  85. 'razor',
  86. 'php',
  87. 'ruby',
  88. 'swift',
  89. 'kotlin',
  90. 'dart',
  91. 'svelte',
  92. 'vue',
  93. 'astro',
  94. 'liquid',
  95. 'pascal',
  96. 'scala',
  97. 'lua',
  98. 'luau',
  99. 'objc',
  100. 'r',
  101. 'solidity',
  102. 'nix',
  103. 'yaml',
  104. 'twig',
  105. 'xml',
  106. 'properties',
  107. 'cfml',
  108. 'cfscript',
  109. 'cfquery',
  110. 'cobol',
  111. 'vbnet',
  112. 'erlang',
  113. 'terraform',
  114. 'unknown',
  115. ] as const;
  116. export type Language = (typeof LANGUAGES)[number];
  117. // =============================================================================
  118. // Core Graph Types
  119. // =============================================================================
  120. /**
  121. * A node in the knowledge graph representing a code symbol
  122. */
  123. export interface Node {
  124. /** Unique identifier (hash of file path + qualified name) */
  125. id: string;
  126. /** Type of code element */
  127. kind: NodeKind;
  128. /** Simple name (e.g., "calculateTotal") */
  129. name: string;
  130. /** Fully qualified name (e.g., "src/utils.ts::MathHelper.calculateTotal") */
  131. qualifiedName: string;
  132. /** File path relative to project root */
  133. filePath: string;
  134. /** Programming language */
  135. language: Language;
  136. /** Starting line number (1-indexed) */
  137. startLine: number;
  138. /** Ending line number (1-indexed) */
  139. endLine: number;
  140. /** Starting column (0-indexed) */
  141. startColumn: number;
  142. /** Ending column (0-indexed) */
  143. endColumn: number;
  144. /** Documentation string if present */
  145. docstring?: string;
  146. /** Function/method signature */
  147. signature?: string;
  148. /** Visibility modifier */
  149. visibility?: 'public' | 'private' | 'protected' | 'internal';
  150. /** Whether symbol is exported */
  151. isExported?: boolean;
  152. /** Whether symbol is async */
  153. isAsync?: boolean;
  154. /** Whether symbol is static */
  155. isStatic?: boolean;
  156. /** Whether symbol is abstract */
  157. isAbstract?: boolean;
  158. /** Decorators/annotations applied */
  159. decorators?: string[];
  160. /** Generic type parameters */
  161. typeParameters?: string[];
  162. /**
  163. * Normalized return/result type name for a function/method (the bare class
  164. * name, smart-pointer pointee unwrapped). Captured for C/C++ so resolution
  165. * can infer a chained receiver's type from what the inner call returns —
  166. * `Foo::instance().bar()` resolves `bar` on `Foo` (issue #645). Undefined for
  167. * languages/symbols where it isn't captured.
  168. */
  169. returnType?: string;
  170. /** When the node was last updated */
  171. updatedAt: number;
  172. }
  173. /**
  174. * An edge representing a relationship between two nodes
  175. */
  176. export interface Edge {
  177. /** Source node ID */
  178. source: string;
  179. /** Target node ID */
  180. target: string;
  181. /** Type of relationship */
  182. kind: EdgeKind;
  183. /** Additional context about the relationship */
  184. metadata?: Record<string, unknown>;
  185. /** Line number where relationship occurs (e.g., call site) */
  186. line?: number;
  187. /** Column number where relationship occurs */
  188. column?: number;
  189. /** How this edge was created */
  190. provenance?: 'tree-sitter' | 'scip' | 'heuristic';
  191. }
  192. /**
  193. * Metadata about a tracked file
  194. */
  195. export interface FileRecord {
  196. /** File path relative to project root */
  197. path: string;
  198. /** Content hash for change detection */
  199. contentHash: string;
  200. /** Detected language */
  201. language: Language;
  202. /** File size in bytes */
  203. size: number;
  204. /** Last modification timestamp */
  205. modifiedAt: number;
  206. /** When last indexed */
  207. indexedAt: number;
  208. /** Number of nodes extracted */
  209. nodeCount: number;
  210. /** Any extraction errors */
  211. errors?: ExtractionError[];
  212. /**
  213. * Tool-generated source, decided at index time from the filename
  214. * convention OR a generation banner in the file's header (see
  215. * extraction/generated-detection.ts). A relevance hint for ranking, not a
  216. * hard filter. Absent on indexes built before schema v9 — treat
  217. * `undefined` as "content signal unknown, fall back to the path check".
  218. */
  219. generated?: boolean;
  220. }
  221. // =============================================================================
  222. // Extraction Types
  223. // =============================================================================
  224. /**
  225. * Result from parsing a source file
  226. */
  227. export interface ExtractionResult {
  228. /** Extracted nodes */
  229. nodes: Node[];
  230. /** Extracted edges */
  231. edges: Edge[];
  232. /** References that couldn't be resolved yet */
  233. unresolvedReferences: UnresolvedReference[];
  234. /** Any errors during extraction */
  235. errors: ExtractionError[];
  236. /** Extraction duration in milliseconds */
  237. durationMs: number;
  238. /**
  239. * Deferred-decode transport (native kernel, bulk-index path): when present,
  240. * `nodes`/`edges`/`unresolvedReferences` are EMPTY and the file's tables
  241. * ride as flat buffers to be decoded at the store boundary (the store
  242. * worker), so the MAIN thread never materializes per-node objects.
  243. * `kernelCounts` carries the table sizes for bookkeeping. Decode into a
  244. * plain result with `materializeKernelResult` (src/extraction/kernel).
  245. */
  246. kernelBuffers?: {
  247. meta: Uint8Array;
  248. nodes: Uint8Array;
  249. edges: Uint8Array;
  250. refs: Uint8Array;
  251. arena: Uint8Array;
  252. };
  253. kernelCounts?: { nodes: number; edges: number; refs: number };
  254. }
  255. /**
  256. * Error during code extraction
  257. */
  258. export interface ExtractionError {
  259. /** Error message */
  260. message: string;
  261. /** File path where the error occurred */
  262. filePath?: string;
  263. /** Line number if available */
  264. line?: number;
  265. /** Column number if available */
  266. column?: number;
  267. /** Error severity */
  268. severity: 'error' | 'warning';
  269. /** Error code for categorization */
  270. code?: string;
  271. }
  272. /**
  273. * Kinds an unresolved reference can carry. `function_ref` is internal-only —
  274. * a function name used as a VALUE (callback registration, #756). It never
  275. * becomes an edge kind: resolution maps it to a `references` edge targeting
  276. * function/method nodes only (see `matchFunctionRef`).
  277. */
  278. export type ReferenceKind = EdgeKind | 'function_ref';
  279. /**
  280. * A reference that couldn't be resolved during extraction
  281. */
  282. export interface UnresolvedReference {
  283. /** ID of the node containing the reference */
  284. fromNodeId: string;
  285. /** Name being referenced */
  286. referenceName: string;
  287. /** Type of reference (call, type, import, etc.) */
  288. referenceKind: ReferenceKind;
  289. /** Location of the reference */
  290. line: number;
  291. column: number;
  292. /** File path where reference occurs (denormalized for performance) */
  293. filePath?: string;
  294. /** Language of the source file (denormalized for performance) */
  295. language?: Language;
  296. /** Possible qualified names it might resolve to */
  297. candidates?: string[];
  298. /**
  299. * `unresolved_refs.id` when this ref was loaded from the database. Post-pass
  300. * cleanup (delete-on-resolve / park-as-failed) targets exactly this row.
  301. * Without it, cleanup falls back to deleting by (fromNodeId, referenceName,
  302. * referenceKind) — which also removes SIBLING rows (same caller calling the
  303. * same callee at other lines) that a later batch hasn't attempted yet, so
  304. * their edges were silently never created when a batch boundary split the
  305. * call sites (#1269).
  306. */
  307. rowId?: number;
  308. }
  309. // =============================================================================
  310. // Query Types
  311. // =============================================================================
  312. /**
  313. * A subgraph containing a subset of the knowledge graph
  314. */
  315. export interface Subgraph {
  316. /** Nodes in this subgraph */
  317. nodes: Map<string, Node>;
  318. /** Edges in this subgraph */
  319. edges: Edge[];
  320. /** Root node IDs (entry points) */
  321. roots: string[];
  322. /**
  323. * Retrieval confidence for context-style queries. `'low'` means the query
  324. * resolved only to isolated common-word matches (no entry point corroborated
  325. * by 2+ distinct query terms) — callers should surface an honest handoff to
  326. * explore/trace rather than present the results as comprehensive. Undefined
  327. * for graph traversals that don't run the search-ranking path.
  328. */
  329. confidence?: 'high' | 'low';
  330. }
  331. /**
  332. * Options for graph traversal
  333. */
  334. export interface TraversalOptions {
  335. /** Maximum depth to traverse (default: Infinity) */
  336. maxDepth?: number;
  337. /** Edge types to follow (default: all) */
  338. edgeKinds?: EdgeKind[];
  339. /** Node types to include (default: all) */
  340. nodeKinds?: NodeKind[];
  341. /** Direction of traversal */
  342. direction?: 'outgoing' | 'incoming' | 'both';
  343. /** Maximum nodes to return */
  344. limit?: number;
  345. /** Whether to include the starting node */
  346. includeStart?: boolean;
  347. }
  348. /**
  349. * Options for searching the graph
  350. */
  351. export interface SearchOptions {
  352. /** Node types to search */
  353. kinds?: NodeKind[];
  354. /** Languages to include */
  355. languages?: Language[];
  356. /** File path patterns to include */
  357. includePatterns?: string[];
  358. /** File path patterns to exclude */
  359. excludePatterns?: string[];
  360. /** Maximum results to return */
  361. limit?: number;
  362. /** Offset for pagination */
  363. offset?: number;
  364. /** Whether search is case-sensitive */
  365. caseSensitive?: boolean;
  366. }
  367. /**
  368. * A search result with relevance scoring
  369. */
  370. export interface SearchResult {
  371. /** Matching node */
  372. node: Node;
  373. /**
  374. * Relevance score for relative ranking only — higher is more relevant.
  375. * NOT normalized and NOT a 0-1 fraction: the FTS path returns an unbounded
  376. * BM25 magnitude (often in the tens or hundreds), while the fuzzy/exact
  377. * paths return ~0-1. Use it to order results, not as an absolute percentage.
  378. */
  379. score: number;
  380. /** Matched text snippets for highlighting */
  381. highlights?: string[];
  382. }
  383. /**
  384. * A symbol whose name-segments match prose words from a prompt — the
  385. * graph-derived signal behind the front-load hook's medium tier
  386. * (CodeGraph.getSegmentMatches). Always verified to exist in `nodes` at the
  387. * time it is returned.
  388. */
  389. export interface SegmentMatch {
  390. /** Symbol name as indexed (e.g. `OrderStateMachine`). */
  391. name: string;
  392. /** Kind of the representative definition. */
  393. kind: NodeKind;
  394. /** File of the representative definition. */
  395. filePath: string;
  396. /** 1-based start line of the representative definition. */
  397. startLine: number;
  398. /** The prompt words (normalized) that matched this name's segments. */
  399. matchedWords: string[];
  400. }
  401. // =============================================================================
  402. // Context Types
  403. // =============================================================================
  404. /**
  405. * Context information for code understanding
  406. */
  407. export interface Context {
  408. /** Primary node being examined */
  409. focal: Node;
  410. /** Nodes containing the focal node (file, class, etc.) */
  411. ancestors: Node[];
  412. /** Nodes directly contained by focal node */
  413. children: Node[];
  414. /** Incoming references (who calls/uses this) */
  415. incomingRefs: Array<{ node: Node; edge: Edge }>;
  416. /** Outgoing references (what this calls/uses) */
  417. outgoingRefs: Array<{ node: Node; edge: Edge }>;
  418. /** Related type information */
  419. types: Node[];
  420. /** Relevant imports */
  421. imports: Node[];
  422. }
  423. /**
  424. * A block of code with context
  425. */
  426. export interface CodeBlock {
  427. /** The code content */
  428. content: string;
  429. /** File path */
  430. filePath: string;
  431. /** Starting line */
  432. startLine: number;
  433. /** Ending line */
  434. endLine: number;
  435. /** Language for syntax highlighting */
  436. language: Language;
  437. /** Associated node if extracted */
  438. node?: Node;
  439. }
  440. // =============================================================================
  441. // Database Types
  442. // =============================================================================
  443. /**
  444. * Database schema version info
  445. */
  446. export interface SchemaVersion {
  447. /** Current schema version */
  448. version: number;
  449. /** When schema was created/updated */
  450. appliedAt: number;
  451. /** Description of this version */
  452. description?: string;
  453. }
  454. /**
  455. * Statistics about the knowledge graph
  456. */
  457. export interface GraphStats {
  458. /** Total number of nodes */
  459. nodeCount: number;
  460. /** Total number of edges */
  461. edgeCount: number;
  462. /** Number of tracked files */
  463. fileCount: number;
  464. /** Node counts by kind */
  465. nodesByKind: Record<NodeKind, number>;
  466. /** Edge counts by kind */
  467. edgesByKind: Record<EdgeKind, number>;
  468. /** File counts by language */
  469. filesByLanguage: Record<Language, number>;
  470. /** Database size in bytes */
  471. dbSizeBytes: number;
  472. /** Size of the SQLite `-wal` sidecar in bytes (0 when absent). A WAL far
  473. * larger than the DB at rest means killed sessions left it behind (#1431). */
  474. walSizeBytes: number;
  475. /** Last update timestamp */
  476. lastUpdated: number;
  477. }
  478. // =============================================================================
  479. // Task Context Types (for buildContext)
  480. // =============================================================================
  481. /**
  482. * Input for building task context
  483. */
  484. export type TaskInput = string | { title: string; description?: string };
  485. /**
  486. * Options for building task context
  487. */
  488. export interface BuildContextOptions {
  489. /** Maximum number of nodes to include (default: 50) */
  490. maxNodes?: number;
  491. /** Maximum number of code blocks to include (default: 10) */
  492. maxCodeBlocks?: number;
  493. /** Maximum characters per code block (default: 2000) */
  494. maxCodeBlockSize?: number;
  495. /** Whether to include code blocks (default: true) */
  496. includeCode?: boolean;
  497. /** Output format (default: 'markdown') */
  498. format?: 'markdown' | 'json';
  499. /** Number of semantic search results (default: 5) */
  500. searchLimit?: number;
  501. /** Graph traversal depth from entry points (default: 2) */
  502. traversalDepth?: number;
  503. /** Minimum semantic similarity score (default: 0.3) */
  504. minScore?: number;
  505. }
  506. /**
  507. * Full context for a task, ready for Claude
  508. */
  509. export interface TaskContext {
  510. /** The original query/task */
  511. query: string;
  512. /** Subgraph of relevant nodes and edges */
  513. subgraph: Subgraph;
  514. /** Entry point nodes (from semantic search) */
  515. entryPoints: Node[];
  516. /** Code blocks extracted from key nodes */
  517. codeBlocks: CodeBlock[];
  518. /** Files involved in this context */
  519. relatedFiles: string[];
  520. /** Brief summary of the context */
  521. summary: string;
  522. /** Statistics about the context */
  523. stats: {
  524. /** Number of nodes included */
  525. nodeCount: number;
  526. /** Number of edges included */
  527. edgeCount: number;
  528. /** Number of files touched */
  529. fileCount: number;
  530. /** Number of code blocks included */
  531. codeBlockCount: number;
  532. /** Total characters in code blocks */
  533. totalCodeSize: number;
  534. };
  535. }
  536. /**
  537. * Options for finding relevant context
  538. */
  539. export interface FindRelevantContextOptions {
  540. /** Number of semantic search results (default: 5) */
  541. searchLimit?: number;
  542. /** Graph traversal depth (default: 2) */
  543. traversalDepth?: number;
  544. /** Maximum nodes in result (default: 50) */
  545. maxNodes?: number;
  546. /** Minimum semantic similarity score (default: 0.3) */
  547. minScore?: number;
  548. /** Edge types to follow in traversal */
  549. edgeKinds?: EdgeKind[];
  550. /** Node types to include */
  551. nodeKinds?: NodeKind[];
  552. /**
  553. * Extra symbol names to merge in as exact-name search candidates, at a
  554. * dampened score. Fed by the segment-vocabulary supplement (CodeGraph.
  555. * findRelevantContext): word-level query terms can't reach camelCase names
  556. * through FTS — `pinFeedIfNearBottom` is one FTS token — so names whose
  557. * SEGMENTS the query's words name are seeded here instead.
  558. */
  559. seedNames?: string[];
  560. }