@gavin-hu/my-pi-agent 0.14.0 → 0.15.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 +55 -33
- package/README.zh-CN.md +44 -27
- package/extensions/bytefly/README.md +193 -140
- package/extensions/bytefly/block/component.ts +7 -15
- package/extensions/bytefly/block/register.ts +6 -1
- package/extensions/bytefly/doctor/register.ts +24 -5
- package/extensions/bytefly/doctor/tools.ts +4 -0
- package/extensions/bytefly/footer/collect/snapshot.ts +6 -1
- package/extensions/bytefly/footer/config.ts +10 -6
- package/extensions/bytefly/footer/price/price.ts +5 -3
- package/extensions/bytefly/footer/price/rates.ts +63 -26
- package/extensions/bytefly/footer/render/status.ts +3 -3
- package/extensions/bytefly/header/component.ts +3 -2
- package/extensions/bytefly/index.ts +3 -3
- package/extensions/bytefly/notice/component.ts +8 -3
- package/extensions/bytefly/notify/config.ts +6 -11
- package/extensions/bytefly/notify/dispatch.ts +13 -5
- package/extensions/bytefly/panel/commands.ts +21 -1
- package/extensions/bytefly/panel/format.ts +5 -2
- package/extensions/bytefly/panel/settings-runtime.ts +26 -6
- package/extensions/bytefly/panel/settings.ts +41 -4
- package/extensions/bytefly/panel/themes.ts +32 -0
- package/extensions/bytefly/panel/tui/editing.ts +77 -0
- package/extensions/bytefly/panel/tui/entries.ts +24 -0
- package/extensions/bytefly/panel/tui/extensions-view.ts +13 -8
- package/extensions/bytefly/panel/tui/frame.ts +121 -4
- package/extensions/bytefly/panel/tui/settings-view.ts +54 -15
- package/extensions/bytefly/panel/tui.ts +94 -152
- package/extensions/bytefly/picker/discovery.ts +1 -0
- package/extensions/bytefly/picker/types.ts +2 -0
- package/extensions/bytefly/separator/component.ts +14 -4
- package/extensions/bytefly/update/cache.ts +58 -19
- package/extensions/bytefly/update/check.ts +35 -0
- package/extensions/bytefly/update/format.ts +76 -35
- package/extensions/bytefly/update/register.ts +144 -55
- package/extensions/bytefly/update/state.ts +4 -2
- package/extensions/bytefly/update/suppress.ts +66 -0
- package/extensions/bytefly/update/types.ts +15 -0
- package/extensions/check/README.md +253 -0
- package/extensions/check/commands.ts +128 -0
- package/extensions/check/config.ts +39 -0
- package/extensions/check/detect.ts +269 -0
- package/extensions/check/failures.ts +230 -0
- package/extensions/check/format.ts +135 -0
- package/extensions/check/index.ts +26 -0
- package/extensions/check/render.ts +185 -0
- package/extensions/check/runner.ts +176 -0
- package/extensions/check/runtime.ts +244 -0
- package/extensions/check/source.ts +80 -0
- package/extensions/check/tools.ts +173 -0
- package/extensions/check/tui.ts +195 -0
- package/extensions/check/types.ts +99 -0
- package/extensions/document/README.md +1 -1
- package/extensions/document/extract/pdf.ts +8 -16
- package/extensions/document/formats.ts +2 -2
- package/extensions/file-browse/README.md +66 -32
- package/extensions/file-browse/client.ts +95 -32
- package/extensions/file-browse/config.ts +9 -9
- package/extensions/file-browse/git.ts +37 -47
- package/extensions/file-browse/html.ts +39 -58
- package/extensions/file-browse/markdown.ts +110 -92
- package/extensions/file-browse/raw-html.ts +478 -0
- package/extensions/file-browse/router.ts +32 -70
- package/extensions/file-browse/server.ts +18 -56
- package/extensions/file-browse/urls.ts +80 -0
- package/extensions/goal/README.md +103 -47
- package/extensions/goal/clarify-parse.ts +4 -9
- package/extensions/goal/clarify.ts +27 -4
- package/extensions/goal/commands.ts +24 -11
- package/extensions/goal/format.ts +41 -10
- package/extensions/goal/index.ts +39 -16
- package/extensions/goal/plan-route.ts +51 -0
- package/extensions/goal/schema.ts +6 -23
- package/extensions/goal/state.ts +39 -57
- package/extensions/goal/tools.ts +26 -20
- package/extensions/goal/types.ts +11 -1
- package/extensions/job/README.md +20 -6
- package/extensions/job/format.ts +18 -68
- package/extensions/job/index.ts +26 -41
- package/extensions/job/log-writer.ts +208 -0
- package/extensions/job/logs.ts +3 -2
- package/extensions/job/process.ts +6 -99
- package/extensions/job/runtime.ts +42 -181
- package/extensions/job/schema.ts +1 -4
- package/extensions/job/tools.ts +1 -15
- package/extensions/job/tui.ts +117 -307
- package/extensions/job/ui.ts +7 -33
- package/extensions/memory/README.md +1 -1
- package/extensions/memory/errors.ts +5 -6
- package/extensions/memory/tui.ts +14 -24
- package/extensions/plan/README.md +94 -18
- package/extensions/plan/commands.ts +9 -5
- package/extensions/plan/format.ts +87 -0
- package/extensions/plan/index.ts +31 -15
- package/extensions/plan/plans.ts +2 -3
- package/extensions/plan/policy.ts +0 -6
- package/extensions/plan/runtime.ts +4 -2
- package/extensions/plan/steps.ts +37 -8
- package/extensions/plan/todos.ts +44 -3
- package/extensions/plan/tools/enter.ts +94 -0
- package/extensions/plan/tools/exit.ts +296 -0
- package/extensions/plan/tools/nested.ts +21 -0
- package/extensions/plan/tools/steps.ts +136 -0
- package/extensions/plan/tools/todo-seed.ts +76 -0
- package/extensions/plan/tools/write.ts +127 -0
- package/extensions/plan/tools.ts +18 -703
- package/extensions/plan/web-client.ts +6 -22
- package/extensions/plan/web-page.ts +19 -30
- package/extensions/plan/web-router.ts +34 -71
- package/extensions/plan/web.ts +13 -40
- package/extensions/question/answers.ts +3 -8
- package/extensions/question/tui.ts +6 -6
- package/extensions/rewind/README.md +95 -22
- package/extensions/rewind/checklist.ts +185 -0
- package/extensions/rewind/commands.ts +8 -0
- package/extensions/rewind/config.ts +3 -11
- package/extensions/rewind/format.ts +220 -2
- package/extensions/rewind/git.ts +74 -7
- package/extensions/rewind/hunk-picker.ts +114 -0
- package/extensions/rewind/patch.ts +88 -0
- package/extensions/rewind/path-picker.ts +67 -100
- package/extensions/rewind/paths.ts +93 -19
- package/extensions/rewind/restore.ts +53 -10
- package/extensions/rewind/review-tui.ts +320 -0
- package/extensions/rewind/review.ts +397 -0
- package/extensions/rewind/rewind-tui.ts +4 -3
- package/extensions/rewind/runtime.ts +94 -17
- package/extensions/subagent/README.md +61 -6
- package/extensions/subagent/background-tui.ts +208 -0
- package/extensions/subagent/background.ts +470 -0
- package/extensions/subagent/commands.ts +80 -0
- package/extensions/subagent/config.ts +4 -0
- package/extensions/subagent/format.ts +24 -1
- package/extensions/subagent/index.ts +91 -2
- package/extensions/subagent/render.ts +13 -0
- package/extensions/subagent/run.ts +17 -16
- package/extensions/subagent/schema.ts +12 -0
- package/extensions/subagent/types.ts +11 -0
- package/extensions/subagent/ui.ts +50 -0
- package/extensions/todo/README.md +18 -13
- package/extensions/todo/format.ts +3 -2
- package/extensions/todo/runtime.ts +3 -2
- package/extensions/todo/schema.ts +8 -84
- package/extensions/todo/state.ts +5 -46
- package/extensions/todo/tools.ts +2 -1
- package/extensions/todo/types.ts +6 -15
- package/extensions/watch/README.md +14 -6
- package/extensions/watch/child.ts +150 -0
- package/extensions/watch/format.ts +8 -48
- package/extensions/watch/index.ts +42 -58
- package/extensions/watch/runtime.ts +49 -128
- package/extensions/watch/schema.ts +1 -4
- package/extensions/watch/tools.ts +1 -11
- package/extensions/watch/tui.ts +103 -273
- package/extensions/watch/ui.ts +5 -32
- package/extensions/web-access/README.md +1 -1
- package/extensions/web-access/fetch/page.ts +1 -1
- package/extensions/web-access/fetch/tool.ts +6 -2
- package/extensions/web-access/search/search.ts +2 -5
- package/extensions/wechat/README.md +1 -1
- package/extensions/wechat/client.ts +23 -0
- package/extensions/wechat/commands.ts +57 -42
- package/extensions/wechat/deliver.ts +5 -9
- package/extensions/wechat/errors.ts +3 -6
- package/extensions/wechat/inbound.ts +2 -5
- package/extensions/wechat/index.ts +2 -8
- package/extensions/wechat/outbound.ts +2 -4
- package/extensions/wechat/peer-worker.ts +3 -8
- package/extensions/wechat/poll.ts +10 -9
- package/extensions/wechat/presence.ts +35 -62
- package/extensions/wechat/reply-pipeline.ts +3 -1
- package/extensions/wechat/status-screen.ts +1 -1
- package/extensions/wechat/timer.ts +57 -0
- package/extensions/worktree/config.ts +8 -20
- package/extensions/worktree/enter.ts +7 -12
- package/extensions/worktree/git.ts +38 -69
- package/extensions/worktree/index.ts +5 -4
- package/extensions/worktree/registry.ts +7 -7
- package/extensions/worktree/root-tools.ts +2 -2
- package/extensions/worktree/status.ts +3 -2
- package/lib/README.md +22 -8
- package/lib/config.ts +50 -3
- package/lib/errors.ts +12 -0
- package/lib/format.ts +50 -0
- package/lib/git/read.ts +8 -0
- package/lib/goal-state.ts +23 -8
- package/lib/http/headers.ts +54 -0
- package/lib/http/index.ts +13 -0
- package/lib/http/response.ts +46 -0
- package/lib/http/router.ts +52 -0
- package/lib/http/server.ts +91 -0
- package/lib/lines.ts +77 -0
- package/lib/pdf.ts +82 -0
- package/lib/plan-entry.ts +71 -0
- package/lib/plan-state.ts +34 -0
- package/lib/report.ts +99 -0
- package/lib/requirements.ts +25 -19
- package/lib/spawn.ts +170 -0
- package/lib/todo-state.ts +110 -23
- package/lib/tool-names.ts +7 -0
- package/lib/tool-result.ts +33 -0
- package/lib/tui/README.md +68 -3
- package/lib/tui/chrome.ts +28 -4
- package/lib/tui/columns.ts +6 -1
- package/lib/tui/confirm.ts +65 -0
- package/lib/tui/dock-screen.ts +410 -0
- package/lib/tui/glyphs.ts +2 -1
- package/lib/tui/indent.ts +1 -1
- package/lib/tui/index.ts +2 -0
- package/lib/tui/rows.ts +21 -0
- package/lib/tui/status-controller.ts +35 -1
- package/lib/tui/tool.ts +59 -1
- package/lib/web/components.ts +20 -1
- package/lib/web/markup.ts +32 -0
- package/lib/web/runtime.ts +50 -0
- package/package.json +22 -5
- package/skills/init/SKILL.md +165 -0
- package/skills/init/references/agents-md-quality.md +103 -0
- package/skills/init/references/interview-questions.md +81 -0
- package/skills/refactor/SKILL.md +141 -0
- package/extensions/watch/process.ts +0 -63
- package/extensions/web-access/fetch/pdf.ts +0 -45
|
@@ -8,8 +8,9 @@ records each completed turn in the transcript, one keyboard-driven screen with t
|
|
|
8
8
|
sections — Extensions, every resolved Pi extension with its enable checkbox and
|
|
9
9
|
its health, and Settings, the common app and `bytefly.json` preferences — and
|
|
10
10
|
an opt-in notify capability that raises an OS notification when a run finishes,
|
|
11
|
-
a job finishes, or the agent asks for input, and a
|
|
12
|
-
|
|
11
|
+
a job finishes, or the agent asks for input, and a package-update check that
|
|
12
|
+
replaces Pi's startup block with one notice and marks bytefly's own new version
|
|
13
|
+
on the header.
|
|
13
14
|
DeepSeek is priced from the provider's published yuan rates and peak tariff by
|
|
14
15
|
default; set `price.currency.code` to `USD` to price it from the provider's
|
|
15
16
|
published dollar table instead, under the same peak windows, with Pi's recorded
|
|
@@ -34,7 +35,7 @@ How the `run_doctor` call and its result look in the transcript — the call lin
|
|
|
34
35
|
The extension owns ten surfaces: the startup header, the footer, the
|
|
35
36
|
user-message marker, the rule between completed turns, the notice block for
|
|
36
37
|
shared transcript notices, the tool-block frame, the live working line, the
|
|
37
|
-
two-section control center, notifications, and the
|
|
38
|
+
two-section control center, notifications, and the package-update check.
|
|
38
39
|
|
|
39
40
|
**Header.** A nameplate: a two-tone half-block mark from the active theme's
|
|
40
41
|
`accent` / `warn` roles, the agent identity (`Pi`, bold, and its version), the
|
|
@@ -75,7 +76,7 @@ identity, and grouped help are tuned in
|
|
|
75
76
|
(`⎇ branch · ⑂ worktree`) and the `◉` browse chip on the right.
|
|
76
77
|
- **Line 2 — resources:** the context gauge and usage meters on the left, the
|
|
77
78
|
child-run roll-up (`↳ 3 · ¥0.12`, present only once a subagent has finished),
|
|
78
|
-
the mode/alert slot (
|
|
79
|
+
the mode/alert slot (`≡ plan`) trailing after a `│` when present, and the model
|
|
79
80
|
and thinking level on the right. The gauge is anchored at column 0, so `%` is
|
|
80
81
|
always in the same place.
|
|
81
82
|
The roll-up is its own number, never folded into the session's cost: a subagent
|
|
@@ -86,7 +87,7 @@ identity, and grouped help are tuned in
|
|
|
86
87
|
|
|
87
88
|
```
|
|
88
89
|
~/repo/my-pi-agent ⎇ main · ⑂ smoke
|
|
89
|
-
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↳ 2 · ¥0.06 · ↑42k ↓8.0k · R96k CH 87%
|
|
90
|
+
▰▰▰▰▰▰▱▱▱▱ 62%/200k · ¥0.31 · ↳ 2 · ¥0.06 · ↑42k ↓8.0k · R96k CH 87% │ ≡ plan opus-4.5 · high
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
(The examples show the default `¥` symbol. A model that neither `rates` nor the
|
|
@@ -94,7 +95,7 @@ built-in table covers contributes nothing in `CNY` mode, so the bar shows no
|
|
|
94
95
|
figure rather than a guessed one; `USD` mode adds Pi's recorded dollars for that
|
|
95
96
|
record instead — see the currency note under [Configuration](#configuration).)
|
|
96
97
|
|
|
97
|
-
With no plan mode there is no mode slot, so the
|
|
98
|
+
With no plan mode there is no mode slot, so the `│` is omitted:
|
|
98
99
|
|
|
99
100
|
```
|
|
100
101
|
~/repo/my-pi-agent ⎇ main · ⑂ smoke
|
|
@@ -107,19 +108,19 @@ fits, rather than collapsing to a bare glyph:
|
|
|
107
108
|
|
|
108
109
|
```
|
|
109
110
|
~/repo/project ⎇ main · ⑂ smoke
|
|
110
|
-
▰▰▰▰▰▰▱▱▱▱ 62% · ¥0.31
|
|
111
|
+
▰▰▰▰▰▰▱▱▱▱ 62% · ¥0.31 │ ≡ plan opus-4.5 · high
|
|
111
112
|
```
|
|
112
113
|
|
|
113
114
|
```
|
|
114
115
|
project ⎇ main
|
|
115
|
-
62%
|
|
116
|
+
62% ≡ opus-4.5
|
|
116
117
|
```
|
|
117
118
|
|
|
118
119
|
With a named session, the name follows the path and truncates before it drops:
|
|
119
120
|
|
|
120
121
|
```
|
|
121
122
|
~/repo/project · feature-refac… ⎇ main
|
|
122
|
-
▰▰▰▰▰▰▱▱▱▱ 62%
|
|
123
|
+
▰▰▰▰▰▰▱▱▱▱ 62% │ ≡ plan opus-4.5
|
|
123
124
|
```
|
|
124
125
|
|
|
125
126
|
Zero-value meters are omitted, so a fresh session shows only `?/window` instead
|
|
@@ -318,15 +319,17 @@ method follows the terminal (OSC 777, OSC 99, a Windows toast) or falls back to
|
|
|
318
319
|
the platform notifier (`osascript`, `notify-send`); see
|
|
319
320
|
[Notifications](#notifications).
|
|
320
321
|
|
|
321
|
-
**Update check.** In the background at an interactive session's start,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
322
|
+
**Update check.** In the background at an interactive session's start, Pi's
|
|
323
|
+
package manager reports which configured packages are behind. bytefly suppresses
|
|
324
|
+
Pi's own startup block, caches the snapshot in `<agentDir>/bytefly/update.json`
|
|
325
|
+
with the time it was read, and posts one transcript notice listing every package
|
|
326
|
+
plus `pi update --extensions`. This package's new version alone puts `↑0.12.0`
|
|
327
|
+
after the header's chrome version and adds its release URL to the notice. A
|
|
328
|
+
session inside the 24-hour window reuses the cache without a package-manager
|
|
329
|
+
call, and `/bytefly update` re-runs the check on demand. `PI_OFFLINE` uses the
|
|
330
|
+
cached marker with no notice, only `tui` starts the background check, and a
|
|
331
|
+
failed read is silent and not cached, so the next session tries again; see
|
|
332
|
+
[Update check](#update-check).
|
|
330
333
|
|
|
331
334
|
## Commands
|
|
332
335
|
|
|
@@ -335,7 +338,7 @@ request is silent; see [Update check](#update-check).
|
|
|
335
338
|
| `/bytefly [extension] [refresh]` | Open the control center on Extensions. In `tui` it mounts a docked list; every other mode prints the grouped listing, or one extension's full findings when named. |
|
|
336
339
|
| `/bytefly settings` | Open the control center on Settings. Outside `tui` it prints the grouped settings listing with each row's value. |
|
|
337
340
|
| `/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. |
|
|
338
|
-
| `/bytefly update` | Re-run the
|
|
341
|
+
| `/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. |
|
|
339
342
|
|
|
340
343
|
Tab completes the subcommands, extension names after `doctor`, and `refresh`;
|
|
341
344
|
`/bytefly settings` and `/bytefly update` take no name.
|
|
@@ -374,8 +377,8 @@ separators, icons, status keys), and the turn separator in
|
|
|
374
377
|
[`separator/config.ts`](./separator/config.ts) (glyph, label prefix, padding,
|
|
375
378
|
minimum duration, outcome wording, colors).
|
|
376
379
|
|
|
377
|
-
Every key of every section is listed with its type, default, and bounds in
|
|
378
|
-
[configuration
|
|
380
|
+
Every key of every section is listed with its type, default, and bounds in
|
|
381
|
+
[`docs/configuration.md`](../../docs/configuration.md); this section
|
|
379
382
|
covers what that table cannot — when each section is read, and what the cost
|
|
380
383
|
does when no rate matches.
|
|
381
384
|
|
|
@@ -472,7 +475,10 @@ it with its own rates for the models they match:
|
|
|
472
475
|
- **Which rate.** The most specific key wins, with the model segment outranking
|
|
473
476
|
the provider one: `provider/model`, then `*/model`, then `provider/*`, then
|
|
474
477
|
`*`. A segment ending in a star is a prefix match (`*/gpt-*`); equally
|
|
475
|
-
specific keys are resolved in file order.
|
|
478
|
+
specific keys are resolved in file order. A key splits at its first slash, so
|
|
479
|
+
the model segment may contain one: an OpenRouter id is
|
|
480
|
+
`anthropic/claude-fable-5` and its key is
|
|
481
|
+
`openrouter/anthropic/claude-fable-5`.
|
|
476
482
|
- **Which formula.** `tokens × rate ÷ 1,000,000`, summed over the four token
|
|
477
483
|
classes. Cache tokens are never billed again as fresh input.
|
|
478
484
|
- **Which tariff.** Each record is dated by its session entry, so a window is
|
|
@@ -519,9 +525,9 @@ The worktree status is read from the `worktree` status key, so the
|
|
|
519
525
|
from the `browse` status key published by [file-browse](../file-browse/) while
|
|
520
526
|
its server runs, and shows the two-tone `◉ <port>` (green glyph, accent port).
|
|
521
527
|
The trailing slot shows plan-style alerts when present and is omitted otherwise;
|
|
522
|
-
a plan chip's trailing plan file name is dropped, so the slot reads
|
|
528
|
+
a plan chip's trailing plan file name is dropped, so the slot reads `≡ plan`
|
|
523
529
|
even though the built-in footer keeps the name. An alert (a failed job) sorts to
|
|
524
|
-
the front of the slot. The slot trails the meters after a
|
|
530
|
+
the front of the slot. The slot trails the meters after a `│`, so the context
|
|
525
531
|
gauge always starts the line. It keeps each extension's own colour when it
|
|
526
532
|
compacts, and it is droppable: a tight bar drops the slot rather than truncating
|
|
527
533
|
the model, which sits at the end of the line.
|
|
@@ -582,7 +588,7 @@ when the row is switched off in settings, `env disabled` when
|
|
|
582
588
|
glyph and summary. The screen is drawn from the design system: a label-first
|
|
583
589
|
`bytefly ────` title rule,
|
|
584
590
|
the `Extensions · Settings` section bar beside the section's counts, one row
|
|
585
|
-
grammar (`❯ ◼
|
|
591
|
+
grammar (`❯ ◼ name … summary`), and the shared `◼` / `◻` checkbox.
|
|
586
592
|
`/bytefly doctor [extension] [refresh]` selects the doctor report, the same text
|
|
587
593
|
the `run_doctor` tool returns; in `tui` it opens the same screen. `[extension]`
|
|
588
594
|
narrows the Extensions section to one extension and `refresh` forces the first
|
|
@@ -606,12 +612,13 @@ installs or fetches a package.
|
|
|
606
612
|
manages the list is never a selectable row; its doctor report still appears in
|
|
607
613
|
the trailing `Not resolved` group.
|
|
608
614
|
- Shows whether each one is enabled (`◼`) or disabled (`◻`) in settings.
|
|
609
|
-
- Gives each row one verdict from the doctor's report: the worst severity
|
|
610
|
-
|
|
611
|
-
instead, because it will not load; a row the session's
|
|
615
|
+
- Gives each row one verdict from the doctor's report: the worst severity's
|
|
616
|
+
glyph (`!` degraded, `✕` missing) and its summary. A row that is `◻` reads
|
|
617
|
+
`off` instead, because it will not load; a row the session's
|
|
612
618
|
`PI_DISABLED_EXTENSIONS` excludes reads `env disabled`, so the two axes cannot
|
|
613
|
-
contradict each other.
|
|
614
|
-
|
|
619
|
+
contradict each other. The glyph marks what needs attention, so a row with
|
|
620
|
+
nothing to report — a clean report or none at all — leaves the glyph column
|
|
621
|
+
blank and says `ok` in words when a report exists.
|
|
615
622
|
- Toggles the focused extension with `Space`, writing `+pattern` / `-pattern`
|
|
616
623
|
into `extensions` (and package filter objects) in the active scope. A row in
|
|
617
624
|
the trailing `Not resolved` group has no pattern to write, so `Space` says so
|
|
@@ -635,11 +642,11 @@ installs or fetches a package.
|
|
|
635
642
|
without leaving the session.
|
|
636
643
|
|
|
637
644
|
**Settings.** The second section uses the same frame and the same `Tab` scope
|
|
638
|
-
switch, with its own cursor. It lists twenty-
|
|
645
|
+
switch, with its own cursor. It lists twenty-nine preferences in ten groups:
|
|
639
646
|
|
|
640
647
|
```
|
|
641
648
|
bytefly ──────────────────────────────────────────────────────────────
|
|
642
|
-
Extensions · Settings Global ·
|
|
649
|
+
Extensions · Settings Global · 29 settings
|
|
643
650
|
|
|
644
651
|
Startup (1)
|
|
645
652
|
❯ ◻ Bytefly startup TUI Off
|
|
@@ -662,7 +669,8 @@ bytefly ────────────────────────
|
|
|
662
669
|
Rail glyph ╎
|
|
663
670
|
Achieved goal Hide
|
|
664
671
|
Output padding 1
|
|
665
|
-
Terminal (
|
|
672
|
+
Terminal (2)
|
|
673
|
+
Theme system
|
|
666
674
|
◻ Hardware cursor Off
|
|
667
675
|
Worktree (4)
|
|
668
676
|
◼ Fetch remote On
|
|
@@ -704,6 +712,7 @@ bytefly ────────────────────────
|
|
|
704
712
|
| Transcript | Rail glyph | `chrome.rail` | Text, exactly one column |
|
|
705
713
|
| Transcript | Achieved goal | `goal.achieved` | Show, Hide |
|
|
706
714
|
| Transcript | Output padding | Pi `settings.json` | 0, 1 |
|
|
715
|
+
| Terminal | Theme | Pi `settings.json` (`theme`) | `system`, `bytefly-dark`, `bytefly-light` |
|
|
707
716
|
| Terminal | Hardware cursor | Pi `settings.json` | Off, On |
|
|
708
717
|
| Worktree | Base ref | `worktree.baseRef` | Fresh, Head |
|
|
709
718
|
| Worktree | Branch prefix | `worktree.branchPrefix` | Text, trimmed, required |
|
|
@@ -720,24 +729,35 @@ bytefly ────────────────────────
|
|
|
720
729
|
Choosing **Currency** also writes that currency's default precision. Both rows
|
|
721
730
|
stay editable afterwards, so the footer follows the explicit values.
|
|
722
731
|
|
|
732
|
+
The **Theme** row lists `system` first, then the palettes this package ships,
|
|
733
|
+
`bytefly-dark` and `bytefly-light`; it cycles no further, so a bytefly screen
|
|
734
|
+
never proposes a palette it cannot vouch for. It writes the personal `theme`
|
|
735
|
+
setting and takes effect after reload. A value chosen elsewhere — Pi's built-in
|
|
736
|
+
`dark`, another package's theme, or an automatic pair such as
|
|
737
|
+
`bytefly-light/bytefly-dark` — is shown as stored (the pair with `… (automatic)`)
|
|
738
|
+
and is replaced by the next choice here, so manage those in Pi's `/settings` →
|
|
739
|
+
**Theme**.
|
|
740
|
+
|
|
723
741
|
`Space` (or `Enter`) changes the focused row: a boolean toggles, an enum cycles
|
|
724
742
|
forward, and a text row opens an inline editor on its value — the notification
|
|
725
743
|
title, the probe timeout, the branch prefix, and the rail glyph. `u` deletes the
|
|
726
744
|
focused row's key so its default applies again (`Already at its default.` when
|
|
727
|
-
nothing is stored
|
|
728
|
-
|
|
729
|
-
|
|
745
|
+
nothing is stored in that scope; an inherited Project value says so instead),
|
|
746
|
+
`J` swaps the detail pane for the focused row's whole section as the active
|
|
747
|
+
scope stores it — the only view of the keys this screen leaves to JSON — and
|
|
748
|
+
`[` / `]` jump to the previous or next group. The detail pane names
|
|
730
749
|
the source, describes the preference, and shows
|
|
731
|
-
where the value
|
|
732
|
-
.pi/bytefly.json`,
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
loader's
|
|
750
|
+
where the value comes from — `Global · ~/.pi/agent/bytefly.json`, `Project ·
|
|
751
|
+
.pi/bytefly.json`, `Inherited from Global · ~/.pi/agent/bytefly.json`, or
|
|
752
|
+
`Default · <the active scope's file>`; an app row names the personal
|
|
753
|
+
`settings.json`. A successful change marks the screen `Saved · reload to apply`
|
|
754
|
+
— even when the terminal is too short for the detail body — and closing offers
|
|
755
|
+
the same reload confirm as an extension toggle.
|
|
756
|
+
|
|
757
|
+
Six of the ten `bytefly.json` sections belong to other extensions. The screen
|
|
758
|
+
cannot import their normalizers, so it reports the leaf as the file states it and
|
|
759
|
+
declares the loader's default; `test/settings-coverage.test.ts` holds the
|
|
760
|
+
catalogue to every loader's defaults and bounds in both directions.
|
|
741
761
|
|
|
742
762
|
**Bytefly startup TUI** is the one row whose label differs from the Pi key it
|
|
743
763
|
writes: On writes `"quietStartup": true` (bytefly's header replaces Pi's startup
|
|
@@ -758,7 +778,7 @@ removes that one leaf through the same writer's `unsetConfigValueAt`.
|
|
|
758
778
|
The non-`tui` form prints the headline, the groups, and `Label: Value` rows:
|
|
759
779
|
|
|
760
780
|
```
|
|
761
|
-
bytefly: Settings · Global ·
|
|
781
|
+
bytefly: Settings · Global · 29 settings
|
|
762
782
|
|
|
763
783
|
Startup (1)
|
|
764
784
|
Bytefly startup TUI: Off
|
|
@@ -810,6 +830,9 @@ headline; a named extension prints its full findings instead.
|
|
|
810
830
|
| `Space` | Toggle the focused extension (Extensions); change the focused setting (Settings), or open the editor on a text row. |
|
|
811
831
|
| `x` | Clear the focused extension's project override (Extensions, Project scope). |
|
|
812
832
|
| `Enter` | Expand or collapse the focused extension's findings (Extensions); change the focused setting, or open the editor on a text row (Settings). |
|
|
833
|
+
| `u` | Delete the focused setting's key so its default applies again (Settings, `bytefly.json` rows). |
|
|
834
|
+
| `J` | Show or hide the focused row's whole section as stored (Settings, `bytefly.json` rows). |
|
|
835
|
+
| `[` / `]` | Jump to the previous or next group (Settings). |
|
|
813
836
|
| `←` / `→`, `Home` / `End` (`Ctrl+A` / `Ctrl+E`) | Move the editor's caret while a text row is being edited. |
|
|
814
837
|
| `Backspace` / `Delete`, `Ctrl+U` | Edit the buffer: delete a character, or clear it. |
|
|
815
838
|
| `Enter` / `Esc` (editing) | Save the buffer, or cancel and restore the stored value. |
|
|
@@ -901,10 +924,11 @@ control-free line before it reaches an escape sequence or a shell argument.
|
|
|
901
924
|
|
|
902
925
|
## Update check
|
|
903
926
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
927
|
+
Pi's package manager already knows which configured packages are behind, so
|
|
928
|
+
bytefly does not keep a second detector. Once per interactive session, in the
|
|
929
|
+
background, it asks the captured `checkForAvailableUpdates` for the package list,
|
|
930
|
+
suppresses Pi's own `Package Updates Available` block, and draws one notice for
|
|
931
|
+
every row Pi returned.
|
|
908
932
|
|
|
909
933
|
```
|
|
910
934
|
█▀█ Pi v1.3.0
|
|
@@ -912,47 +936,50 @@ reports it once, in the two places it already owns:
|
|
|
912
936
|
```
|
|
913
937
|
|
|
914
938
|
```
|
|
915
|
-
bytefly ·
|
|
916
|
-
╎ ◌
|
|
939
|
+
bytefly · 2 package updates available
|
|
940
|
+
╎ ◌ @gavin-hu/my-pi-agent · v0.11.4 → v0.12.0
|
|
941
|
+
╎ ◌ some-other-package · project
|
|
917
942
|
╎ ◌ update · pi update --extensions
|
|
918
943
|
╎ ◌ release · https://github.com/gavin-hu/my-pi-agent/releases/tag/v0.12.0
|
|
919
944
|
```
|
|
920
945
|
|
|
921
|
-
The marker is the shared `↑` glyph and
|
|
922
|
-
wide, so the header's column math is unchanged — painted with the
|
|
923
|
-
`accent` role: an action rather than a warning, so the muted version
|
|
924
|
-
stays quiet and the transcript is not turned yellow for a normal state.
|
|
925
|
-
|
|
926
|
-
|
|
946
|
+
The marker is the shared `↑` glyph and this package's newest version — the arrow
|
|
947
|
+
is one cell wide, so the header's column math is unchanged — painted with the
|
|
948
|
+
header's `accent` role: an action rather than a warning, so the muted version
|
|
949
|
+
beside it stays quiet and the transcript is not turned yellow for a normal state.
|
|
950
|
+
Other packages never change the header. The marker is part of the chrome cell, so
|
|
951
|
+
the two identity cells still line up, and it is the first thing the identity
|
|
952
|
+
sheds when the terminal narrows.
|
|
927
953
|
|
|
928
954
|
The notice is the shared transcript block: the `bytefly · title` headline at the
|
|
929
|
-
margin,
|
|
955
|
+
margin, one rail row per package with this package's version arrow or the other
|
|
956
|
+
package's scope, then the fixing command and this package's release URL, all at
|
|
930
957
|
`info` severity because nothing is broken. It stays in scrollback and the model
|
|
931
|
-
reads the same
|
|
932
|
-
|
|
933
|
-
The
|
|
934
|
-
|
|
935
|
-
registry
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
Past the window the check runs again and rewrites the entry; a failed
|
|
946
|
-
nothing, so the next session tries again. Offline, the cached
|
|
947
|
-
no request and no
|
|
948
|
-
available and the
|
|
949
|
-
|
|
950
|
-
`/bytefly update` is the on-demand half: it ignores the window,
|
|
951
|
-
now, records and paints the result, and prints one line —
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
set)`, or `could not
|
|
955
|
-
|
|
958
|
+
reads the same names, version, command, and URL in plain text.
|
|
959
|
+
|
|
960
|
+
The list is Pi's decision: npm ranges, git refs, project scope, a missing
|
|
961
|
+
install, and `PI_OFFLINE` all follow its package manager. The only extra read is
|
|
962
|
+
`GET https://registry.npmjs.org/@gavin-hu%2Fmy-pi-agent/latest` when Pi reports
|
|
963
|
+
this package, used just to name the version arrow and release URL. A failed
|
|
964
|
+
version read drops those two pieces but keeps the package list and command.
|
|
965
|
+
|
|
966
|
+
The answer is cached in `<agentDir>/bytefly/update.json` as the package list,
|
|
967
|
+
this package's optional version, the time it was read, and a key over the cwd and
|
|
968
|
+
the effective package sources. A session that starts inside the 24-hour window
|
|
969
|
+
reuses that snapshot — painting the marker and posting the notice from it —
|
|
970
|
+
without repeating Pi's npm/git checks, so a working day of sessions costs one
|
|
971
|
+
read. A project switch or a package install/removal changes the key and forces a
|
|
972
|
+
fresh read. Past the window the check runs again and rewrites the entry; a failed
|
|
973
|
+
read writes nothing, so the next session tries again. Offline, the cached marker
|
|
974
|
+
is used with no request and no notice, because a stale version is still the best
|
|
975
|
+
answer available and the list itself is advisory.
|
|
976
|
+
|
|
977
|
+
`/bytefly update` is the on-demand half: it ignores the window, asks Pi's package
|
|
978
|
+
manager now, records and paints the result, and prints one line — the package
|
|
979
|
+
list with this package's version and release URL when known, `up to date — no
|
|
980
|
+
configured package has an update`, `the update check was skipped (PI_OFFLINE is
|
|
981
|
+
set)`, or `could not check package updates`. It resolves no packages, probes no
|
|
982
|
+
extension, and posts no second notice, so a session open for days can see a
|
|
956
983
|
release without a restart. Opening the control center never checks: the screen has
|
|
957
984
|
no update surface, and the only request paths are `session_start` and this
|
|
958
985
|
command.
|
|
@@ -964,9 +991,16 @@ command.
|
|
|
964
991
|
rule, and transcript renderers stay on. Use `PI_DISABLED_EXTENSIONS=bytefly`
|
|
965
992
|
(or `pi config`) to turn off all of bytefly.
|
|
966
993
|
- **App settings are Global only.** Pi's setters for preferences such as
|
|
967
|
-
`quietStartup` (the **Bytefly startup TUI** row), `outputPad`,
|
|
968
|
-
`showHardwareCursor` write the personal `settings.json`; the
|
|
969
|
-
those rows in Project scope rather than writing a file Pi cannot
|
|
994
|
+
`quietStartup` (the **Bytefly startup TUI** row), `outputPad`,
|
|
995
|
+
`showHardwareCursor`, and `theme` write the personal `settings.json`; the
|
|
996
|
+
screen hides those rows in Project scope rather than writing a file Pi cannot
|
|
997
|
+
manage.
|
|
998
|
+
- **The Theme row offers only this package's palettes.** `system`,
|
|
999
|
+
`bytefly-dark`, and `bytefly-light` are the whole cycle; Pi's built-ins and any
|
|
1000
|
+
user, project, or other package's theme stay in Pi's `/settings` → **Theme**,
|
|
1001
|
+
and a value set there shows as stored here. An automatic pair such as
|
|
1002
|
+
`bytefly-light/bytefly-dark` shows as stored but is replaced by the next single
|
|
1003
|
+
choice, and the change applies after a reload like the other app rows.
|
|
970
1004
|
- **Project overrides of app settings are not shown.** App rows read the
|
|
971
1005
|
personal file; a `.pi/settings.json` override still wins at runtime, and
|
|
972
1006
|
`pi config` is the place to manage it.
|
|
@@ -986,19 +1020,22 @@ command.
|
|
|
986
1020
|
their authoritative names are not exposed to extensions. Use `pi config`.
|
|
987
1021
|
- **Packages are not installed, removed, or updated here**; use `pi install`,
|
|
988
1022
|
`pi remove`, and `pi update`.
|
|
989
|
-
- **The update
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1023
|
+
- **The update list is Pi's.** Only packages configured in `settings.json` are
|
|
1024
|
+
checked; `pi -e .`, a temporary checkout, and other unmanaged loads get no
|
|
1025
|
+
update prompt. The version arrow and release URL still come from npm's
|
|
1026
|
+
`latest`, so a private registry or a version published under another tag can
|
|
1027
|
+
lose those two pieces while the list stays correct.
|
|
993
1028
|
- **The cache window is fixed at 24 hours.** It runs at `session_start` in `tui`
|
|
994
|
-
mode and reuses
|
|
995
|
-
`/bytefly` and `doctor` do not
|
|
996
|
-
|
|
1029
|
+
mode and reuses a snapshot younger than that whose key matches the cwd and
|
|
1030
|
+
package sources; there is no setting for it, and `/bytefly` and `doctor` do not
|
|
1031
|
+
report the version. A failed or slow background request is retried by the next
|
|
1032
|
+
session, or immediately by `/bytefly update`.
|
|
997
1033
|
- **The marker needs the bytefly startup TUI.** It lives on the custom header,
|
|
998
1034
|
so with `quietStartup` off the notice is the whole signal.
|
|
999
|
-
- **Pi
|
|
1000
|
-
|
|
1001
|
-
|
|
1035
|
+
- **Pi's block is suppressed by a host shim.** bytefly wraps
|
|
1036
|
+
`DefaultPackageManager.prototype.checkForAvailableUpdates` at `session_start`
|
|
1037
|
+
and restores it on shutdown. A future Pi that changes that method shape makes
|
|
1038
|
+
the shim inert, and Pi's own block can come back.
|
|
1002
1039
|
- **No auto-update, and the release URL is text only.** The notice names a
|
|
1003
1040
|
command instead of running one, and the notice renderer cannot open a link, so
|
|
1004
1041
|
the release row prints the URL and nothing more — no changelog body, no way to
|
|
@@ -1105,15 +1142,15 @@ rather than showing a wrong value.
|
|
|
1105
1142
|
| Notifications | `agent_settled` (skipped when aborted), `ui_prompt_start` only while `agent_start`…`agent_settled` marks a run active, and `my-pi-agent/job-finished` on `pi.events`; the `notify` section of `bytefly.json` gates each. Delivery writes an OSC 777/99 sequence to stdout or spawns `osascript`, `notify-send`, or `powershell.exe`. The bus subscription is created in `session_start` and released in `session_shutdown`, and the `job` extension never imports bytefly. |
|
|
1106
1143
|
| Picker discovery | `SettingsManager.create(...)` plus `DefaultPackageManager.resolve({ onMissing: "skip" })`, both public exports; both views drop `bytefly`'s own entrypoint. |
|
|
1107
1144
|
| Picker writes | `SettingsManager` setters (`setExtensionPaths`, `setPackages`, `setProjectExtensionPaths`, `setProjectPackages`) then `flush()`; `ctx.reload()` after the screen closes when changes are pending. |
|
|
1108
|
-
| Settings writes | App rows call `SettingsManager` setters (`setQuietStartup`, `setOutputPad`, `setShowHardwareCursor`) on the global store and `flush()`, then surface `drainErrors()`; `bytefly.json` rows call `
|
|
1145
|
+
| Settings writes | App rows call `SettingsManager` setters (`setQuietStartup`, `setOutputPad`, `setShowHardwareCursor`, `setTheme`) on the global store and `flush()`, then surface `drainErrors()`; `bytefly.json` rows call `writeConfigValuesAt` on the selected scope's document with the row's leaf path, so a nested key (`price.currency.decimals`) and a flat one (`notify.method`) share one writer, and a row that also writes a companion leaf (the currency and its default precision) applies both in one document pass; and `u` calls `unsetConfigValueAt` with the same path. A failed or refused write shows a notice in the screen's hint row and leaves the displayed value unchanged; a successful one marks the screen dirty. |
|
|
1109
1146
|
| Doctor tool | `pi.registerTool("run_doctor")`, read-only (`readOnlyHint: true`, `openWorldHint: false`), direct exposure and active on registration (the defaults, so not declared), with a typed `outputSchema` mirroring `structuredContent`. Its `readOnlyHint` is what the shared default-deny policy in `lib/policy.ts` reads to allow it in plan mode. |
|
|
1110
1147
|
| Doctor probes | `run_doctor` and the screen share the session cache created by `registerDoctor`; the screen mounts on that cache and probes on the first Extensions view (the command's `refresh` forces it), while the text modes probe before printing, and `/bytefly refresh` and `refresh: true` re-probe. Probes spawn `<binary> --version`, lazily import optional packages, and read config files through `lib/requirements.ts`; nothing is ever written. |
|
|
1111
1148
|
| Status routing | Reads `footerData.getExtensionStatuses()` (a custom footer replaces the built-in one entirely); `worktree` routes to line 1, plan/alert statuses to line 2's trailing slot. |
|
|
1112
|
-
| Update check | `session_start` in `tui` mode reads `<agentDir>/bytefly/update.json
|
|
1149
|
+
| Update check | `session_start` in `tui` mode installs a suppression on `DefaultPackageManager.prototype.checkForAvailableUpdates`, then reads `<agentDir>/bytefly/update.json`. A fresh entry whose key matches the cwd and effective package sources is recorded without a package-manager call; otherwise bytefly fires `fetchAvailableUpdates()` without awaiting, resolves this package's version through `fetchLatestVersion()` when Pi reports it, writes the snapshot, and records it. `onUpdate` re-installs the header, and `pi.sendMessage(updateNotice(...))` posts the one notice with its version arrow and release URL. `PI_OFFLINE` paints the cached marker only. `/bytefly update` calls the returned `UpdateHandle.recheck()`, which bypasses the window and returns an `UpdateOutcome`; a generation counter drops a background reply that lands after `session_shutdown`, a per-load flag keeps it to one announcement, and shutdown restores Pi's method. |
|
|
1113
1150
|
| Config | `bytefly.json` from the agent directory and `<cwd>/.pi`; the `price` section is read once per footer install (a new session or a session-tree change), the `notify` and `doctor` sections at `session_start`, and the `chrome` section's rail glyph at `session_start`/`session_tree`. Nothing watches the document. The update check has no section: it is on whenever `PI_OFFLINE` is off, and its 24 h window is not configurable. |
|
|
1114
1151
|
| Data sources | `footerData.getGitBranch()`, `footerData.getAvailableProviderCount()`, `ctx.getContextUsage()`, `ctx.sessionManager.getEntries()`, `ctx.sessionManager.getSessionName()`, `ctx.model`; subscribes to `footerData.onBranchChange` to repaint. |
|
|
1115
|
-
| State storage | None besides the inert separator entries. The footer reads session entries and the price config (a memoized scan) and writes no tool-result `details`; it appends `bytefly-separator` entries excluded from LLM context. The screen derives its view from the picker runtime and the current reports, and persists extension toggles through `settings.json`. The Settings section derives from a snapshot of the personal `settings.json` and both `bytefly.json` documents, and persists through the same `SettingsManager` setters or the per-leaf `bytefly.json` writer. Doctor's findings are session-scoped in memory only — cached for the session, never written to the session or a file. Notify holds only the config and the run-active flag in its closure. The update check holds
|
|
1116
|
-
| Lifecycle | `session_start` installs the header when Pi's `quietStartup` is `true` and the footer, loads the chrome rail glyph, points the doctor runtime at the session cwd, probes the extensions with hard requirements when `bytefly.json`'s `doctor.proactive` is on and `quietStartup` is `true`, loads the notify config and subscribes to the job bus, and starts the
|
|
1152
|
+
| State storage | None besides the inert separator entries. The footer reads session entries and the price config (a memoized scan) and writes no tool-result `details`; it appends `bytefly-separator` entries excluded from LLM context. The screen derives its view from the picker runtime and the current reports, and persists extension toggles through `settings.json`. The Settings section derives from a snapshot of the personal `settings.json` and both `bytefly.json` documents, and persists through the same `SettingsManager` setters or the per-leaf `bytefly.json` writer. Doctor's findings are session-scoped in memory only — cached for the session, never written to the session or a file. Notify holds only the config and the run-active flag in its closure. The update check holds this package's version in the per-load `UpdateSource` and one project-scoped snapshot in `<agentDir>/bytefly/update.json`. |
|
|
1153
|
+
| Lifecycle | `session_start` installs the header when Pi's `quietStartup` is `true` and the footer, loads the chrome rail glyph, points the doctor runtime at the session cwd, probes the extensions with hard requirements when `bytefly.json`'s `doctor.proactive` is on and `quietStartup` is `true`, loads the notify config and subscribes to the job bus, and starts the package-update check; `session_tree` reinstalls the header and footer and reloads the rail; `session_shutdown` restores Pi's built-in header, footer, and package-update method, disposes the branch subscription, drops doctor's cached findings, drops the notify bus subscription, and clears the recorded version. |
|
|
1117
1154
|
|
|
1118
1155
|
## Design notes
|
|
1119
1156
|
|
|
@@ -1155,8 +1192,12 @@ rather than showing a wrong value.
|
|
|
1155
1192
|
expand toggle, so no themed string outlives its theme. `indentBlockLines` only
|
|
1156
1193
|
measures a line it cannot prove fits, and the header memoizes on the width,
|
|
1157
1194
|
theme, shape, and the help chords it prints, so a live rebind still repaints.
|
|
1158
|
-
|
|
1159
|
-
|
|
1195
|
+
`SeparatorComponent` uses the same memo for its full-width rule, so a long
|
|
1196
|
+
session does not repaint every turn's rule each frame. The footer's context
|
|
1197
|
+
estimate and session name join its pricing scan in the leaf-keyed memo: all
|
|
1198
|
+
three are O(session) work the host recomputes from scratch, and
|
|
1199
|
+
`createRateLookup` compiles the rate table once per config instead of once per
|
|
1200
|
+
record.
|
|
1160
1201
|
- **The frame delegates; it does not re-render.** Pi resolves tool renderers
|
|
1161
1202
|
through the extension chain, and the resolved object is the definition the row
|
|
1162
1203
|
reads, so a resolver can override `renderShell` and wrap `next()`'s
|
|
@@ -1190,7 +1231,8 @@ rather than showing a wrong value.
|
|
|
1190
1231
|
themselves by that pad: the tool frame and the notice take it from Pi, and the
|
|
1191
1232
|
turn separator reads the last value a sibling observed (`pad.ts`). Pi's setting
|
|
1192
1233
|
is the only knob — bytefly adds no padding of its own. The footer's group
|
|
1193
|
-
separator
|
|
1234
|
+
separator draws `│` between chips — a divider, not the rail (`╎`), which stays
|
|
1235
|
+
a transcript-only glyph.
|
|
1194
1236
|
- **The header is a nameplate, not a dashboard.** Pi's built-in brand colors are
|
|
1195
1237
|
fixed, so the mark ignores the active theme; bytefly's header draws a two-tone
|
|
1196
1238
|
mark from the `accent`/`warn` roles, a signature rule whose accent lead sits
|
|
@@ -1211,7 +1253,7 @@ rather than showing a wrong value.
|
|
|
1211
1253
|
dispatching process and the delegated work stays visible beside it.
|
|
1212
1254
|
- **The gauge is anchored at column 0.** A leading mode slot would shift the
|
|
1213
1255
|
context percentage left and right as plan mode came and went; trailing it
|
|
1214
|
-
after a
|
|
1256
|
+
after a `│` keeps the percentage in a fixed place while the mode stays
|
|
1215
1257
|
visible as the meters drop.
|
|
1216
1258
|
- **Statuses are routed, not repeated.** The built-in footer renders every
|
|
1217
1259
|
`setStatus` value on its own line, so the bar sorts them by meaning instead:
|
|
@@ -1229,9 +1271,9 @@ rather than showing a wrong value.
|
|
|
1229
1271
|
non-zero usage, so it reads full only at 100% and a small percentage never
|
|
1230
1272
|
disappears; unknown usage draws no gauge at all. Only at extreme widths does
|
|
1231
1273
|
`truncateToWidth` clip the remaining text.
|
|
1232
|
-
- **Separators shrink to a single space.** Padded separators (` · `, `
|
|
1274
|
+
- **Separators shrink to a single space.** Padded separators (` · `, ` │ `)
|
|
1233
1275
|
collapse to one space before `truncateToWidth` applies, so adjacent segments
|
|
1234
|
-
never collide and the ellipsis never replaces a
|
|
1276
|
+
never collide and the ellipsis never replaces a `│` with nothing after it.
|
|
1235
1277
|
- **Statuses compact with their colour.** A themed status's compact icon form
|
|
1236
1278
|
reattaches its opening and closing SGR sequences around the visible text, so a
|
|
1237
1279
|
red `✗1` stays red instead of losing its colour exactly when the bar tightens.
|
|
@@ -1335,21 +1377,27 @@ rather than showing a wrong value.
|
|
|
1335
1377
|
- **The prerequisite table is data.** No I/O, no host access, no module state:
|
|
1336
1378
|
every probe dependency arrives as a seam, so `probeExtension` is testable with
|
|
1337
1379
|
no process and `lib/` stays value-only.
|
|
1338
|
-
- **
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1380
|
+
- **Pi owns the update list; bytefly owns the look.** There is one detector, not
|
|
1381
|
+
two: `DefaultPackageManager` already resolves npm ranges, git refs, project
|
|
1382
|
+
scope, and offline mode, and bytefly only carries its result to a themed
|
|
1383
|
+
surface. The extra registry read only names this package's version for the
|
|
1384
|
+
marker, arrow, and release URL; it never decides whether an update exists.
|
|
1385
|
+
- **The suppression is a host shim, not a second checker.** Pi has no setting or
|
|
1386
|
+
extension event for its startup block, so bytefly replaces the public method
|
|
1387
|
+
that feeds it while keeping the captured original for its own read. It is
|
|
1388
|
+
installed only in `tui`, restored on shutdown, and made inert if the host
|
|
1389
|
+
changes shape.
|
|
1390
|
+
- **The marker is an action, the notice is information.** This package's new
|
|
1391
|
+
version is drawn in the accent on the header, where it sits beside a control
|
|
1392
|
+
the user can act on, and every package is listed at `info` severity in the
|
|
1393
|
+
transcript, where a `warn` rail would say something is broken. Neither surface
|
|
1394
|
+
needs per-frame polling: the value arrives once, the memo key includes it, and
|
|
1395
|
+
one `setHeader` re-install repaints.
|
|
1349
1396
|
- **The transport stays local.** `web-access`'s runner does redirects, SSRF
|
|
1350
1397
|
checks, HTML extraction, and caching — none of it applies to one fixed JSON
|
|
1351
1398
|
endpoint, and an extension may not import another's modules, so the ~20-line
|
|
1352
|
-
read lives beside the check with the `fetch` and timeout as seams.
|
|
1399
|
+
read lives beside the check with the `fetch` and timeout as seams. The package
|
|
1400
|
+
list itself is Pi's own command execution, not a second transport.
|
|
1353
1401
|
|
|
1354
1402
|
## Files
|
|
1355
1403
|
|
|
@@ -1359,8 +1407,8 @@ calculation), `message/` (the user-message marker), `notice/` (the shared notice
|
|
|
1359
1407
|
run line on Pi's working row), `panel/` (the
|
|
1360
1408
|
unified screen and its merged model),
|
|
1361
1409
|
`picker/` (discovery and the settings store), `doctor/` (the `run_doctor` tool
|
|
1362
|
-
and its probe runtime), `notify/`, and `update/` (the
|
|
1363
|
-
|
|
1410
|
+
and its probe runtime), `notify/`, and `update/` (Pi's package list, the host
|
|
1411
|
+
suppression, the cache, and the header marker). The chrome and the screen are drawn from
|
|
1364
1412
|
the package's [`lib/tui/`](../../lib/tui/) design system (tokens, rules, rows,
|
|
1365
1413
|
columns, gauge), so the look follows the active theme.
|
|
1366
1414
|
|
|
@@ -1376,10 +1424,10 @@ columns, gauge), so the look follows the active theme.
|
|
|
1376
1424
|
| `footer/config.ts` | Bar tuning (`CONFIG`): thresholds, gauge, separators, icons, status keys, labels. |
|
|
1377
1425
|
| `footer/types.ts` | `StatusSnapshot`, `Segment`, `LineSpec`, `UsageRecord`, and footer/TUI shapes. |
|
|
1378
1426
|
| `footer/collect/entries.ts` | Session entries → usage records, each resolved to the model in effect. |
|
|
1379
|
-
| `footer/collect/snapshot.ts` | Snapshot assembly; memoized pricing scan per branch leaf. |
|
|
1427
|
+
| `footer/collect/snapshot.ts` | Snapshot assembly; memoized pricing scan, context estimate, and session name per branch leaf. |
|
|
1380
1428
|
| `footer/price/types.ts` | `Currency`, `ModelRates`, `PeakWindow`/`PeakSchedule`, `ByteflyConfig`. |
|
|
1381
1429
|
| `footer/price/config.ts` | The `price` section of `bytefly.json`: schema, defaults, built-in DeepSeek rates/tariff, currency defaults, normalizer, loader. |
|
|
1382
|
-
| `footer/price/rates.ts` | Model-key matching: exact and wildcard
|
|
1430
|
+
| `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. |
|
|
1383
1431
|
| `footer/price/schedule.ts` | Peak-window parsing and evaluation in a configured zone. |
|
|
1384
1432
|
| `footer/price/price.ts` | Records → totals: rated cost in both modes, Pi's recorded cost as USD's fallback, and the peak multiplier. |
|
|
1385
1433
|
| `footer/render/format.ts` | Generic formatters (tokens, cost in the configured currency, cwd, the context role, truncation). |
|
|
@@ -1400,7 +1448,7 @@ columns, gauge), so the look follows the active theme.
|
|
|
1400
1448
|
| `block/register.ts` | The `registerToolRenderer` resolver that frames every tool; it recolours a shell call's string before the frame wraps it, rails the result body by status, and rails the call body for `edit`/`write` (the two whose call body carries the result). |
|
|
1401
1449
|
| `separator/config.ts` | Turn-rule tuning: `customType`, glyph, label prefix, padding, receipt minimum duration and outcome wording, and roles. |
|
|
1402
1450
|
| `separator/register.ts` | Registers the entry renderer, tracks the run's tools and failures, and appends the receipt on `agent_settled`. |
|
|
1403
|
-
| `separator/component.ts` | `SeparatorComponent`: the
|
|
1451
|
+
| `separator/component.ts` | `SeparatorComponent`: the entry renderer, memoized on the width so a repeat frame does not rebuild the rule. |
|
|
1404
1452
|
| `separator/format.ts` | Pure `receiptLabel` (the width ladder), `receiptRole`, and `separatorLine`, drawn by the kit's `centeredRule`. |
|
|
1405
1453
|
| `separator/types.ts` | `TurnSeparatorData`: the turn plus the optional receipt fields. |
|
|
1406
1454
|
| `working/config.ts` | Counter tuning (`WORKING_CONFIG`): the words, the tool singular/plural, and the tick interval. |
|
|
@@ -1411,7 +1459,8 @@ columns, gauge), so the look follows the active theme.
|
|
|
1411
1459
|
| `panel/format.ts` | Non-TUI text: the extension headline and grouped listing with a per-row health suffix, plus the section segments, the Settings counts/headline, and the grouped Settings listing. |
|
|
1412
1460
|
| `panel/settings.ts` | The curated Settings catalogue: descriptors, snapshot views and origins, value cycling, stored-value mapping, validation, and grouping, plus the per-section readers that resolve a row's leaf over the global and project documents. |
|
|
1413
1461
|
| `panel/settings-runtime.ts` | The Settings runtime: snapshot cache, scope guards, app setters, per-leaf `bytefly.json` writes, dirty state, and change listeners. |
|
|
1414
|
-
| `panel/
|
|
1462
|
+
| `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. |
|
|
1463
|
+
| `panel/tui.ts` | `PanelComponent`, the two-section dock screen (Extensions list and Settings list) and its section composition; the editing key map is `tui/editing.ts` and the shared frame is `tui/frame.ts`. |
|
|
1415
1464
|
| `panel/commands.ts` | `/bytefly`: one command for the screen sections, the `doctor` report, the settings listing, and their text modes. |
|
|
1416
1465
|
| `picker/types.ts` | Picker host seams (`SettingsStore`, `ExtensionResolver`, `Discovery`), the app-settings setters, and row types. |
|
|
1417
1466
|
| `picker/resources.ts` | Pure grouping, labels, display names, and pattern helpers. |
|
|
@@ -1429,12 +1478,14 @@ columns, gauge), so the look follows the active theme.
|
|
|
1429
1478
|
| `notify/dispatch.ts` | Method selection and delivery: OSC 777/99, Windows toast, `osascript`, `notify-send`, over injected seams. |
|
|
1430
1479
|
| `notify/format.ts` | Pure notification text: session label and the turn / input / job / watch bodies. |
|
|
1431
1480
|
| `notify/register.ts` | Registers the four triggers, loads the config at `session_start`, and owns the job- and watch-bus subscriptions. |
|
|
1432
|
-
| `update/
|
|
1481
|
+
| `update/types.ts` | `PackageUpdate`, derived from Pi's public manager method, and `PackageUpdateCheck`. |
|
|
1482
|
+
| `update/suppress.ts` | The host shim: capture Pi's `checkForAvailableUpdates`, replace it with an empty result, and restore it on shutdown. |
|
|
1483
|
+
| `update/check.ts` | Pi's package list through `DefaultPackageManager`, plus the registry `GET` that names this package's version for the marker, arrow, and release URL. |
|
|
1433
1484
|
| `update/version.ts` | Pure semver parsing and `isNewerVersion`, including prerelease precedence. |
|
|
1434
|
-
| `update/state.ts` | `UpdateSource` and `createUpdateState` (
|
|
1435
|
-
| `update/cache.ts` | The
|
|
1436
|
-
| `update/format.ts` | `updateMarker`, `updateNotice`, `releaseUrl`, and `updateOutcomeText`: the header's `↑0.12.0`, the
|
|
1437
|
-
| `update/register.ts` | The lifecycle: the cache-first session-start read, the async
|
|
1485
|
+
| `update/state.ts` | `UpdateSource` and `createUpdateState` (this package's known version, one record per load), plus `UpdateOutcome`, the four answers an explicit re-check can give. |
|
|
1486
|
+
| `update/cache.ts` | The project-scoped snapshot: `<agentDir>/bytefly/update.json`, the cwd/package key, the 24 h window in `isFresh`, a validated read that degrades to a miss, and the atomic write. |
|
|
1487
|
+
| `update/format.ts` | `updateMarker`, `updateNotice`, `releaseUrl`, and `updateOutcomeText`: the header's `↑0.12.0`, the multi-package notice, and the one line `/bytefly update` prints. |
|
|
1488
|
+
| `update/register.ts` | The lifecycle: suppression, the cache-first session-start read, the async package-manager call, this package's version lookup, the `PI_OFFLINE` and `tui` gates, the once-per-load announcement, the shutdown generation guard, and the `recheck()` handle `/bytefly update` calls. |
|
|
1438
1489
|
|
|
1439
1490
|
## Testing
|
|
1440
1491
|
|
|
@@ -1467,7 +1518,8 @@ unified screen is covered by its pure model merge (`panel/join`), its text
|
|
|
1467
1518
|
formatter (`panel/format`), the settings catalogue and its cycling
|
|
1468
1519
|
(`panel/settings`), the scope-aware settings runtime (`panel/settings-runtime`,
|
|
1469
1520
|
including a nested leaf write that keeps its siblings),
|
|
1470
|
-
the screen's rendering
|
|
1521
|
+
the screen's rendering (`panel/tui`), its editing key map (`tui/editing`),
|
|
1522
|
+
the shared frame (`tui/frame`), and the command through
|
|
1471
1523
|
the bytefly factory (`panel/commands`).
|
|
1472
1524
|
The doctor surface is covered by its pure report
|
|
1473
1525
|
formatting (`doctor/format`), its config loader (`doctor/config`), and
|
|
@@ -1476,14 +1528,15 @@ through the factory (`doctor/register`). The notify capability is covered by its
|
|
|
1476
1528
|
(`notify/config`), the pure text builders (`notify/format`), method selection and
|
|
1477
1529
|
delivery over recording seams (`notify/dispatch`), and its four triggers,
|
|
1478
1530
|
reload, and shutdown through `registerNotify` (`notify/register`). The update
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
and
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1531
|
+
surface is covered by the version-ordering table (`update/version`), Pi's package
|
|
1532
|
+
list and the injected registry read (`update/check`), the host shim and its
|
|
1533
|
+
idempotent restore (`update/suppress`), the per-load store (`update/state`), the
|
|
1534
|
+
marker, multi-package notice, release URL, and recheck wording (`update/format`),
|
|
1535
|
+
the project-scoped snapshot and its window (`update/cache`), and its lifecycle —
|
|
1536
|
+
a fresh matching entry reused without a package-manager call, a stale one re-read
|
|
1537
|
+
and rewritten, silent on failure or an empty list, cache-only offline, skipped
|
|
1538
|
+
outside `tui`, an explicit `recheck()` that ignores the window, and immunity to a
|
|
1539
|
+
reply that lands after shutdown (`update/register`).
|
|
1487
1540
|
The user-message nameplate is covered by its pure transform
|
|
1488
1541
|
(`message/format`, including a render through pi-tui's real `Markdown`) and its
|
|
1489
1542
|
registration (`message/register`), plus the factory check in `extension`.
|