@gavin-hu/my-pi-agent 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -12
- package/README.zh-CN.md +15 -9
- package/docs/extensions/README.md +2 -1
- package/docs/extensions/board.md +329 -151
- package/docs/extensions/bytefly.md +427 -273
- package/docs/extensions/file-browse.md +46 -44
- package/docs/extensions/job.md +1 -2
- package/docs/extensions/plan.md +86 -24
- package/docs/extensions/serve.md +129 -0
- package/docs/extensions/session-bus.md +23 -10
- package/docs/extensions/team.md +56 -28
- package/docs/extensions/wechat.md +2 -1
- package/docs/extensions/worktree.md +30 -15
- package/extensions/board/commands.ts +48 -17
- package/extensions/board/format.ts +107 -9
- package/extensions/board/index.ts +14 -2
- package/extensions/board/join.ts +31 -10
- package/extensions/board/page.ts +202 -156
- package/extensions/board/result.ts +10 -24
- package/extensions/board/rows.ts +1 -1
- package/extensions/board/schema.ts +31 -10
- package/extensions/board/seat.ts +9 -10
- package/extensions/board/snapshot.ts +7 -5
- package/extensions/board/tools.ts +211 -34
- package/extensions/board/transport/router.ts +27 -110
- package/extensions/board/transport/server.ts +76 -56
- package/extensions/board/types.ts +57 -0
- package/extensions/board/view/client.ts +24 -13
- package/extensions/board/view/dialog.ts +43 -0
- package/extensions/board/view/keys.ts +28 -24
- package/extensions/board/view/live.ts +6 -178
- package/extensions/board/view/names.ts +91 -0
- package/extensions/board/view/page.ts +60 -89
- package/extensions/board/view/render.ts +228 -200
- package/extensions/board/view/styles.ts +72 -49
- package/extensions/board/view/team.ts +63 -41
- package/extensions/bytefly/footer/budget.ts +6 -5
- package/extensions/bytefly/footer/collect/entries.ts +12 -4
- package/extensions/bytefly/footer/collect/snapshot.ts +8 -17
- package/extensions/bytefly/footer/config.ts +19 -11
- package/extensions/bytefly/footer/price/price.ts +30 -8
- package/extensions/bytefly/footer/register.ts +5 -5
- package/extensions/bytefly/footer/render/footer.ts +18 -4
- package/extensions/bytefly/footer/render/format.ts +18 -0
- package/extensions/bytefly/footer/render/key.ts +46 -0
- package/extensions/bytefly/footer/render/layout.ts +13 -3
- package/extensions/bytefly/footer/render/lines.ts +23 -7
- package/extensions/bytefly/footer/render/segments.ts +93 -31
- package/extensions/bytefly/footer/types.ts +29 -5
- package/extensions/bytefly/footer/unpriced.ts +42 -17
- package/extensions/bytefly/header/component.ts +4 -20
- package/extensions/bytefly/panel/commands.ts +28 -1
- package/extensions/bytefly/panel/filter.ts +68 -0
- package/extensions/bytefly/panel/format.ts +16 -15
- package/extensions/bytefly/panel/join.ts +56 -13
- package/extensions/bytefly/panel/prices.ts +43 -0
- package/extensions/bytefly/panel/settings.ts +72 -23
- package/extensions/bytefly/panel/tui/entries.ts +26 -8
- package/extensions/bytefly/panel/tui/frame.ts +130 -93
- package/extensions/bytefly/panel/tui/keys.ts +352 -0
- package/extensions/bytefly/panel/tui/list-view.ts +25 -46
- package/extensions/bytefly/panel/tui/panes.ts +76 -0
- package/extensions/bytefly/panel/tui/section-view.ts +126 -0
- package/extensions/bytefly/panel/tui/settings-section.ts +54 -125
- package/extensions/bytefly/panel/tui/settings-view.ts +30 -131
- package/extensions/bytefly/panel/tui/side-pane.ts +224 -0
- package/extensions/bytefly/panel/tui.ts +306 -259
- package/extensions/check/commands.ts +2 -1
- package/extensions/check/render.ts +10 -1
- package/extensions/file-browse/config/config.ts +4 -19
- package/extensions/file-browse/files/classify.ts +136 -0
- package/extensions/file-browse/files/files.ts +8 -547
- package/extensions/file-browse/files/index.ts +90 -0
- package/extensions/file-browse/files/list.ts +261 -0
- package/extensions/file-browse/files/tree.ts +101 -0
- package/extensions/file-browse/index.ts +27 -48
- package/extensions/file-browse/live/live.ts +1 -1
- package/extensions/file-browse/transport/router.ts +12 -6
- package/extensions/file-browse/transport/server.ts +61 -28
- package/extensions/file-browse/view/chrome.ts +4 -4
- package/extensions/file-browse/view/client.ts +3 -1
- package/extensions/file-browse/view/emit.ts +51 -0
- package/extensions/file-browse/view/html.ts +78 -46
- package/extensions/file-browse/view/live-client.ts +2 -2
- package/extensions/file-browse/view/markdown.ts +23 -26
- package/extensions/file-browse/view/palette.ts +2 -2
- package/extensions/file-browse/view/raw-html.ts +27 -22
- package/extensions/file-browse/view/tree.ts +1 -1
- package/extensions/file-browse/view/urls.ts +20 -6
- package/extensions/goal/tui.ts +12 -2
- package/extensions/job/runtime.ts +4 -4
- package/extensions/job/tools.ts +19 -7
- package/extensions/job/tui.ts +2 -28
- package/extensions/plan/commands.ts +2 -2
- package/extensions/plan/feedback.ts +88 -18
- package/extensions/plan/format.ts +10 -3
- package/extensions/plan/index.ts +24 -2
- package/extensions/plan/plan-files.ts +88 -0
- package/extensions/plan/plan-text.ts +114 -0
- package/extensions/plan/plans.ts +19 -23
- package/extensions/plan/policy.ts +10 -5
- package/extensions/plan/runtime.ts +43 -4
- package/extensions/plan/todos.ts +51 -3
- package/extensions/plan/tools/exit.ts +10 -1
- package/extensions/plan/tools/todo-seed.ts +4 -2
- package/extensions/plan/tools/write.ts +12 -1
- package/extensions/plan/tools.ts +2 -2
- package/extensions/plan/types.ts +15 -0
- package/extensions/plan/web-blocks.ts +160 -0
- package/extensions/plan/web-chrome.ts +7 -5
- package/extensions/plan/web-client.ts +271 -325
- package/extensions/plan/web-collab.ts +7 -7
- package/extensions/plan/web-comments.ts +57 -16
- package/extensions/plan/web-composer.ts +91 -0
- package/extensions/plan/web-draft.ts +40 -0
- package/extensions/plan/web-keys.ts +258 -0
- package/extensions/plan/web-markdown.ts +1 -1
- package/extensions/plan/web-outline.ts +212 -0
- package/extensions/plan/web-page.ts +59 -86
- package/extensions/plan/web-payload.ts +188 -0
- package/extensions/plan/web-plan.ts +160 -0
- package/extensions/plan/web-router.ts +0 -1
- package/extensions/plan/web-settle.ts +201 -0
- package/extensions/plan/web-share-session.ts +24 -55
- package/extensions/plan/web-share.ts +19 -37
- package/extensions/plan/web-write.ts +112 -0
- package/extensions/plan/web.ts +77 -130
- package/extensions/rewind/commands/review.ts +2 -1
- package/extensions/serve/config.ts +37 -0
- package/extensions/serve/index.ts +71 -0
- package/extensions/serve/registry.ts +251 -0
- package/extensions/session-bus/join-request.ts +16 -9
- package/extensions/session-bus/result.ts +1 -27
- package/extensions/session-bus/rows.ts +7 -3
- package/extensions/session-bus/runtime.ts +100 -38
- package/extensions/session-bus/store.ts +14 -2
- package/extensions/session-bus/tools.ts +5 -4
- package/extensions/session-bus/tui.ts +1 -1
- package/extensions/session-bus/types.ts +10 -1
- package/extensions/subagent/commands.ts +2 -1
- package/extensions/team/commands.ts +44 -9
- package/extensions/team/format.ts +14 -0
- package/extensions/team/index.ts +2 -1
- package/extensions/team/tools.ts +30 -9
- package/extensions/team/types.ts +17 -0
- package/extensions/todo/index.ts +4 -1
- package/extensions/todo/nudge.ts +8 -2
- package/extensions/todo/tui.ts +21 -3
- package/extensions/wechat/bridge.ts +43 -172
- package/extensions/wechat/intake.ts +245 -0
- package/extensions/worktree/commands.ts +24 -17
- package/extensions/worktree/exit.ts +12 -6
- package/extensions/worktree/git.ts +22 -14
- package/extensions/worktree/guard.ts +15 -285
- package/extensions/worktree/handoff.ts +10 -2
- package/extensions/worktree/index.ts +2 -1
- package/extensions/worktree/lifecycle.ts +2 -0
- package/extensions/worktree/registry.ts +20 -11
- package/extensions/worktree/root-tools.ts +13 -3
- package/extensions/worktree/runtime.ts +8 -2
- package/extensions/worktree/screen.ts +15 -8
- package/extensions/worktree/shell.ts +303 -0
- package/extensions/worktree/state.ts +1 -1
- package/extensions/worktree/status.ts +42 -9
- package/extensions/worktree/tools.ts +19 -13
- package/lib/README.md +9 -7
- package/lib/board/card.ts +192 -3
- package/lib/board/links.ts +26 -2
- package/lib/board/page-pointer.ts +111 -32
- package/lib/board/round-text.ts +11 -2
- package/lib/board/round.ts +25 -20
- package/lib/board/rules.ts +144 -11
- package/lib/board/session.ts +84 -18
- package/lib/board/store.ts +268 -55
- package/lib/board/view.ts +114 -24
- package/lib/bus-request.ts +83 -0
- package/lib/format.ts +22 -0
- package/lib/http/index.ts +11 -7
- package/lib/http/mount.ts +142 -0
- package/lib/http/port.ts +25 -0
- package/lib/http/serve.ts +170 -43
- package/lib/http/server.ts +3 -3
- package/lib/http/sink.ts +34 -9
- package/lib/plan-entry.ts +20 -13
- package/lib/policy.ts +14 -1
- package/lib/requirements.ts +2 -2
- package/lib/session-label.ts +23 -7
- package/lib/session-roster.ts +74 -3
- package/lib/session-tool.ts +37 -21
- package/lib/spawn.ts +37 -3
- package/lib/stray-fields.ts +45 -0
- package/lib/tool-names.ts +13 -0
- package/lib/tui/README.md +6 -3
- package/lib/tui/glyphs.ts +3 -6
- package/lib/tui/render-cache.ts +29 -0
- package/lib/tui/tool.ts +30 -1
- package/lib/web/README.md +52 -2
- package/lib/web/client-runtime.ts +149 -0
- package/lib/web/index.ts +4 -2
- package/lib/web/markup.ts +106 -2
- package/lib/web/names.ts +42 -0
- package/package.json +3 -2
- package/extensions/board/config.ts +0 -36
- package/extensions/board/view/actions.ts +0 -306
- package/extensions/board/writes.ts +0 -99
- package/extensions/bytefly/panel/tui/extensions-view.ts +0 -40
- package/extensions/bytefly/panel/tui/skills-view.ts +0 -50
- package/extensions/job/process.ts +0 -35
|
@@ -17,8 +17,8 @@ Status records what a reader can rely on: **Shipped** is in a tagged release, **
|
|
|
17
17
|
| Capability | How | What you get | Status |
|
|
18
18
|
|---|---|---|---|
|
|
19
19
|
| Startup header | `quietStartup` | One two-tone nameplate with the agent and chrome versions and the live help keys, in place of Pi's startup header and resource listing. | Shipped |
|
|
20
|
-
| Two-line footer | every `tui` session |
|
|
21
|
-
| Extension status chips | `footerData.getExtensionStatuses()` | Worktree, browse, plan, and alert statuses appear in the footer, using each extension's own colour. | Shipped |
|
|
20
|
+
| Two-line footer | every `tui` session | State on one line — location, modes, and alerts — and meters on the other — context, spend, tokens, cache, and model — each shedding parts rather than clipping. | Shipped |
|
|
21
|
+
| Extension status chips | `footerData.getExtensionStatuses()` | Worktree, browse, plan, and alert statuses appear in the footer, using each extension's own colour. A failed job is the one chip no width drops. | Shipped |
|
|
22
22
|
| Priced session total | the `price` section of `bytefly.json` | The session's spend in yuan or dollars, with DeepSeek priced out of the box. | Shipped |
|
|
23
23
|
| Delegated-run cost roll-up | the `↳` footer segment | A finished subagent's cost appears beside the session total, without merging the two ledgers. | Shipped |
|
|
24
24
|
| User-message nameplate | every `tui` session | Each user message opens with a two-row `You` label and rule. | Shipped |
|
|
@@ -32,12 +32,12 @@ Status records what a reader can rely on: **Shipped** is in a tagged release, **
|
|
|
32
32
|
|
|
33
33
|
| Capability | How | What you get | Status |
|
|
34
34
|
|---|---|---|---|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
35
|
+
| One frame, three sections | `/bytefly`, `/bytefly skills`, `/bytefly settings` | Extensions, skills, and settings in one dock: the worst problem in the header, each section's count on the tabs, the write scope at the right, and one body height for all three, so changing section never resizes the screen. | Shipped |
|
|
36
|
+
| Resource rows and the block | `Space`, `Enter`, `?` | A name-first row — `worktree`, not `worktree/index.ts` — with one checkbox, one status glyph and one verdict word, and the focused row's findings, path, source, state, and health beside the list at 96 columns and under it below. | Shipped |
|
|
37
|
+
| Grouped settings | `/bytefly settings` | Twelve preferences under `Startup`, `Notifications`, `Session`, and `Price`, each value in one aligned column and editable in place; `J` shows the stored JSON section. | Shipped |
|
|
37
38
|
| Theme selection | the `Theme` row in `/bytefly settings` | `system` and the package's `bytefly-dark` and `bytefly-light` palettes are one selection; a reload applies it. | Shipped |
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
| Reload after changes | `/bytefly` after a pending write | The screen offers the reload that applies extension, skill, or setting changes instead of leaving the session to be restarted by hand. | Shipped |
|
|
39
|
+
| Filters and scope | `/`, `!`, `s`, `x` | Narrow the rows by text or to what needs attention — the chips on the tab row say which — and choose where a toggle lands, the personal or project `settings.json`, with `x` clearing a project override. | Shipped |
|
|
40
|
+
| Reload after changes | `R` | `unsaved changes` joins the header while a write is pending, and `R` reloads to apply it instead of leaving the session to be restarted by hand. | Shipped |
|
|
41
41
|
| Health report | `run_doctor`, `/bytefly doctor` | Prerequisites, parse errors, and aged rate tables as text and typed data. | Shipped |
|
|
42
42
|
|
|
43
43
|
### Upkeep
|
|
@@ -45,7 +45,7 @@ Status records what a reader can rely on: **Shipped** is in a tagged release, **
|
|
|
45
45
|
| Capability | How | What you get | Status |
|
|
46
46
|
|---|---|---|---|
|
|
47
47
|
| Currency and peak tariff | `price.currency.code`, `price.peak` | `CNY` and `USD` are separate pricing methods with published rates; DeepSeek's peak windows apply per token record. | Shipped |
|
|
48
|
-
| Session budget alert | `price.budget` |
|
|
48
|
+
| Session budget alert | `price.budget` | The session total shows as `spent/limit` in the footer, and one notice plus one OS notification fires when it reaches the threshold. | Partial |
|
|
49
49
|
| Unpriced-record notice | `price.currency.code` | A `CNY` session names the records it could not price, and the two ways to fix it. | Shipped |
|
|
50
50
|
| Desktop notifications | `notify.enabled`, `notify.turnFinished`, `notify.needsInput`, `notify.jobFinished`, `notify.matchFound` | An OS notification when a run settles, the agent needs you, a job finishes, or a watcher matches. | Shipped |
|
|
51
51
|
| Proactive health check | `doctor.proactive` | At session start, when the startup header is on, a hard requirement is probed once and reported before the first turn. | Shipped |
|
|
@@ -97,12 +97,13 @@ One command runs the screen, prints the report, and re-checks updates:
|
|
|
97
97
|
| `/bytefly settings` | Open the control center on Settings. Outside `tui` it prints one `Label: Value` line per setting. |
|
|
98
98
|
| `/bytefly skills` | Open the control center on Skills. Outside `tui` it prints the grouped skills listing with one row per skill. |
|
|
99
99
|
| `/bytefly doctor [extension] [refresh]` | Print the doctor report. Outside `tui` it prints `run_doctor`'s text for every extension, or one named extension's findings; in `tui` it mounts the same docked screen. |
|
|
100
|
+
| `/bytefly prices` | Name the models this session could not price: the `price.rates` key for each, the records behind it, and where to add it. It prices the session when asked, so it answers in every mode — the footer that carries the same fact exists only in `tui`. No rate is suggested. |
|
|
100
101
|
| `/bytefly update` | Re-run the package update check now, ignoring the cache window, and report what it found — the updateable packages, this package's version and release URL when known, `PI_OFFLINE`, or an unreadable list. It resolves no packages and probes no extension. |
|
|
101
102
|
| `/bytefly upgrade` | Install what the check found, behind a confirmation: Pi's own package manager updates every configured package, the marker is re-read, and one line reports the result and the reload it needs. `PI_OFFLINE` and a pinned npm version skip the work. It resolves no packages and mounts no screen. |
|
|
102
103
|
|
|
103
104
|
Tab completes the subcommands, extension names after `doctor`, and `refresh`;
|
|
104
|
-
`/bytefly settings`, `/bytefly skills`, `/bytefly
|
|
105
|
-
take no name.
|
|
105
|
+
`/bytefly settings`, `/bytefly skills`, `/bytefly prices`, `/bytefly update`, and
|
|
106
|
+
`/bytefly upgrade` take no name.
|
|
106
107
|
|
|
107
108
|
## Behaviour by mode
|
|
108
109
|
|
|
@@ -193,7 +194,7 @@ catch-all prices everything).
|
|
|
193
194
|
| Section | Read at | Applies to |
|
|
194
195
|
|---|---|---|
|
|
195
196
|
| `chrome` | `session_start`, `session_tree` | the rail glyph |
|
|
196
|
-
| `price` | the footer install (`session_start`, `session_tree`) | the cost total |
|
|
197
|
+
| `price` | the footer install (`session_start`, `session_tree`) | the cost total and the budget ceiling beside it |
|
|
197
198
|
| `notify` | `session_start` | which events are announced, and how |
|
|
198
199
|
| `doctor` | `session_start` | the proactive check |
|
|
199
200
|
|
|
@@ -231,7 +232,7 @@ resolve live from Pi's keybindings, so a rebound key shows the user's chord; the
|
|
|
231
232
|
identity and help text are `meta` / `faint` so the mark keeps the eye. It opens
|
|
232
233
|
with a blank row, so the nameplate clears the top edge. It is installed only in
|
|
233
234
|
interactive (`tui`) sessions when Pi's `quietStartup` is `true` — the Settings
|
|
234
|
-
row **
|
|
235
|
+
row **Startup screen** — and `false`, `"header"`, and unset leave Pi's
|
|
235
236
|
built-in header in place; on terminals that cannot render half blocks the mark
|
|
236
237
|
falls back to a two-tone `Pi` wordmark.
|
|
237
238
|
|
|
@@ -260,13 +261,14 @@ identity, and grouped help are tuned in
|
|
|
260
261
|
|
|
261
262
|
Two lines, each with a left and right zone:
|
|
262
263
|
|
|
263
|
-
- **Line 1 — identity:** `pwd` and the session name on the left;
|
|
264
|
-
|
|
264
|
+
- **Line 1 — identity:** `pwd` and the session name on the left; on the right the
|
|
265
|
+
alert, then the mode chips (`≡ plan`), then `⎇ branch · ⑂ worktree`, then the
|
|
266
|
+
session's page port (`◉ 4780`) while anything is served on it. One server serves
|
|
267
|
+
every page of a session, so it is one number from one status key.
|
|
265
268
|
- **Line 2 — resources:** the context gauge and usage meters on the left, the
|
|
266
269
|
child-run roll-up (`↳ 3 · ¥0.12`, present only once a subagent has finished),
|
|
267
|
-
the
|
|
268
|
-
|
|
269
|
-
always in the same place.
|
|
270
|
+
and the model and thinking level on the right. The gauge is anchored at column
|
|
271
|
+
0, so `%` is always in the same place.
|
|
270
272
|
The roll-up is its own number, never folded into the session's cost: a subagent
|
|
271
273
|
runs in its own process, and the footer prices those runs with the same rate
|
|
272
274
|
table and currency as the session so a currency change moves both. It covers
|
|
@@ -274,8 +276,8 @@ Two lines, each with a left and right zone:
|
|
|
274
276
|
`/resume` (the events are not session entries).
|
|
275
277
|
|
|
276
278
|
```
|
|
277
|
-
~/repo/my-pi-agent
|
|
278
|
-
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↳ 2 · ¥0.06 · ↑42k ↓8.0k · R96k CH 87%
|
|
279
|
+
~/repo/my-pi-agent ≡ plan · ⎇ main · ⑂ smoke
|
|
280
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↳ 2 · ¥0.06 · ↑42k ↓8.0k · R96k CH 87% opus-4.5 · high
|
|
279
281
|
```
|
|
280
282
|
|
|
281
283
|
(The examples show the default `¥` symbol. A model that neither `rates` nor the
|
|
@@ -283,11 +285,18 @@ built-in table covers contributes nothing in `CNY` mode, so the bar shows no
|
|
|
283
285
|
figure rather than a guessed one; `USD` mode adds Pi's recorded dollars for that
|
|
284
286
|
record instead — see [Cost calculation](#cost-calculation).)
|
|
285
287
|
|
|
286
|
-
With no plan mode
|
|
288
|
+
With no plan mode the mode slot is simply absent:
|
|
287
289
|
|
|
288
290
|
```
|
|
289
|
-
~/repo/my-pi-agent
|
|
290
|
-
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↑42k ↓8.0k · R96k CH 87%
|
|
291
|
+
~/repo/my-pi-agent ⎇ main · ⑂ smoke
|
|
292
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↑42k ↓8.0k · R96k CH 87% opus-4.5 · high
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
While a page is served, the session's port joins the run beside the worktree:
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
~/repo/my-pi-agent ⎇ main · ◉ 4780
|
|
299
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↑42k ↓8.0k · R96k CH 87% opus-4.5 · high
|
|
291
300
|
```
|
|
292
301
|
|
|
293
302
|
As the terminal narrows, segments shrink and drop by priority rather than
|
|
@@ -295,20 +304,29 @@ clipping. The branch keeps its name and is dropped when the name no longer
|
|
|
295
304
|
fits, rather than collapsing to a bare glyph:
|
|
296
305
|
|
|
297
306
|
```
|
|
298
|
-
~/repo/
|
|
299
|
-
▰▰▰▰▰▰▱▱▱▱ 62
|
|
307
|
+
~/repo/my-pi-agent ≡ plan · ⎇ main · ⑂
|
|
308
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 opus-4.5 · high
|
|
300
309
|
```
|
|
301
310
|
|
|
302
311
|
```
|
|
303
|
-
|
|
304
|
-
62%
|
|
312
|
+
~/my-pi-agent ⎇ main
|
|
313
|
+
▰▰▰▰▰▰▱▱▱▱ 62% opus-4.5
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
The port drops the digits before the page they name: it compacts to `◉` once
|
|
317
|
+
the number no longer fits, so the narrowest bar that fits the location chips still
|
|
318
|
+
says a page is up.
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
~/repo/my-pi-agent ⎇ main · ◉
|
|
322
|
+
▰▰▰▰▰▰▱▱▱▱ 62% · ¥0.31 opus-4.5 · high
|
|
305
323
|
```
|
|
306
324
|
|
|
307
325
|
With a named session, the name follows the path and truncates before it drops:
|
|
308
326
|
|
|
309
327
|
```
|
|
310
|
-
~/repo/project · feature-refac…
|
|
311
|
-
▰▰▰▰▰▰▱▱▱▱ 62
|
|
328
|
+
~/repo/project · [feature-refac…] ⎇ main
|
|
329
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 opus-4.5 · high
|
|
312
330
|
```
|
|
313
331
|
|
|
314
332
|
Zero-value meters are omitted, so a fresh session shows only `?/window` instead
|
|
@@ -324,29 +342,33 @@ Each segment reads a theme role and carries its own drop order:
|
|
|
324
342
|
|---|---|---|---|
|
|
325
343
|
| pwd | 1 left | dim | last |
|
|
326
344
|
| session | 1 left | muted, bracketed | after worktree |
|
|
327
|
-
| browse | 1 right | success glyph + accent port | first |
|
|
328
345
|
| branch | 1 right | muted (warning when detached) | last |
|
|
329
346
|
| worktree | 1 right | success | first |
|
|
347
|
+
| port `◉ 4780` | 1 right | success glyph + accent port | first |
|
|
330
348
|
| context gauge + `%` | 2 left | muted ≤70 · warning 71–90 · error >90 | never |
|
|
331
349
|
| `/window` | 2 left | dim | before cost |
|
|
332
350
|
| cost | 2 left | muted | after tokens |
|
|
333
351
|
| tokens `↑in ↓out` | 2 left | dim | after cache |
|
|
334
352
|
| cache `R… CH …%` | 2 left | dim | first |
|
|
335
|
-
| statuses |
|
|
353
|
+
| statuses | 1 right | as emitted by each extension | before branch |
|
|
336
354
|
| model | 2 right | accent | never |
|
|
337
355
|
| thinking level | 2 right | thinking token | before cost |
|
|
338
356
|
|
|
339
357
|
The worktree status is read from the `worktree` status key, so the
|
|
340
|
-
[worktree](./worktree.md) extension and the bar agree. The
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
358
|
+
[worktree](./worktree.md) extension and the bar agree. The port is the `http`
|
|
359
|
+
status key, published by [serve](./serve.md) while anything is mounted on the
|
|
360
|
+
session's server — one number, because one socket serves every page a session
|
|
361
|
+
opens. It is a two-tone `<glyph> <port>` with a green glyph and an accent port,
|
|
362
|
+
and it compacts from `◉ 4780` to `◉` before it drops, so a bar too narrow for
|
|
363
|
+
the number still says a page is up.
|
|
364
|
+
|
|
365
|
+
The mode slot holds everything else an extension publishes: a plan chip, a
|
|
366
|
+
job count, a rewind timeline, the `✆` bridge, and an alert's front position. A
|
|
367
|
+
plan chip's trailing plan file name is dropped, so the slot reads `≡ plan` even
|
|
368
|
+
though the built-in footer keeps the name, and an alert (a failed job) sorts to
|
|
369
|
+
the front of it. It keeps each extension's own colour when it compacts, and it is
|
|
370
|
+
droppable: a tight bar drops the slot rather than truncating the model, which
|
|
371
|
+
sits at the end of the line.
|
|
350
372
|
|
|
351
373
|
## Cost calculation
|
|
352
374
|
|
|
@@ -407,14 +429,27 @@ turns it off. The check reads the total the footer already priced, and the
|
|
|
407
429
|
footer exists only in `tui` sessions, so a print or JSON run has no budget
|
|
408
430
|
alert; the footer's own numbers are visible in every interactive session.
|
|
409
431
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
`
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
432
|
+
A record nothing prices contributes nothing to the total. `CNY` has no fallback at
|
|
433
|
+
all; `USD` falls back to Pi's recorded amount, which is `0` for a model its catalog
|
|
434
|
+
does not know either. So "unpriced" means the same thing in both modes — no
|
|
435
|
+
`price.rates` key matched **and** nothing else priced it — and it is counted by
|
|
436
|
+
*model*, because a count says the total is short while a key says what to do:
|
|
437
|
+
|
|
438
|
+
- The footer's cost segment marks it: `¥1.23 · 2 unpriced`, dropping to the count
|
|
439
|
+
alone on a narrow bar. A session where nothing could be priced shows `2 unpriced`
|
|
440
|
+
beside no price at all, where it used to show nothing.
|
|
441
|
+
- `/bytefly prices` lists them — the key, the records behind it, and the line saying
|
|
442
|
+
where the keys go. It prices the session when asked, so it works in every mode,
|
|
443
|
+
including the ones with no footer.
|
|
444
|
+
- One `bytefly · Records with no rate` notice fires per session, on the run that
|
|
445
|
+
settles, naming up to three keys. The two fixes it offers are both honest: switch
|
|
446
|
+
`price.currency.code` to `USD` (Pi's catalog is per model, tiers included) or add
|
|
447
|
+
`price.rates` entries for those keys.
|
|
448
|
+
|
|
449
|
+
The key is the `price.rates` vocabulary, so it is copy-pasteable: `provider/model`,
|
|
450
|
+
`*` for a side the history does not name, and a model id containing a slash kept
|
|
451
|
+
whole (`openrouter/anthropic/claude-fable-5`). A genuinely free model — a local one
|
|
452
|
+
whose recorded cost is `0` — is listed too; adding its key costs nothing.
|
|
418
453
|
|
|
419
454
|
For example, DeepSeek flash at `¥2` in and `¥8` out per million, with the
|
|
420
455
|
published peak windows and `offPeakMultiplier: 0.5`, prices a 1M-in + 1M-out
|
|
@@ -621,39 +656,122 @@ in [`working/config.ts`](../../extensions/bytefly/working/config.ts).
|
|
|
621
656
|
|
|
622
657
|
## The control center
|
|
623
658
|
|
|
624
|
-
<img src="../../assets/screens/bytefly.png" alt="The /bytefly control center:
|
|
659
|
+
<img src="../../assets/screens/bytefly.png" alt="The /bytefly control center at 120 columns: a `Bytefly` rule with `1 missing` at its right edge, the `Extensions 9 · Skills 0 · Settings 12` tabs with `writes Global` at the right, one name-first row per extension with its checkbox and verdict, and the focused extension's block beside the list — its findings and their fix, Path, Source, State, and Health" width="100%">
|
|
625
660
|
|
|
626
661
|
`/bytefly [extension] [refresh]` opens the control center on **Extensions**: a
|
|
627
|
-
keyboard-driven dock
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
enable checkbox and label, then one verdict — `off` when the row is switched off
|
|
634
|
-
in settings, `env disabled` when `PI_DISABLED_EXTENSIONS` excludes it, otherwise
|
|
635
|
-
the doctor's worst-severity glyph and summary. The screen is drawn from the
|
|
636
|
-
design system: a label-first `Bytefly ────` title rule,
|
|
637
|
-
the `Extensions · Skills · Settings` section bar beside the section's counts, one
|
|
638
|
-
row grammar (`❯ ◼ name … summary`), the shared `◼` / `◻` checkbox, and the closing
|
|
639
|
-
rule under the key hints that Pi's own list screens draw.
|
|
640
|
-
`/bytefly doctor [extension] [refresh]` selects the doctor report, the same text
|
|
641
|
-
the `run_doctor` tool returns; in `tui` it opens the same screen. `[extension]`
|
|
642
|
-
narrows the Extensions section to one extension and `refresh` forces the first
|
|
643
|
-
probe. Tab completes the subcommands, extension names after `doctor`, and
|
|
644
|
-
`refresh`; `/bytefly settings` and `/bytefly skills` take no name.
|
|
662
|
+
keyboard-driven dock of every resource Pi resolves for the session, so the list
|
|
663
|
+
matches what actually loads. `/bytefly skills` and `/bytefly settings` open the
|
|
664
|
+
other two sections directly, and `←`/`→` (or `h`/`l`, or `Tab`) change section,
|
|
665
|
+
wrapping at the ends because the tabs read as a ring. `/bytefly <extension>`
|
|
666
|
+
narrows the list to one extension, and `refresh` forces the first probe. One
|
|
667
|
+
frame draws all three sections.
|
|
645
668
|
|
|
646
669
|
The screen opens on the findings the session already has, and the Extensions
|
|
647
670
|
section probes once on its first view (the hint shows `refreshing…` while it
|
|
648
671
|
runs). `/bytefly settings` therefore never waits for a probe, and a failed probe
|
|
649
672
|
is a notice with the screen still open rather than a refused command. A refusal
|
|
650
|
-
or a failed write appears in the screen's own hint row
|
|
651
|
-
aside
|
|
673
|
+
or a failed write appears in the screen's own hint row — the key hints step
|
|
674
|
+
aside — and clears on the next key, so nothing is written behind the screen.
|
|
652
675
|
|
|
653
676
|
The screen reuses Pi's own settings and package resolution (`SettingsManager`
|
|
654
677
|
plus `DefaultPackageManager` with `onMissing: "skip"`), so opening it never
|
|
655
678
|
installs or fetches a package.
|
|
656
679
|
|
|
680
|
+
**One frame.** The `Bytefly ────` header rule carries the screen's attention at
|
|
681
|
+
its right edge — `1 missing` or `2 degraded` in the severity's own colour, else
|
|
682
|
+
`2 off`, else `all clear`, with `unsaved changes` after it while a write is
|
|
683
|
+
pending. The tab row below names every section with the rows it holds,
|
|
684
|
+
`Extensions 9 · Skills 0 · Settings 12`, the active tab in the accent and the
|
|
685
|
+
counts faint, then any filter chips (`/git`, `needs attention`, `changed only`),
|
|
686
|
+
with `writes Global` (or `writes Project`) at the right edge. The scope is a word
|
|
687
|
+
there because no count line has to carry it any more: the counts are on the tabs,
|
|
688
|
+
the problems are in the header, and the scope is at the right.
|
|
689
|
+
|
|
690
|
+
The body is padded to the tallest section's row count, group headings counted, so
|
|
691
|
+
all three sections draw the same height and the dock does not resize when the
|
|
692
|
+
tabs change. A shorter section pads its last rows with blanks; a longer one
|
|
693
|
+
scrolls inside the same height and puts `showing 3–14 of 19` on its last body
|
|
694
|
+
row. The height is measured from both resource lists and the visible scope's
|
|
695
|
+
settings rows, so changing tab does not resize the dock: only a resize of the
|
|
696
|
+
terminal moves the hint row, or the Project scope's one-line note on a terminal
|
|
697
|
+
too short to hold both.
|
|
698
|
+
|
|
699
|
+
**Two panes.** At 96 columns and wider the focused row's block sits in a side
|
|
700
|
+
column after a `╎` divider: the row's name and verdict; the doctor's findings,
|
|
701
|
+
under a `── findings ──` rule and each with its fix; `Path`, `Source`, and
|
|
702
|
+
`State` for a resolved resource; `Health` when the row has a report; and
|
|
703
|
+
`Saved · reload to apply` once something is pending. Below 96 columns the same
|
|
704
|
+
block is drawn under the list in three rows, clipped, ending with
|
|
705
|
+
`… N more lines` when it has more to say; it leaves out what the row above
|
|
706
|
+
already says — the name and verdict on a resource row, the label and value on a
|
|
707
|
+
settings row, and the path when there are findings to show instead.
|
|
708
|
+
|
|
709
|
+
The picture above is 120 columns wide; the two frames below are the same screen
|
|
710
|
+
at 100 and 80.
|
|
711
|
+
|
|
712
|
+
```
|
|
713
|
+
Bytefly ────────────────────────────────────────────────────────────────────────────────── 1 missing
|
|
714
|
+
Extensions 9 · Skills 0 · Settings 12 writes Global
|
|
715
|
+
|
|
716
|
+
npm:pkg (user) (9) ╎ worktree 1 missing
|
|
717
|
+
◼ file-read ╎ ── findings ────────────────────────────
|
|
718
|
+
◼ job ╎ git: not found on PATH — worktree
|
|
719
|
+
◼ memory ╎ isolation
|
|
720
|
+
◼ plan ╎ → install git and make sure it is on
|
|
721
|
+
◼ subagent ╎ PATH (https://git-scm.com/downloads).
|
|
722
|
+
◼ todo ╎ symlink: the host cannot create symlinks
|
|
723
|
+
◻ ∅ web-access off ╎ → copy the included files by hand.
|
|
724
|
+
◻ ∅ wechat off ╎ Path /pkg/extensions/worktree/ind…
|
|
725
|
+
❯ ◼ ✕ worktree 1 missing ╎ Source npm:pkg (user)
|
|
726
|
+
Not resolved (1) ╎ State enabled
|
|
727
|
+
bytefly ok ╎ Health 1 missing
|
|
728
|
+
╎
|
|
729
|
+
╎
|
|
730
|
+
╎
|
|
731
|
+
╎
|
|
732
|
+
|
|
733
|
+
Esc close · ←/→ section · Space toggle · Enter detail · / filter · ? keys · r refresh · s scope
|
|
734
|
+
────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
```
|
|
738
|
+
Bytefly ────────────────────────────────────────────────────────────── 1 missing
|
|
739
|
+
Extensions 9 · Skills 0 · Settings 12 writes Global
|
|
740
|
+
|
|
741
|
+
npm:pkg (user) (9)
|
|
742
|
+
◼ file-read
|
|
743
|
+
◼ job
|
|
744
|
+
◼ memory
|
|
745
|
+
◼ plan
|
|
746
|
+
◼ subagent
|
|
747
|
+
◼ todo
|
|
748
|
+
◻ ∅ web-access off
|
|
749
|
+
◻ ∅ wechat off
|
|
750
|
+
❯ ◼ ✕ worktree 1 missing
|
|
751
|
+
Not resolved (1)
|
|
752
|
+
bytefly ok
|
|
753
|
+
|
|
754
|
+
git: not found on PATH — worktree isolation
|
|
755
|
+
→ install git and make sure it is on PATH (https://git-scm.com/downloads).
|
|
756
|
+
… 2 more lines
|
|
757
|
+
|
|
758
|
+
Esc close · ←/→ section · Space toggle · Enter detail · / filter · ? keys
|
|
759
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
At 80 columns the block's three rows clip to the first finding and its fix and
|
|
763
|
+
say how many lines are left out, and the hint row has already shed `r refresh`
|
|
764
|
+
and `s scope` from its right edge.
|
|
765
|
+
|
|
766
|
+
**Rows.** A row is named for the resource, not for its file: `worktree`, not
|
|
767
|
+
`worktree/index.ts`. The picker's `folder/file.ts` label survives only where two
|
|
768
|
+
resources share a directory name, because the two rows would otherwise read
|
|
769
|
+
alike. What is left is one checkbox, one status glyph and one verdict word —
|
|
770
|
+
`off`, `1 missing`, `2 degraded`, `env disabled`, `not loaded` for a skill Pi
|
|
771
|
+
refused, `hidden` for one its frontmatter keeps from the model — and a clean row
|
|
772
|
+
carries no glyph and no word at all, so the column reads as one shape and the eye
|
|
773
|
+
finds the rows that need it.
|
|
774
|
+
|
|
657
775
|
- Lists every resolved extension, grouped by source (each package, user
|
|
658
776
|
settings, project settings), sorted packages-first and then by display name.
|
|
659
777
|
- Omits `bytefly`'s own entrypoint from the picker groups, so the tool that
|
|
@@ -664,11 +782,10 @@ installs or fetches a package.
|
|
|
664
782
|
glyph (`!` degraded, `✕` missing) and its summary. A row that is `◻` reads
|
|
665
783
|
`off` instead, because it will not load; a row the session's
|
|
666
784
|
`PI_DISABLED_EXTENSIONS` excludes reads `env disabled`, so the two axes cannot
|
|
667
|
-
contradict each other.
|
|
668
|
-
nothing to report — a clean report or none at all — leaves the glyph column
|
|
785
|
+
contradict each other. A row with nothing to report leaves the glyph column
|
|
669
786
|
blank and says `ok` in words when a report exists.
|
|
670
787
|
- Toggles the focused extension with `Space`, writing `+pattern` / `-pattern`
|
|
671
|
-
into `extensions` (and package filter objects) in the
|
|
788
|
+
into `extensions` (and package filter objects) in the write scope. A row in
|
|
672
789
|
the trailing `Not resolved` group has no pattern to write, so `Space` says so
|
|
673
790
|
instead of doing nothing.
|
|
674
791
|
- Clears the focused extension's project override with `x` in Project scope: the
|
|
@@ -677,30 +794,37 @@ installs or fetches a package.
|
|
|
677
794
|
created), and the row returns to its inherited state. A row with no override
|
|
678
795
|
says so instead of writing, and Global scope does not offer the key — the
|
|
679
796
|
personal file is the base layer.
|
|
680
|
-
- Switches the write scope with `Tab`: **Global** (personal `settings.json`) or
|
|
681
|
-
**Project** (`.pi/settings.json`, only when the project is trusted; an
|
|
682
|
-
untrusted project refuses with a notice).
|
|
683
797
|
- Expands or collapses the focused extension's findings with `Enter` — per row,
|
|
684
|
-
so another row stays as it was — and
|
|
685
|
-
height while
|
|
686
|
-
|
|
798
|
+
so another row stays as it was — and gives the block the screen's whole body
|
|
799
|
+
height while it is open, so its findings are not clipped to three rows.
|
|
800
|
+
- Re-probes with `r`; while a probe is in flight the hint shows `refreshing…` and
|
|
801
|
+
a second `r` is ignored, so probes cannot stack.
|
|
687
802
|
- Checks an `<extension>` name against the discovered set before probing, so a
|
|
688
803
|
typo fails immediately instead of waiting for every prerequisite check.
|
|
689
|
-
-
|
|
690
|
-
|
|
804
|
+
- Reloads with `R`, so a new selection takes effect without leaving the session.
|
|
805
|
+
|
|
806
|
+
**Filters.** `/` opens an editor seeded with the current query. The query applies
|
|
807
|
+
as it is typed — a filter that only took effect on `Enter` would make the reader
|
|
808
|
+
wait to see it work — and matches a row's name, path, and source (Settings: its
|
|
809
|
+
label, description, and value). `Esc` clears it rather than leaving a hidden
|
|
810
|
+
narrowing behind. `!` keeps only the rows worth acting on: a resource row that
|
|
811
|
+
needs attention, or on Settings a value that differs from its default. The chips
|
|
812
|
+
on the tab row say which is on, and an emptied section says
|
|
813
|
+
`Nothing matches the filter.`
|
|
691
814
|
|
|
692
815
|
**Skills.** The second section is the same list over Pi's skills: one row per
|
|
693
816
|
skill, grouped by source and sorted by name, labelled with the name its
|
|
694
817
|
`SKILL.md` declares (or the folder name when it declares none). `Space` writes
|
|
695
818
|
`+pattern` / `-pattern` into `skills` — or a package's `skills` filter — in the
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
`not loaded` with Pi's reason when the file was refused. The
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
819
|
+
write scope, and `x` behaves as it does for extensions. A row's verdict comes
|
|
820
|
+
from the skill's own file: `off` when it is disabled, `hidden` when frontmatter
|
|
821
|
+
sets `disable-model-invocation` so only `/skill:<name>` loads it, and
|
|
822
|
+
`not loaded` with Pi's reason when the file was refused. The block carries
|
|
823
|
+
`Path`, `Call` (`/skill:<name>`), `Model` when the skill is hidden from the
|
|
824
|
+
model, `Problem` when Pi refused the file, and the declared description — one
|
|
825
|
+
line until `Enter` expands it. There is nothing to probe, so `r` is not offered
|
|
826
|
+
here; the metadata is read once when the section first appears, so an edited
|
|
827
|
+
`SKILL.md` shows on the next open.
|
|
704
828
|
|
|
705
829
|
Themes and prompts have no section of their own, by decision rather than by
|
|
706
830
|
omission: a theme is one active selection — a scalar, global setting — and a
|
|
@@ -708,53 +832,40 @@ prompt template is a file Pi discovers from a directory, so neither is a scoped
|
|
|
708
832
|
enable list this screen's checkbox rows can write. Themes stay with `pi config`;
|
|
709
833
|
`ROADMAP.md` carries the reason under *Deliberately left thin*.
|
|
710
834
|
|
|
711
|
-
**Settings.** The third section
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
|
745
|
-
|---|---|---|
|
|
746
|
-
| Bytefly startup TUI | Pi `settings.json` (`quietStartup`) | Off, On |
|
|
747
|
-
| Theme | Pi `settings.json` (`theme`) | `system`, `bytefly-dark`, `bytefly-light` |
|
|
748
|
-
| Desktop notifications | `notify.enabled` | Off, On |
|
|
749
|
-
| Turn finished | `notify.turnFinished` | Off, On |
|
|
750
|
-
| Needs input | `notify.needsInput` | Off, On |
|
|
751
|
-
| Job finished | `notify.jobFinished` | Off, On |
|
|
752
|
-
| Watcher matched | `notify.matchFound` | Off, On |
|
|
753
|
-
| Wake when a job finishes | `job.wakeOnFinish` | Off, On |
|
|
754
|
-
| Automatic snapshots | `rewind.autoSnapshots` | Off, On |
|
|
755
|
-
| Proactive health check | `doctor.proactive` | Off, On |
|
|
756
|
-
| Currency | `price.currency.code` | CNY, USD |
|
|
757
|
-
| Session budget | `price.budget` | Number, `0` = off |
|
|
835
|
+
**Settings.** The third section is the same frame over the curated preferences,
|
|
836
|
+
grouped by what they do rather than by which file holds them: `Startup (2)`,
|
|
837
|
+
`Notifications (5)`, `Session (3)`, and `Price (2)`. It is the shortlist a
|
|
838
|
+
session changes: twelve preferences, each with its value in one aligned column
|
|
839
|
+
instead of beside its label, so a column of values can be read down. Sixteen
|
|
840
|
+
entries — twelve rows and their four headings — fit a 24-row terminal when the
|
|
841
|
+
block sits beside the list; on a narrower one the list scrolls and the block
|
|
842
|
+
keeps its three rows. The frame never grows past the tallest section, however
|
|
843
|
+
tall the terminal is. In Project scope the two app rows drop out and the note
|
|
844
|
+
`App settings are Global only.` stands above the list.
|
|
845
|
+
|
|
846
|
+
The block carries `Now` with the value, `About` with the preference's own
|
|
847
|
+
description, and `Stored in <origin> · <file>` — `Global`, `Project`,
|
|
848
|
+
`Inherited from Global`, or `Default`, with the file that supplied the value
|
|
849
|
+
(`~/.pi/agent/settings.json` for an app row, the active scope's `bytefly.json`
|
|
850
|
+
otherwise). `J` on a `bytefly.json` row appends that section as the active scope
|
|
851
|
+
stores it, under a `── notify ──` rule.
|
|
852
|
+
|
|
853
|
+
<img src="../../assets/screens/bytefly-settings.png" alt="The /bytefly Settings section at 120 columns: the `Startup (2)`, `Notifications (5)`, `Session (3)`, and `Price (2)` groups with each value in one aligned column, the `Extensions 9 · Skills 0 · Settings 12` tabs with `writes Global` at the right, and the focused row's block beside the list — its value, description, and the file the value is stored in" width="100%">
|
|
854
|
+
|
|
855
|
+
| Group | Row | Source | Values |
|
|
856
|
+
|---|---|---|---|
|
|
857
|
+
| Startup | Startup screen | Pi `settings.json` (`quietStartup`) | Off, On |
|
|
858
|
+
| Startup | Theme | Pi `settings.json` (`theme`) | `system`, `bytefly-dark`, `bytefly-light` |
|
|
859
|
+
| Notifications | Desktop notifications | `notify.enabled` | Off, On |
|
|
860
|
+
| Notifications | When a turn ends | `notify.turnFinished` | Off, On |
|
|
861
|
+
| Notifications | When the agent needs you | `notify.needsInput` | Off, On |
|
|
862
|
+
| Notifications | When a job ends | `notify.jobFinished` | Off, On |
|
|
863
|
+
| Notifications | When a watcher matches | `notify.matchFound` | Off, On |
|
|
864
|
+
| Session | Resume after a job | `job.wakeOnFinish` | Off, On |
|
|
865
|
+
| Session | Snapshot before a turn | `rewind.autoSnapshots` | Off, On |
|
|
866
|
+
| Session | Health check at startup | `doctor.proactive` | Off, On |
|
|
867
|
+
| Price | Currency | `price.currency.code` | `CNY (¥)`, `USD ($)` |
|
|
868
|
+
| Price | Session budget | `price.budget` | `Off`, or the amount as `¥5.00` |
|
|
758
869
|
|
|
759
870
|
Choosing **Currency** also writes that currency's default precision
|
|
760
871
|
(`price.currency.decimals`). Both stay editable in `bytefly.json` afterwards, so
|
|
@@ -771,20 +882,16 @@ and is replaced by the next choice here, so manage those in Pi's `/settings` →
|
|
|
771
882
|
|
|
772
883
|
`Space` (or `Enter`) changes the focused row: a boolean toggles, an enum cycles
|
|
773
884
|
forward, and the one text row — **Session budget** — opens an inline editor on its
|
|
774
|
-
amount. `u` deletes the focused row's key so its default applies again (
|
|
775
|
-
at its default.` when nothing is stored in that scope; an inherited
|
|
776
|
-
says so instead
|
|
777
|
-
section as the active scope stores it — the
|
|
778
|
-
leaves to JSON.
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
`Default · <the active scope's file>`; an app row names the personal
|
|
782
|
-
`settings.json`. A successful change marks the screen `Saved · reload to apply`
|
|
783
|
-
— even when the terminal is too short for the detail body — and closing offers
|
|
784
|
-
the same reload confirm as an extension or skill toggle.
|
|
885
|
+
amount. `u` deletes the focused row's key so its default applies again (`<row>
|
|
886
|
+
is already at its default.` when nothing is stored in that scope; an inherited
|
|
887
|
+
Project value says so instead, and an app row answers that Pi has no unset), and
|
|
888
|
+
`J` appends the focused row's whole section as the active scope stores it — the
|
|
889
|
+
only view of the keys this screen leaves to JSON. A successful change marks the
|
|
890
|
+
block `Saved · reload to apply` and puts `unsaved changes` in the header, and
|
|
891
|
+
closing offers the same reload confirm as an extension or skill toggle.
|
|
785
892
|
|
|
786
893
|
The list is capped at twelve rows so the screen keeps fitting a 24-row
|
|
787
|
-
terminal: adding a setting means removing one (`panel/
|
|
894
|
+
terminal: adding a setting means removing one (`panel/settings.test.ts` holds the
|
|
788
895
|
ceiling). Everything else stays in `bytefly.json` — the tuning numbers, the
|
|
789
896
|
cosmetic labels, and the Pi preferences Pi's own `/settings` owns — and
|
|
790
897
|
`test/settings-coverage.test.ts` keeps the split honest: every loader key is
|
|
@@ -800,11 +907,11 @@ screen cannot import their normalizers, so it reports the leaf as
|
|
|
800
907
|
the file states it and declares the loader's default; the same test holds the
|
|
801
908
|
catalogue to every loader's defaults and bounds in both directions.
|
|
802
909
|
|
|
803
|
-
**
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
910
|
+
**Startup screen** is the one row whose label differs from the Pi key it writes:
|
|
911
|
+
On writes `"quietStartup": true` (bytefly's header replaces Pi's startup detail),
|
|
912
|
+
and Off writes `false` (Pi's built-in header stays). A hand-set `"header"` reads
|
|
913
|
+
Off, because it keeps Pi's header; the next toggle replaces it with `true` or
|
|
914
|
+
`false`.
|
|
808
915
|
|
|
809
916
|
App rows are **Global only**: Pi's setters for them write the personal
|
|
810
917
|
`settings.json`, and only resource paths have public project setters. Project
|
|
@@ -821,18 +928,18 @@ screen order:
|
|
|
821
928
|
|
|
822
929
|
```
|
|
823
930
|
bytefly: Settings · Global · 12 settings
|
|
824
|
-
|
|
931
|
+
Startup screen: Off
|
|
825
932
|
Theme: bytefly-dark
|
|
826
933
|
Desktop notifications: On
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
934
|
+
When a turn ends: On
|
|
935
|
+
When the agent needs you: On
|
|
936
|
+
When a job ends: On
|
|
937
|
+
When a watcher matches: On
|
|
938
|
+
Resume after a job: On
|
|
939
|
+
Snapshot before a turn: On
|
|
940
|
+
Health check at startup: On
|
|
834
941
|
Currency: CNY (¥)
|
|
835
|
-
Session budget: 5
|
|
942
|
+
Session budget: ¥5.00
|
|
836
943
|
```
|
|
837
944
|
|
|
838
945
|
The doctor side probes every declared extension and reports each check as `ok`,
|
|
@@ -865,27 +972,38 @@ headline; a named extension prints its full findings instead.
|
|
|
865
972
|
|
|
866
973
|
### Keys
|
|
867
974
|
|
|
975
|
+
One table in [`panel/tui/keys.ts`](../../extensions/bytefly/panel/tui/keys.ts)
|
|
976
|
+
drives the bindings, the hint row, and the `?` key list, so a key cannot drift
|
|
977
|
+
from its hint or its help line. The hint row is per section and drops whole hints
|
|
978
|
+
from the right as the width runs out, so `Esc` and the section keys survive on a
|
|
979
|
+
narrow terminal; the Settings section's row is the shorter one.
|
|
980
|
+
|
|
868
981
|
| Key | Effect |
|
|
869
982
|
|---|---|
|
|
870
|
-
|
|
|
871
|
-
| `
|
|
872
|
-
| `
|
|
873
|
-
| `
|
|
983
|
+
| `Esc` (`Ctrl+C`) | Close the screen. |
|
|
984
|
+
| `←` / `→`, `h` / `l`, `Tab` / `Shift+Tab` | Previous or next section — Extensions, Skills, Settings — wrapping at the ends. |
|
|
985
|
+
| `↑` / `↓`, `j` / `k` | Move to the previous or next row. |
|
|
986
|
+
| `PgUp` / `PgDn` | Move a page. |
|
|
987
|
+
| `Home` / `End`, `g` / `G` | Jump to the first or last row. |
|
|
988
|
+
| `[` / `]` | Jump to the previous or next group; a group heading is never the focus. |
|
|
989
|
+
| `Space` | Toggle the focused extension or skill; change the focused value (Settings). |
|
|
990
|
+
| `Enter` | Expand or collapse the focused row's findings, or a skill's description; change the focused value, or open the editor on a text row (Settings). |
|
|
991
|
+
| `/` | Filter the rows by text; the query applies as it is typed and `Esc` clears it. |
|
|
992
|
+
| `!` | Show only the rows that need attention; on Settings, only values changed from their default. |
|
|
993
|
+
| `s` | Switch where a change is written: Global or Project. |
|
|
994
|
+
| `x` | Drop the focused resource's Project override, so Global applies again (Extensions and Skills, Project scope only). |
|
|
995
|
+
| `r` | Re-probe every extension's requirements (Extensions only); a second `r` while one is in flight is ignored. |
|
|
996
|
+
| `R` | Reload now, to apply what you changed; with nothing pending it says so instead. |
|
|
874
997
|
| `u` | Delete the focused setting's key so its default applies again (Settings, `bytefly.json` rows). |
|
|
875
|
-
| `J` | Show or hide the focused row's whole section as stored (Settings
|
|
876
|
-
|
|
|
877
|
-
| `←` / `→`, `Home` / `End` (`Ctrl+A` / `Ctrl+E`) | Move the editor's caret while a text row is being edited. |
|
|
998
|
+
| `J` | Show or hide the focused row's whole `bytefly.json` section as stored (Settings). |
|
|
999
|
+
| `?` | Show the key list in the focused row's block; `?` again hides it. |
|
|
1000
|
+
| `←` / `→`, `Home` / `End` (`Ctrl+A` / `Ctrl+E`) | Move the editor's caret while a text row or the filter is being edited. |
|
|
878
1001
|
| `Backspace` / `Delete`, `Ctrl+U` | Edit the buffer: delete a character, or clear it. |
|
|
879
1002
|
| `Enter` / `Esc` (editing) | Save the buffer, or cancel and restore the stored value. |
|
|
880
|
-
| `Tab` | Switch between Global and Project scope, in any section. |
|
|
881
|
-
| `r` | Re-probe the doctor (Extensions). |
|
|
882
|
-
| `↑`/`↓`, `j`/`k` | Move the selection, in any section. |
|
|
883
|
-
| `PgUp`/`PgDn` | Move a page, in any section. |
|
|
884
|
-
| `g` / `G`, `Home` / `End` | Jump to the first or last row, in any section. |
|
|
885
|
-
| `Esc` / `Ctrl+C` | Close the screen. |
|
|
886
1003
|
|
|
887
|
-
|
|
888
|
-
|
|
1004
|
+
`Esc` clears an open filter or editor before it closes the screen, so nothing
|
|
1005
|
+
typed is left narrowing the list or half-written. Mouse wheel scrolling and
|
|
1006
|
+
clicking a row to focus it work; every action also has a keyboard path.
|
|
889
1007
|
|
|
890
1008
|
### What is checked
|
|
891
1009
|
|
|
@@ -1059,12 +1177,12 @@ why the line says so, and each source the manager reports is shown while it runs
|
|
|
1059
1177
|
|
|
1060
1178
|
## Limitations
|
|
1061
1179
|
|
|
1062
|
-
- **
|
|
1180
|
+
- **The Startup screen row is the startup surface only.** It installs or removes
|
|
1063
1181
|
bytefly's startup header and the proactive doctor notice; the footer, turn
|
|
1064
1182
|
rule, and transcript renderers stay on. Use `PI_DISABLED_EXTENSIONS=bytefly`
|
|
1065
1183
|
(or `pi config`) to turn off all of bytefly.
|
|
1066
1184
|
- **App settings are Global only.** Pi's setters for the two app preferences
|
|
1067
|
-
the screen carries — `quietStartup` (the **
|
|
1185
|
+
the screen carries — `quietStartup` (the **Startup screen** row) and
|
|
1068
1186
|
`theme` — write the personal `settings.json`; the screen hides those rows in
|
|
1069
1187
|
Project scope rather than writing a file Pi cannot manage.
|
|
1070
1188
|
- **The Theme row offers only this package's palettes.** `system`,
|
|
@@ -1139,10 +1257,11 @@ why the line says so, and each source the manager reports is shown while it runs
|
|
|
1139
1257
|
Anthropic's 2× one-hour cache write are not modelled; switch to `USD` mode
|
|
1140
1258
|
to use Pi's recorded cost for those models.
|
|
1141
1259
|
- **No FX conversion.** The two modes are separate methods; neither converts
|
|
1142
|
-
one currency into the other. A model is priced only by the selected method
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1260
|
+
one currency into the other. A model is priced only by the selected method, and
|
|
1261
|
+
a model neither method can price is named — by key, in the footer, in
|
|
1262
|
+
`/bytefly prices`, and in one notice — instead of being quietly left out. What
|
|
1263
|
+
is *not* built is a table for another provider: rates are sourced data, and
|
|
1264
|
+
`price.rates` is where they go.
|
|
1146
1265
|
- **Two built-in footer indicators cannot be reproduced.** Pi's `(auto)` marks
|
|
1147
1266
|
that auto-compaction is on, and its `(sub)` marks a subscription-backed
|
|
1148
1267
|
provider. Auto-compaction is session state on Pi's own session object, and
|
|
@@ -1218,7 +1337,7 @@ rather than showing a wrong value.
|
|
|
1218
1337
|
|
|
1219
1338
|
| Integration point | Details |
|
|
1220
1339
|
|---|---|
|
|
1221
|
-
| Header | `ctx.ui.setHeader` with a custom component, replacing Pi's built-in header; installed only when `ctx.mode === "tui"` and `pi.getSettings().quietStartup === true` (the **
|
|
1340
|
+
| Header | `ctx.ui.setHeader` with a custom component, replacing Pi's built-in header; installed only when `ctx.mode === "tui"` and `pi.getSettings().quietStartup === true` (the **Startup screen** row). `false`, `"header"`, and unset call `setHeader(undefined)`, leaving Pi's built-in header in place. The nameplate insets by Pi's `outputPad` (read through `pi.getSettings()`), so it sits on the transcript margin, and the help hangs one body indent inside it. The mark and text are drawn from the active theme's tokens, the help keys resolve live through `keyText`, and the mark falls back to a wordmark on Apple Terminal (`isAppleTerminalSession`), mirroring Pi's built-in. The factory reads `tui.terminal.rows` on every render, so the height ladder in `header/config.ts` sheds help groups and then the leading blank row as the terminal shortens (unknown height keeps the full header). The chrome version gains `↑<latest>` from the `UpdateSource`, the agent line gains Pi's own `↑<latest>` from the second store, and `registerHeader` returns a `refresh()` handle that re-installs the last context's header when either value arrives. |
|
|
1222
1341
|
| Footer | `ctx.ui.setFooter` with a custom component, replacing Pi's built-in footer; installed only when `ctx.mode === "tui"`. |
|
|
1223
1342
|
| User message | `pi.registerMarkdownTransformer` puts a two-row `You` nameplate (the label over a full-width rule) above each user message; one padded level-2 heading carries the accent through `mdHeading` for both rows, and the shipped themes set `userMessageBg` to the terminal default, so the block has no fill. Pi renders the result as Markdown, so the surface adds no component or color of its own. |
|
|
1224
1343
|
| Notice | `registerMessageRenderer(NOTICE_TYPE)` draws every shared transcript notice at the margin from its `details`; the headline stays at the margin with its title painted by the notice's own severity, and its rows hang from the transcript rail, painted by the notice's worst severity, whose glyph comes from the shared `RailSource`. `job` and `watch` post one when their work settles, and `doctor` posts one at `session_start` for a missing hard requirement. The type and shape come from `lib/notice.ts`. A message without `details` falls back to Pi's default custom-message box. |
|
|
@@ -1318,9 +1437,9 @@ rather than showing a wrong value.
|
|
|
1318
1437
|
entry renderer none and adds its component raw, so bytefly's blocks inset
|
|
1319
1438
|
themselves by that pad: the tool frame and the notice take it from Pi, and the
|
|
1320
1439
|
turn separator reads the last value a sibling observed (`pad.ts`). Pi's setting
|
|
1321
|
-
is the only knob — bytefly adds no padding of its own. The footer
|
|
1322
|
-
|
|
1323
|
-
a transcript-only glyph.
|
|
1440
|
+
is the only knob — bytefly adds no padding of its own. The footer draws no
|
|
1441
|
+
rule of its own: it joins its chips with the shared ` · `, and the rail (`╎`)
|
|
1442
|
+
stays a transcript-only glyph.
|
|
1324
1443
|
- **The header is a nameplate, not a dashboard.** Pi's built-in brand colors are
|
|
1325
1444
|
fixed, so the mark ignores the active theme; bytefly's header draws a two-tone
|
|
1326
1445
|
mark from the `accent`/`warn` roles, a signature rule whose accent lead sits
|
|
@@ -1332,24 +1451,40 @@ rather than showing a wrong value.
|
|
|
1332
1451
|
terminal: the height ladder drops whole help groups, then the leading blank
|
|
1333
1452
|
row, before the nameplate gives up anything, so a short pane spends its rows
|
|
1334
1453
|
on the transcript instead of chrome.
|
|
1335
|
-
- **Two lines,
|
|
1336
|
-
|
|
1337
|
-
|
|
1454
|
+
- **Two lines, one job each: state and meters.** Line 1 is state (`pwd` and the
|
|
1455
|
+
session name left; the alert, the modes, then `⎇` branch, `⑂` worktree and the
|
|
1456
|
+
ports right); line 2 is meters (the gauge and usage left; model and level
|
|
1457
|
+
right). The state chips change while a session runs, so they ride the line that
|
|
1458
|
+
has slack: the meters are the dense row, and a fact that moves to the top row is
|
|
1459
|
+
one the bottom row stops dropping to fit. It keeps "where am I / what state"
|
|
1460
|
+
separate from "how much am I burning".
|
|
1338
1461
|
- **Child spend is a second figure.** The footer never adds a subagent's tokens to
|
|
1339
1462
|
the session's; it prices the `my-pi-agent/subagent-finished` events with the
|
|
1340
1463
|
same pricer and renders them as `↳`, so "this session" keeps meaning the
|
|
1341
1464
|
dispatching process and the delegated work stays visible beside it.
|
|
1342
|
-
- **The gauge is anchored at column 0
|
|
1343
|
-
context percentage left and right as plan mode came
|
|
1344
|
-
|
|
1345
|
-
|
|
1465
|
+
- **The gauge is anchored at column 0, and nothing can displace it.** A leading
|
|
1466
|
+
mode slot used to push the context percentage left and right as plan mode came
|
|
1467
|
+
and went, which is why the mode chip trailed the meters after a `│`; moving the
|
|
1468
|
+
mode slot to the state line leaves the gauge as the resource line's first
|
|
1469
|
+
segment, so the percentage cannot move at all.
|
|
1346
1470
|
- **Statuses are routed, not repeated.** The built-in footer renders every
|
|
1347
1471
|
`setStatus` value on its own line, so the bar sorts them by meaning instead:
|
|
1348
|
-
`worktree`
|
|
1349
|
-
branch and `⑂` worktree and the
|
|
1350
|
-
|
|
1351
|
-
|
|
1472
|
+
`worktree` is location, so the `◉ <port>` chip sits behind `⎇`
|
|
1473
|
+
branch and `⑂` worktree, and it is the session's one page port, so it keeps a
|
|
1474
|
+
weight and a floor of its own; a plan is a mode, so it leads the state line
|
|
1475
|
+
beside them; a failed job is an alert, so it is its own segment ahead of both. The
|
|
1476
|
+
[wechat](./wechat.md) extension publishes `✆ wechat` while its bridge runs,
|
|
1352
1477
|
which is why the bar has to render `getExtensionStatuses()` at all.
|
|
1478
|
+
- **A state chip leads its zone, so the zone does not move under it.** The right
|
|
1479
|
+
zone is right-aligned: a chip appended to it would push the branch and the
|
|
1480
|
+
worktree label left every time a mode came and went, while a chip prepended to
|
|
1481
|
+
it grows into the empty columns. That is the same stability argument the gauge
|
|
1482
|
+
gets from sitting at column 0, applied to the row that changes.
|
|
1483
|
+
- **A failure is never the thing that drops.** The alert segment is the one
|
|
1484
|
+
non-droppable chip: every other fact can be read again — the branch from git,
|
|
1485
|
+
the mode from the session, the spend from `/bytefly prices` — while a failed
|
|
1486
|
+
job that scrolled off the bar is a failure nobody is looking at. It keeps its
|
|
1487
|
+
count (`✗1`) when it compacts.
|
|
1353
1488
|
- **Segments degrade; they do not clip.** Each `Segment` carries progressively
|
|
1354
1489
|
shorter `forms` and a `weight`; the layout advances the lowest-priority form
|
|
1355
1490
|
or drops the lowest-priority segment, and only truncates once everything is
|
|
@@ -1359,15 +1494,23 @@ rather than showing a wrong value.
|
|
|
1359
1494
|
non-zero usage, so it reads full only at 100% and a small percentage never
|
|
1360
1495
|
disappears; unknown usage draws no gauge at all. Only at extreme widths does
|
|
1361
1496
|
`truncateToWidth` clip the remaining text.
|
|
1362
|
-
- **Separators shrink to a single space.**
|
|
1363
|
-
|
|
1364
|
-
never collide and the ellipsis never replaces a
|
|
1497
|
+
- **Separators shrink to a single space.** Every segment is joined by the same
|
|
1498
|
+
padded ` · `, which collapses to one space before `truncateToWidth` applies, so
|
|
1499
|
+
adjacent segments never collide and the ellipsis never replaces a separator
|
|
1500
|
+
with nothing after it.
|
|
1365
1501
|
- **Statuses compact with their colour.** A themed status's compact icon form
|
|
1366
1502
|
reattaches its opening and closing SGR sequences around the visible text, so a
|
|
1367
1503
|
red `✗1` stays red instead of losing its colour exactly when the bar tightens.
|
|
1368
1504
|
A two-token `icon count` badge (for `rewind`: `↺ 2`) compacts to `↺2`, keeping
|
|
1369
|
-
the count.
|
|
1370
|
-
|
|
1505
|
+
the count. A mode is droppable, so it goes before the branch and long before
|
|
1506
|
+
the model is clipped; only an alert is not.
|
|
1507
|
+
- **A budget is a position, not a second figure.** With `price.budget` set, the
|
|
1508
|
+
cost segment reads `$0.31/$5` and turns `warn` once the spend reaches the
|
|
1509
|
+
ceiling, which is the same `budgetState` condition the notice fires on, so the
|
|
1510
|
+
bar cannot call a session over budget that the notice has not. The ceiling is
|
|
1511
|
+
formatted by its own `formatLimit` — the number the user typed, with trailing
|
|
1512
|
+
zeros dropped — while the spend keeps the currency's precision; both the bar
|
|
1513
|
+
and the notice use it, so the two cannot disagree about one figure.
|
|
1371
1514
|
- **Neutral by default; color means something.** A tool block carries no status
|
|
1372
1515
|
colour except the accent tool name and the status-coloured result rail; an
|
|
1373
1516
|
informational notice leads with `muted`; a failure is red only where the
|
|
@@ -1510,8 +1653,10 @@ columns, gauge), so the look follows the active theme.
|
|
|
1510
1653
|
| `header/identity.ts` | `IdentityInput` and `identityCells`: the agent and chrome cells, each with its `↑` marker, in the ladder that sheds the chrome marker, the chrome version, the chrome line, and finally the agent's marker with the row. |
|
|
1511
1654
|
| `header/register.ts` | Installs/restores the header and owns its session lifecycle. |
|
|
1512
1655
|
| `footer/register.ts` | Installs/restores the footer and owns its session lifecycle. |
|
|
1513
|
-
| `footer/config.ts` | Bar tuning (`CONFIG`): thresholds, gauge, separators, icons, status keys, labels. |
|
|
1656
|
+
| `footer/config.ts` | Bar tuning (`CONFIG`): thresholds, gauge, separators, icons, alert and plan status keys, labels. |
|
|
1514
1657
|
| `footer/types.ts` | `StatusSnapshot`, `Segment`, `LineSpec`, `UsageRecord`, and footer/TUI shapes. |
|
|
1658
|
+
| `footer/budget.ts` | The session spend guardrail: whether the configured ceiling has been crossed and the one notice that says so — an alert, never a limit. |
|
|
1659
|
+
| `footer/delegation.ts` | The child-run ledger: the pricing inputs of the last delegated runs, versioned so the footer re-prices when a subagent finishes. |
|
|
1515
1660
|
| `footer/collect/entries.ts` | Session entries → usage records, each resolved to the model in effect. |
|
|
1516
1661
|
| `footer/collect/snapshot.ts` | Snapshot assembly; memoized pricing scan, context estimate, and session name per branch leaf. |
|
|
1517
1662
|
| `footer/price/types.ts` | `Currency`, `ModelRates`, `PeakWindow`/`PeakSchedule`, `ByteflyConfig`. |
|
|
@@ -1519,13 +1664,14 @@ columns, gauge), so the look follows the active theme.
|
|
|
1519
1664
|
| `footer/price/rates.ts` | Model-key matching: `createRateLookup` splits every key once, splits a key at its first slash (so an OpenRouter model id may contain one), matches exact and wildcard most-specific-first, and remembers the last record's model. |
|
|
1520
1665
|
| `footer/price/schedule.ts` | Peak-window parsing and evaluation in a configured zone. |
|
|
1521
1666
|
| `footer/price/price.ts` | Records → totals: rated cost in both modes, Pi's recorded cost as USD's fallback, the peak multiplier, and the count of records CNY could not rate. |
|
|
1522
|
-
| `footer/unpriced.ts` | The one notice a
|
|
1667
|
+
| `footer/unpriced.ts` | The one notice a session posts for records nothing could price: the models by key, the count that the two agree on (`recordsText`), and its OS-notification body. |
|
|
1523
1668
|
| `footer/render/format.ts` | Generic formatters (tokens, cost in the configured currency, cwd, the context role, truncation). |
|
|
1524
1669
|
| `footer/render/status.ts` | Status-chip transforms: `compactStatus` and `dropStatusDetail`. |
|
|
1525
1670
|
| `footer/render/segments.ts` | The segment builders: forms, weights, separators, roles. |
|
|
1526
1671
|
| `footer/render/lines.ts` | Snapshot → two `LineSpec`s; status routing. |
|
|
1527
1672
|
| `footer/render/layout.ts` | Width reduction and right-zone folding. |
|
|
1528
1673
|
| `footer/render/footer.ts` | `StatusBar` component and footer factory. |
|
|
1674
|
+
| `footer/render/key.ts` | `snapshotKey`: the bar's repaint key, derived from the snapshot's own shape — sorted object keys, a map as sorted entries, a primitive by value — so a field added to `StatusSnapshot` is in the key the day it is added. |
|
|
1529
1675
|
| `message/config.ts` | Nameplate tuning (`MESSAGE_CONFIG`): the label and the rule. |
|
|
1530
1676
|
| `message/format.ts` | Pure `nameplate` and `styleUserMessage`: the two-row nameplate (label over a full-width rule) and its placement above the message. |
|
|
1531
1677
|
| `message/register.ts` | Registers the Markdown transformer (the nameplate). |
|
|
@@ -1545,21 +1691,25 @@ columns, gauge), so the look follows the active theme.
|
|
|
1545
1691
|
| `working/format.ts` | Pure `formatElapsed` (whole seconds) and the working-message shape: the plain count and the `tool · N tools · elapsed` run line. |
|
|
1546
1692
|
| `working/register.ts` | Starts the tick on `turn_start`, tracks top-level tools on `tool_execution_start`, and cancels on `agent_end`/`session_shutdown`. |
|
|
1547
1693
|
| `panel/types.ts` | `PanelSection` (`extensions` \| `skills` \| `settings`), `PanelRow` with its optional skill info, `SkillInfo`, and `PanelModel`, the merged row model. |
|
|
1548
|
-
| `panel/join.ts` | The item/report union with the unambiguous-name
|
|
1549
|
-
| `panel/
|
|
1550
|
-
| `panel/
|
|
1694
|
+
| `panel/join.ts` | The item/report union with the unambiguous-name naming rule — a row is `worktree`, and a directory claims a report only when one resource uses that name — plus unique row keys, groups, ordering, and the skills model that labels rows from `SKILL.md`. |
|
|
1695
|
+
| `panel/filter.ts` | The two filters as predicates and chips: a text query over a row's name, path, and source, the attention switch, and what the tab row says is on. |
|
|
1696
|
+
| `panel/format.ts` | Non-TUI text: the resource headline and grouped listing with a per-row verdict, the header's attention segments, the one `rowBadge` the screen and the listing share, the section segments and their order, the Settings counts/headline, and the flat Settings listing. |
|
|
1697
|
+
| `panel/settings.ts` | The curated Settings catalogue: the twelve descriptors in screen order, their four groups, the value labels (`Off`, `¥5.00`) and display origins, value cycling, stored-value mapping, validation, plus the per-section readers that resolve a row's leaf over the global and project documents. |
|
|
1551
1698
|
| `panel/settings-runtime.ts` | The Settings runtime: snapshot cache, scope guards, app setters, per-leaf `bytefly.json` writes, dirty state, and change listeners. |
|
|
1552
1699
|
| `panel/themes.ts` | Which themes the Theme row offers: the host's resolved list narrowed to the palettes under this package's `themes/`, identified by directory rather than name. |
|
|
1700
|
+
| `panel/prices.ts` | The `/bytefly prices` report: the unpriced models by key, the records behind each, and the one line saying where the keys go. It quotes no price — a rate is the user's to state. |
|
|
1553
1701
|
| `panel/skills.ts` | Skill metadata through Pi's own `loadSkills`, keyed by resolved path, plus the deduplicated paths both discovery views read. |
|
|
1554
|
-
| `panel/tui.ts` | `PanelComponent
|
|
1555
|
-
| `panel/tui/
|
|
1556
|
-
| `panel/tui/
|
|
1557
|
-
| `panel/tui/
|
|
1558
|
-
| `panel/tui/
|
|
1702
|
+
| `panel/tui.ts` | `PanelComponent`: the section switch, the three cursors and focus keys, the filter and help state, the toggle chain, and the one render that hands the frame its header, tabs, rows, and block. |
|
|
1703
|
+
| `panel/tui/keys.ts` | The one key table: each binding with the sections that offer it, the hint row they produce, and the `?` help block, so a key cannot drift from its hint or its help line. |
|
|
1704
|
+
| `panel/tui/panes.ts` | The two-pane arithmetic: the 96-column breakpoint, the side-pane width, one composed row with its `╎` divider, and the clip that ends a block with `… N more lines`. |
|
|
1705
|
+
| `panel/tui/side-pane.ts` | The focused row's block in both layouts: name and verdict, findings, `Path`, `Source`, `State`, `Health`, a setting's `Now`/`About`/`Stored in`, the JSON pane, and the saved marker. |
|
|
1706
|
+
| `panel/tui/section-view.ts` | What the screen derives from the session: the tab counts, the one body height, the header's attention, the filter chips, the empty label, and the merged model for a list section. |
|
|
1707
|
+
| `panel/tui/list-view.ts` | The resource row grammar only: the checkbox, the status glyph, the name, and the verdict column. |
|
|
1708
|
+
| `panel/tui/settings-view.ts` | The settings row — checkbox, label, value in its measured column, the editing cell — and the editor's hint row. |
|
|
1559
1709
|
| `panel/tui/entries.ts` | The flat display entries per section and the stable focus keys. |
|
|
1560
1710
|
| `panel/tui/editing.ts` | The text-row editor's key map: caret moves, delete, clear, commit, cancel. |
|
|
1561
|
-
| `panel/tui/frame.ts` | The
|
|
1562
|
-
| `panel/tui/settings-section.ts` | The Settings section's editor
|
|
1711
|
+
| `panel/tui/frame.ts` | The chrome — the header rule, the tab row with its counts, chips and scope, the group heading, the hint or notice row, and the saved marker — and the height law: one body target for all three sections, the range row, and the rows a short terminal sheds. |
|
|
1712
|
+
| `panel/tui/settings-section.ts` | The Settings section's state only: the text editor, the JSON pane, the write chain, and the reset. |
|
|
1563
1713
|
| `panel/tui/nav.ts` | The panel's cursor arithmetic and one read of a navigation key. |
|
|
1564
1714
|
| `panel/commands.ts` | `/bytefly`: one command for the screen sections, the `doctor` report, the settings and skills listings, and their text modes. |
|
|
1565
1715
|
| `picker/types.ts` | Picker host seams (`SettingsStore`, `ResourceResolver`, `Discovery`, `ResourceKind`), the app-settings setters, and row types. |
|
|
@@ -1591,62 +1741,66 @@ columns, gauge), so the look follows the active theme.
|
|
|
1591
1741
|
|
|
1592
1742
|
## Testing
|
|
1593
1743
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
the
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
and its
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
and
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1744
|
+
Every suite sits beside the code it covers, so a slash-prefixed stem below
|
|
1745
|
+
resolves to `extensions/bytefly/<stem>.test.ts`.
|
|
1746
|
+
|
|
1747
|
+
`extension` covers the registration, the interactive surfaces, and the command
|
|
1748
|
+
wiring through the factory.
|
|
1749
|
+
|
|
1750
|
+
`chrome` covers the chrome that frames a session: the config and its pad store;
|
|
1751
|
+
the header's frames, width shedding, identity ladder, update marker, live theme,
|
|
1752
|
+
quiet-startup lifecycle, and terminal-height shapes; the transcript notice's rows
|
|
1753
|
+
and registration; the turn separator's formatting (including the receipt's width
|
|
1754
|
+
ladder), component, and register/append/render/disable lifecycle with the run
|
|
1755
|
+
stats it records; and the user-message nameplate's transform — through pi-tui's
|
|
1756
|
+
real `Markdown` — and its registration.
|
|
1757
|
+
|
|
1758
|
+
`footer/footer` covers the bar end to end: the price config, its schema, clamping,
|
|
1759
|
+
and defaults; rate matching, window parsing and peak evaluation in two zones, the
|
|
1760
|
+
pricing formula with its off-peak multiplier, the built-in DeepSeek table and the
|
|
1761
|
+
fallback, the usage records, and the delegation ledger; the snapshot reader and its
|
|
1762
|
+
memo, the unpriced notice, and the budget; the formatters, the status-chip
|
|
1763
|
+
transforms, the segment builders, line composition, and the repaint key that
|
|
1764
|
+
spares an unchanged frame a rebuild; the reduction, separator collapse, and
|
|
1765
|
+
right-zone folding across a width sweep from 6 to 120 plus wide characters; and the
|
|
1766
|
+
component with its install/skip/restore/toggle lifecycle and a config-driven price.
|
|
1767
|
+
|
|
1768
|
+
`block/block` covers the tool-block frame: `toolBlockLines`, the call-headline
|
|
1769
|
+
rewrites, `ToolBlock`'s memo, the generic and call fallbacks, and the resolver's
|
|
1770
|
+
shell override and self-shell carve-out.
|
|
1771
|
+
|
|
1772
|
+
`picker/picker` covers discovery with an injected factory, the resolver and its
|
|
1773
|
+
entries, the pattern helpers, and the runtime's toggling, scope, and project
|
|
1774
|
+
override across the four list operations.
|
|
1775
|
+
|
|
1776
|
+
`panel/…` covers the control centre, one suite per capability: `panel/model` (the
|
|
1777
|
+
two panes' merged model and the text formatter), `panel/filter` and its chips, the settings
|
|
1778
|
+
catalogue and its cycling (`panel/settings`), the scope-aware runtime
|
|
1779
|
+
(`panel/settings-runtime`, including a nested leaf write that keeps its siblings),
|
|
1780
|
+
the skill metadata join and loader (`panel/skills`, on real `SKILL.md` files), the
|
|
1781
|
+
key table whose hints and help it holds to one source (`panel/keys`), the frame and
|
|
1782
|
+
the one height all three sections agree on (`panel/layout`), the row grammar and the
|
|
1783
|
+
focused-row block beside and under the list (`panel/views`), the two-pane split and
|
|
1784
|
+
its `… N more lines` clip (`panel/panes`), the editing key map (`panel/editing`),
|
|
1785
|
+
the update section's view (`panel/update`), the discovery probe (`panel/probe`), the
|
|
1786
|
+
component's frames, keys, sections, settings, and probe lifecycle
|
|
1787
|
+
(`panel/component`, `panel/component-input`, `panel/component-sections`,
|
|
1788
|
+
`panel/component-settings`, `panel/component-probing`), and the command through the
|
|
1789
|
+
bytefly factory (`panel/commands`) — eighteen suites in all.
|
|
1790
|
+
|
|
1791
|
+
`doctor/doctor` covers the report counts and text, the config loader, the notify
|
|
1792
|
+
seam, the published search provider, the proactive probe, the session state,
|
|
1793
|
+
`run_doctor`, and the tool wiring.
|
|
1794
|
+
|
|
1795
|
+
`notify/notify` covers its config loader, method selection, delivery over recording
|
|
1796
|
+
seams, the text builders, and its four triggers plus the handle.
|
|
1797
|
+
|
|
1798
|
+
`update/update` covers the cache path and key, the cache read and write with its
|
|
1799
|
+
window, the check and the injected registry read, the version ordering, the
|
|
1800
|
+
formatters and the release notice, the prototype suppression with its idempotent
|
|
1801
|
+
restore, the per-load state, the lifecycle — a fresh matching entry reused without
|
|
1802
|
+
a package-manager call, a stale one re-read and rewritten, silent on failure or an
|
|
1803
|
+
empty list, cache-only offline, skipped outside `tui`, a `recheck()` that ignores
|
|
1804
|
+
the window, and a reply that lands after shutdown — and the `update` action.
|
|
1805
|
+
|
|
1806
|
+
`working/working` covers the elapsed format, the counter, and the timer registration.
|