types.ts 17 KB

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