@kentwynn/kgraph 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Persistent repository intelligence for AI coding tools.
4
4
 
5
- KGraph gives Codex, GitHub Copilot, Cursor, and Claude Code a local knowledge layer for your repo: file maps, symbols, imports, relationships, and durable notes from previous AI sessions. The goal is simple: your assistant should not spend every session re-learning the same codebase.
5
+ KGraph gives Codex, GitHub Copilot, Cursor, Claude Code, Gemini CLI, Windsurf, and Cline a local knowledge layer for your repo: file maps, symbols, imports, relationships, and durable notes from previous AI sessions. The goal is simple: your assistant should not spend every session re-learning the same codebase.
6
6
 
7
7
  ## The Workflow
8
8
 
@@ -10,7 +10,7 @@ Use KGraph in two steps:
10
10
 
11
11
  ```bash
12
12
  # Required once per repository
13
- kgraph init --integrations codex,copilot,cursor,claude-code
13
+ kgraph init --integrations codex,copilot,cursor,claude-code,gemini,windsurf,cline
14
14
 
15
15
  # Normal daily command
16
16
  kgraph "auth token refresh"
@@ -51,6 +51,7 @@ KGraph stores the reusable parts locally:
51
51
  - What files exist and what language they use.
52
52
  - What symbols each source file defines.
53
53
  - Which files import each other.
54
+ - Which TypeScript/JavaScript functions and methods directly call each other when KGraph can infer it cheaply.
54
55
  - Which notes, decisions, debugging findings, and gotchas were captured from prior sessions.
55
56
  - Which cognition references are current, mixed, stale, or unresolved after code moves.
56
57
 
@@ -89,7 +90,7 @@ From the root of a repository:
89
90
  kgraph init
90
91
 
91
92
  # 2. Optional: connect AI tools so they know the KGraph workflow
92
- kgraph integrate add codex copilot cursor claude-code
93
+ kgraph integrate add codex copilot cursor claude-code gemini windsurf cline
93
94
 
94
95
  # 3. Run the normal workflow for a topic
95
96
  kgraph "auth token refresh"
@@ -120,7 +121,7 @@ kgraph init
120
121
  Required once per repo. Creates `.kgraph/` and the local config.
121
122
 
122
123
  ```bash
123
- kgraph init --integrations codex,copilot,cursor,claude-code
124
+ kgraph init --integrations codex,copilot,cursor,claude-code,gemini,windsurf,cline
124
125
  ```
125
126
 
126
127
  Initializes KGraph and writes local instruction files for supported AI tools.
@@ -196,7 +197,7 @@ Show processed cognition sessions.
196
197
  KGraph integrations are local files. They do not start background agents, call AI providers, or send data anywhere.
197
198
 
198
199
  ```bash
199
- kgraph integrate add codex copilot cursor claude-code
200
+ kgraph integrate add codex copilot cursor claude-code gemini windsurf cline
200
201
  kgraph integrate list
201
202
  kgraph integrate remove cursor
202
203
  ```
@@ -207,6 +208,11 @@ kgraph integrate remove cursor
207
208
  | GitHub Copilot | `.github/copilot-instructions.md`, `.github/prompts/*` |
208
209
  | Cursor | `.cursor/rules/kgraph.mdc` |
209
210
  | Claude Code | `CLAUDE.md`, `.claude/commands/*` |
211
+ | Gemini CLI | `GEMINI.md` |
212
+ | Windsurf | `.windsurf/rules/kgraph.md` |
213
+ | Cline | `.clinerules/kgraph.md` |
214
+
215
+ Antigravity is supported through the existing agent instruction surfaces it can read, especially `AGENTS.md` and `GEMINI.md`; it does not need a separate KGraph adapter yet.
210
216
 
211
217
  KGraph preserves existing user-authored content and updates only its marked instruction blocks or generated command files.
212
218
 
@@ -235,7 +241,7 @@ The files are local, inspectable, and human-readable. There is no database, tele
235
241
 
236
242
  KGraph deeply scans:
237
243
 
238
- - TypeScript and JavaScript
244
+ - TypeScript and JavaScript, including lightweight function/method call relationships
239
245
  - Python
240
246
  - Go
241
247
  - Rust
@@ -243,7 +249,7 @@ KGraph deeply scans:
243
249
  - C and C++
244
250
  - C#
245
251
 
246
- Other common file types still appear in the file map with generic metadata, so context queries can still point to docs, config, SQL, CSS, HTML, YAML, and similar files.
252
+ Other languages keep practical file, import, and symbol depth without full call graph analysis. Common file types still appear in the file map with generic metadata, so context queries can still point to docs, config, SQL, CSS, HTML, YAML, and similar files.
247
253
 
248
254
  ## Visualization
249
255
 
@@ -251,7 +257,7 @@ Other common file types still appear in the file map with generic metadata, so c
251
257
  kgraph visualize
252
258
  ```
253
259
 
254
- The graph shows files, symbols, imports, cognition notes, and relationship edges. Cognition notes are colored by reference health:
260
+ The graph shows files, symbols, imports, TypeScript/JavaScript call edges, ownership edges, cognition notes, and relationship edges. Cognition notes are colored by reference health:
255
261
 
256
262
  - current
257
263
  - mixed
package/dist/cli/help.js CHANGED
@@ -2,7 +2,7 @@ import { Chalk } from 'chalk';
2
2
  import figlet from 'figlet';
3
3
  export function renderRootHelp(useColor = supportsColor()) {
4
4
  const theme = new Chalk({ level: useColor ? 3 : 0 });
5
- const command = (name, description) => ` ${theme.green(name.padEnd(30))} ${description}`;
5
+ const command = (name, description) => ` ${theme.green(name.padEnd(42))} ${description}`;
6
6
  const logo = renderLogo();
7
7
  return [
8
8
  '',
@@ -11,7 +11,7 @@ export function renderRootHelp(useColor = supportsColor()) {
11
11
  ` ${theme.bold('KGraph')} ${theme.dim('Persistent repo intelligence for AI coding tools')}`,
12
12
  '',
13
13
  ` ${theme.hex('#c084fc')('Build a local knowledge layer that helps Codex, Copilot, Cursor,')}`,
14
- ` ${theme.hex('#c084fc')('and Claude Code reuse repo structure, decisions, and debugging history.')}`,
14
+ ` ${theme.hex('#c084fc')('Claude Code, Gemini, Windsurf, and Cline reuse repo intelligence.')}`,
15
15
  '',
16
16
  theme.bold('Usage'),
17
17
  ' kgraph [topic]',
@@ -19,7 +19,7 @@ export function renderRootHelp(useColor = supportsColor()) {
19
19
  '',
20
20
  theme.bold('Start'),
21
21
  command('init', 'Required once: create .kgraph/ workspace'),
22
- command('init --integrations codex,cursor', 'Initialize and connect AI tools'),
22
+ command('init --integrations codex,gemini', 'Initialize and connect AI tools'),
23
23
  '',
24
24
  theme.bold('Daily workflow'),
25
25
  command('kgraph', 'Refresh scan maps and process pending cognition notes'),
@@ -38,7 +38,7 @@ export function renderRootHelp(useColor = supportsColor()) {
38
38
  '',
39
39
  theme.bold('Integrations'),
40
40
  command('integrate list', 'Show configured AI tool integrations'),
41
- command('integrate add codex copilot', 'Write KGraph instructions for AI tools'),
41
+ command('integrate add gemini windsurf cline', 'Write KGraph instructions for AI tools'),
42
42
  command('integrate remove cursor', 'Remove KGraph-managed instruction blocks'),
43
43
  '',
44
44
  theme.bold('Options'),
@@ -46,7 +46,7 @@ export function renderRootHelp(useColor = supportsColor()) {
46
46
  command('-h, --help', 'Show this help'),
47
47
  '',
48
48
  `${theme.yellow('Examples')}`,
49
- ' kgraph init --integrations codex,copilot,cursor',
49
+ ' kgraph init --integrations codex,copilot,cursor,claude-code,gemini,windsurf,cline',
50
50
  ' kgraph "blog admin token usage"',
51
51
  ' kgraph doctor',
52
52
  '',
@@ -56,7 +56,7 @@ export function renderRootHelp(useColor = supportsColor()) {
56
56
  }
57
57
  export function renderWorkflowBanner(stats, useColor = supportsColor()) {
58
58
  const theme = new Chalk({ level: useColor ? 3 : 0 });
59
- const command = (name, description) => ` ${theme.green(name.padEnd(30))} ${description}`;
59
+ const command = (name, description) => ` ${theme.green(name.padEnd(42))} ${description}`;
60
60
  return [
61
61
  '',
62
62
  theme.hex('#7dd3fc').bold(renderLogo()),
@@ -25,10 +25,13 @@ export const DEFAULT_CONFIG = {
25
25
  'specs',
26
26
  '.cursor',
27
27
  '.claude',
28
+ '.windsurf',
29
+ '.clinerules',
28
30
  '.github/copilot-instructions.md',
29
31
  '.github/prompts',
30
32
  'AGENTS.md',
31
33
  'CLAUDE.md',
34
+ 'GEMINI.md',
32
35
  'REQUIREMENTS.md',
33
36
  '*.log',
34
37
  '*.tgz',
@@ -132,7 +135,15 @@ function normalizeIntegrations(value) {
132
135
  seen.has(candidate.name)) {
133
136
  continue;
134
137
  }
135
- if (!['claude-code', 'codex', 'copilot', 'cursor'].includes(candidate.name)) {
138
+ if (![
139
+ 'claude-code',
140
+ 'cline',
141
+ 'codex',
142
+ 'copilot',
143
+ 'cursor',
144
+ 'gemini',
145
+ 'windsurf',
146
+ ].includes(candidate.name)) {
136
147
  continue;
137
148
  }
138
149
  seen.add(candidate.name);
@@ -39,6 +39,13 @@ export async function queryContext(workspace, config, maps, query) {
39
39
  ...domain.item.symbols,
40
40
  ]),
41
41
  ]);
42
+ for (const relationship of maps.relationshipMap.relationships) {
43
+ if (relatedIds.has(relationship.sourceId) ||
44
+ relatedIds.has(relationship.targetId)) {
45
+ relatedIds.add(relationship.sourceId);
46
+ relatedIds.add(relationship.targetId);
47
+ }
48
+ }
42
49
  const rankedRelationships = rankByFields(query, maps.relationshipMap.relationships, [
43
50
  { name: 'source', value: (relationship) => relationship.sourceId },
44
51
  { name: 'target', value: (relationship) => relationship.targetId },
@@ -0,0 +1,2 @@
1
+ import type { IntegrationAdapter } from '../integration-registry.js';
2
+ export declare const clineAdapter: IntegrationAdapter;
@@ -0,0 +1,17 @@
1
+ export const clineAdapter = {
2
+ name: 'cline',
3
+ label: 'Cline',
4
+ targetPath: '.clinerules/kgraph.md',
5
+ instructions: `# KGraph Workflow
6
+
7
+ - **Before exploring the repository**, run \`kgraph "<topic>"\` to refresh maps, process pending inbox notes, and load focused repo intelligence. Use the returned files, symbols, relationships, and cognition before any broad exploration.
8
+ - Run \`kgraph doctor\` when setup, maps, inbox processing, or integrations look wrong. Run \`kgraph doctor --quality\` when context shows stale/noisy cognition references.
9
+ - At the end of any session that changed repository files, check the KGraph capture workflow before finishing.
10
+ - If the file change has future value, write one concise Markdown note to \`.kgraph/inbox/<slug>.md\`; otherwise explicitly skip capture as trivial.
11
+ - Skip capture only for read-only work, trivial formatting, typo-only docs, dependency-only churn, mechanical cleanup with no future value, or sessions where no repo files changed.
12
+ - Do not run KGraph repeatedly. Run it once at the start with \`kgraph "<topic>"\`. If repo files changed, write any needed inbox note first, then run \`kgraph\` once at the end.
13
+ - Run \`kgraph repair --dry-run\` before cleanup when stale/noisy cognition needs fixing. Run \`kgraph repair\` only when the user asks to apply that cleanup.
14
+ - Run \`kgraph visualize\` to open the interactive dependency graph at http://localhost:4242 with PNG export.
15
+ - Run \`kgraph history\` to review the timeline of past cognition sessions with git author attribution.
16
+ `,
17
+ };
@@ -0,0 +1,2 @@
1
+ import type { IntegrationAdapter } from '../integration-registry.js';
2
+ export declare const geminiAdapter: IntegrationAdapter;
@@ -0,0 +1,17 @@
1
+ export const geminiAdapter = {
2
+ name: 'gemini',
3
+ label: 'Gemini CLI',
4
+ targetPath: 'GEMINI.md',
5
+ instructions: `## KGraph Workflow
6
+
7
+ - **Before exploring the repository**, run \`kgraph "<topic>"\` to refresh maps, process pending inbox notes, and load focused repo intelligence. Use the returned files, symbols, relationships, and cognition before any broad exploration.
8
+ - Run \`kgraph doctor\` when setup, maps, inbox processing, or integrations look wrong. Run \`kgraph doctor --quality\` when context shows stale/noisy cognition references.
9
+ - At the end of any session that changed repository files, check the KGraph capture workflow before finishing.
10
+ - If the file change has future value, write one concise Markdown note to \`.kgraph/inbox/<slug>.md\`; otherwise explicitly skip capture as trivial.
11
+ - Skip capture only for read-only work, trivial formatting, typo-only docs, dependency-only churn, mechanical cleanup with no future value, or sessions where no repo files changed.
12
+ - Do not run KGraph repeatedly. Run it once at the start with \`kgraph "<topic>"\`. If repo files changed, write any needed inbox note first, then run \`kgraph\` once at the end.
13
+ - Run \`kgraph repair --dry-run\` before cleanup when stale/noisy cognition needs fixing. Run \`kgraph repair\` only when the user asks to apply that cleanup.
14
+ - Run \`kgraph visualize\` to open the interactive dependency graph at http://localhost:4242 with PNG export.
15
+ - Run \`kgraph history\` to review the timeline of past cognition sessions with git author attribution.
16
+ `,
17
+ };
@@ -0,0 +1,2 @@
1
+ import type { IntegrationAdapter } from '../integration-registry.js';
2
+ export declare const windsurfAdapter: IntegrationAdapter;
@@ -0,0 +1,17 @@
1
+ export const windsurfAdapter = {
2
+ name: 'windsurf',
3
+ label: 'Windsurf',
4
+ targetPath: '.windsurf/rules/kgraph.md',
5
+ instructions: `# KGraph Workflow
6
+
7
+ - **Before exploring the repository**, run \`kgraph "<topic>"\` to refresh maps, process pending inbox notes, and load focused repo intelligence. Use the returned files, symbols, relationships, and cognition before any broad exploration.
8
+ - Run \`kgraph doctor\` when setup, maps, inbox processing, or integrations look wrong. Run \`kgraph doctor --quality\` when context shows stale/noisy cognition references.
9
+ - At the end of any session that changed repository files, check the KGraph capture workflow before finishing.
10
+ - If the file change has future value, write one concise Markdown note to \`.kgraph/inbox/<slug>.md\`; otherwise explicitly skip capture as trivial.
11
+ - Skip capture only for read-only work, trivial formatting, typo-only docs, dependency-only churn, mechanical cleanup with no future value, or sessions where no repo files changed.
12
+ - Do not run KGraph repeatedly. Run it once at the start with \`kgraph "<topic>"\`. If repo files changed, write any needed inbox note first, then run \`kgraph\` once at the end.
13
+ - Run \`kgraph repair --dry-run\` before cleanup when stale/noisy cognition needs fixing. Run \`kgraph repair\` only when the user asks to apply that cleanup.
14
+ - Run \`kgraph visualize\` to open the interactive dependency graph at http://localhost:4242 with PNG export.
15
+ - Run \`kgraph history\` to review the timeline of past cognition sessions with git author attribution.
16
+ `,
17
+ };
@@ -1,12 +1,18 @@
1
1
  import { claudeCodeAdapter } from "./adapters/claude-code.js";
2
+ import { clineAdapter } from "./adapters/cline.js";
2
3
  import { codexAdapter } from "./adapters/codex.js";
3
4
  import { copilotAdapter } from "./adapters/copilot.js";
4
5
  import { cursorAdapter } from "./adapters/cursor.js";
6
+ import { geminiAdapter } from "./adapters/gemini.js";
7
+ import { windsurfAdapter } from "./adapters/windsurf.js";
5
8
  const ADAPTERS = [
6
9
  claudeCodeAdapter,
10
+ clineAdapter,
7
11
  codexAdapter,
8
12
  copilotAdapter,
9
- cursorAdapter
13
+ cursorAdapter,
14
+ geminiAdapter,
15
+ windsurfAdapter
10
16
  ].sort((left, right) => left.name.localeCompare(right.name));
11
17
  export function listIntegrationAdapters() {
12
18
  return ADAPTERS;
@@ -6,11 +6,14 @@ export function extractTsSymbols(sourceText, filePath) {
6
6
  const dependencies = [];
7
7
  const relationships = [];
8
8
  const warnings = [];
9
+ const symbolIdsByNode = new Map();
10
+ const symbolsByName = new Map();
11
+ const importedBindings = new Map();
9
12
  const addSymbol = (name, kind, node, exported = false, parentName) => {
10
13
  const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
11
14
  const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
12
15
  const id = [filePath, kind, parentName, name, start.line + 1, end.line + 1].filter(Boolean).join("#");
13
- symbols.push({
16
+ const symbol = {
14
17
  id,
15
18
  name,
16
19
  kind,
@@ -19,7 +22,12 @@ export function extractTsSymbols(sourceText, filePath) {
19
22
  endLine: end.line + 1,
20
23
  exported,
21
24
  parentName
22
- });
25
+ };
26
+ symbols.push(symbol);
27
+ symbolIdsByNode.set(node, id);
28
+ const byName = symbolsByName.get(name) ?? [];
29
+ byName.push(symbol);
30
+ symbolsByName.set(name, byName);
23
31
  relationships.push({
24
32
  sourceType: "file",
25
33
  sourceId: filePath,
@@ -28,8 +36,9 @@ export function extractTsSymbols(sourceText, filePath) {
28
36
  relationshipType: "contains",
29
37
  confidence: "high"
30
38
  });
39
+ return symbol;
31
40
  };
32
- const visit = (node, parentName) => {
41
+ const collectSymbols = (node, parentName) => {
33
42
  if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
34
43
  const specifier = node.moduleSpecifier.text;
35
44
  const dependency = {
@@ -48,6 +57,7 @@ export function extractTsSymbols(sourceText, filePath) {
48
57
  relationshipType: "import",
49
58
  confidence: dependency.resolvedFile ? "high" : "medium"
50
59
  });
60
+ collectImportedBindings(node, specifier, dependency.resolvedFile, importedBindings);
51
61
  }
52
62
  if (ts.isExportDeclaration(node)) {
53
63
  const name = node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier) ? node.moduleSpecifier.text : "export";
@@ -66,10 +76,18 @@ export function extractTsSymbols(sourceText, filePath) {
66
76
  }
67
77
  }
68
78
  if (ts.isClassDeclaration(node) && node.name) {
69
- addSymbol(node.name.text, "class", node, isExported(node), parentName);
79
+ const classSymbol = addSymbol(node.name.text, "class", node, isExported(node), parentName);
70
80
  node.members.forEach((member) => {
71
81
  if (ts.isMethodDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
72
- addSymbol(member.name.text, "method", member, false, node.name?.text);
82
+ const methodSymbol = addSymbol(member.name.text, "method", member, false, node.name?.text);
83
+ relationships.push({
84
+ sourceType: "symbol",
85
+ sourceId: classSymbol.id,
86
+ targetType: "symbol",
87
+ targetId: methodSymbol.id,
88
+ relationshipType: "symbol-contains",
89
+ confidence: "high"
90
+ });
73
91
  }
74
92
  });
75
93
  }
@@ -79,16 +97,85 @@ export function extractTsSymbols(sourceText, filePath) {
79
97
  if (ts.isTypeAliasDeclaration(node)) {
80
98
  addSymbol(node.name.text, "type", node, isExported(node), parentName);
81
99
  }
82
- ts.forEachChild(node, (child) => visit(child, parentName));
100
+ ts.forEachChild(node, (child) => collectSymbols(child, parentName));
101
+ };
102
+ const collectCalls = (node, currentSymbolId) => {
103
+ const nextSymbolId = symbolIdsByNode.get(node) ?? currentSymbolId;
104
+ if (ts.isCallExpression(node) && nextSymbolId) {
105
+ const target = resolveCallTarget(node, symbolsByName, importedBindings);
106
+ if (target) {
107
+ relationships.push({
108
+ sourceType: "symbol",
109
+ sourceId: nextSymbolId,
110
+ targetType: target.targetType,
111
+ targetId: target.targetId,
112
+ relationshipType: "calls",
113
+ confidence: target.confidence
114
+ });
115
+ }
116
+ }
117
+ ts.forEachChild(node, (child) => collectCalls(child, nextSymbolId));
83
118
  };
84
119
  try {
85
- visit(sourceFile);
120
+ collectSymbols(sourceFile);
121
+ collectCalls(sourceFile);
86
122
  }
87
123
  catch (error) {
88
124
  warnings.push(error instanceof Error ? error.message : String(error));
89
125
  }
90
126
  return { symbols, dependencies, relationships, warnings };
91
127
  }
128
+ function collectImportedBindings(node, specifier, resolvedFile, importedBindings) {
129
+ const clause = node.importClause;
130
+ if (!clause) {
131
+ return;
132
+ }
133
+ if (clause.name) {
134
+ importedBindings.set(clause.name.text, { specifier, resolvedFile });
135
+ }
136
+ const bindings = clause.namedBindings;
137
+ if (bindings && ts.isNamedImports(bindings)) {
138
+ for (const element of bindings.elements) {
139
+ importedBindings.set(element.name.text, { specifier, resolvedFile });
140
+ }
141
+ }
142
+ }
143
+ function resolveCallTarget(node, symbolsByName, importedBindings) {
144
+ const expression = node.expression;
145
+ if (ts.isIdentifier(expression)) {
146
+ const localSymbols = symbolsByName
147
+ .get(expression.text)
148
+ ?.filter((symbol) => symbol.kind === "function" || symbol.kind === "method");
149
+ if (localSymbols?.[0]) {
150
+ return {
151
+ targetType: "symbol",
152
+ targetId: localSymbols[0].id,
153
+ confidence: "high"
154
+ };
155
+ }
156
+ const imported = importedBindings.get(expression.text);
157
+ if (imported) {
158
+ return {
159
+ targetType: "symbol",
160
+ targetId: imported.resolvedFile ? `${imported.resolvedFile}#${expression.text}` : expression.text,
161
+ confidence: imported.resolvedFile ? "medium" : "low"
162
+ };
163
+ }
164
+ return {
165
+ targetType: "symbol",
166
+ targetId: expression.text,
167
+ confidence: "low"
168
+ };
169
+ }
170
+ if (ts.isPropertyAccessExpression(expression)) {
171
+ return {
172
+ targetType: "symbol",
173
+ targetId: expression.getText(),
174
+ confidence: "low"
175
+ };
176
+ }
177
+ return undefined;
178
+ }
92
179
  function isExported(node) {
93
180
  return ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword));
94
181
  }
@@ -12,7 +12,7 @@ export interface DomainHint {
12
12
  paths?: string[];
13
13
  tags?: string[];
14
14
  }
15
- export type IntegrationName = "claude-code" | "codex" | "copilot" | "cursor";
15
+ export type IntegrationName = "claude-code" | "cline" | "codex" | "copilot" | "cursor" | "gemini" | "windsurf";
16
16
  export interface IntegrationConfig {
17
17
  name: IntegrationName;
18
18
  enabled: boolean;
@@ -1,7 +1,7 @@
1
1
  export type ScanStatus = "mapped" | "generic" | "failed";
2
2
  export type DependencyKind = "local" | "package" | "unknown";
3
3
  export type SymbolKind = "function" | "class" | "method" | "type" | "interface" | "export" | "import";
4
- export type RelationshipType = "import" | "contains" | "mentions" | "belongs-to-domain" | "stale-reference" | "moved-from";
4
+ export type RelationshipType = "import" | "contains" | "symbol-contains" | "calls" | "mentions" | "belongs-to-domain" | "stale-reference" | "moved-from";
5
5
  export interface RepositoryFile {
6
6
  id: string;
7
7
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kentwynn/kgraph",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Persistent repo intelligence for AI coding assistants.",
5
5
  "type": "module",
6
6
  "bin": {