@vndv/pi-codegraph 0.1.6 → 0.1.8

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,12 +2,13 @@
2
2
  ### CodeGraph tools for pi
3
3
 
4
4
  [![Skylos Grade](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/vndv/pi-codegraph/main/.github/badges/skylos.json)](https://github.com/duriantaco/skylos)
5
+ [![npm downloads](https://img.shields.io/npm/dm/%40vndv%2Fpi-codegraph)](https://www.npmjs.com/package/@vndv/pi-codegraph)
5
6
 
6
7
  [Install](#install) · [Usage](#usage) · [How it works](#how-it-works)
7
8
 
8
9
  Ask pi structural questions about your codebase without falling back to slow grep/read loops.
9
10
 
10
- An extension for [pi](https://pi.dev) that gives the agent access to [CodeGraph](https://github.com/colbymchenry/codegraph) tools. CodeGraph indexes your project with tree-sitter, then pi can query symbols, callers, callees, dependency impact, files, and call paths through native extension tools.
11
+ An extension for [pi](https://pi.dev) that gives the agent access to [CodeGraph](https://github.com/colbymchenry/codegraph) tools. CodeGraph indexes your project with tree-sitter, then pi can query symbols, callers, callees, dependency impact, files, and relationships through native extension tools.
11
12
 
12
13
  ---
13
14
 
@@ -17,7 +18,7 @@ An extension for [pi](https://pi.dev) that gives the agent access to [CodeGraph]
17
18
  npm install -g @colbymchenry/codegraph
18
19
  cd /path/to/project
19
20
  codegraph init -i
20
- pi install npm:@vndv/pi-codegraph@0.1.6
21
+ pi install npm:@vndv/pi-codegraph@0.1.8
21
22
  pi
22
23
  ```
23
24
 
@@ -35,13 +36,11 @@ Extension tools only. There is no MCP setup for pi users to maintain.
35
36
 
36
37
  | Tool | Description |
37
38
  | --- | --- |
38
- | `codegraph_context` | Broad task context: entry points, related symbols, callers, callees, and key code |
39
39
  | `codegraph_search` | Symbol search by name |
40
40
  | `codegraph_node` | One symbol's signature, location, source, callers, and callees |
41
41
  | `codegraph_files` | Indexed file tree |
42
42
  | `codegraph_callers` | Functions or methods that call a symbol |
43
43
  | `codegraph_callees` | Functions or methods called by a symbol |
44
- | `codegraph_trace` | Static call path from one symbol to another |
45
44
  | `codegraph_impact` | Impact radius for changing a symbol |
46
45
  | `codegraph_explore` | Source for several related symbols grouped by file |
47
46
  | `codegraph_status` | Index health and pending sync status |
@@ -53,7 +52,7 @@ Extension tools only. There is no MCP setup for pi users to maintain.
53
52
  From npm:
54
53
 
55
54
  ```bash
56
- pi install npm:@vndv/pi-codegraph@0.1.6
55
+ pi install npm:@vndv/pi-codegraph@0.1.8
57
56
  ```
58
57
 
59
58
  From GitHub:
@@ -82,7 +81,7 @@ pi list
82
81
 
83
82
  ## Requirements
84
83
 
85
- Node.js 22 LTS is recommended. CodeGraph blocks Node.js 25 because that Node line has a V8 WASM JIT issue that can crash while compiling tree-sitter grammars.
84
+ Node.js 22.19.0 or newer is required.
86
85
 
87
86
  CodeGraph must be installed and available on `PATH`:
88
87
 
@@ -125,12 +124,10 @@ Use CodeGraph. Show files under internal/services and important symbols.
125
124
 
126
125
  ### 3. Prefer the right tool
127
126
 
128
- Use `codegraph_context` for broad "how does this work?" questions.
127
+ Use `codegraph_explore` for broad "how does this work?" or "how does X reach Y?" questions.
129
128
 
130
129
  Use `codegraph_node` when you already know the symbol name.
131
130
 
132
- Use `codegraph_trace` for "how does X reach Y?" flow questions.
133
-
134
131
  Use `codegraph_search` for declarations and symbols, not arbitrary text or constant values.
135
132
 
136
133
  ---
@@ -162,7 +159,7 @@ That means another developer only needs the npm package, the `codegraph` CLI, an
162
159
  Remove the package using the same source shown by `pi list`:
163
160
 
164
161
  ```bash
165
- pi remove npm:@vndv/pi-codegraph@0.1.6
162
+ pi remove npm:@vndv/pi-codegraph@0.1.8
166
163
  ```
167
164
 
168
165
  If you installed from GitHub or a local path, remove that exact entry instead:
@@ -199,7 +196,7 @@ codegraph init -i
199
196
 
200
197
  ### Node.js version is unsupported
201
198
 
202
- Use Node.js 22 LTS:
199
+ Use Node.js 22.19.0 or newer:
203
200
 
204
201
  ```bash
205
202
  nvm install 22
@@ -1,5 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { stat } from "node:fs/promises";
3
+ import os from "node:os";
3
4
  import path from "node:path";
4
5
  import { pathToFileURL } from "node:url";
5
6
  import type { ChildProcessWithoutNullStreams } from "node:child_process";
@@ -34,17 +35,6 @@ const ToolDefinitions = [
34
35
  projectPath: OptionalProjectPath,
35
36
  }),
36
37
  },
37
- {
38
- name: "codegraph_context",
39
- label: "CodeGraph Context",
40
- description: "Primary tool for architecture, feature, bug-context, or how-does-X-work questions.",
41
- parameters: Type.Object({
42
- task: Type.String({ description: "Task, question, or code area to understand." }),
43
- maxNodes: Type.Optional(Type.Number({ default: 20 })),
44
- includeCode: Type.Optional(Type.Boolean({ default: true })),
45
- projectPath: OptionalProjectPath,
46
- }),
47
- },
48
38
  {
49
39
  name: "codegraph_callers",
50
40
  label: "CodeGraph Callers",
@@ -120,16 +110,6 @@ const ToolDefinitions = [
120
110
  projectPath: OptionalProjectPath,
121
111
  }),
122
112
  },
123
- {
124
- name: "codegraph_trace",
125
- label: "CodeGraph Trace",
126
- description: "Trace the call path between two symbols.",
127
- parameters: Type.Object({
128
- from: Type.String(),
129
- to: Type.String(),
130
- projectPath: OptionalProjectPath,
131
- }),
132
- },
133
113
  ] as const;
134
114
 
135
115
  type ToolName = (typeof ToolDefinitions)[number]["name"];
@@ -180,6 +160,34 @@ export async function resolveProjectCwd(projectPath: string | undefined): Promis
180
160
  return cwd;
181
161
  }
182
162
 
163
+ export function normalizeFilesPath(inputPath?: string, projectCwd?: string): string | undefined {
164
+ if (typeof inputPath !== "string" || inputPath.trim() === "") return undefined;
165
+
166
+ const trimmed = inputPath.trim();
167
+ let expanded = trimmed;
168
+ if (expanded === "~" || expanded.startsWith("~/") || expanded.startsWith("~\\")) {
169
+ expanded = path.join(os.homedir(), expanded.slice(1));
170
+ }
171
+
172
+ if (projectCwd && path.isAbsolute(expanded)) {
173
+ const relative = path.relative(projectCwd, expanded);
174
+ if (relative === "") return undefined;
175
+ if (!relative.startsWith("..") && !path.isAbsolute(relative)) {
176
+ return relative.split(path.sep).join("/");
177
+ }
178
+ }
179
+
180
+ return trimmed.split(path.sep).join("/");
181
+ }
182
+
183
+ const EmptyFilesMarker = "No files found matching the criteria.";
184
+
185
+ export function annotateFilesResult(resultText: string, originalPath?: string): string {
186
+ if (!originalPath || !resultText.includes(EmptyFilesMarker)) return resultText;
187
+
188
+ return `${resultText}\n\nHint: codegraph_files interprets "path" as a root-relative POSIX prefix (e.g. "src/components"). The filter "${originalPath}" did not match any indexed path.`;
189
+ }
190
+
183
191
  export function sanitizeDiagnostic(value: string): string {
184
192
  const withoutAnsi = value.replace(/\u001b\[[0-9;]*m/g, "");
185
193
  const redacted = withoutAnsi
@@ -332,17 +340,42 @@ async function initializeJsonRpcSession(
332
340
  sendNotification("initialized", {});
333
341
  }
334
342
 
343
+ async function prepareToolArguments(
344
+ name: ToolName,
345
+ params: ToolParams,
346
+ ): Promise<{ args: ToolParams; originalFilesPath?: string }> {
347
+ if (name !== "codegraph_files") return { args: params };
348
+
349
+ const projectPath = typeof params.projectPath === "string" ? params.projectPath : undefined;
350
+ const projectCwd = await resolveProjectCwd(projectPath);
351
+ const originalFilesPath = typeof params.path === "string" ? params.path : undefined;
352
+ const normalizedPath = normalizeFilesPath(originalFilesPath, projectCwd);
353
+
354
+ const args: ToolParams = { ...params };
355
+ if (normalizedPath === undefined) {
356
+ delete args.path;
357
+ } else {
358
+ args.path = normalizedPath;
359
+ }
360
+
361
+ return { args, originalFilesPath };
362
+ }
363
+
335
364
  export async function callCodeGraphTool(
336
365
  name: ToolName,
337
366
  params: ToolParams,
338
367
  signal?: AbortSignal,
339
368
  ): Promise<string> {
340
- const projectPath = typeof params.projectPath === "string" ? params.projectPath : undefined;
341
- const result = await withCodeGraphMcp(projectPath, signal, (request) =>
342
- request("tools/call", {
343
- name,
344
- arguments: params || {},
345
- })
369
+ const { args, originalFilesPath } = await prepareToolArguments(name, params);
370
+
371
+ const result = await withCodeGraphMcp(
372
+ typeof args.projectPath === "string" ? args.projectPath : undefined,
373
+ signal,
374
+ (request) =>
375
+ request("tools/call", {
376
+ name,
377
+ arguments: args,
378
+ }),
346
379
  );
347
380
 
348
381
  const text = (result?.content || [])
@@ -351,7 +384,8 @@ export async function callCodeGraphTool(
351
384
  .join("\n");
352
385
 
353
386
  if (result?.isError) throw new Error(text || "CodeGraph tool failed.");
354
- return text || JSON.stringify(result);
387
+ const finalText = text || JSON.stringify(result);
388
+ return name === "codegraph_files" ? annotateFilesResult(finalText, originalFilesPath) : finalText;
355
389
  }
356
390
 
357
391
  export default function codegraphExtension(pi: ExtensionAPI): void {
@@ -359,8 +393,8 @@ export default function codegraphExtension(pi: ExtensionAPI): void {
359
393
  const guidance = [
360
394
  "CodeGraph tools are available as codegraph_* Pi tools.",
361
395
  "For architecture, flow, where-is-symbol, impact, and codebase navigation questions, use CodeGraph tools directly before grep/read.",
362
- "Use codegraph_context first for broad questions, codegraph_search for symbol-name lookup, codegraph_files for project structure, codegraph_node for a known symbol, and codegraph_trace for call paths.",
363
- "If codegraph_search returns no exact result, try codegraph_context or codegraph_files/codegraph_explore before falling back to grep/read; CodeGraph symbol search may miss literal constants or generated names that still exist in source text.",
396
+ "Use codegraph_explore first for broad questions, codegraph_search for symbol-name lookup, codegraph_files for project structure, codegraph_node for a known symbol, and codegraph_callers for impact/flow analysis.",
397
+ "If codegraph_search returns no exact result, try codegraph_explore or codegraph_files/codegraph_node before falling back to grep/read; CodeGraph symbol search may miss literal constants or generated names that still exist in source text.",
364
398
  "Only use grep/read after CodeGraph is insufficient or when the user asks for literal text matching.",
365
399
  ].join("\n");
366
400
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vndv/pi-codegraph",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "CodeGraph tools for Pi Agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,7 +48,7 @@
48
48
  "version-packages": "changeset version && npm run sync:readme-version && npm install --package-lock-only --ignore-scripts"
49
49
  },
50
50
  "engines": {
51
- "node": ">=22.19.0 <25"
51
+ "node": ">=22.19.0"
52
52
  },
53
53
  "publishConfig": {
54
54
  "access": "public"