@groeponline/pi-wishcraft 0.20.0 → 0.22.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +83 -0
  3. package/ROADMAP.md +18 -20
  4. package/bash-mode/editor-ghost.ts +63 -0
  5. package/bash-mode/editor-history.ts +81 -0
  6. package/bash-mode/editor-input.ts +35 -0
  7. package/bash-mode/editor.ts +16 -134
  8. package/bash-mode/shell-session.ts +12 -15
  9. package/bash-mode/types.ts +2 -0
  10. package/docs/bash-mode.md +46 -0
  11. package/docs/commands.md +122 -0
  12. package/docs/configuration.md +307 -0
  13. package/docs/index.md +18 -0
  14. package/docs/segments.md +168 -0
  15. package/docs/skill-manager.md +7 -0
  16. package/docs/stash-and-shortcuts.md +64 -0
  17. package/docs/working-vibes.md +71 -0
  18. package/package.json +2 -1
  19. package/queue/store.ts +72 -3
  20. package/src/config/custom-items.ts +45 -0
  21. package/src/config/parse.ts +19 -3
  22. package/src/config/powerline-config.ts +5 -0
  23. package/src/config/primitives.ts +13 -1
  24. package/src/config/segment-options.ts +29 -24
  25. package/src/config/settings-patch.ts +23 -2
  26. package/src/config/types.ts +32 -17
  27. package/src/extension/commands/bash-mode-actions.ts +1 -0
  28. package/src/extension/commands/commands.ts +36 -18
  29. package/src/extension/commands/powerline-completions.ts +8 -0
  30. package/src/extension/commands/powerline-doctor.ts +247 -0
  31. package/src/extension/commands/powerline-export.ts +94 -0
  32. package/src/extension/commands/queue-commands.ts +29 -1
  33. package/src/extension/commands/vibe-command.ts +49 -1
  34. package/src/extension/core/constants.ts +1 -0
  35. package/src/extension/core/segment-context.ts +38 -2
  36. package/src/extension/core/state.ts +5 -1
  37. package/src/extension/core/status-export.ts +68 -0
  38. package/src/extension/core/types.ts +4 -0
  39. package/src/extension/hooks/repairs.ts +89 -16
  40. package/src/extension/session/activate.ts +1 -2
  41. package/src/extension/session/cost-alert.ts +36 -0
  42. package/src/extension/session/session-lifecycle.ts +82 -1
  43. package/src/extension/settings/settings-io.ts +23 -17
  44. package/src/extension/settings/wishcraft-config.ts +2 -1
  45. package/src/extension/shortcuts/shortcuts-config.ts +5 -0
  46. package/src/extension/ui/layout.ts +1 -1
  47. package/src/extension/ui/menu-items.ts +379 -0
  48. package/src/extension/ui/menu-views.ts +377 -191
  49. package/src/extension/ui/overlay-chrome.ts +163 -0
  50. package/src/extension/ui/powerline-menu-view.ts +2 -4
  51. package/src/extension/ui/token-overlays.ts +82 -0
  52. package/src/extension/welcome/welcome-integration.ts +5 -9
  53. package/src/segments/registry.ts +100 -39
  54. package/src/segments/system.ts +204 -64
  55. package/src/segments/usage.ts +10 -4
  56. package/src/usage/ledger.ts +6 -0
  57. package/src/usage/token-budget.ts +57 -0
  58. package/src/usage/tps-ring.ts +151 -0
  59. package/src/usage/usage-store.ts +351 -0
  60. package/src/welcome/banner.ts +2 -1
  61. package/src/welcome/index.ts +3 -1
  62. package/src/welcome/overlay.ts +2 -0
  63. package/src/welcome/renderer.ts +52 -10
  64. package/src/welcome/types.ts +1 -2
  65. package/src/welcome/whats-new.ts +156 -0
  66. package/src/welcome/widgets/index.ts +3 -0
  67. package/src/welcome/widgets/whats-new-widget.ts +19 -0
  68. package/src/working-vibes/generate.ts +144 -58
  69. package/src/working-vibes/index.ts +10 -2
  70. package/src/working-vibes/storage.ts +5 -0
@@ -0,0 +1,46 @@
1
+ # Bash mode
2
+
3
+ Toggle bash mode with either:
4
+
5
+ - `ctrl+shift+b`
6
+ - `/bash-mode on`
7
+ - `/bash-mode off`
8
+ - `/bash-mode toggle`
9
+
10
+ Reset the managed shell with `/bash-reset`.
11
+
12
+ While bash mode is active:
13
+
14
+ - Enter runs the current shell command
15
+ - Right Arrow accepts ghost text into the editor without running it
16
+ - Tab completes the ghost suggestion one token/segment at a time (repeat Tab to step through each further token); once the full suggestion is inserted it clears, otherwise Tab does nothing
17
+ - Up and Down browse matching shell history
18
+ - `escape` exits bash mode and returns to normal prompt mode
19
+ - `ctrl+c` interrupts the active shell job before falling back to normal pi behavior
20
+
21
+ The managed shell is persistent for the current pi session. Command output appears in a transcript below the editor, and shell cwd changes are reflected in the footer path and `shell_mode` segment.
22
+
23
+ ## Shell ghost suggestions
24
+
25
+ Bash mode is ghost-first. Successful per-project shell history is the primary source, while deterministic path and git continuations can still extend an existing command. Shell-native completion probes are disabled so `!command` predictions never spawn interactive shell completion subprocesses.
26
+
27
+ At command position, short stems first resolve from the newest successful local command, can use guarded global shell history for high-confidence heads like `git`, and finally fall back to a tiny curated default set when history is absent. Right now that curated set is `g` → `git status` and `c` → `cd ..`.
28
+
29
+ If the bash prompt is empty, bash mode shows the newest successful project-history ghost suggestion immediately when one exists, including right after mode entry or after the prompt is cleared again. One-off `!command` and `!!command` prompts reuse the same shell prediction pipeline, including ghost text. Right Arrow or Tab accepts ghost text into the editor, and Enter runs the current shell command. Mode entry stays quiet: there is no automatic or manual dropdown completion surface, and ghost suggestions do not run shell-native completion probes.
30
+
31
+ ## Configuration
32
+
33
+ In `~/.pi/agent/settings.json` (or under `PI_CODING_AGENT_DIR` when that environment variable is set):
34
+
35
+ ```json
36
+ {
37
+ "bashMode": {
38
+ "toggleShortcut": "ctrl+shift+b",
39
+ "transcriptMaxLines": 2000,
40
+ "transcriptMaxBytes": 524288,
41
+ "initScript": "export NODE_ENV=development\nalias g='git status'"
42
+ }
43
+ }
44
+ ```
45
+
46
+ `initScript` is a project-scoped shell setup block: it is sourced once when the managed shell starts (before your first command), so a repo can export env vars, define aliases, or set shell options per project. Put it in the project-local `.pi/settings.json` to keep it repo-specific; omit it (or use a global `bashMode` entry) otherwise.
@@ -0,0 +1,122 @@
1
+ # Commands & interactivity
2
+
3
+ ## Usage
4
+
5
+ Activates automatically. Toggle with `/powerline`, switch presets with `/powerline <name>`, and move the primary row with `/powerline placement above|below|toggle`.
6
+
7
+ Use `/cd <path>` to continue the current conversation from another working directory. It supports relative paths, absolute paths, `~`, `~/...`, and directory completions. With no argument, `/cd` prints the current Pi session directory. The command switches into a cwd-updated session file so Pi tools and the footer path segment agree after the change.
8
+
9
+ ### Powerline Queue + Inbox
10
+
11
+ Commands and capture shortcuts:
12
+
13
+ - `# <text>`: capture an idea for the current project without sending it to the agent
14
+ - `# @global <text>`: capture a global idea
15
+ - `# @current <text>`: capture an idea targeted to the current session
16
+ - `/queue alias <name> [path]`: save a project alias, defaulting to the current cwd when `path` is omitted
17
+ - `# @name <text>`: capture an idea for a saved project alias
18
+ - `/compact <text>`: compact now and queue `<text>` as the next prompt after successful compaction
19
+ - `/idea [@target] <text>`: command form of idea capture, useful for scripts and users who disable the sigil
20
+ - `/idea issue [id]`: hand the oldest active idea, or a specific idea, to the current agent for safe GitHub issue triage
21
+ - `/ideas`: open the captured-ideas picker
22
+ - `/ideas next`: send the oldest active idea to the current session
23
+ - `/ideas issue [id]`: ask the current agent to dedupe and file a GitHub issue only when the target repo is clear and owned/controlled
24
+ - `/ideas send <id>`: send an idea to the current session
25
+ - `/queue`: open the queued-prompt picker
26
+ - `/queue send [id]` / `/queue retry [id]`: deliver a queued item now
27
+ - `/queue clear <id|all>`: clear queued prompt items
28
+ - `/queue target <id> @name|global|current`: retarget a queued item
29
+ - `/queue archive [hours]`: move completed items older than the retention window from `inbox.jsonl` into `inbox.archive.jsonl`
30
+
31
+ The default capture sigil is `#`. When the editor text starts with `#` followed by a space, the prompt glyph changes to `#`; pressing Enter saves the idea, clears the editor, and leaves the original sigil text in editor history for quick recovery. Configure or disable this under `powerline.queue.captureSigil`:
32
+
33
+ ```json
34
+ {
35
+ "powerline": {
36
+ "queue": {
37
+ "captureSigil": "#"
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ Set `captureSigil` to `false` if you often submit markdown headings and prefer `/idea` instead.
44
+
45
+ `powerline.queue.retentionHours` (default `24`) controls how long completed (sent) items stay in the inbox before `/queue archive` moves them to `inbox.archive.jsonl` and before the store prunes them on the next write:
46
+
47
+ ```json
48
+ {
49
+ "powerline": {
50
+ "queue": {
51
+ "captureSigil": "#",
52
+ "retentionHours": 72
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ Captured data is stored under the Pi agent directory in `powerline-footer/inbox.jsonl` and `powerline-footer/projects.json`. `inbox.jsonl` is a stable read surface for orchestrators and helper agents; each line is a queue item with `id`, `text`, `createdAt`, `updatedAt`, `source`, `target`, `intent`, `status`, and optional `error`. Writes should still go through Powerline commands or the store so locking and atomic writes are preserved. Ideas sent with `/ideas next` or `/ideas send <id>` include a small provenance header so the receiving agent can treat them as deferred captured context. `/idea issue` and `/ideas issue` do not file issues directly from the extension; they send a guarded handoff prompt that tells the current agent to dedupe open issues first, create a GitHub issue only for a clear owned/controlled repo, and ask before filing when the target is unclear.
59
+
60
+ ### Placement
61
+
62
+ - `/powerline placement below`: move the primary powerline row below the editor
63
+ - `/powerline placement above`: restore the default placement
64
+ - `/powerline placement toggle`: switch between above and below
65
+
66
+ You can also set it in the agent settings file (`~/.pi/agent/settings.json` by default, or under `PI_CODING_AGENT_DIR`) or project-local `.pi/settings.json`:
67
+
68
+ ```json
69
+ {
70
+ "showLastPrompt": true,
71
+ "powerline": {
72
+ "preset": "default",
73
+ "placement": "below",
74
+ "welcome": true
75
+ }
76
+ }
77
+ ```
78
+
79
+ ## Presets
80
+
81
+ | Preset | Description |
82
+ |--------|-------------|
83
+ | `default` | Balanced daily driver: model, thinking, path (basename), git (branch + dirty + latest commit + ↑/↓ ahead-behind + host icon), session, queue, subagent cost, tokens in/out, cache-hit%, cost, context |
84
+ | `minimal` | Just path (basename), git branch and context% (branch-only polling, no indicators/commit) |
85
+ | `compact` | Model, git (short commit + ahead/behind), queue, cost, context%, session id |
86
+ | `full` | Everything: hostname, model, path (abbreviated), full git incl commit + ↑/↓, totals, context total, elapsed + clock |
87
+ | `nerd` | Maximum detail for Nerd Font users: qualified model, full tokens + cache, commit, totals, seconds clock |
88
+ | `ascii` | Safe for any terminal: branch + short commit + ↑/↓, tokens, cost, context% (no Nerd glyphs) |
89
+ | `chef` | Fork default: muted colors, slash separators, live TPS in/out + open-ports + subagent-cost segments |
90
+
91
+ **Environment:** `POWERLINE_NERD_FONTS=1` to force Nerd Fonts, `=0` for ASCII.
92
+
93
+ Preset selection is saved under `powerline` in the agent settings file and restored on startup. Run `/powerline default` to switch back to the default preset.
94
+
95
+ ## Interactivity
96
+
97
+ Pi core renders the footer as static text, so live click is not possible; actions live in commands and a navigable overlay.
98
+
99
+ - `/tps`: overlay of the live 1s window (same ring as the segment). `/tps <value>` sets `POWERLINE_TPS`
100
+ - `/usage`: session / today / week overlay from `~/.pi/agent/wishcraft-usage.json`
101
+ - `/open-ports`: list listening ports and pick one
102
+ - `/powerline doctor`: diagnostics overlay — settings file validity, unknown presets, Nerd Font detection, git polling, bash-mode status, and queue file health
103
+ - `/powerline export`: export the current preset + effective layout + labels as a JSON snippet (Enter copies it to the clipboard)
104
+ - `alt+p`: **powerline menu**: navigate the live segments (`↑`/`↓` + `enter`, `→`/`tab` opens a per-segment detail panel; values refresh every second while open), configure (preset / TPS / UDP / segment visibility / labels / build custom preset), or open the full ports list
105
+ - `alt+i`: **powerline info**: full open-ports list
106
+
107
+ Both `alt+p` and `alt+i` are rebindable (see Keybinds below); changes apply after `/reload`.
108
+
109
+ ## Keybinds
110
+
111
+ The powerline menu and info shortcuts are configurable via `powerlineShortcuts` (same map as the other powerline shortcuts), with automatic conflict resolution. Set a binding to `null` to disable it.
112
+
113
+ ```json
114
+ {
115
+ "powerlineShortcuts": {
116
+ "menu": "alt+p",
117
+ "info": "alt+i"
118
+ }
119
+ }
120
+ ```
121
+
122
+ Changes apply after `/reload` (the extension re-registers shortcuts on reload).
@@ -0,0 +1,307 @@
1
+ # Configuration
2
+
3
+ ## Custom items from extension statuses
4
+
5
+ You can promote any extension status key into its own dedicated powerline item. This gives you a general way to register your own status items without changing this extension.
6
+
7
+ 1. Any extension can publish status text through `ctx.ui.setStatus("my-key", "...value...")`.
8
+ 2. Configure `powerline.customItems` to place those keys on the left, right, or secondary row.
9
+
10
+ ```json
11
+ {
12
+ "powerline": {
13
+ "preset": "default",
14
+ "customItems": [
15
+ {
16
+ "id": "ci",
17
+ "statusKey": "ci-status",
18
+ "position": "right",
19
+ "prefix": "CI",
20
+ "color": "warning"
21
+ },
22
+ {
23
+ "id": "review",
24
+ "position": "secondary",
25
+ "hideWhenMissing": false,
26
+ "prefix": "review"
27
+ }
28
+ ]
29
+ }
30
+ }
31
+ ```
32
+
33
+ `customItems` fields:
34
+
35
+ - `id` (required): unique item id (`a-z`, `A-Z`, `0-9`, `_`, `-`)
36
+ - `statusKey` (optional): extension status key to read, defaults to `id`
37
+ - `position` (optional): `left`, `right`, or `secondary` (default `right`)
38
+ - `prefix` (optional): text shown before the live status value
39
+ - `color` (optional): any Pi theme color (`warning`, `accent`, etc.) or hex (`#RRGGBB`)
40
+ - `hideWhenMissing` (optional): hide item when no status is present (default `true`)
41
+ - `excludeFromExtensionStatuses` (optional): omit this key from the aggregate `extension_statuses` segment (default `true`)
42
+
43
+ ### Auto-promote every status key (`customItems.auto`)
44
+
45
+ Instead of listing each status key explicitly, set `powerline.customItems.auto: true` to turn every live extension status key into its own right-aligned segment. This is the ChefBar status bridge: any extension that calls `ctx.ui.setStatus("some-key", "value")` gets a matching segment automatically, without edits to this extension.
46
+
47
+ ```json
48
+ {
49
+ "powerline": {
50
+ "customItems": {
51
+ "auto": true
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ Auto items follow the same rules as explicit items: notification-style statuses, internal/excluded keys, and keys already claimed by an explicit item are skipped, and each auto item is excluded from the aggregate `extension_statuses` segment so a status renders exactly once. Mix `auto` with explicit entries by using the object form of `customItems`:
58
+
59
+ ```json
60
+ {
61
+ "powerline": {
62
+ "customItems": {
63
+ "auto": true,
64
+ "ci": { "statusKey": "ci-status", "prefix": "CI", "color": "warning" }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ If you still prefer the older string preset config shape, `"powerline": "default"` continues to work. String preset shorthand keeps `welcome` enabled and uses the default shortcut/cost/model display settings.
71
+
72
+ ## Custom segments (computed, no code)
73
+
74
+ Define your own segments directly in settings: run a command, read an env var, or show static text. No TypeScript needed.
75
+
76
+ ```json
77
+ {
78
+ "powerline": {
79
+ "preset": "chef",
80
+ "segments": {
81
+ "battery": { "type": "command", "command": "cat /sys/class/power_supply/BAT0/capacity", "prefix": "batt", "cacheMs": 30000 },
82
+ "who": { "type": "env", "env": "USER", "prefix": "u", "color": "#888888" },
83
+ "chef": { "type": "static", "text": "CHEF", "color": "accent" }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ Each segment becomes usable in a preset as `custom:<id>` (e.g. `custom:battery`).
90
+
91
+ Segment fields:
92
+
93
+ - `type` (required): `command` | `env` | `static`
94
+ - `command` (command type): shell command to run; output is trimmed
95
+ - `cacheMs` (command type, optional): cache output for N ms to avoid re-spawning a shell every paint
96
+ - `env` (env type): environment variable to read
97
+ - `fallback` (env type, optional): text shown when the variable is unset (omit to hide the segment)
98
+ - `text` (static type): fixed text
99
+ - `prefix` (optional): text shown before the value
100
+ - `color` (optional): Pi theme color (`warning`, `accent`, ...) or hex (`#RRGGBB`)
101
+
102
+ If a command fails or an env var is unset without a fallback, the segment renders nothing.
103
+
104
+ ## Custom presets
105
+
106
+ Define your own preset in settings; it merges over built-ins and is selectable via `powerline.preset` (or `/powerline <name>`).
107
+
108
+ ```json
109
+ {
110
+ "powerline": {
111
+ "preset": "mine",
112
+ "segments": { "battery": { "type": "command", "command": "cat /sys/class/power_supply/BAT0/capacity", "prefix": "batt" } },
113
+ "presets": {
114
+ "mine": {
115
+ "left": ["hostname", "model", "custom:battery", "git"],
116
+ "right": ["tps", "open_ports", "cost", "time"],
117
+ "separator": "slash",
118
+ "colors": { "model": "text" },
119
+ "segmentOptions": { "path": { "mode": "basename" } }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Build a preset from the menu
127
+
128
+ You don't have to edit JSON: `alt+p` → `Configure…` → `Build custom preset…` walks you through naming a preset, choosing a base preset (for its colors + segment options), picking left/right/secondary segments, and choosing a separator. It saves the result under `powerline.presets.<name>`, sets it as the active preset, and applies it immediately.
129
+
130
+ ## Segment labels (custom text)
131
+
132
+ Rename the text shown for **any** segment via `powerline.segmentLabels` (a map of segment id → label). The label appears between the icon and the value. Works for built-in segments, custom segments, and custom items alike.
133
+
134
+ ```json
135
+ {
136
+ "powerline": {
137
+ "segmentLabels": {
138
+ "tps": "speed",
139
+ "open_ports": "ports",
140
+ "time": "clock",
141
+ "git": "branch"
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## Segment templates (custom value format)
148
+
149
+ Full control over the rendered value with `powerline.segmentOptions.<id>.template`. The placeholder `{value}` is replaced with the segment's value text (the icon and label, if any, stay in place).
150
+
151
+ ```json
152
+ {
153
+ "powerline": {
154
+ "segmentOptions": {
155
+ "tps": { "template": "{value} tok/s" },
156
+ "open_ports": { "template": "{value} listeners" }
157
+ }
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## Disabling segments
163
+
164
+ Set `powerline.disabledSegments` to hide built-in or configured custom segments from the active preset. You can also toggle segments live from the `alt+p` menu (`Configure…` → `Toggle segment visibility…`), which persists to `powerline.disabledSegments`:
165
+
166
+ ```json
167
+ {
168
+ "powerline": {
169
+ "preset": "default",
170
+ "disabledSegments": ["cost", "extension_statuses", "custom:ci"]
171
+ }
172
+ }
173
+ ```
174
+
175
+ Built-in names are listed under Segments in [Segments & theming](./segments.md). Custom items use `custom:<id>`. Unknown names are ignored with a startup warning.
176
+
177
+ ## Open-ports host (fleet)
178
+
179
+ Make `open_ports` probe a named SSH host instead of the laptop:
180
+
181
+ ```json
182
+ {
183
+ "powerline": {
184
+ "segmentOptions": {
185
+ "openPorts": { "host": "sofie", "includeUdp": false }
186
+ }
187
+ }
188
+ }
189
+ ```
190
+
191
+ See [Segments & theming](./segments.md) for the probe's best-effort behavior and requirements.
192
+
193
+ ## Status bridge for other extensions
194
+
195
+ Powerline publishes its own state under a stable key set so ChefBar and other extensions can read it without depending on powerline internals:
196
+
197
+ | Status key | Value |
198
+ |------------|-------|
199
+ | `powerline.preset` | Active preset name (e.g. `chef`) |
200
+ | `powerline.tps` | `POWERLINE_TPS` override, cleared when live rate is used |
201
+ | `powerline.ports` | Open-port count (`?` when a fleet host probe fails) |
202
+
203
+ The keys update on preset change, `/tps`, the open-ports list, and the UDP toggle. They are intentionally hidden from powerline's own `extension_statuses` segment (they exist for other extensions to consume).
204
+
205
+ ## Cost alert
206
+
207
+ Set `powerline.costAlert` to a USD threshold to get a single warning notification per session when the running session spend (assistant + subagent cost) reaches it. Omit it or set `0` to disable.
208
+
209
+ ```json
210
+ {
211
+ "powerline": {
212
+ "costAlert": 5
213
+ }
214
+ }
215
+ ```
216
+
217
+ ## Hooks and repairs
218
+
219
+ Command hooks live under `wishcraft.hooks` in the **global** agent settings file. `wishcraft.hooksEnabled: false` is the kill-switch. See the README Hooks section for three copy-paste examples (bash-guard, write-audit, SessionStart git-status).
220
+
221
+ Tool-input repairs apply to custom/extension tools only (`wishcraft.repairsEnabled`, default on). `/repairs` prints the counters.
222
+
223
+ ## Token budget
224
+
225
+ `wishcraft.tokenBudget.daily` is a token count (input + output + cache). At 80% the cost segment turns warning-coloured; at 100% it turns red and welcome notifies. It never blocks a turn.
226
+
227
+ ```json
228
+ {
229
+ "wishcraft": {
230
+ "tokenBudget": { "daily": 500000 }
231
+ }
232
+ }
233
+ ```
234
+
235
+ ## Custom layout
236
+
237
+ Use `powerline.layout` to override segment order and grouping while keeping the selected preset's colors and segment options. Set `powerline.separator` when you want a separator style independent of the preset:
238
+
239
+ ```json
240
+ {
241
+ "powerline": {
242
+ "preset": "default",
243
+ "separator": "chevron",
244
+ "layout": {
245
+ "left": ["model", "thinking", "path", "git"],
246
+ "right": ["context_pct", "cost"],
247
+ "secondary": ["custom:ci"]
248
+ },
249
+ "customItems": [
250
+ { "id": "ci", "statusKey": "ci-status" }
251
+ ]
252
+ }
253
+ }
254
+ ```
255
+
256
+ A present `left`, `right`, or `secondary` array replaces that preset group exactly; an empty array clears it. Omitted groups keep the preset entries and automatically append custom items by their configured `position`. Explicitly listing a segment moves it out of omitted preset groups, and explicitly placed custom items are not auto-appended elsewhere. `disabledSegments` is applied after layout. `separator` accepts any style listed in [Segments & theming](./segments.md); omit it to keep the preset's separator.
257
+
258
+ Responsive behavior is unchanged: these groups control ordering and overflow priority, not permanently pinned terminal rows. `right` means "later primary segments," not right-edge alignment. On wide terminals secondary entries can fit in the top bar; on narrow terminals primary overflow moves into the secondary line. Some segments are hidden when they have no value, so `thinking` appears only when the active session/model reports a non-`off` thinking level. Unknown entries are ignored with a startup warning. The old fixed `custom` preset has been removed; combine any preset with `layout` instead.
259
+
260
+ ## Demo settings
261
+
262
+ For a compact current footer setup:
263
+
264
+ ```json
265
+ {
266
+ "powerline": {
267
+ "preset": "default",
268
+ "path": { "mode": "basename" },
269
+ "model": { "display": "name" },
270
+ "cost": { "subscriptionDisplay": "subscription", "currency": "USD" }
271
+ }
272
+ }
273
+ ```
274
+
275
+ Use `"model": { "display": "qualified" }` when two providers expose models with the same display name.
276
+
277
+ ### Cost currency
278
+
279
+ `cost.currency` accepts `USD`, `CNY`, `EUR`, `GBP`, `JPY`, `CAD`, `AUD`, `CHF`, `INR`, or `KRW`. Pi reports costs in USD; non-USD display uses a keyless USD FX rate fetched in the background and cached for 24 hours under the Pi agent directory. If no cached rate is available yet, the cost segment renders `-- CODE` until a later footer refresh can use the fetched rate.
280
+
281
+ ### Subscription cost display
282
+
283
+ | Mode | Subscription + reported cost | Subscription + no reported cost |
284
+ |------|------------------------------|----------------------------------|
285
+ | `subscription` | `(sub)` | `(sub)` |
286
+ | `reported-cost` | `$0.12` | `(sub)` |
287
+ | `both` | `$0.12 (sub)` | `(sub)` |
288
+
289
+ ### Segment display formats
290
+
291
+ Opt-in; defaults match the historical rendering.
292
+
293
+ | Segment option | Values | Default | Effect |
294
+ |---|---|---|---|
295
+ | `"context": { "format" }` | `"full"` / `"percent"` | `"full"` | `"percent"` shows a bare rounded `83%` (threshold-colored, no icon) instead of `12k/200k (6.2%)` |
296
+ | `"cache_read": { "format" }` | `"tokens"` / `"percent"` / `"both"` | `"tokens"` | `"percent"` shows the cache hit rate `cacheRead / (input + cacheRead)` instead of the raw token count; `"both"` shows raw tokens plus the hit rate, e.g. `cache in: 12k (80%)` |
297
+ | `"tps": { "windowMs" }` | number, clamped to 500–5000 | `1000` | Length of the sliding rate window; widen it (e.g. `2000`) for a smoother read on very fast models |
298
+ | `"<segment>": { "template" }` | string with `{value}` | — | Replaces the segment's value text; see Segment templates above |
299
+
300
+ ```json
301
+ {
302
+ "powerline": {
303
+ "context": { "format": "percent" },
304
+ "cache_read": { "format": "both" }
305
+ }
306
+ }
307
+ ```
package/docs/index.md ADDED
@@ -0,0 +1,18 @@
1
+ # pi-wishcraft documentation
2
+
3
+ This is the detailed documentation split out of the top-level `README.md`.
4
+ The README stays a short landing page; everything below lives here.
5
+
6
+ ## Guides
7
+
8
+ - [Commands & interactivity](./commands.md) — `/powerline`, `/tps`, `/usage`, `/queue`, `/idea`, placement, presets, keybinds, and the navigable overlay.
9
+ - [Configuration](./configuration.md) — custom items, hooks, repairs, token budget, labels, templates, layout, cost alert, and display formats.
10
+ - [Bash mode](./bash-mode.md) — sticky shell, ghost suggestions, and shell config.
11
+ - [Stash & shortcuts](./stash-and-shortcuts.md) — editor stash, prompt history, clipboard/navigation shortcuts, and shortcut config.
12
+ - [Skill manager](./skill-manager.md) — browsing and inserting installed skills.
13
+ - [Working vibes](./working-vibes.md) — themed loading messages, modes, and configuration.
14
+ - [Segments & theming](./segments.md) — segment reference, separators, thinking/path/git options, and theme overrides.
15
+
16
+ ## Planning
17
+
18
+ - [ROADMAP.md](../ROADMAP.md) — release campaigns and leftover 0.20 / 1.0 work.
@@ -0,0 +1,168 @@
1
+ # Segments & theming
2
+
3
+ ## The `chef` preset
4
+
5
+ `preset: "chef"` is the GroepOnline fork's default look: muted colors (no rainbow), slash separators, and two extra right-side segments:
6
+
7
+ - `tps`: live tokens/sec over a rolling 1-second window (EMA-free, no spikes), now reporting **output and input** rates separately (`⇡out ⇣in`) so you can see generation speed and incoming prompt tokens at a glance. A rocket/bolt icon lights up while streaming (override with env `POWERLINE_TPS`).
8
+ - `open_ports`: count of unique **TCP** listening ports (`ss` → `netstat` → `/proc/net` fallback, dedupes IPv4/IPv6). Set `segmentOptions.openPorts.includeUdp: true` to include noisy UDP (mDNS/DHCP/ephemeral).
9
+
10
+ ### Open-port process owners
11
+
12
+ Open the segment detail view (`alt+p` → `Navigate segments` → `open_ports` → `→`) to see **which process owns each listening port**. It best-effort parses `ss -tulnp` (falling back to `netstat -tulnp`), so the row list shows `tcp:3000 → node (12345)` per port; a port without a visible owner is marked `(unknown)`. The result is cached for 2 seconds so the live navigator refresh stays cheap. The full `alt+i` ports list shows the raw `ss -p` process column as well.
13
+
14
+ ### Fleet open-ports (SSH probe)
15
+
16
+ `open_ports` is laptop-local by default. Set `powerline.segmentOptions.openPorts.host` to probe a named fleet host over SSH instead:
17
+
18
+ ```json
19
+ {
20
+ "powerline": {
21
+ "segmentOptions": {
22
+ "openPorts": { "host": "sofie" }
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ `host` accepts a hostname, `user@host`, or IPv4 address (validated to prevent shell injection). The probe is best-effort: it runs `ssh` in `BatchMode` with a 3-second connect timeout, so it requires passwordless/agent SSH and the host to already be in `known_hosts`. When the probe can't run (no `ss`/`netstat` remotely, unreachable host, missing key), the segment shows `?` instead of a misleading `0`. The detail view and `alt+i` full list reuse the same remote probe.
29
+
30
+ ## Thinking level display
31
+
32
+ The thinking segment shows live updates when you change thinking level:
33
+
34
+ | Level | Display | Color |
35
+ |-------|---------|-------|
36
+ | off | `think:off` | gray |
37
+ | minimal | `think:min` | purple-gray |
38
+ | low | `think:low` | blue |
39
+ | medium | `think:med` | teal |
40
+ | high | `think:high` | rainbow |
41
+ | xhigh | `think:xhigh` | rainbow |
42
+ | max | `think:max` | rainbow |
43
+
44
+ ## Path display
45
+
46
+ The path segment supports three modes:
47
+
48
+ | Mode | Example | Description |
49
+ |------|---------|-------------|
50
+ | `basename` | `powerline-footer` | Just the directory name (default) |
51
+ | `abbreviated` | `…/extensions/powerline-footer` | Full path with home abbreviated and length limit |
52
+ | `full` | `~/.pi/agent/extensions/powerline-footer` | Complete path with home abbreviated |
53
+
54
+ Configure via preset options: `path: { mode: "full" }`
55
+
56
+ ## Git polling
57
+
58
+ By default the git segment polls both branch and dirty state. If background `git status --porcelain` calls interfere with your workflow, use branch-only polling:
59
+
60
+ ```json
61
+ {
62
+ "powerline": {
63
+ "git": { "polling": "branch" }
64
+ }
65
+ }
66
+ ```
67
+
68
+ Use `"off"` to disable extension-owned git polling entirely and only show the branch reported by Pi when available.
69
+
70
+ ## Git host icon
71
+
72
+ Set `git.hostIcon` to replace the branch icon with the origin remote's host logo:
73
+
74
+ ```json
75
+ {
76
+ "powerline": {
77
+ "git": { "hostIcon": true }
78
+ }
79
+ }
80
+ ```
81
+
82
+ The origin remote is detected (SSH or HTTPS) and mapped to an icon: GitHub (`nf-fa-github`), GitLab (`nf-fa-gitlab`), Bitbucket (`nf-fa-bitbucket`), or a generic git logo (`nf-fa-git`) for any other remote (self-hosted, Gitea, Codeberg, …). Repositories without an origin remote keep the plain branch icon (`nf-fa-code_fork`), as do ASCII (non–Nerd Font) setups. The remote is read once and cached, so this adds no per-render cost. Default is `false` (branch icon unchanged).
83
+
84
+ ## Git status extras (commits, ahead/behind)
85
+
86
+ The git segment can also show the last commit on `HEAD` (short hash + subject) and the upstream ahead/behind counts — handy for a quick "where am I relative to main" GitHub signal:
87
+
88
+ - `git.showCommit` (`true` by default) — appends `#<hash> <subject>` for the latest commit.
89
+ - `git.maxCommitSubjectLength` (`24`) — truncates the commit subject shown.
90
+ - `git.showAheadBehind` (`true` by default) — appends `↑<n> ↓<n>` for commits ahead/behind the configured upstream (hidden when there is no upstream).
91
+
92
+ ```json
93
+ {
94
+ "powerline": {
95
+ "git": { "showCommit": true, "showAheadBehind": true, "maxCommitSubjectLength": 24 }
96
+ }
97
+ }
98
+ ```
99
+
100
+ The `minimal` and `compact` presets keep these off to stay lean; set `showCommit: true`/`showAheadBehind: true` to enable them.
101
+
102
+ ## Segments
103
+
104
+ `model` · `shell_mode` · `path` · `git` · `subagents` · `queue` · `token_in` · `token_out` · `token_total` · `cost` · `context_pct` · `context_total` · `time_spent` · `time` · `session` · `hostname` · `cache_read` · `cache_write` · `thinking` · `tps` · `open_ports` · `extension_statuses`
105
+
106
+ ## Separators
107
+
108
+ `powerline` · `powerline-thin` · `slash` · `pipe` · `dot` · `chevron` · `star` · `block` · `none` · `ascii`
109
+
110
+ ## Theming
111
+
112
+ Colors are configurable via pi's theme system. Each preset defines its own color scheme, and you can override individual colors and icons with a `theme.json` file in the extension directory.
113
+
114
+ ### Default colors
115
+
116
+ | Semantic | Theme Color | Description |
117
+ |----------|-------------|-------------|
118
+ | `model` | `#d787af` | Model name |
119
+ | `shellMode` | `accent` | Bash mode segment |
120
+ | `path` | `#00afaf` | Directory path |
121
+ | `gitClean` | `success` | Git branch (clean) |
122
+ | `gitDirty` | `warning` | Git branch (dirty) |
123
+ | `thinking` | `thinkingOff` | Thinking level (`off`) |
124
+ | `thinkingMinimal` | `thinkingMinimal` | Thinking level (`minimal`) |
125
+ | `thinkingLow` | `thinkingLow` | Thinking level (`low`) |
126
+ | `thinkingMedium` | `thinkingMedium` | Thinking level (`medium`) |
127
+ | `context` | `dim` | Context usage |
128
+ | `contextWarn` | `warning` | Context usage >70% |
129
+ | `contextError` | `error` | Context usage >90% |
130
+ | `cost` | `text` | Cost display |
131
+ | `tokens` | `muted` | Token counts |
132
+ | `queue` | `accent` | Queue / ideas / blocked counts |
133
+ | `separator` | `dim` | Segment separators and ahead/behind counts |
134
+ | `border` | `borderMuted` | Panel/border chrome |
135
+
136
+ ### Custom theme override
137
+
138
+ Create `extensions/powerline-footer/theme.json` in the agent dir (`~/.pi/agent` by default, or `PI_CODING_AGENT_DIR` when set):
139
+
140
+ ```json
141
+ {
142
+ "colors": {
143
+ "model": "accent",
144
+ "shellMode": "accent",
145
+ "path": "#00afaf",
146
+ "gitClean": "success",
147
+ "thinking": "thinkingOff",
148
+ "thinkingMinimal": "thinkingMinimal",
149
+ "thinkingLow": "thinkingLow",
150
+ "thinkingMedium": "thinkingMedium"
151
+ },
152
+ "icons": {
153
+ "auto": "↯",
154
+ "warning": ""
155
+ }
156
+ }
157
+ ```
158
+
159
+ Colors can be:
160
+
161
+ - **Theme color names**: `accent`, `muted`, `dim`, `text`, `success`, `warning`, `error`, `border`, `borderAccent`, `borderMuted`
162
+ - **Hex colors**: `#ff5500`, `#d787af`
163
+
164
+ Icons can be any string, including `""` when you want to suppress a specific glyph entirely.
165
+
166
+ For npm package installs, this documented agent-dir file is separate from the package files under `~/.pi/agent/npm/node_modules`. The extension reads the agent-dir override first, then falls back to a `theme.json` colocated with the loaded extension file. Use `/reload` or restart Pi after creating or editing `theme.json`.
167
+
168
+ See `theme.example.json` for all available options.
@@ -0,0 +1,7 @@
1
+ # Skill manager
2
+
3
+ Browse and insert your installed skills (`SKILL.md` files and `*.md`/`*.txt` prompts) from an interactive TUI overlay:
4
+
5
+ - **`/skills`** — open the skill manager. Filter with plain typing, `↑↓` to move, `enter` to open a skill's detail body, `↑↓` in the detail to scroll, `enter`/`tab` to insert the skill content into your prompt, `esc` to go back/close.
6
+
7
+ The manager reuses the same skill discovery as inline `/command`/`$skill` triggers, so anything you can inline you can also browse and insert manually.