@andares/pi-toolkits 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,12 +9,12 @@
9
9
  [![npm version](https://img.shields.io/npm/v/@andares/pi-toolkits?label=npm&logo=npm)](https://www.npmjs.com/package/@andares/pi-toolkits)
10
10
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
11
  [![Package Manager](https://img.shields.io/badge/package%20manager-pnpm-orange?logo=pnpm)](https://pnpm.io)
12
- [![pi >= 0.86](https://img.shields.io/badge/pi-%3E%3D0.86.0%20%3C2.0.0-blueviolet)](https://github.com/earendil-works/pi)
12
+ [![pi >= 0.87](https://img.shields.io/badge/pi-%3E%3D0.87.0%20%3C2.0.0-blueviolet)](https://github.com/earendil-works/pi)
13
13
  [![GitHub](https://img.shields.io/badge/github-andares%2Fpi--toolkits-181717?logo=github)](https://github.com/andares/pi-toolkits)
14
14
 
15
15
  In a nutshell: six ready-to-use capabilities — **read-only consult mode** `ask`, **model favorites** `favorites`, **prompt stash** `stash`, **third-party code review** `third-review`, **dedicated compaction model** `compact-model` and **session startup automation** `autostart` — with more to come.
16
16
 
17
- **Requirements**: pi `>=0.86.0 <2.0.0` (covering the four most recently released minor lines — 0.86.x / 0.87.x / 0.99.x / 1.0.x; 0.88–0.98 were never released). Every one of the 10 published versions inside that range was compared against the host `dist`: no differences in the extension APIs we use, and the two runtime patch targets used by favorites — `ModelSelectorComponent` / `AgentSession.cycleModel` — are byte-identical. `typecheck` plus the full test suite pass on each of 0.86.0, 0.86.1, 0.87.1, 0.99.2 and 1.0.2, and smoke-loading on real pi 1.0.2 produces no warnings. Note: pi ≥ 0.99 hosts require `@earendil-works/pi-tui` to be declared in `peerDependencies` as `"*"` (provided by the host); this package declares it as required.
17
+ **Requirements**: pi `>=0.87.0 <2.0.0` (covering the four most recently released minor lines — 0.87.x / 0.99.x / 1.0.x / 1.1.x; 0.88–0.98 were never released). Every one of the 11 published versions inside that range (0.87.0 → 1.1.0) was compared against the host `dist`: the extension APIs we use carry no breaking differences (1.0.4 → 1.1.0 only adds fields), and the two runtime patch targets used by favorites — `ModelSelectorComponent` / `AgentSession.cycleModel` — are byte-identical. `typecheck` plus the full test suite pass on each of 0.87.0, 0.87.1, 0.99.0, 0.99.2, 1.0.0, 1.0.4 and 1.1.0, and smoke-loading on real pi 1.1.0 produces no warnings. Note: pi ≥ 0.99 hosts require `@earendil-works/pi-tui` to be declared in `peerDependencies` as `"*"` (provided by the host); this package declares it as required.
18
18
 
19
19
  ---
20
20
 
@@ -36,7 +36,7 @@ pi -e ./src/index.ts
36
36
  After installing, verify in any pi session:
37
37
 
38
38
  - `/ask` → a grey `ask` status appears in the footer, `write`/`edit` are hard-disabled
39
- - `/model` (or `ctrl+l`) → a favorites hint line appears at the top of the selector
39
+ - `/model` (or `ctrl+l`) → a favorites hint line appears at the top of the selector; `ctrl+A` on the selected model → it turns bold bright yellow and the favorites counter goes up (this step is also the real-machine keypress check — see Keybindings)
40
40
  - press `ctrl+alt+y` in the input box → the current prompt is stashed and the input box is cleared
41
41
  - after finishing a development task, type `/third-review` → switches to the review model and runs check + fix
42
42
  - `/compact-model`, pick a cheap fast model → from then on both `/compact` and auto-compaction summarize with it (a grey `compact` status appears in the footer)
@@ -66,7 +66,7 @@ After installing, verify in any pi session:
66
66
  | Feature | Entry point | One-line description |
67
67
  | --- | --- | --- |
68
68
  | 🛡️ **ask** read-only consult mode | `/ask` | enter read-only Q&A mode: `write`/`edit` hard-disabled, `bash` runs in a read-only sandbox |
69
- | ⭐ **favorites** model favorites | `ctrl+alt+F` / `ctrl+J` inside `/model` | favorite the models you use most (marked in bold bright yellow), `ctrl+p` cycles only among favorites |
69
+ | ⭐ **favorites** model favorites | `ctrl+A` / `ctrl+J` inside `/model` | favorite the models you use most (marked in bold bright yellow), `ctrl+p` cycles only among favorites |
70
70
  | 📥 **stash** prompt stash | `ctrl+alt+y` | a stash slot for one prompt: press to swap, press twice to stash and clear the input box |
71
71
  | 🔎 **review** third-party code review | `/third-review` | summon the configured review model to check + fix the task just finished, focusing on "is this round's requirement implemented / is anything missing / is anything wrong" |
72
72
  | 🗜️ **compact** dedicated compaction model | `/compact-model` | give `/compact` and auto-compact a cheap fast model to summarize with, leaving the main model free to focus on the conversation; zero overhead when unconfigured, falls back to pi's default on any failure |
@@ -100,7 +100,7 @@ Mark the models you use often so that model switching "sticks" to them. Favorite
100
100
  **Inside the `/model` selector** (open it with `/model` or `ctrl+l`):
101
101
 
102
102
  - The top hint line shows the keys and the current filter state
103
- - `ctrl+alt+F` — toggle the favorite flag on the currently selected model; favorite models are rendered in **bold bright yellow**
103
+ - `ctrl+A` — toggle the favorite flag on the currently selected model; favorite models are rendered in **bold bright yellow**
104
104
  - `ctrl+J` — toggle the "show only favorite models" filter (composable with the built-in search)
105
105
 
106
106
  **Model cycling**: as long as ≥1 favorite exists, `ctrl+p` / `ctrl+shift+p` cycle **only among favorite models**. When the current model is not a favorite, `ctrl+p` jumps to the first favorite and `ctrl+shift+p` to the last; with exactly one favorite it stays put (`Only one model available`). `ctrl+l` / `/model` always allow picking any model freely, favorites or not. Set `"cycleOnlyFavorites": false` in the state file to restore full cycling.
@@ -116,9 +116,9 @@ Mark the models you use often so that model switching "sticks" to them. Favorite
116
116
 
117
117
  The `/favorites` command lists the current favorites and the cycling mode.
118
118
 
119
- > **Implementation notes**: pi's `app.model.cycleForward` (`ctrl+p`) and `cycleBackward` are **reserved keybindings** that extension shortcuts cannot override; extension shortcuts also only fire while the editor is focused. This feature therefore rebinds nothing; instead it patches two built-in prototypes at runtime (version-guarded, idempotent under `/reload`): `ModelSelectorComponent` (hint line, `ctrl+alt+F`/`ctrl+J`, bright-yellow rendering, favorites-only filter — the keys are consumed only inside the selector, so in the editor `ctrl+j` still inserts a newline) and `AgentSession.cycleModel` (favorites-only cycling). If a pi upgrade makes the patch inapplicable, it warns and degrades gracefully without affecting the other features.
119
+ > **Implementation notes**: pi's `app.model.cycleForward` (`ctrl+p`) and `cycleBackward` are **reserved keybindings** that extension shortcuts cannot override; extension shortcuts also only fire while the editor is focused. This feature therefore rebinds nothing; instead it patches two built-in prototypes at runtime (version-guarded, idempotent under `/reload`): `ModelSelectorComponent` (hint line, `ctrl+A`/`ctrl+J`, bright-yellow rendering, favorites-only filter — the keys are consumed only inside the selector, so in the editor `ctrl+j` still inserts a newline) and `AgentSession.cycleModel` (favorites-only cycling). If a pi upgrade makes the patch inapplicable, it warns and degrades gracefully without affecting the other features.
120
120
  >
121
- > **Why `ctrl+alt+F` and not `ctrl+F`**: since pi 1.0 the default `tuiMode` is `fullscreen` (0.86–0.99 defaulted to `regular`), and on Windows/WSL the host resolves `tui.altScreen.search` to `ctrl+f`; `TuiAltScreen.handleViewportInput()` checks that binding **before** handing input to the focused overlay, so `ctrl+f` opened the transcript search instead of reaching the selector. `alt+f`, `shift+f` and `ctrl+shift+f` are all taken or unreliable as well — see `src/features/favorites/constants.ts` and `pnpm check:keybindings`.
121
+ > **Why `ctrl+A` and not `ctrl+F`**: since pi 1.0 the default `tuiMode` is `fullscreen` (0.87–0.99 defaulted to `regular`), and on Windows/WSL the host resolves `tui.altScreen.search` to `ctrl+f`; `TuiAltScreen.handleViewportInput()` checks that binding **before** handing input to the focused overlay, so `ctrl+f` opened the transcript search instead of reaching the selector. An interim pick, `ctrl+alt+f`, was clean at the pi layer but turned out to be grabbed by a Windows screenshot tool — a key free in the host table is not necessarily free on the machine. The final pick takes a letter from "favorite" and audits each: `v` is Windows Terminal's paste, `o`/`r`/`t` are host app actions, `i` is byte-identical to Tab (the selector's scope toggle), `e` works but carries no mnemonic; `a` only shadows the search box's jump-to-line-start, reads as *add favorite*, and nothing upstream of the selector claims it. Full audit: `src/features/favorites/constants.ts` and `pnpm check:keybindings`.
122
122
 
123
123
  ---
124
124
 
@@ -195,7 +195,7 @@ pi's `/compact` and auto-compact summarize the context **with the current sessio
195
195
  | auto-compact threshold reached | summarized by the compaction model |
196
196
  | context overflow recovery | summarized by the compaction model, retry behavior unchanged |
197
197
 
198
- **Parts that are identical to pi's built-in behavior after takeover** (the built-in implementation is mirrored verbatim — byte-identical since 0.87.1, verified up to 1.0.2 — and only the executing model changes):
198
+ **Parts that are identical to pi's built-in behavior after takeover** (the built-in implementation is mirrored verbatim — byte-identical since 0.87.1, verified up to 1.1.0; 0.87.0 shipped an earlier split-turn prompt, and the mirror carries the 0.87.1 fix for every host — and only the executing model changes):
199
199
 
200
200
  - **Summary format** — the structured Goal / Progress / Key Decisions checkpoint; when a summary already exists, the iterative-update prompt is used so information carries over instead of being lost
201
201
  - **Split behavior** — the `keepRecentTokens` retention policy, and `firstKeptEntryId` / `tokensBefore` passed back unchanged
@@ -262,7 +262,7 @@ No file = feature disabled, zero overhead, silently skipped.
262
262
 
263
263
  **Key constraint: extension commands only**. Commands registered via `registerCommand` such as `/add-dir` (pi-add-dir) and `/cd` (pi-cd) work; built-in commands (`/compact`, `/reload`, `/resume`, …) are dispatched in the TUI layer and cannot be triggered from the extension layer; skill commands (`/skill:name`) are an expansion mechanism rather than an execution mechanism. The target extension you depend on (e.g. pi-add-dir) must be installed first.
264
264
 
265
- > **Implementation notes**: execution uses `sendUserMessage(cmd, { expandPromptTemplates: true })` — that option routes `/cmd args` into command dispatch instead of the model prompt path (the wrapper defaults to `false`; verified against pi 0.86–1.0.4 sources, see the host-compatibility discipline in AGENTS.md). Pre-validation uses `pi.getCommands()` (accepting only `source: "extension"`). Depends on `smol-toml` (zero-dependency, ~10KB, TOML 1.0).
265
+ > **Implementation notes**: execution uses `sendUserMessage(cmd, { expandPromptTemplates: true })` — that option routes `/cmd args` into command dispatch instead of the model prompt path (the wrapper defaults to `false`; verified against pi 0.87.0–1.1.0 sources, see the host-compatibility discipline in AGENTS.md). Pre-validation uses `pi.getCommands()` (accepting only `source: "extension"`). Depends on `smol-toml` (zero-dependency, ~10KB, TOML 1.0).
266
266
 
267
267
  ---
268
268
 
@@ -326,7 +326,7 @@ PRs and issues welcome. A few conventions:
326
326
  - **Tests** — every feature ships vitest cases; keep them deterministic (injectable clocks/state), no writes to the real agent dir
327
327
  - **Built-in patches** (favorites) must stay **version-guarded and idempotent** — verify the target prototype members exist before patching, guard against double-apply, degrade with a `console.warn` instead of breaking the extension
328
328
  - **Built-in prompt sync** (compact) — the summarization prompts in `src/features/compact/prompt.ts` are copied verbatim from pi's built-in compaction; when upgrading the pi dependency, diff `dist/core/compaction/compaction.js` (and `utils.js`) and update the strings + assembly helpers to match, keeping takeover output byte-compatible with stock
329
- - **Keybindings** — before picking a new shortcut, check pi defaults + reserved keys, terminal control chars, and OS/terminal-emulator grabs; prefer `ctrl+alt+<letter>` for cross-platform safety. Do not stop at "it works on my machine in the main screen": in `fullscreen` mode (pi's default since 1.0) the alt-screen layer consumes `tui.altScreen.*` **before** dialogs see the key, and on Windows/WSL several of those bindings differ from the Linux defaults. Run `pnpm check:keybindings [candidate...]` (and `pnpm check:keybindings --all` after a pi upgrade) — it probes the installed host's resolved keybinding table with the host's own `matchesKey`.
329
+ - **Keybindings** — before picking a new shortcut, check pi defaults + reserved keys, terminal control chars, and OS/terminal-emulator grabs; prefer `ctrl+alt+<letter>` for cross-platform safety. Do not stop at "it works on my machine in the main screen": in `fullscreen` mode (pi's default since 1.0) the alt-screen layer consumes `tui.altScreen.*` **before** dialogs see the key, and on Windows/WSL several of those bindings differ from the Linux defaults. Run `pnpm check:keybindings [candidate...]` (and `pnpm check:keybindings --all` after a pi upgrade) — it probes the installed host's resolved keybinding table with the host's own `matchesKey`. A key free in the host table can still be taken at the machine layer: Windows Terminal binds `ctrl+v` (paste) and `ctrl+shift+f` (find), and third-party Windows tools commonly grab `ctrl+alt+<letter>` (a screenshot tool once took `ctrl+alt+f`) — so try the key for real on the target machine before shipping it.
330
330
  - **Quality gate** — `pnpm typecheck && pnpm test` must pass before submitting
331
331
 
332
332
  ---
package/README.zh-CN.md CHANGED
@@ -9,12 +9,12 @@
9
9
  [![npm version](https://img.shields.io/npm/v/@andares/pi-toolkits?label=npm&logo=npm)](https://www.npmjs.com/package/@andares/pi-toolkits)
10
10
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
11
11
  [![Package Manager](https://img.shields.io/badge/package%20manager-pnpm-orange?logo=pnpm)](https://pnpm.io)
12
- [![pi >= 0.86](https://img.shields.io/badge/pi-%3E%3D0.86.0%20%3C2.0.0-blueviolet)](https://github.com/earendil-works/pi)
12
+ [![pi >= 0.87](https://img.shields.io/badge/pi-%3E%3D0.87.0%20%3C2.0.0-blueviolet)](https://github.com/earendil-works/pi)
13
13
  [![GitHub](https://img.shields.io/badge/github-andares%2Fpi--toolkits-181717?logo=github)](https://github.com/andares/pi-toolkits)
14
14
 
15
15
  一句话介绍:目前包含六个开箱即用的功能——**只读咨询模式** `ask`、**模型收藏** `favorites`、**提示词暂存** `stash`、**第三方代码评审** `third-review`、**独立压缩模型** `compact-model`、**会话启动自动化** `autostart`,后续持续追加。
16
16
 
17
- **版本要求**:pi `>=0.86.0 <2.0.0`(覆盖最近 4 个中版本线 0.86.x / 0.87.x / 0.99.x / 1.0.x —— 0.88–0.98 从未发布。区间内全部 10 个已发布版本逐版本比对宿主 dist:用到的扩展 API 无差异,favorites 两处运行时 patch 目标 `ModelSelectorComponent` / `AgentSession.cycleModel` 字节级一致;并在 0.86.0、0.86.1、0.87.1、0.99.2、1.0.2 上逐一通过 typecheck + 全量测试,在真实 pi 1.0.2 上冒烟加载无警告)。注:pi ≥ 0.99 的宿主要求 `@earendil-works/pi-tui` 声明为 peerDependencies `"*"`(由宿主提供),本包已按要求声明。
17
+ **版本要求**:pi `>=0.87.0 <2.0.0`(覆盖最近 4 个中版本线 0.87.x / 0.99.x / 1.0.x / 1.1.x —— 0.88–0.98 从未发布。区间内全部 11 个已发布版本(0.87.0 → 1.1.0)逐版本比对宿主 dist:用到的扩展 API 无破坏性差异(1.0.4 → 1.1.0 仅新增字段),favorites 两处运行时 patch 目标 `ModelSelectorComponent` / `AgentSession.cycleModel` 字节级一致;并在 0.87.0、0.87.1、0.99.0、0.99.2、1.0.0、1.0.4、1.1.0 上逐一通过 typecheck + 全量测试,在真实 pi 1.1.0 上冒烟加载无警告)。注:pi ≥ 0.99 的宿主要求 `@earendil-works/pi-tui` 声明为 peerDependencies `"*"`(由宿主提供),本包已按要求声明。
18
18
 
19
19
  ---
20
20
 
@@ -36,7 +36,7 @@ pi -e ./src/index.ts
36
36
  安装后在任意 pi 会话中验证:
37
37
 
38
38
  - `/ask` → footer 出现灰色 `ask` 状态,`write`/`edit` 被硬禁用
39
- - `/model`(或 `ctrl+l`)→ 选择器顶部出现收藏提示行
39
+ - `/model`(或 `ctrl+l`)→ 选择器顶部出现收藏提示行;对选中模型按 `ctrl+A` → 文字变**加粗亮黄**、收藏计数 +1(这一步同时就是真机按键检查,见「键位」约定)
40
40
  - 输入框内按 `ctrl+alt+y` → 当前提示词被暂存并清空输入框
41
41
  - 完成一个开发任务后输入 `/third-review` → 切换到评审模型执行查+修
42
42
  - `/compact-model` 选一个便宜快模型 → 之后 `/compact` 与自动压缩的总结都由它执行(footer 出现灰色 `compact` 状态)
@@ -66,7 +66,7 @@ pi -e ./src/index.ts
66
66
  | 功能 | 入口 | 一句话说明 |
67
67
  | --- | --- | --- |
68
68
  | 🛡️ **ask** 只读咨询模式 | `/ask` | 进入只读问答模式,`write`/`edit` 硬禁用,`bash` 只读沙箱 |
69
- | ⭐ **favorites** 模型收藏 | `/model` 内 `ctrl+alt+F` / `ctrl+J` | 收藏常用模型(加粗亮黄标记),`ctrl+p` 仅在收藏间循环 |
69
+ | ⭐ **favorites** 模型收藏 | `/model` 内 `ctrl+A` / `ctrl+J` | 收藏常用模型(加粗亮黄标记),`ctrl+p` 仅在收藏间循环 |
70
70
  | 📥 **stash** 提示词暂存 | `ctrl+alt+y` | 一段提示词的暂存槽,按键交换 / 连按两次暂存并清空输入框 |
71
71
  | 🔎 **review** 第三方代码评审 | `/third-review` | 召唤配置的评审模型,对刚完成的任务做查+修,重点检查「本轮需求实现 / 是否有遗漏 / 是否有错误」 |
72
72
  | 🗜️ **compact** 独立压缩模型 | `/compact-model` | 给 `/compact` 与 auto-compact 配一个便宜快模型做总结,主模型专注对话;未配置零开销、任何异常回落 pi 默认 |
@@ -100,7 +100,7 @@ pi -e ./src/index.ts
100
100
  **在 `/model` 选择器内**(`/model` 或 `ctrl+l` 打开):
101
101
 
102
102
  - 顶部提示行显示按键与当前过滤状态
103
- - `ctrl+alt+F` —— 对当前选中模型开/关收藏;收藏的模型文字显示为**加粗亮黄**
103
+ - `ctrl+A` —— 对当前选中模型开/关收藏;收藏的模型文字显示为**加粗亮黄**
104
104
  - `ctrl+J` —— 开/关「仅显示收藏模型」过滤(可与内置搜索叠加使用)
105
105
 
106
106
  **模型循环**:只要存在 ≥1 个收藏,`ctrl+p` / `ctrl+shift+p` 就**只在收藏模型间循环**。当前模型不是收藏时,`ctrl+p` 跳到第一个收藏、`ctrl+shift+p` 跳到最后一个;收藏仅 1 个时停在原地(`Only one model available`)。`ctrl+l` / `/model` 始终可自由选择任意模型(含非收藏)。在状态文件中设 `"cycleOnlyFavorites": false` 可恢复全量循环。
@@ -116,9 +116,9 @@ pi -e ./src/index.ts
116
116
 
117
117
  `/favorites` 命令列出当前收藏与循环模式。
118
118
 
119
- > **实现说明**:pi 的 `app.model.cycleForward`(`ctrl+p`)与 `cycleBackward` 是**保留键位**,扩展快捷键无法覆盖;且扩展快捷键只在编辑器聚焦时生效。因此本功能不重绑任何按键,而是在运行时 patch 两个内置原型(带版本守卫、`/reload` 幂等):`ModelSelectorComponent`(提示行、`ctrl+alt+F`/`ctrl+J`、亮黄渲染、仅收藏过滤——按键仅在选择器内消费,编辑器里 `ctrl+j` 换行不受影响)与 `AgentSession.cycleModel`(收藏循环)。若 pi 升级导致 patch 无法应用,会 warn 并优雅降级,不影响其它功能。
119
+ > **实现说明**:pi 的 `app.model.cycleForward`(`ctrl+p`)与 `cycleBackward` 是**保留键位**,扩展快捷键无法覆盖;且扩展快捷键只在编辑器聚焦时生效。因此本功能不重绑任何按键,而是在运行时 patch 两个内置原型(带版本守卫、`/reload` 幂等):`ModelSelectorComponent`(提示行、`ctrl+A`/`ctrl+J`、亮黄渲染、仅收藏过滤——按键仅在选择器内消费,编辑器里 `ctrl+j` 换行不受影响)与 `AgentSession.cycleModel`(收藏循环)。若 pi 升级导致 patch 无法应用,会 warn 并优雅降级,不影响其它功能。
120
120
  >
121
- > **为何是 `ctrl+alt+F` 而不是 `ctrl+F`**:pi 自 1.0 起 `tuiMode` 默认 `fullscreen`(0.86–0.99 默认 `regular`),而在 Windows/WSL 上宿主把 `tui.altScreen.search` 解析为 `ctrl+f`;`TuiAltScreen.handleViewportInput()` 在**把输入交给聚焦覆盖层之前**先检查该绑定,于是 `ctrl+f` 打开了会话记录搜索、根本到不了选择器。`alt+f`、`shift+f`、`ctrl+shift+f` 同样被占或不可靠——依据见 `src/features/favorites/constants.ts` 与 `pnpm check:keybindings`。
121
+ > **为何是 `ctrl+A` 而不是 `ctrl+F`**:pi 自 1.0 起 `tuiMode` 默认 `fullscreen`(0.87–0.99 默认 `regular`),而在 Windows/WSL 上宿主把 `tui.altScreen.search` 解析为 `ctrl+f`;`TuiAltScreen.handleViewportInput()` 在**把输入交给聚焦覆盖层之前**先检查该绑定,于是 `ctrl+f` 打开了会话记录搜索、根本到不了选择器。曾过渡性地选过 `ctrl+alt+f`——pi 层完全空闲,却被 Windows 侧截图工具作为全局热键截走:**宿主表空闲 ≠ 机器层空闲**。最终从 "favorite" 一词里逐字母审计:`v` 是 Windows Terminal 的粘贴键,`o`/`r`/`t` 是宿主 app 层动作,`i` 与 Tab 字节恒等(选择器的 scope 切换),`e` 可用但无记忆点;`a` 仅遮蔽搜索框内的行首跳转、读作 *add favorite*,且选择器上游无任何消费者。完整依据见 `src/features/favorites/constants.ts` 与 `pnpm check:keybindings`。
122
122
 
123
123
  ---
124
124
 
@@ -195,7 +195,7 @@ pi 的 `/compact` 与 auto-compact 默认**用当前会话模型**做上下文
195
195
  | auto-compact 阈值触发 | 压缩模型总结 |
196
196
  | context overflow 恢复 | 压缩模型总结,重试行为不变 |
197
197
 
198
- **接管后与 pi 内建行为完全一致的部分**(逐字同步 pi 内建实现,0.87.1 起字节级不变、已核对至 1.0.2,只换执行模型):
198
+ **接管后与 pi 内建行为完全一致的部分**(逐字同步 pi 内建实现,0.87.1 起字节级不变、已核对至 1.1.0,只换执行模型;0.87.0 的分割轮次前缀 prompt 与 0.87.1 不同,本镜像对所有宿主采用 0.87.1 的修复文本):
199
199
 
200
200
  - **摘要格式** —— Goal / Progress / Key Decisions 结构化 checkpoint;已有摘要时用迭代更新版 prompt,信息延续不丢
201
201
  - **切分行为** —— 保留最近 `keepRecentTokens` 的策略、`firstKeptEntryId` / `tokensBefore` 原样回传,不动
@@ -262,7 +262,7 @@ run = [
262
262
 
263
263
  **关键约束:只支持扩展命令**。`/add-dir`(pi-add-dir)、`/cd`(pi-cd)等 `registerCommand` 注册的命令可以;内置命令(`/compact`、`/reload`、`/resume`…)在 TUI 层分发,扩展层触发不了;skill 命令(`/skill:name`)是展开机制而非执行机制。依赖的目标扩展(如 pi-add-dir)需要先安装。
264
264
 
265
- > **实现说明**:执行用 `sendUserMessage(cmd, { expandPromptTemplates: true })` —— 该选项把 `/cmd args` 路由到命令分发而不是模型 prompt 路径(包装层默认 `false`,已对照 pi 0.86–1.0.4 源码核实,见 AGENTS.md 宿主兼容纪律)。预校验用 `pi.getCommands()`(只认 `source: "extension"`)。依赖 `smol-toml`(零依赖、~10KB、TOML 1.0)。
265
+ > **实现说明**:执行用 `sendUserMessage(cmd, { expandPromptTemplates: true })` —— 该选项把 `/cmd args` 路由到命令分发而不是模型 prompt 路径(包装层默认 `false`,已对照 pi 0.87.0–1.1.0 源码核实,见 AGENTS.md 宿主兼容纪律)。预校验用 `pi.getCommands()`(只认 `source: "extension"`)。依赖 `smol-toml`(零依赖、~10KB、TOML 1.0)。
266
266
 
267
267
  ---
268
268
 
@@ -325,7 +325,7 @@ pnpm release patch --dry-run # 预览,不做任何改动
325
325
  - **测试** —— 每个功能自带 vitest 用例;保持确定性(时钟/状态可注入),不写真实 agent dir
326
326
  - **内建 patch**(favorites)必须保持**版本守卫 + 幂等** —— 打 patch 前先确认目标原型成员存在,防止重复应用,失败时用 `console.warn` 降级而不是把扩展搞挂
327
327
  - **内建提示词同步**(compact) —— `src/features/compact/prompt.ts` 里的总结 prompt 逐字抄自 pi 内建压缩;升级 pi 依赖时 diff `dist/core/compaction/compaction.js`(及 `utils.js`),同步字符串与组装辅助函数,保持接管输出与内建字节级一致
328
- - **键位** —— 定新快捷键前先查 pi 默认键位 + 保留键、终端控制字符、OS/终端模拟器占用;跨平台安全优先选 `ctrl+alt+<字母>`。**不得只验证「主屏下我这台机器能用」**:自 pi 1.0 起默认 `fullscreen`,alt-screen 层在对话框看到按键**之前**就消费 `tui.altScreen.*`,且 Windows/WSL 上多个绑定与 Linux 默认值不同。用 `pnpm check:keybindings [候选键...]` 核查(pi 升级后跑 `pnpm check:keybindings --all`),它用宿主自己的 `matchesKey` 探测已安装宿主的**已解析**键位表。
328
+ - **键位** —— 定新快捷键前先查 pi 默认键位 + 保留键、终端控制字符、OS/终端模拟器占用;跨平台安全优先选 `ctrl+alt+<字母>`。**不得只验证「主屏下我这台机器能用」**:自 pi 1.0 起默认 `fullscreen`,alt-screen 层在对话框看到按键**之前**就消费 `tui.altScreen.*`,且 Windows/WSL 上多个绑定与 Linux 默认值不同。用 `pnpm check:keybindings [候选键...]` 核查(pi 升级后跑 `pnpm check:keybindings --all`),它用宿主自己的 `matchesKey` 探测已安装宿主的**已解析**键位表。**宿主表空闲 ≠ 机器层空闲**:Windows Terminal 默认占 `ctrl+v`(粘贴)与 `ctrl+shift+f`(查找),第三方 Windows 工具常绑 `ctrl+alt+<字母>`(截图工具占过 `ctrl+alt+f`)——定键后必须在真机试按,确认按键真的到得了应用。
329
329
  - **质量门禁** —— 提交前必须通过 `pnpm typecheck && pnpm test`
330
330
 
331
331
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andares/pi-toolkits",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Integrated toolkit extension for pi — ask mode (read-only Q&A), model favorites, prompt stash, third-party code review, and a dedicated compaction model",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,7 @@
28
28
  "autostart"
29
29
  ],
30
30
  "peerDependencies": {
31
- "@earendil-works/pi-coding-agent": ">=0.86.0 <2.0.0",
31
+ "@earendil-works/pi-coding-agent": ">=0.87.0 <2.0.0",
32
32
  "@earendil-works/pi-tui": "*"
33
33
  },
34
34
  "dependencies": {
@@ -36,9 +36,9 @@
36
36
  "smol-toml": "^1.9.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@earendil-works/pi-ai": "^1.0.2",
40
- "@earendil-works/pi-coding-agent": "^1.0.2",
41
- "@earendil-works/pi-tui": "^1.0.2",
39
+ "@earendil-works/pi-ai": "^1.1.0",
40
+ "@earendil-works/pi-coding-agent": "^1.1.0",
41
+ "@earendil-works/pi-tui": "^1.1.0",
42
42
  "@types/node": "^26.6.2",
43
43
  "typescript": "^5.6.0",
44
44
  "vitest": "^4.1.10"
@@ -16,7 +16,7 @@
16
16
  * Dispatch uses `sendUserMessage(cmd, { expandPromptTemplates: true })` —
17
17
  * that flag is what routes "/cmd args" through _tryExecuteExtensionCommand
18
18
  * instead of the model prompt path. The wrapper defaults it to false
19
- * (verified against pi 1.0.4 agent-session.js; see AGENTS.md host-compat
19
+ * (verified against pi 1.1.0 agent-session.js; see AGENTS.md host-compat
20
20
  * discipline for the version matrix).
21
21
  *
22
22
  * Only extension commands can run this way. Built-in commands (/compact,
@@ -11,7 +11,7 @@
11
11
  * before running its own compaction
12
12
  * - prompts, message assembly, split-turn handling, output budgets, and the
13
13
  * summary file-list tail are verbatim pi built-in behavior (copied from
14
- * 0.87.1, verified unchanged through 1.0.2) — only the executing model
14
+ * 0.87.1, verified unchanged through 1.1.0) — only the executing model
15
15
  * differs
16
16
  * - lossless fallback: unset config, unavailable model, empty/failed
17
17
  * summary, or user abort → return undefined and pi's default compaction
@@ -116,7 +116,7 @@ async function completeSummary(
116
116
  }
117
117
 
118
118
  /**
119
- * pi's output-budget formula (compaction.js, 0.87.1 → 1.0.2 unchanged): a
119
+ * pi's output-budget formula (compaction.js, 0.87.1 → 1.1.0 unchanged): a
120
120
  * fraction of reserveTokens clamped by the model's own output cap.
121
121
  */
122
122
  function summarizationBudget(
@@ -132,7 +132,7 @@ function summarizationBudget(
132
132
 
133
133
  /**
134
134
  * Run the full compaction summarization with the configured model,
135
- * replicating pi's compact() (0.87.1, verified unchanged through 1.0.2):
135
+ * replicating pi's compact() (0.87.1, verified unchanged through 1.1.0):
136
136
  * history summary (first-connection or iterative-update prompt, custom
137
137
  * focus appended), plus a separate turn-prefix checkpoint when the cut point
138
138
  * splits a turn, merged into one summary with the file-list tail. Returns
@@ -5,9 +5,11 @@
5
5
  * compaction (dist/core/compaction/compaction.js and utils.js) so that
6
6
  * summaries produced by the configured compact model are formatted exactly
7
7
  * like pi's own compaction output. Only the executing model differs.
8
- * Verified byte-identical against pi 1.0.2 (0.88–0.98 were never published;
9
- * the only 0.87.1→1.0.2 change there is a combineUsage refactor into a
10
- * shared module, no prompt or budget change).
8
+ * Verified byte-identical against pi 1.1.0 (0.88–0.98 were never published;
9
+ * the only 0.87.1→1.1.0 change there is a combineUsage refactor into a
10
+ * shared core/usage-totals.js, no prompt or budget change). 0.87.0 shipped a
11
+ * different split-turn prefix prompt; the text mirrored here is 0.87.1+'s
12
+ * fix, which is also what 0.87.0 hosts get — intentional.
11
13
  *
12
14
  * Update these strings whenever pi changes its built-in prompts (diff
13
15
  * dist/core/compaction/compaction.js between versions).
@@ -196,7 +198,8 @@ export function formatFileOperations(
196
198
 
197
199
  /**
198
200
  * Combine two provider usage records field-wise (pi 0.87.1 compaction.js
199
- * combineUsage): used when a split turn produces two summarization calls.
201
+ * combineUsage, moved verbatim to core/usage-totals.js in 0.99.0): used when
202
+ * a split turn produces two summarization calls.
200
203
  */
201
204
  export function combineUsage<T extends UsageLike>(first: T, second: T): T {
202
205
  return {
@@ -8,7 +8,7 @@
8
8
  * bindings — only the cycle semantics change (patch-cycle.ts), so no
9
9
  * keybinding conflicts arise.
10
10
  *
11
- * Verified against pi 0.86.0 / 0.87.0 / 0.99.0 / 1.0.2 / 1.0.4 keybinding
11
+ * Verified against pi 0.87.0 / 0.99.0 / 1.0.4 / 1.1.0 keybinding
12
12
  * tables + pi-tui input dispatch on WSL2 + Windows Terminal; re-run
13
13
  * `pnpm check:keybindings` after every host upgrade before trusting this.
14
14
  */
@@ -20,31 +20,51 @@ export const FAVORITES_FILE = "pi-toolkits-favorites.json";
20
20
  /**
21
21
  * Selector-scoped keybindings (only honored while the model selector is open).
22
22
  *
23
- * Why ctrl+alt+f for the toggle (was ctrl+f through v0.6.0):
24
- * - ctrl+f is consumed by the host in fullscreen mode, which became pi's
25
- * default `tuiMode` in 1.0 (0.86–0.99 defaulted to `regular`, where the
26
- * binding is inert). On Windows/WSL `tui.altScreen.search` resolves to
27
- * ctrl+f, and `TuiAltScreen.handleViewportInput()` checks it before
28
- * `shouldDeferViewportInputToOverlay()`, so the keystroke opens transcript
29
- * search and the selector never sees it. Verified in pi-tui 1.0.4
30
- * `dist/tui-alt-screen.js` (search check is the first key branch and
31
- * returns `{ consume: true }` unconditionally).
32
- * - alt+f is taken by `tui.editor.cursorWordRight` and `app.tree.unfoldOrDown`.
33
- * - shift+f arrives as the literal character "F" without the kitty keyboard
34
- * protocol, i.e. it would steal a typed character from the selector's
35
- * search box.
36
- * - ctrl+shift+f collapses to ctrl+f on Windows/WSL terminals (the reason
37
- * pi itself binds search to ctrl+f there instead) and Windows Terminal
38
- * binds it to its own Find action.
39
- * - ctrl+alt+f is unclaimed across the whole 0.86–1.0 window (only
40
- * `ctrl+alt+]` is taken from that family) and is byte-distinguishable from
41
- * ctrl+f/alt+f without kitty (ESC + ctrl-f). Same family as the shipped
42
- * stash key ctrl+alt+y, which is proven to reach pi on this terminal.
23
+ * Toggle key history: ctrl+f (through v0.6.0) → ctrl+alt+f (discarded before
24
+ * release) → ctrl+a (current). Each step is a real layer the previous pick
25
+ * missed — audit trail below; re-run `pnpm check:keybindings` on upgrades.
26
+ *
27
+ * Why ctrl+f is dead: fullscreen became pi's default `tuiMode` in 1.0
28
+ * (0.87–0.99 defaulted to `regular`, where the binding is inert). On
29
+ * Windows/WSL `tui.altScreen.search` resolves to ctrl+f, and
30
+ * `TuiAltScreen.handleViewportInput()` checks it before
31
+ * `shouldDeferViewportInputToOverlay()`, so the keystroke opens transcript
32
+ * search and the selector never sees it (verified in pi-tui 1.1.0
33
+ * `dist/tui-alt-screen.js`: the search check is the first key branch and
34
+ * returns `{ consume: true }` unconditionally).
35
+ *
36
+ * Why ctrl+alt+f was discarded: clean at the pi layer across 0.87–1.1 (only
37
+ * ctrl+alt+] is taken from that family) and byte-distinguishable without
38
+ * kitty — but grabbed at the OS/app layer on the author's machine by a
39
+ * Windows screenshot tool, so it never reached the terminal. Lesson: a key
40
+ * that is free in the host table is not necessarily free on the machine.
41
+ *
42
+ * Why ctrl+a (letter taken from "favorite", audited with the host's own
43
+ * matchesKey on WSL2 + Windows Terminal):
44
+ * - f: consumed upstream by `tui.altScreen.search` in fullscreen (above).
45
+ * - v: free at the pi layer on WSL (`app.clipboard.pasteImage` is alt+v
46
+ * there) but Windows Terminal binds ctrl+v to paste — and pasting a model
47
+ * name into the search box is a feature, not a slot to steal.
48
+ * - o / r / t: host-owned at the app layer (`app.tools.expand`,
49
+ * `app.session.rename`, `app.thinking.toggle`).
50
+ * - i: byte-identical to Tab on non-kitty terminals ("\t"), and Tab is the
51
+ * selector's built-in scope toggle — a guaranteed fight.
52
+ * - e: viable (shadows only `tui.editor.cursorLineEnd` inside the selector)
53
+ * but carries no mnemonic; a was preferred.
54
+ * - a: shadows only `tui.editor.cursorLineStart` (readline home) inside the
55
+ * selector — our patch consumes it before the search box, exactly like
56
+ * ctrl+j shadows newLine. No upstream consumer, nothing bound at the
57
+ * Windows Terminal / Windows OS layer, no other loaded extension claims
58
+ * it, and "a" reads as *add favorite*.
59
+ * (Rejected elsewhere: alt+f = cursorWordRight + tree unfold; shift+f is
60
+ * the literal character "F" without kitty, stealing typed search text;
61
+ * ctrl+shift+f collapses to ctrl+f on Windows/WSL and is Windows Terminal's
62
+ * own Find.)
43
63
  *
44
64
  * ctrl+j is kept: no host layer consumes it before the selector, so it only
45
65
  * shadows `tui.input.newLine` inside the search box.
46
66
  */
47
- export const FAVORITE_TOGGLE_KEY = "ctrl+alt+f";
67
+ export const FAVORITE_TOGGLE_KEY = "ctrl+a";
48
68
  export const FAVORITES_ONLY_KEY = "ctrl+j";
49
69
 
50
70
  /**
@@ -6,7 +6,7 @@
6
6
  * - cycle patch: favorites-only cycling (fallback to stock when disabled or
7
7
  * no favorites; favorites-only pick; single-favorite jump; not-a-favorite
8
8
  * → forward first / backward last)
9
- * - selector patches: ctrl+j favorites-only filter, ctrl+alt+f toggle, hint
9
+ * - selector patches: ctrl+j favorites-only filter, ctrl+a toggle, hint
10
10
  * injection, idempotent apply, plain ctrl+f left to the host
11
11
  *
12
12
  * The patches read the shared store via getFavoritesStore(); each test gets an
@@ -408,19 +408,19 @@ describe("selector patches", () => {
408
408
  expect(selector.filteredModels).toHaveLength(3);
409
409
  });
410
410
 
411
- it("ctrl+alt+f toggles favorite for the selected model", () => {
411
+ it("ctrl+a toggles favorite for the selected model", () => {
412
412
  const selector = fakeSelector({
413
413
  filteredModels: models.map(item),
414
414
  selectedIndex: 1, // opus-4
415
415
  activeModels: models.map(item),
416
416
  });
417
- selector.handleInput("\x1b\x06"); // ctrl+alt+f (legacy ESC + ctrl-f)
417
+ selector.handleInput("\x01"); // ctrl+a
418
418
  expect(getFavoritesStore().has(models[1])).toBe(true);
419
- selector.handleInput("\x1b\x06");
419
+ selector.handleInput("\x01");
420
420
  expect(getFavoritesStore().has(models[1])).toBe(false);
421
421
  });
422
422
 
423
- it("does not intercept plain ctrl+f (host-owned in fullscreen mode)", () => {
423
+ it("does not intercept the retired keys ctrl+f / ctrl+alt+f (host/machine-owned)", () => {
424
424
  const forwarded: string[] = [];
425
425
  getFavoritesStore().toggle(models[1]);
426
426
  const selector = fakeSelector({
@@ -432,9 +432,10 @@ describe("selector patches", () => {
432
432
  handleInput: (d: string) => forwarded.push(d),
433
433
  },
434
434
  });
435
- selector.handleInput("\x06"); // stock ctrl+f
436
- // Reached the search box instead of our toggle, so the store is unchanged.
437
- expect(forwarded).toEqual(["\x06"]);
435
+ selector.handleInput("\x06"); // stock ctrl+f — upstream transcript search
436
+ selector.handleInput("\x1b\x06"); // retired ctrl+alt+f — machine-level hotkey
437
+ // Both reached the search box instead of our toggle, so the store is unchanged.
438
+ expect(forwarded).toEqual(["\x06", "\x1b\x06"]);
438
439
  expect(getFavoritesStore().has(models[1])).toBe(true);
439
440
  });
440
441
 
@@ -4,14 +4,15 @@
4
4
  * What it does:
5
5
  * - Inside the /model selector (opened via /model or ctrl+l):
6
6
  * * a hint row at the top shows the keys and the favorites-only state
7
- * * ctrl+alt+f toggles favorite on the currently selected model
7
+ * * ctrl+a toggles favorite on the currently selected model
8
8
  * * ctrl+j toggles the "only favorites" filter
9
9
  * * favorited model ids render in bold bright yellow
10
10
  * The keys are consumed by the selector component only, so pi's editor
11
11
  * bindings (ctrl+j newline) are untouched elsewhere. (The toggle moved off
12
- * ctrl+f after v0.6.0: pi >= 1.0 defaults to fullscreen, where ctrl+f is
12
+ * ctrl+f after v0.6.0 — pi >= 1.0 defaults to fullscreen, where ctrl+f is
13
13
  * consumed by the alt-screen transcript search before the selector sees
14
- * it — see constants.ts for the full key audit.)
14
+ * it — and an interim ctrl+alt+f pick turned out to be grabbed by a
15
+ * Windows screenshot tool; see constants.ts for the full key audit.)
15
16
  * - ctrl+p / ctrl+shift+p keep their bindings but, once favorites exist
16
17
  * (and cycleOnlyFavorites is not false), cycle only among favorited
17
18
  * models instead of all models. ctrl+l / /model remain the escape hatch
@@ -95,13 +96,13 @@ export function registerFavorites(pi: ExtensionAPI): void {
95
96
 
96
97
  pi.registerCommand("favorites", {
97
98
  description:
98
- "List favorited models (add/remove with ctrl+alt+F in /model)",
99
+ "List favorited models (add/remove with ctrl+A in /model)",
99
100
  handler: async (_args: string, ctx: ExtensionContext) => {
100
101
  captureTheme(ctx);
101
102
  const list = getFavoritesStore().list();
102
103
  if (list.length === 0) {
103
104
  ctx.ui.notify(
104
- "No favorited models. Open /model and press ctrl+alt+F on a model to favorite it.",
105
+ "No favorited models. Open /model and press ctrl+A on a model to favorite it.",
105
106
  "info",
106
107
  );
107
108
  return;
@@ -14,7 +14,7 @@
14
14
  * - with exactly one favorite, already on it → undefined (stock "only one
15
15
  * model available" feedback); otherwise jump to it
16
16
  * - the apply logic mirrors pi's _cycleScopedModel/_cycleAvailableModel
17
- * (byte-identical across every published version in 0.86.0 → 1.0.2:
17
+ * (byte-identical across every published version in 0.87.0 → 1.1.0:
18
18
  * state swap, session persistence, default-model persistence only when
19
19
  * `options.persist` is set, thinking-level re-clamp, model_select emit
20
20
  * with source "cycle")
@@ -30,9 +30,9 @@ import { getFavoritesStore, modelKey } from "./store.js";
30
30
 
31
31
  /**
32
32
  * pi's `Model<any>` — the exact type of `ModelCycleResult.model`
33
- * (pi-coding-agent 0.86–1.0; the field is unchanged across that span).
33
+ * (pi-coding-agent 0.87–1.1; the field is unchanged across that span).
34
34
  * Derived here instead of importing `Model` from @earendil-works/pi-ai,
35
- * whose index.d.ts (0.86 through 1.0.2 alike) re-exports it via an
35
+ * whose index.d.ts (0.87 through 1.1.0 alike) re-exports it via an
36
36
  * extensioned `"./types.ts"` specifier that not every TS resolver substitutes
37
37
  * to `types.d.ts` (tsc 5.9 bundler does; other tsserver builds don't).
38
38
  */
@@ -5,7 +5,7 @@
5
5
  * selector, so we patch the component prototype at runtime. Three hooks:
6
6
  *
7
7
  * 1. handleInput — intercept the favorites keys (see constants.ts for why
8
- * they are ctrl+alt+f / ctrl+j) BEFORE the original
8
+ * they are ctrl+a / ctrl+j) BEFORE the original
9
9
  * forwards them to the search box. Scoped to the
10
10
  * selector: outside it, ctrl+j keeps pi's default editor
11
11
  * binding untouched.
@@ -22,7 +22,7 @@
22
22
  * keeps loading and ctrl+p falls back to stock behavior. The prototype
23
23
  * shape touched here (handleInput/updateList/filterModels and the instance
24
24
  * fields below) is byte-identical across every published version in
25
- * pi 0.86.0 → 1.0.4.
25
+ * pi 0.87.0 → 1.1.0.
26
26
  */
27
27
  import {
28
28
  ModelSelectorComponent,
@@ -116,7 +116,7 @@ let patched = false;
116
116
  export function applyModelSelectorPatches(): boolean {
117
117
  if (patched) return true;
118
118
  // SAFETY: ModelSelectorComponent's members are TS-private (compile-time
119
- // only); the structural view matches pi 0.86–1.0's prototype shape
119
+ // only); the structural view matches pi 0.87–1.1's prototype shape
120
120
  // (byte-identical across that span) and every touched method is
121
121
  // existence-checked below before any patching happens.
122
122
  const proto =
@@ -155,7 +155,7 @@ export function applyModelSelectorPatches(): boolean {
155
155
  };
156
156
 
157
157
  // ── 2. List rendering: hint row + bold bright yellow favorites ────────
158
- // Replicates the built-in updateList layout (pi 0.86–1.0: fixed-width cursor
158
+ // Replicates the built-in updateList layout (pi 0.87–1.1: fixed-width cursor
159
159
  // and ✓ current-marker columns, provider badge, `· default` badge, scroll
160
160
  // indicator, empty/error states, refresh status, Model Name footer) with
161
161
  // one change: favorited model ids render in the favorite style.
@@ -21,7 +21,7 @@ import type { KeyId } from "@earendil-works/pi-tui";
21
21
  /**
22
22
  * Stash hotkey.
23
23
  *
24
- * Compatibility rationale (verified against pi 0.84 keybindings, live
24
+ * Compatibility rationale (verified against pi 0.87.0–1.1.0 keybindings, live
25
25
  * matchesKey probes and terminal/OS behavior):
26
26
  * - pi: no default binding for ctrl+alt+<letter> (only ctrl+alt+] is taken);
27
27
  * extension shortcuts dispatch first while the editor is focused
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Current features:
8
8
  * - ask — read-only Q&A mode (/ask)
9
- * - favorites — model favorites (ctrl+alt+F/ctrl+J in /model, favorites-only cycling)
9
+ * - favorites — model favorites (ctrl+A/ctrl+J in /model, favorites-only cycling)
10
10
  * - stash — prompt stash (ctrl+alt+y swap / double-press stash-and-clear)
11
11
  * - review — third-party code review with a configured review model (third-review)
12
12
  * - compact — dedicated compact model for /compact + auto-compact summaries
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Types are derived from pi-coding-agent's own exports (ModelRegistry)
7
7
  * rather than imported from @earendil-works/pi-ai: pi-ai's index.d.ts (0.87
8
- * through 1.0.2 alike) re-exports `Model`/`Api` via extensioned
8
+ * through 1.1.0 alike) re-exports `Model`/`Api` via extensioned
9
9
  * `./types.ts` specifiers, which tsc 5.9 bundler resolution substitutes to
10
10
  * `.d.ts` but some tsserver builds do not. Deriving from ModelRegistry keeps
11
11
  * every resolver in agreement with the exact type
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * The component is driven through a small ModelRuntime facade backed by
11
11
  * ctx.modelRegistry (pi's extension-facing wrapper). SAFETY: verified
12
- * against pi 0.86–1.0 dist (modes/interactive/components/model-selector.js +
12
+ * against pi 0.87.0–1.1.0 dist (modes/interactive/components/model-selector.js +
13
13
  * model-catalog-refresh.js — byte-identical across that span) — the
14
14
  * component only calls getAvailableSnapshot, getModel, getError and refresh
15
15
  * on modelRuntime, and ModelRegistry provides exactly those
@@ -42,7 +42,7 @@ function modelRuntimeFacade(ctx: ExtensionContext): ModelRuntime {
42
42
  refresh: (options?: { signal?: AbortSignal }) =>
43
43
  ctx.modelRegistry.refresh(options),
44
44
  };
45
- // SAFETY: the selector only touches the four members above (pi 0.86–1.0
45
+ // SAFETY: the selector only touches the four members above (pi 0.87–1.1
46
46
  // model-selector.js); everything else on ModelRuntime is never reached
47
47
  // from this component.
48
48
  return facade as unknown as ModelRuntime;