@andares/pi-toolkits 0.7.0 → 0.7.1

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
@@ -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.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. 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
 
@@ -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
@@ -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.86–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
 
@@ -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.1",
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",
@@ -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.86–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.0.4
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.86–1.0 (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;
@@ -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.
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