@trim21/personal-pi-extensions 0.0.313 → 0.0.314
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/package.json +1 -1
- package/src/aft/tools.ts +0 -9
- package/src/claude-code/files.ts +90 -5
package/package.json
CHANGED
package/src/aft/tools.ts
CHANGED
|
@@ -120,15 +120,6 @@ export function registerOutlineTool(pi: ExtensionAPI, ctx: AftToolContext): void
|
|
|
120
120
|
content: [{ type: "text", text }],
|
|
121
121
|
details: {
|
|
122
122
|
truncated,
|
|
123
|
-
pendant: {
|
|
124
|
-
markdown: buildPendantMarkdown({
|
|
125
|
-
title: "aft_outline",
|
|
126
|
-
input: params,
|
|
127
|
-
output: text,
|
|
128
|
-
truncated,
|
|
129
|
-
}),
|
|
130
|
-
expanded: true,
|
|
131
|
-
} satisfies ToolPendant,
|
|
132
123
|
},
|
|
133
124
|
};
|
|
134
125
|
},
|
package/src/claude-code/files.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { Type } from "typebox";
|
|
16
16
|
|
|
17
17
|
import { createLspService, initLsp, type LspService } from "../lib/lsp/lsp.js";
|
|
18
|
+
import { type ToolPendant } from "../lib/pendant.js";
|
|
18
19
|
import { guardWriteAccess } from "../lib/write-guard.js";
|
|
19
20
|
import {
|
|
20
21
|
type ClaudeCodeState,
|
|
@@ -45,6 +46,43 @@ function formatFileSize(bytes: number): string {
|
|
|
45
46
|
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`;
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
/** Edit/Write 结果的可折叠面板:diff(```diff 代码块)+ LSP errors(有则显示)。 */
|
|
50
|
+
export function buildEditPendant(options: {
|
|
51
|
+
filePath: string;
|
|
52
|
+
diff: string;
|
|
53
|
+
diagnosticText: string;
|
|
54
|
+
}): ToolPendant {
|
|
55
|
+
const lines = [`## Diff — \`${options.filePath}\``, "", "```diff", options.diff, "```"];
|
|
56
|
+
if (options.diagnosticText !== "") {
|
|
57
|
+
lines.push("", "## LSP errors", "", "```text", options.diagnosticText, "```");
|
|
58
|
+
}
|
|
59
|
+
return { markdown: lines.join("\n"), expanded: true };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Read 结果的可折叠面板:路径、总行数、读取范围与文件大小。 */
|
|
63
|
+
export function buildReadPendant(options: {
|
|
64
|
+
filePath: string;
|
|
65
|
+
byteSize: number;
|
|
66
|
+
offset?: number;
|
|
67
|
+
limit?: number;
|
|
68
|
+
totalLines?: number;
|
|
69
|
+
type?: string;
|
|
70
|
+
}): ToolPendant {
|
|
71
|
+
const lines = ["## Read", "", `- **Path**: \`${options.filePath}\``];
|
|
72
|
+
if (options.type) lines.push(`- **Type**: ${options.type}`);
|
|
73
|
+
if (options.totalLines !== undefined) {
|
|
74
|
+
const start = options.offset ?? 1;
|
|
75
|
+
const end = Math.min(
|
|
76
|
+
options.limit === undefined ? options.totalLines : start + options.limit - 1,
|
|
77
|
+
options.totalLines,
|
|
78
|
+
);
|
|
79
|
+
lines.push(`- **Total lines**: ${options.totalLines}`);
|
|
80
|
+
if (start <= end) lines.push(`- **Range**: ${start}-${end}`);
|
|
81
|
+
}
|
|
82
|
+
lines.push(`- **Size**: ${formatFileSize(options.byteSize)}`);
|
|
83
|
+
return { markdown: lines.join("\n"), expanded: false };
|
|
84
|
+
}
|
|
85
|
+
|
|
48
86
|
/** Tool guidance, kept in markdown so it reads like documentation. */
|
|
49
87
|
const READ_PROMPT = readFileSync(fileURLToPath(new URL("read.md", import.meta.url)), "utf8").trim();
|
|
50
88
|
const EDIT_PROMPT = readFileSync(fileURLToPath(new URL("edit.md", import.meta.url)), "utf8").trim();
|
|
@@ -69,6 +107,8 @@ export interface FileToolDetails {
|
|
|
69
107
|
* session 文件,resume 后由 session_start 重建 reads state。
|
|
70
108
|
*/
|
|
71
109
|
reads?: Record<string, FileSnapshot>;
|
|
110
|
+
/** 可折叠的 diff / LSP 结果面板(pi TUI 渲染)。 */
|
|
111
|
+
pendant?: ToolPendant;
|
|
72
112
|
}
|
|
73
113
|
|
|
74
114
|
function snapshotOf(content: Uint8Array | string, textEditable = true): FileSnapshot {
|
|
@@ -286,7 +326,17 @@ export function registerFileTools(
|
|
|
286
326
|
const snapshot = snapshotOf(image, false);
|
|
287
327
|
const key = await readStateKey(filePath);
|
|
288
328
|
state.reads.set(key, snapshot);
|
|
289
|
-
return {
|
|
329
|
+
return {
|
|
330
|
+
content,
|
|
331
|
+
details: {
|
|
332
|
+
reads: { [key]: snapshot },
|
|
333
|
+
pendant: buildReadPendant({
|
|
334
|
+
filePath,
|
|
335
|
+
byteSize: image.length,
|
|
336
|
+
type: imageMime,
|
|
337
|
+
}),
|
|
338
|
+
},
|
|
339
|
+
};
|
|
290
340
|
}
|
|
291
341
|
|
|
292
342
|
const buffer = await readFile(filePath);
|
|
@@ -316,7 +366,16 @@ export function registerFileTools(
|
|
|
316
366
|
});
|
|
317
367
|
return {
|
|
318
368
|
content: [{ type: "text", text: formatted.text }],
|
|
319
|
-
details: {
|
|
369
|
+
details: {
|
|
370
|
+
reads: { [key]: snapshot },
|
|
371
|
+
pendant: buildReadPendant({
|
|
372
|
+
filePath,
|
|
373
|
+
byteSize: buffer.length,
|
|
374
|
+
offset: params.offset ?? 1,
|
|
375
|
+
limit: params.limit,
|
|
376
|
+
totalLines: formatted.totalLines,
|
|
377
|
+
}),
|
|
378
|
+
},
|
|
320
379
|
};
|
|
321
380
|
},
|
|
322
381
|
});
|
|
@@ -388,9 +447,15 @@ export function registerFileTools(
|
|
|
388
447
|
const snapshot = snapshotOf(newString);
|
|
389
448
|
const key = await readStateKey(filePath);
|
|
390
449
|
state.reads.set(key, snapshot);
|
|
450
|
+
const diff = generateDiffString("", newString);
|
|
391
451
|
return [
|
|
392
452
|
`The file ${filePath} has been updated successfully.`,
|
|
393
|
-
{
|
|
453
|
+
{
|
|
454
|
+
diff: diff.diff,
|
|
455
|
+
patch: generateUnifiedPatch(filePath, "", newString),
|
|
456
|
+
firstChangedLine: diff.firstChangedLine,
|
|
457
|
+
reads: { [key]: snapshot },
|
|
458
|
+
},
|
|
394
459
|
];
|
|
395
460
|
}
|
|
396
461
|
const replaceAll = params.replace_all ?? false;
|
|
@@ -477,7 +542,17 @@ export function registerFileTools(
|
|
|
477
542
|
const text = diagnosticText
|
|
478
543
|
? `${message}\n\nLSP errors detected in this file, please fix:\n${diagnosticText}`
|
|
479
544
|
: message;
|
|
480
|
-
return {
|
|
545
|
+
return {
|
|
546
|
+
content: [{ type: "text" as const, text }],
|
|
547
|
+
details: {
|
|
548
|
+
...details,
|
|
549
|
+
pendant: buildEditPendant({
|
|
550
|
+
filePath,
|
|
551
|
+
diff: details.diff ?? "",
|
|
552
|
+
diagnosticText,
|
|
553
|
+
}),
|
|
554
|
+
},
|
|
555
|
+
};
|
|
481
556
|
},
|
|
482
557
|
});
|
|
483
558
|
|
|
@@ -556,7 +631,17 @@ export function registerFileTools(
|
|
|
556
631
|
const text = diagnosticText
|
|
557
632
|
? `${message}\n\nLSP errors detected in this file, please fix:\n${diagnosticText}`
|
|
558
633
|
: message;
|
|
559
|
-
return {
|
|
634
|
+
return {
|
|
635
|
+
content: [{ type: "text" as const, text }],
|
|
636
|
+
details: {
|
|
637
|
+
...details,
|
|
638
|
+
pendant: buildEditPendant({
|
|
639
|
+
filePath,
|
|
640
|
+
diff: details.diff ?? "",
|
|
641
|
+
diagnosticText,
|
|
642
|
+
}),
|
|
643
|
+
},
|
|
644
|
+
};
|
|
560
645
|
},
|
|
561
646
|
});
|
|
562
647
|
}
|