pi-readseek 0.5.6 → 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 +76 -19
- package/package.json +1 -1
- package/src/def.ts +1 -1
- package/src/edit.ts +13 -8
- package/src/grep.ts +11 -8
- package/src/hover.ts +1 -1
- package/src/read.ts +11 -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 +11 -8
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
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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,45 @@ 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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
+
const toolAliases = {
|
|
72
|
+
readSeek_read: readName,
|
|
73
|
+
readSeek_edit: editName,
|
|
74
|
+
readSeek_grep: grepName,
|
|
75
|
+
readSeek_write: writeName,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
registerReadTool(pi, { onSuccessfulRead: markAnchored, name: readName });
|
|
79
|
+
registerEditTool(pi, { wasReadInSession: hasFreshAnchors, name: editName, toolAliases });
|
|
80
|
+
registerGrepTool(pi, { onFileAnchored: markAnchored, name: grepName });
|
|
39
81
|
registerSgTool(pi, { onFileAnchored: markAnchored });
|
|
40
82
|
registerRefsTool(pi, { onFileAnchored: markAnchored });
|
|
41
83
|
registerRenameTool(pi);
|
|
42
84
|
registerHoverTool(pi);
|
|
43
85
|
registerDefTool(pi, { onFileAnchored: markAnchored });
|
|
44
|
-
registerWriteTool(pi, { onFileAnchored: markAnchored });
|
|
86
|
+
registerWriteTool(pi, { onFileAnchored: markAnchored, name: writeName });
|
|
45
87
|
|
|
46
88
|
pi.on("session_start", (_event, ctx) => {
|
|
47
|
-
const {
|
|
48
|
-
const replacedTools = new Set<string>(settings.replacedTools ?? []);
|
|
89
|
+
const { warnings } = resolveReadSeekJsonSettings();
|
|
49
90
|
const problems = warnings.map(formatSettingsWarning);
|
|
50
91
|
|
|
51
92
|
const availability = readSeekBinaryAvailability();
|
|
@@ -60,8 +101,24 @@ export default function piReadSeekExtension(pi: ExtensionAPI): void {
|
|
|
60
101
|
|
|
61
102
|
if (!availability.available) return;
|
|
62
103
|
|
|
63
|
-
|
|
64
|
-
|
|
104
|
+
// readSeek tools were registered at load under names chosen from the
|
|
105
|
+
// load-time replacedTools. Replaced built-ins are registered under the
|
|
106
|
+
// built-in name, so the built-in stays active (now readSeek-backed);
|
|
107
|
+
// their readSeek_* variant was never registered and is excluded.
|
|
108
|
+
const activeReadSeekNames = READSEEK_TOOL_ENTRIES.map((entry) =>
|
|
109
|
+
entry.builtIn && replacedBuiltIns.has(entry.builtIn) ? entry.builtIn : entry.readSeekName,
|
|
110
|
+
);
|
|
111
|
+
const inactiveReadSeekNames = new Set(
|
|
112
|
+
READSEEK_TOOL_ENTRIES.filter(
|
|
113
|
+
(entry): entry is { builtIn: ReplacedBuiltIn; readSeekName: string } =>
|
|
114
|
+
entry.builtIn !== null && replacedBuiltIns.has(entry.builtIn),
|
|
115
|
+
).map((entry) => entry.readSeekName),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const activeTools = [...pi.getActiveTools(), ...activeReadSeekNames].filter(
|
|
119
|
+
(name) => !inactiveReadSeekNames.has(name),
|
|
120
|
+
);
|
|
65
121
|
pi.setActiveTools([...new Set(activeTools)]);
|
|
66
122
|
});
|
|
67
|
-
|
|
123
|
+
|
|
124
|
+
}
|
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,
|
|
@@ -110,6 +106,8 @@ function mapEditFileError(err: any, filePath: string, _displayPath: string, _pha
|
|
|
110
106
|
export interface EditToolOptions {
|
|
111
107
|
wasReadInSession?: FreshAnchorsPredicate;
|
|
112
108
|
syntaxValidate?: SyntaxValidateOptions["syntaxValidate"];
|
|
109
|
+
name?: string;
|
|
110
|
+
toolAliases?: Readonly<Record<string, string>>;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
export interface ExecuteEditOptions {
|
|
@@ -564,12 +562,19 @@ export async function executeEdit(opts: ExecuteEditOptions): Promise<any> {
|
|
|
564
562
|
|
|
565
563
|
|
|
566
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
|
+
});
|
|
567
572
|
const tool = registerReadSeekTool(pi, {
|
|
568
|
-
name
|
|
573
|
+
name,
|
|
569
574
|
label: "Edit",
|
|
570
|
-
description:
|
|
571
|
-
promptSnippet:
|
|
572
|
-
promptGuidelines:
|
|
575
|
+
description: promptMetadata.description,
|
|
576
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
577
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
573
578
|
parameters: hashlineEditSchema,
|
|
574
579
|
renderShell: "default" as const,
|
|
575
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" }),
|
|
@@ -169,6 +165,7 @@ function escapeForRegex(s: string): string {
|
|
|
169
165
|
|
|
170
166
|
interface GrepToolOptions {
|
|
171
167
|
onFileAnchored?: FileAnchoredCallback;
|
|
168
|
+
name?: string;
|
|
172
169
|
}
|
|
173
170
|
|
|
174
171
|
export interface ExecuteGrepOptions {
|
|
@@ -513,13 +510,19 @@ export async function executeGrep(opts: ExecuteGrepOptions): Promise<any> {
|
|
|
513
510
|
}
|
|
514
511
|
|
|
515
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
|
+
});
|
|
516
519
|
const tool = registerReadSeekTool(pi, {
|
|
517
|
-
name
|
|
520
|
+
name,
|
|
518
521
|
label: "grep",
|
|
519
|
-
description:
|
|
522
|
+
description: promptMetadata.description,
|
|
520
523
|
parameters: grepSchema,
|
|
521
|
-
promptSnippet:
|
|
522
|
-
promptGuidelines:
|
|
524
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
525
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
523
526
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
524
527
|
return executeGrep({
|
|
525
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;
|
|
@@ -49,6 +45,7 @@ interface ReadParams {
|
|
|
49
45
|
|
|
50
46
|
interface ReadToolOptions {
|
|
51
47
|
onSuccessfulRead?: FileAnchoredCallback;
|
|
48
|
+
name?: string;
|
|
52
49
|
}
|
|
53
50
|
|
|
54
51
|
export interface ExecuteReadOptions {
|
|
@@ -459,12 +456,18 @@ function splitReadSeekLines(text: string): string[] {
|
|
|
459
456
|
}
|
|
460
457
|
|
|
461
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
|
+
});
|
|
462
465
|
const tool = registerReadSeekTool(pi, {
|
|
463
|
-
name
|
|
466
|
+
name,
|
|
464
467
|
label: "Read",
|
|
465
|
-
description:
|
|
466
|
-
promptSnippet:
|
|
467
|
-
promptGuidelines:
|
|
468
|
+
description: promptMetadata.description,
|
|
469
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
470
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
468
471
|
parameters: Type.Object({
|
|
469
472
|
path: filePathParam(),
|
|
470
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;
|
|
@@ -123,6 +119,7 @@ function generateWriteDiff(previousContent: string, nextContent: string): { diff
|
|
|
123
119
|
|
|
124
120
|
export interface WriteToolOptions {
|
|
125
121
|
onFileAnchored?: FileAnchoredCallback;
|
|
122
|
+
name?: string;
|
|
126
123
|
}
|
|
127
124
|
|
|
128
125
|
function buildWriteFsErrorResult(err: any, absolutePath: string) {
|
|
@@ -241,12 +238,18 @@ export async function executeWrite(opts: {
|
|
|
241
238
|
}
|
|
242
239
|
|
|
243
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
|
+
});
|
|
244
247
|
const tool = registerReadSeekTool(pi, {
|
|
245
|
-
name
|
|
248
|
+
name,
|
|
246
249
|
label: "write",
|
|
247
|
-
description:
|
|
248
|
-
promptSnippet:
|
|
249
|
-
promptGuidelines:
|
|
250
|
+
description: promptMetadata.description,
|
|
251
|
+
promptSnippet: promptMetadata.promptSnippet,
|
|
252
|
+
promptGuidelines: promptMetadata.promptGuidelines,
|
|
250
253
|
parameters: Type.Object({
|
|
251
254
|
path: filePathParam(),
|
|
252
255
|
content: Type.String({ description: "File content" }),
|