pi-cockpit 0.24.1 → 0.24.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  A responsive **agent cockpit** for [Pi](https://pi.dev): wide terminals get a docked Maestro operations sidebar, narrow terminals automatically fall back to the existing Todo and Agent widgets, and every layout keeps the Starship-style footer.
4
4
 
5
- It is the third plugin of the `pi-maestro-flow` project (alongside `pi-maestro-flow` and `pi-maestro-teammate`). It is installed and registered with `pi-maestro-flow`, but it also runs standalone. Current version: **0.9.1**.
5
+ It is the third plugin of the `pi-maestro-flow` project (alongside `pi-maestro-flow` and `pi-maestro-teammate`). It is installed and registered with `pi-maestro-flow`, but it also runs standalone. Current version: **0.24.2**.
6
6
 
7
7
  The dock is a non-capturing top-right overlay. Cockpit reserves its columns by wrapping the active TUI renderer at runtime, so the Pi workspace reflows instead of rendering underneath it. No Pi source files are modified.
8
8
 
@@ -25,7 +25,7 @@ The dock is a non-capturing top-right overlay. Cockpit reserves its columns by w
25
25
  `pi-cockpit` comes automatically with the orchestration layer — installing `pi-maestro-flow` pulls `pi-cockpit` and registers it into `settings.packages` on postinstall, no manual setup required. To use it on its own:
26
26
 
27
27
  ```bash
28
- pi install npm:pi-cockpit@0.9.1 # standalone from npm
28
+ pi install npm:pi-cockpit@0.24.2 # standalone from npm
29
29
  # or, for one run:
30
30
  pi -e ./packages/pi-cockpit
31
31
  ```
@@ -141,7 +141,9 @@ The tab title is `frame + pi - <session> - <working state>`. The session part fo
141
141
 
142
142
  ## Sidebar compatibility
143
143
 
144
- The split-pane wrapper depends on Pi's current TUI renderer shape and is verified against Pi `0.84.4`. A render integration failure disables the split and retries the original renderer at full width. The `/cockpit` panel exposes a read-only "host patches" row showing which pi-internal patches are live; a pi-tui version outside the verified range triggers a one-time warning at session start.
144
+ The split-pane wrapper depends on Pi's current TUI renderer shape. Host hooks retain runtime capability checks and reversible fallbacks; there is no startup version-allowlist warning. A render integration failure disables the split and retries the original renderer at full width. The `/cockpit` panel exposes a read-only "host patches" row with recorded patch status and degradation reasons.
145
+
146
+ Native startup, viewport-stability and compaction-style regressions have been exercised against the installed Pi `0.99.2` SDK and its real dynamic TUI reference. This is not a certification of every interactive surface: dynamic references currently leave the split pane unattached, while the sidebar can still report attachment success. This existing limitation also affects `0.99.0`.
145
147
 
146
148
  Do not enable `pi-cockpit`'s dock and `pi-atelier@0.7.0`'s sidebar together. Both reserve columns by wrapping the same renderer, and `pi-atelier@0.7.0` does not participate in Cockpit's split-owner marker protocol. Use `"sidebar": { "mode": "off" }` when running Atelier.
147
149
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cockpit",
3
- "version": "0.24.1",
3
+ "version": "0.24.2",
4
4
  "description": "Responsive Maestro operations sidebar, fallback status widgets, and footer for Pi.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -72,7 +72,7 @@
72
72
  "@earendil-works/pi-coding-agent": "0.99.0",
73
73
  "@earendil-works/pi-tui": "0.99.0",
74
74
  "@types/node": "^22.0.0",
75
- "pi-maestro-teammate": "2.7.2",
75
+ "pi-maestro-teammate": "2.8.0",
76
76
  "typebox": "1.3.27",
77
77
  "typescript": "^5.5.0"
78
78
  },
package/src/footer.ts CHANGED
@@ -196,6 +196,14 @@ function extensionStatusColor(status: ExtensionStatusSegment): ThemeColor {
196
196
  if (mode === "READY" || mode === "PLAN READY") return "accent";
197
197
  return "muted";
198
198
  }
199
+ if (status.key === "maestro-plan-auto") return "warning";
200
+ if (status.key === "self-evolve") return "success";
201
+ if (status.key === "decision-policy") {
202
+ if (status.text.startsWith("DEC !")) return "error";
203
+ if (status.text.startsWith("DEC ?")) return "accent";
204
+ if (status.text.startsWith("DEC ▶")) return "warning";
205
+ if (status.text.startsWith("DEC ✓")) return "success";
206
+ }
199
207
  if (status.key !== "approval-mode") return "muted";
200
208
  const mode = approvalMode(status);
201
209
  if (UNSAFE_APPROVAL_MODES.has(mode)) return "error";
@@ -207,6 +215,8 @@ function extensionStatusColor(status: ExtensionStatusSegment): ThemeColor {
207
215
 
208
216
  const HIDDEN_EXTENSION_STATUS_KEYS = new Set([
209
217
  "maestro-auto-compact-mode",
218
+ // The active thinking level already belongs to the model identity on line one.
219
+ "maestro-effort",
210
220
  "mcp",
211
221
  "swarm-best",
212
222
  "team-swarm",
@@ -216,6 +226,8 @@ function isVisibleExtensionStatus(status: ExtensionStatusSegment, thinking?: str
216
226
  if (status.text === "" || status.text === thinking) return false;
217
227
  if (HIDDEN_EXTENSION_STATUS_KEYS.has(status.key)) return false;
218
228
  if (status.key === "self-evolve" && /^EVOL off$/i.test(status.text.trim())) return false;
229
+ if (status.key === "maestro-plan-auto" && /^PLAN-AUTO off$/i.test(status.text.trim())) return false;
230
+ if (status.key === "decision-policy" && /^DEC ○ (?:未配置|A:off E:off)$/i.test(status.text.trim())) return false;
219
231
  return !/^(?:TEAM SWARM\b|BEST\b|COMPLETED$|ACT$)/i.test(status.text.trim());
220
232
  }
221
233
 
@@ -223,6 +235,14 @@ function paintExtensionStatus(
223
235
  status: ExtensionStatusSegment,
224
236
  theme: PaintTheme,
225
237
  ): string {
238
+ const marker = status.key === "decision-policy"
239
+ ? /^(DEC) ([○!?▶✓])(.*)$/.exec(status.text)
240
+ : status.key === "self-evolve" ? /^(EVOL) (●)(.*)$/.exec(status.text) : null;
241
+ if (marker) {
242
+ return theme.fg("muted", `${marker[1]} `)
243
+ + theme.fg(extensionStatusColor(status), marker[2])
244
+ + theme.fg("muted", marker[3]);
245
+ }
226
246
  const text = status.key === "approval-mode" && UNSAFE_APPROVAL_MODES.has(approvalMode(status))
227
247
  ? "YOLO"
228
248
  : status.key === "maestro-auto-compact-mode"
@@ -307,6 +327,7 @@ export function renderFooter(p: FooterParts): string[] {
307
327
  const visibleStatuses = (p.extensionStatuses ?? []).filter(
308
328
  (status) => isVisibleExtensionStatus(status, p.thinking),
309
329
  );
330
+ const fastStatus = visibleStatuses.find((status) => status.key === "codex-fast");
310
331
  const controlStatuses = visibleStatuses.filter(
311
332
  (status) => status.key === "mode"
312
333
  || status.key === "approval-mode"
@@ -331,6 +352,9 @@ export function renderFooter(p: FooterParts): string[] {
331
352
  priority: 5,
332
353
  minWidth: utils.measure(g.model) + 1 + utils.measure(g.ellipsis) + 3,
333
354
  });
355
+ if (fastStatus) {
356
+ leftParts.push({ text: theme.fg("success", "FAST"), priority: 4, clippable: false });
357
+ }
334
358
  if (p.thinking && p.thinking !== "off") {
335
359
  leftParts.push({ text: theme.fg("muted", p.thinking), priority: 4, clippable: false });
336
360
  }
@@ -454,7 +478,7 @@ export function renderFooter(p: FooterParts): string[] {
454
478
  if (p.maestroWorkflow) {
455
479
  lines.push(utils.clip(renderMaestroWorkflowLine(p.maestroWorkflow, theme, g), width, ell));
456
480
  }
457
- const statuses = visibleStatuses.filter((status) => !controlStatuses.includes(status));
481
+ const statuses = visibleStatuses.filter((status) => status !== fastStatus && !controlStatuses.includes(status));
458
482
  if (statuses.length > 0) {
459
483
  const statusSeparator = ` ${sep} `;
460
484
  const fittedStatuses = fitSegmentsByPriority(
package/src/index.ts CHANGED
@@ -389,24 +389,6 @@ export default function (pi: ExtensionAPI): void {
389
389
  let viewportStabilityPatch: ViewportStabilityPatch | undefined;
390
390
  let compactionStylePatch: CompactionStylePatch | undefined;
391
391
 
392
- // Host SDK versions the TUI patches were validated against. A mismatch does
393
- // not block anything — every patch fails closed — but the user should know
394
- // the cockpit is running on an unverified host shape.
395
- const VERIFIED_PI_TUI = /^(0\.83\.|0\.84\.|0\.99\.0$)/;
396
- let hostVersionWarned = false;
397
- const checkHostVersion = (ctx: ExtensionContext): void => {
398
- if (hostVersionWarned) return;
399
- try {
400
- // Public coding-agent VERSION is the host compatibility diagnostic;
401
- // package.json deep exports are not part of the SDK contract.
402
- const version = VERSION;
403
- if (VERIFIED_PI_TUI.test(version)) return;
404
- hostVersionWarned = true;
405
- ctx.ui.notify(tuiT("notice.hostVersion", { version }), "warning");
406
- } catch {
407
- // version probe is best-effort; never block session start
408
- }
409
- };
410
392
  const ensureViewportStability = (tui: TUI): void => {
411
393
  // Native fullscreen owns a fixed application viewport and has no main-screen
412
394
  // applyLineResets hook. Do not cache that expected miss: the same dynamic TUI
@@ -2025,7 +2007,6 @@ export default function (pi: ExtensionAPI): void {
2025
2007
  publishUiOwnership();
2026
2008
  lastCtx = ctx;
2027
2009
  uiPromptDepth = 0;
2028
- checkHostVersion(ctx);
2029
2010
  ambientSurfaces.reset();
2030
2011
  agentReads.bindSession(ctx.sessionManager.getSessionId());
2031
2012
  agents = agentReads.current;
package/src/tui-i18n.ts CHANGED
@@ -321,7 +321,6 @@ export const COCKPIT_TUI_CATALOGS: TranslationCatalogs = {
321
321
  "editor.historyUnavailable": "Input history unavailable: {message}",
322
322
  "notice.sidebarWidthSaveFailed": "Cockpit sidebar width kept for this session; save failed: {message}",
323
323
  "notice.sidebarUnavailable": "Cockpit sidebar unavailable: {message}",
324
- "notice.hostVersion": "Cockpit host patches were verified against pi-tui 0.83.x/0.84.x; running on {version} — degraded surfaces fail closed.",
325
324
  "notice.themeUnavailable": "theme \"{name}\" unavailable — {message}",
326
325
  "notice.themeSelected": "theme: {name}",
327
326
  "notice.notFound": "not found",
@@ -653,7 +652,6 @@ export const COCKPIT_TUI_CATALOGS: TranslationCatalogs = {
653
652
  "editor.historyUnavailable": "输入历史不可用:{message}",
654
653
  "notice.sidebarWidthSaveFailed": "侧边栏宽度仅在本会话保留;保存失败:{message}",
655
654
  "notice.sidebarUnavailable": "Cockpit 侧边栏不可用:{message}",
656
- "notice.hostVersion": "Cockpit 宿主补丁已验证 pi-tui 0.83.x/0.84.x;当前 {version} —— 不兼容的面会静默降级。",
657
655
  "notice.themeUnavailable": "主题 \"{name}\" 不可用 — {message}",
658
656
  "notice.themeSelected": "主题:{name}",
659
657
  "notice.notFound": "未找到",