@pi-unipi/footer 3.0.0-alpha.14 → 3.0.0-alpha.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/footer",
3
- "version": "3.0.0-alpha.14",
3
+ "version": "3.0.0-alpha.16",
4
4
  "description": "Persistent status bar for Unipi — subscribes to UNIPI_EVENTS and renders key stats from all unipi packages",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -32,8 +32,8 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@pi-unipi/core": "3.0.0-alpha.14",
36
- "@pi-unipi/background-tasks": "3.0.0-alpha.14"
35
+ "@pi-unipi/core": "3.0.0-alpha.16",
36
+ "@pi-unipi/background-tasks": "3.0.0-alpha.16"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -21,6 +21,7 @@ import type { EditorOptions, EditorTheme, TUI } from "@earendil-works/pi-tui";
21
21
  import type { KeybindingsManager } from "@earendil-works/pi-coding-agent";
22
22
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
23
23
  import { getIcon, getResolvedIconStyle } from "./rendering/icons.js";
24
+ import { kanboardGlanceLabel } from "@pi-unipi/core";
24
25
  import { lolcatRainbow, paintLolcatGradient } from "./rendering/lolcat.js";
25
26
 
26
27
  /** Live status injected by the footer extension. */
@@ -43,12 +44,13 @@ export interface GlanceStatus {
43
44
  modelName: string;
44
45
  /** Current thinking level (already "off"-filtered by the provider). */
45
46
  thinkingLevel: string | null;
46
- /**
47
- * Active Fusion pair, when selected. When set, the model slot renders
48
- * `Fusion · <lead> <effort> ◆ <sidekick>` — lead lit, sidekick muted —
49
- * and the plain thinking slot is suppressed (efforts are inline).
47
+ /** Active Fusion pair, when selected. When set, the model slot renders
48
+ * `Fusion · <lead> <effort> ◆ <sidekick>` — lead lit, sidekick muted —
49
+ * and the plain thinking slot is suppressed (efforts are inline).
50
50
  */
51
51
  fusion: { leadName: string; leadEffort: string; sidekickName: string; sidekickEffort: string; savedUsd?: number; busy?: boolean; leadToolCalls?: number; sidekickToolCalls?: number } | null;
52
+ /** Kanboard claims/autowork snapshot (null → no `▣` segment). */
53
+ kanboard: { claims: string[]; autowork: boolean } | null;
52
54
  }
53
55
 
54
56
  const BORDER = {
@@ -198,17 +200,21 @@ export function composeGlanceTitles(
198
200
  branch: string | null,
199
201
  workspace: string,
200
202
  lhMode: string | null = null,
203
+ kanboard: { claims: string[]; autowork: boolean } | null = null,
201
204
  ): { titleParts: string[]; leftTitle: string } {
205
+ const kanboardLabel = kanboardGlanceLabel(kanboard);
202
206
  const titleParts: string[] = [];
203
207
  if (getResolvedIconStyle() === "text") {
204
208
  titleParts.push(brand);
205
209
  if (lhMode) titleParts.push(`mode:${lhMode}`);
210
+ if (kanboardLabel) titleParts.push(kanboardLabel.replace(/^▣ /, "kanboard:"));
206
211
  if (branch) titleParts.push(`branch:${branch}`);
207
212
  return { titleParts, leftTitle: ` workspace:${workspace} ` };
208
213
  }
209
214
  const brandIcon = getIcon("model");
210
215
  titleParts.push(`${brandIcon ? brandIcon + " " : ""}${brand}`);
211
216
  if (lhMode) titleParts.push(lhMode);
217
+ if (kanboardLabel) titleParts.push(kanboardLabel);
212
218
  if (branch) {
213
219
  const gitIcon = getIcon("git");
214
220
  titleParts.push(`${gitIcon ? gitIcon + " " : ""}${branch}`);
@@ -278,7 +284,7 @@ export class GlanceEditor extends CustomEditor {
278
284
  // Brand rendered as an animated lolcat gradient (phase from wall time;
279
285
  // the footer's 1s refresh timer re-renders, so it shimmers each tick).
280
286
  const brand = lolcatRainbow("UNIPI", Date.now() / 1000);
281
- const { titleParts, leftTitle } = composeGlanceTitles(brand, st.branch, st.workspace, st.lhMode);
287
+ const { titleParts, leftTitle } = composeGlanceTitles(brand, st.branch, st.workspace, st.lhMode, st.kanboard);
282
288
  const title = titleParts.join(SEP);
283
289
  const leadRule = `${BORDER.horizontal} `;
284
290
  const titleText = ` ${title}${SEP}`;
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { ExtensionAPI, Theme, ExtensionContext } from "@earendil-works/pi-coding-agent";
9
9
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
10
- import { UNIPI_EVENTS, emitEvent, UNIPI_PREFIX, FOOTER_COMMANDS, getSharedFusionStatus, getSharedLongHorizonMode, getSharedPlanPermissionStatus } from "@pi-unipi/core";
10
+ import { UNIPI_EVENTS, emitEvent, UNIPI_PREFIX, FOOTER_COMMANDS, getSharedFusionStatus, getSharedKanboardStatus, getSharedLongHorizonMode, getSharedPlanPermissionStatus } from "@pi-unipi/core";
11
11
  import { FooterRegistry, getFooterRegistry } from "./registry/index.js";
12
12
  import { FooterRenderer } from "./rendering/renderer.js";
13
13
  import { subscribeToEvents } from "./events.js";
@@ -448,6 +448,7 @@ function installGlanceEditor(
448
448
  const lhMode = typeof lhModeRaw === "string" && lhModeRaw.length > 0
449
449
  ? MODE_LABELS[lhModeRaw] ?? lhModeRaw
450
450
  : null;
451
+ const kanboard = getSharedKanboardStatus() ?? null;
451
452
  // Plan/permission state rides the same CORE registry data, written by
452
453
  // the workflow module's events (also re-emitted on session_start).
453
454
  const coreData = st.registry.getGroupData("core") as
@@ -470,6 +471,7 @@ function installGlanceEditor(
470
471
  modelName,
471
472
  thinkingLevel: typeof p?.thinkingLevel === "string" ? p.thinkingLevel : null,
472
473
  fusion,
474
+ kanboard,
473
475
  };
474
476
  }),
475
477
  );