@gonrocca/zero-pi 0.1.36 → 0.1.38

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.
@@ -142,58 +142,27 @@ export function bannerBlock(width: number): string[] {
142
142
  return [ornament(width), ...renderLogo(width), center(tag, width), ornament(width)];
143
143
  }
144
144
 
145
- /** The slice of pi's UI surface this extension uses. */
146
- interface PiUI {
147
- setWidget(id: string, lines: string[]): void;
148
- }
149
- interface PiSessionContext {
150
- ui?: PiUI;
151
- }
152
- interface PiAPI {
153
- on(event: string, handler: (event: unknown, ctx: PiSessionContext) => void): void;
154
- }
155
-
156
- /** Stable widget id — re-installing with the same id replaces the previous lines. */
157
- const WIDGET_ID = "zero-banner";
158
-
159
- /**
160
- * Install (or refresh) the banner as a pi-managed widget above the editor.
161
- *
162
- * Using `ctx.ui.setWidget` instead of a one-shot `stdout.write` means pi owns
163
- * the lines and redraws them on every resize, every reload, every session
164
- * restart — so the banner survives maximize/minimize instead of vanishing into
165
- * scrollback. The crash this file's earlier comment warned about was the
166
- * animated 140 ms re-render loop; a static widget set once per `session_start`
167
- * has no timer and re-uses the same id, so it never spams.
168
- */
169
- function installWidget(ctx: PiSessionContext): void {
170
- if (!ctx?.ui || typeof ctx.ui.setWidget !== "function") return;
171
- if (process.env.NO_COLOR) return;
172
- const cols = process.stdout?.columns && process.stdout.columns > 0 ? process.stdout.columns : 80;
173
- ctx.ui.setWidget(WIDGET_ID, bannerBlock(cols));
174
- }
175
-
176
145
  /**
177
146
  * The pi extension entry point.
178
147
  *
179
- * Hooks `session_start` (fires on startup, reload, new, resume, fork) and
180
- * installs the banner as a pi-managed widget above the editor so pi keeps it
181
- * rendered and redraws it on resize. Disabled with `ZERO_HEADER=off`.
182
- * Defensive: any failure of registration or the widget install is swallowed
183
- * a banner must never break a pi session.
148
+ * Writes the banner ONCE to stdout at extension load — pi loads extensions
149
+ * before its TUI takes over the screen, so the banner ends up at the very top
150
+ * of the terminal scrollback, above everything else. `setWidget` was tried
151
+ * (0.1.33–0.1.37) but pi positions widgets above the editor, not at the top
152
+ * of the viewport short chats showed the banner in the middle.
153
+ *
154
+ * Known tradeoff: resizing the terminal lets pi clear/reflow its TUI area, and
155
+ * the one-shot banner in scrollback can scroll out of view. That is normal
156
+ * CLI startup-banner behavior. `ZERO_HEADER=off` disables it.
184
157
  */
185
- export default function register(pi?: unknown): void {
158
+ export default function register(_pi?: unknown): void {
186
159
  try {
187
160
  if ((process.env.ZERO_HEADER ?? "").trim().toLowerCase() === "off") return;
188
- if (!pi || typeof (pi as PiAPI).on !== "function") return;
189
- (pi as PiAPI).on("session_start", (_event, ctx) => {
190
- try {
191
- installWidget(ctx);
192
- } catch {
193
- // A widget install failure must never break a pi session.
194
- }
195
- });
161
+ const stream = process.stdout;
162
+ if (!stream || !stream.isTTY || process.env.NO_COLOR) return;
163
+ const width = stream.columns && stream.columns > 0 ? stream.columns : 80;
164
+ stream.write("\n" + bannerBlock(width).join("\n") + "\n\n");
196
165
  } catch {
197
- // Registration itself must never break a pi session.
166
+ // A banner failure must never break a pi session.
198
167
  }
199
168
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gonrocca/zero-pi",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "zero-pi — an installable layer for pi (pi.dev): the zero spec-driven development workflow, per-phase model autotune, and skill auto-learning. Adds capability to pi without modifying pi.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -16,7 +16,7 @@
16
16
  "errPanel": "#2a171b"
17
17
  },
18
18
  "colors": {
19
- "accent": "cyan",
19
+ "accent": "violet",
20
20
  "border": "blue",
21
21
  "borderAccent": "amber",
22
22
  "borderMuted": "dimSteel",