@groeponline/pi-wishcraft 0.22.0 → 0.22.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/CHANGELOG.md +13 -0
- package/README.md +75 -644
- package/ROADMAP.md +5 -5
- package/docs/commands.md +1 -1
- package/docs/index.md +1 -2
- package/docs/segments.md +1 -1
- package/package.json +1 -1
- package/queue/store.ts +4 -2
- package/src/extension/ui/menu-views.ts +6 -25
- package/src/segments/system.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.22.2] - 2026-08-20
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Queue archive cutoff uses a frozen clock in tests, and the TPS "starts at 0" case resets the shared ring so file order cannot leak a fake rate.
|
|
9
|
+
|
|
10
|
+
## [0.22.1] - 2026-08-20
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- README is a landing page for the 0.22 cockpit. The Kongming banner stays; the inherited upstream screenshot is gone.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Segment-navigator detail (`→` in `alt+p` Navigate) snapshots live state when opened. It no longer runs a 1s timer (CHE-41).
|
|
17
|
+
|
|
5
18
|
## [0.22.0] - 2026-08-20
|
|
6
19
|
|
|
7
20
|
### Added
|
package/README.md
CHANGED
|
@@ -4,260 +4,69 @@
|
|
|
4
4
|
|
|
5
5
|
# pi-wishcraft
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Cockpit and harness for the [pi](https://github.com/badlogic/pi-mono) coding agent: a live status bar, overlay menus, skills, an idea inbox, sticky bash, hooks, and tool-input repairs. Stock pi stays the engine. This package is the operator layer.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
1. **Ground Telemetry**: A live status bar at the bottom border tracking git, tokens/sec, context window, and active process ports (Alt+P).
|
|
11
|
-
2. **Cast & Release (`# <idea>`)**: Queue ideas instantly without interrupting the active agent run.
|
|
12
|
-
3. **Autonomous Horizons**: The queue feeds background dreaming SDK routines, mission runners, and autoresearch loops while you work or sleep.
|
|
13
|
-
4. **Stash & Pivot (Alt+S)**: Park a prompt draft, ask a quick question, pop it back automatically.
|
|
14
|
-
5. **Sticky Shell (`!cmd`)**: A persistent bash runtime under your fingertips.
|
|
9
|
+
Kongming lanterns started as battlefield signals and later carried wishes. Wishcraft is that split in a coding session: telemetry on the bar, thoughts you can park without interrupting the run.
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
Install `@groeponline/pi-wishcraft`. It is listed on the [Pi package catalog](https://pi.dev/packages?name=wishcraft). Grew out of [`nicobailon/pi-powerline-footer`](https://github.com/nicobailon/pi-powerline-footer). Maintained by [GroepOnline](https://github.com/GroepOnline).
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
Guides live in [`docs/`](docs/index.md). This page is the contract: what ships, how to install it, and what can fail.
|
|
19
14
|
|
|
15
|
+
## Install
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
**Editor stash**: Press `Alt+S` to save your editor content and clear the editor, type a quick prompt, and your stashed text auto-restores when the agent finishes. Toggles between stash, pop, and update-existing-stash. A `stash` indicator appears in the powerline bar while text is stashed.
|
|
24
|
-
|
|
25
|
-
**Powerline Queue + Inbox**: Capture thoughts without interrupting the current agent. Type `# <idea>` and press Enter to save an idea instead of sending it; `# @global <idea>`, `# @current <idea>`, and `# @alias <idea>` route it. Messages typed during compaction are held by Powerline and delivered after successful compaction instead of disappearing into Pi's native queue. `/idea`, `/ideas`, and `/queue` provide a file-backed inbox for current-session prompts, project ideas, aliases, retries, clears, and manual delivery. Use `/ideas next` to work the oldest active idea in the current session, or `/ideas issue` to hand it to the current agent for safe GitHub issue triage. Active queue, idea, and blocked counts appear in the `queue` segment only when there is something to show.
|
|
26
|
-
|
|
27
|
-
**Working Vibes**: AI-generated themed loading messages. Set `/vibe star trek` and your "Working..." becomes "Running diagnostics..." or "Engaging warp drive...". Supports any theme: pirate, zen, noir, cowboy, etc.
|
|
28
|
-
|
|
29
|
-
**Welcome overlay**: Branded splash screen shown as centered overlay on startup. Shows gradient logo, model info, keyboard tips, loaded AGENTS.md/extensions/skills/templates counts, an approximate initial system-prompt token count, and recent sessions. Auto-dismisses after 30 seconds or on any key press. Set `powerline.welcome` to `false` to disable it while keeping the footer enabled.
|
|
30
|
-
|
|
31
|
-
**Rounded box design**: Status renders directly in the editor's top border, not as a separate footer.
|
|
32
|
-
|
|
33
|
-
**Native Pi layout**: Pi owns fixed input, feed scrolling, selection, and terminal behavior; this extension supplies powerline widgets and the custom bash/stash/editor integrations.
|
|
34
|
-
|
|
35
|
-
**Live thinking level indicator**: Shows current thinking level (`think:off`, `think:med`, etc.) with per-level colors. High, xhigh, and max levels use a rainbow effect inspired by Claude Code's ultrathink.
|
|
36
|
-
|
|
37
|
-
**Smart defaults**: Nerd Font auto-detection for iTerm, WezTerm, Kitty, Ghostty, and Alacritty with ASCII fallbacks. Colors matched to oh-my-pi's dark theme.
|
|
38
|
-
|
|
39
|
-
**Git integration**: Async status fetching with 1s cache TTL. Automatically invalidates on file writes/edits. Shows branch, staged (+), unstaged (*), and untracked (?) counts.
|
|
40
|
-
|
|
41
|
-
**Context awareness**: Color-coded warnings above 70% (yellow) and above 90% (red) context usage. During streaming, the context segment refreshes from live assistant usage instead of waiting for the next turn. Auto-compact indicator when enabled. If `pi-custom-compaction` is installed and enabled, the powerline automatically hides native context segments so the footer does not show stale post-summary usage.
|
|
42
|
-
|
|
43
|
-
**Token intelligence**: Smart formatting (1.2k, 45M), used/max/percentage context display, subscription detection, and configurable subscription cost display.
|
|
44
|
-
|
|
45
|
-
**Sticky bash mode**: Toggle bash mode with `ctrl+shift+b` or `/bash-mode`. It keeps a managed shell session alive for the current pi session, shows a dedicated `shell_mode` segment, streams command output into an embedded transcript below the editor, and lets `cd` or exported state persist across commands.
|
|
46
|
-
|
|
47
|
-
**Shell ghost suggestions**: Bash mode is now 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. 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 ..`. If the bash prompt is empty, bash mode shows the newest successful project-history ghost suggestion when one exists, otherwise it stays empty. The same inline predictions now also kick in for one-off `!command` and `!!command` prompts. Right Arrow or Tab accepts ghost text into the editor, and Enter runs the current shell command.
|
|
48
|
-
|
|
49
|
-
## Installation
|
|
50
|
-
|
|
51
|
-
### Method 1: Via Pi Package Manager (Recommended)
|
|
17
|
+
Pi package manager (usual path):
|
|
52
18
|
|
|
53
19
|
```bash
|
|
54
20
|
pi install npm:@groeponline/pi-wishcraft
|
|
55
21
|
```
|
|
56
22
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
### Method 2: One-Liner / Cloud Agent Startup Script (Cursor Cloud, Freebuff, Devcontainers, CI)
|
|
60
|
-
|
|
61
|
-
For ephemeral VMs, cloud agents, or dev environments without manual intervention:
|
|
23
|
+
Ephemeral VMs / CI:
|
|
62
24
|
|
|
63
25
|
```bash
|
|
64
26
|
curl -fsSL https://raw.githubusercontent.com/GroepOnline/pi-wishcraft/main/scripts/install.sh | bash
|
|
65
27
|
```
|
|
66
28
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Extended guides (segments, bash mode, commands, configuration) live in [`docs/`](docs/index.md).
|
|
70
|
-
|
|
71
|
-
## Usage
|
|
72
|
-
|
|
73
|
-
Activates automatically. Toggle with `/powerline`, switch presets with `/powerline <name>`, and move the primary row with `/powerline placement above|below|toggle`. Tab after `/powerline` completes preset names and `placement`; tab again after `placement` completes `above`, `below`, or `toggle`.
|
|
74
|
-
|
|
75
|
-
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.
|
|
76
|
-
|
|
77
|
-
Powerline Queue + Inbox commands and capture shortcuts:
|
|
78
|
-
|
|
79
|
-
- `# <text>`: capture an idea for the current project without sending it to the agent
|
|
80
|
-
- `# @global <text>`: capture a global idea
|
|
81
|
-
- `# @current <text>`: capture an idea targeted to the current session
|
|
82
|
-
- `/queue alias <name> [path]`: save a project alias, defaulting to the current cwd when `path` is omitted
|
|
83
|
-
- `# @name <text>`: capture an idea for a saved project alias
|
|
84
|
-
- `/compact <text>`: compact now and queue `<text>` as the next prompt after successful compaction
|
|
85
|
-
- `/idea [@target] <text>`: command form of idea capture, useful for scripts and users who disable the sigil
|
|
86
|
-
- `/idea issue [id]`: hand the oldest active idea, or a specific idea, to the current agent for safe GitHub issue triage
|
|
87
|
-
- `/ideas`: open the captured-ideas picker
|
|
88
|
-
- `/ideas next`: send the oldest active idea to the current session
|
|
89
|
-
- `/ideas issue [id]`: ask the current agent to dedupe and file a GitHub issue only when the target repo is clear and owned/controlled
|
|
90
|
-
- `/ideas send <id>`: send an idea to the current session
|
|
91
|
-
- `/queue`: open the queued-prompt picker
|
|
92
|
-
- `/queue send [id]` / `/queue retry [id]`: deliver a queued item now
|
|
93
|
-
- `/queue clear <id|all>`: clear queued prompt items
|
|
94
|
-
- `/queue target <id> @name|global|current`: retarget a queued item
|
|
95
|
-
|
|
96
|
-
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`:
|
|
97
|
-
|
|
98
|
-
```json
|
|
99
|
-
{
|
|
100
|
-
"powerline": {
|
|
101
|
-
"queue": {
|
|
102
|
-
"captureSigil": "#"
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Set `captureSigil` to `false` if you often submit markdown headings and prefer `/idea` instead.
|
|
109
|
-
|
|
110
|
-
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.
|
|
111
|
-
|
|
112
|
-
- `/powerline placement below`: move the primary powerline row below the editor
|
|
113
|
-
- `/powerline placement above`: restore the default placement
|
|
114
|
-
- `/powerline placement toggle`: switch between above and below
|
|
115
|
-
|
|
116
|
-
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`:
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"showLastPrompt": true,
|
|
121
|
-
"powerline": {
|
|
122
|
-
"preset": "default",
|
|
123
|
-
"placement": "below",
|
|
124
|
-
"welcome": true
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
| Preset | Description |
|
|
131
|
-
|--------|-------------|
|
|
132
|
-
| `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 |
|
|
133
|
-
| `minimal` | Just path (basename), git branch and context% (branch-only polling, no indicators/commit) |
|
|
134
|
-
| `compact` | Model, git (short commit + ahead/behind), queue, cost, context%, session id |
|
|
135
|
-
| `full` | Everything: hostname, model, path (abbreviated), full git incl commit + ↑/↓, totals, context total, elapsed + clock |
|
|
136
|
-
| `nerd` | Maximum detail for Nerd Font users: qualified model, full tokens + cache, commit, totals, seconds clock |
|
|
137
|
-
| `ascii` | Safe for any terminal: branch + short commit + ↑/↓, tokens, cost, context% (no Nerd glyphs) |
|
|
138
|
-
| `chef` | Fork default: muted colors, slash separators, live TPS in/out + open-ports + subagent-cost segments |
|
|
139
|
-
|
|
140
|
-
**Environment:** `POWERLINE_NERD_FONTS=1` to force Nerd Fonts, `=0` for ASCII.
|
|
141
|
-
|
|
142
|
-
Preset selection is saved under `powerline` in the agent settings file and restored on startup.
|
|
143
|
-
Run `/powerline default` to switch back to the default preset.
|
|
144
|
-
|
|
145
|
-
### Custom items from extension statuses
|
|
146
|
-
|
|
147
|
-
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.
|
|
148
|
-
|
|
149
|
-
1. Any extension can publish status text through `ctx.ui.setStatus("my-key", "...value...")`.
|
|
150
|
-
2. Configure `powerline.customItems` to place those keys on the left, right, or secondary row.
|
|
151
|
-
|
|
152
|
-
```json
|
|
153
|
-
{
|
|
154
|
-
"powerline": {
|
|
155
|
-
"preset": "default",
|
|
156
|
-
"customItems": [
|
|
157
|
-
{
|
|
158
|
-
"id": "ci",
|
|
159
|
-
"statusKey": "ci-status",
|
|
160
|
-
"position": "right",
|
|
161
|
-
"prefix": "CI",
|
|
162
|
-
"color": "warning"
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"id": "review",
|
|
166
|
-
"position": "secondary",
|
|
167
|
-
"hideWhenMissing": false,
|
|
168
|
-
"prefix": "review"
|
|
169
|
-
}
|
|
170
|
-
]
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
`customItems` fields:
|
|
176
|
-
|
|
177
|
-
- `id` (required): unique item id (`a-z`, `A-Z`, `0-9`, `_`, `-`)
|
|
178
|
-
- `statusKey` (optional): extension status key to read, defaults to `id`
|
|
179
|
-
- `position` (optional): `left`, `right`, or `secondary` (default `right`)
|
|
180
|
-
- `prefix` (optional): text shown before the live status value
|
|
181
|
-
- `color` (optional): any Pi theme color (`warning`, `accent`, etc.) or hex (`#RRGGBB`)
|
|
182
|
-
- `hideWhenMissing` (optional): hide item when no status is present (default `true`)
|
|
183
|
-
- `excludeFromExtensionStatuses` (optional): omit this key from the aggregate `extension_statuses` segment (default `true`)
|
|
184
|
-
|
|
185
|
-
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.
|
|
186
|
-
|
|
187
|
-
### Custom segments (computed, no code)
|
|
188
|
-
|
|
189
|
-
Define your own segments directly in settings: run a command, read an env var, or show static text. No TypeScript needed.
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"powerline": {
|
|
194
|
-
"preset": "chef",
|
|
195
|
-
"segments": {
|
|
196
|
-
"battery": { "type": "command", "command": "cat /sys/class/power_supply/BAT0/capacity", "prefix": "batt", "cacheMs": 30000 },
|
|
197
|
-
"who": { "type": "env", "env": "USER", "prefix": "u", "color": "#888888" },
|
|
198
|
-
"chef": { "type": "static", "text": "CHEF", "color": "accent" }
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Each segment becomes usable in a preset as `custom:<id>` (e.g. `custom:battery`).
|
|
29
|
+
Then restart pi or `/reload`. Peer range is `@earendil-works/pi-coding-agent` `>=0.81.0 <0.85.0`.
|
|
205
30
|
|
|
206
|
-
|
|
31
|
+
## What you get
|
|
207
32
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
33
|
+
| Surface | What it does |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| Status bar | Git, TPS (1s window over a 5s ring), context, cost, ports, queue. Default placement is the editor top border; `/powerline placement below` moves it. |
|
|
36
|
+
| `alt+p` | Three overlays: Navigate, Configure, Status. In Navigate, `→` / `tab` opens per-segment detail (ports, git, cost, context). `alt+i` is the ports list. |
|
|
37
|
+
| `# <idea>` | File-backed inbox. Does not send the prompt. `/ideas next` feeds the oldest active idea into the session. |
|
|
38
|
+
| `alt+s` | Stash the draft, ask something else, get it back when the run finishes. |
|
|
39
|
+
| `/skills` | Substring search on name, description, and path. Enter inserts. |
|
|
40
|
+
| `!cmd` / bash mode | Managed shell with ghost suggestions from project history. No shell-native completion probes. |
|
|
41
|
+
| Hooks + repairs | Command hooks on pi events. Custom-tool input repairs before execution. Kill-switch: `wishcraft.hooksEnabled`. |
|
|
216
42
|
|
|
217
|
-
|
|
43
|
+
Pi owns the footer chrome, feed scrolling, and input. Wishcraft supplies widgets, overlays, and the bash/stash/editor integrations. The bar is not clickable; actions are commands and overlays.
|
|
218
44
|
|
|
219
|
-
|
|
45
|
+
## Daily commands
|
|
220
46
|
|
|
221
|
-
|
|
47
|
+
Activates on load. `/powerline` toggles it. `/powerline <preset>` switches look. Tab completes presets and `placement above|below|toggle`.
|
|
222
48
|
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
49
|
+
```text
|
|
50
|
+
/powerline doctor settings, queue, git, bash, fonts
|
|
51
|
+
/powerline export current preset + layout as JSON
|
|
52
|
+
/tps live in/out overlay (same ring as the segment)
|
|
53
|
+
/tps 40 override POWERLINE_TPS
|
|
54
|
+
/usage session / today / week from ~/.pi/agent/wishcraft-usage.json
|
|
55
|
+
/repairs tool-input repair counters
|
|
56
|
+
/skills skill manager
|
|
57
|
+
/wishcraft settings TUI
|
|
58
|
+
/open-ports listening sockets
|
|
59
|
+
/cd <path> continue this conversation in another directory
|
|
60
|
+
/bash-mode sticky shell (also ctrl+shift+b)
|
|
61
|
+
/vibe star trek themed working messages
|
|
239
62
|
```
|
|
240
63
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
`preset: "chef"` is the GroepOnline fork's default look: muted colors (no rainbow), slash separators, and two extra right-side segments:
|
|
244
|
-
|
|
245
|
-
- `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`).
|
|
246
|
-
- `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).
|
|
247
|
-
|
|
248
|
-
Interactivity (Pi core renders the footer as static text, so live click is not possible; actions live in commands and a navigable overlay):
|
|
249
|
-
|
|
250
|
-
- `/tps [value]`: show or set `POWERLINE_TPS`
|
|
251
|
-
- `/usage`: today / week / session token overlay (same ledger as the cost segment)
|
|
252
|
-
- `/open-ports`: list listening ports and pick one
|
|
253
|
-
- `alt+p`: **powerline menu**: three overlays (Navigate, Configure, Status). Status drills down to ports, TPS, and toggle.
|
|
254
|
-
- `alt+i`: **powerline info**: full open-ports list
|
|
255
|
-
|
|
256
|
-
Both `alt+p` and `alt+i` are rebindable (see Keybinds below); changes apply after `/reload`.
|
|
64
|
+
Queue:
|
|
257
65
|
|
|
258
|
-
|
|
66
|
+
- `# <text>` current project; `# @global`, `# @current`, `# @alias`
|
|
67
|
+
- `/idea`, `/ideas`, `/queue` for capture, send, retry, clear, archive
|
|
259
68
|
|
|
260
|
-
|
|
69
|
+
Keybinds (`powerlineShortcuts`, applied after `/reload`; `null` disables):
|
|
261
70
|
|
|
262
71
|
```json
|
|
263
72
|
{
|
|
@@ -268,218 +77,41 @@ The powerline menu and info shortcuts are configurable via `powerlineShortcuts`
|
|
|
268
77
|
}
|
|
269
78
|
```
|
|
270
79
|
|
|
271
|
-
|
|
80
|
+
## Minimal config
|
|
272
81
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
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.
|
|
82
|
+
`~/.pi/agent/settings.json` (or `PI_CODING_AGENT_DIR`):
|
|
276
83
|
|
|
277
84
|
```json
|
|
278
85
|
{
|
|
279
86
|
"powerline": {
|
|
280
|
-
"
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### Disabling segments
|
|
289
|
-
|
|
290
|
-
Set `powerline.disabledSegments` to hide built-in or configured custom segments from the active preset:
|
|
291
|
-
|
|
292
|
-
```json
|
|
293
|
-
{
|
|
294
|
-
"powerline": {
|
|
295
|
-
"preset": "default",
|
|
296
|
-
"disabledSegments": ["cost", "extension_statuses", "custom:ci"]
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
Built-in names are listed under Segments below. Custom items use `custom:<id>`. Unknown names are ignored with a startup warning.
|
|
302
|
-
|
|
303
|
-
### Custom layout
|
|
304
|
-
|
|
305
|
-
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:
|
|
306
|
-
|
|
307
|
-
```json
|
|
308
|
-
{
|
|
309
|
-
"powerline": {
|
|
310
|
-
"preset": "default",
|
|
311
|
-
"separator": "chevron",
|
|
312
|
-
"layout": {
|
|
313
|
-
"left": ["model", "thinking", "path", "git"],
|
|
314
|
-
"right": ["context_pct", "cost"],
|
|
315
|
-
"secondary": ["custom:ci"]
|
|
316
|
-
},
|
|
317
|
-
"customItems": [
|
|
318
|
-
{ "id": "ci", "statusKey": "ci-status" }
|
|
319
|
-
]
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
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 below; omit it to keep the preset’s separator.
|
|
325
|
-
|
|
326
|
-
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.
|
|
327
|
-
|
|
328
|
-
### Demo settings
|
|
329
|
-
|
|
330
|
-
For a compact current footer setup:
|
|
331
|
-
|
|
332
|
-
```json
|
|
333
|
-
{
|
|
334
|
-
"powerline": {
|
|
335
|
-
"preset": "default",
|
|
336
|
-
"path": { "mode": "basename" },
|
|
337
|
-
"model": { "display": "name" },
|
|
338
|
-
"cost": { "subscriptionDisplay": "subscription", "currency": "USD" }
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
Use `"model": { "display": "qualified" }` when two providers expose models with the same display name.
|
|
344
|
-
|
|
345
|
-
`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.
|
|
346
|
-
|
|
347
|
-
Subscription cost display accepts:
|
|
348
|
-
|
|
349
|
-
| Mode | Subscription + reported cost | Subscription + no reported cost |
|
|
350
|
-
|------|------------------------------|----------------------------------|
|
|
351
|
-
| `subscription` | `(sub)` | `(sub)` |
|
|
352
|
-
| `reported-cost` | `$0.12` | `(sub)` |
|
|
353
|
-
| `both` | `$0.12 (sub)` | `(sub)` |
|
|
354
|
-
|
|
355
|
-
Segment display formats (opt-in; defaults match the historical rendering):
|
|
356
|
-
|
|
357
|
-
| Segment option | Values | Default | Effect |
|
|
358
|
-
|---|---|---|---|
|
|
359
|
-
| `"context": { "format" }` | `"full"` / `"percent"` | `"full"` | `"percent"` shows a bare rounded `83%` (threshold-colored, no icon) instead of `12k/200k (6.2%)` |
|
|
360
|
-
| `"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%)` |
|
|
361
|
-
|
|
362
|
-
```json
|
|
363
|
-
{
|
|
364
|
-
"powerline": {
|
|
365
|
-
"context": { "format": "percent" },
|
|
366
|
-
"cache_read": { "format": "both" }
|
|
87
|
+
"preset": "chef",
|
|
88
|
+
"placement": "above",
|
|
89
|
+
"welcome": true
|
|
367
90
|
}
|
|
368
91
|
}
|
|
369
92
|
```
|
|
370
93
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
Toggle bash mode with either:
|
|
374
|
-
|
|
375
|
-
- `ctrl+shift+b`
|
|
376
|
-
- `/bash-mode on`
|
|
377
|
-
- `/bash-mode off`
|
|
378
|
-
- `/bash-mode toggle`
|
|
94
|
+
`chef` is muted colors, slash separators, live TPS in/out, and TCP port count. Built-in presets: `default`, `minimal`, `compact`, `full`, `nerd`, `ascii`, `chef`. Custom segments, labels, layout, and presets are documented in [docs/configuration.md](docs/configuration.md).
|
|
379
95
|
|
|
380
|
-
|
|
96
|
+
Nerd Fonts auto-detect for iTerm, WezTerm, Kitty, Ghostty, and Alacritty; ASCII otherwise. `POWERLINE_NERD_FONTS=0` forces ASCII.
|
|
381
97
|
|
|
382
|
-
|
|
98
|
+
Context turns warning above 70% and error above 90%. TPS is tokens in the last ~1s, not a session average. `/tps` reads that ring; it does not start a second sampler.
|
|
383
99
|
|
|
384
|
-
|
|
385
|
-
- Right Arrow accepts ghost text into the editor without running it
|
|
386
|
-
- 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
|
|
387
|
-
- Up and Down browse matching shell history
|
|
388
|
-
- `escape` exits bash mode and returns to normal prompt mode
|
|
389
|
-
- `ctrl+c` interrupts the active shell job before falling back to normal pi behavior
|
|
390
|
-
|
|
391
|
-
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. 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. Mode entry stays quiet: there is no automatic or manual dropdown completion surface, and ghost suggestions do not run shell-native completion probes.
|
|
392
|
-
|
|
393
|
-
### Bash mode configuration
|
|
394
|
-
|
|
395
|
-
In `~/.pi/agent/settings.json` (or under `PI_CODING_AGENT_DIR` when that environment variable is set):
|
|
100
|
+
Daily token budget (never blocks a turn):
|
|
396
101
|
|
|
397
102
|
```json
|
|
398
103
|
{
|
|
399
|
-
"
|
|
400
|
-
"
|
|
401
|
-
"transcriptMaxLines": 2000,
|
|
402
|
-
"transcriptMaxBytes": 524288
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
## Editor Stash
|
|
408
|
-
|
|
409
|
-
Use `Alt+S` / `Option+S` as a quick stash toggle while drafting. It keeps one active stash and clears the editor when stashing. Powerline listens for unambiguous Alt/Meta-S escape encodings by default. If your old terminal setup only emits the printable German sharp-S character for Option+S and you still want that to trigger stash, set `"stashSharpSShortcut": true` under `powerline`.
|
|
410
|
-
|
|
411
|
-
| Editor | Stash | `Alt+S` result |
|
|
412
|
-
|--------|-------|----------------|
|
|
413
|
-
| Has text | Empty | Stash current text, clear editor |
|
|
414
|
-
| Empty | Has stash | Restore stash into editor |
|
|
415
|
-
| Has text | Has stash | Update stash with current text, clear editor |
|
|
416
|
-
| Empty | Empty | Show "Nothing to stash" |
|
|
417
|
-
|
|
418
|
-
Auto-restore after an agent run only happens when the editor is still empty. If you typed meanwhile, the stash is preserved.
|
|
419
|
-
|
|
420
|
-
The `stash` indicator appears in the powerline bar (on presets with `extension_statuses`). Active stash is still session-local and resets on session switch / disable, but stash history is persisted to the agent dir at `powerline-footer/stash-history.json` so it survives restarts. By default the agent dir is `~/.pi/agent`; set `PI_CODING_AGENT_DIR` to move global powerline settings, stash history, sessions, vibes, skills, commands, and extension discovery with Pi.
|
|
421
|
-
|
|
422
|
-
### Stash history
|
|
423
|
-
|
|
424
|
-
Open prompt history with either:
|
|
425
|
-
|
|
426
|
-
- `ctrl+alt+h`
|
|
427
|
-
- `/stash-history`
|
|
428
|
-
|
|
429
|
-
Prompt history now has two sources:
|
|
430
|
-
|
|
431
|
-
- stashed prompts: up to 12 recent stashed prompts (newest first)
|
|
432
|
-
- recent project prompts: up to 50 recent user-submitted prompts pulled from pi sessions in the current project folder
|
|
433
|
-
|
|
434
|
-
Selecting a stashed entry lets you insert it or promote it to an idea. Project prompt history entries insert into the editor. If the editor already has text, you can choose `Replace`, `Append`, or `Cancel`.
|
|
435
|
-
|
|
436
|
-
### Editor clipboard and navigation shortcuts
|
|
437
|
-
|
|
438
|
-
- `ctrl+alt+c`: copy full editor content
|
|
439
|
-
- `ctrl+alt+x`: cut full editor content (copy, then clear)
|
|
440
|
-
- `ctrl+alt+q`: open the queued-prompt picker
|
|
441
|
-
- `cmd+shift+up`: move the editor cursor to the start of the first line
|
|
442
|
-
- `cmd+shift+down`: move the editor cursor to the end of the last line
|
|
443
|
-
|
|
444
|
-
Copy/cut actions do not modify stash state or stash history. Dragging files, folders, images, or screenshots from Finder into the custom editor inserts their path strings. Pi owns chat scrolling, selection, and fixed input behavior natively.
|
|
445
|
-
|
|
446
|
-
### Shortcut configuration
|
|
447
|
-
|
|
448
|
-
You can override shortcut keys in the agent settings file:
|
|
449
|
-
|
|
450
|
-
```json
|
|
451
|
-
{
|
|
452
|
-
"powerlineShortcuts": {
|
|
453
|
-
"stashHistory": "ctrl+alt+h",
|
|
454
|
-
"copyEditor": "ctrl+alt+c",
|
|
455
|
-
"cutEditor": "ctrl+alt+x",
|
|
456
|
-
"ideaCapture": null,
|
|
457
|
-
"queueOpen": "ctrl+alt+q",
|
|
458
|
-
"editorStart": "cmd+shift+up",
|
|
459
|
-
"editorEnd": "cmd+shift+down"
|
|
104
|
+
"wishcraft": {
|
|
105
|
+
"tokenBudget": { "daily": 500000 }
|
|
460
106
|
}
|
|
461
107
|
}
|
|
462
108
|
```
|
|
463
109
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
### Editor autocomplete composition
|
|
467
|
-
|
|
468
|
-
Powerline wraps Pi's autocomplete provider so bash mode can add shell-aware suggestions. When another editor extension was already installed, powerline now passes Pi's provider through that previous editor's `setAutocompleteProvider()` first and then wraps the resulting provider. This preserves prior autocomplete-provider wrappers where possible, but it is not full render/input composition between custom editors.
|
|
469
|
-
|
|
470
|
-
## Skill manager
|
|
471
|
-
|
|
472
|
-
Browse and insert your installed skills (`SKILL.md` files and `*.md`/`*.txt` prompts) from an interactive TUI overlay:
|
|
473
|
-
|
|
474
|
-
- **`/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.
|
|
475
|
-
|
|
476
|
-
The manager reuses the same skill discovery as inline `/command`/`$skill` triggers, so anything you can inline you can also browse and insert manually.
|
|
477
|
-
|
|
478
|
-
## Hooks (harness)
|
|
110
|
+
At 80% the cost segment warns; at 100% it goes red and welcome notifies. `/usage` shows the ledger.
|
|
479
111
|
|
|
480
|
-
|
|
112
|
+
## Hooks
|
|
481
113
|
|
|
482
|
-
|
|
114
|
+
Hooks are commands that read JSON on stdin. Definitions come from the **global** agent settings file only. Project `.pi/settings.json` cannot install new hook commands. `wishcraft.hooksEnabled: false` disables every hook without deleting the config.
|
|
483
115
|
|
|
484
116
|
```json
|
|
485
117
|
{
|
|
@@ -487,32 +119,23 @@ Put the scripts somewhere executable (example: `~/.pi/agent/hooks/`) and point s
|
|
|
487
119
|
"hooksEnabled": true,
|
|
488
120
|
"hooks": {
|
|
489
121
|
"preToolUse": [
|
|
490
|
-
{
|
|
491
|
-
"matcher": "bash",
|
|
492
|
-
"hooks": [{ "command": "~/.pi/agent/hooks/bash-guard.sh", "timeout": 5 }]
|
|
493
|
-
}
|
|
122
|
+
{ "matcher": "bash", "hooks": [{ "command": "~/.pi/agent/hooks/bash-guard.sh", "timeout": 5 }] }
|
|
494
123
|
],
|
|
495
124
|
"postToolUse": [
|
|
496
|
-
{
|
|
497
|
-
"matcher": "write",
|
|
498
|
-
"hooks": [{ "command": "~/.pi/agent/hooks/write-audit.sh", "timeout": 5 }]
|
|
499
|
-
}
|
|
125
|
+
{ "matcher": "write", "hooks": [{ "command": "~/.pi/agent/hooks/write-audit.sh", "timeout": 5 }] }
|
|
500
126
|
],
|
|
501
127
|
"sessionStart": [
|
|
502
|
-
{
|
|
503
|
-
"hooks": [{ "command": "~/.pi/agent/hooks/session-git-status.sh", "timeout": 10 }]
|
|
504
|
-
}
|
|
128
|
+
{ "hooks": [{ "command": "~/.pi/agent/hooks/session-git-status.sh", "timeout": 10 }] }
|
|
505
129
|
]
|
|
506
130
|
}
|
|
507
131
|
}
|
|
508
132
|
}
|
|
509
133
|
```
|
|
510
134
|
|
|
511
|
-
**
|
|
135
|
+
**bash-guard** (exit 2 = deny):
|
|
512
136
|
|
|
513
137
|
```bash
|
|
514
138
|
#!/usr/bin/env bash
|
|
515
|
-
# ~/.pi/agent/hooks/bash-guard.sh
|
|
516
139
|
payload=$(cat)
|
|
517
140
|
cmd=$(printf '%s' "$payload" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))')
|
|
518
141
|
if printf '%s' "$cmd" | grep -Eq '(^|[[:space:]])rm[[:space:]]+(-[a-zA-Z]*[[:space:]]+)*-r[a-zA-Z]*f|-fr[a-zA-Z]*|[[:space:]]/[[:space:]]*$'; then
|
|
@@ -523,23 +146,18 @@ fi
|
|
|
523
146
|
exit 0
|
|
524
147
|
```
|
|
525
148
|
|
|
526
|
-
**
|
|
149
|
+
**write-audit** (append-only, never blocks):
|
|
527
150
|
|
|
528
151
|
```bash
|
|
529
152
|
#!/usr/bin/env bash
|
|
530
|
-
# ~/.pi/agent/hooks/write-audit.sh
|
|
531
153
|
mkdir -p "$HOME/.pi/agent/logs"
|
|
532
|
-
printf '%s\n' "$(date -Is) $1" >> "$HOME/.pi/agent/logs/write-audit.jsonl"
|
|
533
154
|
cat >> "$HOME/.pi/agent/logs/write-audit.jsonl"
|
|
534
155
|
```
|
|
535
156
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
**3. SessionStart git-status** — inject `git status --short` as extra context at session start.
|
|
157
|
+
**SessionStart git-status** (extra context, never blocks):
|
|
539
158
|
|
|
540
159
|
```bash
|
|
541
160
|
#!/usr/bin/env bash
|
|
542
|
-
# ~/.pi/agent/hooks/session-git-status.sh
|
|
543
161
|
status=$(git status --short 2>/dev/null | head -n 40)
|
|
544
162
|
CTX="$status" python3 - <<'PY'
|
|
545
163
|
import json, os
|
|
@@ -551,212 +169,25 @@ print(json.dumps({
|
|
|
551
169
|
PY
|
|
552
170
|
```
|
|
553
171
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
`wishcraft.tokenBudget.daily` (token count) paints the cost segment warning/red at 80%/100% and notifies on welcome. It never blocks a turn. `/usage` shows session / today / week from `~/.pi/agent/wishcraft-usage.json`. `/tps` with no args opens the live ring overlay (same sampler as the segment).
|
|
557
|
-
|
|
558
|
-
## Working Vibes
|
|
559
|
-
|
|
560
|
-
Transform boring "Working..." messages into themed phrases that match your style:
|
|
561
|
-
|
|
562
|
-
```text
|
|
563
|
-
/vibe star trek → "Running diagnostics...", "Engaging warp drive..."
|
|
564
|
-
/vibe pirate → "Hoisting the sails...", "Charting course..."
|
|
565
|
-
/vibe zen → "Breathing deeply...", "Finding balance..."
|
|
566
|
-
/vibe noir → "Following the trail...", "Checking the angles..."
|
|
567
|
-
/vibe → Shows current theme, mode, and model
|
|
568
|
-
/vibe off → Disables (back to "Working...")
|
|
569
|
-
/vibe model → Shows current model
|
|
570
|
-
/vibe model openai/gpt-4o-mini → Use a different model
|
|
571
|
-
/vibe mode → Shows current mode (generate or file)
|
|
572
|
-
/vibe mode file → Switch to file-based mode (instant, no API calls)
|
|
573
|
-
/vibe mode generate → Switch to on-demand generation (contextual)
|
|
574
|
-
/vibe generate mafia 200 → Pre-generate 200 vibes and save to file
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
### Configuration
|
|
578
|
-
|
|
579
|
-
In the agent settings file:
|
|
580
|
-
|
|
581
|
-
```json
|
|
582
|
-
{
|
|
583
|
-
"workingVibe": "star trek", // Theme phrase
|
|
584
|
-
"workingVibeMode": "generate", // "generate" (on-demand) or "file" (pre-generated)
|
|
585
|
-
"workingVibeModel": "openai-codex/gpt-5.4-mini", // Optional: model to use (default)
|
|
586
|
-
"workingVibeFallback": "Working", // Optional: fallback message
|
|
587
|
-
"workingVibeRefreshInterval": 30, // Optional: seconds between refreshes (default 30)
|
|
588
|
-
"workingVibePrompt": "Generate a {theme} loading message for: {task}", // Optional: custom prompt template
|
|
589
|
-
"workingVibeMaxLength": 65 // Optional: max message length (default 65)
|
|
590
|
-
}
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
### Modes
|
|
172
|
+
Repairs run on custom/extension tools only, before hooks: drop null optionals, parse JSON-string arrays before wrapping, turn `{}` into `[]` on array keys, wrap bare strings, alias `filePath` / `absolutePath` / `target_file` to `path`, unwrap degenerate markdown auto-links. Core tools (`bash`, `read`, `edit`, `write`, `grep`, `find`, `ls`) are never rewritten. `/repairs` prints the counters.
|
|
594
173
|
|
|
595
|
-
|
|
596
|
-
|------|-------------|------|------|
|
|
597
|
-
| `generate` | On-demand AI generation (default) | Contextual, hints at actual task | Model-dependent cost and latency |
|
|
598
|
-
| `file` | Pull from pre-generated file | Instant, zero cost, works offline | Not contextual |
|
|
599
|
-
|
|
600
|
-
**File mode setup:**
|
|
601
|
-
```bash
|
|
602
|
-
/vibe generate mafia 200 # Generate 200 vibes, save to the agent dir
|
|
603
|
-
/vibe mode file # Switch to file mode
|
|
604
|
-
/vibe mafia # Now uses the file
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
**How file mode works:**
|
|
608
|
-
1. Vibes are loaded from `vibes/{theme}.txt` in the agent dir into memory
|
|
609
|
-
2. Uses seeded shuffle (Mulberry32 PRNG): cycles through all vibes before repeating
|
|
610
|
-
3. New seed each session: different order every time you restart pi
|
|
611
|
-
4. Zero latency, zero cost, works offline
|
|
612
|
-
|
|
613
|
-
**Prompt template variables (generate mode only):**
|
|
614
|
-
- `{theme}`: the current vibe theme (e.g., "star trek", "mafia")
|
|
615
|
-
- `{task}`: context hint (user prompt initially, then agent's response text or tool info on refresh)
|
|
616
|
-
- `{exclude}`: recent vibes to avoid (auto-populated, e.g., "Don't use: vibe1, vibe2...")
|
|
617
|
-
|
|
618
|
-
**How it works:**
|
|
619
|
-
1. When you send a message, shows "Channeling {theme}..." placeholder
|
|
620
|
-
2. AI generates a themed message in the background (3s timeout)
|
|
621
|
-
3. Message updates to the themed version (e.g., "Engaging warp drive...")
|
|
622
|
-
4. During long tasks, refreshes on tool calls (rate-limited, default 30s)
|
|
623
|
-
5. Cost and latency depend on your configured `workingVibeModel`
|
|
624
|
-
|
|
625
|
-
## Thinking Level Display
|
|
626
|
-
|
|
627
|
-
The thinking segment shows live updates when you change thinking level:
|
|
628
|
-
|
|
629
|
-
| Level | Display | Color |
|
|
630
|
-
|-------|---------|-------|
|
|
631
|
-
| off | `think:off` | gray |
|
|
632
|
-
| minimal | `think:min` | purple-gray |
|
|
633
|
-
| low | `think:low` | blue |
|
|
634
|
-
| medium | `think:med` | teal |
|
|
635
|
-
| high | `think:high` | rainbow |
|
|
636
|
-
| xhigh | `think:xhigh` | rainbow |
|
|
637
|
-
| max | `think:max` | rainbow |
|
|
638
|
-
|
|
639
|
-
## Path Display
|
|
640
|
-
|
|
641
|
-
The path segment supports three modes:
|
|
642
|
-
|
|
643
|
-
| Mode | Example | Description |
|
|
644
|
-
|------|---------|-------------|
|
|
645
|
-
| `basename` | `powerline-footer` | Just the directory name (default) |
|
|
646
|
-
| `abbreviated` | `…/extensions/powerline-footer` | Full path with home abbreviated and length limit |
|
|
647
|
-
| `full` | `~/.pi/agent/extensions/powerline-footer` | Complete path with home abbreviated |
|
|
648
|
-
|
|
649
|
-
Configure via preset options: `path: { mode: "full" }`
|
|
650
|
-
|
|
651
|
-
## Git polling
|
|
652
|
-
|
|
653
|
-
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:
|
|
654
|
-
|
|
655
|
-
```json
|
|
656
|
-
{
|
|
657
|
-
"powerline": {
|
|
658
|
-
"git": { "polling": "branch" }
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
Use `"off"` to disable extension-owned git polling entirely and only show the branch reported by Pi when available.
|
|
664
|
-
|
|
665
|
-
## Git host icon
|
|
666
|
-
|
|
667
|
-
Set `git.hostIcon` to replace the branch icon with the origin remote's host logo:
|
|
668
|
-
|
|
669
|
-
```json
|
|
670
|
-
{
|
|
671
|
-
"powerline": {
|
|
672
|
-
"git": { "hostIcon": true }
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
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).
|
|
678
|
-
|
|
679
|
-
## Git status extras (commits, ahead/behind)
|
|
680
|
-
|
|
681
|
-
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:
|
|
682
|
-
|
|
683
|
-
- `git.showCommit` (`true` by default) — appends `#<hash> <subject>` for the latest commit.
|
|
684
|
-
- `git.maxCommitSubjectLength` (`24`) — truncates the commit subject shown.
|
|
685
|
-
- `git.showAheadBehind` (`true` by default) — appends `↑<n> ↓<n>` for commits ahead/behind the configured upstream (hidden when there is no upstream).
|
|
686
|
-
|
|
687
|
-
```json
|
|
688
|
-
{
|
|
689
|
-
"powerline": {
|
|
690
|
-
"git": { "showCommit": true, "showAheadBehind": true, "maxCommitSubjectLength": 24 }
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
The `minimal` and `compact` presets keep these off to stay lean; set `showCommit: true`/`showAheadBehind: true` to enable them.
|
|
696
|
-
|
|
697
|
-
## Segments
|
|
698
|
-
|
|
699
|
-
`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`
|
|
700
|
-
|
|
701
|
-
## Separators
|
|
702
|
-
|
|
703
|
-
`powerline` · `powerline-thin` · `slash` · `pipe` · `dot` · `chevron` · `star` · `block` · `none` · `ascii`
|
|
704
|
-
|
|
705
|
-
## Theming
|
|
706
|
-
|
|
707
|
-
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.
|
|
708
|
-
|
|
709
|
-
### Default Colors
|
|
710
|
-
|
|
711
|
-
| Semantic | Theme Color | Description |
|
|
712
|
-
|----------|-------------|-------------|
|
|
713
|
-
| `model` | `#d787af` | Model name |
|
|
714
|
-
| `shellMode` | `accent` | Bash mode segment |
|
|
715
|
-
| `path` | `#00afaf` | Directory path |
|
|
716
|
-
| `gitClean` | `success` | Git branch (clean) |
|
|
717
|
-
| `gitDirty` | `warning` | Git branch (dirty) |
|
|
718
|
-
| `thinking` | `thinkingOff` | Thinking level (`off`) |
|
|
719
|
-
| `thinkingMinimal` | `thinkingMinimal` | Thinking level (`minimal`) |
|
|
720
|
-
| `thinkingLow` | `thinkingLow` | Thinking level (`low`) |
|
|
721
|
-
| `thinkingMedium` | `thinkingMedium` | Thinking level (`medium`) |
|
|
722
|
-
| `context` | `dim` | Context usage |
|
|
723
|
-
| `contextWarn` | `warning` | Context usage >70% |
|
|
724
|
-
| `contextError` | `error` | Context usage >90% |
|
|
725
|
-
| `cost` | `text` | Cost display |
|
|
726
|
-
| `tokens` | `muted` | Token counts |
|
|
727
|
-
| `queue` | `accent` | Queue / ideas / blocked counts |
|
|
728
|
-
| `separator` | `dim` | Segment separators and ahead/behind counts |
|
|
729
|
-
| `border` | `borderMuted` | Panel/border chrome |
|
|
730
|
-
|
|
731
|
-
### Custom Theme Override
|
|
732
|
-
|
|
733
|
-
Create `extensions/powerline-footer/theme.json` in the agent dir (`~/.pi/agent` by default, or `PI_CODING_AGENT_DIR` when set):
|
|
734
|
-
|
|
735
|
-
```json
|
|
736
|
-
{
|
|
737
|
-
"colors": {
|
|
738
|
-
"model": "accent",
|
|
739
|
-
"shellMode": "accent",
|
|
740
|
-
"path": "#00afaf",
|
|
741
|
-
"gitClean": "success",
|
|
742
|
-
"thinking": "thinkingOff",
|
|
743
|
-
"thinkingMinimal": "thinkingMinimal",
|
|
744
|
-
"thinkingLow": "thinkingLow",
|
|
745
|
-
"thinkingMedium": "thinkingMedium"
|
|
746
|
-
},
|
|
747
|
-
"icons": {
|
|
748
|
-
"auto": "↯",
|
|
749
|
-
"warning": ""
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
```
|
|
174
|
+
## Limits
|
|
753
175
|
|
|
754
|
-
|
|
755
|
-
-
|
|
756
|
-
-
|
|
176
|
+
- No mouse on the live footer. Pi core owns that surface.
|
|
177
|
+
- No second `alt+i` product. Ports stay on `alt+i`; other detail is `→` in the navigator.
|
|
178
|
+
- ChefGroep status keys (`powerline.preset`, `powerline.tps`, `powerline.ports`) exist for other extensions. They are not the public pitch.
|
|
179
|
+
- `npm deprecate` of the old `@groeponline/pi-powerline-footer` name is a scope-owner action. That package stays at 0.17.2 until the token allows it.
|
|
180
|
+
- Tags are not rewritten. 0.19.x through current stay on the timeline.
|
|
757
181
|
|
|
758
|
-
|
|
182
|
+
## Docs
|
|
759
183
|
|
|
760
|
-
|
|
184
|
+
- [Commands](docs/commands.md)
|
|
185
|
+
- [Configuration](docs/configuration.md)
|
|
186
|
+
- [Bash mode](docs/bash-mode.md)
|
|
187
|
+
- [Stash and shortcuts](docs/stash-and-shortcuts.md)
|
|
188
|
+
- [Skill manager](docs/skill-manager.md)
|
|
189
|
+
- [Working vibes](docs/working-vibes.md)
|
|
190
|
+
- [Segments and theming](docs/segments.md)
|
|
191
|
+
- [ROADMAP](ROADMAP.md)
|
|
761
192
|
|
|
762
|
-
|
|
193
|
+
MIT. Issues: [GroepOnline/pi-wishcraft](https://github.com/GroepOnline/pi-wishcraft/issues).
|
package/ROADMAP.md
CHANGED
|
@@ -223,7 +223,7 @@ Het `alt+p`-menu krijgt gestapelde `SelectList`-overlays (pijltjes +
|
|
|
223
223
|
descriptions) in plaats van platte `ctx.ui.select`. Max drie
|
|
224
224
|
top-level ingangen. #19 landt de top-level boom (Navigate / Configure /
|
|
225
225
|
Status). Configure gebruikt nu `showSelectOverlay` (CHE-42 rest). CHE-40
|
|
226
|
-
is Done (#18). CHE-41 is
|
|
226
|
+
is Done (#18). CHE-41 is Done: `→` in Navigate, snapshot bij openen, geen tweede `alt+i`-pad.
|
|
227
227
|
|
|
228
228
|
### PR H — skills manager v2 UI + token-overlays
|
|
229
229
|
|
|
@@ -281,9 +281,9 @@ Pas na 0.20. Geen parallelle 1.0-tak.
|
|
|
281
281
|
blijven voor alles wat niet in een regel past.
|
|
282
282
|
4. **Preset editor** — links/rechts segmenten kiezen in het menu,
|
|
283
283
|
opslaan in settings. Vandaag is custom JSON-only.
|
|
284
|
-
5. **Per-segment detail** (CHE-41): `→` in de navigator opent
|
|
284
|
+
5. **Per-segment detail** (CHE-41): ✅ `→` in de navigator opent
|
|
285
285
|
ports-lijst, git-samenvatting, cost-breakdown, context-math.
|
|
286
|
-
|
|
286
|
+
Snapshot bij openen, geen live timer.
|
|
287
287
|
6. **Idee-review** — `/ideas` in dezelfde overlay-taal; status
|
|
288
288
|
idea / in-progress / done; tags; "verwerk met skill X".
|
|
289
289
|
Welcome queue-widget: item oppakken → prompt.
|
|
@@ -303,9 +303,9 @@ Pas na 0.20. Geen parallelle 1.0-tak.
|
|
|
303
303
|
| GRO-1060 fork cleanup | Done. Release-pad bewezen. CHANGELOG niet inkorten. Versie niet resetten. `banner.png` blijft. |
|
|
304
304
|
| GRO-1061 CI queue | Ops, niet deze roadmap. |
|
|
305
305
|
| CHE-40 `/powerline` tab | Done (#18 / 0.19.2). |
|
|
306
|
-
| CHE-41 per-segment detail |
|
|
306
|
+
| CHE-41 per-segment detail | Done. `→` in Navigate; snapshot on open; `alt+i` stays ports. |
|
|
307
307
|
| CHE-42 drill-down | Done (#19 + Configure in #13). |
|
|
308
|
-
| GRO-1414 0.20 leftovers |
|
|
308
|
+
| GRO-1414 0.20 leftovers | Done (#20 / 0.22.0). |
|
|
309
309
|
|
|
310
310
|
Oude `pi-powerline-footer`-projecttickets niet laten staan alsof
|
|
311
311
|
die package nog leeft.
|
package/docs/commands.md
CHANGED
|
@@ -101,7 +101,7 @@ Pi core renders the footer as static text, so live click is not possible; action
|
|
|
101
101
|
- `/open-ports`: list listening ports and pick one
|
|
102
102
|
- `/powerline doctor`: diagnostics overlay — settings file validity, unknown presets, Nerd Font detection, git polling, bash-mode status, and queue file health
|
|
103
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
|
|
104
|
+
- `alt+p`: **powerline menu**: navigate the live segments (`↑`/`↓` + `enter`, `→`/`tab` opens a per-segment detail panel captured at open), configure (preset / TPS / UDP / segment visibility / labels / build custom preset), or open the full ports list
|
|
105
105
|
- `alt+i`: **powerline info**: full open-ports list
|
|
106
106
|
|
|
107
107
|
Both `alt+p` and `alt+i` are rebindable (see Keybinds below); changes apply after `/reload`.
|
package/docs/index.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# pi-wishcraft documentation
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
The README stays a short landing page; everything below lives here.
|
|
3
|
+
The README is the public landing page (`banner.png` only). Everything below lives here.
|
|
5
4
|
|
|
6
5
|
## Guides
|
|
7
6
|
|
package/docs/segments.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
### Open-port process owners
|
|
11
11
|
|
|
12
|
-
Open the segment detail view (`alt+p` →
|
|
12
|
+
Open the segment detail view (`alt+p` → Navigate → `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 opening detail stays cheap. The full `alt+i` ports list shows the raw `ss -p` process column as well.
|
|
13
13
|
|
|
14
14
|
### Fleet open-ports (SSH probe)
|
|
15
15
|
|
package/package.json
CHANGED
package/queue/store.ts
CHANGED
|
@@ -364,12 +364,14 @@ export class PowerlineQueueStore {
|
|
|
364
364
|
* `archiveSentItems` and `writeItems` share one `now` snapshot so a sent
|
|
365
365
|
* item counted as remaining cannot be pruned on the same write.
|
|
366
366
|
*/
|
|
367
|
-
archiveSentItems(
|
|
367
|
+
archiveSentItems(
|
|
368
|
+
olderThanMs: number = this.sentRetentionMs,
|
|
369
|
+
now: number = Date.now(),
|
|
370
|
+
): {
|
|
368
371
|
archived: number;
|
|
369
372
|
remainingSent: number;
|
|
370
373
|
} {
|
|
371
374
|
return this.withStoreLock(() => {
|
|
372
|
-
const now = Date.now();
|
|
373
375
|
const items = this.list();
|
|
374
376
|
// writeItems prunes sent items older than sentRetentionMs on every write.
|
|
375
377
|
// If the requested archive window were wider than that, items in the gap
|
|
@@ -45,7 +45,6 @@ import {
|
|
|
45
45
|
collectSegmentIds,
|
|
46
46
|
configureItemsToSelectItems,
|
|
47
47
|
segmentItemsToSelectItems,
|
|
48
|
-
selectIndexForValue,
|
|
49
48
|
validatePresetName,
|
|
50
49
|
} from "./menu-items.ts";
|
|
51
50
|
import { overlaySelectListTheme, showSelectOverlay } from "./overlay-chrome.ts";
|
|
@@ -53,9 +52,6 @@ import { showTpsOverlay } from "./token-overlays.ts";
|
|
|
53
52
|
|
|
54
53
|
export { overlaySelectListTheme, showSelectOverlay } from "./overlay-chrome.ts";
|
|
55
54
|
|
|
56
|
-
/** How often the open segment navigator re-reads live segment state. */
|
|
57
|
-
const SEGMENT_NAVIGATOR_REFRESH_MS = 1000;
|
|
58
|
-
|
|
59
55
|
/** Full open-ports list as a scrollable overlay (the Info view). */
|
|
60
56
|
export async function showOpenPortsList(ctx: any): Promise<void> {
|
|
61
57
|
try {
|
|
@@ -402,12 +398,16 @@ export async function showSegmentNavigator(
|
|
|
402
398
|
let items = segmentItemsToSelectItems(buildSegmentItems(segCtx, config));
|
|
403
399
|
let detailId: StatusLineSegmentId | null = null;
|
|
404
400
|
let detailLines: ReturnType<typeof buildSegmentDetailLines> = [];
|
|
405
|
-
let timer: ReturnType<typeof setInterval> | null = null;
|
|
406
401
|
|
|
407
402
|
const border = (text: string) => theme.fg("dim", text);
|
|
408
403
|
const wrapRow = (text: string, innerWidth: number) =>
|
|
409
404
|
`${border("│")}${truncateToWidth(text, innerWidth, "…", true)}${border("│")}`;
|
|
410
405
|
|
|
406
|
+
const snapshot = () => {
|
|
407
|
+
segCtx = buildSegmentContext(rt, ctx, theme);
|
|
408
|
+
items = segmentItemsToSelectItems(buildSegmentItems(segCtx, config));
|
|
409
|
+
};
|
|
410
|
+
|
|
411
411
|
const buildDetail = (id: StatusLineSegmentId) =>
|
|
412
412
|
id === "open_ports"
|
|
413
413
|
? buildSegmentDetailLines(
|
|
@@ -422,15 +422,12 @@ export async function showSegmentNavigator(
|
|
|
422
422
|
|
|
423
423
|
const openDetail = (id: string) => {
|
|
424
424
|
if (id === "__none__") return;
|
|
425
|
+
snapshot();
|
|
425
426
|
detailId = id as StatusLineSegmentId;
|
|
426
427
|
detailLines = buildDetail(detailId);
|
|
427
428
|
};
|
|
428
429
|
|
|
429
430
|
const finish = (result: { id: string; label: string } | null) => {
|
|
430
|
-
if (timer !== null) {
|
|
431
|
-
clearInterval(timer);
|
|
432
|
-
timer = null;
|
|
433
|
-
}
|
|
434
431
|
done(result);
|
|
435
432
|
};
|
|
436
433
|
|
|
@@ -452,22 +449,6 @@ export async function showSegmentNavigator(
|
|
|
452
449
|
|
|
453
450
|
let selectList = makeSelectList();
|
|
454
451
|
|
|
455
|
-
// Re-read live segment state (TPS, context %, cost, git, queue, …) while
|
|
456
|
-
// the overlay stays open, preserving the selected segment across rebuilds.
|
|
457
|
-
const refresh = () => {
|
|
458
|
-
const previous = selectList.getSelectedItem()?.value ?? null;
|
|
459
|
-
segCtx = buildSegmentContext(rt, ctx, theme);
|
|
460
|
-
items = segmentItemsToSelectItems(buildSegmentItems(segCtx, config));
|
|
461
|
-
selectList = makeSelectList();
|
|
462
|
-
selectList.setSelectedIndex(selectIndexForValue(items, previous));
|
|
463
|
-
if (detailId !== null) {
|
|
464
|
-
detailLines = buildDetail(detailId);
|
|
465
|
-
}
|
|
466
|
-
tui.requestRender();
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
timer = setInterval(refresh, SEGMENT_NAVIGATOR_REFRESH_MS);
|
|
470
|
-
|
|
471
452
|
const renderList = (innerWidth: number): string[] => {
|
|
472
453
|
const lines: string[] = [];
|
|
473
454
|
lines.push(border(`╭${"─".repeat(innerWidth)}╮`));
|
package/src/segments/system.ts
CHANGED
|
@@ -303,8 +303,8 @@ const OPEN_PORT_PROCESSES_TTL_MS = 2000;
|
|
|
303
303
|
/**
|
|
304
304
|
* Best-effort process owners for listening ports via `ss -tulnp` (falls back
|
|
305
305
|
* to `netstat -tulnp`), optionally probed over SSH for a fleet host. Cached
|
|
306
|
-
* like the open_ports count so the detail
|
|
307
|
-
* process on every
|
|
306
|
+
* like the open_ports count so opening the ports detail does not spawn a
|
|
307
|
+
* process on every keystroke.
|
|
308
308
|
*/
|
|
309
309
|
export function listOpenPortProcesses(
|
|
310
310
|
includeUdp = false,
|