pi-zentui 0.20.2 → 0.21.0
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/README.md +93 -548
- package/extensions/zentui/accent-rail-editor.ts +99 -0
- package/extensions/zentui/accent-rail-layout-patch.ts +457 -0
- package/extensions/zentui/completion-menu.ts +157 -0
- package/extensions/zentui/config.ts +64 -4
- package/extensions/zentui/index.ts +139 -61
- package/extensions/zentui/settings-command.ts +73 -1
- package/extensions/zentui/settings-previews.ts +62 -44
- package/extensions/zentui/ui.ts +195 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,180 +1,79 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Zentui</h1>
|
|
2
2
|
|
|
3
|
-
A Starship-inspired statusline and Opencode-style TUI for
|
|
3
|
+
<p align="center">A Starship-inspired statusline and Opencode-style TUI for <a href="https://pi.dev">Pi</a>.</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/pi-zentui"><img alt="npm version" src="https://shieldcn.dev/npm/pi-zentui.svg?variant=outline" /></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/pi-zentui"><img alt="npm monthly downloads" src="https://shieldcn.dev/npm/dm/pi-zentui.svg?variant=outline" /></a>
|
|
8
|
+
<a href="https://github.com/lmilojevicc/pi-zentui/actions/workflows/ci.yml"><img alt="CI status" src="https://shieldcn.dev/github/ci/lmilojevicc/pi-zentui.svg?workflow=ci.yml&branch=main&variant=outline" /></a>
|
|
9
|
+
<a href="https://github.com/lmilojevicc/pi-zentui/graphs/contributors"><img alt="GitHub contributors" src="https://shieldcn.dev/github/contributors/lmilojevicc/pi-zentui.svg?variant=outline" /></a>
|
|
10
|
+
<a href="https://github.com/lmilojevicc/pi-zentui/blob/main/LICENSE"><img alt="MIT license" src="https://shieldcn.dev/github/license/lmilojevicc/pi-zentui.svg?variant=outline" /></a>
|
|
11
|
+
</p>
|
|
6
12
|
|
|
7
|
-

|
|
8
14
|
|
|
9
15
|
## What is this?
|
|
10
16
|
|
|
11
|
-
Zentui
|
|
17
|
+
Zentui gives four Pi surfaces independent ownership and styling:
|
|
12
18
|
|
|
13
|
-
- **Editor** —
|
|
14
|
-
- **User messages** —
|
|
15
|
-
- **Working line** — optional ownership
|
|
16
|
-
- **
|
|
19
|
+
- **Editor** — Opencode, Opencode copy-friendly, Accent Rail, and Minimalist input treatments
|
|
20
|
+
- **User messages** — framed, framed copy-friendly, compact, and labeled transcript messages
|
|
21
|
+
- **Working line** — optional ownership of Pi's complete in-progress row and settled turn summary
|
|
22
|
+
- **Footer** — Pi's native Footer, a Starship-style statusline, or a hidden zero-row Footer
|
|
17
23
|
|
|
18
|
-
Editor, User messages, Working line, and selector borders
|
|
24
|
+
Editor, User messages, Working line, and selector borders have independent `enabled` fields. Footer uses one `style`: `native`, `starship`, or `hidden`. Use `/zentui` to configure each component without coupling it to the others.
|
|
19
25
|
|
|
20
|
-
##
|
|
26
|
+
## Highlights
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
| Surface | Default | Available treatments |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| Editor | `opencode` | Opencode, copy-friendly, Accent Rail, Minimalist |
|
|
31
|
+
| User messages | `framed` | Framed, copy-friendly, Compact, Labeled |
|
|
32
|
+
| Working line | disabled | Five spinner presets, live tool/time/thinking/token segments, turn summary |
|
|
33
|
+
| Footer | `starship` | Native, Starship, Hidden |
|
|
34
|
+
| Selector borders | `zentui` | Independent enablement and color source |
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
- `on branch` — git branch with icon
|
|
26
|
-
- `[!?↑]` — git status indicators (modified, untracked, ahead/behind, stashed, etc.)
|
|
27
|
-
- `via v5.5.0` — runtime detection with version and Starship-style Nerd Font runtime/language modules
|
|
28
|
-
- Optional segments (off by default): selected model/provider, `user@host`, current time, OS icon, session duration, and the **project package version** (e.g. `package.json` → `0.6.0`) — distinct from the runtime segment, which shows the installed toolchain
|
|
29
|
-
- Right side shows context usage, token counts, and cost
|
|
30
|
-
- Built-in footer segments can be shown or hidden individually from `/zentui`
|
|
31
|
-
- Fully custom Starship-style layout via the `components.footer.styles.starship.format` template string — see [Footer Format Template](#footer-format-template)
|
|
32
|
-
- Third-party Pi extension statuses from `ctx.ui.setStatus()` can be shown on the left,
|
|
33
|
-
middle, or right side, or hidden per status key from `/zentui`
|
|
36
|
+
The Starship Footer shows directory, Git, runtime, context, tokens, and cost. Optional segments include model/provider, package version, session duration, `user@host`, time, OS, Git commit, Git metrics, and third-party extension statuses. The layout is segment-driven by default and supports a complete Starship-style format template.
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
Zentui detects a broad set of runtime and language modules, preserves Nerd Font icons with an ASCII mode, and can source colors from the active Pi theme or directly from the terminal palette.
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
- `opencode-copy-friendly` (**Opencode (copy-friendly)** in `/zentui`) preserves the low-rail rendering for clean terminal selection
|
|
39
|
-
- `minimalist` moves session name, cost, model, thinking, context, Git, configurable path, Bash state, and turn duration into a rounded frame
|
|
40
|
-
- The selected model label and provider appear inside both Opencode editor variants; the model ID is used by default, while `components.editor.modelLabel: "name"` uses the display name with ID fallback.
|
|
41
|
-
- Opencode autocomplete rows retain Pi's original unframed trailing layout; Minimalist keeps autocomplete inside its rounded frame
|
|
42
|
-
- Configurable model, provider, thinking-level, accent, and border colors
|
|
40
|
+
## Screenshots
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
### Editors
|
|
45
43
|
|
|
46
44
|
<h4 align="center"><code>opencode</code></h4>
|
|
47
45
|
|
|
48
|
-

|
|
49
47
|
|
|
50
48
|
<h4 align="center"><code>opencode-copy-friendly</code></h4>
|
|
51
49
|
|
|
52
|
-

|
|
53
51
|
|
|
54
|
-
<h4 align="center"><code>
|
|
52
|
+
<h4 align="center"><code>accent-rail</code></h4>
|
|
55
53
|
|
|
56
|
-

|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
<h4 align="center"><code>minimalist</code></h4>
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
- `framed-copy-friendly` (**Framed (copy-friendly)** in `/zentui`) keeps the full-width horizontal borders and blank spacer rows, removes the copied accent rail, and retains a one-cell leading gutter before body text.
|
|
62
|
-
- `compact` uses only an accent rail, with no border or padding rows
|
|
63
|
-
- `labeled` uses a rounded box with the fixed label `User`
|
|
64
|
-
- Disabling User-message styling delegates byte-for-byte to Pi's native renderer; native is not a style ID
|
|
65
|
-
- No custom `plain` message style is provided
|
|
58
|
+

|
|
66
59
|
|
|
67
|
-
User
|
|
60
|
+
### User messages
|
|
68
61
|
|
|
69
62
|
<h4 align="center"><code>framed</code></h4>
|
|
70
63
|
|
|
71
|
-

|
|
72
65
|
|
|
73
66
|
<h4 align="center"><code>framed-copy-friendly</code></h4>
|
|
74
67
|
|
|
75
|
-

|
|
76
69
|
|
|
77
70
|
<h4 align="center"><code>compact</code></h4>
|
|
78
71
|
|
|
79
|
-

|
|
80
73
|
|
|
81
74
|
<h4 align="center"><code>labeled</code></h4>
|
|
82
75
|
|
|
83
|
-

|
|
178
77
|
|
|
179
78
|
## Install
|
|
180
79
|
|
|
@@ -186,456 +85,102 @@ pi install npm:pi-zentui
|
|
|
186
85
|
pi install git:github.com/lmilojevicc/pi-zentui
|
|
187
86
|
```
|
|
188
87
|
|
|
189
|
-
##
|
|
190
|
-
|
|
191
|
-
User config lives at `~/.pi/agent/zentui.json`. The file is optional: missing or invalid known values fall back to Zentui defaults, unknown keys are ignored at runtime, and `/zentui` can patch color-source settings, UI feature toggles, built-in footer segment visibility, and active third-party status placements.
|
|
192
|
-
|
|
193
|
-
The interactive `/zentui` menu is split into exactly eight component-oriented sections, in this order. Use `Tab` and `Shift+Tab` to switch sections:
|
|
194
|
-
|
|
195
|
-
1. **Appearance** — selector-border enablement, style, and colors; icon mode.
|
|
196
|
-
2. **Editor** — editor enablement, style, colors, model label, border behavior, viewport indicators, settings for the selected editor style, and a static synthetic preview.
|
|
197
|
-
3. **User messages** — message enablement, `framed | framed-copy-friendly | compact | labeled` style selection (including **Framed (copy-friendly)**), colors, and a static synthetic Markdown preview.
|
|
198
|
-
4. **Working line** — ownership, settled Turn summary, spinner and text speeds, optional spinner-color motion, text animation, color source, custom-message toggle and editable list, Tool/Elapsed/Thinking/Tokens toggles, and animated preview.
|
|
199
|
-
5. **Footer** — `Native | Starship | Hidden` style selection. Starship additionally shows colors, model label, responsive layout, separator, context style, and path display.
|
|
200
|
-
6. **Segments** — visibility toggles for non-Git Starship segments.
|
|
201
|
-
7. **Git** — Starship Git segment and probe controls.
|
|
202
|
-
8. **Extensions** — Starship extension-status placement and color controls for active keys.
|
|
88
|
+
## Configure
|
|
203
89
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
Starship-specific Footer rows are shown only while Starship is selected. The **Segments**, **Git**, and **Extensions** sections remain available for preconfiguration under every Footer style. Free-form values such as custom formats, Opencode metadata format, raw colors/styles, and inactive extension keys remain JSON-only; Working-line speed accepts validated custom milliseconds in `/zentui`.
|
|
207
|
-
|
|
208
|
-
Useful slash-command shortcuts:
|
|
90
|
+
Run `/zentui` inside Pi to configure Appearance, Editor, User messages, Working line, Footer, Segments, Git, and Extensions. Use `Tab` and `Shift+Tab` to switch sections. Changes are applied live and saved to:
|
|
209
91
|
|
|
210
92
|
```text
|
|
211
|
-
/zentui
|
|
212
|
-
/zentui editor disable
|
|
213
|
-
/zentui statusline enable
|
|
214
|
-
/zentui statusline disable
|
|
215
|
-
/zentui editor toggle
|
|
216
|
-
/zentui messages enable
|
|
217
|
-
/zentui messages disable
|
|
218
|
-
/zentui messages toggle
|
|
219
|
-
/zentui statusline toggle
|
|
220
|
-
/zentui messages
|
|
221
|
-
/zentui user-messages
|
|
222
|
-
/zentui working-line
|
|
223
|
-
/zentui viewport-indicators enable
|
|
224
|
-
/zentui viewport-indicators disable
|
|
225
|
-
/zentui viewport-indicators toggle
|
|
226
|
-
/zentui format "$cwd on branch $git_branch$git_status using $runtime $fill $context"
|
|
227
|
-
/zentui format clear
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
`footer`, `statusline`, `status`, and `status line` are aliases: enable selects Starship, disable selects Native, and toggle selects Native only from Starship (Native or Hidden toggle to Starship).
|
|
231
|
-
|
|
232
|
-
Default config values — copy this and change any value you want:
|
|
233
|
-
|
|
234
|
-
```json
|
|
235
|
-
{
|
|
236
|
-
"projectRefreshIntervalMs": 30000,
|
|
237
|
-
"components": {
|
|
238
|
-
"editor": {
|
|
239
|
-
"enabled": true,
|
|
240
|
-
"style": "opencode",
|
|
241
|
-
"colorSource": "theme",
|
|
242
|
-
"borderColorMode": "static",
|
|
243
|
-
"modelLabel": "id",
|
|
244
|
-
"viewportIndicators": true,
|
|
245
|
-
"styles": {
|
|
246
|
-
"opencode": {
|
|
247
|
-
"metadataFormat": "$model $provider( $thinking)"
|
|
248
|
-
},
|
|
249
|
-
"opencode-copy-friendly": {
|
|
250
|
-
"metadataFormat": "$model $provider( $thinking)"
|
|
251
|
-
},
|
|
252
|
-
"minimalist": {
|
|
253
|
-
"pathDisplay": "compact",
|
|
254
|
-
"contextFormat": "percent",
|
|
255
|
-
"contextGauge": false,
|
|
256
|
-
"showSessionName": true,
|
|
257
|
-
"showTimer": true,
|
|
258
|
-
"showCost": true,
|
|
259
|
-
"showGit": true,
|
|
260
|
-
"contextThresholds": {
|
|
261
|
-
"warning": 70,
|
|
262
|
-
"error": 90
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
"userMessages": {
|
|
268
|
-
"enabled": true,
|
|
269
|
-
"style": "framed",
|
|
270
|
-
"colorSource": "theme",
|
|
271
|
-
"styles": {
|
|
272
|
-
"framed": {},
|
|
273
|
-
"framed-copy-friendly": {},
|
|
274
|
-
"compact": {},
|
|
275
|
-
"labeled": {}
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
"workingLine": {
|
|
279
|
-
"enabled": false,
|
|
280
|
-
"turnSummary": true,
|
|
281
|
-
"spinner": "star-bloom",
|
|
282
|
-
"spinnerIntervalMs": 100,
|
|
283
|
-
"animateSpinnerColor": false,
|
|
284
|
-
"textIntervalMs": 60,
|
|
285
|
-
"textAnimation": "classic",
|
|
286
|
-
"colorSource": "theme",
|
|
287
|
-
"messages": {
|
|
288
|
-
"custom": true,
|
|
289
|
-
"values": [
|
|
290
|
-
"Sautéing…", "Cooking…", "Ionizing…", "Zigzagging…",
|
|
291
|
-
"Razzle-dazzling…", "Photosynthesizing…", "Nucleating…", "Brewing…",
|
|
292
|
-
"Combobulating…", "Boogieing…", "Befuddling…", "Alchemizing…",
|
|
293
|
-
"Conjuring…", "Baking…", "Simmering…", "Blanching…"
|
|
294
|
-
]
|
|
295
|
-
},
|
|
296
|
-
"segments": {
|
|
297
|
-
"tool": true,
|
|
298
|
-
"elapsed": true,
|
|
299
|
-
"thought": true,
|
|
300
|
-
"tokens": true
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
"selectorBorders": {
|
|
304
|
-
"enabled": true,
|
|
305
|
-
"style": "zentui",
|
|
306
|
-
"colorSource": "theme"
|
|
307
|
-
},
|
|
308
|
-
"footer": {
|
|
309
|
-
"style": "starship",
|
|
310
|
-
"colorSource": "theme",
|
|
311
|
-
"modelLabel": "id",
|
|
312
|
-
"styles": {
|
|
313
|
-
"starship": {
|
|
314
|
-
"format": "",
|
|
315
|
-
"responsive": true,
|
|
316
|
-
"compactFormat": "$cwd$wrap(in $session_name)$wrap(on $git_branch) $git_status$wrap$context$wrap_sep$tokens",
|
|
317
|
-
"compactMaxLines": 2,
|
|
318
|
-
"separator": "pipe",
|
|
319
|
-
"contextStyle": "text",
|
|
320
|
-
"contextThresholds": {
|
|
321
|
-
"warning": 70,
|
|
322
|
-
"error": 90
|
|
323
|
-
},
|
|
324
|
-
"pathDisplay": {
|
|
325
|
-
"mode": "basename",
|
|
326
|
-
"depth": 0
|
|
327
|
-
},
|
|
328
|
-
"segments": {
|
|
329
|
-
"cwd": true,
|
|
330
|
-
"sessionName": true,
|
|
331
|
-
"gitBranch": true,
|
|
332
|
-
"gitStatus": true,
|
|
333
|
-
"gitCounts": false,
|
|
334
|
-
"runtime": true,
|
|
335
|
-
"modelInfo": false,
|
|
336
|
-
"context": true,
|
|
337
|
-
"tokens": true,
|
|
338
|
-
"cost": true,
|
|
339
|
-
"sessionDuration": false,
|
|
340
|
-
"username": false,
|
|
341
|
-
"time": false,
|
|
342
|
-
"os": false,
|
|
343
|
-
"packageVersion": false,
|
|
344
|
-
"gitCommit": false,
|
|
345
|
-
"gitMetrics": false
|
|
346
|
-
},
|
|
347
|
-
"gitBranch": {
|
|
348
|
-
"maxLength": "full"
|
|
349
|
-
},
|
|
350
|
-
"gitCommit": {
|
|
351
|
-
"hashLength": 7,
|
|
352
|
-
"onlyDetached": true,
|
|
353
|
-
"showTag": true
|
|
354
|
-
},
|
|
355
|
-
"gitMetrics": {
|
|
356
|
-
"onlyNonzero": true,
|
|
357
|
-
"ignoreSubmodules": false
|
|
358
|
-
},
|
|
359
|
-
"extensionStatuses": {
|
|
360
|
-
"defaultPlacement": "right",
|
|
361
|
-
"placements": {},
|
|
362
|
-
"colorModes": {}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
"icons": {
|
|
369
|
-
"mode": "auto",
|
|
370
|
-
"cwd": "",
|
|
371
|
-
"git": "",
|
|
372
|
-
"ahead": "↑",
|
|
373
|
-
"behind": "↓",
|
|
374
|
-
"diverged": "⇕",
|
|
375
|
-
"conflicted": "=",
|
|
376
|
-
"untracked": "?",
|
|
377
|
-
"stashed": "$",
|
|
378
|
-
"modified": "!",
|
|
379
|
-
"staged": "+",
|
|
380
|
-
"renamed": "»",
|
|
381
|
-
"deleted": "✘",
|
|
382
|
-
"typechanged": "T",
|
|
383
|
-
"cacheHit": "",
|
|
384
|
-
"editorPrompt": "",
|
|
385
|
-
"rail": "│",
|
|
386
|
-
"username": "",
|
|
387
|
-
"time": "",
|
|
388
|
-
"os": ""
|
|
389
|
-
},
|
|
390
|
-
"colors": {
|
|
391
|
-
"cwd": "bold cyan",
|
|
392
|
-
"sessionName": "bold green",
|
|
393
|
-
"gitBranch": "bold purple",
|
|
394
|
-
"gitStatus": "bold red",
|
|
395
|
-
"contextNormal": "bright-black",
|
|
396
|
-
"contextWarning": "bold yellow",
|
|
397
|
-
"contextError": "bold red",
|
|
398
|
-
"tokens": "bright-black",
|
|
399
|
-
"cost": "bold green",
|
|
400
|
-
"extensionStatus": "bright-black",
|
|
401
|
-
"separator": "bright-black",
|
|
402
|
-
"runtimePrefix": "",
|
|
403
|
-
"sessionDuration": "yellow",
|
|
404
|
-
"packageVersion": "208",
|
|
405
|
-
"gitCommit": "bold green",
|
|
406
|
-
"gitMetricsAdded": "bold green",
|
|
407
|
-
"gitMetricsDeleted": "bold red",
|
|
408
|
-
"username": "bold yellow",
|
|
409
|
-
"time": "bold yellow",
|
|
410
|
-
"os": "bold white",
|
|
411
|
-
"editorAccent": "accent",
|
|
412
|
-
"editorPrompt": "accent",
|
|
413
|
-
"editorBorder": "borderMuted",
|
|
414
|
-
"editorModel": "accent",
|
|
415
|
-
"editorProvider": "text",
|
|
416
|
-
"editorThinking": "muted",
|
|
417
|
-
"editorThinkingMinimal": "thinkingMinimal",
|
|
418
|
-
"editorThinkingLow": "thinkingLow",
|
|
419
|
-
"editorThinkingMedium": "thinkingMedium",
|
|
420
|
-
"editorThinkingHigh": "thinkingHigh",
|
|
421
|
-
"editorThinkingXhigh": "thinkingXhigh"
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
- Style values can be Starship/terminal strings (`bold purple`, `fg:202`, `#89b` / `#89b4fa`, `bg:blue fg:bright-green`) or Pi theme tokens (`accent`, `borderMuted`, `thinkingHigh`). Short `#rgb` hex values expand to `#rrggbb`.
|
|
427
|
-
- `projectRefreshIntervalMs`: project status polling interval; `0` disables polling. Values `1..4999` clamp up to `5000` (minimum 5s); invalid/non-finite values fall back to `30000`.
|
|
428
|
-
- `components.editor`: owns editor enablement, `opencode | opencode-copy-friendly | minimalist` style selection, color source, border mode, model label, viewport indicators, and all three editor-style configurations.
|
|
429
|
-
- `components.userMessages`: owns message enablement, `framed | framed-copy-friendly | compact | labeled` style selection, and color source. `framed-copy-friendly` remains Zentui-rendered; disabling the component delegates to Pi's native renderer.
|
|
430
|
-
- `components.workingLine`: `enabled` is the sole ownership switch. While enabled, Zentui owns both the Working-row message and indicator and renders the full row. It configures `braille | star-bloom | pinwheel | claude-inspired | pulse`, independent spinner/text speeds, optional Classic/KITT spinner-color participation, `classic | kitt | disabled` text animation, color source, the default-on `messages.custom` toggle and editable 16-value list, plus Tool/Elapsed/Thinking/Tokens segments. Thinking only controls the live row; measurement and final summaries continue while it is hidden. Custom-off and empty-list fallback both render owned `Working…`; Static keeps glyph motion but ignores text speed and spinner-color participation.
|
|
431
|
-
- Optional `colors.workingLineLow`, `colors.workingLineMid`, and `colors.workingLineHigh` override its palette. Without overrides, theme mode uses `dim`, `muted`, and `bold accent`; terminal mode uses `bright-black`, `cyan`, and `bold cyan`.
|
|
432
|
-
- `components.selectorBorders`: owns selector-border enablement, the fixed `zentui` style, and its color source.
|
|
433
|
-
- `components.footer`: owns `native | starship | hidden` style selection, Footer color source, Footer model label, and every Starship option under `styles.starship` (formats, segments, context thresholds, path, Git, and extension statuses). Native restores Pi's built-in Footer; Hidden installs an empty component with zero rows.
|
|
434
|
-
- Editor and Footer `modelLabel` values are independent and have separate controls in the **Editor** and **Footer** sections.
|
|
435
|
-
- Selector borders support only `zentui`; set their owning `enabled` field to `false` for native Pi behavior.
|
|
436
|
-
- Flat released keys such as `editorStyle`, `features`, and `footerFormat` remain accepted as migration input. `components.footer.enabled` and `features.statusLine` migrate to Starship or Native when no valid Footer style is present; Hidden projects `features.statusLine: false`. Canonical `components` paths are the primary JSON interface, and component saves materialize canonical snapshots.
|
|
437
|
-
- Explicit unsupported future component style IDs are preserved unchanged on disk but fail open at runtime: Editor, User-message, and selector-border customization stay disabled, while Footer behavior is Native. Missing, empty, or malformed style values continue normal default and legacy migration behavior.
|
|
438
|
-
- The flat properties returned by `mergeConfig`, `loadConfig`, and save helpers are deprecated compatibility output and will remain available until at least the next major release. This output deprecation is separate from accepted legacy flat JSON input.
|
|
439
|
-
- `polished` and `polished-copy-friendly` remain read-only migration aliases for `opencode` and `opencode-copy-friendly`. Legacy `features.copyFriendly` and the old nested Editor/message `copyFriendly` fields are read-only migration inputs: message copy-friendly `true` selects `framed-copy-friendly` rather than disabling custom rendering. Explicit Editor or User-message style saves remove only the corresponding obsolete nested flag; raw released feature keys, unknown fields, and unknown style data remain preserved as user-owned migration data.
|
|
440
|
-
- The shown `editor*` values match the default `theme` source. Omit those keys to keep Zentui's source-aware defaults when switching between `theme` and `terminal`.
|
|
441
|
-
- `editorAccent` styles Editor and User-message accent rails and the labeled message label.
|
|
442
|
-
- `editorPrompt` styles the `opencode-copy-friendly` Editor prompt glyph. Omit it to use `editorAccent`, then the default accent fallback.
|
|
443
|
-
- `editorBorder` styles the `framed` and `framed-copy-friendly` previous-message top/bottom borders and the active editor in static border color mode; the border glyph stays `─`.
|
|
444
|
-
- `editorGitBranch` and `editorThinkingMax` are optional editor-owned overrides, omitted above so source-specific and adaptive defaults remain active. `editorGitBranch` owns the minimalist Editor branch color independently from Footer `gitBranch`; where Zentui resolves configured thinking colors, `max` falls back through `editorThinkingXhigh` and then `editorThinking`.
|
|
445
|
-
- `editorModel`, `editorProvider`, and `editorThinking*` style the editor metadata. `editorThinking` applies to every non-`off` thinking level unless a level-specific key is set.
|
|
446
|
-
|
|
447
|
-
Tip: with `opencode-copy-friendly`, setting Pi's `editorPaddingX` to `1` in `~/.pi/agent/settings.json` keeps a small left gutter without copying a rail glyph.
|
|
448
|
-
|
|
449
|
-
## Minimalist editor style
|
|
450
|
-
|
|
451
|
-
Set `components.editor.style` to `minimalist` or select it from the `/zentui` **Editor** tab. The rounded frame shows viewport counts, Bash state, the current/completed turn duration, and the explicit Pi session name at top left; cost, model, thinking level, and context usage at top right; viewport count plus Git branch/status at bottom left; and the configured path at bottom right. Unnamed sessions add no placeholder. Autocomplete stays inside the frame when Pi's existing editor output can be split safely. Unknown third-party editor layouts fail open without decoration.
|
|
452
|
-
|
|
453
|
-
The Minimalist editor is inspired by [pi-custom-input](https://github.com/VinhLe1410/pi-custom-input), with an independent implementation in Zentui.
|
|
454
|
-
|
|
455
|
-
While `minimalist` is selected, the `/zentui` **Editor** area shows its focused controls without repeating the style name on every row. Path examples are `src` (`compact`), `zentui/src` (`project`), and `~/Projects/zentui/src` (`full`). Context can render as `11%`, `11%/372k`, or—with the gauge enabled and enough room—`[█░░░░] 11%/372k`. The gauge shortens or disappears before the context text at narrow widths. Session name, timer, cost, and Git can be hidden independently; model, thinking, and context remain structurally stable.
|
|
456
|
-
|
|
457
|
-
Footer visibility is controlled by `components.footer.style`: use `starship`, `native`, or `hidden`. Minimalist editor decoration and the Starship Footer may be shown together, including at narrow widths or after decoration fallback. Minimalist style does not remove Pi's header.
|
|
458
|
-
|
|
459
|
-
## Editor Metadata Format
|
|
460
|
-
|
|
461
|
-
Set `metadataFormat` under either opencode style in `~/.pi/agent/zentui.json` to customize that style's metadata row. The two variants retain independent values:
|
|
462
|
-
|
|
463
|
-
```json
|
|
464
|
-
{
|
|
465
|
-
"components": {
|
|
466
|
-
"editor": {
|
|
467
|
-
"styles": {
|
|
468
|
-
"opencode": {
|
|
469
|
-
"metadataFormat": "$model_name ($model_id)( · $provider)( · $thinking)( · $session_name)"
|
|
470
|
-
},
|
|
471
|
-
"opencode-copy-friendly": {
|
|
472
|
-
"metadataFormat": "$model( · $provider)"
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
93
|
+
~/.pi/agent/zentui.json
|
|
478
94
|
```
|
|
479
95
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
| Token | Renders |
|
|
483
|
-
| --------------- | --------------------------------------------------------------------------------------------- |
|
|
484
|
-
| `$model` | label selected by `components.editor.modelLabel` (`id`, or name with ID fallback) |
|
|
485
|
-
| `$model_id` | active Pi model ID |
|
|
486
|
-
| `$model_name` | active Pi model display name; empty when no name is set |
|
|
487
|
-
| `$provider` | provider label using Zentui's existing formatting |
|
|
488
|
-
| `$thinking` | current thinking level; empty when thinking is `off` |
|
|
489
|
-
| `$session_name` | current Pi session name; empty when unnamed |
|
|
490
|
-
|
|
491
|
-
Model variables use `editorModel`, provider uses `editorProvider`, and thinking uses the matching `editorThinking*` style. Literal text and `$session_name` use the neutral editor border theme style. The template controls spacing. ANSI/VT sequences, control characters, and line-breaking whitespace are sanitized before rendering without collapsing ordinary spaces.
|
|
492
|
-
|
|
493
|
-
Missing, non-string, or empty values use the default `$model $provider( $thinking)`. A non-empty format that resolves to no visible metadata keeps the normal blank spacer and metadata rows so the editor frame height remains stable. This option is configured only through JSON in its first version; `/zentui format` continues to control the footer only.
|
|
494
|
-
|
|
495
|
-
## Footer Format Template
|
|
496
|
-
|
|
497
|
-
For full control, set `components.footer.styles.starship.format` to a Starship-style template string. It supports `$variable` and `${variable}` tokens, a special `$fill` token that splits the line into left and right zones, and conditional groups `( ... )` that drop entirely when every nested variable is empty. When set, it overrides `components.footer.styles.starship.segments`; when empty or omitted, the segment layout above is used.
|
|
498
|
-
|
|
499
|
-
A second `$fill` creates a **centered middle zone** — content between the two fills is true-centered (`floor((gap - middle) / 2)`), just like third-party statuses placed `middle`.
|
|
96
|
+
A small starter config:
|
|
500
97
|
|
|
501
98
|
```json
|
|
502
99
|
{
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
100
|
+
"components": {
|
|
101
|
+
"editor": {
|
|
102
|
+
"enabled": true,
|
|
103
|
+
"style": "accent-rail"
|
|
104
|
+
},
|
|
105
|
+
"userMessages": {
|
|
106
|
+
"enabled": true,
|
|
107
|
+
"style": "framed"
|
|
108
|
+
},
|
|
109
|
+
"workingLine": {
|
|
110
|
+
"enabled": false
|
|
111
|
+
},
|
|
112
|
+
"footer": {
|
|
113
|
+
"style": "starship"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"icons": {
|
|
117
|
+
"mode": "auto"
|
|
118
|
+
}
|
|
512
119
|
}
|
|
513
120
|
```
|
|
514
121
|
|
|
515
|
-
|
|
122
|
+
Detailed reference:
|
|
516
123
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
"components": {
|
|
520
|
-
"footer": {
|
|
521
|
-
"styles": {
|
|
522
|
-
"starship": {
|
|
523
|
-
"format": "$cwd $fill $git_branch $fill $cost"
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
```
|
|
124
|
+
- [Configuration, component styles, defaults, runtime detection, and compatibility](https://github.com/lmilojevicc/pi-zentui/blob/main/docs/configuration.md)
|
|
125
|
+
- [Footer format template and variables](https://github.com/lmilojevicc/pi-zentui/blob/main/docs/footer-format.md)
|
|
530
126
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
### Variables
|
|
534
|
-
|
|
535
|
-
| Token | Aliases | Renders |
|
|
536
|
-
| ------------------- | ------------ | ------------------------------------------------------------------- |
|
|
537
|
-
| `$cwd` | `$directory` | current directory |
|
|
538
|
-
| `$session_name` | | current Pi session name |
|
|
539
|
-
| `$git_branch` | `$branch` | git branch with icon |
|
|
540
|
-
| `$git_status` | `$status` | `[!?↑]` status block |
|
|
541
|
-
| `$git_state` | `$state` | `REBASING` / `MERGING` / … (optional `n/m`) |
|
|
542
|
-
| `$git_commit` | `$commit` | short commit hash (+ exact-match tag when present) |
|
|
543
|
-
| `$git_tag` | `$tag` | exact-match tag at HEAD |
|
|
544
|
-
| `$git_metrics` | | aggregate line changes `+added −deleted` |
|
|
545
|
-
| `$git_added` | | added line count (`+N`) |
|
|
546
|
-
| `$git_deleted` | | deleted line count (`−N`) |
|
|
547
|
-
| `$runtime` | | runtime icon + version |
|
|
548
|
-
| `$model` | | selected model label (`components.footer.modelLabel`) |
|
|
549
|
-
| `$provider` | | formatted provider label |
|
|
550
|
-
| `$package` | | project package version, `is <glyph> <version>` (manifest-derived) |
|
|
551
|
-
| `$package_version` | | raw project package version (no icon) |
|
|
552
|
-
| `$session_duration` | `$duration` | session running time |
|
|
553
|
-
| `$username` | | `user@host` |
|
|
554
|
-
| `$os` | | operating-system icon |
|
|
555
|
-
| `$time` | | current time `HH:MM` |
|
|
556
|
-
| `$context` | | context usage (text and/or gauge; finite percentages use one decimal) |
|
|
557
|
-
| `$tokens` | | input/output counts and existing cache-hit percentage |
|
|
558
|
-
| `$cache_read` | | cache-read total (`R1.2k`); empty at zero or when unavailable |
|
|
559
|
-
| `$cache_write` | | cache-write total (`W300`); empty at zero or when unavailable |
|
|
560
|
-
| `$cost` | | session cost |
|
|
561
|
-
| `$subscription` | | `(sub)` in subscription mode; otherwise empty |
|
|
562
|
-
| `$auto_compaction` | | `(auto)` when automatic compaction is enabled; otherwise empty |
|
|
563
|
-
| `$sep` | `$separator` | themed `\|` using `colors.separator` |
|
|
564
|
-
| `$fill` | — | special: splits zones |
|
|
565
|
-
|
|
566
|
-
### `$fill` behavior
|
|
567
|
-
|
|
568
|
-
| `$fill` count | Layout |
|
|
569
|
-
| ------------- | ------------------------------------------------------------------------ |
|
|
570
|
-
| 0 | everything left-aligned |
|
|
571
|
-
| 1 | tokens before → left, tokens after → right |
|
|
572
|
-
| 2 | before first → left, between → **centered middle**, after second → right |
|
|
573
|
-
| 3+ | first two count; extras ignored |
|
|
574
|
-
|
|
575
|
-
- Literal text (`on branch`, `using`, `\|`, spaces) is rendered verbatim — you control all spacing.
|
|
576
|
-
- Each variable renders its core value only (no `on`/`via` prefixes); add those words as literal text.
|
|
577
|
-
- Conditional groups: wrap optional pieces in parentheses, e.g. `$cwd( on $git_branch)($git_status)$fill($context)`. If every `$var` inside a group is empty, the whole group (including its literals) is dropped.
|
|
578
|
-
- `$session_name` is available whenever `components.footer.styles.starship.format` is set, independently of `components.footer.styles.starship.segments.sessionName`; use a conditional group such as `($sep$session_name)` so unnamed sessions leave no separator.
|
|
579
|
-
- The built-in wide footer appends cache totals to the token segment, `(sub)` to cost, and `(auto)` to context when available. Custom formats keep `$tokens`, `$cost`, and `$context` backward-compatible and include telemetry only through the atomic variables above.
|
|
580
|
-
- `DEFAULT_COMPACT_FOOTER_FORMAT` omits model/provider and atomic telemetry. Add their variables explicitly to `components.footer.styles.starship.compactFormat` to opt in at narrow widths. The flat `compactFooterFormat` key is a legacy migration input.
|
|
581
|
-
- Auto-compaction settings refresh on the next normal footer synchronization event. Unsupported Pi capabilities or settings-read errors safely omit optional markers.
|
|
582
|
-
- Unknown `$variables` render empty.
|
|
583
|
-
- Set or clear at runtime: `/zentui format "<template>"` and `/zentui format clear`.
|
|
584
|
-
|
|
585
|
-
## Pi fullscreen mode
|
|
586
|
-
|
|
587
|
-
Pi 0.84 introduces a native fullscreen TUI with a sticky editor and Footer plus an independently scrollable transcript. Enable it in Pi's `~/.pi/agent/settings.json`:
|
|
127
|
+
Useful shortcuts:
|
|
588
128
|
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
129
|
+
```text
|
|
130
|
+
/zentui editor toggle
|
|
131
|
+
/zentui messages toggle
|
|
132
|
+
/zentui working-line
|
|
133
|
+
/zentui statusline toggle
|
|
134
|
+
/zentui viewport-indicators toggle
|
|
135
|
+
/zentui format "$cwd on branch $git_branch$git_status using $runtime $fill $context"
|
|
136
|
+
/zentui format clear
|
|
593
137
|
```
|
|
594
138
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
## Acknowledgments
|
|
598
|
-
|
|
599
|
-
The minimalist frame's information hierarchy was inspired by [VinhLe1410/pi-custom-input](https://github.com/VinhLe1410/pi-custom-input) and is integrated with Zentui's existing editor, state, configuration, and compatibility layers.
|
|
139
|
+
Pi 0.84 also provides a native fullscreen TUI with a sticky editor and Footer. Zentui does not enable it automatically; select fullscreen from Pi's `/settings`, set `"tuiMode": "fullscreen"` in Pi settings, or launch Pi with `--tui-mode fullscreen`.
|
|
600
140
|
|
|
601
141
|
## Requirements
|
|
602
142
|
|
|
603
143
|
- [Pi](https://pi.dev) coding agent 0.80.5 or newer
|
|
604
|
-
- A [Nerd Font](https://www.nerdfonts.com/) for icons
|
|
144
|
+
- A [Nerd Font](https://www.nerdfonts.com/) for icons, or `icons.mode: "ascii"`
|
|
605
145
|
|
|
606
146
|
## Development
|
|
607
147
|
|
|
608
148
|
```bash
|
|
609
149
|
npm install
|
|
610
|
-
npm run verify
|
|
611
150
|
npm run fmt
|
|
151
|
+
npm run verify
|
|
612
152
|
npm run pack:check
|
|
613
153
|
```
|
|
614
154
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
The project keeps Pi core packages as peer dependencies for runtime and dev dependencies for
|
|
618
|
-
typechecking. To avoid accidentally running the local `node_modules/.bin/pi` shim, the dev scripts use
|
|
619
|
-
the globally installed Pi binary by default:
|
|
155
|
+
Run Pi with only the local extension:
|
|
620
156
|
|
|
621
157
|
```bash
|
|
622
158
|
npm run pi:dev
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Install the checkout as a local Pi package:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
623
164
|
npm run pi:install-local
|
|
624
165
|
```
|
|
625
166
|
|
|
626
|
-
Override the
|
|
167
|
+
Override the globally installed Pi binary when needed:
|
|
627
168
|
|
|
628
169
|
```bash
|
|
629
170
|
PI_BIN=/path/to/pi npm run pi:dev
|
|
630
171
|
```
|
|
631
172
|
|
|
632
|
-
|
|
173
|
+
See [CONTRIBUTING.md](https://github.com/lmilojevicc/pi-zentui/blob/main/CONTRIBUTING.md) for manual UI-test and pull-request expectations.
|
|
174
|
+
|
|
175
|
+
## Inspiration and credits
|
|
633
176
|
|
|
634
|
-
|
|
177
|
+
- [Starship](https://starship.rs/) — inspiration for the informative, segment-based Footer
|
|
178
|
+
- [Opencode](https://github.com/anomalyco/opencode) — inspiration for the Opencode editor treatment
|
|
179
|
+
- [Oh My Pi (`omp`)](https://github.com/can1357/oh-my-pi) by [Can Bölük](https://github.com/can1357) — visual inspiration for the filled, single-left-rail Accent Rail editor
|
|
180
|
+
- [Pi Custom Input](https://github.com/VinhLe1410/pi-custom-input) by [Vinh Le](https://github.com/VinhLe1410) — visual inspiration for Minimalist's framed, border-embedded session, model, context, Git, and path metadata
|
|
635
181
|
|
|
636
|
-
|
|
637
|
-
- [Opencode](https://github.com/opencode-ai/opencode) — terminal-based AI coding assistant
|
|
182
|
+
Zentui's implementations are independent; these credits acknowledge product and visual inspiration rather than source-code reuse.
|
|
638
183
|
|
|
639
184
|
## License
|
|
640
185
|
|
|
641
|
-
MIT
|
|
186
|
+
Zentui is licensed under the MIT License. Wallpaper photo by [Mohammad Alizade](https://unsplash.com/@mohamadaz) on [Unsplash](https://unsplash.com/photos/SB5MIXFjJxs), used under the [Unsplash License](https://unsplash.com/license). The photograph appearing in showcase screenshots is not relicensed under MIT.
|