pi-cockpit 0.8.0 → 0.9.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 CHANGED
@@ -104,7 +104,7 @@ Cockpit has no package dependency on `pi-maestro-flow`. It observes optional pro
104
104
  - `title.showGit`: include the git branch tag (`git:main`, `git:detached`); read synchronously from `.git/HEAD`, so it costs no process spawn. Off by default.
105
105
  - `title.showMaestro`: include the Maestro workflow status tag (`wf:running`, `wf:done`). Off by default.
106
106
  - `title.maxLength`: hard cap on the composed title; the middle is ellided to keep the head and the working-state tail. Clamped to `20..200`; default `80`.
107
- - `title.generationModel`: `"provider/model"` (e.g. `"maestro-qwen/qwen3.8-max-preview"`) of a model registered with the `/api-manager` command (or any other provider pi resolves). When set, the session title is generated by that model over the first completed turn (user prompt + assistant reply) through its OpenAI-compatible endpoint, with a 10s timeout. Empty (default) uses the offline rule-based extractor instead. Generation is best-effort — on any failure the title silently falls back to the rule-based one.
107
+ - `title.generationModel`: `"provider/model"` (e.g. `"maestro-qwen/qwen3.8-max-preview"`) of a model registered with the `/api-manager` command (or any other provider pi resolves). When set, the session title is generated by that model over the first completed turn (user prompt + assistant reply) through its OpenAI-compatible endpoint, with a 10s timeout. Empty (default) uses the offline rule-based extractor instead. Generation is best-effort — on any failure the title silently falls back to the rule-based one. Editable from the `/cockpit` settings overlay (`z` or cursor to the `title gen model` row, Enter, type, Enter to save; empty clears back to rule-based).
108
108
 
109
109
  The tab title is `frame + pi - <session> - <working state>`. The session part follows Claude Code's chain (`sessionTitle ?? agentTitle ?? haikuTitle ?? default`): the `/session name` title wins, otherwise the generated title, otherwise a short session id. The frame is Claude Code's title chrome: `⠂`/`⠐` braille spinner while a turn runs, static `✳` when idle; failure replaces it with `✗`. On quit, Cockpit clears the title so no stale tab label lingers (Claude Code's `CLEAR_TERMINAL_TITLE`).
110
110
  - `theme`: named theme override; empty string follows the Pi session theme.
@@ -112,6 +112,8 @@ The tab title is `frame + pi - <session> - <working state>`. The session part fo
112
112
  ## Commands
113
113
 
114
114
  - `/cockpit` — opens the settings overlay.
115
+ - `/maestro-settings` — opens the unified settings shell (Cockpit, Flow, Teammate and integrations).
116
+ - `Alt+J` — opens the background Bash jobs overlay (live status, command, cwd, duration, output tail).
115
117
  - `/cockpit sidebar` — reports the current sidebar mode, width, and density.
116
118
  - `/cockpit sidebar auto|on|off` — selects dock behavior.
117
119
  - `/cockpit sidebar resize` or `Ctrl+Shift+R` — enters temporary Resize mode. Left/Right adjusts one column, Shift+Left/Shift+Right adjusts four, Enter accepts, and Escape rolls back. Mouse reporting is active only during Resize mode.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cockpit",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Responsive Maestro operations sidebar, fallback status widgets, and footer for Pi.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -63,7 +63,7 @@
63
63
  "@earendil-works/pi-coding-agent": "0.83.0",
64
64
  "@earendil-works/pi-tui": "0.83.0",
65
65
  "@types/node": "^22.0.0",
66
- "pi-maestro-teammate": "1.6.0",
66
+ "pi-maestro-teammate": "1.7.0",
67
67
  "typescript": "^5.5.0"
68
68
  },
69
69
  "main": "./src/index.ts",
@@ -405,6 +405,14 @@ export class AgentsStore {
405
405
  return false;
406
406
  }
407
407
 
408
+ /** True while any agent (foreground or background) is still running, so elapsed/stall repaints keep the loop alive. */
409
+ hasActive(): boolean {
410
+ for (const row of this.roster.values()) {
411
+ if (row.status === "running") return true;
412
+ }
413
+ return false;
414
+ }
415
+
408
416
  private applyProgress(parentCorrelationId: string, p: ProgressPayload, now: number): void {
409
417
  if (!this.roster.has(p.correlationId)
410
418
  && this.canMaterialize(p.correlationId, parentCorrelationId, now)) {
@@ -1,7 +1,9 @@
1
1
  import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
2
2
  import {
3
+ Key,
3
4
  type Component,
4
5
  type Focusable,
6
+ matchesKey,
5
7
  truncateToWidth,
6
8
  visibleWidth,
7
9
  wrapTextWithAnsi,
@@ -56,7 +58,7 @@ export class BashBgOverlay implements Component, Focusable {
56
58
  }
57
59
 
58
60
  handleInput(data: string): void {
59
- if (data === "\x1b") {
61
+ if (matchesKey(data, Key.escape)) {
60
62
  if (this.mode === "detail") this.mode = "list";
61
63
  else this.params.close();
62
64
  this.params.requestRender();
@@ -64,20 +66,20 @@ export class BashBgOverlay implements Component, Focusable {
64
66
  }
65
67
  // Plain letters stay reserved for future filter/command modes, so navigation
66
68
  // and refresh use arrows and a non-letter key only.
67
- if (data === "\x1b[A") {
69
+ if (matchesKey(data, Key.up)) {
68
70
  this.move(-1);
69
71
  return;
70
72
  }
71
- if (data === "\x1b[B") {
73
+ if (matchesKey(data, Key.down)) {
72
74
  this.move(1);
73
75
  return;
74
76
  }
75
- if (data === "\r" || data === "\n") {
77
+ if (matchesKey(data, Key.enter)) {
76
78
  if (this.selectedJob()) this.mode = this.mode === "detail" ? "list" : "detail";
77
79
  this.params.requestRender();
78
80
  return;
79
81
  }
80
- if (data === "\x12" || data === "\x1b[15~") {
82
+ if (data === "\x12" || matchesKey(data, Key.f5)) {
81
83
  // Ctrl+R / F5 — refresh is acknowledged immediately even though the
82
84
  // authoritative snapshot only arrives later. Schedule the ack's own
83
85
  // expiry so it disappears even without any follow-up repaint.