pi-readseek 0.5.7 → 0.5.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/index.ts +7 -1
- package/package.json +1 -1
- package/src/def.ts +1 -1
- package/src/edit.ts +12 -8
- package/src/grep.ts +10 -8
- package/src/hover.ts +1 -1
- package/src/read.ts +10 -8
- package/src/refs.ts +1 -1
- package/src/rename.ts +1 -1
- package/src/sg.ts +1 -1
- package/src/tool-prompt-metadata.ts +55 -12
- package/src/write.ts +10 -8
package/index.ts
CHANGED
|
@@ -68,9 +68,15 @@ export default function piReadSeekExtension(pi: ExtensionAPI): void {
|
|
|
68
68
|
const editName = swap("edit", "readSeek_edit");
|
|
69
69
|
const writeName = swap("write", "readSeek_write");
|
|
70
70
|
const grepName = swap("grep", "readSeek_grep");
|
|
71
|
+
const toolAliases = {
|
|
72
|
+
readSeek_read: readName,
|
|
73
|
+
readSeek_edit: editName,
|
|
74
|
+
readSeek_grep: grepName,
|
|
75
|
+
readSeek_write: writeName,
|
|
76
|
+
};
|
|
71
77
|
|
|
72
78
|
registerReadTool(pi, { onSuccessfulRead: markAnchored, name: readName });
|
|
73
|
-
registerEditTool(pi, { wasReadInSession: hasFreshAnchors, name: editName });
|
|
79
|
+
registerEditTool(pi, { wasReadInSession: hasFreshAnchors, name: editName, toolAliases });
|
|
74
80
|
registerGrepTool(pi, { onFileAnchored: markAnchored, name: grepName });
|
|
75
81
|
registerSgTool(pi, { onFileAnchored: markAnchored });
|
|
76
82
|
registerRefsTool(pi, { onFileAnchored: markAnchored });
|
package/package.json
CHANGED
package/src/def.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { FileAnchoredCallback } from "./tool-types.js";
|
|
|
15
15
|
|
|
16
16
|
const DEF_PROMPT_METADATA = defineToolPromptMetadata({
|
|
17
17
|
promptUrl: new URL("../prompts/def.md", import.meta.url),
|
|
18
|
-
promptSnippet: "Find structural
|
|
18
|
+
promptSnippet: "Find structural definitions for a symbol",
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
type DefParams = {
|
package/src/edit.ts
CHANGED
|
@@ -69,10 +69,6 @@ const hashlineEditSchema = Type.Object(
|
|
|
69
69
|
|
|
70
70
|
type HashlineParams = Static<typeof hashlineEditSchema>;
|
|
71
71
|
|
|
72
|
-
const EDIT_PROMPT_METADATA = defineToolPromptMetadata({
|
|
73
|
-
promptUrl: new URL("../prompts/edit.md", import.meta.url),
|
|
74
|
-
promptSnippet: "Edit files using hash-verified anchors from readSeek_read/readSeek_grep/readSeek_search/readSeek_write",
|
|
75
|
-
});
|
|
76
72
|
|
|
77
73
|
function buildEditError(
|
|
78
74
|
path: string,
|
|
@@ -111,6 +107,7 @@ export interface EditToolOptions {
|
|
|
111
107
|
wasReadInSession?: FreshAnchorsPredicate;
|
|
112
108
|
syntaxValidate?: SyntaxValidateOptions["syntaxValidate"];
|
|
113
109
|
name?: string;
|
|
110
|
+
toolAliases?: Readonly<Record<string, string>>;
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
export interface ExecuteEditOptions {
|
|
@@ -565,12 +562,19 @@ export async function executeEdit(opts: ExecuteEditOptions): Promise<any> {
|
|
|
565
562
|
|
|
566
563
|
|
|
567
564
|
export function registerEditTool(pi: ExtensionAPI, options: EditToolOptions = {}) {
|
|
565
|
+
const name = options.name ?? "readSeek_edit";
|
|
566
|
+
const promptMetadata = defineToolPromptMetadata({
|
|
567
|
+
promptUrl: new URL("../prompts/edit.md", import.meta.url),
|
|
568
|
+
promptSnippet: "Edit with fresh hash-verified anchors",
|
|
569
|
+
registeredName: name,
|
|
570
|
+
toolAliases: options.toolAliases,
|
|
571
|
+
});
|
|
568
572
|
const tool = registerReadSeekTool(pi, {
|
|
569
|
-
name
|
|
573
|
+
name,
|
|
570
574
|
label: "Edit",
|
|
571
|
-
description:
|
|
572
|
-
promptSnippet:
|
|
573
|
-
promptGuidelines:
|
|
575
|
+
description: promptMetadata.description,
|
|
576
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
577
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
574
578
|
parameters: hashlineEditSchema,
|
|
575
579
|
renderShell: "default" as const,
|
|
576
580
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
package/src/grep.ts
CHANGED
|
@@ -24,10 +24,6 @@ import type { FileAnchoredCallback } from "./tool-types.js";
|
|
|
24
24
|
import { optionalIntOrString, registerReadSeekTool } from "./register-tool.js";
|
|
25
25
|
import { searchPathParam } from "./readseek-params.js";
|
|
26
26
|
|
|
27
|
-
const GREP_PROMPT_METADATA = defineToolPromptMetadata({
|
|
28
|
-
promptUrl: new URL("../prompts/grep.md", import.meta.url),
|
|
29
|
-
promptSnippet: "Search file contents and return edit-ready hashline anchors",
|
|
30
|
-
});
|
|
31
27
|
|
|
32
28
|
const grepSchema = Type.Object({
|
|
33
29
|
pattern: Type.String({ description: "Pattern to search" }),
|
|
@@ -514,13 +510,19 @@ export async function executeGrep(opts: ExecuteGrepOptions): Promise<any> {
|
|
|
514
510
|
}
|
|
515
511
|
|
|
516
512
|
export function registerGrepTool(pi: ExtensionAPI, options: GrepToolOptions = {}) {
|
|
513
|
+
const name = options.name ?? "readSeek_grep";
|
|
514
|
+
const promptMetadata = defineToolPromptMetadata({
|
|
515
|
+
promptUrl: new URL("../prompts/grep.md", import.meta.url),
|
|
516
|
+
promptSnippet: "Search file text with edit-ready anchors",
|
|
517
|
+
registeredName: name,
|
|
518
|
+
});
|
|
517
519
|
const tool = registerReadSeekTool(pi, {
|
|
518
|
-
name
|
|
520
|
+
name,
|
|
519
521
|
label: "grep",
|
|
520
|
-
description:
|
|
522
|
+
description: promptMetadata.description,
|
|
521
523
|
parameters: grepSchema,
|
|
522
|
-
promptSnippet:
|
|
523
|
-
promptGuidelines:
|
|
524
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
525
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
524
526
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
525
527
|
return executeGrep({
|
|
526
528
|
toolCallId,
|
package/src/hover.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { clampLineToWidth, clampLinesToWidth, linkToolPath, renderPendingResult,
|
|
|
15
15
|
|
|
16
16
|
const HOVER_PROMPT_METADATA = defineToolPromptMetadata({
|
|
17
17
|
promptUrl: new URL("../prompts/hover.md", import.meta.url),
|
|
18
|
-
promptSnippet: "Identify
|
|
18
|
+
promptSnippet: "Identify a cursor token and enclosing symbol",
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const hoverSchema = Type.Object({
|
package/src/read.ts
CHANGED
|
@@ -33,10 +33,6 @@ import { clampLineToWidth, clampLinesToWidth, linkToolPath, renderPendingResult,
|
|
|
33
33
|
import type { FileAnchoredCallback } from "./tool-types.js";
|
|
34
34
|
import { filePathParam, mapParam, optionalIntOrString, registerReadSeekTool } from "./register-tool.js";
|
|
35
35
|
|
|
36
|
-
const READ_PROMPT_METADATA = defineToolPromptMetadata({
|
|
37
|
-
promptUrl: new URL("../prompts/read.md", import.meta.url),
|
|
38
|
-
promptSnippet: "Read text files or images; text reads include hashline anchors and optional maps/symbol lookup, image reads include the attachment plus OCR text, an image caption, and detected objects",
|
|
39
|
-
});
|
|
40
36
|
|
|
41
37
|
interface ReadParams {
|
|
42
38
|
path: string;
|
|
@@ -460,12 +456,18 @@ function splitReadSeekLines(text: string): string[] {
|
|
|
460
456
|
}
|
|
461
457
|
|
|
462
458
|
export function registerReadTool(pi: ExtensionAPI, options: ReadToolOptions = {}) {
|
|
459
|
+
const name = options.name ?? "readSeek_read";
|
|
460
|
+
const promptMetadata = defineToolPromptMetadata({
|
|
461
|
+
promptUrl: new URL("../prompts/read.md", import.meta.url),
|
|
462
|
+
promptSnippet: "Read files or images with anchors, maps, symbols, and OCR",
|
|
463
|
+
registeredName: name,
|
|
464
|
+
});
|
|
463
465
|
const tool = registerReadSeekTool(pi, {
|
|
464
|
-
name
|
|
466
|
+
name,
|
|
465
467
|
label: "Read",
|
|
466
|
-
description:
|
|
467
|
-
promptSnippet:
|
|
468
|
-
promptGuidelines:
|
|
468
|
+
description: promptMetadata.description,
|
|
469
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
470
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
469
471
|
parameters: Type.Object({
|
|
470
472
|
path: filePathParam(),
|
|
471
473
|
offset: optionalIntOrString("Start line (1-indexed)"),
|
package/src/refs.ts
CHANGED
|
@@ -27,7 +27,7 @@ type RefsParams = {
|
|
|
27
27
|
|
|
28
28
|
const REFS_PROMPT_METADATA = defineToolPromptMetadata({
|
|
29
29
|
promptUrl: new URL("../prompts/refs.md", import.meta.url),
|
|
30
|
-
promptSnippet: "Find references
|
|
30
|
+
promptSnippet: "Find identifier references with enclosing symbols",
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
interface RefsToolOptions {
|
package/src/rename.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { clampLineToWidth, clampLinesToWidth, linkToolPath, renderPendingResult,
|
|
|
13
13
|
|
|
14
14
|
const RENAME_PROMPT_METADATA = defineToolPromptMetadata({
|
|
15
15
|
promptUrl: new URL("../prompts/rename.md", import.meta.url),
|
|
16
|
-
promptSnippet: "Rename
|
|
16
|
+
promptSnippet: "Rename a binding accurately from its cursor",
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
const renameSchema = Type.Object({
|
package/src/sg.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function mergeRanges(ranges: SgRange[]): SgRange[] {
|
|
|
49
49
|
|
|
50
50
|
const SG_PROMPT_METADATA = defineToolPromptMetadata({
|
|
51
51
|
promptUrl: new URL("../prompts/sg.md", import.meta.url),
|
|
52
|
-
promptSnippet: "Search code
|
|
52
|
+
promptSnippet: "Search code by AST pattern with edit-ready anchors",
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
interface SgToolOptions {
|
|
@@ -12,24 +12,42 @@ const COMPACT_DESCRIPTIONS: Record<string, string> = {
|
|
|
12
12
|
"refs.md": "Find references to an identifier and return anchored usages with enclosing symbols.",
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
const REPLACEABLE_TOOL_GUIDELINES: Record<string, { readSeekName: string; builtInName: string; benefit: string }> = {
|
|
16
|
+
"read.md": {
|
|
17
|
+
readSeekName: "readSeek_read",
|
|
18
|
+
builtInName: "read",
|
|
19
|
+
benefit: "it provides LINE:HASH anchors for safe edits.",
|
|
20
|
+
},
|
|
21
|
+
"edit.md": {
|
|
22
|
+
readSeekName: "readSeek_edit",
|
|
23
|
+
builtInName: "edit",
|
|
24
|
+
benefit: "it verifies fresh LINE:HASH anchors.",
|
|
25
|
+
},
|
|
26
|
+
"grep.md": {
|
|
27
|
+
readSeekName: "readSeek_grep",
|
|
28
|
+
builtInName: "grep",
|
|
29
|
+
benefit: "it returns edit-ready anchors.",
|
|
30
|
+
},
|
|
31
|
+
"write.md": {
|
|
32
|
+
readSeekName: "readSeek_write",
|
|
33
|
+
builtInName: "write",
|
|
34
|
+
benefit: "it returns LINE:HASH anchors.",
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
15
38
|
const COMPACT_GUIDELINES: Record<string, string[]> = {
|
|
16
39
|
"read.md": [
|
|
17
|
-
"Use readSeek_read
|
|
18
|
-
"Use
|
|
19
|
-
"Use readSeek_read for images; it returns the image attachment plus OCR text, a caption, and detected objects, so you don't need separate OCR tools.",
|
|
40
|
+
"Use readSeek_read map or symbol mode before pulling large code files into context.",
|
|
41
|
+
"Use readSeek_read for images; it returns the image attachment plus OCR text, a caption, and detected objects.",
|
|
20
42
|
],
|
|
21
43
|
"edit.md": [
|
|
22
|
-
"
|
|
23
|
-
"Prefer set_line, replace_lines, and insert_after; use replace only when anchors are impractical.",
|
|
44
|
+
"With readSeek_edit, prefer set_line, replace_lines, and insert_after; use replace only when anchors are impractical.",
|
|
24
45
|
],
|
|
25
46
|
"grep.md": [
|
|
26
|
-
"Use readSeek_grep for text search and edit-ready matching anchors.",
|
|
27
47
|
"Use readSeek_grep summary mode for broad count/file discovery before narrowing.",
|
|
28
48
|
],
|
|
29
|
-
|
|
30
49
|
"write.md": [
|
|
31
|
-
"Use readSeek_write
|
|
32
|
-
"Use readSeek_edit rather than readSeek_write for small changes or appends to existing files.",
|
|
50
|
+
"Use anchored edits rather than readSeek_write for small changes or appends to existing files.",
|
|
33
51
|
],
|
|
34
52
|
"sg.md": [
|
|
35
53
|
"Use readSeek_search for AST-shaped code patterns.",
|
|
@@ -62,16 +80,41 @@ function promptFileName(promptUrl: URL): string {
|
|
|
62
80
|
return promptUrl.pathname.split("/").pop() ?? "";
|
|
63
81
|
}
|
|
64
82
|
|
|
83
|
+
function rewriteToolAliases(value: string, toolAliases: Readonly<Record<string, string>> | undefined): string {
|
|
84
|
+
if (!toolAliases) return value;
|
|
85
|
+
return Object.entries(toolAliases).reduce(
|
|
86
|
+
(rewritten, [canonicalName, registeredName]) => rewritten.replaceAll(canonicalName, registeredName),
|
|
87
|
+
value,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
65
91
|
export function defineToolPromptMetadata(options: {
|
|
66
92
|
promptUrl: URL;
|
|
67
93
|
promptSnippet: string;
|
|
94
|
+
registeredName?: string;
|
|
95
|
+
toolAliases?: Readonly<Record<string, string>>;
|
|
68
96
|
}): ToolPromptMetadata {
|
|
69
97
|
const prompt = loadPrompt(options.promptUrl);
|
|
70
98
|
const fileName = promptFileName(options.promptUrl);
|
|
71
99
|
const compactDescription = COMPACT_DESCRIPTIONS[fileName];
|
|
100
|
+
const replaceable = REPLACEABLE_TOOL_GUIDELINES[fileName];
|
|
101
|
+
const registeredName = options.registeredName ?? replaceable?.readSeekName;
|
|
102
|
+
const preferenceGuideline = replaceable && registeredName
|
|
103
|
+
? registeredName === replaceable.readSeekName
|
|
104
|
+
? `Prefer ${registeredName} over ${replaceable.builtInName} when both are available; ${replaceable.benefit}`
|
|
105
|
+
: `Use ${registeredName}; ${replaceable.benefit}`
|
|
106
|
+
: undefined;
|
|
72
107
|
return {
|
|
73
|
-
description: compactDescription ?? firstPromptParagraph(prompt),
|
|
74
|
-
promptSnippet: options.promptSnippet,
|
|
75
|
-
promptGuidelines:
|
|
108
|
+
description: rewriteToolAliases(compactDescription ?? firstPromptParagraph(prompt), options.toolAliases),
|
|
109
|
+
promptSnippet: rewriteToolAliases(options.promptSnippet, options.toolAliases),
|
|
110
|
+
promptGuidelines: [
|
|
111
|
+
...(preferenceGuideline ? [preferenceGuideline] : []),
|
|
112
|
+
...(COMPACT_GUIDELINES[fileName] ?? []).map((guideline) =>
|
|
113
|
+
rewriteToolAliases(
|
|
114
|
+
registeredName && replaceable ? guideline.replaceAll(replaceable.readSeekName, registeredName) : guideline,
|
|
115
|
+
options.toolAliases,
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
],
|
|
76
119
|
};
|
|
77
120
|
}
|
package/src/write.ts
CHANGED
|
@@ -66,10 +66,6 @@ function pendingWritePreviewParts(summary: string, preview: PendingDiffPreviewRe
|
|
|
66
66
|
return { lines: [summary, headerLine], diffData: expanded ? diffData : undefined };
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const WRITE_PROMPT_METADATA = defineToolPromptMetadata({
|
|
70
|
-
promptUrl: new URL("../prompts/write.md", import.meta.url),
|
|
71
|
-
promptSnippet: "Create or overwrite a complete file and return edit anchors",
|
|
72
|
-
});
|
|
73
69
|
|
|
74
70
|
type WriteDiffFields = {
|
|
75
71
|
diff?: string;
|
|
@@ -242,12 +238,18 @@ export async function executeWrite(opts: {
|
|
|
242
238
|
}
|
|
243
239
|
|
|
244
240
|
export function registerWriteTool(pi: ExtensionAPI, options: WriteToolOptions = {}) {
|
|
241
|
+
const name = options.name ?? "readSeek_write";
|
|
242
|
+
const promptMetadata = defineToolPromptMetadata({
|
|
243
|
+
promptUrl: new URL("../prompts/write.md", import.meta.url),
|
|
244
|
+
promptSnippet: "Create or overwrite a file with edit anchors",
|
|
245
|
+
registeredName: name,
|
|
246
|
+
});
|
|
245
247
|
const tool = registerReadSeekTool(pi, {
|
|
246
|
-
name
|
|
248
|
+
name,
|
|
247
249
|
label: "write",
|
|
248
|
-
description:
|
|
249
|
-
promptSnippet:
|
|
250
|
-
promptGuidelines:
|
|
250
|
+
description: promptMetadata.description,
|
|
251
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
252
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
251
253
|
parameters: Type.Object({
|
|
252
254
|
path: filePathParam(),
|
|
253
255
|
content: Type.String({ description: "File content" }),
|