pi-zen 0.1.0 → 0.1.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
@@ -22,6 +22,8 @@ For real knowledge work, I like being an active participant. I want to understan
22
22
 
23
23
  ## Quick start
24
24
 
25
+ Requires Pi 0.84.3 or newer.
26
+
25
27
  Install the extension from npm:
26
28
 
27
29
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-zen",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A quiet Pi TUI on one switch: backgroundless messages, a rail editor, compact tool calls, and restrained reasoning",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.21.0",
@@ -29,6 +29,7 @@
29
29
  "files": [
30
30
  "extensions",
31
31
  "src",
32
+ "screenshots",
32
33
  "README.md",
33
34
  "LICENSE"
34
35
  ],
@@ -45,12 +46,12 @@
45
46
  ]
46
47
  },
47
48
  "peerDependencies": {
48
- "@earendil-works/pi-coding-agent": "*",
49
- "@earendil-works/pi-tui": "*"
49
+ "@earendil-works/pi-coding-agent": ">=0.84.3",
50
+ "@earendil-works/pi-tui": ">=0.84.3"
50
51
  },
51
52
  "devDependencies": {
52
- "@earendil-works/pi-coding-agent": "0.84.3",
53
- "@earendil-works/pi-tui": "0.84.3",
53
+ "@earendil-works/pi-coding-agent": "0.85.0",
54
+ "@earendil-works/pi-tui": "0.85.0",
54
55
  "@oxlint/plugins": "^1.79.0",
55
56
  "@types/node": "^24.10.0",
56
57
  "oxlint": "^1.79.0",
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- import { Theme, type ThemeColor } from "@earendil-works/pi-coding-agent";
1
+ import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  /** Name used only while Zen's backgroundless projection is active. */
4
4
  export const BACKGROUNDLESS_THEME_NAME = "pi-zen:backgroundless";
@@ -53,11 +53,14 @@ const THEME_COLORS = [
53
53
  "bashMode",
54
54
  ] as const satisfies ReadonlyArray<ThemeColor>;
55
55
 
56
- type ThemeBackground = Parameters<Theme["bg"]>[0];
56
+ type ThemeBackground = Parameters<Theme["bg"]>[0] | "scrollbarThumb";
57
+
58
+ type LegacyScrollbarTheme = {
59
+ readonly getBgAnsi: (color: ThemeBackground) => string;
60
+ };
57
61
 
58
62
  const THEME_BACKGROUNDS = [
59
63
  "selectedBg",
60
- "scrollbarThumb",
61
64
  "searchMatchBg",
62
65
  "userMessageBg",
63
66
  "customMessageBg",
@@ -98,11 +101,32 @@ function emptyBackgrounds(): BackgroundInput {
98
101
  return Object.fromEntries(THEME_BACKGROUNDS.map((color) => [color, ""])) as BackgroundInput;
99
102
  }
100
103
 
104
+ function captureScrollbarColors(
105
+ source: Theme,
106
+ foregroundAnsi: Map<ThemeColor, string>,
107
+ backgroundAnsi: Map<ThemeBackground, string>,
108
+ ): void {
109
+ let thumb: string;
110
+ try {
111
+ thumb = source.getFgAnsi("scrollbarThumb");
112
+ } catch (error) {
113
+ if (!(error instanceof Error) || error.message !== "Unknown theme color: scrollbarThumb") throw error;
114
+ // SAFETY: Pi 0.84.x reports this missing foreground because its thumb is a background token.
115
+ // The current Theme type omits that legacy key; its getter still checks the key at runtime.
116
+ const legacySource = source as LegacyScrollbarTheme;
117
+ backgroundAnsi.set("scrollbarThumb", legacySource.getBgAnsi("scrollbarThumb"));
118
+ return;
119
+ }
120
+ foregroundAnsi.set("scrollbarThumb", thumb);
121
+ foregroundAnsi.set("scrollbarTrack", source.getFgAnsi("scrollbarTrack"));
122
+ }
123
+
101
124
  function makeThemeSnapshot(source: Theme, options: ThemeSnapshotOptions): Theme {
102
125
  const foregroundAnsi = new Map<ThemeColor, string>();
103
126
  const backgroundAnsi = new Map<ThemeBackground, string>();
104
127
  for (const color of THEME_COLORS) foregroundAnsi.set(color, source.getFgAnsi(color));
105
128
  for (const color of THEME_BACKGROUNDS) backgroundAnsi.set(color, source.getBgAnsi(color));
129
+ captureScrollbarColors(source, foregroundAnsi, backgroundAnsi);
106
130
 
107
131
  // SAFETY: Pi created source, so its constructor is the runtime's Theme constructor. Using that exact constructor
108
132
  // keeps instanceof checks valid when this source package has a different development copy of Pi installed.
@@ -120,16 +144,17 @@ function makeThemeSnapshot(source: Theme, options: ThemeSnapshotOptions): Theme
120
144
  if (ansi === undefined) throw new Error(`Unknown theme color: ${color}`);
121
145
  return ansi;
122
146
  };
123
- snapshot.getBgAnsi = (color: ThemeBackground): string => {
147
+ const getBgAnsi = (color: ThemeBackground): string => {
124
148
  if (options.suppressContentBackgrounds && CONTENT_BACKGROUNDS.has(color)) return "\x1b[49m";
125
149
  const ansi = backgroundAnsi.get(color);
126
150
  if (ansi === undefined) throw new Error(`Unknown theme background: ${color}`);
127
151
  return ansi;
128
152
  };
153
+ snapshot.getBgAnsi = getBgAnsi;
129
154
  snapshot.fg = (color: ThemeColor, text: string): string => `${snapshot.getFgAnsi(color)}${text}\x1b[39m`;
130
155
  snapshot.bg = (color: ThemeBackground, text: string): string => {
131
156
  if (options.suppressContentBackgrounds && CONTENT_BACKGROUNDS.has(color)) return text;
132
- return `${snapshot.getBgAnsi(color)}${text}\x1b[49m`;
157
+ return `${getBgAnsi(color)}${text}\x1b[49m`;
133
158
  };
134
159
 
135
160
  return snapshot;
@@ -148,7 +173,7 @@ export function snapshotTheme(source: Theme): Theme {
148
173
  /**
149
174
  * Keep the active theme while removing message and tool backgrounds.
150
175
  * Surface-specific body text falls back to the theme's terminal-safe base text;
151
- * selection, search, and scrollbar backgrounds remain as affordances.
176
+ * selection and search backgrounds, plus scrollbar colors, remain as affordances.
152
177
  *
153
178
  * @param source - Pi's currently active theme.
154
179
  * @returns A backgroundless projection of the active theme.