@gavin-hu/my-pi-agent 0.18.0 → 0.20.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 (324) hide show
  1. package/README.md +66 -52
  2. package/README.zh-CN.md +56 -46
  3. package/docs/extensions/README.md +34 -0
  4. package/docs/extensions/board.md +507 -0
  5. package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +774 -574
  6. package/{extensions/check/README.md → docs/extensions/check.md} +83 -68
  7. package/{extensions/context/README.md → docs/extensions/context.md} +40 -23
  8. package/docs/extensions/file-browse.md +561 -0
  9. package/{extensions/file-open/README.md → docs/extensions/file-open.md} +31 -23
  10. package/{extensions/file-read/README.md → docs/extensions/file-read.md} +47 -55
  11. package/{extensions/goal/README.md → docs/extensions/goal.md} +115 -131
  12. package/{extensions/job/README.md → docs/extensions/job.md} +62 -52
  13. package/{extensions/memory/README.md → docs/extensions/memory.md} +71 -60
  14. package/{extensions/plan/README.md → docs/extensions/plan.md} +440 -322
  15. package/{extensions/question/README.md → docs/extensions/question.md} +54 -31
  16. package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
  17. package/docs/extensions/session-bus.md +298 -0
  18. package/{extensions/subagent/README.md → docs/extensions/subagent.md} +165 -118
  19. package/docs/extensions/team.md +254 -0
  20. package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
  21. package/{extensions/watch/README.md → docs/extensions/watch.md} +54 -36
  22. package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
  23. package/{extensions/wechat/README.md → docs/extensions/wechat.md} +260 -163
  24. package/{extensions/worktree/README.md → docs/extensions/worktree.md} +137 -79
  25. package/extensions/board/commands.ts +105 -0
  26. package/extensions/board/config.ts +36 -0
  27. package/extensions/board/format.ts +170 -0
  28. package/extensions/board/index.ts +40 -0
  29. package/extensions/board/input.ts +54 -0
  30. package/extensions/board/join.ts +42 -0
  31. package/extensions/board/page.ts +388 -0
  32. package/extensions/board/result.ts +108 -0
  33. package/extensions/board/rows.ts +48 -0
  34. package/extensions/board/schema.ts +90 -0
  35. package/extensions/board/seat.ts +28 -0
  36. package/extensions/board/snapshot.ts +42 -0
  37. package/extensions/board/tools.ts +444 -0
  38. package/extensions/board/transport/router.ts +91 -0
  39. package/extensions/board/transport/server.ts +138 -0
  40. package/extensions/board/types.ts +121 -0
  41. package/extensions/board/view/client.ts +51 -0
  42. package/extensions/board/view/dialog.ts +43 -0
  43. package/extensions/board/view/keys.ts +125 -0
  44. package/extensions/board/view/live.ts +231 -0
  45. package/extensions/board/view/names.ts +91 -0
  46. package/extensions/board/view/page.ts +118 -0
  47. package/extensions/board/view/render.ts +519 -0
  48. package/extensions/board/view/styles.ts +228 -0
  49. package/extensions/board/view/team.ts +327 -0
  50. package/extensions/bytefly/footer/budget.ts +6 -5
  51. package/extensions/bytefly/footer/collect/entries.ts +12 -4
  52. package/extensions/bytefly/footer/collect/snapshot.ts +8 -17
  53. package/extensions/bytefly/footer/config.ts +19 -8
  54. package/extensions/bytefly/footer/price/price.ts +30 -8
  55. package/extensions/bytefly/footer/register.ts +5 -5
  56. package/extensions/bytefly/footer/render/format.ts +18 -0
  57. package/extensions/bytefly/footer/render/lines.ts +23 -7
  58. package/extensions/bytefly/footer/render/segments.ts +117 -31
  59. package/extensions/bytefly/footer/types.ts +29 -5
  60. package/extensions/bytefly/footer/unpriced.ts +42 -17
  61. package/extensions/bytefly/panel/commands.ts +67 -7
  62. package/extensions/bytefly/panel/filter.ts +68 -0
  63. package/extensions/bytefly/panel/format.ts +16 -15
  64. package/extensions/bytefly/panel/join.ts +56 -13
  65. package/extensions/bytefly/panel/prices.ts +43 -0
  66. package/extensions/bytefly/panel/settings-runtime.ts +0 -6
  67. package/extensions/bytefly/panel/settings.ts +75 -43
  68. package/extensions/bytefly/panel/tui/entries.ts +26 -8
  69. package/extensions/bytefly/panel/tui/frame.ts +130 -93
  70. package/extensions/bytefly/panel/tui/keys.ts +352 -0
  71. package/extensions/bytefly/panel/tui/list-view.ts +25 -46
  72. package/extensions/bytefly/panel/tui/panes.ts +76 -0
  73. package/extensions/bytefly/panel/tui/section-view.ts +126 -0
  74. package/extensions/bytefly/panel/tui/settings-section.ts +54 -125
  75. package/extensions/bytefly/panel/tui/settings-view.ts +30 -131
  76. package/extensions/bytefly/panel/tui/side-pane.ts +224 -0
  77. package/extensions/bytefly/panel/tui.ts +306 -259
  78. package/extensions/bytefly/picker/discovery.ts +0 -2
  79. package/extensions/bytefly/picker/types.ts +0 -2
  80. package/extensions/bytefly/update/check.ts +39 -0
  81. package/extensions/bytefly/update/format.ts +15 -0
  82. package/extensions/bytefly/update/register.ts +73 -34
  83. package/extensions/bytefly/update/state.ts +6 -3
  84. package/extensions/check/commands.ts +2 -1
  85. package/extensions/context/tui.ts +1 -1
  86. package/extensions/file-browse/{config.ts → config/config.ts} +1 -1
  87. package/extensions/file-browse/files/classify.ts +136 -0
  88. package/extensions/file-browse/files/files.ts +12 -0
  89. package/extensions/file-browse/files/index.ts +90 -0
  90. package/extensions/file-browse/files/list.ts +261 -0
  91. package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
  92. package/extensions/file-browse/files/tree.ts +101 -0
  93. package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
  94. package/extensions/file-browse/index.ts +4 -4
  95. package/extensions/file-browse/{live.ts → live/live.ts} +20 -69
  96. package/extensions/file-browse/{router.ts → transport/router.ts} +21 -17
  97. package/extensions/file-browse/transport/server.ts +110 -0
  98. package/extensions/file-browse/{chrome.ts → view/chrome.ts} +4 -4
  99. package/extensions/file-browse/{client.ts → view/client.ts} +1 -1
  100. package/extensions/file-browse/{diff-html.ts → view/diff-html.ts} +3 -3
  101. package/extensions/file-browse/view/emit.ts +51 -0
  102. package/extensions/file-browse/{html.ts → view/html.ts} +19 -18
  103. package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
  104. package/extensions/file-browse/{markdown.ts → view/markdown.ts} +18 -20
  105. package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +19 -14
  106. package/extensions/file-browse/{styles.ts → view/styles.ts} +29 -5
  107. package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
  108. package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
  109. package/extensions/file-read/schema.ts +2 -1
  110. package/extensions/job/runtime.ts +4 -4
  111. package/extensions/memory/store.ts +12 -5
  112. package/extensions/plan/blocks.ts +23 -2
  113. package/extensions/plan/commands.ts +21 -16
  114. package/extensions/plan/feedback.ts +185 -52
  115. package/extensions/plan/format.ts +10 -3
  116. package/extensions/plan/index.ts +23 -5
  117. package/extensions/plan/plan-files.ts +88 -0
  118. package/extensions/plan/plan-index.ts +43 -9
  119. package/extensions/plan/plan-text.ts +33 -23
  120. package/extensions/plan/plans.ts +27 -34
  121. package/extensions/plan/policy.ts +30 -17
  122. package/extensions/plan/review.ts +3 -27
  123. package/extensions/plan/runtime.ts +52 -11
  124. package/extensions/plan/sections.ts +112 -0
  125. package/extensions/plan/steps.ts +3 -22
  126. package/extensions/plan/todos.ts +51 -3
  127. package/extensions/plan/tools/exit.ts +20 -95
  128. package/extensions/plan/tools/todo-seed.ts +4 -2
  129. package/extensions/plan/tools/write.ts +12 -1
  130. package/extensions/plan/tui.ts +5 -34
  131. package/extensions/plan/types.ts +15 -8
  132. package/extensions/plan/web-blocks.ts +89 -0
  133. package/extensions/plan/web-chrome.ts +3 -5
  134. package/extensions/plan/web-client.ts +179 -330
  135. package/extensions/plan/web-collab.ts +3 -3
  136. package/extensions/plan/web-comments.ts +18 -8
  137. package/extensions/plan/web-composer.ts +80 -0
  138. package/extensions/plan/web-draft.ts +40 -0
  139. package/extensions/plan/web-keys.ts +134 -0
  140. package/extensions/plan/web-outline.ts +192 -0
  141. package/extensions/plan/web-page.ts +4 -8
  142. package/extensions/plan/web-plan.ts +150 -0
  143. package/extensions/plan/web-router.ts +3 -58
  144. package/extensions/plan/web-settle.ts +194 -0
  145. package/extensions/plan/web-share-session.ts +24 -30
  146. package/extensions/plan/web-streams.ts +14 -14
  147. package/extensions/plan/web-tokens.ts +2 -2
  148. package/extensions/plan/web.ts +66 -120
  149. package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
  150. package/extensions/rewind/{review.ts → commands/review.ts} +15 -14
  151. package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
  152. package/extensions/rewind/{config.ts → config/config.ts} +1 -1
  153. package/extensions/rewind/index.ts +3 -3
  154. package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
  155. package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
  156. package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
  157. package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
  158. package/extensions/rewind/{format.ts → text/format.ts} +3 -3
  159. package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
  160. package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
  161. package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
  162. package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
  163. package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
  164. package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
  165. package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
  166. package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
  167. package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
  168. package/extensions/rewind/{status.ts → view/status.ts} +4 -4
  169. package/extensions/session-bus/commands.ts +17 -69
  170. package/extensions/session-bus/format.ts +22 -45
  171. package/extensions/session-bus/index.ts +13 -7
  172. package/extensions/session-bus/join-request.ts +40 -0
  173. package/extensions/session-bus/mail-watch.ts +134 -0
  174. package/extensions/session-bus/notice.ts +32 -4
  175. package/{lib/claims → extensions/session-bus}/overlap.ts +11 -18
  176. package/extensions/session-bus/protocol.ts +19 -49
  177. package/extensions/session-bus/resolve.ts +67 -0
  178. package/extensions/session-bus/result.ts +16 -51
  179. package/extensions/session-bus/rows.ts +11 -5
  180. package/extensions/session-bus/runtime.ts +220 -267
  181. package/extensions/session-bus/store.ts +55 -7
  182. package/extensions/session-bus/tools.ts +31 -66
  183. package/extensions/session-bus/tui.ts +5 -5
  184. package/extensions/session-bus/types.ts +23 -14
  185. package/extensions/subagent/agents.ts +9 -8
  186. package/extensions/subagent/commands.ts +2 -1
  187. package/extensions/subagent/invocation.ts +4 -2
  188. package/extensions/team/commands.ts +145 -0
  189. package/extensions/team/dispatch.ts +133 -0
  190. package/extensions/team/format.ts +119 -0
  191. package/extensions/team/index.ts +34 -0
  192. package/extensions/team/schema.ts +29 -0
  193. package/extensions/team/tools.ts +267 -0
  194. package/extensions/team/types.ts +65 -0
  195. package/extensions/todo/index.ts +4 -1
  196. package/extensions/todo/nudge.ts +8 -2
  197. package/extensions/web-access/fetch/page.ts +4 -1
  198. package/extensions/web-access/fetch/structured.ts +447 -0
  199. package/extensions/web-access/fetch/tool.ts +2 -1
  200. package/extensions/web-access/search/tool.ts +2 -1
  201. package/extensions/wechat/bridge.ts +106 -251
  202. package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
  203. package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
  204. package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
  205. package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
  206. package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
  207. package/extensions/wechat/dialog/channels.ts +136 -0
  208. package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +37 -37
  209. package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +2 -2
  210. package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
  211. package/extensions/wechat/index.ts +10 -10
  212. package/extensions/wechat/intake.ts +245 -0
  213. package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
  214. package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
  215. package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +100 -22
  216. package/extensions/wechat/{presence.ts → peer/presence.ts} +8 -7
  217. package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +1 -1
  218. package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
  219. package/extensions/wechat/{state.ts → state/state.ts} +14 -2
  220. package/extensions/wechat/{format.ts → text/format.ts} +3 -3
  221. package/extensions/wechat/{notices.ts → text/notices.ts} +8 -0
  222. package/extensions/wechat/tools.ts +29 -12
  223. package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
  224. package/extensions/wechat/{deliver.ts → transport/deliver.ts} +72 -28
  225. package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
  226. package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
  227. package/extensions/wechat/transport/outbound.ts +142 -0
  228. package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
  229. package/extensions/wechat/types.ts +10 -1
  230. package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
  231. package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
  232. package/extensions/worktree/commands.ts +24 -17
  233. package/extensions/worktree/exit.ts +12 -6
  234. package/extensions/worktree/git.ts +22 -14
  235. package/extensions/worktree/guard.ts +18 -290
  236. package/extensions/worktree/handoff.ts +10 -2
  237. package/extensions/worktree/index.ts +2 -1
  238. package/extensions/worktree/lifecycle.ts +2 -0
  239. package/extensions/worktree/registry.ts +20 -11
  240. package/extensions/worktree/root-tools.ts +13 -3
  241. package/extensions/worktree/runtime.ts +8 -2
  242. package/extensions/worktree/screen.ts +15 -8
  243. package/extensions/worktree/shell.ts +303 -0
  244. package/extensions/worktree/state.ts +1 -1
  245. package/extensions/worktree/status.ts +42 -9
  246. package/extensions/worktree/tools.ts +19 -13
  247. package/lib/README.md +11 -8
  248. package/lib/board/card.ts +479 -0
  249. package/lib/board/links.ts +141 -0
  250. package/lib/board/page-pointer.ts +310 -0
  251. package/lib/board/round-text.ts +81 -0
  252. package/lib/board/round.ts +94 -0
  253. package/lib/board/rules.ts +437 -0
  254. package/lib/board/session.ts +105 -0
  255. package/lib/board/store.ts +497 -0
  256. package/lib/board/view.ts +234 -0
  257. package/lib/errors.ts +12 -4
  258. package/lib/format.ts +35 -0
  259. package/lib/http/guard.ts +112 -0
  260. package/lib/http/index.ts +16 -5
  261. package/lib/http/serve.ts +237 -0
  262. package/lib/http/server.ts +12 -10
  263. package/lib/http/sink.ts +135 -0
  264. package/lib/http/token.ts +38 -0
  265. package/lib/plan-entry.ts +11 -0
  266. package/lib/policy.ts +25 -2
  267. package/lib/requirements.ts +6 -7
  268. package/lib/session-label.ts +64 -0
  269. package/lib/session-roster.ts +201 -0
  270. package/lib/session-tool.ts +184 -0
  271. package/lib/spawn.ts +37 -3
  272. package/lib/stray-fields.ts +45 -0
  273. package/lib/tool-names.ts +38 -2
  274. package/lib/tui/glyphs.ts +3 -2
  275. package/lib/web/README.md +57 -4
  276. package/lib/web/client-runtime.ts +123 -0
  277. package/lib/web/components.ts +5 -0
  278. package/lib/web/index.ts +4 -2
  279. package/lib/web/markup.ts +88 -1
  280. package/lib/web/names.ts +42 -0
  281. package/lib/web/runtime.ts +7 -1
  282. package/lib/web/tokens.ts +25 -2
  283. package/package.json +26 -14
  284. package/skills/next/SKILL.md +4 -3
  285. package/skills/project-docs/SKILL.md +133 -0
  286. package/skills/project-docs/references/audit.md +131 -0
  287. package/skills/project-docs/references/changelog.md +105 -0
  288. package/skills/project-docs/references/discovery.md +127 -0
  289. package/skills/project-docs/references/readme.md +80 -0
  290. package/skills/project-docs/references/release.md +84 -0
  291. package/skills/project-docs/references/roadmap.md +93 -0
  292. package/skills/project-docs/scripts/state.ts +316 -0
  293. package/skills/refactor/SKILL.md +100 -125
  294. package/skills/refactor/references/handoff.md +35 -0
  295. package/skills/refactor/references/signals.md +54 -0
  296. package/skills/refactor/scripts/inventory.ts +587 -0
  297. package/extensions/bytefly/panel/tui/extensions-view.ts +0 -40
  298. package/extensions/bytefly/panel/tui/skills-view.ts +0 -50
  299. package/extensions/file-browse/README.md +0 -506
  300. package/extensions/file-browse/files.ts +0 -564
  301. package/extensions/file-browse/server.ts +0 -141
  302. package/extensions/job/process.ts +0 -35
  303. package/extensions/plan/split.ts +0 -87
  304. package/extensions/session-bus/README.md +0 -247
  305. package/extensions/session-bus/team.ts +0 -102
  306. package/extensions/wechat/outbound.ts +0 -100
  307. package/lib/plans/sections.ts +0 -172
  308. package/lib/plans/setting.ts +0 -52
  309. package/lib/plans/split.ts +0 -215
  310. package/lib/plans/store.ts +0 -19
  311. package/lib/plans/team.ts +0 -151
  312. package/skills/changelog/SKILL.md +0 -148
  313. package/skills/parallel-dev/SKILL.md +0 -150
  314. /package/extensions/file-browse/{rev.ts → live/rev.ts} +0 -0
  315. /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
  316. /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
  317. /package/extensions/file-browse/{live-client.ts → view/live-client.ts} +0 -0
  318. /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
  319. /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
  320. /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
  321. /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
  322. /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
  323. /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
  324. /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
@@ -4,40 +4,48 @@ A single model-facing tool, `ask_user_question`, that lets the model ask the
4
4
  human one or more structured questions mid-turn and wait for typed answers.
5
5
  Modelled on Claude Code's `AskUserQuestion`.
6
6
 
7
- <img src="../../assets/question.png" alt="The ask_user_question dialog: Auth and Scope tabs, a question, four numbered options with descriptions, and the navigation hint" width="100%">
7
+ <img src="../../assets/screens/question.png" alt="The ask_user_question dialog: Auth and Scope tabs, a question, four numbered options with descriptions, and the navigation hint" width="100%">
8
8
 
9
- ```
9
+ ## Capabilities
10
+
11
+ Status records what a reader can rely on: **Shipped** is in a tagged release, **Unreleased** is complete in the current tree but not yet tagged, and **Partial** has one released part and one unreleased part. Rows are ordered by user value, highest first.
12
+
13
+ | Capability | How | What you get | Status |
14
+ |---|---|---|---|
15
+ | Mid-turn asking | `ask_user_question` | The model asks 1–4 questions and the turn waits until you answer or cancel. | Shipped |
16
+ | Labelled options | `questions[].options` | Each question offers up to four choices, each with an optional second line describing it. | Shipped |
17
+ | Free-form answers | the automatic `Other (type something)` row, `questions[].options` omitted | You can type an answer the options do not cover, and a question with no options asks for plain text. | Shipped |
18
+ | Multiple selections | `questions[].multiSelect` | `Space` toggles options and `Enter` confirms the set. | Shipped |
19
+ | Batched questions | `questions[]` | Up to four questions ride in one call and are answered in one pass. | Shipped |
20
+ | Submit gating | the `Submit` tab | Submit refuses until every question is answered and names the missing ones; a single question submits on `Enter` without a Submit tab. | Shipped |
21
+ | Tab headers | `questions[].header` | Each question gets a short tab label, defaulted to `Q{n}` and clipped to 12 columns. | Shipped |
22
+ | Language-aware batch | `dialogUI.language` | A remote turn in Chinese gets the batch prompt, retry text, and format line in Chinese. | Shipped |
23
+ | Dialog fallback | `select`, `input`, `editor` | RPC and remote turns answer the same questions without the TUI screen. | Shipped |
24
+ | No-UI degradation | `print`, `json` | The tool returns `unavailable` with an error instead of hanging when no dialog channel exists. | Shipped |
25
+ | Cancelling | `Esc` | The model is told you cancelled and can continue or ask in prose. | Shipped |
26
+ | Branch-scoped answers | tool-result `details` | The answers stay with the transcript, so `/resume` and `/tree` show the same history. | Shipped |
27
+
28
+ ## Quickstart
29
+
30
+ ```bash
10
31
  pi --extension ./extensions/question # load just this extension
11
32
  pi -e . # load the whole @gavin-hu/my-pi-agent package
12
33
  pi install ./ # install the package
13
34
  ```
14
35
 
15
- ## Tool rendering
36
+ The tool is declared in every session and activated where a UI exists, so ask
37
+ the model for a decision and the questionnaire takes the screen.
16
38
 
17
- How the `ask_user_question` call and its result look in the transcript — the call line as a headline and the body indented under it:
39
+ ## Tool
18
40
 
19
41
  <img src="../../assets/tools/ask_user_question.png" alt="The ask_user_question tool's call and result: the call line and an indented body with the question headers, the options, and the answers" width="100%">
20
42
 
21
- ## What it does
22
-
23
43
  The model calls `ask_user_question` with 1–4 questions. Each question offers up
24
44
  to four labelled options (plus an automatic **“Other (type something)”** free-form
25
45
  entry); a question with no options asks for free-form text. The tool blocks until
26
46
  the user answers or cancels, then returns the answers as text the model can act
27
47
  on.
28
48
 
29
- - Multiple questions: a tab bar, per-question answered indicators, and a Submit
30
- tab that refuses to submit until every question is answered.
31
- - `multiSelect: true`: `Space` toggles options, `Enter` confirms the set. On the
32
- `Other` row `Space` opens the editor, like `Enter`.
33
- - `Esc` cancels; the model receives “User cancelled the question.” and can
34
- continue or ask in prose.
35
- - On a dialog-only host (RPC/WeChat), one question uses the normal select/input.
36
- Two or more become one batch editor prompt and one reply (`1: 2; 2: A, B`),
37
- with one retry if the format is unclear; the TUI keeps its tabbed screen.
38
-
39
- ## Tool
40
-
41
49
  | | |
42
50
  |---|---|
43
51
  | Name | `ask_user_question` |
@@ -90,22 +98,37 @@ ask_user_question 2 questions (Auth, Scope)
90
98
  ✓ Format: (wrote) json for logs
91
99
  ```
92
100
 
101
+ ### The questionnaire
102
+
103
+ - Multiple questions: a tab bar, per-question answered indicators, and a Submit
104
+ tab that refuses to submit until every question is answered.
105
+ - `multiSelect: true`: `Space` toggles options, `Enter` confirms the set. On the
106
+ `Other` row `Space` opens the editor, like `Enter`.
107
+ - `Esc` cancels; the model receives “User cancelled the question.” and can
108
+ continue or ask in prose.
109
+
93
110
  ## Behaviour by mode
94
111
 
95
- | Mode | Behavior |
112
+ | Mode | Behaviour |
96
113
  |---|---|
97
114
  | Interactive TUI (local turn) | Full tabbed questionnaire with descriptions, multi-select, and an inline editor |
98
115
  | RPC (`hasUI`) | Forwarded dialogs: `select` per question, `input` for “Other”/free-form, `editor` for multi-select |
99
116
  | Remote turn (WeChat) | Same forwarded dialogs, routed to the remote channel by the `ctx.ui` adapter; the full-screen component is skipped |
100
117
  | `print` / `json` | The tool is registered inactive (`defaultActive: false`) and never switched on; if invoked anyway it returns a clear error telling the model to ask in prose |
101
118
 
119
+ On a dialog-only host, two or more questions become one batch editor prompt and
120
+ one reply (`1: 2; 2: A, B`), with one retry if the format is unclear; the TUI
121
+ keeps its tabbed screen.
122
+
102
123
  Whether a turn uses the rich component or dialogs is decided by
103
- `askHuman(ctx, { custom, dialogs })` from `lib/interaction.ts`, not by reading
104
- `ctx.mode`; a remote-answered turn reports no custom-UI support.
124
+ `askHuman(ctx, { custom, dialogs })` from
125
+ [`lib/interaction.ts`](../../lib/interaction.ts), not by reading `ctx.mode`; a
126
+ remote-answered turn reports no custom-UI support.
105
127
 
106
128
  ## Configuration
107
129
 
108
- None in v1 — the tool is either available (a UI exists) or not.
130
+ None. There are no keys: the tool is available exactly when the session has a
131
+ UI.
109
132
 
110
133
  ## Limitations
111
134
 
@@ -173,7 +196,7 @@ None in v1 — the tool is either available (a UI exists) or not.
173
196
  - **Transcript rendering is driven by `details`.** `renderCall` summarises the
174
197
  question count and headers and lists one option line per question;
175
198
  `renderResult` renders `✓ Auth: 1. OAuth` per answer, `(wrote)` for custom
176
- text, warning-colored `Cancelled`, and error-colored `No UI` when unavailable
199
+ text, warning-coloured `Cancelled`, and error-coloured `No UI` when unavailable
177
200
  (matching the result rail its `isError` draws). The call
178
201
  summary reads the call's *streaming* args, so a field that has not arrived yet
179
202
  — a question `header`, an option `label` — reads as absent instead of
@@ -184,14 +207,14 @@ None in v1 — the tool is either available (a UI exists) or not.
184
207
 
185
208
  | File | Responsibility |
186
209
  |---|---|
187
- | `index.ts` | Extension factory: register the tool, gate it by UI availability |
188
- | `schema.ts` | TypeBox parameters, validation, defaulting (pure) |
189
- | `types.ts` | Shared raw/normalized types |
190
- | `answers.ts` | Answer normalization and model-facing formatting (pure) |
191
- | `tui-state.ts` | Pure keyboard/navigation state machine |
192
- | `tui.ts` | Custom terminal component (render + input), drawn from the `lib/tui/` kit (`titleRule`/`plainRule`, `checkbox`, `flowCells`, `screenHint`, `editorTheme`). |
193
- | `dialogs.ts` | `select`/`input`/`editor` fallback driver |
194
- | `tools.ts` | Tool registration and transcript renderers |
210
+ | [`index.ts`](../../extensions/question/index.ts) | Extension factory: register the tool, gate it by UI availability |
211
+ | [`schema.ts`](../../extensions/question/schema.ts) | TypeBox parameters, validation, defaulting (pure) |
212
+ | [`types.ts`](../../extensions/question/types.ts) | Shared raw/normalized types |
213
+ | [`answers.ts`](../../extensions/question/answers.ts) | Answer normalization and model-facing formatting (pure) |
214
+ | [`tui-state.ts`](../../extensions/question/tui-state.ts) | Pure keyboard/navigation state machine |
215
+ | [`tui.ts`](../../extensions/question/tui.ts) | Custom terminal component (render + input), drawn from the `lib/tui/` kit (`titleRule`/`plainRule`, `checkbox`, `flowCells`, `screenHint`, `editorTheme`). |
216
+ | [`dialogs.ts`](../../extensions/question/dialogs.ts) | `select`/`input`/`editor` fallback driver |
217
+ | [`tools.ts`](../../extensions/question/tools.ts) | Tool registration and transcript renderers |
195
218
 
196
219
  ## Testing
197
220
 
@@ -2,92 +2,93 @@
2
2
 
3
3
  Snapshot the working tree at the start of each task and return to an earlier
4
4
  prompt from a menu — restoring the **code**, the **conversation**, or **both**.
5
- `/review` uses the same snapshot to show the latest turn's changes and revert one
6
- file or the whole turn. A snapshot is a git commit kept under
7
- `refs/pi/rewind/<id>`; restoring one rewrites the working tree **without
8
- touching the real index or moving HEAD**, so commits, branches, staged state, and
9
- the reflog are untouched. Conversation rewind uses Pi's session tree, so the
10
- branch you leave is not erased.
11
-
12
- This is the `rewind` extension entrypoint; it is one of two sibling git
13
- extensions in this package (`worktree` is the other).
14
-
15
- <img src="../../assets/rewind.png" alt="The /rewind screen: prompt rows newest first, a diamond marking prompts with a code snapshot, and the focused prompt's snapshot detail" width="100%">
16
-
17
- <img src="../../assets/review.png" alt="The /review screen: changed files with M, A, and D marks, line counts, and the focused file's detail" width="100%">
18
-
19
- ```
20
- pi --extension ./extensions/rewind # load this extension alone
5
+ Snapshots are git commits under `refs/pi/rewind/<id>`, so restoring one rewrites
6
+ the working tree without touching the real index or moving HEAD, and a
7
+ conversation rewind moves Pi's session tree without erasing the branch you leave.
8
+ `/review` uses the same snapshot to show the latest turn's changes and revert a
9
+ file, a selection, or the whole turn.
10
+
11
+ <img src="../../assets/screens/rewind.png" alt="The /rewind screen: prompt rows newest first, a diamond marking prompts with a code snapshot, and a detail line naming the snapshot the focused prompt holds" width="100%">
12
+
13
+ ## Capabilities
14
+
15
+ Status records what a reader can rely on: **Shipped** is in a tagged release, **Unreleased** is complete in the current tree but not yet tagged, and **Partial** has one released part and one unreleased part. Rows are ordered by user value, highest first.
16
+
17
+ | Capability | How | What you get | Status |
18
+ |---|---|---|---|
19
+ | Automatic snapshots | the `autoSnapshots` key | One snapshot per prompt, taken before its first mutating call, so every task has a restore point. | Shipped |
20
+ | Durable snapshots | `refNamespace` | Snapshots survive the session and are listed from git rather than from session state. | Shipped |
21
+ | Prompt timeline | `/rewind` | Every user prompt on the active branch, newest first, marked `⬥` where a code snapshot was captured. | Shipped |
22
+ | Scoped restore | `/rewind` | Code, conversation, or both, from the prompt you pick. | Shipped |
23
+ | Undoable restore | the `safetySnapshot` key | A code restore snapshots the state it replaces first, so it can itself be undone. | Shipped |
24
+ | Partial restore | `/rewind` | The changed paths grouped by directory, chosen with a checklist, and previewed as the subset you selected. | Shipped |
25
+ | Latest-turn review | `/review` | The changed files of the latest prompt, with `M`/`A`/`D`/`R` marks and line counts. | Shipped |
26
+ | File, batch, and hunk revert | `/review` | Revert one file, a selection, the whole turn, or chosen hunks, each with its own safety snapshot. | Shipped |
27
+ | Busy-git refusal | `/rewind`, `/review` | A merge, rebase, cherry-pick, revert, or bisect in progress refuses the restore instead of fighting it. | Shipped |
28
+ | Root-scoped snapshots | `refs/pi/rewind` | Worktrees share the ref store, while another root's snapshot is filtered out and refused. | Shipped |
29
+ | Untracked capture | `autoSnapshots` | Non-ignored untracked files are captured, and a restore removes the ones that appeared after the snapshot. | Shipped |
30
+ | Ref cap and auto-prune | `max`, `autoPrune` | The snapshot store is bounded and pruned instead of growing without limit. | Shipped |
31
+ | Review plan guard | `/review` in plan mode | Review refuses while plan mode is on, matching the read-only planning rule. | Shipped |
32
+ | Prompt-count chip | `↺ N`, the `showStatus` key | The status bar counts the prompts on the active branch, whether or not each has a snapshot. | Shipped |
33
+
34
+ ## Quickstart
35
+
36
+ ```bash
37
+ pi --extension ./extensions/rewind # load just this extension
21
38
  pi -e . # load the whole @gavin-hu/my-pi-agent package
22
39
  pi install ./ # install the package
23
40
  ```
24
41
 
25
- ## What it does
26
-
27
- - Takes **one automatic snapshot per user prompt**, before the prompt's first
28
- mutating tool call. A read-only prompt snapshots nothing.
29
- - `/review` compares the working tree with the snapshot taken before the latest
30
- prompt on the active branch. The file list carries `M`/`A`/`D`/`R` and line
31
- counts; `Enter` opens a scrollable patch, `Space` selects files, `r` reverts
32
- the selection (or the focused file when nothing is selected), and `R` reverts
33
- every changed path. A modified text file's diff offers `h`, which opens a hunk
34
- checklist; the chosen hunks revert as one reverse patch with its own
35
- pre-restore safety snapshot. A rename is one `R` row, so reverting it restores
36
- the old path and removes the new one together. A selected batch is one restore
37
- and one pre-restore safety snapshot, not one per file. When the working tree
38
- matches HEAD, the screen says the changes are already committed and a revert
39
- leaves the commits in place.
40
- - `/rewind` lists **every user prompt on the active branch** (newest first), each
41
- marked `⬥` when a code snapshot was captured for it.
42
- - Picking a point asks what to restore: **Code and conversation**,
43
- **Conversation only**, or **Code only**.
44
- - *Code* rewrites the working tree to the snapshot and is itself undoable
45
- (a `pre-restore` safety snapshot is taken first).
46
- - When code moves, a second step asks **Restore what?** — **Everything (N
47
- files)** or **Choose paths…**. The checklist lists every changed path
48
- grouped by directory (`M` modified, `D` deleted since the snapshot, `A`
49
- created after it, `R` renamed), with all of them selected, so `Enter` twice
50
- reproduces a whole-tree restore. `Space` toggles a file or a directory,
51
- `a`/`n` select all/none, and the confirm that follows previews only the
52
- chosen subset.
53
- - *Conversation* moves the session tree back to that prompt and puts the
54
- prompt text back in the editor; the abandoned branch stays in the session.
55
- - Shows a `↺ N` status chip counting the prompts on the active branch — the
56
- same points `/rewind` lists (its list size), whether or not each has a code
57
- snapshot.
58
- - Stores metadata in the commit body, so snapshots survive across sessions and
59
- are listed from git rather than from session state.
42
+ ```text
43
+ /rewind # pick a prompt, then a scope, then the paths
44
+ /review # the latest turn's changes, ready to revert
45
+ ```
60
46
 
61
- Snapshots include tracked files plus (by default) untracked, non-ignored files.
62
- `.gitignore`d files are never captured. Because refs live in the shared git
63
- directory, a snapshot taken inside a [`worktree`](../worktree/) is visible from
64
- the main checkout; `list`/matching filter to the current root by default.
47
+ Nothing is registered for the model: snapshots are taken automatically, and both
48
+ commands are user-driven.
65
49
 
66
- ## Command
50
+ ## Commands
67
51
 
68
52
  | Command | What it does |
69
53
  |---|---|
70
54
  | `/rewind` | Open the timeline; pick a prompt, then a restore scope, then (for code) the paths. |
71
55
  | `/review` | Review the latest prompt's changes; open a diff, select files with `Space`, revert the selection or all files, or revert chosen hunks with `h`. |
72
56
 
73
- The path checklist is its own `ctx.ui.custom` screen: `Space` toggles the focused
74
- row, `a`/`n` select all or none, `Enter` returns the selection, and `Esc` cancels
75
- the rewind.
57
+ The timeline is keyboard-driven: `↑`/`↓` or `j`/`k` move,
58
+ `PgUp`/`PgDn`/`Home`/`End` jump, `Enter` chooses the focused prompt, the mouse
59
+ wheel scrolls, and `Esc` closes. The scope choice and the confirmation (with a
60
+ diff preview) run after the screen closes. Picking a point asks what to restore:
61
+ **Code and conversation**, **Conversation only**, or **Code only**. A conversation
62
+ rewind moves the session tree back to that prompt and puts the prompt text back in
63
+ the editor; the abandoned branch stays in the session.
64
+
65
+ When code moves and more than one path changed, a second step asks **Restore
66
+ what?** — **Everything (N files)** or **Choose paths…**. The path checklist is
67
+ its own `ctx.ui.custom` screen: it lists every changed path grouped by directory
68
+ (`M` modified, `D` deleted since the snapshot, `A` created after it, `R`
69
+ renamed), with all of them selected, so `Enter` twice reproduces a whole-tree
70
+ restore. `Space` toggles a file or a directory, `a`/`n` select all or none, and
71
+ `Enter` returns the selection. The confirm that follows previews only the chosen
72
+ subset.
73
+
74
+ <img src="../../assets/screens/review.png" alt="The /review screen: changed files with M, A, and D marks, line counts, and the focused file's detail" width="100%">
75
+
76
+ `/review` compares the working tree with the snapshot taken before the latest
77
+ prompt on the active branch. The list is keyboard-driven too: `↑`/`↓` or `j`/`k`
78
+ move, `PgUp`/`PgDn` and `Home`/`End` jump, `Space` toggles the focused file,
79
+ `a`/`n` select all or none, `Enter` opens the focused file's diff, `r` reverts the
80
+ selection (or the focused file when nothing is selected), `R` reverts every
81
+ changed path, and `Esc` closes. A selected batch is one restore and one
82
+ pre-restore safety snapshot, not one per file. A rename is one `R` row, so
83
+ reverting it restores the old path and removes the new one together.
76
84
 
77
- The timeline is keyboard-driven: `↑`/`↓` or `j`/`k` move, `PgUp`/`PgDn`/`Home`/`End`
78
- jump, `Enter` chooses the focused prompt, the mouse wheel scrolls, `Esc` closes.
79
- The scope choice and the confirmation (with a diff preview) run after the screen
80
- closes. The path checklist is the same grammar: `Space` toggles, `a`/`n` select
81
- all or none, `Enter` restores the selection, `Esc` cancels the rewind.
82
-
83
- The review list is keyboard-driven too: `↑`/`↓` or `j`/`k` move, `PgUp`/`PgDn` and
84
- `Home`/`End` jump, `Space` toggles the focused file, `a`/`n` select all or none,
85
- `Enter` opens the focused file's diff, `r` reverts the selection (or the focused
86
- file when nothing is selected), `R` reverts every changed path, and `Esc` closes.
87
85
  In the diff, `j`/`k`, the arrows, `PgUp`/`PgDn`, and `g`/`G` scroll, `r` reverts
88
86
  the file, and `Esc` goes back. A modified text file's diff offers `h` for the
89
87
  hunk checklist: `Space` toggles, `a`/`n` select all or none, `Enter` reverts the
90
- chosen hunks, and `Esc` cancels back to the diff.
88
+ chosen hunks, and `Esc` cancels back to the diff. The chosen hunks revert as one
89
+ reverse patch with its own pre-restore safety snapshot. When the working tree
90
+ matches HEAD, the screen says the changes are already committed and a revert
91
+ leaves the commits in place.
91
92
 
92
93
  ## Behaviour by mode
93
94
 
@@ -99,40 +100,32 @@ chosen hunks, and `Esc` cancels back to the diff.
99
100
 
100
101
  ## Configuration
101
102
 
102
- The `rewind` section of the shared `bytefly.json` (global document, then
103
- `<root>/.pi/bytefly.json`, project wins).
104
-
105
- ```json
106
- // bytefly.json → "rewind"
107
- {
108
- "autoSnapshots": true,
109
- "max": 20,
110
- "includeUntracked": true,
111
- "safetySnapshot": true,
112
- "autoPrune": true,
113
- "showStatus": true,
114
- "watch": [],
115
- "ignore": [],
116
- "refNamespace": "refs/pi/rewind"
117
- }
118
- ```
119
-
120
- | Key | Meaning |
121
- |---|---|
122
- | `autoSnapshots` | Take one automatic snapshot per prompt. Default `true`. |
123
- | `max` | Snapshot refs kept per root; automatic and pre-restore safety snapshots both count. |
124
- | `includeUntracked` | Capture untracked, non-ignored files. |
125
- | `safetySnapshot` | Save the current state before a code restore. |
126
- | `autoPrune` | Delete the oldest refs beyond `max` after an automatic snapshot. |
127
- | `showStatus` | Draw the `↺ N` status chip. |
128
- | `watch` | Extra tool names to treat as mutating. |
129
- | `ignore` | Tool names never to snapshot; this package's own tools are always excluded. |
130
- | `refNamespace` | Ref namespace for stored snapshots. |
103
+ The `rewind` section of the shared `bytefly.json`; resolution rules are in
104
+ [`../configuration.md`](../configuration.md#rewind--snapshots).
105
+
106
+ | Key | Default | Meaning |
107
+ |---|---|---|
108
+ | `autoSnapshots` | `true` | Take one automatic snapshot per prompt. |
109
+ | `max` | `20` | Snapshot refs kept per root; automatic and pre-restore safety snapshots both count. |
110
+ | `includeUntracked` | `true` | Capture untracked, non-ignored files. |
111
+ | `safetySnapshot` | `true` | Save the current state before a code restore. |
112
+ | `autoPrune` | `true` | Delete the oldest refs beyond `max` after an automatic snapshot. |
113
+ | `showStatus` | `true` | Draw the `↺ N` status chip. |
114
+ | `watch` | `[]` | Extra tool names to treat as mutating. |
115
+ | `ignore` | `[]` | Tool names never to snapshot; this package's own tools are always excluded. |
116
+ | `refNamespace` | `"refs/pi/rewind"` | Ref namespace for stored snapshots. |
131
117
 
132
118
  A restore's safety snapshot is not pruned immediately, so the snapshot it
133
119
  restored from stays available for a follow-up restore; the next automatic
134
120
  snapshot applies the cap.
135
121
 
122
+ ## What a snapshot captures
123
+
124
+ Snapshots include tracked files plus (by default) untracked, non-ignored files.
125
+ `.gitignore`d files are never captured. Because refs live in the shared git
126
+ directory, a snapshot taken inside a [`worktree`](./worktree.md) is visible from
127
+ the main checkout; `list`/matching filter to the current root by default.
128
+
136
129
  ## How snapshots are stored
137
130
 
138
131
  Each snapshot is a commit under `refs/pi/rewind/<id>` whose body carries a
@@ -272,26 +265,26 @@ commit. These refs are not branches and are not touched by `git push --all`.
272
265
  |---|---|
273
266
  | `index.ts` | Registrar: wire the runtime, the commands, and the run-state module to Pi's events (`registerRewind`). |
274
267
  | `types.ts` | `Snapshot`, `SnapshotReason`, `RestoreSummary`. |
275
- | `config.ts` | Config defaults and merge/normalize over `lib/config.ts`. |
276
- | `git.ts` | Single git entry point: rewind plumbing, the shared read helpers rewind consumes (name status, stat, patch, and `--numstat`), the reverse apply a hunk revert uses, and the production `RunGit`. |
277
- | `snapshot.ts` | Create a snapshot (tree from a temporary index → commit → ref). |
278
- | `snapshot-run.ts` | Per-run automatic-snapshot state: one snapshot per prompt, with a synchronous guard. |
279
- | `restore.ts` | Plan and apply a working-tree rewind, whole or for a chosen subset of paths, recreating a rename's source and removing its destination. |
280
- | `paths.ts` | Pure: the changed-path list from `git diff --name-status` (a rename is one paired entry), its directory grouping, the change marks, the `--numstat` counts, and the restore counts. |
281
- | `checklist.ts` | The shared multi-select checklist screen: the cursor, `Space`/`a`/`n`/`Enter`, the height math, and the dock frame. The three checklists below supply only their rows and their words. |
282
- | `path-picker.ts` | The partial restore's checklist, a `ChecklistScreen` over grouped paths: directory toggles, the change marks, and the selection it returns. |
283
- | `patch.ts` | Pure: split a single-file unified diff into its header and hunks, and rebuild a patch from chosen hunks. |
284
- | `hunk-picker.ts` | The hunk checklist a modified file's diff opens, a `ChecklistScreen` over the hunks: previews, the indices it returns, and its own row budget. |
285
- | `store.ts` | Versioned metadata encoding and ref-backed listing/pruning. |
286
- | `policy.ts` | Which tool calls are worth a snapshot. |
287
- | `temp-index.ts` | Per-process `GIT_INDEX_FILE` paths: create, release, and sweep stale files. |
288
- | `status.ts` | The `↺ N` status chip. |
289
- | `queue.ts` | The serialized git operation queue for staging calls (`GIT_INDEX_FILE`). |
290
- | `runtime.ts` | Root/config caches and the snapshot/list/plan/patch/numstat/restore/hunk-revert operations. |
291
- | `timeline.ts` | Pure: prompts on the branch, paired with their snapshots. |
292
- | `rewind.ts` | Scope choice, the path step, confirmation, and applying code + conversation rewind. |
293
- | `review.ts` | The `/review` orchestration: the latest snapshot, the list/diff loop, the hunk step, confirmations, and the reverts. |
294
- | `review-tui.ts` | The changed-file list (a `ChecklistScreen`) and the scrollable per-file diff, which offers the hunk checklist. |
295
- | `rewind-tui.ts` | The selectable, width-safe timeline component, drawn from the `lib/tui/` kit (`titleRule`, `dockListFrame`, `listRow`, `emptyState`). |
296
- | `commands.ts` | The `/rewind` and `/review` commands. |
297
- | `format.ts` | Pure rewind and review text, including diff bounding and the hunk prompt. |
268
+ | `config/config.ts` | Config defaults and merge/normalize over `lib/config.ts`. |
269
+ | `transport/git.ts` | Single git entry point: rewind plumbing, the shared read helpers rewind consumes (name status, stat, patch, and `--numstat`), the reverse apply a hunk revert uses, and the production `RunGit`. |
270
+ | `transport/snapshot.ts` | Create a snapshot (tree from a temporary index → commit → ref). |
271
+ | `state/snapshot-run.ts` | Per-run automatic-snapshot state: one snapshot per prompt, with a synchronous guard. |
272
+ | `transport/restore.ts` | Plan and apply a working-tree rewind, whole or for a chosen subset of paths, recreating a rename's source and removing its destination. |
273
+ | `text/paths.ts` | Pure: the changed-path list from `git diff --name-status` (a rename is one paired entry), its directory grouping, the change marks, the `--numstat` counts, and the restore counts. |
274
+ | `view/checklist.ts` | The shared multi-select checklist screen: the cursor, `Space`/`a`/`n`/`Enter`, the height math, and the dock frame. The three checklists below supply only their rows and their words. |
275
+ | `view/path-picker.ts` | The partial restore's checklist, a `ChecklistScreen` over grouped paths: directory toggles, the change marks, and the selection it returns. |
276
+ | `text/patch.ts` | Pure: split a single-file unified diff into its header and hunks, and rebuild a patch from chosen hunks. |
277
+ | `view/hunk-picker.ts` | The hunk checklist a modified file's diff opens, a `ChecklistScreen` over the hunks: previews, the indices it returns, and its own row budget. |
278
+ | `transport/store.ts` | Versioned metadata encoding and ref-backed listing/pruning. |
279
+ | `state/policy.ts` | Which tool calls are worth a snapshot. |
280
+ | `transport/temp-index.ts` | Per-process `GIT_INDEX_FILE` paths: create, release, and sweep stale files. |
281
+ | `view/status.ts` | The `↺ N` status chip. |
282
+ | `transport/queue.ts` | The serialized git operation queue for staging calls (`GIT_INDEX_FILE`). |
283
+ | `state/runtime.ts` | Root/config caches and the snapshot/list/plan/patch/numstat/restore/hunk-revert operations. |
284
+ | `state/timeline.ts` | Pure: prompts on the branch, paired with their snapshots. |
285
+ | `commands/rewind.ts` | Scope choice, the path step, confirmation, and applying code + conversation rewind. |
286
+ | `commands/review.ts` | The `/review` orchestration: the latest snapshot, the list/diff loop, the hunk step, confirmations, and the reverts. |
287
+ | `view/review-tui.ts` | The changed-file list (a `ChecklistScreen`) and the scrollable per-file diff, which offers the hunk checklist. |
288
+ | `view/rewind-tui.ts` | The selectable, width-safe timeline component, drawn from the `lib/tui/` kit (`titleRule`, `dockListFrame`, `listRow`, `emptyState`). |
289
+ | `commands/commands.ts` | The `/rewind` and `/review` commands. |
290
+ | `text/format.ts` | Pure rewind and review text, including diff bounding and the hunk prompt. |