@pi-unipi/unipi 3.0.0-alpha.26 → 3.0.0-alpha.28

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +12 -4
  3. package/package.json +21 -21
  4. package/packages/ask-user/package.json +2 -2
  5. package/packages/autocomplete/package.json +1 -1
  6. package/packages/autocomplete/src/constants.ts +3 -5
  7. package/packages/background-tasks/package.json +2 -2
  8. package/packages/btw/package.json +2 -2
  9. package/packages/compactor/package.json +3 -3
  10. package/packages/core/constants.ts +0 -1
  11. package/packages/core/package.json +1 -1
  12. package/packages/core/src/hints/lines.ts +30 -2
  13. package/packages/footer/README.md +31 -45
  14. package/packages/footer/package.json +3 -3
  15. package/packages/footer/src/commands.ts +12 -41
  16. package/packages/footer/src/config.ts +162 -225
  17. package/packages/footer/src/events.ts +40 -247
  18. package/packages/footer/src/glance-editor.ts +116 -31
  19. package/packages/footer/src/index.ts +193 -377
  20. package/packages/footer/src/registry/index.ts +4 -53
  21. package/packages/footer/src/rendering/icons.ts +18 -1
  22. package/packages/footer/src/segments/compactor.ts +4 -55
  23. package/packages/footer/src/segments/long-horizon.ts +2 -35
  24. package/packages/footer/src/session-scan.ts +271 -0
  25. package/packages/footer/src/strip.ts +238 -0
  26. package/packages/footer/src/types.ts +48 -135
  27. package/packages/fusion/package.json +4 -4
  28. package/packages/fusion/src/index.ts +5 -4
  29. package/packages/fusion/src/nudge.ts +59 -2
  30. package/packages/fusion/src/prompts.ts +2 -2
  31. package/packages/info-screen/package.json +2 -2
  32. package/packages/input-shortcuts/package.json +2 -2
  33. package/packages/kanboard/package.json +7 -7
  34. package/packages/long-horizon/package.json +2 -2
  35. package/packages/mcp/package.json +2 -2
  36. package/packages/memory/package.json +3 -3
  37. package/packages/notify/package.json +2 -2
  38. package/packages/skill-registry/package.json +2 -2
  39. package/packages/subagents/package.json +3 -3
  40. package/packages/unipi/bundled.js +1752 -3209
  41. package/packages/updater/package.json +2 -2
  42. package/packages/utility/README.md +3 -2
  43. package/packages/utility/package.json +2 -2
  44. package/packages/utility/skills/summarize/SKILL.md +9 -2
  45. package/packages/utility/skills/utility/SKILL.md +1 -1
  46. package/packages/utility/src/summarize/index.ts +7 -9
  47. package/packages/watchdog/package.json +3 -3
  48. package/packages/web-api/package.json +2 -2
  49. package/packages/workflow/index.ts +24 -4
  50. package/packages/workflow/package.json +2 -2
  51. package/packages/workflow/src/plan/enforce.ts +32 -32
  52. package/packages/workflow/src/plan/index.ts +86 -26
  53. package/packages/workflow/src/plan/review.ts +167 -43
  54. package/packages/workflow/src/plan/state.ts +4 -2
  55. package/packages/footer/src/help.ts +0 -160
  56. package/packages/footer/src/presets.ts +0 -128
  57. package/packages/footer/src/rendering/renderer.ts +0 -454
  58. package/packages/footer/src/rendering/separators.ts +0 -102
  59. package/packages/footer/src/segments/core.ts +0 -412
  60. package/packages/footer/src/segments/kanboard.ts +0 -91
  61. package/packages/footer/src/segments/mcp.ts +0 -109
  62. package/packages/footer/src/segments/memory.ts +0 -168
  63. package/packages/footer/src/segments/notify.ts +0 -61
  64. package/packages/footer/src/segments/ralph.ts +0 -123
  65. package/packages/footer/src/segments/status-ext.ts +0 -123
  66. package/packages/footer/src/segments/workflow.ts +0 -124
package/CHANGELOG.md CHANGED
@@ -6,6 +6,40 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.0.0-alpha.28] — 2026-10-04
10
+
11
+ ### Changed
12
+ - `utility`: **`/unipi:summarize` re-summarizes the last reply**, with the session as context. The command sends only `/skill:summarize`, plus any text you add, which reaches the skill as your question ("what would it change?" now asks about the last reply). It no longer wraps your text in a "summarize this session" prompt.
13
+
14
+ ## [3.0.0-alpha.27] — 2026-10-04
15
+
16
+ ### Added
17
+ - `core`: 4 new Unicrab hints for the footer changes — three what's-new tips (tokens and cost under the input, the Footer settings, the responsive drop) and a setting hint for `footer.rainbow`.
18
+ - `footer`: **Glance settings** — the stats strip under the input, the frame badges and the rainbow are configurable in `/unipi:settings` → **Footer**: per-part strip toggles (`strip.turns`, `strip.time`, `strip.speed`, `strip.tokens`, `strip.cost`, `strip.compactions`, `strip.cache`), a **Rainbow** mode (`always` / `brand-only` / `off`), the background-task line (`processLine`), and badge toggles (`badges.mode`, `badges.planPermission`, `badges.fusion`, `badges.kanboard`).
19
+ - `footer`: **session tokens and cost in the stats line** — `↑12.3k in · ↓4.1k out` and `$1.23` (`sub` on subscription models); sums skip failed/aborted replies.
20
+ - `footer`: **responsive to the terminal** — narrow widths drop stats parts by priority (compactions → cache → time → turns → speed → cost → tokens) whole instead of truncating mid-part, and the frame degrades its badges (kanboard → fusion → plan/permission → mode) before the branch or model truncate; below 20 terminal rows the stats and task lines hide while the frame stays.
21
+
22
+ - `workflow`: **plan reviews in two parts** — plans have a `## Summary` for the approver and an `## Implementation` for whoever builds it; the review overlay shows them side by side at 120+ columns (Tab switches pane) and stacked on narrower terminals.
23
+
24
+ ### Changed
25
+ - `workflow`: **plan mode is no longer read-only by allowlist** — research, memory, subagents and read-only shell run as normal; only writes outside the plan file, `docs/plans/` and temp dirs are blocked (in every permission mode), and state-changing shell asks first (skipped in `full`).
26
+ - `workflow`: **plan with the user before submitting** — the plan-mode prompt asks the model to settle shaping decisions with `ask_user`; `plan_submit` refuses while `### Open questions` lists items or when the plan is unchanged since "Keep planning", and Approve/Discard end the turn.
27
+ - `fusion`: the lead's shell-delegation nudge counts per request (it no longer fires at the start of a new prompt) and treats piped read-only commands (`grep … | head`, `2>&1`) as trivial.
28
+
29
+ ### Removed
30
+ - `footer`: the **classic segment renderer** — presets, separators, segments, `/unipi:footer-help` and their settings (`preset`, `separator`, `zoneSeparator`, `showFullLabels`, `groups`, `glanceMode`) are gone; the glance frame is the only footer. Old keys in existing config files are ignored. `enabled: false` gives the plain pi editor.
31
+
32
+ ### Changed (footer)
33
+ - `footer`: the **Color mode** setting now offers `auto` / `truecolor` / `256` / `none` (the hub previously offered `mono`, which the footer silently treated as `auto`; stored `mono` values load as `none`).
34
+ - `footer`: the 1-second refresh no longer replays the whole session branch — the scan is incremental (full rescan on branch change or compaction), the stats read a cached snapshot instead of walking the branch per paint, settings loads are memoized, and the redraw fires only when something displayed changed.
35
+ - `core` / `autocomplete`: `/unipi:footer-help` command entries removed.
36
+
37
+ ### Fixed
38
+ - `footer`: the MODULE_READY announcement now reports the package version instead of a hard-coded `0.1.0`.
39
+
40
+ ### Docs
41
+ - README: the glance-footer caption names tokens, cost and the responsive fit; a new What's new row for alpha.27 (classic footer removed).
42
+
9
43
  ## [3.0.0-alpha.26] — 2026-10-04
10
44
 
11
45
  ### Fixed
package/README.md CHANGED
@@ -27,9 +27,16 @@
27
27
  ## Install
28
28
 
29
29
  ```bash
30
- pi install npm:@pi-unipi/unipi
30
+ pi install npm:@pi-unipi/unipi@alpha
31
31
  ```
32
32
 
33
+ > [!NOTE]
34
+ > **UniPi 3 is in alpha.** This README describes v3, published under the npm
35
+ > `alpha` tag. Plain `pi install npm:@pi-unipi/unipi` still installs the stable
36
+ > 2.x line ([2.x README](https://github.com/Neuron-Mr-White/unipi/tree/main#readme)).
37
+ > To update an alpha install: `pi update npm:@pi-unipi/unipi@alpha`. To go back
38
+ > to stable: `pi install npm:@pi-unipi/unipi@latest`.
39
+
33
40
  UniPi needs [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent)
34
41
  `0.87.1` or later. This command installs 21 extension packages. Each package
35
42
  also works alone.
@@ -44,8 +51,9 @@ This screenshot shows one turn in a demo session:
44
51
  - **Memory** finds the test setup from an earlier session and saves a new fact
45
52
  for later sessions.
46
53
  - **The glance footer** frames the input box. It shows the git branch, the
47
- mode, the context use and the model. The strip below it shows turns, steps,
48
- wall time, tool time, time to first token, tokens per second and cache hits.
54
+ mode, the context use and the model. The strip below it shows tokens in and
55
+ out, cost, speed, turns, time and cache hits. It fits itself to the window:
56
+ on a narrow screen the less important parts drop out first.
49
57
 
50
58
  ## Why UniPi
51
59
 
@@ -241,10 +249,10 @@ The recent releases, in short. The [changelog](CHANGELOG.md) has the details.
241
249
 
242
250
  | Release | What changed for you |
243
251
  |---|---|
252
+ | alpha.27 | The footer shows tokens in and out and the session cost under the input. It fits narrow and short windows. Each part of the stats line, the frame badges and the rainbow can be turned off in `/unipi:settings` → Footer. The classic footer is gone. |
244
253
  | alpha.25 | The Unicrab splash at startup. A new `/unipi:info`: this session, the context bucket, compaction savings and `s`/`p`/`g` scope tags. Prompts that UniPi sends for you (goal, summarize, answer) show as a UniPi panel, not as your own message. |
245
254
  | alpha.24 | The `summarize` skill and `/unipi:summarize [focus]`. Long work ends with a short recap: the answer first, then findings, open items and questions. |
246
255
  | alpha.23 | `/unipi:settings` explains each setting and each option in a panel below the list. Web tools with no working provider hide from the agent. |
247
- | alpha.22 | Simple mode is the default. Each tool call is one line, and `Ctrl+O` opens it. Images no longer overlap the text below them. |
248
256
 
249
257
  ## Docs
250
258
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/unipi",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "All-in-one extension suite for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -83,26 +83,26 @@
83
83
  "typebox": "^1.1.38"
84
84
  },
85
85
  "dependencies": {
86
- "@pi-unipi/ask-user": "3.0.0-alpha.26",
87
- "@pi-unipi/background-tasks": "3.0.0-alpha.26",
88
- "@pi-unipi/btw": "3.0.0-alpha.26",
89
- "@pi-unipi/command-enchantment": "3.0.0-alpha.26",
90
- "@pi-unipi/compactor": "3.0.0-alpha.26",
91
- "@pi-unipi/core": "3.0.0-alpha.26",
92
- "@pi-unipi/footer": "3.0.0-alpha.26",
93
- "@pi-unipi/fusion": "3.0.0-alpha.26",
94
- "@pi-unipi/info-screen": "3.0.0-alpha.26",
95
- "@pi-unipi/input-shortcuts": "3.0.0-alpha.26",
96
- "@pi-unipi/kanboard": "3.0.0-alpha.26",
97
- "@pi-unipi/mcp": "3.0.0-alpha.26",
98
- "@pi-unipi/memory": "3.0.0-alpha.26",
99
- "@pi-unipi/notify": "3.0.0-alpha.26",
100
- "@pi-unipi/skill-registry": "3.0.0-alpha.26",
101
- "@pi-unipi/subagents": "3.0.0-alpha.26",
102
- "@pi-unipi/updater": "3.0.0-alpha.26",
103
- "@pi-unipi/utility": "3.0.0-alpha.26",
104
- "@pi-unipi/web-api": "3.0.0-alpha.26",
105
- "@pi-unipi/workflow": "3.0.0-alpha.26"
86
+ "@pi-unipi/ask-user": "3.0.0-alpha.28",
87
+ "@pi-unipi/background-tasks": "3.0.0-alpha.28",
88
+ "@pi-unipi/btw": "3.0.0-alpha.28",
89
+ "@pi-unipi/command-enchantment": "3.0.0-alpha.28",
90
+ "@pi-unipi/compactor": "3.0.0-alpha.28",
91
+ "@pi-unipi/core": "3.0.0-alpha.28",
92
+ "@pi-unipi/footer": "3.0.0-alpha.28",
93
+ "@pi-unipi/fusion": "3.0.0-alpha.28",
94
+ "@pi-unipi/info-screen": "3.0.0-alpha.28",
95
+ "@pi-unipi/input-shortcuts": "3.0.0-alpha.28",
96
+ "@pi-unipi/kanboard": "3.0.0-alpha.28",
97
+ "@pi-unipi/mcp": "3.0.0-alpha.28",
98
+ "@pi-unipi/memory": "3.0.0-alpha.28",
99
+ "@pi-unipi/notify": "3.0.0-alpha.28",
100
+ "@pi-unipi/skill-registry": "3.0.0-alpha.28",
101
+ "@pi-unipi/subagents": "3.0.0-alpha.28",
102
+ "@pi-unipi/updater": "3.0.0-alpha.28",
103
+ "@pi-unipi/utility": "3.0.0-alpha.28",
104
+ "@pi-unipi/web-api": "3.0.0-alpha.28",
105
+ "@pi-unipi/workflow": "3.0.0-alpha.28"
106
106
  },
107
107
  "devDependencies": {
108
108
  "@earendil-works/pi-agent-core": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/ask-user",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Structured user input tool for Pi coding agent — single-select, multi-select, freeform",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@pi-unipi/core": "3.0.0-alpha.26"
43
+ "@pi-unipi/core": "3.0.0-alpha.28"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/command-enchantment",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Enhanced TUI autocomplete for /unipi:* commands — colored, sorted, and grouped by package",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -118,9 +118,8 @@ export const COMMAND_REGISTRY: Record<string, string> = {
118
118
  "unipi:kanboard-do": "kanboard",
119
119
  "unipi:kanboard-autowork": "kanboard",
120
120
 
121
- // footer (3 commands)
121
+ // footer (1 command)
122
122
  "unipi:footer": "footer",
123
- "unipi:footer-help": "footer",
124
123
 
125
124
  // updater (3 commands)
126
125
  "unipi:readme": "updater",
@@ -161,7 +160,7 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
161
160
  "unipi:cleanup": "Remove stale UniPi temp files and leftovers (preview first)",
162
161
  "unipi:doctor": "Check UniPi's runtime: config, model cache, Decision Model, skills",
163
162
  "unipi:answer": "Answer the last reply — fixed input under the scrollable reply, per question, or web form",
164
- "unipi:summarize": "Summarize this session — answer first, then findings, open items, questions; add text to set a focus",
163
+ "unipi:summarize": "Summarize your last reply again (answer first, then findings, open items, questions). Add text to ask about it",
165
164
  "unipi:skills": "Manage skills — on/off per project, listed or not, the skill vault",
166
165
 
167
166
  "unipi:kanboard": "Kanboard — capture tasks, run them, open the board",
@@ -183,8 +182,7 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
183
182
  "unipi:compact-help": "Show compactor command help",
184
183
  "unipi:notify-event": "Toggle a notify event without the TUI: <event> <on|off>",
185
184
 
186
- "unipi:footer": "Toggle footer or switch preset",
187
- "unipi:footer-help": "Show footer segment guide",
185
+ "unipi:footer": "Toggle footer on or off",
188
186
 
189
187
  "unipi:readme": "Browse package README files",
190
188
  "unipi:changelog": "Browse changelog (Keep a Changelog format)",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/background-tasks",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Background tasks for UniPi — durable shell jobs and delegated background agents with a footer dock",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-ai": "^0.87.1",
13
- "@pi-unipi/core": "3.0.0-alpha.26",
13
+ "@pi-unipi/core": "3.0.0-alpha.28",
14
14
  "turndown": "^7.2.4"
15
15
  },
16
16
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/btw",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "A pi extension for parallel side conversations with /unipi:btw — part of the Unipi suite",
5
5
  "type": "module",
6
6
  "main": "extensions/btw.ts",
@@ -37,7 +37,7 @@
37
37
  "@earendil-works/pi-tui": "^0.87.1"
38
38
  },
39
39
  "dependencies": {
40
- "@pi-unipi/core": "3.0.0-alpha.26"
40
+ "@pi-unipi/core": "3.0.0-alpha.28"
41
41
  },
42
42
  "pi": {
43
43
  "extensions": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/compactor",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Compaction for Pi — lossless zero-LLM or model summaries, rebuilt from full history, with session recall",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -33,8 +33,8 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "3.0.0-alpha.26",
37
- "@pi-unipi/info-screen": "3.0.0-alpha.26",
36
+ "@pi-unipi/core": "3.0.0-alpha.28",
37
+ "@pi-unipi/info-screen": "3.0.0-alpha.28",
38
38
  "@earendil-works/pi-agent-core": "^0.87.1"
39
39
  },
40
40
  "peerDependencies": {
@@ -239,7 +239,6 @@ export const UPDATER_DIRS = {
239
239
  /** Footer command names */
240
240
  export const FOOTER_COMMANDS = {
241
241
  FOOTER: "footer",
242
- FOOTER_HELP: "footer-help",
243
242
  } as const;
244
243
 
245
244
  /** Compactor defaults */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/core",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
4
4
  "description": "Shared utilities, event types, and constants for Unipi extension suite",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -244,7 +244,7 @@ export const HINT_LINES: readonly Hint[] = [
244
244
  when: "startup",
245
245
  },
246
246
 
247
- // ─── setting (12) ───────────────────────────────────────────────────────────
247
+ // ─── setting (13) ───────────────────────────────────────────────────────────
248
248
  {
249
249
  id: "set.render-style",
250
250
  category: "setting",
@@ -319,6 +319,12 @@ export const HINT_LINES: readonly Hint[] = [
319
319
  text: "Info Screen → Unicrab splash in /unipi:settings: auto-close, stay until a key, or off.",
320
320
  when: "startup",
321
321
  },
322
+ {
323
+ id: "set.footer-rainbow",
324
+ category: "setting",
325
+ text: "footer.rainbow in /unipi:settings: always, brand-only, or off when the shimmer distracts you.",
326
+ when: "startup",
327
+ },
322
328
 
323
329
  // ─── capability (10) ────────────────────────────────────────────────────────
324
330
  {
@@ -493,7 +499,7 @@ export const HINT_LINES: readonly Hint[] = [
493
499
  teaches: "/unipi:cleanup",
494
500
  },
495
501
 
496
- // ─── whatsnew (12) ───────────────────────────────────────────────────────────
502
+ // ─── whatsnew (15) ───────────────────────────────────────────────────────────
497
503
  {
498
504
  id: "new.unicrab",
499
505
  category: "whatsnew",
@@ -582,6 +588,28 @@ export const HINT_LINES: readonly Hint[] = [
582
588
  when: "startup",
583
589
  since: "3.0.0-alpha.25",
584
590
  },
591
+ {
592
+ id: "new.footer-tokens-cost",
593
+ category: "whatsnew",
594
+ text: "The footer now counts tokens in and out and what the session cost, right under the input.",
595
+ when: "startup",
596
+ since: "3.0.0-alpha.27",
597
+ },
598
+ {
599
+ id: "new.footer-settings",
600
+ category: "whatsnew",
601
+ text: "Too busy down there? /unipi:settings → Footer turns off any stats part, badge or the rainbow.",
602
+ when: "startup",
603
+ teaches: "/unipi:settings",
604
+ since: "3.0.0-alpha.27",
605
+ },
606
+ {
607
+ id: "new.footer-responsive",
608
+ category: "whatsnew",
609
+ text: "Shrink the window and the footer drops its least important stats first, no cut-off text.",
610
+ when: "startup",
611
+ since: "3.0.0-alpha.27",
612
+ },
585
613
 
586
614
  // ─── workflow (8) ───────────────────────────────────────────────────────────
587
615
  {
@@ -1,6 +1,6 @@
1
1
  # Footer
2
2
 
3
- Show live session stats and the state of every UniPi package at the bottom of the terminal.
3
+ Frames the input box and shows live session stats at the bottom of the terminal.
4
4
 
5
5
  `@pi-unipi/footer` · part of [UniPi](../../README.md)
6
6
 
@@ -8,11 +8,10 @@ Show live session stats and the state of every UniPi package at the bottom of th
8
8
 
9
9
  ## What it does
10
10
 
11
- - Puts a frame around the input box. This is **glance mode**, and it is on by default.
12
- - Shows a stats line below the input. It shows turns, steps, model time and tool time. It also shows average time to first token (TTFT), tokens per second, compactions and cache hit rate.
11
+ - Puts a frame around the input box (**the glance frame**, always on when the footer is enabled).
12
+ - Shows a stats line below the input: input/output tokens, cost, average time to first token (TTFT), tokens per second, turns, steps, model and tool time, cache hit rate, and compactions.
13
13
  - Shows a line above the input with counts of background tasks: running, stopped, failed and done.
14
- - Shows a status line with segments from each package when glance mode is off. This is the **classic** footer.
15
- - Lets you select a preset, separator, icon style and color mode, and turn each segment on or off.
14
+ - Adapts to the terminal: parts of the stats line drop by priority when the terminal is narrow, badges leave the frame titles before the branch or model truncate, and on very short terminals the stats and task lines hide.
16
15
 
17
16
  ## Quick start
18
17
 
@@ -36,35 +35,23 @@ The footer starts with the session. Open `/unipi:settings` → **Footer** to cha
36
35
  |---|---|
37
36
  | `/unipi:footer` | Turns the footer on or off. |
38
37
  | `/unipi:footer on` | Turns the footer on. |
39
- | `/unipi:footer off` | Turns the footer off. |
40
- | `/unipi:footer-help` | Shows each active segment with its icon, label and description. |
38
+ | `/unipi:footer off` | Turns the footer off (plain pi editor). |
41
39
 
42
40
  ## The glance frame
43
41
 
44
- The glance frame has three parts:
42
+ The frame has three parts:
45
43
 
46
- - **Top border.** The UNIPI brand, the long-horizon mode, the git branch, and the plan and permission mode. The brand shows a moving rainbow. The frame also shows the rainbow when the thinking level is `xhigh` or `max`.
44
+ - **Top border.** The UNIPI brand, the long-horizon mode, the git branch, and the plan and permission mode. The brand shows a moving rainbow. The frame also shows the rainbow when the thinking level is `xhigh` or `max` (unless **Rainbow** is `brand-only`).
47
45
  - **Bottom border.** The workspace name, context use and window size, the model and the thinking level. With a [Fusion](../fusion/README.md) pair, it shows the lead and the sidekick. It also shows Kanboard claims.
48
46
  - **Stats line.** The line below the input. A part stays hidden until it has data. For example, compactions show only after the first compaction.
49
47
 
50
48
  The background-task line reads the [Background Tasks](../background-tasks/README.md) registry. It shows nothing when no task exists.
51
49
 
52
- Set **Glance mode** to off to get the classic status line.
50
+ ## Responsive behavior
53
51
 
54
- ## Presets
55
-
56
- A preset selects the segments of the classic status line.
57
-
58
- | Preset | Segments |
59
- |---|---|
60
- | `default` | brand, mode, model, directory, git, context, compactions, tokens, TPS, cost, clock, duration |
61
- | `classic` | mode, model, API state, tool count, git, TPS, context, cost, compactions, memory, command, loop status, extensions |
62
- | `minimal` | mode, model, git, context, clock |
63
- | `compact` | mode, model, git, TPS, context, cost, clock, duration |
64
- | `full` | all groups, with a second row |
65
- | `ascii` | the same segments as `compact` |
66
-
67
- The hub list also shows `dense`, `devops` and `zen`. These names have no preset definition, so the footer uses `default` for them. To select `compact`, `full` or `ascii`, edit the settings file.
52
+ - **Width.** Each stats-line part has a priority. When the line does not fit, the lowest-priority parts drop whole (never mid-part), in this order: compactions, cache, time, turns, speed, cost — tokens always survive. The frame titles degrade the same way: the Kanboard label, the Fusion pair, the plan/permission cluster and the mode label drop (lowest value first) before the branch or model ever truncate.
53
+ - **Width safety.** Nothing ever writes the last terminal column (a full-width line desyncs wrapping terminals).
54
+ - **Height.** Below 20 terminal rows the stats line and the background-task line hide; the frame stays.
68
55
 
69
56
  ## Settings
70
57
 
@@ -72,33 +59,32 @@ Open `/unipi:settings` → **Footer**. The file is `~/.unipi/config/footer/confi
72
59
 
73
60
  | Key | Default | What it does |
74
61
  |---|---|---|
75
- | `enabled` | `true` | Turns the footer on or off. |
76
- | `glanceMode` | `true` | Uses the glance frame around the input. |
77
- | `preset` | `default` | Selects the segments of the classic status line. |
78
- | `showFullLabels` | `false` | Shows full labels in place of short labels. |
79
- | `separator` | `powerline-thin` | Segment divider: `powerline`, `powerline-thin`, `slash`, `pipe`, `dot`, `ascii`. |
80
- | `zoneSeparator` | `│` | Divider between the left, center and right zones. |
62
+ | `enabled` | `true` | Turns the footer on or off. `false` leaves the plain pi editor. |
81
63
  | `iconStyle` | `nerd` | Icon set: `nerd` (needs a Nerd Font), `emoji` or `text`. |
82
- | `colorMode` | `auto` | `auto`, `truecolor`, `256` or `none`. |
83
- | `groups.<group>.show` | `true` (`notify`: `false`) | Shows or hides a segment group. |
84
- | `groups.<group>.segments.<id>` | per segment | Shows or hides one segment. |
85
-
86
- `colorMode: auto` uses 24-bit color where the terminal supports it. It uses 256 colors in terminals such as Apple Terminal. It uses no color when the `NO_COLOR` environment variable exists.
87
-
88
- The hub **Color mode** list shows `mono`. The footer does not know this value and uses `auto`. Use `none` in the file to turn off color.
89
-
90
- For the full list of segments and icons, refer to [Footer customization](../../FOOTER_CUSTOMIZATION.md).
64
+ | `colorMode` | `auto` | `auto`, `truecolor`, `256` or `none`. The legacy value `mono` loads as `none`. |
65
+ | `rainbow` | `always` | `always` animates the brand (and the whole frame at `xhigh`/`max` thinking); `brand-only` never animates the whole frame; `off` disables the animation. |
66
+ | `processLine` | `true` | Shows the background-task line above the input. |
67
+ | `strip.turns` | `true` | Turn and step counters. |
68
+ | `strip.time` | `true` | Model time and tool time. |
69
+ | `strip.speed` | `true` | Average TTFT and tokens per second. |
70
+ | `strip.tokens` | `true` | Session input and output tokens. |
71
+ | `strip.cost` | `true` | Session cost, or `sub` when the model runs on a subscription. |
72
+ | `strip.compactions` | `true` | Compaction count, sizes and recency. |
73
+ | `strip.cache` | `true` | Cache hit percentage. |
74
+ | `badges.mode` | `true` | Long-horizon mode label beside the brand. |
75
+ | `badges.planPermission` | `true` | PLAN badge and permission mode in the top border. |
76
+ | `badges.fusion` | `true` | Fusion lead and sidekick in the bottom border. |
77
+ | `badges.kanboard` | `true` | Kanboard claims label in the top border. |
78
+
79
+ `colorMode: auto` uses 24-bit color where the terminal supports it, 256 colors in terminals such as Apple Terminal, and no color when the `NO_COLOR` environment variable exists.
80
+
81
+ Old v2 keys (`preset`, `separator`, `zoneSeparator`, `showFullLabels`, `groups`, `glanceMode`) in existing config files are ignored.
91
82
 
92
83
  ## How it works
93
84
 
94
- The footer listens to UniPi events on the [event bus](../../docs/architecture/event-bus.md). Examples are `MEMORY_STORED`, `MCP_SERVER_STARTED`, `RALPH_LOOP_START`, `WORKFLOW_START`, `COMPACTOR_COMPACTED` and `NOTIFICATION_SENT`. It keeps the last data of each event. Thus a package that loads after the footer still shows its data.
95
-
96
- Some segments read data directly: the Pi session, the Kanboard registry and the Info Screen cache. The footer draws again each second.
97
-
98
- The classic status line puts segments that do not fit into a second row.
85
+ The footer listens to UniPi events on the [event bus](../../docs/architecture/event-bus.md) for mode, plan and permission state. Usage data comes from an incremental scan of the session branch: each second only new entries are processed (a compaction or branch change triggers a full rescan), the same pass filling a cached snapshot for the stats line. The TPS tracker is fed live by pi's streaming events and reconciled by the same scan. The footer redraws when something it displays changed — plus once a second while the rainbow animates.
99
86
 
100
87
  ## See also
101
88
 
102
- - [Footer customization](../../FOOTER_CUSTOMIZATION.md)
103
89
  - [Info Screen](../info-screen/README.md)
104
90
  - [Settings reference](../../docs/reference/settings.md)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/footer",
3
- "version": "3.0.0-alpha.26",
3
+ "version": "3.0.0-alpha.28",
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.26",
36
- "@pi-unipi/background-tasks": "3.0.0-alpha.26"
35
+ "@pi-unipi/core": "3.0.0-alpha.28",
36
+ "@pi-unipi/background-tasks": "3.0.0-alpha.28"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,15 +1,14 @@
1
1
  /**
2
2
  * @pi-unipi/footer — Commands
3
3
  *
4
- * Footer commands: /unipi:footer (toggle) and /unipi:footer <preset>.
4
+ * /unipi:footer — toggle the footer on/off.
5
5
  */
6
6
 
7
7
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
8
8
  import { UNIPI_PREFIX, FOOTER_COMMANDS } from "@pi-unipi/core";
9
- import { loadFooterSettings, saveFooterSettings } from "./config.js";
10
- import { showFooterHelp } from "./help.js";
11
- import type { FooterSegment } from "./types.js";
12
- import { applyGlanceMode, type FooterState } from "./index.js";
9
+ import { saveFooterSettings } from "./config.js";
10
+ import type { FooterState } from "./index.js";
11
+ import { fullRescan } from "./index.js";
13
12
 
14
13
  /**
15
14
  * Register footer commands.
@@ -21,34 +20,17 @@ export function registerCommands(pi: ExtensionAPI, state: FooterState): void {
21
20
  handler: async (args, ctx) => {
22
21
  const arg = args?.trim().toLowerCase();
23
22
 
24
- // on
25
- if (arg === "on") {
26
- state.enabled = true;
27
- state.renderer.setActive(true);
28
- saveFooterSettings({ enabled: true });
29
- state.setupUI?.(pi, ctx);
30
- ctx.ui.notify("Footer enabled", "info");
31
- return;
32
- }
23
+ let enable: boolean;
24
+ if (arg === "on") enable = true;
25
+ else if (arg === "off") enable = false;
26
+ else enable = !state.enabled;
33
27
 
34
- // off
35
- if (arg === "off") {
36
- state.enabled = false;
37
- state.renderer.setActive(false);
38
- ctx.ui.setFooter(undefined);
39
- ctx.ui.setWidget("footer-top", undefined);
40
- ctx.ui.setWidget("footer-secondary", undefined);
41
- saveFooterSettings({ enabled: false });
42
- ctx.ui.notify("Footer disabled", "info");
43
- return;
44
- }
45
-
46
- // Toggle (no args or unknown args)
47
- state.enabled = !state.enabled;
48
- state.renderer.setActive(state.enabled);
28
+ state.enabled = enable;
29
+ saveFooterSettings({ enabled: enable });
49
30
 
50
- if (state.enabled) {
31
+ if (enable) {
51
32
  state.setupUI?.(pi, ctx);
33
+ fullRescan(state);
52
34
  ctx.ui.notify("Footer enabled", "info");
53
35
  } else {
54
36
  ctx.ui.setFooter(undefined);
@@ -56,17 +38,6 @@ export function registerCommands(pi: ExtensionAPI, state: FooterState): void {
56
38
  ctx.ui.setWidget("footer-secondary", undefined);
57
39
  ctx.ui.notify("Footer disabled", "info");
58
40
  }
59
-
60
- saveFooterSettings({ enabled: state.enabled });
61
- },
62
- });
63
-
64
- // /unipi:footer-help — show help overlay
65
- pi.registerCommand(`${UNIPI_PREFIX}${FOOTER_COMMANDS.FOOTER_HELP}`, {
66
- description: "Show footer segment guide (icons, labels, descriptions)",
67
- handler: async (_args, _ctx) => {
68
- const allSegments = Array.from(state.segmentLookup.values());
69
- showFooterHelp(pi, allSegments, state.renderer.getPresetName());
70
41
  },
71
42
  });
72
43
  }