@gavin-hu/my-pi-agent 0.15.1 → 0.17.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 +22 -13
- package/README.zh-CN.md +19 -11
- package/extensions/bytefly/README.md +255 -200
- package/extensions/bytefly/footer/collect/entries.ts +1 -6
- package/extensions/bytefly/footer/collect/snapshot.ts +23 -9
- package/extensions/bytefly/footer/price/price.ts +12 -8
- package/extensions/bytefly/footer/register.ts +13 -1
- package/extensions/bytefly/footer/types.ts +11 -0
- package/extensions/bytefly/footer/unpriced.ts +36 -0
- package/extensions/bytefly/header/component.ts +15 -29
- package/extensions/bytefly/header/identity.ts +71 -0
- package/extensions/bytefly/header/register.ts +9 -3
- package/extensions/bytefly/index.ts +13 -5
- package/extensions/bytefly/message/format.ts +20 -13
- package/extensions/bytefly/message/register.ts +8 -7
- package/extensions/bytefly/notice/component.ts +6 -4
- package/extensions/bytefly/notice/config.ts +16 -2
- package/extensions/bytefly/panel/commands.ts +46 -25
- package/extensions/bytefly/panel/format.ts +52 -22
- package/extensions/bytefly/panel/join.ts +36 -15
- package/extensions/bytefly/panel/settings.ts +72 -392
- package/extensions/bytefly/panel/skills.ts +51 -0
- package/extensions/bytefly/panel/tui/entries.ts +16 -14
- package/extensions/bytefly/panel/tui/extensions-view.ts +7 -58
- package/extensions/bytefly/panel/tui/frame.ts +11 -3
- package/extensions/bytefly/panel/tui/list-view.ts +72 -0
- package/extensions/bytefly/panel/tui/nav.ts +71 -3
- package/extensions/bytefly/panel/tui/settings-section.ts +250 -0
- package/extensions/bytefly/panel/tui/settings-view.ts +8 -12
- package/extensions/bytefly/panel/tui/skills-view.ts +50 -0
- package/extensions/bytefly/panel/tui.ts +223 -333
- package/extensions/bytefly/panel/types.ts +26 -8
- package/extensions/bytefly/picker/discovery.ts +32 -27
- package/extensions/bytefly/picker/resources.ts +22 -10
- package/extensions/bytefly/picker/runtime.ts +62 -34
- package/extensions/bytefly/picker/toggle.ts +16 -10
- package/extensions/bytefly/picker/types.ts +31 -13
- package/extensions/bytefly/update/format.ts +66 -8
- package/extensions/bytefly/update/patch.ts +66 -0
- package/extensions/bytefly/update/register.ts +4 -11
- package/extensions/bytefly/update/release.ts +65 -0
- package/extensions/bytefly/update/state.ts +14 -0
- package/extensions/bytefly/update/suppress.ts +47 -29
- package/extensions/bytefly/update/types.ts +15 -5
- package/extensions/bytefly/working/register.ts +2 -8
- package/extensions/check/tools.ts +2 -11
- package/extensions/check/tui.ts +2 -0
- package/extensions/context/README.md +172 -0
- package/extensions/context/collect.ts +53 -0
- package/extensions/context/commands.ts +100 -0
- package/extensions/context/format.ts +84 -0
- package/extensions/context/index.ts +16 -0
- package/extensions/context/report.ts +332 -0
- package/extensions/context/tui.ts +284 -0
- package/extensions/context/types.ts +124 -0
- package/extensions/file-browse/README.md +67 -19
- package/extensions/file-browse/client.ts +16 -463
- package/extensions/file-browse/config.ts +8 -0
- package/extensions/file-browse/html.ts +9 -7
- package/extensions/file-browse/index.ts +17 -2
- package/extensions/file-browse/live-client.ts +13 -13
- package/extensions/file-browse/live.ts +44 -10
- package/extensions/file-browse/markdown.ts +3 -10
- package/extensions/file-browse/palette.ts +224 -0
- package/extensions/file-browse/raw-html.ts +3 -10
- package/extensions/file-browse/router.ts +2 -2
- package/extensions/file-browse/server.ts +13 -2
- package/extensions/file-browse/styles.ts +8 -3
- package/extensions/file-browse/tree.ts +381 -0
- package/extensions/file-open/README.md +1 -2
- package/extensions/{document → file-read}/README.md +76 -57
- package/extensions/{document → file-read}/config.ts +12 -9
- package/extensions/{document → file-read}/extract/doc.ts +2 -2
- package/extensions/{document → file-read}/extract/docx.ts +3 -3
- package/extensions/{document → file-read}/extract/file.ts +9 -9
- package/extensions/{document → file-read}/extract/odt.ts +10 -8
- package/extensions/{document → file-read}/extract/pdf.ts +3 -3
- package/extensions/{document → file-read}/extract/rtf.ts +3 -3
- package/extensions/{document → file-read}/extract/xlsx.ts +4 -4
- package/extensions/{document → file-read}/formats.ts +11 -11
- package/extensions/file-read/index.ts +17 -0
- package/extensions/{document → file-read}/paging.ts +15 -13
- package/extensions/{document → file-read}/render.ts +17 -13
- package/extensions/{document → file-read}/schema.ts +7 -7
- package/extensions/{document → file-read}/tool.ts +36 -28
- package/extensions/goal/tools.ts +16 -25
- package/extensions/job/commands.ts +32 -46
- package/extensions/job/index.ts +20 -45
- package/extensions/job/runtime.ts +6 -8
- package/extensions/job/tools.ts +58 -103
- package/extensions/memory/commands.ts +30 -44
- package/extensions/memory/tools.ts +10 -20
- package/extensions/memory/tui.ts +5 -1
- package/extensions/plan/README.md +88 -33
- package/extensions/plan/commands.ts +19 -4
- package/extensions/plan/config.ts +27 -0
- package/extensions/plan/plan-index.ts +3 -1
- package/extensions/plan/plans.ts +31 -13
- package/extensions/plan/review.ts +34 -14
- package/extensions/plan/runtime.ts +3 -1
- package/extensions/plan/steps.ts +43 -14
- package/extensions/plan/tools/cancel.ts +79 -0
- package/extensions/plan/tools/enter.ts +16 -17
- package/extensions/plan/tools/exit.ts +60 -50
- package/extensions/plan/tools/steps.ts +13 -26
- package/extensions/plan/tools/write.ts +30 -38
- package/extensions/plan/tools.ts +5 -2
- package/extensions/plan/tui.ts +9 -7
- package/extensions/plan/types.ts +8 -0
- package/extensions/plan/web-chrome.ts +101 -0
- package/extensions/plan/web-client.ts +98 -311
- package/extensions/plan/web-markdown.ts +222 -0
- package/extensions/plan/web-page.ts +28 -2
- package/extensions/plan/web-router.ts +2 -2
- package/extensions/plan/web.ts +21 -12
- package/extensions/question/tools.ts +5 -4
- package/extensions/rewind/checklist.ts +4 -0
- package/extensions/rewind/review-tui.ts +3 -1
- package/extensions/rewind/rewind-tui.ts +4 -0
- package/extensions/subagent/README.md +25 -12
- package/extensions/subagent/background.ts +1 -7
- package/extensions/subagent/format.ts +72 -25
- package/extensions/subagent/index.ts +21 -47
- package/extensions/subagent/orchestrate.ts +18 -41
- package/extensions/subagent/render.ts +29 -42
- package/extensions/subagent/stream.ts +24 -18
- package/extensions/subagent/types.ts +7 -0
- package/extensions/todo/tools.ts +15 -20
- package/extensions/todo/tui.ts +5 -1
- package/extensions/watch/README.md +5 -5
- package/extensions/watch/commands.ts +33 -47
- package/extensions/watch/index.ts +10 -35
- package/extensions/watch/runtime.ts +5 -7
- package/extensions/watch/tools.ts +38 -77
- package/extensions/web-access/README.md +3 -3
- package/extensions/web-access/search/search.ts +9 -18
- package/extensions/wechat/README.md +40 -18
- package/extensions/wechat/bridge.ts +38 -40
- package/extensions/wechat/client.ts +1 -4
- package/extensions/wechat/commands.ts +1 -1
- package/extensions/wechat/interaction.ts +25 -4
- package/extensions/wechat/login-screen.ts +2 -3
- package/extensions/wechat/notices.ts +7 -5
- package/extensions/wechat/prompt.ts +19 -4
- package/extensions/wechat/qrcode.ts +9 -9
- package/extensions/wechat/slash.ts +14 -0
- package/extensions/wechat/status-screen.ts +2 -2
- package/extensions/wechat/timer.ts +9 -30
- package/extensions/wechat/tools.ts +7 -18
- package/extensions/worktree/README.md +48 -12
- package/extensions/worktree/commands.ts +109 -65
- package/extensions/worktree/enter.ts +1 -1
- package/extensions/worktree/exit.ts +11 -1
- package/extensions/worktree/lifecycle.ts +9 -1
- package/extensions/worktree/screen.ts +263 -0
- package/extensions/worktree/status.ts +84 -38
- package/lib/README.md +15 -11
- package/lib/config.ts +12 -0
- package/lib/escape.ts +15 -2
- package/lib/format.ts +6 -2
- package/lib/interaction.ts +18 -1
- package/lib/pdf.ts +2 -2
- package/lib/report.ts +75 -2
- package/lib/requirements.ts +2 -2
- package/lib/screen-session.ts +85 -0
- package/lib/timer.ts +61 -0
- package/lib/tool-result.ts +54 -4
- package/lib/tui/README.md +19 -11
- package/lib/tui/chrome.ts +27 -6
- package/lib/tui/columns.ts +33 -8
- package/lib/tui/dock-screen.ts +6 -2
- package/lib/tui/gauge.ts +9 -5
- package/lib/tui/rows.ts +15 -6
- package/lib/tui/rules.ts +4 -8
- package/lib/tui/tool.ts +55 -2
- package/lib/usage.ts +26 -0
- package/lib/web/README.md +131 -0
- package/lib/web/base.ts +19 -2
- package/lib/web/components.ts +10 -6
- package/lib/web/layout.ts +2 -0
- package/lib/web/markup.ts +2 -1
- package/lib/web/runtime.ts +103 -25
- package/lib/web/tokens.ts +23 -7
- package/package.json +10 -4
- package/skills/changelog/SKILL.md +148 -0
- package/skills/next/SKILL.md +184 -0
- package/extensions/document/index.ts +0 -17
- /package/extensions/{document → file-read}/deadline.ts +0 -0
- /package/extensions/{document → file-read}/extract/vendor.d.ts +0 -0
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
this package adds: one themed startup header whose two-tone nameplate carries
|
|
5
5
|
the agent and chrome identities, one compact, colorful, width-adaptive two-line
|
|
6
6
|
footer, a two-row `You` nameplate that opens each user message, a receipt rule that
|
|
7
|
-
records each completed turn in the transcript, one keyboard-driven screen with
|
|
8
|
-
sections — Extensions, every resolved Pi extension with its enable
|
|
9
|
-
its health
|
|
10
|
-
|
|
7
|
+
records each completed turn in the transcript, one keyboard-driven screen with
|
|
8
|
+
three sections — Extensions, every resolved Pi extension with its enable
|
|
9
|
+
checkbox and its health; Skills, every resolved Pi skill with the same checkbox
|
|
10
|
+
and its declared description; and Settings, the common app and `bytefly.json`
|
|
11
|
+
preferences — and an opt-in notify capability that raises an OS notification when a run finishes,
|
|
11
12
|
a job finishes, or the agent asks for input, and a package-update check that
|
|
12
|
-
replaces Pi's startup
|
|
13
|
-
on the header.
|
|
13
|
+
replaces Pi's startup blocks — the package list and Pi's own release — with one
|
|
14
|
+
notice each and marks a new version on the header.
|
|
14
15
|
DeepSeek is priced from the provider's published yuan rates and peak tariff by
|
|
15
16
|
default; set `price.currency.code` to `USD` to price it from the provider's
|
|
16
17
|
published dollar table instead, under the same peak windows, with Pi's recorded
|
|
@@ -35,7 +36,7 @@ How the `run_doctor` call and its result look in the transcript — the call lin
|
|
|
35
36
|
The extension owns ten surfaces: the startup header, the footer, the
|
|
36
37
|
user-message marker, the rule between completed turns, the notice block for
|
|
37
38
|
shared transcript notices, the tool-block frame, the live working line, the
|
|
38
|
-
|
|
39
|
+
three-section control center, notifications, and the update check.
|
|
39
40
|
|
|
40
41
|
**Header.** A nameplate: a two-tone half-block mark from the active theme's
|
|
41
42
|
`accent` / `warn` roles, the agent identity (`Pi`, bold, and its version), the
|
|
@@ -58,9 +59,9 @@ that cannot render half blocks the mark falls back to a two-tone `Pi` wordmark.
|
|
|
58
59
|
/ commands · ! bash · !! bash (no context) · /bytefly extensions
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
As the terminal narrows, the identity sheds the
|
|
62
|
-
version, then the chrome line, then the agent name, and the help
|
|
63
|
-
keys, so nothing wraps or clips mid-word. Height sheds the same way: at 28 rows
|
|
62
|
+
As the terminal narrows, the identity sheds the chrome marker, then the chrome
|
|
63
|
+
version, then the chrome line, then Pi's marker with the agent name, and the help
|
|
64
|
+
rows drop whole keys, so nothing wraps or clips mid-word. Height sheds the same way: at 28 rows
|
|
64
65
|
all three help groups print, below 28 the middle group (the expand and model
|
|
65
66
|
chords) goes first, below 22 only the `/` commands row survives, and below 16 the
|
|
66
67
|
help block and the leading blank row go, leaving the nameplate and its rule. An
|
|
@@ -152,6 +153,15 @@ default, turns it off. The check reads the total the footer already priced, and
|
|
|
152
153
|
the footer exists only in `tui` sessions, so a print or JSON run has no budget
|
|
153
154
|
alert; the footer's own numbers are visible in every interactive session.
|
|
154
155
|
|
|
156
|
+
**Unpriced records.** `CNY` has no fallback, so a record for a model with no
|
|
157
|
+
`price.rates` entry contributes nothing to the total — with nothing on screen
|
|
158
|
+
saying so. The footer counts those records on the pass it already prices, and
|
|
159
|
+
one `bytefly · Records with no CNY rate` notice names the count and the two
|
|
160
|
+
fixes: switch `price.currency.code` to `USD` (Pi's catalog is per model, tiers
|
|
161
|
+
included) or add yuan `price.rates` entries. It fires once per session, on the
|
|
162
|
+
run that settles, like the budget alert. `USD` never counts one: Pi's recorded
|
|
163
|
+
amount covers every model.
|
|
164
|
+
|
|
155
165
|
**User message.** Every user message opens with a two-row `You` nameplate —
|
|
156
166
|
the label over a rule that spans the width — above the message:
|
|
157
167
|
|
|
@@ -217,7 +227,10 @@ job · 2 background jobs finished
|
|
|
217
227
|
```
|
|
218
228
|
|
|
219
229
|
The rail is painted by the notice's worst severity, so a failure reads red at the
|
|
220
|
-
edge like an errored tool result
|
|
230
|
+
edge like an errored tool result, and the headline's title takes the notice's own
|
|
231
|
+
severity — a warning reads yellow where its sentence is, while an `info` or `ok`
|
|
232
|
+
notice stays body text. A row's label stays body text too: its severity is the
|
|
233
|
+
glyph it hangs on, so one failing row never tints the rest of the list.
|
|
221
234
|
|
|
222
235
|
`job` and `watch` post one when a background job finishes or a watched line
|
|
223
236
|
matches, so the report the model reads is visible too. `doctor` posts one when a
|
|
@@ -326,22 +339,26 @@ with the time it was read, and posts one transcript notice listing every package
|
|
|
326
339
|
plus `pi update --extensions`. This package's new version alone puts `↑0.12.0`
|
|
327
340
|
after the header's chrome version and adds its release URL to the notice. A
|
|
328
341
|
session inside the 24-hour window reuses the cache without a package-manager
|
|
329
|
-
call, and `/bytefly update` re-runs the check on demand.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
342
|
+
call, and `/bytefly update` re-runs the check on demand. Pi's own newer release
|
|
343
|
+
is drawn the same way: Pi resolves it from `pi.dev` and would draw `Update
|
|
344
|
+
Available`, and bytefly patches the method that draws it, so the release becomes
|
|
345
|
+
a notice naming `pi update` and the changelog and marks `Pi v1.3.0 ↑1.4.0` on
|
|
346
|
+
the agent line. `PI_OFFLINE` uses the cached marker with no notice, only `tui`
|
|
347
|
+
starts the background check, and a failed read is silent and not cached, so the
|
|
348
|
+
next session tries again; see [Update check](#update-check).
|
|
333
349
|
|
|
334
350
|
## Commands
|
|
335
351
|
|
|
336
352
|
| Command | What it does |
|
|
337
353
|
|---|---|
|
|
338
354
|
| `/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. |
|
|
339
|
-
| `/bytefly settings` | Open the control center on Settings. Outside `tui` it prints
|
|
355
|
+
| `/bytefly settings` | Open the control center on Settings. Outside `tui` it prints one `Label: Value` line per setting. |
|
|
356
|
+
| `/bytefly skills` | Open the control center on Skills. Outside `tui` it prints the grouped skills listing with one row per skill. |
|
|
340
357
|
| `/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. |
|
|
341
358
|
| `/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. |
|
|
342
359
|
|
|
343
360
|
Tab completes the subcommands, extension names after `doctor`, and `refresh`;
|
|
344
|
-
`/bytefly settings
|
|
361
|
+
`/bytefly settings`, `/bytefly skills`, and `/bytefly update` take no name.
|
|
345
362
|
|
|
346
363
|
## Behaviour by mode
|
|
347
364
|
|
|
@@ -355,7 +372,7 @@ print the grouped listing with a per-row health suffix and the headline, or that
|
|
|
355
372
|
extension's full findings when one is named. In `tui` the screen opens on the
|
|
356
373
|
session's cached report and probes on the first Extensions view; the text modes
|
|
357
374
|
probe before they print. `/bytefly settings` prints the
|
|
358
|
-
|
|
375
|
+
flat settings listing with each row's value outside `tui`; it does not
|
|
359
376
|
resolve packages or probe the doctor. The
|
|
360
377
|
proactive session-start check posts a transcript notice through the shared
|
|
361
378
|
`my-pi-agent/notice` renderer rather than a transient notification, and is
|
|
@@ -493,13 +510,14 @@ it with its own rates for the models they match:
|
|
|
493
510
|
changes how the total is printed; the symbol follows the code.
|
|
494
511
|
- **Which source.** Both currencies price a matched record from `rates`; only
|
|
495
512
|
the unmatched case differs. `CNY` contributes nothing for a model it cannot
|
|
496
|
-
price
|
|
497
|
-
|
|
513
|
+
price and counts the record instead, so the session can name what its total
|
|
514
|
+
leaves out; `USD` adds Pi's recorded dollar amount for that record, because
|
|
515
|
+
that number is already dollars and already per model.
|
|
498
516
|
|
|
499
517
|
For example, DeepSeek flash at `¥2` in and `¥8` out per million, with the
|
|
500
518
|
published peak windows and `offPeakMultiplier: 0.5`, prices a 1M-in + 1M-out
|
|
501
519
|
turn at `¥10.00` at peak and `¥5.00` off-peak. That example is worked end to end
|
|
502
|
-
in [`footer/
|
|
520
|
+
in [`footer/footer.test.ts`](./footer/footer.test.ts), which also prices the built-in
|
|
503
521
|
table with no config file at all.
|
|
504
522
|
|
|
505
523
|
## Content and colors
|
|
@@ -575,25 +593,27 @@ and outcome as the width allows.
|
|
|
575
593
|
|
|
576
594
|
## The control center
|
|
577
595
|
|
|
578
|
-
<img src="../../assets/bytefly.png" alt="The /bytefly control center: the Extensions and Settings section bar with the `Global · 10 extensions · 2 off · 1 missing` counts, one checkbox row per extension with its verdict, the focused extension's report, and the key hints" width="100%">
|
|
596
|
+
<img src="../../assets/bytefly.png" alt="The /bytefly control center: the Extensions, Skills, and Settings section bar with the `Global · 10 extensions · 2 off · 1 missing` counts, one checkbox row per extension with its verdict, the focused extension's report, and the key hints" width="100%">
|
|
579
597
|
|
|
580
598
|
`/bytefly [extension] [refresh]` opens the control center on **Extensions**: a
|
|
581
599
|
keyboard-driven dock list of every extension Pi resolves for the session, so the
|
|
582
|
-
list matches what actually loads. `←`/`→`
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
600
|
+
list matches what actually loads. `←`/`→` move to **Skills** and then
|
|
601
|
+
**Settings**, one section per press and stopping at the ends, where the same
|
|
602
|
+
frame lists every resolved skill and the curated preferences. `/bytefly skills`
|
|
603
|
+
and `/bytefly settings` open their section directly. It merges the former
|
|
604
|
+
extensions picker and doctor report into one row per extension: the picker's
|
|
605
|
+
enable checkbox and label, then one verdict — `off` when the row is switched off
|
|
606
|
+
in settings, `env disabled` when `PI_DISABLED_EXTENSIONS` excludes it, otherwise
|
|
607
|
+
the doctor's worst-severity glyph and summary. The screen is drawn from the
|
|
608
|
+
design system: a label-first `Bytefly ────` title rule,
|
|
609
|
+
the `Extensions · Skills · Settings` section bar beside the section's counts, one
|
|
610
|
+
row grammar (`❯ ◼ name … summary`), the shared `◼` / `◻` checkbox, and the closing
|
|
611
|
+
rule under the key hints that Pi's own list screens draw.
|
|
592
612
|
`/bytefly doctor [extension] [refresh]` selects the doctor report, the same text
|
|
593
613
|
the `run_doctor` tool returns; in `tui` it opens the same screen. `[extension]`
|
|
594
614
|
narrows the Extensions section to one extension and `refresh` forces the first
|
|
595
615
|
probe. Tab completes the subcommands, extension names after `doctor`, and
|
|
596
|
-
`refresh`; `/bytefly settings`
|
|
616
|
+
`refresh`; `/bytefly settings` and `/bytefly skills` take no name.
|
|
597
617
|
|
|
598
618
|
The screen opens on the findings the session already has, and the Extensions
|
|
599
619
|
section probes once on its first view (the hint shows `refreshing…` while it
|
|
@@ -641,93 +661,72 @@ installs or fetches a package.
|
|
|
641
661
|
- Offers a reload after pending changes, so the new selection takes effect
|
|
642
662
|
without leaving the session.
|
|
643
663
|
|
|
644
|
-
**
|
|
645
|
-
|
|
664
|
+
**Skills.** The second section is the same list over Pi's skills: one row per
|
|
665
|
+
skill, grouped by source and sorted by name, labelled with the name its
|
|
666
|
+
`SKILL.md` declares (or the folder name when it declares none). `Space` writes
|
|
667
|
+
`+pattern` / `-pattern` into `skills` — or a package's `skills` filter — in the
|
|
668
|
+
active scope, and `Tab` and `x` behave as they do for extensions. A row's verdict
|
|
669
|
+
comes from the skill's own file: `off` when it is disabled, `hidden` when
|
|
670
|
+
frontmatter sets `disable-model-invocation` so only `/skill:<name>` loads it, and
|
|
671
|
+
`not loaded` with Pi's reason when the file was refused. The detail pane carries
|
|
672
|
+
the resolved path and the declared description, one line until `Enter` expands
|
|
673
|
+
it. There is nothing to probe, so `r` is not offered here; the metadata is read
|
|
674
|
+
once when the section first appears, so an edited `SKILL.md` shows on the next
|
|
675
|
+
open.
|
|
676
|
+
|
|
677
|
+
**Settings.** The third section uses the same frame and the same `Tab` scope
|
|
678
|
+
switch, with its own cursor. It is the shortlist a session changes: thirteen
|
|
679
|
+
preferences on one flat line each, the value beside its label, and no group
|
|
680
|
+
headings. The whole list fits a 24-row terminal, and the frame stops growing
|
|
681
|
+
there however tall the terminal is.
|
|
646
682
|
|
|
647
683
|
```
|
|
648
|
-
|
|
649
|
-
Extensions · Settings
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
◼
|
|
656
|
-
◼
|
|
657
|
-
◼
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
Currency CNY (¥)
|
|
666
|
-
Cost decimals 2
|
|
667
|
-
Session budget 0
|
|
668
|
-
Transcript (3)
|
|
669
|
-
Rail glyph ╎
|
|
670
|
-
Achieved goal Hide
|
|
671
|
-
Output padding 1
|
|
672
|
-
Terminal (2)
|
|
673
|
-
Theme system
|
|
674
|
-
◻ Hardware cursor Off
|
|
675
|
-
Worktree (4)
|
|
676
|
-
◼ Fetch remote On
|
|
677
|
-
Base ref Fresh
|
|
678
|
-
Branch prefix worktree-
|
|
679
|
-
Prune after (days) 7
|
|
680
|
-
Snapshots (3)
|
|
681
|
-
◼ Automatic snapshots On
|
|
682
|
-
Snapshots kept 20
|
|
683
|
-
◼ Safety snapshot On
|
|
684
|
-
Jobs and watchers (3)
|
|
685
|
-
◻ Wake when a job finishes Off
|
|
686
|
-
◻ Keep jobs after exit Off
|
|
687
|
-
◻ Wake on a match Off
|
|
688
|
-
Memory (1)
|
|
689
|
-
◼ Inject notes On
|
|
684
|
+
Bytefly ──────────────────────────────────────────────────────────────
|
|
685
|
+
Extensions · Skills · Settings Global · 13 settings
|
|
686
|
+
|
|
687
|
+
❯ ◻ Bytefly startup TUI Off
|
|
688
|
+
◼ Theme system
|
|
689
|
+
◻ Desktop notifications Off
|
|
690
|
+
◼ Turn finished On
|
|
691
|
+
◼ Needs input On
|
|
692
|
+
◼ Job finished On
|
|
693
|
+
◼ Watcher matched On
|
|
694
|
+
◻ Wake when a job finishes Off
|
|
695
|
+
◼ Offer the session goal On
|
|
696
|
+
◼ Automatic snapshots On
|
|
697
|
+
◼ Proactive health check On
|
|
698
|
+
Currency CNY (¥)
|
|
699
|
+
Session budget 0
|
|
700
|
+
|
|
690
701
|
Bytefly startup TUI — Pi setting
|
|
691
702
|
Use bytefly's startup header in place of Pi's startup TUI.
|
|
692
703
|
Default · ~/.pi/agent/settings.json
|
|
693
704
|
|
|
694
|
-
Esc close · ←/→ · Space change · Tab scope · u reset · J JSON ·
|
|
705
|
+
Esc close · ←/→ · Space change · Tab scope · u reset · J JSON · ↑/↓ select
|
|
706
|
+
──────────────────────────────────────────────────────────────────────
|
|
695
707
|
```
|
|
696
708
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
|
700
|
-
|
|
701
|
-
|
|
|
702
|
-
|
|
|
703
|
-
|
|
|
704
|
-
|
|
|
705
|
-
|
|
|
706
|
-
|
|
|
707
|
-
|
|
|
708
|
-
|
|
|
709
|
-
|
|
|
710
|
-
|
|
|
711
|
-
|
|
|
712
|
-
|
|
|
713
|
-
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
| Worktree | Branch prefix | `worktree.branchPrefix` | Text, trimmed, required |
|
|
719
|
-
| Worktree | Fetch remote | `worktree.fetchRemote` | Off, On |
|
|
720
|
-
| Worktree | Prune after (days) | `worktree.pruneAfterDays` | Number, 0–3650 |
|
|
721
|
-
| Snapshots | Automatic snapshots | `rewind.autoSnapshots` | Off, On |
|
|
722
|
-
| Snapshots | Snapshots kept | `rewind.max` | Number, 0–1000 |
|
|
723
|
-
| Snapshots | Safety snapshot | `rewind.safetySnapshot` | Off, On |
|
|
724
|
-
| Jobs and watchers | Wake when a job finishes | `job.wakeOnFinish` | Off, On |
|
|
725
|
-
| Jobs and watchers | Keep jobs after exit | `job.detachedByDefault` | Off, On |
|
|
726
|
-
| Jobs and watchers | Wake on a match | `watch.wakeOnMatch` | Off, On |
|
|
727
|
-
| Memory | Inject notes | `memory.inject` | Off, On |
|
|
728
|
-
|
|
729
|
-
Choosing **Currency** also writes that currency's default precision. Both rows
|
|
730
|
-
stay editable afterwards, so the footer follows the explicit values.
|
|
709
|
+
<img src="../../assets/bytefly-settings.png" alt="The /bytefly Settings section: one flat list of thirteen preferences with each value beside its label, the `Global · 13 settings` counts, and a three-row detail pane naming the focused row's source, description, and file" width="100%">
|
|
710
|
+
|
|
711
|
+
| Row | Source | Values |
|
|
712
|
+
|---|---|---|
|
|
713
|
+
| Bytefly startup TUI | Pi `settings.json` (`quietStartup`) | Off, On |
|
|
714
|
+
| Theme | Pi `settings.json` (`theme`) | `system`, `bytefly-dark`, `bytefly-light` |
|
|
715
|
+
| Desktop notifications | `notify.enabled` | Off, On |
|
|
716
|
+
| Turn finished | `notify.turnFinished` | Off, On |
|
|
717
|
+
| Needs input | `notify.needsInput` | Off, On |
|
|
718
|
+
| Job finished | `notify.jobFinished` | Off, On |
|
|
719
|
+
| Watcher matched | `notify.matchFound` | Off, On |
|
|
720
|
+
| Wake when a job finishes | `job.wakeOnFinish` | Off, On |
|
|
721
|
+
| Offer the session goal | `plan.goalPrompt` | Off, On |
|
|
722
|
+
| Automatic snapshots | `rewind.autoSnapshots` | Off, On |
|
|
723
|
+
| Proactive health check | `doctor.proactive` | Off, On |
|
|
724
|
+
| Currency | `price.currency.code` | CNY, USD |
|
|
725
|
+
| Session budget | `price.budget` | Number, `0` = off |
|
|
726
|
+
|
|
727
|
+
Choosing **Currency** also writes that currency's default precision
|
|
728
|
+
(`price.currency.decimals`). Both stay editable in `bytefly.json` afterwards, so
|
|
729
|
+
the footer follows the explicit values.
|
|
731
730
|
|
|
732
731
|
The **Theme** row lists `system` first, then the palettes this package ships,
|
|
733
732
|
`bytefly-dark` and `bytefly-light`; it cycles no further, so a bytefly screen
|
|
@@ -739,24 +738,34 @@ and is replaced by the next choice here, so manage those in Pi's `/settings` →
|
|
|
739
738
|
**Theme**.
|
|
740
739
|
|
|
741
740
|
`Space` (or `Enter`) changes the focused row: a boolean toggles, an enum cycles
|
|
742
|
-
forward, and
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
the source, describes the preference, and shows
|
|
750
|
-
where the value comes from — `Global · ~/.pi/agent/bytefly.json`, `Project ·
|
|
741
|
+
forward, and the one text row — **Session budget** — opens an inline editor on its
|
|
742
|
+
amount. `u` deletes the focused row's key so its default applies again (`Already
|
|
743
|
+
at its default.` when nothing is stored in that scope; an inherited Project value
|
|
744
|
+
says so instead), and `J` swaps the detail pane for the focused row's whole
|
|
745
|
+
section as the active scope stores it — the only view of the keys this screen
|
|
746
|
+
leaves to JSON. The detail pane names the source, describes the preference, and
|
|
747
|
+
shows where the value comes from — `Global · ~/.pi/agent/bytefly.json`, `Project ·
|
|
751
748
|
.pi/bytefly.json`, `Inherited from Global · ~/.pi/agent/bytefly.json`, or
|
|
752
749
|
`Default · <the active scope's file>`; an app row names the personal
|
|
753
750
|
`settings.json`. A successful change marks the screen `Saved · reload to apply`
|
|
754
751
|
— 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
|
-
|
|
758
|
-
|
|
759
|
-
|
|
752
|
+
the same reload confirm as an extension or skill toggle.
|
|
753
|
+
|
|
754
|
+
The list is capped at thirteen rows so the screen keeps fitting a 24-row
|
|
755
|
+
terminal: adding a setting means removing one (`panel/panel.test.ts` holds the
|
|
756
|
+
ceiling). Everything else stays in `bytefly.json` — the tuning numbers, the
|
|
757
|
+
cosmetic labels, and the Pi preferences Pi's own `/settings` owns — and
|
|
758
|
+
`test/settings-coverage.test.ts` keeps the split honest: every loader key is
|
|
759
|
+
either a row or a declared JSON-only edit with the reason it left. Five
|
|
760
|
+
`bytefly.json` sections therefore have no row at all (`chrome`, `goal`, `watch`,
|
|
761
|
+
`worktree`, `memory`), as do `notify.title`, `doctor.timeoutMs`,
|
|
762
|
+
`price.currency.decimals`, `rewind.max`, `rewind.safetySnapshot`,
|
|
763
|
+
`job.detachedByDefault`, and `watch.wakeOnMatch` inside sections that do. Each is
|
|
764
|
+
documented in [`docs/configuration.md`](../../docs/configuration.md).
|
|
765
|
+
|
|
766
|
+
Three of the six sections belong to other extensions (`rewind`, `job`, and
|
|
767
|
+
`plan`). The screen cannot import their normalizers, so it reports the leaf as
|
|
768
|
+
the file states it and declares the loader's default; the same test holds the
|
|
760
769
|
catalogue to every loader's defaults and bounds in both directions.
|
|
761
770
|
|
|
762
771
|
**Bytefly startup TUI** is the one row whose label differs from the Pi key it
|
|
@@ -767,31 +776,28 @@ with `true` or `false`.
|
|
|
767
776
|
|
|
768
777
|
App rows are **Global only**: Pi's setters for them write the personal
|
|
769
778
|
`settings.json`, and only resource paths have public project setters. Project
|
|
770
|
-
scope therefore lists the
|
|
779
|
+
scope therefore lists the eleven `bytefly.json` rows and a
|
|
771
780
|
`App settings are Global only.` note rather than promising a write that cannot
|
|
772
781
|
happen. A `bytefly.json` row writes one leaf in the selected scope (a depth-1
|
|
773
|
-
key, or a nested one such as `price.currency.
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
782
|
+
key, or a nested one such as `price.currency.code`) through a per-key writer, so
|
|
783
|
+
every sibling key, section, `$schema`, and `version` is preserved. A malformed
|
|
784
|
+
document is refused with a notice instead of overwritten, and `u` removes that
|
|
785
|
+
one leaf through the same writer's `unsetConfigValueAt`.
|
|
777
786
|
|
|
778
|
-
The non-`tui` form prints the headline
|
|
787
|
+
The non-`tui` form prints the headline and one `Label: Value` row per line, in
|
|
788
|
+
screen order:
|
|
779
789
|
|
|
780
790
|
```
|
|
781
|
-
bytefly: Settings · Global ·
|
|
782
|
-
|
|
783
|
-
Startup (1)
|
|
791
|
+
bytefly: Settings · Global · 14 settings
|
|
784
792
|
Bytefly startup TUI: Off
|
|
785
|
-
|
|
786
|
-
Notifications (7)
|
|
793
|
+
Theme: system
|
|
787
794
|
Desktop notifications: Off
|
|
788
795
|
Turn finished: On
|
|
789
796
|
Needs input: On
|
|
790
797
|
Job finished: On
|
|
791
798
|
Watcher matched: On
|
|
792
799
|
Delivery method: Auto
|
|
793
|
-
|
|
794
|
-
...
|
|
800
|
+
...
|
|
795
801
|
```
|
|
796
802
|
|
|
797
803
|
The doctor side probes every declared extension and reports each check as `ok`,
|
|
@@ -826,21 +832,21 @@ headline; a named extension prints its full findings instead.
|
|
|
826
832
|
|
|
827
833
|
| Key | Effect |
|
|
828
834
|
|---|---|
|
|
829
|
-
| `←` / `→` | Show the
|
|
830
|
-
| `Space` | Toggle the focused extension
|
|
831
|
-
| `x` | Clear the focused
|
|
832
|
-
| `Enter` | Expand or collapse the focused extension's findings
|
|
835
|
+
| `←` / `→` | Show the previous or next section — Extensions, Skills, Settings; the ends stop. |
|
|
836
|
+
| `Space` | Toggle the focused extension or skill; change the focused setting, or open the editor on a text row. |
|
|
837
|
+
| `x` | Clear the focused resource's project override (Extensions and Skills, Project scope). |
|
|
838
|
+
| `Enter` | Expand or collapse the focused extension's findings, or the focused skill's description; change the focused setting, or open the editor on a text row (Settings). |
|
|
833
839
|
| `u` | Delete the focused setting's key so its default applies again (Settings, `bytefly.json` rows). |
|
|
834
840
|
| `J` | Show or hide the focused row's whole section as stored (Settings, `bytefly.json` rows). |
|
|
835
|
-
| `[` / `]` | Jump to the previous or next group (
|
|
841
|
+
| `[` / `]` | Jump to the previous or next group (Extensions and Skills). |
|
|
836
842
|
| `←` / `→`, `Home` / `End` (`Ctrl+A` / `Ctrl+E`) | Move the editor's caret while a text row is being edited. |
|
|
837
843
|
| `Backspace` / `Delete`, `Ctrl+U` | Edit the buffer: delete a character, or clear it. |
|
|
838
844
|
| `Enter` / `Esc` (editing) | Save the buffer, or cancel and restore the stored value. |
|
|
839
|
-
| `Tab` | Switch between Global and Project scope, in
|
|
845
|
+
| `Tab` | Switch between Global and Project scope, in any section. |
|
|
840
846
|
| `r` | Re-probe the doctor (Extensions). |
|
|
841
|
-
| `↑`/`↓`, `j`/`k` | Move the selection, in
|
|
842
|
-
| `PgUp`/`PgDn` | Move a page, in
|
|
843
|
-
| `g` / `G`, `Home` / `End` | Jump to the first or last row, in
|
|
847
|
+
| `↑`/`↓`, `j`/`k` | Move the selection, in any section. |
|
|
848
|
+
| `PgUp`/`PgDn` | Move a page, in any section. |
|
|
849
|
+
| `g` / `G`, `Home` / `End` | Jump to the first or last row, in any section. |
|
|
844
850
|
| `Esc` / `Ctrl+C` | Close the screen. |
|
|
845
851
|
|
|
846
852
|
Mouse wheel scrolling and clicking a row to focus it work; every action also
|
|
@@ -931,7 +937,7 @@ suppresses Pi's own `Package Updates Available` block, and draws one notice for
|
|
|
931
937
|
every row Pi returned.
|
|
932
938
|
|
|
933
939
|
```
|
|
934
|
-
█▀█ Pi v1.3.0
|
|
940
|
+
█▀█ Pi v1.3.0 ↑1.4.0
|
|
935
941
|
█▀ █ enhanced by bytefly v0.11.4 ↑0.12.0
|
|
936
942
|
```
|
|
937
943
|
|
|
@@ -947,9 +953,10 @@ The marker is the shared `↑` glyph and this package's newest version — the a
|
|
|
947
953
|
is one cell wide, so the header's column math is unchanged — painted with the
|
|
948
954
|
header's `accent` role: an action rather than a warning, so the muted version
|
|
949
955
|
beside it stays quiet and the transcript is not turned yellow for a normal state.
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
956
|
+
Pi's own newer version marks the agent line the same way, after `Pi v1.3.0`.
|
|
957
|
+
Other packages never change the header. The marker is part of the identity cell,
|
|
958
|
+
so the two cells still line up, and it is the first thing the identity sheds when
|
|
959
|
+
the terminal narrows.
|
|
953
960
|
|
|
954
961
|
The notice is the shared transcript block: the `bytefly · title` headline at the
|
|
955
962
|
margin, one rail row per package with this package's version arrow or the other
|
|
@@ -957,6 +964,26 @@ package's scope, then the fixing command and this package's release URL, all at
|
|
|
957
964
|
`info` severity because nothing is broken. It stays in scrollback and the model
|
|
958
965
|
reads the same names, version, command, and URL in plain text.
|
|
959
966
|
|
|
967
|
+
Pi's own release takes the same route. Pi resolves its newer version from
|
|
968
|
+
`pi.dev` and would draw a bordered `Update Available` block from
|
|
969
|
+
`InteractiveMode.showNewVersionNotification`; bytefly replaces that method, so
|
|
970
|
+
the release Pi already fetched becomes one shared notice and the agent line's
|
|
971
|
+
marker:
|
|
972
|
+
|
|
973
|
+
```
|
|
974
|
+
bytefly · pi v1.4.0 is available
|
|
975
|
+
╎ ◌ pi · v1.3.0 → v1.4.0
|
|
976
|
+
╎ ◌ update · pi update
|
|
977
|
+
╎ ◌ changelog · https://pi.dev/changelog
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
That notice is bytefly's rendering, not a second check: Pi makes the request and
|
|
981
|
+
resolves the release, and bytefly reads the same answer, including the release's
|
|
982
|
+
optional `note` as a `release notes` row sanitized to one line. `PI_OFFLINE` and
|
|
983
|
+
`PI_SKIP_VERSION_CHECK` keep their Pi meaning, and a host whose method is missing
|
|
984
|
+
or renamed keeps its own block. The patch is process-wide like the package one,
|
|
985
|
+
installed at `session_start` and restored at `session_shutdown`.
|
|
986
|
+
|
|
960
987
|
The list is Pi's decision: npm ranges, git refs, project scope, a missing
|
|
961
988
|
install, and `PI_OFFLINE` all follow its package manager. The only extra read is
|
|
962
989
|
`GET https://registry.npmjs.org/@gavin-hu%2Fmy-pi-agent/latest` when Pi reports
|
|
@@ -1004,18 +1031,23 @@ command.
|
|
|
1004
1031
|
- **Project overrides of app settings are not shown.** App rows read the
|
|
1005
1032
|
personal file; a `.pi/settings.json` override still wins at runtime, and
|
|
1006
1033
|
`pi config` is the place to manage it.
|
|
1007
|
-
- **
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1034
|
+
- **The list is a shortlist, not the whole document.** A row is one boolean,
|
|
1035
|
+
enum, string, or number; the tuning numbers, the labels, and the Pi
|
|
1036
|
+
preferences `/settings` owns stay in their files, and the catalogue is capped
|
|
1037
|
+
at thirteen rows so the screen fits a 24-row terminal. `doctor.skip` (an
|
|
1038
|
+
array), the `rates` table, and `price.peak` (a nested object) could never be a
|
|
1039
|
+
row; the rest are declared JSON-only with their reason in
|
|
1040
|
+
`test/settings-coverage.test.ts`.
|
|
1041
|
+
- **The rail glyph is typed in `bytefly.json`.** It must be exactly one column,
|
|
1011
1042
|
because a two-column glyph would push every railed body one cell right; the
|
|
1012
|
-
former four-glyph menu is
|
|
1013
|
-
|
|
1043
|
+
loader drops anything else, and the former four-glyph menu is the
|
|
1044
|
+
configuration reference's example list.
|
|
1045
|
+
- **`doctor`, `settings`, `skills`, and `update` are reserved first arguments.**
|
|
1014
1046
|
`/bytefly doctor` always selects the report, so an extension literally named
|
|
1015
|
-
`doctor` cannot be narrowed to by name; `settings` and `update` are
|
|
1016
|
-
the same way.
|
|
1017
|
-
- **The picker manages
|
|
1018
|
-
and themes
|
|
1047
|
+
`doctor` cannot be narrowed to by name; `settings`, `skills`, and `update` are
|
|
1048
|
+
reserved the same way.
|
|
1049
|
+
- **The picker manages the `extensions` and `skills` resource types.** Prompts
|
|
1050
|
+
and themes stay with Pi's own `pi config`.
|
|
1019
1051
|
- **Built-in extensions are not listed** (`builtin:mcp`, `builtin:codemode`, …):
|
|
1020
1052
|
their authoritative names are not exposed to extensions. Use `pi config`.
|
|
1021
1053
|
- **Packages are not installed, removed, or updated here**; use `pi install`,
|
|
@@ -1030,16 +1062,19 @@ command.
|
|
|
1030
1062
|
package sources; there is no setting for it, and `/bytefly` and `doctor` do not
|
|
1031
1063
|
report the version. A failed or slow background request is retried by the next
|
|
1032
1064
|
session, or immediately by `/bytefly update`.
|
|
1033
|
-
- **The
|
|
1065
|
+
- **The markers need the bytefly startup TUI.** They live on the custom header,
|
|
1034
1066
|
so with `quietStartup` off the notice is the whole signal.
|
|
1035
|
-
- **Pi's
|
|
1036
|
-
`DefaultPackageManager.prototype.checkForAvailableUpdates`
|
|
1037
|
-
|
|
1038
|
-
|
|
1067
|
+
- **Pi's blocks are suppressed by host shims.** bytefly wraps
|
|
1068
|
+
`DefaultPackageManager.prototype.checkForAvailableUpdates` and
|
|
1069
|
+
`InteractiveMode.prototype.showNewVersionNotification` at `session_start` and
|
|
1070
|
+
restores both on shutdown. A future Pi that changes either method shape makes
|
|
1071
|
+
that shim inert, and Pi's own block can come back.
|
|
1039
1072
|
- **No auto-update, and the release URL is text only.** The notice names a
|
|
1040
1073
|
command instead of running one, and the notice renderer cannot open a link, so
|
|
1041
1074
|
the release row prints the URL and nothing more — no changelog body, no way to
|
|
1042
|
-
click through from the transcript.
|
|
1075
|
+
click through from the transcript. Pi's optional release note arrives as one
|
|
1076
|
+
sanitized `release notes` row, so a multi-paragraph note is flattened and
|
|
1077
|
+
clipped at the width.
|
|
1043
1078
|
- **Project toggles are two-state per press** (`enable`/`disable`). `x` clears
|
|
1044
1079
|
the override, which is the third state; a resource with no project entry in
|
|
1045
1080
|
`pi config` is still managed there.
|
|
@@ -1055,7 +1090,10 @@ command.
|
|
|
1055
1090
|
Anthropic's 2× one-hour cache write are not modelled; switch to `USD` mode
|
|
1056
1091
|
to use Pi's recorded cost for those models.
|
|
1057
1092
|
- **No FX conversion.** The two modes are separate methods; neither converts
|
|
1058
|
-
one currency into the other. A model is priced only by the selected method.
|
|
1093
|
+
one currency into the other. A model is priced only by the selected method. A
|
|
1094
|
+
`CNY` session names the records it could not price instead of silently leaving
|
|
1095
|
+
them out — switch to `USD` for Pi's per-model cost, or add yuan `price.rates`
|
|
1096
|
+
entries for the models you use.
|
|
1059
1097
|
- **Two built-in footer indicators cannot be reproduced.** Pi's `(auto)` marks
|
|
1060
1098
|
that auto-compaction is on, and its `(sub)` marks a subscription-backed
|
|
1061
1099
|
provider. Auto-compaction is session state on Pi's own session object, and
|
|
@@ -1131,12 +1169,12 @@ rather than showing a wrong value.
|
|
|
1131
1169
|
|
|
1132
1170
|
| Integration point | Details |
|
|
1133
1171
|
|---|---|
|
|
1134
|
-
| 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 **Bytefly startup TUI** 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`, and `registerHeader` returns a `refresh()` handle that re-installs the last context's header when
|
|
1172
|
+
| 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 **Bytefly startup TUI** 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. |
|
|
1135
1173
|
| Footer | `ctx.ui.setFooter` with a custom component, replacing Pi's built-in footer; installed only when `ctx.mode === "tui"`. |
|
|
1136
1174
|
| 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. |
|
|
1137
|
-
| Notice | `registerMessageRenderer(NOTICE_TYPE)` draws every shared transcript notice at the margin from its `details`; the headline stays at the margin 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. |
|
|
1175
|
+
| 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. |
|
|
1138
1176
|
| Tool blocks | `registerToolRenderer` returns, for every tool, `renderShell: "self"`; `renderCall` leaves the tool's own first line as the block's headline (a shell prompt shown as the tool name, its command repainted in the body colour, and a primary subject demoted to the body colour) and indents the rest of the call two columns under it, `renderResult` indents its body the same and leads it with the status-coloured rail, and each wraps the tool's own renderer (or a generic fallback). `edit` and `write` carry their result on the call body, so that body is railed too. |
|
|
1139
|
-
| Screen command | `pi.registerCommand("bytefly")` takes `[doctor] [settings] [extension] [refresh]`: `tui` mounts a dock screen via `ctx.ui.custom()` with the rails suppressed; other modes print through `ctx.ui.notify()` — the grouped listing, `run_doctor`'s report for `doctor`, or the
|
|
1177
|
+
| Screen command | `pi.registerCommand("bytefly")` takes `[doctor] [settings] [extension] [refresh]`: `tui` mounts a dock screen via `ctx.ui.custom()` with the rails suppressed; other modes print through `ctx.ui.notify()` — the grouped listing, `run_doctor`'s report for `doctor`, or the flat settings listing with values for `settings`. A named extension is checked against the discovered set before any probe. Tab completes the subcommands, extension names after `doctor`, and `refresh`; `/bytefly settings` rejects a name. |
|
|
1140
1178
|
| Turn separator | `registerEntryRenderer("bytefly-separator")` draws each stored receipt; `agent_start` opens it, top-level `tool_execution_start`/`tool_execution_end` count tools and failures, and `agent_settled` appends `pi.appendEntry("bytefly-separator", { turn, durationMs, tools, failures, aborted })` in `tui` mode only. The receipt fields are omitted when no `agent_start` was seen, so an older or partially observed entry stays `{ turn }`. |
|
|
1141
1179
|
| Working line | `turn_start` starts a 1s tick that drives `ctx.ui.setWorkingMessage` in `tui` mode; before a tool runs the message is `Working… Ns`, and each top-level `tool_execution_start` repaints it as `tool · N tools · Ns` (nested calls carrying `parentToolCallId` are skipped). `agent_end` restores Pi's default and cancels the tick (also on `session_shutdown`). No config file and no persisted state; the count lives in the register's closure. |
|
|
1142
1180
|
| 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. |
|
|
@@ -1146,11 +1184,12 @@ rather than showing a wrong value.
|
|
|
1146
1184
|
| 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. |
|
|
1147
1185
|
| 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. |
|
|
1148
1186
|
| 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. |
|
|
1187
|
+
| Release notice | `session_start` in `tui` mode patches `InteractiveMode.prototype.showNewVersionNotification` through the shared `patchPrototypeMethod`, so the release Pi resolved becomes `pi.sendMessage(piReleaseNotice(...))` under the shared notice type and `paintLatest` records its version for the agent line's marker (`onUpdate` re-installs the header). The callback posts once per load and only while the session is live; a throw calls the captured original, so Pi's own box is the fallback. `session_shutdown` restores the method and clears the marker. |
|
|
1149
1188
|
| 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. |
|
|
1150
1189
|
| 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. |
|
|
1151
1190
|
| Data sources | `footerData.getGitBranch()`, `footerData.getAvailableProviderCount()`, `ctx.getContextUsage()`, `ctx.sessionManager.getEntries()`, `ctx.sessionManager.getSessionName()`, `ctx.model`; subscribes to `footerData.onBranchChange` to repaint. |
|
|
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
|
|
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,
|
|
1191
|
+
| 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, the current reports, and the skill index, and persists extension and skill 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`. |
|
|
1192
|
+
| 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, package-update method, and release-notice method, disposes the branch subscription, drops doctor's cached findings, drops the notify bus subscription, and clears the recorded versions. |
|
|
1154
1193
|
|
|
1155
1194
|
## Design notes
|
|
1156
1195
|
|
|
@@ -1344,7 +1383,7 @@ rather than showing a wrong value.
|
|
|
1344
1383
|
a third layer.** An extension cannot import another extension's modules, so
|
|
1345
1384
|
the only legal home for a shared prerequisite table is `lib/requirements.ts`;
|
|
1346
1385
|
the report itself is a pure function of the probe results.
|
|
1347
|
-
- **The install hint has one home.** `
|
|
1386
|
+
- **The install hint has one home.** `file-read` and `web-access` format their
|
|
1348
1387
|
tool errors from the same `REQUIREMENTS` entries `doctor` prints, so a user
|
|
1349
1388
|
reads the same command whether a tool failed or the report named it.
|
|
1350
1389
|
- **Settings are a curated table, not a schema walker.** The rows cover every
|
|
@@ -1407,18 +1446,19 @@ calculation), `message/` (the user-message marker), `notice/` (the shared notice
|
|
|
1407
1446
|
run line on Pi's working row), `panel/` (the
|
|
1408
1447
|
unified screen and its merged model),
|
|
1409
1448
|
`picker/` (discovery and the settings store), `doctor/` (the `run_doctor` tool
|
|
1410
|
-
and its probe runtime), `notify/`, and `update/` (Pi's package list,
|
|
1411
|
-
|
|
1449
|
+
and its probe runtime), `notify/`, and `update/` (Pi's package list, Pi's own
|
|
1450
|
+
release notice, the host patches, the cache, and the header markers). The chrome and the screen are drawn from
|
|
1412
1451
|
the package's [`lib/tui/`](../../lib/tui/) design system (tokens, rules, rows,
|
|
1413
1452
|
columns, gauge), so the look follows the active theme.
|
|
1414
1453
|
|
|
1415
1454
|
| File | Responsibility |
|
|
1416
1455
|
|---|---|
|
|
1417
|
-
| `index.ts` | Composition root: the disable guard, the
|
|
1456
|
+
| `index.ts` | Composition root: the disable guard, the `register*` calls, the two per-load update stores, the one shared output-pad store, and the rail source. |
|
|
1418
1457
|
| `pad.ts` | `PadSource` and `createPadStore`: one record of Pi's output pad, so the tool frame, the notice, and the turn separator inset by the same margin. |
|
|
1419
1458
|
| `chrome.ts` | The transcript rail (`RAIL_ROLES`, `railGlyph`), the `chrome` section's normalizer and loader, and the `RailSource` that `registerChrome` keeps current on `session_start`/`session_tree`. |
|
|
1420
1459
|
| `header/config.ts` | Header tuning (`HEADER_CONFIG`): mark and identity roles, tagline, and the grouped help entries. |
|
|
1421
|
-
| `header/component.ts` | `ByteflyHeader`: the mark, identity rows
|
|
1460
|
+
| `header/component.ts` | `ByteflyHeader`: the mark, the two identity rows mounted from `identityCells`, signature rule, and grouped help, plus its factory. |
|
|
1461
|
+
| `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. |
|
|
1422
1462
|
| `header/register.ts` | Installs/restores the header and owns its session lifecycle. |
|
|
1423
1463
|
| `footer/register.ts` | Installs/restores the footer and owns its session lifecycle. |
|
|
1424
1464
|
| `footer/config.ts` | Bar tuning (`CONFIG`): thresholds, gauge, separators, icons, status keys, labels. |
|
|
@@ -1429,7 +1469,8 @@ columns, gauge), so the look follows the active theme.
|
|
|
1429
1469
|
| `footer/price/config.ts` | The `price` section of `bytefly.json`: schema, defaults, built-in DeepSeek rates/tariff, currency defaults, normalizer, loader. |
|
|
1430
1470
|
| `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. |
|
|
1431
1471
|
| `footer/price/schedule.ts` | Peak-window parsing and evaluation in a configured zone. |
|
|
1432
|
-
| `footer/price/price.ts` | Records → totals: rated cost in both modes, Pi's recorded cost as USD's fallback, and the
|
|
1472
|
+
| `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. |
|
|
1473
|
+
| `footer/unpriced.ts` | The one notice a CNY session posts for records it could not price, and its OS-notification body. |
|
|
1433
1474
|
| `footer/render/format.ts` | Generic formatters (tokens, cost in the configured currency, cwd, the context role, truncation). |
|
|
1434
1475
|
| `footer/render/status.ts` | Status-chip transforms: `compactStatus` and `dropStatusDetail`. |
|
|
1435
1476
|
| `footer/render/segments.ts` | The segment builders: forms, weights, separators, roles. |
|
|
@@ -1438,7 +1479,7 @@ columns, gauge), so the look follows the active theme.
|
|
|
1438
1479
|
| `footer/render/footer.ts` | `StatusBar` component and footer factory. |
|
|
1439
1480
|
| `message/config.ts` | Nameplate tuning (`MESSAGE_CONFIG`): the label and the rule. |
|
|
1440
1481
|
| `message/format.ts` | Pure `nameplate` and `styleUserMessage`: the two-row nameplate (label over a full-width rule) and its placement above the message. |
|
|
1441
|
-
| `message/register.ts` | Registers the Markdown transformer. |
|
|
1482
|
+
| `message/register.ts` | Registers the Markdown transformer (the nameplate). |
|
|
1442
1483
|
| `notice/config.ts` | Notice tuning (`NOTICE_CONFIG`): source/title/detail roles, the severity glyphs and roles, the shared rail roles, and the item cap. |
|
|
1443
1484
|
| `notice/component.ts` | Pure `noticeLines` and `NoticeComponent`: the headline at the margin, the rail-led severity rows, sanitized and width-clipped. |
|
|
1444
1485
|
| `notice/register.ts` | Registers the message renderer for the shared notice type and hands it the rail source. |
|
|
@@ -1454,19 +1495,29 @@ columns, gauge), so the look follows the active theme.
|
|
|
1454
1495
|
| `working/config.ts` | Counter tuning (`WORKING_CONFIG`): the words, the tool singular/plural, and the tick interval. |
|
|
1455
1496
|
| `working/format.ts` | Pure `formatElapsed` (whole seconds) and the working-message shape: the plain count and the `tool · N tools · elapsed` run line. |
|
|
1456
1497
|
| `working/register.ts` | Starts the tick on `turn_start`, tracks top-level tools on `tool_execution_start`, and cancels on `agent_end`/`session_shutdown`. |
|
|
1457
|
-
| `panel/types.ts` | `PanelSection` (`extensions` | `settings`), `PanelRow`, and `PanelModel`, the merged row model. |
|
|
1458
|
-
| `panel/join.ts` | The item/report union with the unambiguous-name health rule and unique row keys, groups, and ordering. |
|
|
1459
|
-
| `panel/format.ts` | Non-TUI text: the
|
|
1460
|
-
| `panel/settings.ts` | The curated Settings catalogue: descriptors, snapshot views and origins, value cycling, stored-value mapping, validation,
|
|
1498
|
+
| `panel/types.ts` | `PanelSection` (`extensions` | `skills` | `settings`), `PanelRow` with its optional skill info, `SkillInfo`, and `PanelModel`, the merged row model. |
|
|
1499
|
+
| `panel/join.ts` | The item/report union with the unambiguous-name health rule and unique row keys, groups, and ordering; the skills model that labels rows from `SKILL.md`. |
|
|
1500
|
+
| `panel/format.ts` | Non-TUI text: the resource headline and grouped listing with a per-row verdict, the section segments and their order, the Settings counts/headline, and the flat Settings listing. |
|
|
1501
|
+
| `panel/settings.ts` | The curated Settings catalogue: the thirteen descriptors in screen order, snapshot views and origins, value cycling, stored-value mapping, validation, plus the per-section readers that resolve a row's leaf over the global and project documents. |
|
|
1461
1502
|
| `panel/settings-runtime.ts` | The Settings runtime: snapshot cache, scope guards, app setters, per-leaf `bytefly.json` writes, dirty state, and change listeners. |
|
|
1462
1503
|
| `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/
|
|
1464
|
-
| `panel/
|
|
1465
|
-
| `
|
|
1466
|
-
| `
|
|
1504
|
+
| `panel/skills.ts` | Skill metadata through Pi's own `loadSkills`, keyed by resolved path, plus the deduplicated paths both discovery views read. |
|
|
1505
|
+
| `panel/tui.ts` | `PanelComponent`, the three-section dock screen: the section switch, the cursors, the toggle chain, and the two list sections through one `LIST_VIEWS` table. |
|
|
1506
|
+
| `panel/tui/list-view.ts` | The shared list grammar: the section headline, one resource row, and the key-hint row both sections offer. |
|
|
1507
|
+
| `panel/tui/extensions-view.ts` | The Extensions detail pane: the doctor's findings, including the resource path when a row has no verdict. |
|
|
1508
|
+
| `panel/tui/skills-view.ts` | The Skills detail pane: the path, the description, and Pi's refusal. |
|
|
1509
|
+
| `panel/tui/settings-view.ts` | The Settings rows, the value's source and description pane, the JSON pane, and the editing cell. |
|
|
1510
|
+
| `panel/tui/entries.ts` | The flat display entries per section and the stable focus keys. |
|
|
1511
|
+
| `panel/tui/editing.ts` | The text-row editor's key map: caret moves, delete, clear, commit, cancel. |
|
|
1512
|
+
| `panel/tui/frame.ts` | The shared dock frame, the section bar, the detail-row budget, and the optional rows that give way on a short terminal. |
|
|
1513
|
+
| `panel/tui/settings-section.ts` | The Settings section's editor and JSON-pane state, its key handling, and the screen it draws. |
|
|
1514
|
+
| `panel/tui/nav.ts` | The panel's cursor arithmetic and one read of a navigation key. |
|
|
1515
|
+
| `panel/commands.ts` | `/bytefly`: one command for the screen sections, the `doctor` report, the settings and skills listings, and their text modes. |
|
|
1516
|
+
| `picker/types.ts` | Picker host seams (`SettingsStore`, `ResourceResolver`, `Discovery`, `ResourceKind`), the app-settings setters, and row types. |
|
|
1517
|
+
| `picker/resources.ts` | Pure grouping, labels, display names per resource kind, and pattern helpers. |
|
|
1467
1518
|
| `picker/toggle.ts` | Pure next-settings transforms for global and project toggles. |
|
|
1468
|
-
| `picker/discovery.ts` | Host wiring: builds
|
|
1469
|
-
| `picker/runtime.ts` | Picker scope, live view copies, dirty tracking, and persistence. |
|
|
1519
|
+
| `picker/discovery.ts` | Host wiring: builds both kinds' global and effective views from Pi's managers, and the two settings stores for the settings-only command path. |
|
|
1520
|
+
| `picker/runtime.ts` | Picker scope, live view copies, dirty tracking, and persistence, for both resource kinds through one ops table. |
|
|
1470
1521
|
| `doctor/register.ts` | Registers `run_doctor` and the proactive session-start check; returns the runtime. |
|
|
1471
1522
|
| `doctor/runtime.ts` | Host seams, the session cache, and the two probe modes. |
|
|
1472
1523
|
| `doctor/tools.ts` | The `run_doctor` tool and its renderers. |
|
|
@@ -1478,14 +1529,16 @@ columns, gauge), so the look follows the active theme.
|
|
|
1478
1529
|
| `notify/dispatch.ts` | Method selection and delivery: OSC 777/99, Windows toast, `osascript`, `notify-send`, over injected seams. |
|
|
1479
1530
|
| `notify/format.ts` | Pure notification text: session label and the turn / input / job / watch bodies. |
|
|
1480
1531
|
| `notify/register.ts` | Registers the four triggers, loads the config at `session_start`, and owns the job- and watch-bus subscriptions. |
|
|
1481
|
-
| `update/types.ts` | `PackageUpdate`, derived from Pi's public manager method
|
|
1482
|
-
| `update/
|
|
1532
|
+
| `update/types.ts` | `PackageUpdate` and `PackageUpdateCheck`, derived from Pi's public manager method; `PiRelease` and `ReleaseNoticePrototype`, derived from Pi's notification method. |
|
|
1533
|
+
| `update/patch.ts` | `patchPrototypeMethod`: the one host-method replacement both update surfaces use — a per-method `Symbol.for` marker, idempotent reuse, a restore that only puts back its own replacement, and an inert result when the host has no such method. |
|
|
1534
|
+
| `update/suppress.ts` | The two host shims over `patchPrototypeMethod`: capture Pi's `checkForAvailableUpdates` and replace it with an empty result, and hand `showNewVersionNotification`'s release to bytefly (falling back to the captured original if that throws). |
|
|
1483
1535
|
| `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. |
|
|
1484
1536
|
| `update/version.ts` | Pure semver parsing and `isNewerVersion`, including prerelease precedence. |
|
|
1485
|
-
| `update/state.ts` | `UpdateSource` and `createUpdateState` (
|
|
1537
|
+
| `update/state.ts` | `UpdateSource` and `createUpdateState` (one known version per subject per load), `paintLatest` (record and repaint the header only on a change), plus `UpdateOutcome`, the four answers an explicit re-check can give. |
|
|
1486
1538
|
| `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 `
|
|
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. |
|
|
1539
|
+
| `update/format.ts` | `updateMarker`, `updateNotice`, `releaseUrl`, `updateOutcomeText`, and `piReleaseNotice`, plus the shared command/link rows: the header's `↑0.12.0`, the multi-package notice, the line `/bytefly update` prints, and the notice that replaces Pi's `Update Available` box. |
|
|
1540
|
+
| `update/register.ts` | The package-update 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. |
|
|
1541
|
+
| `update/release.ts` | Pi's own release lifecycle: install the notification patch in `tui` mode, record the release's version for the agent-line marker, post the notice once per load while the session is live, and restore the method on shutdown. |
|
|
1489
1542
|
|
|
1490
1543
|
## Testing
|
|
1491
1544
|
|
|
@@ -1517,10 +1570,12 @@ transforms (`picker/toggle`), discovery with an injected factory
|
|
|
1517
1570
|
unified screen is covered by its pure model merge (`panel/join`), its text
|
|
1518
1571
|
formatter (`panel/format`), the settings catalogue and its cycling
|
|
1519
1572
|
(`panel/settings`), the scope-aware settings runtime (`panel/settings-runtime`,
|
|
1520
|
-
including a nested leaf write that keeps its siblings),
|
|
1521
|
-
|
|
1522
|
-
the
|
|
1523
|
-
the
|
|
1573
|
+
including a nested leaf write that keeps its siblings), the skill metadata join
|
|
1574
|
+
and loader (`panel/skills`, on real `SKILL.md` files),
|
|
1575
|
+
the screen's rendering (`panel/tui`), its list grammar (`tui/list-view`), the
|
|
1576
|
+
Skills pane (`tui/skills-view`), the Settings section state (`tui/settings-section`),
|
|
1577
|
+
its editing key map (`tui/editing`), the shared frame (`tui/frame`), and the
|
|
1578
|
+
command through the bytefly factory (`panel/commands`).
|
|
1524
1579
|
The doctor surface is covered by its pure report
|
|
1525
1580
|
formatting (`doctor/format`), its config loader (`doctor/config`), and
|
|
1526
1581
|
registration, the proactive notice, the session cache, and `run_doctor`
|