pi-gitnexus 0.2.1 → 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.
- package/CHANGELOG.md +1 -0
- package/README.md +10 -5
- package/package.json +1 -1
- package/src/gitnexus.ts +34 -3
- package/src/index.ts +39 -5
- package/src/mcp-client.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 0.3.0
|
|
4
4
|
|
|
5
|
+
- **Configurable command** — the gitnexus binary invocation is now configurable. Default is `gitnexus` on PATH. Use `/gitnexus config` to set a custom command (e.g. `npx gitnexus@latest`) via an input dialog; the value is persisted to `~/.pi/pi-gitnexus.json`. The `--gitnexus-cmd` CLI flag overrides the saved config for one-off runs. Nothing is ever installed automatically.
|
|
5
6
|
- **TypeScript compatibility** — `tool_result` handler now uses inferred event types from the API overload instead of a manual annotation, fixing a compile error with `@mariozechner/pi-coding-agent` 0.54.x.
|
|
6
7
|
- **Dependency updates** — `@mariozechner/pi-coding-agent` to 0.54.2, `@types/node` to 25.x.
|
|
7
8
|
|
package/README.md
CHANGED
|
@@ -28,15 +28,18 @@ Five tools are also registered directly in pi — the agent can use them explici
|
|
|
28
28
|
|
|
29
29
|
## Requirements
|
|
30
30
|
|
|
31
|
-
- [gitnexus](https://github.com/abhigyanpatwari/GitNexus)
|
|
31
|
+
- [gitnexus](https://github.com/abhigyanpatwari/GitNexus) available as `gitnexus` on PATH (e.g. `npm i -g gitnexus`)
|
|
32
32
|
- A GitNexus index in your project: run `/gitnexus analyze`
|
|
33
33
|
|
|
34
|
+
The extension never installs anything automatically. It assumes `gitnexus` is on PATH. If your setup differs, use `/gitnexus config` to set a custom command (e.g. `npx gitnexus@latest`).
|
|
35
|
+
|
|
34
36
|
## Getting started
|
|
35
37
|
|
|
36
|
-
1. Install
|
|
37
|
-
2.
|
|
38
|
-
3.
|
|
39
|
-
4.
|
|
38
|
+
1. Install the extension: `pi install npm:pi-gitnexus`
|
|
39
|
+
2. Install gitnexus: `npm i -g gitnexus`
|
|
40
|
+
3. Open your project in pi
|
|
41
|
+
4. Run `/gitnexus analyze` to build the knowledge graph
|
|
42
|
+
5. Done — file reads and searches are now enriched automatically
|
|
40
43
|
|
|
41
44
|
## What triggers augmentation
|
|
42
45
|
|
|
@@ -59,6 +62,7 @@ Each tool result augments up to 3 patterns in parallel. Patterns already augment
|
|
|
59
62
|
| `/gitnexus` | Show index status and session enrichment count |
|
|
60
63
|
| `/gitnexus analyze` | Build or rebuild the knowledge graph |
|
|
61
64
|
| `/gitnexus on` / `/gitnexus off` | Enable/disable auto-augment (tools unaffected) |
|
|
65
|
+
| `/gitnexus config` | Set the gitnexus command (saved to `~/.pi/pi-gitnexus.json`) |
|
|
62
66
|
| `/gitnexus <pattern>` | Manual graph lookup for a symbol or pattern |
|
|
63
67
|
| `/gitnexus query <text>` | Search execution flows |
|
|
64
68
|
| `/gitnexus context <name>` | 360° view of a symbol: callers, callees, processes |
|
|
@@ -97,6 +101,7 @@ This extension (pi-gitnexus) is MIT licensed. [GitNexus](https://github.com/abhi
|
|
|
97
101
|
|
|
98
102
|
## Notes
|
|
99
103
|
|
|
104
|
+
- The extension never runs `gitnexus analyze` automatically — indexing is always user-initiated via `/gitnexus analyze`.
|
|
100
105
|
- The index is a static snapshot. Re-run `/gitnexus analyze` after significant code changes. The agent will suggest this when the index appears stale.
|
|
101
106
|
- `gitnexus_detect_changes` is a lightweight alternative: pass `git diff HEAD` output to see affected flows without a full reindex.
|
|
102
107
|
- `gitnexus_cypher` and `gitnexus_rename` are intentionally not exposed (raw graph access and automated multi-file rename).
|
package/package.json
CHANGED
package/src/gitnexus.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
|
-
import { resolve, sep, basename, extname } from 'path';
|
|
3
|
-
import { existsSync } from 'fs';
|
|
2
|
+
import { resolve, sep, basename, extname, join } from 'path';
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
4
|
+
import { homedir } from 'os';
|
|
4
5
|
|
|
5
6
|
/** Max output chars returned to the LLM. Prevents context flooding. JS strings are UTF-16 chars, not bytes. */
|
|
6
7
|
export const MAX_OUTPUT_CHARS = 8 * 1024;
|
|
@@ -13,6 +14,35 @@ export const MAX_OUTPUT_CHARS = 8 * 1024;
|
|
|
13
14
|
export let spawnEnv: NodeJS.ProcessEnv = process.env;
|
|
14
15
|
export function updateSpawnEnv(env: NodeJS.ProcessEnv): void { spawnEnv = env; }
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Resolved command prefix for invoking gitnexus.
|
|
19
|
+
* Set to ['gitnexus'] when the binary is on PATH, otherwise ['npx', '-y', 'gitnexus@latest'].
|
|
20
|
+
* Updated by setGitnexusCmd() during session_start probe.
|
|
21
|
+
*/
|
|
22
|
+
export let gitnexusCmd: string[] = ['gitnexus'];
|
|
23
|
+
export function setGitnexusCmd(cmd: string[]): void { gitnexusCmd = cmd; }
|
|
24
|
+
|
|
25
|
+
const CONFIG_PATH = join(homedir(), '.pi', 'pi-gitnexus.json');
|
|
26
|
+
|
|
27
|
+
interface GitNexusConfig {
|
|
28
|
+
cmd?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function loadSavedConfig(): GitNexusConfig {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(readFileSync(CONFIG_PATH, 'utf8')) as GitNexusConfig;
|
|
34
|
+
} catch {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function saveConfig(config: GitNexusConfig): void {
|
|
40
|
+
try {
|
|
41
|
+
mkdirSync(join(homedir(), '.pi'), { recursive: true });
|
|
42
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
|
|
43
|
+
} catch { /* ignore write errors */ }
|
|
44
|
+
}
|
|
45
|
+
|
|
16
46
|
/** Augment subprocess timeout in ms. Applied via setTimeout + proc.kill('SIGTERM') — spawn has no built-in timeout. */
|
|
17
47
|
const AUGMENT_TIMEOUT = 8_000;
|
|
18
48
|
|
|
@@ -174,7 +204,8 @@ export async function runAugment(pattern: string, cwd: string): Promise<string>
|
|
|
174
204
|
let output = '';
|
|
175
205
|
let done = false;
|
|
176
206
|
|
|
177
|
-
const
|
|
207
|
+
const [bin, ...baseArgs] = gitnexusCmd;
|
|
208
|
+
const proc = spawn(bin, [...baseArgs, 'augment', pattern], {
|
|
178
209
|
cwd,
|
|
179
210
|
stdio: ['ignore', 'ignore', 'pipe'],
|
|
180
211
|
env: spawnEnv,
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import type { ExtensionAPI, ExtensionContext } from '@mariozechner/pi-coding-agent';
|
|
3
|
-
import { findGitNexusIndex, clearIndexCache, extractPattern, extractFilePatternsFromContent, runAugment, spawnEnv, updateSpawnEnv } from './gitnexus';
|
|
3
|
+
import { findGitNexusIndex, clearIndexCache, extractPattern, extractFilePatternsFromContent, runAugment, spawnEnv, updateSpawnEnv, gitnexusCmd, setGitnexusCmd, loadSavedConfig, saveConfig } from './gitnexus';
|
|
4
4
|
import { mcpClient } from './mcp-client';
|
|
5
5
|
import { registerTools } from './tools';
|
|
6
6
|
|
|
@@ -19,14 +19,20 @@ async function resolveShellPath(): Promise<void> {
|
|
|
19
19
|
updateSpawnEnv({ ...process.env, PATH: path });
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function
|
|
22
|
+
function trySpawn(bin: string, args: string[]): Promise<boolean> {
|
|
23
23
|
return new Promise((resolve_) => {
|
|
24
|
-
const proc = spawn(
|
|
24
|
+
const proc = spawn(bin, args, { stdio: 'ignore', env: spawnEnv });
|
|
25
25
|
proc.on('close', (code: number | null) => resolve_(code === 0));
|
|
26
26
|
proc.on('error', () => resolve_(false));
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/** Probe for gitnexus using the configured command. */
|
|
31
|
+
async function probeGitNexusBinary(): Promise<boolean> {
|
|
32
|
+
const [bin, ...args] = gitnexusCmd;
|
|
33
|
+
return trySpawn(bin, [...args, '--version']);
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
/** Cached from session_start/session_switch — avoids re-probing on every /gitnexus status. */
|
|
31
37
|
let binaryAvailable = false;
|
|
32
38
|
|
|
@@ -51,6 +57,12 @@ const augmentedCache = new Set<string>();
|
|
|
51
57
|
export default function(pi: ExtensionAPI) {
|
|
52
58
|
registerTools(pi);
|
|
53
59
|
|
|
60
|
+
pi.registerFlag('gitnexus-cmd', {
|
|
61
|
+
type: 'string',
|
|
62
|
+
default: 'gitnexus',
|
|
63
|
+
description: 'Command used to invoke gitnexus, e.g. "npx gitnexus@latest"',
|
|
64
|
+
});
|
|
65
|
+
|
|
54
66
|
// Append a one-liner so the agent understands graph context in search results.
|
|
55
67
|
pi.on('before_agent_start', async (event: { systemPrompt?: string }, ctx: ExtensionContext) => {
|
|
56
68
|
if (!findGitNexusIndex(ctx.cwd)) return;
|
|
@@ -111,6 +123,12 @@ export default function(pi: ExtensionAPI) {
|
|
|
111
123
|
sessionCwd = ctx.cwd;
|
|
112
124
|
await resolveShellPath();
|
|
113
125
|
|
|
126
|
+
// Resolve command: default → saved config → CLI flag (highest precedence)
|
|
127
|
+
const saved = loadSavedConfig().cmd;
|
|
128
|
+
const flag = pi.getFlag('gitnexus-cmd') as string | undefined;
|
|
129
|
+
const cmdStr = flag ?? saved ?? 'gitnexus';
|
|
130
|
+
setGitnexusCmd(cmdStr.trim().split(/\s+/));
|
|
131
|
+
|
|
114
132
|
binaryAvailable = await probeGitNexusBinary();
|
|
115
133
|
if (!findGitNexusIndex(ctx.cwd)) return;
|
|
116
134
|
|
|
@@ -149,7 +167,8 @@ export default function(pi: ExtensionAPI) {
|
|
|
149
167
|
}
|
|
150
168
|
const out = await new Promise<string>((resolve_) => {
|
|
151
169
|
let stdout = '';
|
|
152
|
-
const
|
|
170
|
+
const [bin, ...baseArgs] = gitnexusCmd;
|
|
171
|
+
const proc = spawn(bin, [...baseArgs, 'status'], {
|
|
153
172
|
cwd: ctx.cwd,
|
|
154
173
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
155
174
|
env: spawnEnv,
|
|
@@ -174,6 +193,7 @@ export default function(pi: ExtensionAPI) {
|
|
|
174
193
|
' /gitnexus — show status\n' +
|
|
175
194
|
' /gitnexus analyze — index the codebase\n' +
|
|
176
195
|
' /gitnexus on|off — enable/disable auto-augment on searches\n' +
|
|
196
|
+
' /gitnexus config — set the gitnexus command (saved to ~/.pi/pi-gitnexus.json)\n' +
|
|
177
197
|
' /gitnexus <pattern> — manual graph lookup\n' +
|
|
178
198
|
' /gitnexus query <q> — search execution flows\n' +
|
|
179
199
|
' /gitnexus context <n> — callers/callees of a symbol\n' +
|
|
@@ -194,6 +214,19 @@ export default function(pi: ExtensionAPI) {
|
|
|
194
214
|
return;
|
|
195
215
|
}
|
|
196
216
|
|
|
217
|
+
// /gitnexus config
|
|
218
|
+
if (sub === 'config') {
|
|
219
|
+
const current = gitnexusCmd.join(' ');
|
|
220
|
+
const input = await ctx.ui.input('gitnexus command', current);
|
|
221
|
+
if (input === undefined) return; // cancelled
|
|
222
|
+
const trimmed = input.trim();
|
|
223
|
+
if (!trimmed) return;
|
|
224
|
+
setGitnexusCmd(trimmed.split(/\s+/));
|
|
225
|
+
saveConfig({ cmd: trimmed });
|
|
226
|
+
ctx.ui.notify(`GitNexus command set to: ${trimmed}`, 'info');
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
197
230
|
// /gitnexus analyze
|
|
198
231
|
if (sub === 'analyze') {
|
|
199
232
|
if (!binaryAvailable) {
|
|
@@ -203,7 +236,8 @@ export default function(pi: ExtensionAPI) {
|
|
|
203
236
|
augmentEnabled = false;
|
|
204
237
|
ctx.ui.notify('GitNexus: analyzing codebase, this may take a while…', 'info');
|
|
205
238
|
const exitCode = await new Promise<number | null>((resolve_) => {
|
|
206
|
-
const
|
|
239
|
+
const [bin, ...baseArgs] = gitnexusCmd;
|
|
240
|
+
const proc = spawn(bin, [...baseArgs, 'analyze'], {
|
|
207
241
|
cwd: ctx.cwd,
|
|
208
242
|
stdio: 'ignore',
|
|
209
243
|
env: spawnEnv,
|
package/src/mcp-client.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn, ChildProcess } from 'child_process';
|
|
2
|
-
import { MAX_OUTPUT_CHARS, spawnEnv } from './gitnexus';
|
|
2
|
+
import { MAX_OUTPUT_CHARS, spawnEnv, gitnexusCmd } from './gitnexus';
|
|
3
3
|
|
|
4
4
|
interface JsonRpcResponse {
|
|
5
5
|
jsonrpc: '2.0';
|
|
@@ -45,7 +45,8 @@ class GitNexusMcpClient {
|
|
|
45
45
|
if (this.startPromise) return this.startPromise;
|
|
46
46
|
|
|
47
47
|
this.startPromise = new Promise<void>((resolve_, reject) => {
|
|
48
|
-
const
|
|
48
|
+
const [bin, ...baseArgs] = gitnexusCmd;
|
|
49
|
+
const proc = spawn(bin, [...baseArgs, 'mcp'], {
|
|
49
50
|
cwd,
|
|
50
51
|
stdio: ['pipe', 'pipe', 'ignore'],
|
|
51
52
|
env: spawnEnv,
|