pi-claude-code-ui 1.0.71 → 1.0.73
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/CHANGELOG.md +13 -0
- package/extensions/index.ts +34 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
> [!IMPORTANT]
|
|
4
4
|
> **1.0.69 — package rename (permanent).** Canonical npm name is now [`pi-claude-code-ui`](https://www.npmjs.com/package/pi-claude-code-ui). `pi-claude-style-tools` is legacy and will not receive further releases. Install with `pi install npm:pi-claude-code-ui` or `npm i pi-claude-code-ui`.
|
|
5
5
|
|
|
6
|
+
## 1.0.73 — 2026-07-18
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Agent rows align with other tools again** — removed the extra leading indent that only applied to Agent-family tool rows.
|
|
11
|
+
- **Agent breathe stays centered** — drop double-width `⬤` (it walked the baseline). Cycle is now single-cell glyphs `● → • → · → (invisible) → · → •` so the optical center never moves.
|
|
12
|
+
|
|
13
|
+
## 1.0.72 — 2026-07-18
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Agent tools breathe** — `Agent` / subagent tools use a size cycle while pending instead of the ordinary on/off `●` blink, so agent work reads as a different kind of tool.
|
|
18
|
+
|
|
6
19
|
## 1.0.71 — 2026-07-18
|
|
7
20
|
|
|
8
21
|
### Fixed
|
package/extensions/index.ts
CHANGED
|
@@ -434,10 +434,10 @@ function isToolExecutionLike(value: unknown): value is { toolName: string; toolC
|
|
|
434
434
|
return typeof candidate.toolName === "string" && typeof candidate.toolCallId === "string";
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
return typeof
|
|
437
|
+
const AGENT_FAMILY_TOOL_NAMES = new Set(["Agent", "Agents", "get_subagent_result", "steer_subagent"]);
|
|
438
|
+
|
|
439
|
+
function isAgentFamilyToolName(name: unknown): boolean {
|
|
440
|
+
return typeof name === "string" && AGENT_FAMILY_TOOL_NAMES.has(name);
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
function isTerminalImageLine(line: string): boolean {
|
|
@@ -541,9 +541,14 @@ function getToolGroupOverallStatus(tools: any[]): ToolStatus {
|
|
|
541
541
|
|
|
542
542
|
// Claude Code: solid filled circle that is either fully present or fully gone
|
|
543
543
|
// while pending — never a hollow outlined ○. Classic ● + bold is the sweet
|
|
544
|
-
// spot
|
|
544
|
+
// spot for ordinary tools. Agent-family tools use a breathing size cycle.
|
|
545
545
|
const STATUS_DOT_FILLED = "●";
|
|
546
546
|
const STATUS_DOT_BOLD = "\x1b[1m";
|
|
547
|
+
// Single-cell glyphs only (⬤ is often double-width and walks the baseline).
|
|
548
|
+
// Optical sizes share the same cell so the center stays put while breathing:
|
|
549
|
+
// big ● → medium • → small · → invisible → small · → medium •
|
|
550
|
+
const AGENT_BREATHE_GLYPHS = ["●", "•", "·", " ", "·", "•"] as const;
|
|
551
|
+
const AGENT_BREATHE_LEN = AGENT_BREATHE_GLYPHS.length;
|
|
547
552
|
|
|
548
553
|
function paintStatusDot(colorAnsi: string): string {
|
|
549
554
|
return `${colorAnsi}${STATUS_DOT_BOLD}${STATUS_DOT_FILLED}${TRANSPARENT_RESET}`;
|
|
@@ -554,6 +559,15 @@ function themeStatusDot(theme: Theme, colorKey: "success" | "error" | "dim" | "m
|
|
|
554
559
|
return theme.fg(colorKey, `${STATUS_DOT_BOLD}${STATUS_DOT_FILLED}`);
|
|
555
560
|
}
|
|
556
561
|
|
|
562
|
+
function agentBreatheDot(theme: Theme): string {
|
|
563
|
+
// Always exactly one display cell — matches ordinary tool dots, keeps titles aligned.
|
|
564
|
+
const glyph = AGENT_BREATHE_GLYPHS[_globalBlinkPhaseIndex % AGENT_BREATHE_LEN];
|
|
565
|
+
if (glyph === " ") return " ";
|
|
566
|
+
// Bold only on the largest frame so weight changes without shifting the cell.
|
|
567
|
+
const bold = glyph === "●" ? STATUS_DOT_BOLD : "";
|
|
568
|
+
return theme.fg("success", `${bold}${glyph}`);
|
|
569
|
+
}
|
|
570
|
+
|
|
557
571
|
function groupStatusLight(status: ToolStatus): string {
|
|
558
572
|
const color = status === "success" ? TOOL_STATUS_SUCCESS : status === "error" ? TOOL_STATUS_ERROR : TOOL_STATUS_PENDING;
|
|
559
573
|
if (status === "pending") {
|
|
@@ -1004,10 +1018,11 @@ function patchGlobalToolBorders(): void {
|
|
|
1004
1018
|
(this as any)[TOOL_RENDER_CACHE] = { width, mode: toolBackgroundMode, lines: rendered, ...branchCache };
|
|
1005
1019
|
return rendered;
|
|
1006
1020
|
}
|
|
1007
|
-
|
|
1021
|
+
// Agent-family tools stay column-aligned with every other tool row — no extra
|
|
1022
|
+
// leading indent (the old nested pad made Agent look offset from Read/Bash).
|
|
1008
1023
|
const core = textLines.map((line) => {
|
|
1009
1024
|
const normalized = normalizeLeadingCheckGlyph(line);
|
|
1010
|
-
return clampLineWidth(stripOuterBackgroundAnsi(
|
|
1025
|
+
return clampLineWidth(stripOuterBackgroundAnsi(normalized), width);
|
|
1011
1026
|
});
|
|
1012
1027
|
const spacerLine = " ".repeat(width);
|
|
1013
1028
|
let result: string[];
|
|
@@ -2606,6 +2621,9 @@ type BlinkEntry = { key: any; order: number; invalidate: () => void };
|
|
|
2606
2621
|
const _blinkContexts = new Map<any, BlinkEntry>();
|
|
2607
2622
|
let _globalBlinkTimer: ReturnType<typeof setTimeout> | null = null;
|
|
2608
2623
|
let _blinkOrder = 0;
|
|
2624
|
+
// Shared phase for all blinkers. Ordinary tools use even/odd (on/off ●).
|
|
2625
|
+
// Agent-family tools map the index onto a 6-step size breath cycle.
|
|
2626
|
+
let _globalBlinkPhaseIndex = 0;
|
|
2609
2627
|
let _globalBlinkPhase = true;
|
|
2610
2628
|
|
|
2611
2629
|
function getBlinkIntervalMs(): number {
|
|
@@ -2664,7 +2682,8 @@ function _scheduleGlobalBlinkTimer(): void {
|
|
|
2664
2682
|
_clearAllBlinkContexts();
|
|
2665
2683
|
return;
|
|
2666
2684
|
}
|
|
2667
|
-
|
|
2685
|
+
_globalBlinkPhaseIndex = (_globalBlinkPhaseIndex + 1) % AGENT_BREATHE_LEN;
|
|
2686
|
+
_globalBlinkPhase = _globalBlinkPhaseIndex % 2 === 0;
|
|
2668
2687
|
for (const entry of getBlinkingEntries()) {
|
|
2669
2688
|
try { entry.invalidate(); } catch { /* noop */ }
|
|
2670
2689
|
}
|
|
@@ -2726,9 +2745,13 @@ function blinkDot(ctx: any, theme: Theme): string {
|
|
|
2726
2745
|
}
|
|
2727
2746
|
setupBlinkTimer(ctx);
|
|
2728
2747
|
const key = getBlinkKey(ctx);
|
|
2748
|
+
if (key?._blinkActive !== true) return " ";
|
|
2749
|
+
// Agent-family tools breathe through sizes; ordinary tools still on/off ●.
|
|
2750
|
+
if (ctx?.state?._agentBreathe === true) {
|
|
2751
|
+
return agentBreatheDot(theme);
|
|
2752
|
+
}
|
|
2729
2753
|
// Claude Code: solid filled circle that either shows or fully disappears —
|
|
2730
2754
|
// never a hollow outlined ○ in the off phase.
|
|
2731
|
-
if (key?._blinkActive !== true) return " ";
|
|
2732
2755
|
return _globalBlinkPhase ? themeStatusDot(theme, "success") : " ";
|
|
2733
2756
|
}
|
|
2734
2757
|
|
|
@@ -4922,6 +4945,8 @@ function genericToolLabel(name: string): string {
|
|
|
4922
4945
|
function renderGenericToolCall(name: string, args: any, theme: Theme, ctx: any): Text {
|
|
4923
4946
|
syncToolCallStatus(ctx);
|
|
4924
4947
|
ctx.state._openAiPatchFiles = [];
|
|
4948
|
+
// Agent / subagent tools get a size-breathing pending marker, not on/off ●.
|
|
4949
|
+
if (isAgentFamilyToolName(name)) ctx.state._agentBreathe = true;
|
|
4925
4950
|
const sp = (path: string) => shortPath(ctx.cwd ?? process.cwd(), path);
|
|
4926
4951
|
const summary = stableCallSummary(ctx, "_callSummary", () => summarizeGenericToolCall(name, args, theme, sp));
|
|
4927
4952
|
return makeText(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-claude-code-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.73",
|
|
4
4
|
"description": "Claude Code-style grouped tool rows for pi with Ctrl+O/Ctrl+Shift+O previews, math rendering, and consistent built-in, MCP, and custom tool rendering",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|