pi-claude-code-ui 1.0.79 → 1.0.83
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 +19 -0
- package/README.md +10 -4
- package/config/config.example.json +2 -0
- package/extensions/bash-command.ts +84 -0
- package/extensions/index.ts +654 -123
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.83 — 2026-09-07
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Support Pi 0.85+ MouseRegion-wrapped thinking blocks** — unwrap `MouseRegion` containers in `replaceHiddenThinkingPlaceholders` and the assistant message Markdown post-processor. Resolves an issue in newer Pi versions where thinking blocks were rendered in raw italics and collapsed thoughts remained stuck on "Thinking…" instead of transitioning to "Thought for Xs". Preserves native Pi 0.85 mouse click-to-expand and click-to-collapse functionality.
|
|
11
|
+
|
|
12
|
+
## 1.0.80 — 2026-08-24
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Scrub Magic Context tags at the terminal writer** — last-resort display filter at the `ProcessTerminal.write` choke point removes every complete `§N§` token from painted output, covering any surface the targeted render strips can't reach: mid-sentence tag references in ctx_reduce/system-reminder tool output, replayed history on resume, overlays, and search hits. Display only — session storage, LLM context, copy sources, and ANSI sequences are untouched, so plugin functionality is unaffected.
|
|
17
|
+
|
|
6
18
|
## 1.0.79 — 2026-08-23
|
|
7
19
|
|
|
8
20
|
### Fixed
|
|
@@ -27,6 +39,13 @@
|
|
|
27
39
|
|
|
28
40
|
- **Hide transient context tags** — hide transient context tags in streaming prose.
|
|
29
41
|
|
|
42
|
+
## Unreleased
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **Grouped Bash commands show live progress** (Raine Virta) - collapsed running Bash rows display their latest non-empty output line beneath the command.
|
|
47
|
+
- **Final timing status stays presentation-only** (Raine Virta) - the `Turn took` line renders as a styled TUI component without adding ANSI escapes or display text to persisted assistant messages.
|
|
48
|
+
|
|
30
49
|
## 1.0.75 — 2026-07-29
|
|
31
50
|
|
|
32
51
|
### Fixed
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Claude Code inspired tool rendering for Pi — Shiki-powered diffs, status dots,
|
|
|
21
21
|
- **Adaptive edit/write diffs** with split or unified layouts, syntax highlighting, and inline word-level emphasis
|
|
22
22
|
- **Diff stat bar** with colored add/remove summary and hunk metadata
|
|
23
23
|
- **Progressive collapsed diff hints** that shorten on narrow terminals
|
|
24
|
-
- **
|
|
24
|
+
- **Live-only thinking** (default) — only the actively-streaming thinking renders expanded; finished thinking collapses to a one-line `Thought for Xs` row (`/cc-tools thinking full` restores always-expanded, `Ctrl+O` still expands anything)
|
|
25
25
|
- **MCP-aware rendering** with hidden, summary, and preview modes
|
|
26
26
|
- **Configurable output modes** for read, search, bash, and MCP results
|
|
27
27
|
- **Live running previews** that show a few output lines for active tool calls (latest lines for bash), persisting until the next tool/text activity
|
|
@@ -31,7 +31,7 @@ Claude Code inspired tool rendering for Pi — Shiki-powered diffs, status dots,
|
|
|
31
31
|
- **Theme-adaptive palette** — borders, branch connectors, dim text, spinner accent, and diff backgrounds automatically follow the active pi theme (set `themeAdaptive: false` to keep the fixed Claude-style palette)
|
|
32
32
|
- **Light Ghostty-sync themes** — edit/write diffs use `github-light` highlighting and light-tinted diff rows; tool pending dots use softer chrome colors
|
|
33
33
|
- **Transparent edit/write diffs** with universal red/green diff colors
|
|
34
|
-
- **Grouped consecutive tool calls** with
|
|
34
|
+
- **Grouped consecutive tool calls** with single-row summaries for repeated targets and per-tool glance rows for mixed work (set `groupToolCalls: false` to disable)
|
|
35
35
|
- **Extra detail toggle** with `Ctrl+Shift+O`, increasing expanded preview caps without making the default view heavy
|
|
36
36
|
- **Global border patch** for all tool rows, including unknown/custom tools
|
|
37
37
|
|
|
@@ -50,8 +50,10 @@ Set in `.pi/settings.json` or `~/.pi/settings.json`:
|
|
|
50
50
|
"extraExpandedPreviewMaxLines": 12000,
|
|
51
51
|
"extraToolOutputExpanded": false,
|
|
52
52
|
"groupToolCalls": true,
|
|
53
|
+
"thinkingMode": "live",
|
|
53
54
|
"bashOutputMode": "opencode",
|
|
54
55
|
"bashCollapsedLines": 10,
|
|
56
|
+
"bashCommandPreviewLines": 8,
|
|
55
57
|
"liveToolPreview": true,
|
|
56
58
|
"liveToolPreviewLines": 5,
|
|
57
59
|
"diffCollapsedLines": 24,
|
|
@@ -69,7 +71,7 @@ When `themeAdaptive` is `true` (default), the following colors are derived from
|
|
|
69
71
|
| User box, tool rules, code fences | `dim` → `muted` → `borderMuted` → `thinkingText` |
|
|
70
72
|
| Branch connectors (`├`, `└`, `│`) | **fixed rgb(72)** by default (theme-independent); `/cc-tools branch theme` to follow pi theme |
|
|
71
73
|
| "✻ Turn took Ns" line (final message only, with session total + turn count) | `muted` |
|
|
72
|
-
|
|
|
74
|
+
| Expanded thinking-block text and `∴` marker | `muted` |
|
|
73
75
|
| Diff add/remove accents | `toolDiffAdded` / `toolDiffRemoved` |
|
|
74
76
|
| Diff background tints | mixed against `toolSuccessBg` base |
|
|
75
77
|
| Spinner verb text (`Working…`) | `borderAccent` (fallback: `accent`) |
|
|
@@ -121,6 +123,8 @@ Use `/cc-tools` to control tool UI at runtime:
|
|
|
121
123
|
/cc-tools outlines # tool style: outlines, transparent, or default
|
|
122
124
|
/cc-tools group toggle # toggle grouped adjacent/concurrent tool calls
|
|
123
125
|
/cc-tools group off # disable grouping (also ungroups current grouped rows)
|
|
126
|
+
/cc-tools thinking live # default: only the streaming thinking expands; finished ones collapse
|
|
127
|
+
/cc-tools thinking full # always render thinking expanded, like stock pi
|
|
124
128
|
/cc-tools detail toggle # same mode as Ctrl+Shift+O
|
|
125
129
|
```
|
|
126
130
|
|
|
@@ -141,8 +145,10 @@ Use `/cc-tools` to control tool UI at runtime:
|
|
|
141
145
|
| `expandedPreviewMaxLines` | `4000` | Max lines when expanded with Ctrl+O |
|
|
142
146
|
| `extraExpandedPreviewMaxLines` | `12000` | Max lines after Ctrl+Shift+O extra-detail mode |
|
|
143
147
|
| `extraToolOutputExpanded` | `false` | Start with Ctrl+Shift+O extra-detail mode enabled |
|
|
144
|
-
| `groupToolCalls` | `true` | Group adjacent/concurrent
|
|
148
|
+
| `groupToolCalls` | `true` | Group adjacent/concurrent calls, collapsing repeated targets into one row |
|
|
149
|
+
| `thinkingMode` | `live` | `live` = only streaming thinking expands (finished collapse to `Thought for Xs`); `full` = always expanded |
|
|
145
150
|
| `bashCollapsedLines` | `10` | Lines for collapsed bash output |
|
|
151
|
+
| `bashCommandPreviewLines` | `8` | Verbatim script lines shown while bash runs or after failure; `0` disables them |
|
|
146
152
|
| `liveToolPreview` | `true` | Show a small live output preview while tools are still running |
|
|
147
153
|
| `liveToolPreviewLines` | `5` | Lines shown in the collapsed live preview |
|
|
148
154
|
| `diffCollapsedLines` | `24` | Diff lines before collapsing |
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
"extraExpandedPreviewMaxLines": 12000,
|
|
9
9
|
"extraToolOutputExpanded": false,
|
|
10
10
|
"groupToolCalls": true,
|
|
11
|
+
"thinkingMode": "live",
|
|
11
12
|
"bashOutputMode": "opencode",
|
|
12
13
|
"bashCollapsedLines": 10,
|
|
14
|
+
"bashCommandPreviewLines": 8,
|
|
13
15
|
"liveToolPreview": true,
|
|
14
16
|
"liveToolPreviewLines": 5,
|
|
15
17
|
"diffCollapsedLines": 24,
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface BashCommandPresentation {
|
|
2
|
+
headline: string;
|
|
3
|
+
sourceLines: string[];
|
|
4
|
+
sourceLineCount: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const CONTROL_CHAR_RE = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
|
8
|
+
const ANSI_ESCAPE_RE = /\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\))/g;
|
|
9
|
+
const HEADLINE_SKIP_RE = /^(?:#|set(?:\s|$)|cd(?:\s|$)|(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=|(?:\{|\}|do|done|then|fi|esac)$)/;
|
|
10
|
+
|
|
11
|
+
function normalizeHeadline(line: string): string {
|
|
12
|
+
return line.replace(/\s+/g, " ").trim();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function summarize(text: string, max = 180): string {
|
|
16
|
+
if (text.length <= max) return text;
|
|
17
|
+
const head = Math.max(1, Math.ceil((max - 3) * 0.65));
|
|
18
|
+
const tail = Math.max(1, max - 3 - head);
|
|
19
|
+
return `${text.slice(0, head)}...${text.slice(-tail)}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function sanitizeSource(command: string): string[] {
|
|
23
|
+
const lines = command
|
|
24
|
+
.replace(/\r\n?/g, "\n")
|
|
25
|
+
.replace(CONTROL_CHAR_RE, "")
|
|
26
|
+
.replace(/\t/g, " ")
|
|
27
|
+
.split("\n");
|
|
28
|
+
while (lines.length > 1 && lines[0].trim() === "") lines.shift();
|
|
29
|
+
while (lines.length > 1 && lines[lines.length - 1].trim() === "") lines.pop();
|
|
30
|
+
return lines;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function buildBashCommandPresentation(command: string): BashCommandPresentation {
|
|
34
|
+
const sourceLines = sanitizeSource(command);
|
|
35
|
+
const nonBlank = sourceLines.map(normalizeHeadline).filter(Boolean);
|
|
36
|
+
const operative = nonBlank.find((line) => !HEADLINE_SKIP_RE.test(line)) ?? nonBlank[0] ?? "command";
|
|
37
|
+
let headline = summarize(operative);
|
|
38
|
+
if (sourceLines.length > 1) headline += ` · ${sourceLines.length} lines`;
|
|
39
|
+
return {
|
|
40
|
+
headline,
|
|
41
|
+
sourceLines,
|
|
42
|
+
sourceLineCount: sourceLines.length,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function describeBashSource(presentation: BashCommandPresentation): string {
|
|
47
|
+
return presentation.sourceLineCount === 1 ? "command" : `script · ${presentation.sourceLineCount} lines`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function formatBashDuration(ms: number): string {
|
|
51
|
+
const safeMs = Math.max(0, Number.isFinite(ms) ? ms : 0);
|
|
52
|
+
if (safeMs < 1_000) return "<1s";
|
|
53
|
+
const totalSeconds = Math.floor(safeMs / 1_000);
|
|
54
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
55
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
56
|
+
const seconds = totalSeconds % 60;
|
|
57
|
+
if (totalMinutes < 60) return `${totalMinutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
58
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
59
|
+
const minutes = totalMinutes % 60;
|
|
60
|
+
return `${hours}h ${String(minutes).padStart(2, "0")}m`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getLastBashOutputLine(output: string): string | undefined {
|
|
64
|
+
const lines = output
|
|
65
|
+
.replace(/\r\n/g, "\n")
|
|
66
|
+
.replace(/\r/g, "\n")
|
|
67
|
+
.split("\n");
|
|
68
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
69
|
+
const line = lines[index]
|
|
70
|
+
.replace(ANSI_ESCAPE_RE, "")
|
|
71
|
+
.replace(CONTROL_CHAR_RE, "")
|
|
72
|
+
.trim();
|
|
73
|
+
if (line) return line;
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function buildBashPreview(sourceLines: string[], limit: number): string[] {
|
|
79
|
+
if (limit <= 0 || sourceLines.length === 0) return [];
|
|
80
|
+
if (sourceLines.length <= limit) return [...sourceLines];
|
|
81
|
+
if (limit === 1) return [`... ${sourceLines.length} more lines`];
|
|
82
|
+
const shown = sourceLines.slice(0, limit - 1);
|
|
83
|
+
return [...shown, `... ${sourceLines.length - shown.length} more lines`];
|
|
84
|
+
}
|