@gavin-hu/my-pi-agent 0.18.0 → 0.19.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 (249) hide show
  1. package/README.md +52 -44
  2. package/README.zh-CN.md +46 -41
  3. package/docs/extensions/README.md +34 -0
  4. package/docs/extensions/board.md +344 -0
  5. package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +446 -404
  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 +554 -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} +61 -50
  13. package/{extensions/memory/README.md → docs/extensions/memory.md} +71 -60
  14. package/{extensions/plan/README.md → docs/extensions/plan.md} +390 -317
  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 +285 -0
  18. package/{extensions/subagent/README.md → docs/extensions/subagent.md} +165 -118
  19. package/docs/extensions/team.md +226 -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} +258 -162
  24. package/{extensions/worktree/README.md → docs/extensions/worktree.md} +115 -72
  25. package/extensions/board/commands.ts +87 -0
  26. package/extensions/board/config.ts +36 -0
  27. package/extensions/board/format.ts +72 -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 +312 -0
  32. package/extensions/board/result.ts +99 -0
  33. package/extensions/board/rows.ts +48 -0
  34. package/extensions/board/schema.ts +75 -0
  35. package/extensions/board/seat.ts +29 -0
  36. package/extensions/board/snapshot.ts +41 -0
  37. package/extensions/board/tools.ts +279 -0
  38. package/extensions/board/transport/router.ts +172 -0
  39. package/extensions/board/transport/server.ts +149 -0
  40. package/extensions/board/types.ts +54 -0
  41. package/extensions/board/view/actions.ts +306 -0
  42. package/extensions/board/view/client.ts +41 -0
  43. package/extensions/board/view/keys.ts +121 -0
  44. package/extensions/board/view/live.ts +397 -0
  45. package/extensions/board/view/page.ts +158 -0
  46. package/extensions/board/view/render.ts +496 -0
  47. package/extensions/board/view/styles.ts +211 -0
  48. package/extensions/board/view/team.ts +305 -0
  49. package/extensions/board/writes.ts +99 -0
  50. package/extensions/bytefly/panel/commands.ts +40 -7
  51. package/extensions/bytefly/panel/settings-runtime.ts +0 -6
  52. package/extensions/bytefly/panel/settings.ts +3 -20
  53. package/extensions/bytefly/panel/tui/settings-view.ts +1 -1
  54. package/extensions/bytefly/picker/discovery.ts +0 -2
  55. package/extensions/bytefly/picker/types.ts +0 -2
  56. package/extensions/bytefly/update/check.ts +39 -0
  57. package/extensions/bytefly/update/format.ts +15 -0
  58. package/extensions/bytefly/update/register.ts +73 -34
  59. package/extensions/bytefly/update/state.ts +6 -3
  60. package/extensions/context/tui.ts +1 -1
  61. package/extensions/file-browse/{config.ts → config/config.ts} +1 -1
  62. package/extensions/file-browse/{files.ts → files/files.ts} +1 -14
  63. package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
  64. package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
  65. package/extensions/file-browse/index.ts +4 -4
  66. package/extensions/file-browse/{live.ts → live/live.ts} +20 -69
  67. package/extensions/file-browse/{router.ts → transport/router.ts} +21 -15
  68. package/extensions/file-browse/transport/server.ts +110 -0
  69. package/extensions/file-browse/{chrome.ts → view/chrome.ts} +4 -4
  70. package/extensions/file-browse/{client.ts → view/client.ts} +1 -1
  71. package/extensions/file-browse/{diff-html.ts → view/diff-html.ts} +3 -3
  72. package/extensions/file-browse/{html.ts → view/html.ts} +14 -12
  73. package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
  74. package/extensions/file-browse/{markdown.ts → view/markdown.ts} +7 -7
  75. package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +1 -1
  76. package/extensions/file-browse/{styles.ts → view/styles.ts} +29 -5
  77. package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
  78. package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
  79. package/extensions/file-read/schema.ts +2 -1
  80. package/extensions/memory/store.ts +12 -5
  81. package/extensions/plan/blocks.ts +23 -2
  82. package/extensions/plan/commands.ts +21 -16
  83. package/extensions/plan/feedback.ts +147 -38
  84. package/extensions/plan/index.ts +6 -4
  85. package/extensions/plan/plan-index.ts +43 -9
  86. package/extensions/plan/plan-text.ts +33 -23
  87. package/extensions/plan/plans.ts +8 -11
  88. package/extensions/plan/policy.ts +20 -12
  89. package/extensions/plan/review.ts +3 -27
  90. package/extensions/plan/runtime.ts +21 -9
  91. package/extensions/plan/sections.ts +112 -0
  92. package/extensions/plan/steps.ts +3 -22
  93. package/extensions/plan/tools/exit.ts +11 -95
  94. package/extensions/plan/tui.ts +5 -34
  95. package/extensions/plan/types.ts +0 -8
  96. package/extensions/plan/web-client.ts +1 -1
  97. package/extensions/plan/web-page.ts +0 -7
  98. package/extensions/plan/web-router.ts +3 -57
  99. package/extensions/plan/web-share-session.ts +24 -30
  100. package/extensions/plan/web-streams.ts +14 -14
  101. package/extensions/plan/web-tokens.ts +2 -2
  102. package/extensions/plan/web.ts +66 -120
  103. package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
  104. package/extensions/rewind/{review.ts → commands/review.ts} +13 -13
  105. package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
  106. package/extensions/rewind/{config.ts → config/config.ts} +1 -1
  107. package/extensions/rewind/index.ts +3 -3
  108. package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
  109. package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
  110. package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
  111. package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
  112. package/extensions/rewind/{format.ts → text/format.ts} +3 -3
  113. package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
  114. package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
  115. package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
  116. package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
  117. package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
  118. package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
  119. package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
  120. package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
  121. package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
  122. package/extensions/rewind/{status.ts → view/status.ts} +4 -4
  123. package/extensions/session-bus/commands.ts +17 -69
  124. package/extensions/session-bus/format.ts +22 -45
  125. package/extensions/session-bus/index.ts +13 -7
  126. package/extensions/session-bus/join-request.ts +40 -0
  127. package/extensions/session-bus/mail-watch.ts +134 -0
  128. package/extensions/session-bus/notice.ts +32 -4
  129. package/{lib/claims → extensions/session-bus}/overlap.ts +11 -18
  130. package/extensions/session-bus/protocol.ts +19 -49
  131. package/extensions/session-bus/resolve.ts +67 -0
  132. package/extensions/session-bus/result.ts +16 -51
  133. package/extensions/session-bus/rows.ts +4 -2
  134. package/extensions/session-bus/runtime.ts +129 -238
  135. package/extensions/session-bus/store.ts +42 -6
  136. package/extensions/session-bus/tools.ts +31 -66
  137. package/extensions/session-bus/tui.ts +4 -4
  138. package/extensions/session-bus/types.ts +13 -13
  139. package/extensions/subagent/agents.ts +9 -8
  140. package/extensions/subagent/invocation.ts +4 -2
  141. package/extensions/team/commands.ts +112 -0
  142. package/extensions/team/dispatch.ts +133 -0
  143. package/extensions/team/format.ts +105 -0
  144. package/extensions/team/index.ts +33 -0
  145. package/extensions/team/schema.ts +29 -0
  146. package/extensions/team/tools.ts +246 -0
  147. package/extensions/team/types.ts +48 -0
  148. package/extensions/web-access/fetch/page.ts +4 -1
  149. package/extensions/web-access/fetch/structured.ts +447 -0
  150. package/extensions/web-access/fetch/tool.ts +2 -1
  151. package/extensions/web-access/search/tool.ts +2 -1
  152. package/extensions/wechat/bridge.ts +76 -92
  153. package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
  154. package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
  155. package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
  156. package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
  157. package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
  158. package/extensions/wechat/dialog/channels.ts +136 -0
  159. package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +37 -37
  160. package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +2 -2
  161. package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
  162. package/extensions/wechat/index.ts +10 -10
  163. package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
  164. package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
  165. package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +100 -22
  166. package/extensions/wechat/{presence.ts → peer/presence.ts} +8 -7
  167. package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +1 -1
  168. package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
  169. package/extensions/wechat/{state.ts → state/state.ts} +14 -2
  170. package/extensions/wechat/{format.ts → text/format.ts} +3 -3
  171. package/extensions/wechat/{notices.ts → text/notices.ts} +8 -0
  172. package/extensions/wechat/tools.ts +29 -12
  173. package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
  174. package/extensions/wechat/{deliver.ts → transport/deliver.ts} +72 -28
  175. package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
  176. package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
  177. package/extensions/wechat/transport/outbound.ts +142 -0
  178. package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
  179. package/extensions/wechat/types.ts +10 -1
  180. package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
  181. package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
  182. package/extensions/worktree/guard.ts +3 -5
  183. package/lib/README.md +8 -6
  184. package/lib/board/card.ts +290 -0
  185. package/lib/board/links.ts +117 -0
  186. package/lib/board/page-pointer.ts +256 -0
  187. package/lib/board/round-text.ts +72 -0
  188. package/lib/board/round.ts +89 -0
  189. package/lib/board/rules.ts +304 -0
  190. package/lib/board/session.ts +105 -0
  191. package/lib/board/store.ts +310 -0
  192. package/lib/board/view.ts +150 -0
  193. package/lib/errors.ts +12 -4
  194. package/lib/format.ts +13 -0
  195. package/lib/http/guard.ts +112 -0
  196. package/lib/http/index.ts +16 -5
  197. package/lib/http/serve.ts +234 -0
  198. package/lib/http/server.ts +12 -10
  199. package/lib/http/sink.ts +110 -0
  200. package/lib/http/token.ts +38 -0
  201. package/lib/policy.ts +12 -2
  202. package/lib/requirements.ts +6 -7
  203. package/lib/session-label.ts +64 -0
  204. package/lib/session-roster.ts +130 -0
  205. package/lib/session-tool.ts +184 -0
  206. package/lib/tool-names.ts +25 -2
  207. package/lib/tui/glyphs.ts +2 -0
  208. package/lib/web/README.md +5 -2
  209. package/lib/web/components.ts +5 -0
  210. package/lib/web/runtime.ts +7 -1
  211. package/lib/web/tokens.ts +25 -2
  212. package/package.json +26 -14
  213. package/skills/next/SKILL.md +4 -3
  214. package/skills/project-docs/SKILL.md +133 -0
  215. package/skills/project-docs/references/audit.md +131 -0
  216. package/skills/project-docs/references/changelog.md +105 -0
  217. package/skills/project-docs/references/discovery.md +127 -0
  218. package/skills/project-docs/references/readme.md +80 -0
  219. package/skills/project-docs/references/release.md +84 -0
  220. package/skills/project-docs/references/roadmap.md +93 -0
  221. package/skills/project-docs/scripts/state.ts +316 -0
  222. package/skills/refactor/SKILL.md +100 -125
  223. package/skills/refactor/references/handoff.md +35 -0
  224. package/skills/refactor/references/signals.md +54 -0
  225. package/skills/refactor/scripts/inventory.ts +587 -0
  226. package/extensions/file-browse/README.md +0 -506
  227. package/extensions/file-browse/server.ts +0 -141
  228. package/extensions/plan/split.ts +0 -87
  229. package/extensions/session-bus/README.md +0 -247
  230. package/extensions/session-bus/team.ts +0 -102
  231. package/extensions/wechat/outbound.ts +0 -100
  232. package/lib/plans/sections.ts +0 -172
  233. package/lib/plans/setting.ts +0 -52
  234. package/lib/plans/split.ts +0 -215
  235. package/lib/plans/store.ts +0 -19
  236. package/lib/plans/team.ts +0 -151
  237. package/skills/changelog/SKILL.md +0 -148
  238. package/skills/parallel-dev/SKILL.md +0 -150
  239. /package/extensions/file-browse/{rev.ts → live/rev.ts} +0 -0
  240. /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
  241. /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
  242. /package/extensions/file-browse/{live-client.ts → view/live-client.ts} +0 -0
  243. /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
  244. /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
  245. /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
  246. /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
  247. /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
  248. /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
  249. /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
@@ -10,10 +10,10 @@
10
10
  */
11
11
 
12
12
  import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
13
- import { messageOf } from "../../lib/errors.ts";
14
- import { sanitizeLine } from "../../lib/format.ts";
15
- import { isPlanModeEnabled } from "../../lib/plan-state.ts";
16
- import { withRailsSuppressed } from "../../lib/rails.ts";
13
+ import { messageOf } from "../../../lib/errors.ts";
14
+ import { sanitizeLine } from "../../../lib/format.ts";
15
+ import { isPlanModeEnabled } from "../../../lib/plan-state.ts";
16
+ import { withRailsSuppressed } from "../../../lib/rails.ts";
17
17
  import {
18
18
  boundDiff,
19
19
  formatHunkRevertBody,
@@ -23,20 +23,20 @@ import {
23
23
  formatRevertSelectedBody,
24
24
  formatReviewListText,
25
25
  formatReviewRevertText,
26
- } from "./format.ts";
27
- import { HunkPickerComponent } from "./hunk-picker.ts";
28
- import { buildHunkPatch, parseFilePatch } from "./patch.ts";
29
- import { entryPaths, toReviewEntries, type ReviewEntry } from "./paths.ts";
26
+ } from "../text/format.ts";
27
+ import { HunkPickerComponent } from "../view/hunk-picker.ts";
28
+ import { buildHunkPatch, parseFilePatch } from "../text/patch.ts";
29
+ import { entryPaths, toReviewEntries, type ReviewEntry } from "../text/paths.ts";
30
30
  import {
31
31
  ReviewDiffComponent,
32
32
  ReviewListComponent,
33
33
  type ReviewDiffAction,
34
34
  type ReviewListResult,
35
- } from "./review-tui.ts";
36
- import type { RestorePlan } from "./restore.ts";
37
- import type { RewindRuntime } from "./runtime.ts";
38
- import { buildRewindPoints, type RewindPoint } from "./timeline.ts";
39
- import type { Snapshot, RestoreSummary } from "./types.ts";
35
+ } from "../view/review-tui.ts";
36
+ import type { RestorePlan } from "../transport/restore.ts";
37
+ import type { RewindRuntime } from "../state/runtime.ts";
38
+ import { buildRewindPoints, type RewindPoint } from "../state/timeline.ts";
39
+ import type { Snapshot, RestoreSummary } from "../types.ts";
40
40
 
41
41
  /** One reviewable view of the working tree. */
42
42
  interface ReviewView {
@@ -9,13 +9,13 @@
9
9
  */
10
10
 
11
11
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
12
- import { withRailsSuppressed } from "../../lib/rails.ts";
12
+ import { withRailsSuppressed } from "../../../lib/rails.ts";
13
13
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
14
- import { formatChangeSummary, formatRestoreText, previewDiffText } from "./format.ts";
15
- import { PathPickerComponent } from "./path-picker.ts";
16
- import type { ChangedPath } from "./paths.ts";
17
- import type { RewindRuntime } from "./runtime.ts";
18
- import { rewindScopes, type RewindPoint, type RewindScope } from "./timeline.ts";
14
+ import { formatChangeSummary, formatRestoreText, previewDiffText } from "../text/format.ts";
15
+ import { PathPickerComponent } from "../view/path-picker.ts";
16
+ import type { ChangedPath } from "../text/paths.ts";
17
+ import type { RewindRuntime } from "../state/runtime.ts";
18
+ import { rewindScopes, type RewindPoint, type RewindScope } from "../state/timeline.ts";
19
19
 
20
20
  /** Human labels for the scope picker, in menu order. */
21
21
  const SCOPE_LABELS: Record<RewindScope, string> = {
@@ -6,7 +6,7 @@
6
6
  * malformed documents are ignored, and every value is clamped to a safe range.
7
7
  */
8
8
 
9
- import { clampInteger, cleanString, loadConfigSection, stringList } from "../../lib/config.ts";
9
+ import { clampInteger, cleanString, loadConfigSection, stringList } from "../../../lib/config.ts";
10
10
 
11
11
  export interface RewindConfig {
12
12
  /** Take one automatic snapshot per user prompt. Default: true. */
@@ -16,9 +16,9 @@
16
16
 
17
17
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
18
18
  import { isExtensionEnabled } from "../../lib/env.ts";
19
- import { registerCommands } from "./commands.ts";
20
- import { createRuntime } from "./runtime.ts";
21
- import { createSnapshotRun } from "./snapshot-run.ts";
19
+ import { registerCommands } from "./commands/commands.ts";
20
+ import { createRuntime } from "./state/runtime.ts";
21
+ import { createSnapshotRun } from "./state/snapshot-run.ts";
22
22
 
23
23
  export function registerRewind(pi: ExtensionAPI): void {
24
24
  const runtime = createRuntime(pi);
@@ -9,12 +9,12 @@
9
9
  */
10
10
 
11
11
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
- import { createReadOnlyPolicy } from "../../lib/policy.ts";
13
- import { ASK_USER_QUESTION_TOOL, GOAL_TOOL, TODO_TOOL } from "../../lib/tool-names.ts";
14
- import type { RewindConfig } from "./config.ts";
12
+ import { createReadOnlyPolicy, WORKSPACE_READERS } from "../../../lib/policy.ts";
13
+ import { ASK_USER_QUESTION_TOOL, GOAL_TOOL, TODO_TOOL } from "../../../lib/tool-names.ts";
14
+ import type { RewindConfig } from "../config/config.ts";
15
15
 
16
16
  /** Tools that only read files or track session state, so they never snapshot. */
17
- const READER_TOOLS = ["read", "grep", "find", "ls", TODO_TOOL, GOAL_TOOL];
17
+ const READER_TOOLS = [...WORKSPACE_READERS, TODO_TOOL, GOAL_TOOL];
18
18
 
19
19
  /** The interactive tool: it prompts the user and never touches the working tree. */
20
20
  const SESSION_TOOLS = [ASK_USER_QUESTION_TOOL];
@@ -9,8 +9,8 @@
9
9
  */
10
10
 
11
11
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
12
- import { resolveEffectiveCwd } from "../../lib/env.ts";
13
- import { loadConfig, type RewindConfig } from "./config.ts";
12
+ import { resolveEffectiveCwd } from "../../../lib/env.ts";
13
+ import { loadConfig, type RewindConfig } from "../config/config.ts";
14
14
  import {
15
15
  applyPatchReverse,
16
16
  createRewindRunner,
@@ -19,16 +19,16 @@ import {
19
19
  repoRoot,
20
20
  revParse,
21
21
  type RunGit,
22
- } from "./git.ts";
23
- import { createOperationQueue } from "./queue.ts";
24
- import { applyRestore, planRestore, type PlanResult, type RestoreInput } from "./restore.ts";
25
- import type { PathStat } from "./paths.ts";
26
- import { createSnapshot } from "./snapshot.ts";
27
- import { createStatusChip } from "./status.ts";
28
- import { belongsToRoot, listSnapshots, pruneSnapshots } from "./store.ts";
29
- import { createTempIndexStore } from "./temp-index.ts";
22
+ } from "../transport/git.ts";
23
+ import { createOperationQueue } from "../transport/queue.ts";
24
+ import { applyRestore, planRestore, type PlanResult, type RestoreInput } from "../transport/restore.ts";
25
+ import type { PathStat } from "../text/paths.ts";
26
+ import { createSnapshot } from "../transport/snapshot.ts";
27
+ import { createStatusChip } from "../view/status.ts";
28
+ import { belongsToRoot, listSnapshots, pruneSnapshots } from "../transport/store.ts";
29
+ import { createTempIndexStore } from "../transport/temp-index.ts";
30
30
  import { lastUserEntryId } from "./timeline.ts";
31
- import type { Snapshot, SnapshotReason, RestoreSummary } from "./types.ts";
31
+ import type { Snapshot, SnapshotReason, RestoreSummary } from "../types.ts";
32
32
 
33
33
  export interface SnapshotOptions {
34
34
  reason: SnapshotReason;
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
13
- import { summarizePrompt } from "./format.ts";
13
+ import { summarizePrompt } from "../text/format.ts";
14
14
  import { createSnapshotPolicy, type SnapshotPolicy } from "./policy.ts";
15
15
  import type { RewindRuntime } from "./runtime.ts";
16
16
 
@@ -9,8 +9,8 @@
9
9
  */
10
10
 
11
11
  import type { SessionEntry, SessionMessageEntry } from "@earendil-works/pi-coding-agent";
12
- import { summarizePrompt } from "./format.ts";
13
- import type { Snapshot } from "./types.ts";
12
+ import { summarizePrompt } from "../text/format.ts";
13
+ import type { Snapshot } from "../types.ts";
14
14
 
15
15
  /** What a rewind can restore for one point. */
16
16
  export type RewindScope = "both" | "conversation" | "code";
@@ -7,10 +7,10 @@
7
7
  */
8
8
 
9
9
  import { sliceByColumn, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
10
- import { sanitizeLine, stripControlChars } from "../../lib/format.ts";
11
- import { GLYPHS, SEPARATORS } from "../../lib/tui/glyphs.ts";
10
+ import { sanitizeLine, stripControlChars } from "../../../lib/format.ts";
11
+ import { GLYPHS, SEPARATORS } from "../../../lib/tui/glyphs.ts";
12
12
  import { SELECTION_MARKS, type ReviewEntry } from "./paths.ts";
13
- import type { RestoreSummary } from "./types.ts";
13
+ import type { RestoreSummary } from "../types.ts";
14
14
 
15
15
  /** Longest prompt summary shown before truncation. */
16
16
  const LABEL_WIDTH = 48;
@@ -23,8 +23,8 @@ import {
23
23
  revParseMany,
24
24
  runGitOrThrow as run,
25
25
  type RunGit,
26
- } from "../../lib/git/index.ts";
27
- import { parseNameStatus, parseNumStat, type ChangedPath, type PathStat } from "./paths.ts";
26
+ } from "../../../lib/git/index.ts";
27
+ import { parseNameStatus, parseNumStat, type ChangedPath, type PathStat } from "../text/paths.ts";
28
28
 
29
29
  // Re-export exactly the shared helpers this extension consumes, so rewind code
30
30
  // has one git import surface instead of reaching into `lib/git` directly.
@@ -26,8 +26,8 @@ import {
26
26
  treeFromWorkingTree,
27
27
  type RunGit,
28
28
  } from "./git.ts";
29
- import { entryPaths, summarize, type ChangedPath } from "./paths.ts";
30
- import type { Snapshot, RestoreSummary } from "./types.ts";
29
+ import { entryPaths, summarize, type ChangedPath } from "../text/paths.ts";
30
+ import type { Snapshot, RestoreSummary } from "../types.ts";
31
31
 
32
32
  export interface RestoreDeps {
33
33
  runGit: RunGit;
@@ -18,7 +18,7 @@ import {
18
18
  type RunGit,
19
19
  } from "./git.ts";
20
20
  import { encodeMessage, refFor, META_VERSION, type SnapshotMeta } from "./store.ts";
21
- import type { Snapshot, SnapshotReason } from "./types.ts";
21
+ import type { Snapshot, SnapshotReason } from "../types.ts";
22
22
 
23
23
  export interface SnapshotDeps {
24
24
  runGit: RunGit;
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { commitMessages, deleteRef, listRefs, type RunGit } from "./git.ts";
10
- import type { Snapshot, SnapshotReason } from "./types.ts";
10
+ import type { Snapshot, SnapshotReason } from "../types.ts";
11
11
 
12
12
  /** Prefix of the metadata line in a snapshot commit body. */
13
13
  export const META_MARKER = "pi-rewind: ";
@@ -14,12 +14,12 @@
14
14
 
15
15
  import type { Theme } from "@earendil-works/pi-coding-agent";
16
16
  import { Key, matchesKey, type Component, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
17
- import { detailBlockRows, dockListFrame, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
18
- import { clip } from "../../lib/tui/columns.ts";
19
- import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "../../lib/tui/cursor.ts";
20
- import { emptyState } from "../../lib/tui/rows.ts";
21
- import { titleRule } from "../../lib/tui/rules.ts";
22
- import { paint } from "../../lib/tui/tokens.ts";
17
+ import { detailBlockRows, dockListFrame, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
18
+ import { clip } from "../../../lib/tui/columns.ts";
19
+ import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "../../../lib/tui/cursor.ts";
20
+ import { emptyState } from "../../../lib/tui/rows.ts";
21
+ import { titleRule } from "../../../lib/tui/rules.ts";
22
+ import { paint } from "../../../lib/tui/tokens.ts";
23
23
 
24
24
  /** Rows the checklist shows when the terminal height is unknown. */
25
25
  const SCREEN_DEFAULT_ITEMS = 12;
@@ -11,15 +11,15 @@
11
11
  */
12
12
 
13
13
  import type { Theme } from "@earendil-works/pi-coding-agent";
14
- import { sanitizeLine } from "../../lib/format.ts";
15
- import { screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
16
- import { clip } from "../../lib/tui/columns.ts";
17
- import { SEPARATORS } from "../../lib/tui/glyphs.ts";
18
- import { checkbox, listRow } from "../../lib/tui/rows.ts";
19
- import { paint } from "../../lib/tui/tokens.ts";
14
+ import { sanitizeLine } from "../../../lib/format.ts";
15
+ import { screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
16
+ import { clip } from "../../../lib/tui/columns.ts";
17
+ import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
18
+ import { checkbox, listRow } from "../../../lib/tui/rows.ts";
19
+ import { paint } from "../../../lib/tui/tokens.ts";
20
20
  import { ChecklistScreen } from "./checklist.ts";
21
- import { formatReviewEntryCounts } from "./format.ts";
22
- import type { Hunk } from "./patch.ts";
21
+ import { formatReviewEntryCounts } from "../text/format.ts";
22
+ import type { Hunk } from "../text/patch.ts";
23
23
 
24
24
  export interface HunkPickerOptions {
25
25
  /** The file the hunks belong to. */
@@ -13,14 +13,14 @@
13
13
  */
14
14
 
15
15
  import type { Theme } from "@earendil-works/pi-coding-agent";
16
- import { sanitizeLine } from "../../lib/format.ts";
17
- import { screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
18
- import { clip } from "../../lib/tui/columns.ts";
19
- import { SEPARATORS } from "../../lib/tui/glyphs.ts";
20
- import { checkbox, listRow } from "../../lib/tui/rows.ts";
21
- import { paint } from "../../lib/tui/tokens.ts";
16
+ import { sanitizeLine } from "../../../lib/format.ts";
17
+ import { screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
18
+ import { clip } from "../../../lib/tui/columns.ts";
19
+ import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
20
+ import { checkbox, listRow } from "../../../lib/tui/rows.ts";
21
+ import { paint } from "../../../lib/tui/tokens.ts";
22
22
  import { ChecklistScreen } from "./checklist.ts";
23
- import { baseName, expandGroup, groupPaths, SELECTION_MARKS, type ChangedPath, type PathGroup } from "./paths.ts";
23
+ import { baseName, expandGroup, groupPaths, SELECTION_MARKS, type ChangedPath, type PathGroup } from "../text/paths.ts";
24
24
 
25
25
  export interface PathPickerOptions {
26
26
  /** The changed paths the snapshot differs on. */
@@ -13,18 +13,18 @@
13
13
 
14
14
  import type { Theme } from "@earendil-works/pi-coding-agent";
15
15
  import type { Component, TuiMouseEvent, TuiMouseEventResult } from "@earendil-works/pi-tui";
16
- import { clip } from "../../lib/tui/columns.ts";
17
- import { detailBlockRows, dockListFrame, screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
18
- import { sanitizeLine } from "../../lib/format.ts";
19
- import { fitRows, formatRange, isCloseKey, wheelDelta } from "../../lib/tui/cursor.ts";
20
- import { SEPARATORS } from "../../lib/tui/glyphs.ts";
21
- import { LinePane } from "../../lib/tui/line-pane.ts";
22
- import { checkbox, emptyState, listRow } from "../../lib/tui/rows.ts";
23
- import { titleRule } from "../../lib/tui/rules.ts";
24
- import { paint, type TuiRole } from "../../lib/tui/tokens.ts";
16
+ import { clip } from "../../../lib/tui/columns.ts";
17
+ import { detailBlockRows, dockListFrame, screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
18
+ import { sanitizeLine } from "../../../lib/format.ts";
19
+ import { fitRows, formatRange, isCloseKey, wheelDelta } from "../../../lib/tui/cursor.ts";
20
+ import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
21
+ import { LinePane } from "../../../lib/tui/line-pane.ts";
22
+ import { checkbox, emptyState, listRow } from "../../../lib/tui/rows.ts";
23
+ import { titleRule } from "../../../lib/tui/rules.ts";
24
+ import { paint, type TuiRole } from "../../../lib/tui/tokens.ts";
25
25
  import { ChecklistScreen } from "./checklist.ts";
26
- import { formatReviewDetail, formatReviewEntryCounts, formatReviewSummary } from "./format.ts";
27
- import { SELECTION_MARKS, type PathChange, type ReviewEntry } from "./paths.ts";
26
+ import { formatReviewDetail, formatReviewEntryCounts, formatReviewSummary } from "../text/format.ts";
27
+ import { SELECTION_MARKS, type PathChange, type ReviewEntry } from "../text/paths.ts";
28
28
 
29
29
  /** Rows a diff screen shows when the terminal height is unknown. */
30
30
  const DIFF_DEFAULT_ITEMS = 20;
@@ -10,15 +10,15 @@
10
10
 
11
11
  import type { Theme } from "@earendil-works/pi-coding-agent";
12
12
  import { Key, matchesKey, type Component, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
13
- import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "../../lib/tui/cursor.ts";
14
- import { detailBlockRows, dockListFrame, screenHint, type ViewportRowsSource } from "../../lib/tui/chrome.ts";
15
- import { clip } from "../../lib/tui/columns.ts";
16
- import { SEPARATORS } from "../../lib/tui/glyphs.ts";
17
- import { emptyState, listRow } from "../../lib/tui/rows.ts";
18
- import { titleRule } from "../../lib/tui/rules.ts";
19
- import { paint } from "../../lib/tui/tokens.ts";
20
- import { formatRewindDetail, formatRewindParts } from "./format.ts";
21
- import type { RewindPoint } from "./timeline.ts";
13
+ import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "../../../lib/tui/cursor.ts";
14
+ import { detailBlockRows, dockListFrame, screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
15
+ import { clip } from "../../../lib/tui/columns.ts";
16
+ import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
17
+ import { emptyState, listRow } from "../../../lib/tui/rows.ts";
18
+ import { titleRule } from "../../../lib/tui/rules.ts";
19
+ import { paint } from "../../../lib/tui/tokens.ts";
20
+ import { formatRewindDetail, formatRewindParts } from "../text/format.ts";
21
+ import type { RewindPoint } from "../state/timeline.ts";
22
22
 
23
23
  export interface RewindListOptions {
24
24
  points: RewindPoint[];
@@ -57,7 +57,7 @@ export class RewindListComponent implements Component {
57
57
  }
58
58
  const count = this.points.length;
59
59
  if (navigateList(data, this.cursor, count)) return;
60
- if (matchesKey(data, Key.enter) || data === "r") {
60
+ if (matchesKey(data, Key.enter)) {
61
61
  const point = this.points[this.cursor.selected];
62
62
  if (point) this.options.onClose(point);
63
63
  }
@@ -139,6 +139,12 @@ export class RewindListComponent implements Component {
139
139
 
140
140
  /** The key-hint row, with the primary action in the accent role. */
141
141
  private hint(width: number): string {
142
- return screenHint(this.theme, width, ["Esc close", { text: "Enter choose", color: "accent" }, "↑/↓ or k/j select"]);
142
+ return screenHint(this.theme, width, [
143
+ "Esc close",
144
+ { text: "Enter choose", color: "accent" },
145
+ "↑/↓ or k/j select",
146
+ "PgUp/PgDn",
147
+ "g/G or Home/End",
148
+ ]);
143
149
  }
144
150
  }
@@ -8,10 +8,10 @@
8
8
  */
9
9
 
10
10
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
11
- import { GLYPHS, STATUS_KEYS } from "../../lib/tui/glyphs.ts";
12
- import { paint } from "../../lib/tui/tokens.ts";
13
- import type { RewindConfig } from "./config.ts";
14
- import { userMessagesFromBranch } from "./timeline.ts";
11
+ import { GLYPHS, STATUS_KEYS } from "../../../lib/tui/glyphs.ts";
12
+ import { paint } from "../../../lib/tui/tokens.ts";
13
+ import type { RewindConfig } from "../config/config.ts";
14
+ import { userMessagesFromBranch } from "../state/timeline.ts";
15
15
 
16
16
  const STATUS_KEY = STATUS_KEYS.rewind;
17
17
  const STATUS_GLYPH = GLYPHS.rewind;
@@ -1,25 +1,23 @@
1
1
  /**
2
- * The `/sessions` command.
2
+ * The `/sessions` command: one act, no arguments.
3
3
  *
4
- * In the TUI, bare `/sessions` opens the live board: `Tab` cycles Sessions,
5
- * Inbox, and Claims, and `w`/`x` act on this session's own watch and claims.
6
- * Every other mode prints the compact listing, because there is no dock to mount
7
- * the screen in. `name <label>` gives this session a stable target and `watch
8
- * [off|wake]` controls the inbox watch from either surface.
4
+ * In the TUI it opens the live board: `Tab` cycles Sessions, Inbox, and Claims,
5
+ * and `w`/`x` act on this session's own watch and claims. Every other mode prints
6
+ * the compact listing, because there is no dock to mount the screen in. Reading is
7
+ * not joining, so the board is empty until this session joins — and a command
8
+ * context cannot name a session, so the join is `session({action:"join"})`,
9
+ * `/team join [<label>]`, or the board's `w`.
9
10
  */
10
11
 
11
12
  import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
12
13
  import { messageOf } from "../../lib/errors.ts";
13
14
  import { sanitizeLine } from "../../lib/format.ts";
14
15
  import { withPolledScreen } from "../../lib/screen-session.ts";
15
- import { formatStatus, formatWatch } from "./format.ts";
16
+ import { formatJoin, formatStatus } from "./format.ts";
16
17
  import { COMMAND_NAME } from "./protocol.ts";
17
18
  import type { SessionBus } from "./runtime.ts";
18
19
  import { SessionListComponent } from "./tui.ts";
19
20
 
20
- const USAGE = "/sessions [name <label>|watch [off|wake]]";
21
- const WATCH_MODES = ["off", "wake"];
22
-
23
21
  /** How often the open board re-reads the bus. */
24
22
  const BOARD_POLL_MS = 1_000;
25
23
 
@@ -48,7 +46,7 @@ function createBoardReader(bus: SessionBus): (screen: SessionListComponent) => P
48
46
  }
49
47
 
50
48
  /** Open the TUI board, and resolve when it closes. */
51
- async function openBoard(pi: ExtensionAPI, ctx: ExtensionCommandContext, bus: SessionBus): Promise<void> {
49
+ async function openSessionsScreen(pi: ExtensionAPI, ctx: ExtensionCommandContext, bus: SessionBus): Promise<void> {
52
50
  await bus.start(ctx);
53
51
  const [status, messages] = await Promise.all([bus.snapshot(), bus.peek()]);
54
52
  const first = { status, messages };
@@ -67,9 +65,10 @@ async function openBoard(pi: ExtensionAPI, ctx: ExtensionCommandContext, bus: Se
67
65
  theme: screen.theme,
68
66
  callbacks: {
69
67
  toggleWatch: async (armed) => {
70
- const watching = await bus.watch({ stop: armed });
68
+ // The board's toggle is the same act as a join, so it says the same thing.
69
+ const joined = await bus.join({ listen: !armed });
71
70
  if (holder.screen) await reader(holder.screen);
72
- return formatWatch(watching);
71
+ return formatJoin(joined.label, joined.watching);
73
72
  },
74
73
  releaseClaim: async (path) => {
75
74
  const released = await bus.releaseStored(path);
@@ -92,7 +91,7 @@ async function openBoard(pi: ExtensionAPI, ctx: ExtensionCommandContext, bus: Se
92
91
  async function open(ctx: ExtensionCommandContext, pi: ExtensionAPI, bus: SessionBus): Promise<void> {
93
92
  try {
94
93
  if (ctx.mode === "tui") {
95
- await openBoard(pi, ctx, bus);
94
+ await openSessionsScreen(pi, ctx, bus);
96
95
  return;
97
96
  }
98
97
  await bus.start(ctx);
@@ -104,61 +103,10 @@ async function open(ctx: ExtensionCommandContext, pi: ExtensionAPI, bus: Session
104
103
 
105
104
  export function registerCommands(pi: ExtensionAPI, bus: SessionBus): void {
106
105
  pi.registerCommand(COMMAND_NAME, {
107
- description: "List parallel Pi sessions, their unread counts and claims; name this session",
108
- getArgumentCompletions: (prefix) => {
109
- const text = prefix.trimStart();
110
- if (text.includes(" ")) return null;
111
- const options = ["name", "help", "watch"].filter((value) => value.startsWith(text));
112
- return options.length > 0 ? options.map((value) => ({ value, label: value })) : null;
113
- },
114
- handler: async (args, ctx) => {
115
- const [sub = "", ...rest] = args.trim().split(/\s+/).filter(Boolean);
116
- if (sub === "help") {
117
- ctx.ui.notify(
118
- `/sessions — open the bus board\n/sessions name <label> — name this session\n` +
119
- `/sessions watch [off|wake] — report new mail at the next turn, or raise one\n\n${USAGE}`,
120
- "info",
121
- );
122
- return;
123
- }
124
- if (sub === "watch") {
125
- const mode = rest[0] ?? "";
126
- if (mode !== "" && !WATCH_MODES.includes(mode)) {
127
- ctx.ui.notify(`Unknown watch mode "${mode}". Usage: /sessions watch [off|wake]`, "warning");
128
- return;
129
- }
130
- try {
131
- await bus.start(ctx);
132
- const status = await bus.status();
133
- const watching = await bus.watch({ stop: mode === "off", wake: mode === "wake" });
134
- ctx.ui.notify(formatWatch(watching, status.me.label), "info");
135
- } catch (error) {
136
- ctx.ui.notify(`Session bus: ${messageOf(error)}`, "warning");
137
- }
138
- return;
139
- }
140
- if (sub === "name") {
141
- const label = rest.join(" ").trim();
142
- if (!label) {
143
- ctx.ui.notify("Usage: /sessions name <label>", "warning");
144
- return;
145
- }
146
- try {
147
- await bus.start(ctx);
148
- await bus.status();
149
- const renamed = await bus.rename(label);
150
- // The bus validates first, so a rejected label leaves both names alone.
151
- pi.setSessionName(renamed);
152
- ctx.ui.notify(`This session is now named "${renamed}".`, "info");
153
- } catch (error) {
154
- ctx.ui.notify(`Session bus: ${messageOf(error)}`, "warning");
155
- }
156
- return;
157
- }
158
- if (sub !== "") {
159
- ctx.ui.notify(`Unknown sessions command "${sub}". Try ${USAGE}.`, "warning");
160
- return;
161
- }
106
+ description: "Open the bus board: sessions, unread mail, and path claims",
107
+ // One command, one act: an argument is not a sub-command, so it is ignored
108
+ // rather than warned about — the board is what the user asked for.
109
+ handler: async (_args, ctx) => {
162
110
  await open(ctx, pi, bus);
163
111
  },
164
112
  });