@gavin-hu/my-pi-agent 0.16.0 → 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.
Files changed (135) hide show
  1. package/README.md +14 -8
  2. package/README.zh-CN.md +14 -9
  3. package/extensions/bytefly/README.md +174 -101
  4. package/extensions/bytefly/footer/collect/entries.ts +1 -6
  5. package/extensions/bytefly/footer/collect/snapshot.ts +23 -9
  6. package/extensions/bytefly/footer/price/price.ts +12 -8
  7. package/extensions/bytefly/footer/register.ts +13 -1
  8. package/extensions/bytefly/footer/types.ts +11 -0
  9. package/extensions/bytefly/footer/unpriced.ts +36 -0
  10. package/extensions/bytefly/header/component.ts +15 -29
  11. package/extensions/bytefly/header/identity.ts +71 -0
  12. package/extensions/bytefly/header/register.ts +9 -3
  13. package/extensions/bytefly/index.ts +13 -5
  14. package/extensions/bytefly/message/format.ts +20 -13
  15. package/extensions/bytefly/message/register.ts +8 -7
  16. package/extensions/bytefly/panel/commands.ts +46 -25
  17. package/extensions/bytefly/panel/format.ts +49 -14
  18. package/extensions/bytefly/panel/join.ts +35 -9
  19. package/extensions/bytefly/panel/settings.ts +10 -27
  20. package/extensions/bytefly/panel/skills.ts +51 -0
  21. package/extensions/bytefly/panel/tui/extensions-view.ts +7 -61
  22. package/extensions/bytefly/panel/tui/frame.ts +9 -1
  23. package/extensions/bytefly/panel/tui/list-view.ts +72 -0
  24. package/extensions/bytefly/panel/tui/nav.ts +71 -3
  25. package/extensions/bytefly/panel/tui/settings-section.ts +250 -0
  26. package/extensions/bytefly/panel/tui/skills-view.ts +50 -0
  27. package/extensions/bytefly/panel/tui.ts +223 -331
  28. package/extensions/bytefly/panel/types.ts +26 -8
  29. package/extensions/bytefly/picker/discovery.ts +32 -27
  30. package/extensions/bytefly/picker/resources.ts +16 -8
  31. package/extensions/bytefly/picker/runtime.ts +62 -34
  32. package/extensions/bytefly/picker/toggle.ts +16 -10
  33. package/extensions/bytefly/picker/types.ts +31 -13
  34. package/extensions/bytefly/update/format.ts +66 -8
  35. package/extensions/bytefly/update/patch.ts +66 -0
  36. package/extensions/bytefly/update/register.ts +4 -11
  37. package/extensions/bytefly/update/release.ts +65 -0
  38. package/extensions/bytefly/update/state.ts +14 -0
  39. package/extensions/bytefly/update/suppress.ts +47 -29
  40. package/extensions/bytefly/update/types.ts +15 -5
  41. package/extensions/check/tui.ts +2 -0
  42. package/extensions/context/README.md +21 -11
  43. package/extensions/context/format.ts +10 -8
  44. package/extensions/context/report.ts +21 -8
  45. package/extensions/context/tui.ts +26 -10
  46. package/extensions/context/types.ts +5 -3
  47. package/extensions/file-browse/README.md +29 -1
  48. package/extensions/file-browse/client.ts +16 -463
  49. package/extensions/file-browse/html.ts +7 -5
  50. package/extensions/file-browse/palette.ts +224 -0
  51. package/extensions/file-browse/router.ts +2 -2
  52. package/extensions/file-browse/styles.ts +8 -3
  53. package/extensions/file-browse/tree.ts +381 -0
  54. package/extensions/file-read/README.md +4 -1
  55. package/extensions/file-read/extract/odt.ts +7 -5
  56. package/extensions/goal/tools.ts +6 -11
  57. package/extensions/job/index.ts +20 -45
  58. package/extensions/job/tools.ts +51 -77
  59. package/extensions/memory/tools.ts +4 -6
  60. package/extensions/memory/tui.ts +5 -1
  61. package/extensions/plan/README.md +88 -33
  62. package/extensions/plan/commands.ts +19 -4
  63. package/extensions/plan/config.ts +27 -0
  64. package/extensions/plan/plan-index.ts +3 -1
  65. package/extensions/plan/plans.ts +31 -13
  66. package/extensions/plan/review.ts +34 -14
  67. package/extensions/plan/runtime.ts +3 -1
  68. package/extensions/plan/steps.ts +43 -14
  69. package/extensions/plan/tools/cancel.ts +79 -0
  70. package/extensions/plan/tools/enter.ts +10 -10
  71. package/extensions/plan/tools/exit.ts +54 -43
  72. package/extensions/plan/tools/steps.ts +7 -19
  73. package/extensions/plan/tools/write.ts +22 -29
  74. package/extensions/plan/tools.ts +5 -2
  75. package/extensions/plan/tui.ts +9 -7
  76. package/extensions/plan/types.ts +8 -0
  77. package/extensions/plan/web-chrome.ts +101 -0
  78. package/extensions/plan/web-client.ts +98 -311
  79. package/extensions/plan/web-markdown.ts +222 -0
  80. package/extensions/plan/web-page.ts +28 -2
  81. package/extensions/plan/web-router.ts +2 -2
  82. package/extensions/rewind/checklist.ts +4 -0
  83. package/extensions/rewind/review-tui.ts +3 -1
  84. package/extensions/rewind/rewind-tui.ts +4 -0
  85. package/extensions/subagent/README.md +25 -12
  86. package/extensions/subagent/format.ts +72 -25
  87. package/extensions/subagent/index.ts +21 -47
  88. package/extensions/subagent/orchestrate.ts +18 -41
  89. package/extensions/subagent/render.ts +29 -42
  90. package/extensions/subagent/stream.ts +24 -18
  91. package/extensions/subagent/types.ts +7 -0
  92. package/extensions/todo/tools.ts +5 -6
  93. package/extensions/todo/tui.ts +5 -1
  94. package/extensions/watch/index.ts +10 -35
  95. package/extensions/watch/tools.ts +31 -59
  96. package/extensions/wechat/README.md +40 -18
  97. package/extensions/wechat/bridge.ts +38 -40
  98. package/extensions/wechat/client.ts +1 -4
  99. package/extensions/wechat/commands.ts +1 -1
  100. package/extensions/wechat/interaction.ts +25 -4
  101. package/extensions/wechat/login-screen.ts +2 -3
  102. package/extensions/wechat/notices.ts +7 -5
  103. package/extensions/wechat/prompt.ts +19 -4
  104. package/extensions/wechat/qrcode.ts +9 -9
  105. package/extensions/wechat/slash.ts +14 -0
  106. package/extensions/wechat/status-screen.ts +2 -2
  107. package/extensions/wechat/tools.ts +3 -11
  108. package/extensions/worktree/README.md +48 -12
  109. package/extensions/worktree/commands.ts +109 -65
  110. package/extensions/worktree/enter.ts +1 -1
  111. package/extensions/worktree/exit.ts +11 -1
  112. package/extensions/worktree/lifecycle.ts +9 -1
  113. package/extensions/worktree/screen.ts +263 -0
  114. package/extensions/worktree/status.ts +84 -38
  115. package/lib/README.md +7 -6
  116. package/lib/config.ts +12 -0
  117. package/lib/format.ts +6 -2
  118. package/lib/interaction.ts +18 -1
  119. package/lib/report.ts +75 -2
  120. package/lib/tool-result.ts +54 -4
  121. package/lib/tui/README.md +16 -8
  122. package/lib/tui/chrome.ts +27 -6
  123. package/lib/tui/dock-screen.ts +6 -2
  124. package/lib/tui/gauge.ts +9 -5
  125. package/lib/usage.ts +26 -0
  126. package/lib/web/README.md +131 -0
  127. package/lib/web/base.ts +19 -2
  128. package/lib/web/components.ts +10 -6
  129. package/lib/web/layout.ts +2 -0
  130. package/lib/web/markup.ts +2 -1
  131. package/lib/web/runtime.ts +103 -25
  132. package/lib/web/tokens.ts +23 -7
  133. package/package.json +3 -1
  134. package/skills/changelog/SKILL.md +57 -45
  135. package/skills/next/SKILL.md +184 -0
@@ -16,7 +16,7 @@ import type { CompactionResult, Theme } from "@earendil-works/pi-coding-agent";
16
16
  import { truncateToWidth, visibleWidth, type Component } from "@earendil-works/pi-tui";
17
17
  import { messageOf } from "../../lib/errors.ts";
18
18
  import { formatTokens } from "../../lib/format.ts";
19
- import { screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
19
+ import { screenFooter, screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
20
20
  import { ConfirmState } from "../../lib/tui/confirm.ts";
21
21
  import { clampScroll, fitRows, formatRange, isCloseKey, navigateScroll } from "../../lib/tui/cursor.ts";
22
22
  import { gaugeBar, gaugeRole } from "../../lib/tui/gauge.ts";
@@ -26,7 +26,7 @@ import { paint, type TuiRole } from "../../lib/tui/tokens.ts";
26
26
  import { formatBudget, formatCompaction, formatDrift } from "./format.ts";
27
27
  import type { ContextBucket, ContextReport } from "./types.ts";
28
28
 
29
- /** Fixed rows around the scrollable body: title, gauge, budget, blank, blank, footer, blank. */
29
+ /** Fixed rows around the scrollable body: title, gauge, budget, blank, blank, footer, closing rule. */
30
30
  const CHROME_ROWS = 7;
31
31
 
32
32
  /** Cells in the composition bar. */
@@ -137,16 +137,28 @@ export class ContextComponent implements Component {
137
137
  const { percent, tokens, window } = this.report;
138
138
  if (window <= 0) return truncateToWidth(` ${paint(this.theme, "meta", "no model context window")}`, width);
139
139
  const role = gaugeRole(percent);
140
+ // The bar and the printed percentage come from one rounded value, so a
141
+ // label reading `0%` can never sit beside a filled cell. The tone stays on
142
+ // the exact percent, so the warn and danger thresholds do not move.
143
+ const shown = percent === null ? null : Math.round(percent);
140
144
  const value = tokens === null ? `? / ${formatTokens(window)}` : `${formatTokens(tokens)} / ${formatTokens(window)}`;
141
- const bar = gaugeBar(this.theme, { percent, blocks: 10 });
142
- const label = percent === null ? "unknown" : `${Math.round(percent)}%`;
145
+ const bar = gaugeBar(this.theme, { percent: shown, blocks: 10 });
146
+ const label = shown === null ? "unknown" : `${shown}%`;
143
147
  return truncateToWidth(` ${paint(this.theme, role, value)} ${bar} ${paint(this.theme, role, label)}`, width);
144
148
  }
145
149
 
150
+ /** The composition header: the denominator the percent column is a share of. */
151
+ private compositionLine(width: number): string {
152
+ const label = paint(this.theme, "label", "Composition");
153
+ const total = paint(this.theme, "meta", `${formatTokens(this.report.estimate)} estimate`);
154
+ const full = ` ${label} · ${total}`;
155
+ return visibleWidth(full) <= width ? full : truncateToWidth(` ${label}`, width);
156
+ }
157
+
146
158
  /** One composition row; optional columns drop as the terminal narrows. */
147
159
  private bucketLine(bucket: ContextBucket, width: number): string {
148
160
  const indent = " ".repeat(bucket.depth > 0 ? 4 : 2);
149
- const labelWidth = bucket.depth > 0 ? 16 : 18;
161
+ const labelWidth = bucket.depth > 0 ? 20 : 22;
150
162
  const label = padCell(bucket.label, labelWidth);
151
163
  const tokens = formatTokens(bucket.tokens).padStart(6);
152
164
  const share = shareCell(bucket.share);
@@ -167,13 +179,17 @@ export class ContextComponent implements Component {
167
179
  return truncateToWidth(head, width);
168
180
  }
169
181
 
170
- /** The scrollable body: composition, drift, compaction, and the largest blocks. */
182
+ /** The scrollable body: composition, drift, compaction, and the largest messages. */
171
183
  private buildBody(width: number): string[] {
172
184
  const report = this.report;
173
- const lines: string[] = report.buckets.map((bucket) => this.bucketLine(bucket, width));
185
+ const lines: string[] = [];
186
+ if (report.buckets.length > 0) {
187
+ lines.push(this.compositionLine(width));
188
+ for (const bucket of report.buckets) lines.push(this.bucketLine(bucket, width));
189
+ }
174
190
 
175
191
  const drift = formatDrift(report);
176
- if (drift) lines.push("", truncateToWidth(` ${paint(this.theme, "warn", drift)}`, width));
192
+ if (drift) lines.push("", truncateToWidth(` ${paint(this.theme, "meta", drift)}`, width));
177
193
 
178
194
  lines.push(
179
195
  "",
@@ -184,7 +200,7 @@ export class ContextComponent implements Component {
184
200
  );
185
201
 
186
202
  if (report.largest.length > 0) {
187
- lines.push("", ` ${paint(this.theme, "label", "Largest blocks")}`);
203
+ lines.push("", ` ${paint(this.theme, "label", "Largest messages")}`);
188
204
  for (const block of report.largest) {
189
205
  const tokens = formatTokens(block.tokens).padStart(6);
190
206
  const role = padCell(block.role, 11);
@@ -230,7 +246,7 @@ export class ContextComponent implements Component {
230
246
  if (this.body.length > this.visible) {
231
247
  lines.push(formatRange(this.theme, w, { start: this.scroll, end, total: this.body.length }));
232
248
  }
233
- lines.push("", this.footerLine(w), "");
249
+ lines.push(...screenFooter(this.theme, w, this.footerLine(w)));
234
250
  return lines.map((line) => truncateToWidth(line, w));
235
251
  }
236
252
 
@@ -79,7 +79,7 @@ export interface CompactionHistory {
79
79
  last: CompactionSummary | null;
80
80
  }
81
81
 
82
- /** One of the largest single blocks in the projected context. */
82
+ /** One of the largest single messages in the projected context. */
83
83
  export interface LargestBlock {
84
84
  /** Estimated tokens. */
85
85
  tokens: number;
@@ -99,7 +99,7 @@ export interface ContextReport {
99
99
  percent: number | null;
100
100
  /** `window - tokens`, `null` when `tokens` is unknown. */
101
101
  free: number | null;
102
- /** `window - reserve - tokens`, `null` when `tokens` is unknown. */
102
+ /** `window - reserve - tokens`, `null` when `tokens` is unknown or automatic compaction is off. */
103
103
  headroom: number | null;
104
104
  /** The resolved `reserveTokens` for the active model. */
105
105
  reserve: number;
@@ -115,8 +115,10 @@ export interface ContextReport {
115
115
  estimate: number;
116
116
  /** `tokens - estimate` when the host's estimate is known, else `null`. */
117
117
  drift: number | null;
118
+ /** True when the projection holds no assistant message: Pi's total is its message-only fallback. */
119
+ beforeFirstReply: boolean;
118
120
  /** The branch's compaction history. */
119
121
  compaction: CompactionHistory;
120
- /** The largest projected blocks, biggest first. */
122
+ /** The largest projected messages, biggest first. */
121
123
  largest: LargestBlock[];
122
124
  }
@@ -147,6 +147,32 @@ nothing is left to serve. That is why a page with JavaScript off — or with liv
147
147
  status off — never counts as a reader, and the server then waits for
148
148
  `/browse stop` or the end of the session.
149
149
 
150
+ ### The page
151
+
152
+ The page is keyboard-first, and the tree is one tab stop rather than two per
153
+ folder:
154
+
155
+ | Key | What it does in the tree |
156
+ |---|---|
157
+ | `↑` / `↓` | Move between the rows on screen |
158
+ | `→` | Open a folder (reading its children first if needed), or enter it |
159
+ | `←` | Close the folder, or step out to its parent |
160
+ | `Space` | Open or close the focused folder |
161
+ | `Enter` | Follow the focused row's link |
162
+ | `Home` / `End` | First or last row on screen |
163
+
164
+ The folder's own link carries `aria-expanded`, so a screen reader hears its
165
+ state once; the twisty beside it is a pointer control kept out of the tab order.
166
+ A mouse click moves the tab stop to that row, so `Tab` comes back to where you
167
+ were. Elsewhere the page keeps its own keys: `/` or `Ctrl`/`Cmd`+`K` for quick
168
+ open, `-` to fold, `u` to wrap, `r` for raw Markdown, `n`/`p` between diff hunks,
169
+ and `?` for the sheet, whose dialog now traps `Tab` and returns focus to its
170
+ button.
171
+
172
+ Printing is supported: the paper gets the light palette whatever the screen is
173
+ showing, the chrome and the tree are dropped, and a file or diff prints whole
174
+ instead of inside its scroll box.
175
+
150
176
  ## Routes
151
177
 
152
178
  | Route | Result |
@@ -399,7 +425,9 @@ document and the project document (project wins):
399
425
  | `urls.ts` | Shared link/image URL policy: scheme allowlist and `/view`/`/raw` rewriting |
400
426
  | `git.ts` | Read-only branch/dirty provider for the header chip |
401
427
  | `icons.ts` | Inline SVG sprite and the per-language mapping |
402
- | `client.ts` | The `/app.js` source (tree toggle, filter, sort, wrap, copy, quick open) |
428
+ | `client.ts` | The `/app.js` source: sort, wrap, copy, hunk navigation, reading progress, and the page keymap |
429
+ | `tree.ts` | The sidebar block: path filter, fold-all, lazy tree loading, and the tree's keyboard model (interpolated into `client.ts`) |
430
+ | `palette.ts` | The quick-open palette: fuzzy search, the combobox wiring, and the `window.bfPalette` contract (interpolated into `client.ts`) |
403
431
  | `live-client.ts` | The client's live status block: the event stream, the chips, the markers, and the footer line (interpolated into `client.ts`) |
404
432
  | `live.ts` | The live status snapshot, its frame, and the fan-out channel that ticks it |
405
433
  | `styles.ts` | The page-only `browse-*` stylesheet (the `bf-*` kit comes from `lib/web`) |