pi-readseek 0.5.6 → 0.5.7

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/index.ts CHANGED
@@ -12,16 +12,31 @@ import { SessionAnchors } from "./src/session-anchors.js";
12
12
  import { readSeekBinaryAvailability } from "./src/readseek-client.js";
13
13
  import { resolveReadSeekJsonSettings, type ReadSeekSettingsWarning } from "./src/readseek-settings.js";
14
14
 
15
- const READSEEK_TOOL_NAMES = [
16
- "readSeek_read",
17
- "readSeek_edit",
18
- "readSeek_grep",
19
- "readSeek_search",
20
- "readSeek_refs",
21
- "readSeek_rename",
22
- "readSeek_hover",
23
- "readSeek_write",
24
- "readSeek_def",
15
+ /** Built-in tool names that pi-readseek can replace with a readSeek-backed implementation. */
16
+ const REPLACEABLE_TOOLS = {
17
+ read: "readSeek_read",
18
+ edit: "readSeek_edit",
19
+ write: "readSeek_write",
20
+ grep: "readSeek_grep",
21
+ } as const;
22
+
23
+ type ReplacedBuiltIn = keyof typeof REPLACEABLE_TOOLS;
24
+
25
+ /**
26
+ * Canonical list of readSeek tools in registration/activation order. Each
27
+ * replaceable entry carries the built-in name it swaps in when replaced; null
28
+ * entries are readSeek-only and never replaced.
29
+ */
30
+ const READSEEK_TOOL_ENTRIES: ReadonlyArray<{ builtIn: ReplacedBuiltIn | null; readSeekName: string }> = [
31
+ { builtIn: "read", readSeekName: "readSeek_read" },
32
+ { builtIn: "edit", readSeekName: "readSeek_edit" },
33
+ { builtIn: "grep", readSeekName: "readSeek_grep" },
34
+ { builtIn: null, readSeekName: "readSeek_search" },
35
+ { builtIn: null, readSeekName: "readSeek_refs" },
36
+ { builtIn: null, readSeekName: "readSeek_rename" },
37
+ { builtIn: null, readSeekName: "readSeek_hover" },
38
+ { builtIn: "write", readSeekName: "readSeek_write" },
39
+ { builtIn: null, readSeekName: "readSeek_def" },
25
40
  ];
26
41
 
27
42
  function formatSettingsWarning(warning: ReadSeekSettingsWarning): string {
@@ -33,19 +48,39 @@ export default function piReadSeekExtension(pi: ExtensionAPI): void {
33
48
  const markAnchored = (absolutePath: string) => sessionAnchors.markAnchored(absolutePath);
34
49
  const hasFreshAnchors = (absolutePath: string) => sessionAnchors.hasFreshAnchors(absolutePath);
35
50
 
36
- registerReadTool(pi, { onSuccessfulRead: markAnchored });
37
- registerEditTool(pi, { wasReadInSession: hasFreshAnchors });
38
- registerGrepTool(pi, { onFileAnchored: markAnchored });
51
+ // Resolve replacedTools at load time so the readSeek implementation is
52
+ // registered under the built-in name (e.g. "edit") when replaced. Extension
53
+ // tool registrations override built-ins of the same name in pi's tool
54
+ // definition registry, so registering under "edit" makes calls to `edit`
55
+ // dispatch to the readSeek implementation.
56
+ const { settings } = resolveReadSeekJsonSettings();
57
+ const replacedBuiltIns = new Set<ReplacedBuiltIn>(
58
+ (settings.replacedTools ?? []) as ReplacedBuiltIn[],
59
+ );
60
+ // Only swap registration under the built-in name when the readSeek binary
61
+ // is available; otherwise keep readSeek_* names so pi's built-ins stay
62
+ // intact and usable.
63
+ const binaryAvailable = readSeekBinaryAvailability().available;
64
+ const swap = (builtIn: ReplacedBuiltIn, readSeekName: string) =>
65
+ binaryAvailable && replacedBuiltIns.has(builtIn) ? builtIn : readSeekName;
66
+
67
+ const readName = swap("read", "readSeek_read");
68
+ const editName = swap("edit", "readSeek_edit");
69
+ const writeName = swap("write", "readSeek_write");
70
+ const grepName = swap("grep", "readSeek_grep");
71
+
72
+ registerReadTool(pi, { onSuccessfulRead: markAnchored, name: readName });
73
+ registerEditTool(pi, { wasReadInSession: hasFreshAnchors, name: editName });
74
+ registerGrepTool(pi, { onFileAnchored: markAnchored, name: grepName });
39
75
  registerSgTool(pi, { onFileAnchored: markAnchored });
40
76
  registerRefsTool(pi, { onFileAnchored: markAnchored });
41
77
  registerRenameTool(pi);
42
78
  registerHoverTool(pi);
43
79
  registerDefTool(pi, { onFileAnchored: markAnchored });
44
- registerWriteTool(pi, { onFileAnchored: markAnchored });
80
+ registerWriteTool(pi, { onFileAnchored: markAnchored, name: writeName });
45
81
 
46
82
  pi.on("session_start", (_event, ctx) => {
47
- const { settings, warnings } = resolveReadSeekJsonSettings();
48
- const replacedTools = new Set<string>(settings.replacedTools ?? []);
83
+ const { warnings } = resolveReadSeekJsonSettings();
49
84
  const problems = warnings.map(formatSettingsWarning);
50
85
 
51
86
  const availability = readSeekBinaryAvailability();
@@ -60,8 +95,24 @@ export default function piReadSeekExtension(pi: ExtensionAPI): void {
60
95
 
61
96
  if (!availability.available) return;
62
97
 
63
- const activeTools = [...pi.getActiveTools(), ...READSEEK_TOOL_NAMES]
64
- .filter((name) => !replacedTools.has(name));
98
+ // readSeek tools were registered at load under names chosen from the
99
+ // load-time replacedTools. Replaced built-ins are registered under the
100
+ // built-in name, so the built-in stays active (now readSeek-backed);
101
+ // their readSeek_* variant was never registered and is excluded.
102
+ const activeReadSeekNames = READSEEK_TOOL_ENTRIES.map((entry) =>
103
+ entry.builtIn && replacedBuiltIns.has(entry.builtIn) ? entry.builtIn : entry.readSeekName,
104
+ );
105
+ const inactiveReadSeekNames = new Set(
106
+ READSEEK_TOOL_ENTRIES.filter(
107
+ (entry): entry is { builtIn: ReplacedBuiltIn; readSeekName: string } =>
108
+ entry.builtIn !== null && replacedBuiltIns.has(entry.builtIn),
109
+ ).map((entry) => entry.readSeekName),
110
+ );
111
+
112
+ const activeTools = [...pi.getActiveTools(), ...activeReadSeekNames].filter(
113
+ (name) => !inactiveReadSeekNames.has(name),
114
+ );
65
115
  pi.setActiveTools([...new Set(activeTools)]);
66
116
  });
67
- }
117
+
118
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-readseek",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "Pi extension for readseek-backed hash-anchored read/edit/grep, structural code maps, structural search, and file exploration",
5
5
  "type": "module",
6
6
  "exports": {
package/src/edit.ts CHANGED
@@ -110,6 +110,7 @@ function mapEditFileError(err: any, filePath: string, _displayPath: string, _pha
110
110
  export interface EditToolOptions {
111
111
  wasReadInSession?: FreshAnchorsPredicate;
112
112
  syntaxValidate?: SyntaxValidateOptions["syntaxValidate"];
113
+ name?: string;
113
114
  }
114
115
 
115
116
  export interface ExecuteEditOptions {
@@ -565,7 +566,7 @@ export async function executeEdit(opts: ExecuteEditOptions): Promise<any> {
565
566
 
566
567
  export function registerEditTool(pi: ExtensionAPI, options: EditToolOptions = {}) {
567
568
  const tool = registerReadSeekTool(pi, {
568
- name: "readSeek_edit",
569
+ name: options.name ?? "readSeek_edit",
569
570
  label: "Edit",
570
571
  description: EDIT_PROMPT_METADATA.description,
571
572
  promptSnippet: EDIT_PROMPT_METADATA.promptSnippet,
package/src/grep.ts CHANGED
@@ -169,6 +169,7 @@ function escapeForRegex(s: string): string {
169
169
 
170
170
  interface GrepToolOptions {
171
171
  onFileAnchored?: FileAnchoredCallback;
172
+ name?: string;
172
173
  }
173
174
 
174
175
  export interface ExecuteGrepOptions {
@@ -514,7 +515,7 @@ export async function executeGrep(opts: ExecuteGrepOptions): Promise<any> {
514
515
 
515
516
  export function registerGrepTool(pi: ExtensionAPI, options: GrepToolOptions = {}) {
516
517
  const tool = registerReadSeekTool(pi, {
517
- name: "readSeek_grep",
518
+ name: options.name ?? "readSeek_grep",
518
519
  label: "grep",
519
520
  description: GREP_PROMPT_METADATA.description,
520
521
  parameters: grepSchema,
package/src/read.ts CHANGED
@@ -49,6 +49,7 @@ interface ReadParams {
49
49
 
50
50
  interface ReadToolOptions {
51
51
  onSuccessfulRead?: FileAnchoredCallback;
52
+ name?: string;
52
53
  }
53
54
 
54
55
  export interface ExecuteReadOptions {
@@ -460,7 +461,7 @@ function splitReadSeekLines(text: string): string[] {
460
461
 
461
462
  export function registerReadTool(pi: ExtensionAPI, options: ReadToolOptions = {}) {
462
463
  const tool = registerReadSeekTool(pi, {
463
- name: "readSeek_read",
464
+ name: options.name ?? "readSeek_read",
464
465
  label: "Read",
465
466
  description: READ_PROMPT_METADATA.description,
466
467
  promptSnippet: READ_PROMPT_METADATA.promptSnippet,
package/src/write.ts CHANGED
@@ -123,6 +123,7 @@ function generateWriteDiff(previousContent: string, nextContent: string): { diff
123
123
 
124
124
  export interface WriteToolOptions {
125
125
  onFileAnchored?: FileAnchoredCallback;
126
+ name?: string;
126
127
  }
127
128
 
128
129
  function buildWriteFsErrorResult(err: any, absolutePath: string) {
@@ -242,7 +243,7 @@ export async function executeWrite(opts: {
242
243
 
243
244
  export function registerWriteTool(pi: ExtensionAPI, options: WriteToolOptions = {}) {
244
245
  const tool = registerReadSeekTool(pi, {
245
- name: "readSeek_write",
246
+ name: options.name ?? "readSeek_write",
246
247
  label: "write",
247
248
  description: WRITE_PROMPT_METADATA.description,
248
249
  promptSnippet: WRITE_PROMPT_METADATA.promptSnippet,