feat: render ASCII progress bar in Pi extension updates

- Add renderProgressBar() helper in pi-extension.ts
- Pi init/reinit now show [████░░░░░░] 3/20 → filename.ts
- Replaces plain text percentage with visual bar
- All 52 tests passing
This commit is contained in:
2026-06-10 18:53:49 +02:00
parent 9bdb862cca
commit 010e4b83eb
+14 -6
View File
@@ -55,6 +55,14 @@ function isDirty(content: string): boolean {
return content.includes("## dirty") && !content.includes("## dirty\n-"); return content.includes("## dirty") && !content.includes("## dirty\n-");
} }
function renderProgressBar(completed: number, total: number, currentFile?: string, width = 20): string {
const pct = total > 0 ? completed / total : 0;
const filled = Math.round(width * pct);
const bar = "█".repeat(filled) + "░".repeat(width - filled);
const file = currentFile ? `${currentFile}` : "";
return `[${bar}] ${completed}/${total}${file}`;
}
export default function (pi: ExtensionAPI) { export default function (pi: ExtensionAPI) {
pi.registerTool({ pi.registerTool({
name: "project_map_init", name: "project_map_init",
@@ -83,10 +91,10 @@ export default function (pi: ExtensionAPI) {
llmClient: client, llmClient: client,
cacheDir: ctx.cwd, cacheDir: ctx.cwd,
onProgress: (info) => { onProgress: (info) => {
const pct = info.total > 0 ? Math.round((info.completed / info.total) * 100) : 0; const bar = renderProgressBar(info.completed, info.total, info.currentFile);
_onUpdate?.({ _onUpdate?.({
content: [{ type: "text", text: `${info.message} (${pct}%)` }], content: [{ type: "text", text: bar }],
details: { progress: pct, file: info.currentFile, dir: info.dir }, details: { progress: info.total > 0 ? Math.round((info.completed / info.total) * 100) : 0, file: info.currentFile, dir: info.dir },
}); });
}, },
}); });
@@ -215,10 +223,10 @@ export default function (pi: ExtensionAPI) {
llmClient: client, llmClient: client,
cacheDir: ctx.cwd, cacheDir: ctx.cwd,
onProgress: (info) => { onProgress: (info) => {
const pct = info.total > 0 ? Math.round((info.completed / info.total) * 100) : 0; const bar = renderProgressBar(info.completed, info.total, info.currentFile);
_onUpdate?.({ _onUpdate?.({
content: [{ type: "text", text: `${info.message} (${pct}%)` }], content: [{ type: "text", text: bar }],
details: { progress: pct, file: info.currentFile, dir: info.dir }, details: { progress: info.total > 0 ? Math.round((info.completed / info.total) * 100) : 0, file: info.currentFile, dir: info.dir },
}); });
}, },
}); });