pi-zentui 0.3.0 → 0.3.2

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 CHANGED
@@ -163,7 +163,8 @@ Default config values — copy this and change any value you want:
163
163
  "deleted": "✘",
164
164
  "typechanged": "T",
165
165
  "cacheHit": "󰆼",
166
- "editorPrompt": ""
166
+ "editorPrompt": "",
167
+ "rail": "│"
167
168
  },
168
169
  "colors": {
169
170
  "cwd": "bold cyan",
@@ -218,7 +219,7 @@ Default config values — copy this and change any value you want:
218
219
 
219
220
  - Style values can be Starship/terminal strings (`bold purple`, `fg:202`, `#89b4fa`, `bg:blue fg:bright-green`) or Pi theme tokens (`accent`, `borderMuted`, `thinkingHigh`).
220
221
  - `projectRefreshIntervalMs`: project status polling interval; `0` disables polling.
221
- - `icons`: every shown icon key is configurable; omit any key to use the Zentui default. `editorPrompt` controls an optional copy-friendly editor prompt glyph; the default is `""` so copy-friendly mode stays rail-free.
222
+ - `icons`: every shown icon key is configurable; omit any key to use the Zentui default. `rail` sets the vertical glyph drawn as the left rail of the active editor frame and previous user messages when `copyFriendly` is disabled (default `│`; any single Unicode vertical or block glyph). `editorPrompt` controls an optional copy-friendly editor prompt glyph; the default is `""` so copy-friendly mode stays rail-free.
222
223
  - `colorSources`: `theme` maps styles through Pi theme tokens; `terminal` emits terminal colors. `/zentui` switches these sources; manual JSON controls specific style values.
223
224
  - `features`: `editor` enables Zentui's custom editor, selector borders, and previous-message chrome. `statusLine` enables Zentui's custom footer/status line. `copyFriendly` hides editor and previous-message rail glyphs so native terminal selection copies less chrome. All three can be changed from `/zentui` or direct slash-command arguments.
224
225
  - `footerSegments`: show or hide individual built-in footer segments (`cwd`, `gitBranch`, `gitStatus`, `runtime`, `context`, `tokens`, `cost`). Toggle them from the `Built-in segments` tab in `/zentui`.
@@ -60,6 +60,7 @@ export type PolishedTuiConfig = {
60
60
  typechanged: string;
61
61
  cacheHit: string;
62
62
  editorPrompt: string;
63
+ rail: string;
63
64
  };
64
65
  colors: {
65
66
  cwd: ColorSpec;
@@ -111,6 +112,7 @@ export const defaultConfig: PolishedTuiConfig = {
111
112
  typechanged: "T",
112
113
  cacheHit: "󰆼",
113
114
  editorPrompt: "",
115
+ rail: "│",
114
116
  },
115
117
  colors: {
116
118
  cwd: "bold cyan",
@@ -187,6 +189,10 @@ function parseProjectRefreshIntervalMs(value: unknown): number {
187
189
  : defaultConfig.projectRefreshIntervalMs;
188
190
  }
189
191
 
192
+ function railValue(value: unknown): string {
193
+ return typeof value === "string" && value.trim().length > 0 ? value : defaultConfig.icons.rail;
194
+ }
195
+
190
196
  function stringValue(record: Record<string, unknown>, key: string): string | undefined {
191
197
  const value = record[key];
192
198
  return typeof value === "string" ? value : undefined;
@@ -394,9 +400,8 @@ export function ensureConfigExists(): void {
394
400
 
395
401
  export function mergeConfig(parsed: unknown): PolishedTuiConfig {
396
402
  const config = isRecord(parsed) ? parsed : {};
397
- const icons = isRecord(config.icons)
398
- ? normalizeIcons(config.icons as Record<string, unknown>)
399
- : {};
403
+ const iconsRecord = isRecord(config.icons) ? (config.icons as Record<string, unknown>) : {};
404
+ const icons = normalizeIcons(iconsRecord);
400
405
  const colors = isRecord(config.colors)
401
406
  ? normalizeColors(config.colors as Record<string, unknown>)
402
407
  : {};
@@ -417,6 +422,7 @@ export function mergeConfig(parsed: unknown): PolishedTuiConfig {
417
422
  icons: {
418
423
  ...defaultConfig.icons,
419
424
  ...icons,
425
+ rail: railValue(iconsRecord.rail),
420
426
  },
421
427
  colors: {
422
428
  ...defaultConfig.colors,
@@ -1,7 +1,7 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
3
  import type { PolishedTuiConfig } from "./config";
4
- import { type ExtensionStatusSegment, collectExtensionStatusSegments } from "./extension-status";
4
+ import { collectExtensionStatusSegments, type ExtensionStatusSegment } from "./extension-status";
5
5
  import { formatCwdLabel, formatRuntimeSegment } from "./format";
6
6
  import type { FooterState } from "./state";
7
7
  import { renderStyleForSource } from "./style";
@@ -9,29 +9,29 @@ import {
9
9
  type ColorSourcesConfig,
10
10
  type ExtensionStatusColorMode,
11
11
  type ExtensionStatusPlacement,
12
- type FooterSegmentsConfig,
13
- type PolishedTuiConfig,
14
- type UiFeaturesConfig,
15
12
  ensureConfigExists,
13
+ type FooterSegmentsConfig,
16
14
  loadConfig,
15
+ type PolishedTuiConfig,
17
16
  saveColorSourcesPatch,
18
17
  saveExtensionStatusColorMode,
19
18
  saveExtensionStatusPlacement,
20
19
  saveFooterSegmentsPatch,
21
20
  saveUiFeaturesPatch,
21
+ type UiFeaturesConfig,
22
22
  } from "./config";
23
23
  import { installFooter } from "./footer";
24
24
  import { emptyGitStatus, readGitStatus } from "./git";
25
25
  import {
26
+ createProjectRefreshScheduler,
26
27
  type ScheduleProjectRefreshOptions,
27
28
  type StopProjectRefreshInterval,
28
- createProjectRefreshScheduler,
29
29
  startProjectRefreshInterval,
30
30
  } from "./project-refresh";
31
31
  import { readRuntimeInfo } from "./runtime";
32
32
  import { installSelectorBorderStyle } from "./selector-border";
33
33
  import { registerZentuiSettingsCommand } from "./settings-command";
34
- import { type FooterState, createInitialState, syncState } from "./state";
34
+ import { createInitialState, type FooterState, syncState } from "./state";
35
35
  import { PolishedEditor, WrappedPolishedEditor } from "./ui";
36
36
  import { installUserMessageStyle } from "./user-message";
37
37
 
@@ -60,8 +60,12 @@ function getZentuiEditorBaseFactory(factory: EditorFactory | undefined): EditorF
60
60
  }
61
61
 
62
62
  function isTuiContext(ctx: ExtensionContext): boolean {
63
- const mode = (ctx as ExtensionContext & { mode?: string }).mode;
64
- return ctx.hasUI && (mode === undefined || mode === "tui");
63
+ try {
64
+ const mode = (ctx as ExtensionContext & { mode?: string }).mode;
65
+ return ctx.hasUI && (mode === undefined || mode === "tui");
66
+ } catch {
67
+ return false;
68
+ }
65
69
  }
66
70
 
67
71
  export default function (pi: ExtensionAPI) {
@@ -3,10 +3,10 @@ import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
3
3
  import {
4
4
  type AutocompleteItem,
5
5
  Key,
6
+ matchesKey,
6
7
  type SettingItem,
7
8
  SettingsList,
8
9
  type SettingsListTheme,
9
- matchesKey,
10
10
  truncateToWidth,
11
11
  } from "@earendil-works/pi-tui";
12
12
  import {
@@ -15,12 +15,12 @@ import {
15
15
  type ExtensionStatusColorMode,
16
16
  type ExtensionStatusPlacement,
17
17
  type FooterSegmentsConfig,
18
- type PolishedTuiConfig,
19
- type UiFeaturesConfig,
20
18
  getExtensionStatusColorMode,
21
19
  getExtensionStatusPlacement,
22
20
  isExtensionStatusColorMode,
23
21
  isExtensionStatusPlacement,
22
+ type PolishedTuiConfig,
23
+ type UiFeaturesConfig,
24
24
  } from "./config";
25
25
  import { sanitizeExtensionStatusText } from "./extension-status";
26
26
  import { EDITOR_BORDER_STYLE, renderChromeBorder, safeThemeFg } from "./style";
@@ -111,7 +111,7 @@ function getEditorChromeWidths(config: PolishedTuiConfig, uiTheme: Theme, reset:
111
111
  config.colorSources.editor,
112
112
  config.colors.editorAccent,
113
113
  EDITOR_ACCENT_FALLBACK,
114
- "│",
114
+ config.icons.rail,
115
115
  )}${reset} `;
116
116
  return {
117
117
  prompt,
@@ -87,6 +87,7 @@ function getUserMessageConfigKey(config: PolishedTuiConfig): string {
87
87
  config.colorSources.userMessages,
88
88
  config.colors.editorAccent ?? "",
89
89
  config.colors.editorBorder ?? "",
90
+ config.icons.rail,
90
91
  ].join("\0");
91
92
  }
92
93
 
@@ -126,6 +127,7 @@ function fillLine(content: string, width: number): string {
126
127
 
127
128
  function renderPromptBoxRail(theme: Theme | undefined, config: PolishedTuiConfig): string {
128
129
  if (config.features.copyFriendly) return "";
130
+ const railGlyph = config.icons.rail;
129
131
 
130
132
  return `${
131
133
  theme
@@ -134,9 +136,9 @@ function renderPromptBoxRail(theme: Theme | undefined, config: PolishedTuiConfig
134
136
  config.colorSources.userMessages,
135
137
  config.colors.editorAccent,
136
138
  EDITOR_ACCENT_FALLBACK,
137
- "│",
139
+ railGlyph,
138
140
  )
139
- : "│"
141
+ : railGlyph
140
142
  } `;
141
143
  }
142
144
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-zentui",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A Starship-inspired statusline and Opencode-style TUI for Pi.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,8 +12,16 @@
12
12
  "bugs": {
13
13
  "url": "https://github.com/lmilojevicc/pi-zentui/issues"
14
14
  },
15
- "keywords": ["pi-package", "pi-extension", "pi-theme", "starship", "tui"],
16
- "files": ["extensions"],
15
+ "keywords": [
16
+ "pi-package",
17
+ "pi-extension",
18
+ "pi-theme",
19
+ "starship",
20
+ "tui"
21
+ ],
22
+ "files": [
23
+ "extensions"
24
+ ],
17
25
  "scripts": {
18
26
  "lint": "biome check .",
19
27
  "typecheck": "tsc --noEmit",
@@ -32,18 +40,20 @@
32
40
  "@earendil-works/pi-tui": "*"
33
41
  },
34
42
  "pi": {
35
- "extensions": ["./extensions"],
43
+ "extensions": [
44
+ "./extensions"
45
+ ],
36
46
  "image": "https://raw.githubusercontent.com/lmilojevicc/pi-zentui/main/assets/zentui.png"
37
47
  },
38
48
  "publishConfig": {
39
49
  "access": "public"
40
50
  },
41
51
  "devDependencies": {
42
- "@biomejs/biome": "^1.9.4",
52
+ "@biomejs/biome": "^2.5.0",
43
53
  "@earendil-works/pi-ai": "^0.79.3",
44
54
  "@earendil-works/pi-coding-agent": "^0.79.3",
45
55
  "@earendil-works/pi-tui": "^0.79.3",
46
- "@types/node": "^25.5.2",
56
+ "@types/node": "^26.0.0",
47
57
  "typescript": "^6.0.2",
48
58
  "vitest": "^4.1.8"
49
59
  }