@herbertgao/pi-extensions 2026.9.19 → 2026.10.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 (444) hide show
  1. package/README.md +14 -16
  2. package/THIRD_PARTY_NOTICES.md +29 -3
  3. package/node_modules/@herbertgao/pi-bark/README.md +39 -3
  4. package/node_modules/@herbertgao/pi-bark/package.json +1 -1
  5. package/node_modules/@herbertgao/pi-bark/src/index.ts +275 -15
  6. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +85 -68
  7. package/node_modules/@herbertgao/pi-cc-extensions/README.md +79 -62
  8. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/preview.webp +0 -0
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +116 -34
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +370 -118
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +6 -36
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/index.ts +2 -2
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +31 -33
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +330 -360
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/index.ts +56 -108
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/session.ts +97 -15
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/subagent.ts +80 -45
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/flush-docked-bash.ts +36 -0
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer-layout.ts +229 -0
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +521 -0
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/mcp-chip.ts +136 -0
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/startup-header.ts +92 -61
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +58 -38
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +19 -3
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +1127 -231
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +267 -262
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +38 -48
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +8 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +2 -7
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +287 -114
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +15 -6
  32. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +18 -72
  33. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +61 -26
  34. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +303 -0
  35. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/ansi-utils.ts +25 -57
  36. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-component.ts +125 -0
  37. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-edit-render.ts +227 -0
  38. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-header.ts +136 -0
  39. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-highlight.ts +151 -0
  40. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-inline.ts +324 -0
  41. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-layout.ts +762 -0
  42. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-limits.ts +152 -0
  43. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-palette.ts +410 -0
  44. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-parse.ts +535 -0
  45. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +4 -4
  46. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +21 -3219
  47. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-text.ts +44 -0
  48. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +568 -0
  49. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +103 -48
  50. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +8 -7
  51. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-execution.ts +2 -1
  52. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +171 -196
  53. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/mcp-title.ts +39 -0
  54. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{message-display.ts → tool/message-display.ts} +27 -93
  55. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +429 -0
  56. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +259 -164
  57. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{show-more-hint.ts → tool/show-more-hint.ts} +10 -0
  58. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +8 -26
  59. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-color.ts +44 -0
  60. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-text.ts +77 -0
  61. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/component-tree.ts +34 -0
  62. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/format.ts +28 -0
  63. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +51 -0
  64. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/patch-keys.ts +124 -0
  65. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/sgr-mouse.ts +70 -0
  66. package/node_modules/@herbertgao/pi-cc-extensions/package.json +10 -8
  67. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  68. package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
  69. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +3 -2
  70. package/node_modules/@herbertgao/sol-pi/CONTRIBUTING.md +22 -0
  71. package/node_modules/@herbertgao/sol-pi/README.md +36 -17
  72. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +10 -6
  73. package/node_modules/@herbertgao/sol-pi/agents-install.md +15 -12
  74. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +24 -8
  75. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +2 -2
  76. package/node_modules/@herbertgao/sol-pi/docs/star-history.md +18 -0
  77. package/node_modules/@herbertgao/sol-pi/package.json +4 -2
  78. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +1 -1
  79. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +1 -1
  80. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +23 -4
  81. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +32 -1
  82. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +3 -2
  83. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +1 -1
  84. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +27 -7
  85. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +137 -41
  86. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +1 -0
  87. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +2 -1
  88. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/projection.ts +58 -0
  89. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +28 -6
  90. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +2 -1
  91. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +15 -2
  92. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  93. package/node_modules/@pi-plugins/fast-mode/README.md +7 -1
  94. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  95. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +7 -1
  96. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  97. package/node_modules/@pi-plugins/fast-mode/package.json +5 -5
  98. package/node_modules/pi-antigravity/README.md +3 -0
  99. package/node_modules/pi-antigravity/package.json +8 -8
  100. package/node_modules/pi-antigravity/src/auth/oauth.ts +6 -3
  101. package/node_modules/pi-antigravity/src/index.ts +114 -110
  102. package/node_modules/pi-antigravity/src/stream/stream.ts +1 -1
  103. package/node_modules/pi-antigravity/src/utils/util.ts +18 -1
  104. package/node_modules/pi-multi-account/CHANGELOG.md +20 -0
  105. package/node_modules/pi-multi-account/README.md +46 -8
  106. package/node_modules/pi-multi-account/config-file-transaction.ts +42 -0
  107. package/node_modules/pi-multi-account/index.ts +255 -269
  108. package/node_modules/pi-multi-account/model-pins.ts +36 -0
  109. package/node_modules/pi-multi-account/package.json +9 -7
  110. package/node_modules/pi-multi-account/slot-proxy-auth.ts +12 -2
  111. package/node_modules/pi-multi-account/slot-proxy.ts +27 -5
  112. package/node_modules/pi-web-access/CHANGELOG.md +17 -0
  113. package/node_modules/pi-web-access/README.md +6 -3
  114. package/node_modules/pi-web-access/brave-rate-limit.ts +170 -0
  115. package/node_modules/pi-web-access/brave.ts +28 -11
  116. package/node_modules/pi-web-access/dist/index.js +202 -33
  117. package/node_modules/pi-web-access/gemini-search.ts +2 -5
  118. package/node_modules/pi-web-access/index.ts +13 -7
  119. package/node_modules/pi-web-access/openai-search.ts +24 -10
  120. package/node_modules/pi-web-access/package.json +1 -1
  121. package/node_modules/pi-web-access/summary-review.ts +8 -2
  122. package/node_modules/{@herbertgao/resume-from → resume-from}/README.md +16 -12
  123. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -5
  124. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.js +2 -3
  125. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.d.ts +2 -2
  126. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.d.ts +3 -0
  127. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.js +27 -15
  128. package/node_modules/{@herbertgao/resume-from/dist/adapters/codex → resume-from/dist/adapters/claude-code}/redaction.js +16 -3
  129. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.d.ts +2 -4
  130. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.js +1 -1
  131. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.d.ts +2 -4
  132. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.js +1 -2
  133. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/read.d.ts +16 -0
  134. package/node_modules/resume-from/dist/adapters/codex/read.js +723 -0
  135. package/node_modules/{@herbertgao/resume-from/dist/adapters/pi → resume-from/dist/adapters/codex}/redaction.js +16 -3
  136. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.d.ts +44 -4
  137. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.js +88 -4
  138. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.d.ts +2 -2
  139. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.js +2 -2
  140. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.d.ts +5 -1
  141. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.js +10 -6
  142. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.d.ts +2 -2
  143. package/node_modules/{@herbertgao/resume-from/dist/adapters/claude-code → resume-from/dist/adapters/pi}/redaction.js +16 -3
  144. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.d.ts +2 -4
  145. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.js +2 -2
  146. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.d.ts +1 -1
  147. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.js +4 -4
  148. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.js +2 -2
  149. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.d.ts +2 -2
  150. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.js +31 -8
  151. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.d.ts +1 -1
  152. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.js +1 -2
  153. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.d.ts +4 -1
  154. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.js +2 -2
  155. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.d.ts +8 -6
  156. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.d.ts +10 -5
  157. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/finder.d.ts +2 -1
  158. package/node_modules/resume-from/dist/import/discovery/finder.js +269 -0
  159. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.d.ts +3 -3
  160. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.js +3 -3
  161. package/node_modules/resume-from/dist/import/pipeline.d.ts +28 -0
  162. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/pipeline.js +31 -11
  163. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.d.ts +2 -2
  164. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.js +9 -5
  165. package/node_modules/resume-from/dist/import/preview/warnings.d.ts +14 -0
  166. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/warnings.js +26 -20
  167. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.js +12 -2
  168. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.d.ts +9 -3
  169. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.d.ts +4 -4
  170. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.js +7 -4
  171. package/node_modules/resume-from/dist/platform/repo/reader.d.ts +3 -0
  172. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/reader.js +60 -20
  173. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.d.ts +8 -1
  174. package/node_modules/{@herbertgao/resume-from → resume-from}/package.json +19 -32
  175. package/node_modules/{@herbertgao/resume-from → resume-from}/shims/pi/extensions/resume-from.js +2 -2
  176. package/package.json +18 -22
  177. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +0 -101
  178. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.svg +0 -101
  179. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/welcome.webp +0 -0
  180. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/render-utils.ts +0 -5
  181. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +0 -30
  182. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +0 -12
  183. package/node_modules/@herbertgao/resume-from/dist/adapters/codex/read.js +0 -270
  184. package/node_modules/@herbertgao/resume-from/dist/import/discovery/finder.js +0 -129
  185. package/node_modules/@herbertgao/resume-from/dist/import/pipeline.d.ts +0 -17
  186. package/node_modules/@herbertgao/resume-from/dist/import/preview/warnings.d.ts +0 -11
  187. package/node_modules/@herbertgao/resume-from/dist/platform/repo/reader.d.ts +0 -8
  188. package/node_modules/pi-footer/CHANGELOG.md +0 -145
  189. package/node_modules/pi-footer/LICENSE +0 -21
  190. package/node_modules/pi-footer/README.md +0 -354
  191. package/node_modules/pi-footer/package.json +0 -68
  192. package/node_modules/pi-footer/src/cache.ts +0 -106
  193. package/node_modules/pi-footer/src/colors.ts +0 -237
  194. package/node_modules/pi-footer/src/config.ts +0 -202
  195. package/node_modules/pi-footer/src/event-widgets.ts +0 -41
  196. package/node_modules/pi-footer/src/extension-statuses.ts +0 -102
  197. package/node_modules/pi-footer/src/git.ts +0 -135
  198. package/node_modules/pi-footer/src/index.ts +0 -268
  199. package/node_modules/pi-footer/src/metrics.ts +0 -141
  200. package/node_modules/pi-footer/src/presets.ts +0 -383
  201. package/node_modules/pi-footer/src/render.ts +0 -114
  202. package/node_modules/pi-footer/src/separators.ts +0 -52
  203. package/node_modules/pi-footer/src/types.ts +0 -122
  204. package/node_modules/pi-footer/src/ui/color-level-confirm.ts +0 -22
  205. package/node_modules/pi-footer/src/ui/color-options.ts +0 -195
  206. package/node_modules/pi-footer/src/ui/config-lifecycle.ts +0 -61
  207. package/node_modules/pi-footer/src/ui/edit-colors.ts +0 -13
  208. package/node_modules/pi-footer/src/ui/events.ts +0 -35
  209. package/node_modules/pi-footer/src/ui/extension-status-picker.ts +0 -60
  210. package/node_modules/pi-footer/src/ui/extension-statuses.ts +0 -73
  211. package/node_modules/pi-footer/src/ui/fields.ts +0 -252
  212. package/node_modules/pi-footer/src/ui/global-menu.ts +0 -126
  213. package/node_modules/pi-footer/src/ui/helpers.ts +0 -44
  214. package/node_modules/pi-footer/src/ui/layout.ts +0 -17
  215. package/node_modules/pi-footer/src/ui/line-list.ts +0 -19
  216. package/node_modules/pi-footer/src/ui/model.ts +0 -64
  217. package/node_modules/pi-footer/src/ui/navigation.ts +0 -29
  218. package/node_modules/pi-footer/src/ui/option-edit.ts +0 -93
  219. package/node_modules/pi-footer/src/ui/overlay-render.ts +0 -103
  220. package/node_modules/pi-footer/src/ui/screen-context.ts +0 -18
  221. package/node_modules/pi-footer/src/ui/screen-controller.ts +0 -27
  222. package/node_modules/pi-footer/src/ui/screen-render.ts +0 -32
  223. package/node_modules/pi-footer/src/ui/screen-state.ts +0 -20
  224. package/node_modules/pi-footer/src/ui/screen.ts +0 -243
  225. package/node_modules/pi-footer/src/ui/screens/add-widget.ts +0 -92
  226. package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +0 -52
  227. package/node_modules/pi-footer/src/ui/screens/controller.ts +0 -12
  228. package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +0 -68
  229. package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +0 -115
  230. package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +0 -61
  231. package/node_modules/pi-footer/src/ui/screens/global.ts +0 -75
  232. package/node_modules/pi-footer/src/ui/screens/line-list.ts +0 -108
  233. package/node_modules/pi-footer/src/ui/screens/main.ts +0 -99
  234. package/node_modules/pi-footer/src/ui/screens/terminal.ts +0 -121
  235. package/node_modules/pi-footer/src/ui/screens/widget-list.ts +0 -154
  236. package/node_modules/pi-footer/src/ui/terminal-menu.ts +0 -32
  237. package/node_modules/pi-footer/src/ui/theme.ts +0 -48
  238. package/node_modules/pi-footer/src/ui/title-bar.ts +0 -100
  239. package/node_modules/pi-footer/src/ui/widget-actions.ts +0 -76
  240. package/node_modules/pi-footer/src/ui.ts +0 -66
  241. package/node_modules/pi-footer/src/widgets/context.ts +0 -28
  242. package/node_modules/pi-footer/src/widgets/core/active-tools.ts +0 -17
  243. package/node_modules/pi-footer/src/widgets/core/context-window.ts +0 -24
  244. package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +0 -19
  245. package/node_modules/pi-footer/src/widgets/core/cwd.ts +0 -108
  246. package/node_modules/pi-footer/src/widgets/core/event.ts +0 -34
  247. package/node_modules/pi-footer/src/widgets/core/external-status.ts +0 -102
  248. package/node_modules/pi-footer/src/widgets/core/model-provider.ts +0 -20
  249. package/node_modules/pi-footer/src/widgets/core/model.ts +0 -35
  250. package/node_modules/pi-footer/src/widgets/core/provider.ts +0 -17
  251. package/node_modules/pi-footer/src/widgets/core/session-name.ts +0 -17
  252. package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +0 -17
  253. package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +0 -17
  254. package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +0 -17
  255. package/node_modules/pi-footer/src/widgets/git/branch.ts +0 -81
  256. package/node_modules/pi-footer/src/widgets/git/clean.ts +0 -19
  257. package/node_modules/pi-footer/src/widgets/git/deletions.ts +0 -17
  258. package/node_modules/pi-footer/src/widgets/git/diff.ts +0 -38
  259. package/node_modules/pi-footer/src/widgets/git/insertions.ts +0 -17
  260. package/node_modules/pi-footer/src/widgets/git/remote.ts +0 -17
  261. package/node_modules/pi-footer/src/widgets/git/root.ts +0 -17
  262. package/node_modules/pi-footer/src/widgets/git/sha.ts +0 -17
  263. package/node_modules/pi-footer/src/widgets/git/staged.ts +0 -17
  264. package/node_modules/pi-footer/src/widgets/git/status.ts +0 -19
  265. package/node_modules/pi-footer/src/widgets/git/unstaged.ts +0 -17
  266. package/node_modules/pi-footer/src/widgets/git/untracked.ts +0 -17
  267. package/node_modules/pi-footer/src/widgets/instance.ts +0 -118
  268. package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +0 -18
  269. package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +0 -32
  270. package/node_modules/pi-footer/src/widgets/layout/separator.ts +0 -57
  271. package/node_modules/pi-footer/src/widgets/layout/spacer.ts +0 -31
  272. package/node_modules/pi-footer/src/widgets/options.ts +0 -122
  273. package/node_modules/pi-footer/src/widgets/project/runtime.ts +0 -361
  274. package/node_modules/pi-footer/src/widgets/registry.ts +0 -223
  275. package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +0 -17
  276. package/node_modules/pi-footer/src/widgets/session/compactions.ts +0 -17
  277. package/node_modules/pi-footer/src/widgets/session/elapsed.ts +0 -18
  278. package/node_modules/pi-footer/src/widgets/session/last-activity.ts +0 -18
  279. package/node_modules/pi-footer/src/widgets/session/messages.ts +0 -19
  280. package/node_modules/pi-footer/src/widgets/session/session-id.ts +0 -17
  281. package/node_modules/pi-footer/src/widgets/session/session-start.ts +0 -18
  282. package/node_modules/pi-footer/src/widgets/session/tool-results.ts +0 -17
  283. package/node_modules/pi-footer/src/widgets/session/total-messages.ts +0 -19
  284. package/node_modules/pi-footer/src/widgets/session/total-time.ts +0 -18
  285. package/node_modules/pi-footer/src/widgets/session/user-messages.ts +0 -17
  286. package/node_modules/pi-footer/src/widgets/store.ts +0 -26
  287. package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +0 -55
  288. package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +0 -18
  289. package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +0 -18
  290. package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +0 -108
  291. package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +0 -26
  292. package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +0 -29
  293. package/node_modules/pi-footer/src/widgets/tokens/context.ts +0 -29
  294. package/node_modules/pi-footer/src/widgets/tokens/cost.ts +0 -51
  295. package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +0 -25
  296. package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +0 -18
  297. package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +0 -25
  298. package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +0 -18
  299. package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +0 -20
  300. package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +0 -25
  301. package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +0 -18
  302. package/node_modules/pi-footer/src/widgets/types.ts +0 -181
  303. package/node_modules/pi-footer/src/widgets/utils/colors.ts +0 -11
  304. package/node_modules/pi-footer/src/widgets/utils/context.ts +0 -112
  305. package/node_modules/pi-footer/src/widgets/utils/session.ts +0 -19
  306. package/node_modules/pi-footer/src/widgets/utils/token-format.ts +0 -78
  307. /package/node_modules/{@herbertgao/resume-from → resume-from}/LICENSE +0 -0
  308. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.js +0 -0
  309. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  310. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.js +0 -0
  311. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  312. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.js +0 -0
  313. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  314. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.js +0 -0
  315. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  316. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.js +0 -0
  317. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  318. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  319. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.js +0 -0
  320. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.js +0 -0
  321. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.d.ts +0 -0
  322. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  323. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.js +0 -0
  324. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  325. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  326. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.js +0 -0
  327. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.js +0 -0
  328. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  329. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.js +0 -0
  330. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.d.ts +0 -0
  331. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.js +0 -0
  332. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.d.ts +0 -0
  333. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.js +0 -0
  334. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  335. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.js +0 -0
  336. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  337. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  338. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.js +0 -0
  339. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.d.ts +0 -0
  340. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.js +0 -0
  341. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.d.ts +0 -0
  342. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.js +0 -0
  343. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.d.ts +0 -0
  344. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.js +0 -0
  345. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.d.ts +0 -0
  346. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.js +0 -0
  347. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.d.ts +0 -0
  348. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.js +0 -0
  349. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.d.ts +0 -0
  350. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.js +0 -0
  351. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.d.ts +0 -0
  352. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.js +0 -0
  353. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.d.ts +0 -0
  354. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.js +0 -0
  355. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.d.ts +0 -0
  356. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.js +0 -0
  357. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.d.ts +0 -0
  358. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.js +0 -0
  359. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  360. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  361. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.js +0 -0
  362. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  363. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.js +0 -0
  364. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  365. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.js +0 -0
  366. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  367. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.js +0 -0
  368. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  369. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.js +0 -0
  370. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  371. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.js +0 -0
  372. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.d.ts +0 -0
  373. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.js +0 -0
  374. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.d.ts +0 -0
  375. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.js +0 -0
  376. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.js +0 -0
  377. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.js +0 -0
  378. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.d.ts +0 -0
  379. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.js +0 -0
  380. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.d.ts +0 -0
  381. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.js +0 -0
  382. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.d.ts +0 -0
  383. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.js +0 -0
  384. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  385. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.js +0 -0
  386. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.d.ts +0 -0
  387. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.js +0 -0
  388. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.d.ts +0 -0
  389. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.js +0 -0
  390. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.js +0 -0
  391. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.d.ts +0 -0
  392. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.js +0 -0
  393. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.d.ts +0 -0
  394. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.js +0 -0
  395. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.d.ts +0 -0
  396. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.js +0 -0
  397. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.d.ts +0 -0
  398. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.d.ts +0 -0
  399. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.js +0 -0
  400. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.d.ts +0 -0
  401. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.js +0 -0
  402. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.d.ts +0 -0
  403. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.js +0 -0
  404. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.d.ts +0 -0
  405. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.js +0 -0
  406. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.d.ts +0 -0
  407. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.js +0 -0
  408. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.d.ts +0 -0
  409. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.js +0 -0
  410. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.d.ts +0 -0
  411. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.js +0 -0
  412. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.d.ts +0 -0
  413. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.d.ts +0 -0
  414. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.js +0 -0
  415. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.d.ts +0 -0
  416. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.js +0 -0
  417. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.d.ts +0 -0
  418. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.js +0 -0
  419. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.d.ts +0 -0
  420. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.js +0 -0
  421. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.d.ts +0 -0
  422. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.js +0 -0
  423. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.d.ts +0 -0
  424. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.js +0 -0
  425. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.d.ts +0 -0
  426. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.js +0 -0
  427. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.d.ts +0 -0
  428. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.js +0 -0
  429. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.js +0 -0
  430. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.d.ts +0 -0
  431. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.js +0 -0
  432. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.d.ts +0 -0
  433. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.js +0 -0
  434. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  435. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.js +0 -0
  436. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.d.ts +0 -0
  437. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.js +0 -0
  438. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  439. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.js +0 -0
  440. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  441. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.js +0 -0
  442. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.d.ts +0 -0
  443. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.js +0 -0
  444. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.js +0 -0
@@ -14,6 +14,7 @@ import {
14
14
  import {
15
15
  SESSION_REFERENCE_CUSTOM_TYPE,
16
16
  SESSION_REFERENCE_PREFIX,
17
+ assignReferenceTokens,
17
18
  buildReferenceContentFromSections,
18
19
  extractSessionReferenceIds,
19
20
  formatReferenceSession,
@@ -26,8 +27,6 @@ const MAX_SESSION_SUGGESTIONS = 3;
26
27
  const MAX_FILE_SUGGESTIONS = 7;
27
28
  const MAX_REFERENCED_SESSIONS = 5;
28
29
  const MENTION_PATTERN = /(?:^|[\t ])@([^\s@]*)$/;
29
- const SUBAGENT_MANAGER_KEY = Symbol.for("pi-subagents:manager");
30
-
31
30
  // ── In-process subagent record tracker ──────────────────────────────
32
31
  // pi-subagents does not expose a global manager; we track records
33
32
  // ourselves by listening to the events it emits.
@@ -53,17 +52,6 @@ type SessionReference = {
53
52
  messages?: unknown[];
54
53
  };
55
54
 
56
- type SubagentRecord = {
57
- id: string;
58
- description?: string;
59
- startedAt?: number;
60
- completedAt?: number;
61
- };
62
-
63
- type SubagentManager = {
64
- getRecord(id: string): SubagentRecord | undefined;
65
- };
66
-
67
55
  // Local subagent record tracking (pi-subagents does not expose a global manager).
68
56
  const liveSubagentRecords = new Map<string, SubagentLiveRecord>();
69
57
  /** Cap retained completed/live records so long-lived pi processes cannot grow unbounded. */
@@ -109,7 +97,7 @@ function trackSubagentFromEvent(data: unknown): void {
109
97
  // Started event — create new record
110
98
  const agent = typeof event.agent === "string" ? event.agent : "";
111
99
  const cwd = typeof event.cwd === "string" ? event.cwd : "";
112
- const startedAt = typeof event.startedAt === "number" ? (event.startedAt as number) : Date.now();
100
+ const startedAt = typeof event.startedAt === "number" ? event.startedAt : Date.now();
113
101
  liveSubagentRecords.set(runId, {
114
102
  runId,
115
103
  sessionId,
@@ -120,26 +108,6 @@ function trackSubagentFromEvent(data: unknown): void {
120
108
  pruneLiveSubagentRecords();
121
109
  }
122
110
 
123
- function getSubagentManager(): SubagentManager | undefined {
124
- // Try the global manager first (future-proof), fall back to local records.
125
- const manager = (globalThis as any)[SUBAGENT_MANAGER_KEY] as SubagentManager | undefined;
126
- if (manager && typeof manager.getRecord === "function") return manager;
127
- // If no global manager, use our local tracking.
128
- if (liveSubagentRecords.size === 0) return undefined;
129
- return {
130
- getRecord(id: string): SubagentRecord | undefined {
131
- const record = liveSubagentRecords.get(id);
132
- if (!record) return undefined;
133
- return {
134
- id: record.runId,
135
- description: record.agent || undefined,
136
- startedAt: record.startedAt,
137
- completedAt: record.completedAt,
138
- };
139
- },
140
- };
141
- }
142
-
143
111
  function extractMentionQuery(textBeforeCursor: string): string | undefined {
144
112
  return textBeforeCursor.match(MENTION_PATTERN)?.[1];
145
113
  }
@@ -156,7 +124,7 @@ function formatDate(date: Date): string {
156
124
  const sessionSearchTextCache = new WeakMap<SessionReference, string>();
157
125
  const sessionItemCache = new WeakMap<
158
126
  SessionReference,
159
- { cwd: string; named?: AutocompleteItem; stable?: AutocompleteItem }
127
+ { cwd: string; token: string; item: AutocompleteItem }
160
128
  >();
161
129
 
162
130
  function sessionSearchText(reference: SessionReference): string {
@@ -171,30 +139,24 @@ function sessionSearchText(reference: SessionReference): string {
171
139
  function sessionItem(
172
140
  reference: SessionReference,
173
141
  currentCwd: string,
174
- useStableId: boolean,
142
+ token: string,
175
143
  ): AutocompleteItem {
176
- let cached = sessionItemCache.get(reference);
177
- const variant = useStableId ? "stable" : "named";
178
- if (cached?.cwd === currentCwd && cached[variant]) return cached[variant];
144
+ const cached = sessionItemCache.get(reference);
145
+ if (cached?.cwd === currentCwd && cached.token === token) return cached.item;
179
146
 
180
147
  const session = reference.info;
181
148
  const workspace = samePath(session.cwd, currentCwd)
182
149
  ? "current workspace"
183
150
  : session.cwd || "unknown workspace";
184
- const label = reference.kind === "subagent" ? "[SubAgent]" : "[Session]";
185
- // 唯一名称保持短格式;同名或无名称时使用稳定 ID,避免引用歧义。
186
- const sessionName = session.name?.trim();
187
- const referenceId = useStableId
188
- ? reference.referenceIds[0]
189
- : (sessionName ?? reference.referenceIds[0]);
151
+ const kindLabel = reference.kind === "subagent" ? "[SubAgent]" : "[Session]";
152
+ // 消歧后的 token 会带上日期;回落到 ID 时下拉仍显示可读标题。
153
+ const title = token === (reference.referenceIds[0] ?? session.id) ? sessionTitle(session) : token;
190
154
  const item: AutocompleteItem = {
191
- value: `${SESSION_REFERENCE_PREFIX}[${referenceId}]`,
192
- label: `${label} ${sessionTitle(session)}`,
155
+ value: `${SESSION_REFERENCE_PREFIX}[${token}]`,
156
+ label: `${kindLabel} ${title}`,
193
157
  description: `${workspace} · ${session.messageCount} messages · ${formatDate(session.modified)}`,
194
158
  };
195
- if (cached?.cwd !== currentCwd) cached = { cwd: currentCwd };
196
- cached[variant] = item;
197
- sessionItemCache.set(reference, cached);
159
+ sessionItemCache.set(reference, { cwd: currentCwd, token, item });
198
160
  return item;
199
161
  }
200
162
 
@@ -230,11 +192,7 @@ function filterSessions(
230
192
  if (query.startsWith("session:")) return [];
231
193
 
232
194
  const ordered = orderSessionReferences(references, currentCwd);
233
- const nameCounts = new Map<string, number>();
234
- for (const reference of ordered) {
235
- const name = reference.info.name?.trim();
236
- if (name) nameCounts.set(name, (nameCounts.get(name) ?? 0) + 1);
237
- }
195
+ const tokens = assignReferenceTokens(ordered);
238
196
  const trimmed = query.trim();
239
197
  // 模糊匹配只接受有 session name 的会话;subagent 按 agent name 匹配。
240
198
  const searchable = ordered.filter(
@@ -244,10 +202,11 @@ function filterSessions(
244
202
  const matches = trimmed
245
203
  ? fuzzyFilter(searchable, trimmed, sessionSearchText)
246
204
  : ordered.slice(0, MAX_SESSION_SUGGESTIONS);
247
- return matches.slice(0, MAX_SESSION_SUGGESTIONS).map((reference) => {
248
- const name = reference.info.name?.trim();
249
- return sessionItem(reference, currentCwd, Boolean(name && (nameCounts.get(name) ?? 0) > 1));
250
- });
205
+ return matches
206
+ .slice(0, MAX_SESSION_SUGGESTIONS)
207
+ .map((reference) =>
208
+ sessionItem(reference, currentCwd, tokens.get(reference) ?? reference.info.id),
209
+ );
251
210
  }
252
211
 
253
212
  function isPathLikeQuery(query: string): boolean {
@@ -279,31 +238,20 @@ function liveSubagentReferences(
279
238
  agentIds: Set<string>,
280
239
  currentSessionId: string,
281
240
  ): SessionReference[] {
282
- const manager = getSubagentManager();
283
- if (!manager) return [];
284
-
285
241
  const references: SessionReference[] = [];
286
242
  for (const agentId of agentIds) {
287
- const record = manager.getRecord(agentId);
288
- if (!record) continue;
289
-
290
- // Try the global manager's live session first (future-proof).
291
- const liveRecord = liveSubagentRecords.get(agentId);
292
- const sessionId = liveRecord?.sessionId ?? record.id;
293
- if (!sessionId || sessionId === currentSessionId) continue;
294
-
295
- const name = record.description?.trim() || liveRecord?.agent || undefined;
296
- const modifiedAt = record.completedAt ?? record.startedAt ?? Date.now();
243
+ const record = liveSubagentRecords.get(agentId);
244
+ if (!record || record.sessionId === currentSessionId) continue;
297
245
  references.push({
298
246
  kind: "subagent",
299
- referenceIds: [sessionId, agentId],
247
+ referenceIds: [record.sessionId, agentId],
300
248
  info: {
301
- id: sessionId,
302
- name,
303
- cwd: liveRecord?.cwd ?? "",
249
+ id: record.sessionId,
250
+ name: record.agent || undefined,
251
+ cwd: record.cwd,
304
252
  firstMessage: "",
305
253
  messageCount: 0,
306
- modified: new Date(modifiedAt),
254
+ modified: new Date(record.completedAt ?? record.startedAt),
307
255
  },
308
256
  });
309
257
  }
@@ -347,14 +295,14 @@ export function createAutocompleteProvider(
347
295
  const currentLine = lines[cursorLine] ?? "";
348
296
  const query = extractMentionQuery(currentLine.slice(0, cursorCol));
349
297
  if (query === undefined) {
350
- const suggestions = await current.getSuggestions(lines, cursorLine, cursorCol, options);
351
- return options.signal.aborted || !isCurrent() ? null : suggestions;
298
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
352
299
  }
353
300
 
354
301
  const [baseSuggestions, references] = await Promise.all([
355
302
  current.getSuggestions(lines, cursorLine, cursorCol, options),
356
303
  getReferences(),
357
304
  ]);
305
+ // 会话已被替换时,旧会话的补全结果不能再泄漏到新会话。
358
306
  if (options.signal.aborted || !isCurrent()) return null;
359
307
 
360
308
  const sessionItems = filterSessions(references, query, currentCwd);
@@ -415,10 +363,13 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
415
363
 
416
364
  pi.on("session_start", (_event, ctx) => {
417
365
  const generation = ++sessionGeneration;
366
+ // 会话替换/reload 会让 ctx 的 getter 抛 stale 错误,await 之后不能再读;
367
+ // 这里在同步阶段一次性取出纯值。
368
+ const currentCwd = ctx.cwd;
369
+ const ui = ctx.ui;
418
370
  subagentIds.clear();
419
371
  clearLiveSubagentRecords();
420
372
  let loadErrorShown = false;
421
- const currentCwd = ctx.cwd;
422
373
  const currentSessionId = ctx.sessionManager.getSessionId();
423
374
  const currentSessionFile = ctx.sessionManager.getSessionFile();
424
375
  let sessionsPromise: Promise<SessionInfo[]> | undefined;
@@ -435,7 +386,7 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
435
386
  if (!loadErrorShown && generation === sessionGeneration) {
436
387
  loadErrorShown = true;
437
388
  const reason = error instanceof Error ? error.message : String(error);
438
- ctx.ui.notify(`session-reference: failed to load sessions: ${reason}`, "error");
389
+ ui.notify(`session-reference: failed to load sessions: ${reason}`, "error");
439
390
  }
440
391
  return [];
441
392
  });
@@ -448,7 +399,7 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
448
399
  | undefined;
449
400
  const getReferences = async (): Promise<SessionReference[]> => {
450
401
  const sessions = await getSessions();
451
- // Session replacement can invalidate this closure while listAll() is pending.
402
+ // 会话替换/reload 后丢弃旧 generation 的结果,避免对失效状态继续工作。
452
403
  if (generation !== sessionGeneration) return [];
453
404
  const subagentKey = [...subagentIds].join("\0");
454
405
  if (
@@ -467,14 +418,15 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
467
418
  };
468
419
 
469
420
  getAvailableReferences = getReferences;
470
- const isTui = ctx.mode === "tui";
471
- if (isTui) {
472
- void getReferences();
421
+ if (ctx.mode === "tui") {
422
+ // 预取是 detached 的,必须兜住 rejection,否则 stale 错误会变成
423
+ // unhandled rejection 直接终止 Pi。
424
+ void getReferences().catch(() => {});
473
425
  // Register after other session_start handlers. pi-fff claims every @
474
426
  // prefix, so a provider installed before it would never see session mentions.
475
427
  setTimeout(() => {
476
428
  if (generation !== sessionGeneration) return;
477
- ctx.ui.addAutocompleteProvider((current) =>
429
+ ui.addAutocompleteProvider((current) =>
478
430
  createAutocompleteProvider(
479
431
  current,
480
432
  getReferences,
@@ -492,38 +444,33 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
492
444
 
493
445
  const generation = sessionGeneration;
494
446
  const currentSessionId = ctx.sessionManager.getSessionId();
495
- const references = await (getAvailableReferences?.() ??
496
- SessionManager.listAll()
497
- .then((sessions) =>
447
+ let references: SessionReference[];
448
+ try {
449
+ references = await (getAvailableReferences?.() ??
450
+ SessionManager.listAll().then((sessions) =>
498
451
  mergeReferences(
499
452
  sessions.filter((session) => session.id !== currentSessionId),
500
453
  liveSubagentReferences(subagentIds, currentSessionId),
501
454
  ),
502
- )
503
- .catch((error: unknown) => {
504
- if (generation !== sessionGeneration) return [];
505
- const reason = error instanceof Error ? error.message : String(error);
506
- ctx.ui.notify(`session-reference: failed to load sessions: ${reason}`, "error");
507
- return [];
508
- }));
455
+ ));
456
+ } catch (error) {
457
+ if (generation !== sessionGeneration) return;
458
+ throw error;
459
+ }
460
+ // await 期间会话被替换/关闭:ctx 已失效,丢弃结果。
509
461
  if (generation !== sessionGeneration) return;
510
462
  const referencesById = new Map<string, SessionReference>();
511
- const referencesByName = new Map<string, SessionReference>();
512
- const ambiguousNames = new Set<string>();
463
+ const referencesByToken = new Map<string, SessionReference>();
513
464
  for (const reference of references) {
514
465
  for (const id of reference.referenceIds) referencesById.set(id, reference);
515
- const name = reference.info.name?.trim();
516
- if (!name || ambiguousNames.has(name)) continue;
517
- if (referencesByName.has(name)) {
518
- referencesByName.delete(name);
519
- ambiguousNames.add(name);
520
- } else {
521
- referencesByName.set(name, reference);
522
- }
466
+ }
467
+ // 同位重名的会话用带日期的 token 区分,解析端与补全端用同一套分配。
468
+ for (const [reference, token] of assignReferenceTokens(references)) {
469
+ referencesByToken.set(token, reference);
523
470
  }
524
471
  const seenReferences = new Set<SessionReference>();
525
472
  const matchingReferences = referenceIds
526
- .map((id) => referencesById.get(id) ?? referencesByName.get(id))
473
+ .map((id) => referencesById.get(id) ?? referencesByToken.get(id))
527
474
  .filter((reference): reference is SessionReference => {
528
475
  if (!reference || reference.info.id === currentSessionId || seenReferences.has(reference))
529
476
  return false;
@@ -585,7 +532,8 @@ export default function sessionReferenceExtension(pi: ExtensionAPI): void {
585
532
  });
586
533
 
587
534
  pi.on("session_before_switch", () => {
588
- // This event can cancel; preserve current-session state until shutdown.
535
+ subagentIds.clear();
536
+ clearLiveSubagentRecords();
589
537
  });
590
538
 
591
539
  pi.on("session_shutdown", () => {
@@ -1,8 +1,10 @@
1
+ import { truncateToWidth } from "@earendil-works/pi-tui";
2
+ import { stripTerminalSequences } from "../../utils/ansi-text.ts";
3
+
1
4
  export const SESSION_REFERENCE_CUSTOM_TYPE = "session-reference";
2
5
  export const SESSION_REFERENCE_PREFIX = "@session:";
3
6
 
4
- const SESSION_REFERENCE_PATTERN =
5
- /(?:^|\s)@session:(?:\[([^\]]+)\]|([A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?))(?![\w.\]-])/g;
7
+ const SESSION_REFERENCE_PATTERN = /(?:^|\s)@session:\[([^\]]+)](?![\w-])/g;
6
8
  const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/g;
7
9
 
8
10
  export interface ReferenceSessionInfo {
@@ -31,13 +33,12 @@ export const DEFAULT_REFERENCE_LIMITS: ReferenceLimits = {
31
33
  maxTotalBytes: 48_000,
32
34
  };
33
35
 
34
- /** 提取 @session:[name](组 1)或旧格式 @session:id(组 2),返回 name 或 id。 */
35
36
  export function extractSessionReferenceIds(text: string): string[] {
36
37
  const ids: string[] = [];
37
38
  const seen = new Set<string>();
38
39
 
39
40
  for (const match of text.matchAll(SESSION_REFERENCE_PATTERN)) {
40
- const id = (match[1] ?? match[2])?.trim();
41
+ const id = match[1]?.trim();
41
42
  if (id && !seen.has(id)) {
42
43
  seen.add(id);
43
44
  ids.push(id);
@@ -47,13 +48,104 @@ export function extractSessionReferenceIds(text: string): string[] {
47
48
  return ids;
48
49
  }
49
50
 
51
+ const EMPTY_SESSION_TITLE = "(no messages)";
52
+
50
53
  export function sessionTitle(info: ReferenceSessionInfo, maxLength = 80): string {
51
- const source = info.name?.trim() || info.firstMessage || "(no messages)";
54
+ const source = info.name?.trim() || info.firstMessage || EMPTY_SESSION_TITLE;
52
55
  const normalized = source.replace(CONTROL_CHARACTERS, " ").replace(/\s+/g, " ").trim();
53
56
  if (normalized.length <= maxLength) return normalized;
54
57
  return `${normalized.slice(0, Math.max(1, maxLength - 1)).trimEnd()}…`;
55
58
  }
56
59
 
60
+ /**
61
+ * 编辑器里的 `@session:[…]` 是行内文本,token 按显示宽度收口,
62
+ * 不让首条消息整段挤进输入行。同名会话靠后缀消歧,不受它影响。
63
+ */
64
+ export const REFERENCE_TOKEN_MAX_WIDTH = 32;
65
+
66
+ /** Editor `@session:[…]` text: the readable title, never a placeholder or brackets. */
67
+ export function sessionReferenceLabel(
68
+ info: ReferenceSessionInfo,
69
+ maxWidth = REFERENCE_TOKEN_MAX_WIDTH,
70
+ ): string {
71
+ const title = sessionTitle(info).replace(/[[\]]/g, "").trim();
72
+ if (!title || title === EMPTY_SESSION_TITLE) return "";
73
+ // truncateToWidth 会在省略号前后补 ANSI reset,token 是明文,去掉。
74
+ return stripTerminalSequences(truncateToWidth(title, maxWidth, "…")).trim();
75
+ }
76
+
77
+ export interface ReferenceTokenSource {
78
+ referenceIds: string[];
79
+ info: ReferenceSessionInfo;
80
+ }
81
+
82
+ /** UTC keeps the disambiguator identical across timezones (same-day drift is harmless). */
83
+ function referenceTokenDate(date: Date): string {
84
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
85
+ const day = String(date.getUTCDate()).padStart(2, "0");
86
+ return `${month}-${day}`;
87
+ }
88
+
89
+ function referenceTokenTime(date: Date): string {
90
+ const hours = String(date.getUTCHours()).padStart(2, "0");
91
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
92
+ return `${hours}:${minutes}`;
93
+ }
94
+
95
+ /** Title first; date then time widen the disambiguation before the ID fallback. */
96
+ function referenceTokenCandidates(reference: ReferenceTokenSource): string[] {
97
+ const title = sessionReferenceLabel(reference.info);
98
+ const stableId = reference.referenceIds[0] ?? reference.info.id;
99
+ if (!title) return [stableId];
100
+ const date = referenceTokenDate(reference.info.modified);
101
+ return [
102
+ title,
103
+ `${title} ${date}`,
104
+ `${title} ${date} ${referenceTokenTime(reference.info.modified)}`,
105
+ stableId,
106
+ ];
107
+ }
108
+
109
+ /**
110
+ * Assign each reference a unique editor token. Same-named sessions keep a readable
111
+ * title plus a date/time suffix; the stable ID is only the last resort.
112
+ */
113
+ export function assignReferenceTokens<T extends ReferenceTokenSource>(
114
+ references: T[],
115
+ ): Map<T, string> {
116
+ const candidates = new Map<T, string[]>();
117
+ let levels = 0;
118
+ for (const reference of references) {
119
+ const options = referenceTokenCandidates(reference);
120
+ levels = Math.max(levels, options.length);
121
+ candidates.set(reference, options);
122
+ }
123
+
124
+ const tokens = new Map<T, string>();
125
+ const taken = new Set<string>();
126
+ for (let level = 0; level < levels && tokens.size < references.length; level++) {
127
+ const counts = new Map<string, number>();
128
+ for (const [reference, options] of candidates) {
129
+ const candidate = tokens.has(reference) ? undefined : options[level];
130
+ if (candidate) counts.set(candidate, (counts.get(candidate) ?? 0) + 1);
131
+ }
132
+ for (const [reference, options] of candidates) {
133
+ if (tokens.has(reference)) continue;
134
+ const candidate = options[level];
135
+ if (candidate && counts.get(candidate) === 1 && !taken.has(candidate)) {
136
+ tokens.set(reference, candidate);
137
+ taken.add(candidate);
138
+ }
139
+ }
140
+ }
141
+ for (const reference of references) {
142
+ if (!tokens.has(reference)) {
143
+ tokens.set(reference, reference.referenceIds[0] ?? reference.info.id);
144
+ }
145
+ }
146
+ return tokens;
147
+ }
148
+
57
149
  function byteLength(text: string): number {
58
150
  return Buffer.byteLength(text, "utf8");
59
151
  }
@@ -250,13 +342,3 @@ export function buildReferenceContentFromSections(
250
342
  ].join("\n");
251
343
  return truncateUtf8([header, ...sections].join("\n\n"), maxTotalBytes);
252
344
  }
253
-
254
- export function buildReferenceContent(
255
- sources: ReferenceSource[],
256
- limits: ReferenceLimits = DEFAULT_REFERENCE_LIMITS,
257
- ): string {
258
- return buildReferenceContentFromSections(
259
- sources.map((source) => formatReferenceSession(source, limits)),
260
- limits.maxTotalBytes,
261
- );
262
- }
@@ -18,13 +18,16 @@ type AgentInfo = {
18
18
  filePath: string;
19
19
  };
20
20
 
21
+ export const SUBAGENT_DELEGATION_CUSTOM_TYPE = "subagent-delegation";
22
+ export const SUBAGENT_REFERENCE_PREFIX = "@subagent:";
23
+
21
24
  const MAX_SUGGESTIONS = 2;
22
- // Match `@name` but NOT `@session:` (reserved by session-reference extension).
23
- const AGENT_NAME_PATTERN = /(?:^|[\t ])@((?:[^\s:@][^\s:]*)?)$/;
25
+ const MENTION_PATTERN = /(?:^|[\t ])@([^\s@]*)$/;
26
+ const SUBAGENT_REFERENCE_PATTERN = /(?:^|\s)@subagent:\[([^\]]+)](?![\w-])/g;
24
27
 
25
28
  function getAgentDir(): string {
26
- const root = process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
27
- return join(root, "agents");
29
+ const override = process.env.PI_CODING_AGENT_DIR;
30
+ return join(override ? override : join(homedir(), ".pi", "agent"), "agents");
28
31
  }
29
32
 
30
33
  function parseFrontmatter(content: string): Record<string, string> {
@@ -41,34 +44,60 @@ function parseFrontmatter(content: string): Record<string, string> {
41
44
  function loadAgents(): AgentInfo[] {
42
45
  const dir = getAgentDir();
43
46
  if (!existsSync(dir)) return [];
44
- let files: string[];
45
- try {
46
- files = readdirSync(dir);
47
- } catch {
48
- return [];
49
- }
50
47
 
51
- const agents: AgentInfo[] = [];
52
- for (const file of files) {
53
- if (!file.endsWith(".md")) continue;
54
- try {
48
+ return readdirSync(dir)
49
+ .filter((f) => f.endsWith(".md"))
50
+ .flatMap((file) => {
55
51
  const filePath = join(dir, file);
56
- const content = readFileSync(filePath, "utf-8");
52
+ let content: string;
53
+ try {
54
+ content = readFileSync(filePath, "utf-8");
55
+ } catch {
56
+ return []; // 目录或不可读条目直接跳过
57
+ }
57
58
  const fm = parseFrontmatter(content);
58
59
  const name = file.replace(/\.md$/, "");
59
- agents.push({
60
- name,
61
- displayName: fm.display_name || name,
62
- description: fm.description || "",
63
- model: fm.model,
64
- thinking: fm.thinking,
65
- filePath,
66
- });
67
- } catch {
68
- // One unreadable agent file must not break autocomplete or prompt submission.
60
+ return [
61
+ {
62
+ name,
63
+ displayName: fm.display_name || name,
64
+ description: fm.description || "",
65
+ model: fm.model,
66
+ thinking: fm.thinking,
67
+ filePath,
68
+ },
69
+ ];
70
+ });
71
+ }
72
+
73
+ function extractMentionQuery(textBeforeCursor: string): string | undefined {
74
+ return textBeforeCursor.match(MENTION_PATTERN)?.[1];
75
+ }
76
+
77
+ /** Filter text for agent names, or null when this provider should not claim the @ query. */
78
+ function agentSearchQuery(raw: string): string | null {
79
+ if (raw.startsWith("session:")) return null;
80
+ if (raw === "subagent") return "";
81
+ const prefixed = raw.match(/^subagent:\[?([^\]]*)$/);
82
+ if (prefixed) return prefixed[1] ?? "";
83
+ return raw;
84
+ }
85
+
86
+ export function extractSubagentReferenceNames(text: string): string[] {
87
+ const names: string[] = [];
88
+ const seen = new Set<string>();
89
+ for (const match of text.matchAll(SUBAGENT_REFERENCE_PATTERN)) {
90
+ const name = match[1]?.trim();
91
+ if (name && !seen.has(name)) {
92
+ seen.add(name);
93
+ names.push(name);
69
94
  }
70
95
  }
71
- return agents;
96
+ return names;
97
+ }
98
+
99
+ export function subagentReferenceValue(name: string): string {
100
+ return `${SUBAGENT_REFERENCE_PREFIX}[${name}]`;
72
101
  }
73
102
 
74
103
  export function createAgentAutocompleteProvider(
@@ -85,13 +114,16 @@ export function createAgentAutocompleteProvider(
85
114
  ): Promise<AutocompleteSuggestions | null> {
86
115
  const currentLine = lines[cursorLine] ?? "";
87
116
  const textBeforeCursor = currentLine.slice(0, cursorCol);
88
- const match = textBeforeCursor.match(AGENT_NAME_PATTERN);
117
+ const rawQuery = extractMentionQuery(textBeforeCursor);
118
+ if (rawQuery === undefined) {
119
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
120
+ }
89
121
 
90
- if (!match) {
122
+ const search = agentSearchQuery(rawQuery);
123
+ if (search === null) {
91
124
  return current.getSuggestions(lines, cursorLine, cursorCol, options);
92
125
  }
93
126
 
94
- const query = match[1]!;
95
127
  const agents = getAgents();
96
128
 
97
129
  if (options.signal.aborted || agents.length === 0) {
@@ -100,17 +132,20 @@ export function createAgentAutocompleteProvider(
100
132
 
101
133
  const [baseSuggestions, matches] = await Promise.all([
102
134
  current.getSuggestions(lines, cursorLine, cursorCol, options),
103
- Promise.resolve(query.trim() ? fuzzyFilter(agents, query, (a) => a.name) : agents),
135
+ Promise.resolve(search.trim() ? fuzzyFilter(agents, search, (a) => a.name) : agents),
104
136
  ]);
105
137
  if (options.signal.aborted) return null;
106
138
 
107
139
  const agentItems: AutocompleteItem[] = matches.slice(0, MAX_SUGGESTIONS).map((agent) => ({
108
- value: `@${agent.name}`,
140
+ value: subagentReferenceValue(agent.name),
109
141
  label: `[SubAgent] ${agent.displayName}`,
110
142
  description: `${agent.model ?? "?"} · ${agent.thinking ?? "?"}`,
111
143
  }));
112
- const hasCompatibleBaseSuggestions = baseSuggestions?.prefix === `@${query}`;
113
- const agentValues = new Set(agents.map((agent) => `@${agent.name}`));
144
+ const prefix = `@${rawQuery}`;
145
+ const hasCompatibleBaseSuggestions = baseSuggestions?.prefix === prefix;
146
+ const agentValues = new Set(
147
+ agents.flatMap((agent) => [`@${agent.name}`, subagentReferenceValue(agent.name)]),
148
+ );
114
149
  const baseItems = hasCompatibleBaseSuggestions
115
150
  ? baseSuggestions.items.filter((item) => !agentValues.has(item.value))
116
151
  : [];
@@ -123,7 +158,7 @@ export function createAgentAutocompleteProvider(
123
158
  });
124
159
 
125
160
  if (items.length === 0 && !hasCompatibleBaseSuggestions) return baseSuggestions;
126
- return { items, prefix: `@${query}` };
161
+ return { items, prefix };
127
162
  },
128
163
 
129
164
  applyCompletion(
@@ -177,16 +212,13 @@ export default function agentAutocompleteExtension(pi: ExtensionAPI): void {
177
212
  sessionGeneration++;
178
213
  });
179
214
 
180
- // Inject instruction when user types @agent-name (not @session:) in prompt.
181
- // Supports multiple different subagents in a single prompt.
182
- const AGENT_PROMPT_PATTERN = /(?:^|[\s])@([^\s:@][^\s:]*)/g;
215
+ // Inject as a request message, not systemPrompt, so the cached prefix stays stable.
183
216
  pi.on("before_agent_start", async (event, _ctx) => {
184
217
  const agents = getAgents();
185
218
  if (agents.length === 0) return;
186
219
 
187
220
  const mentions: string[] = [];
188
- for (const m of event.prompt.matchAll(AGENT_PROMPT_PATTERN)) {
189
- const name = m[1]!;
221
+ for (const name of extractSubagentReferenceNames(event.prompt)) {
190
222
  if (agents.some((a) => a.name === name) && !mentions.includes(name)) {
191
223
  mentions.push(name);
192
224
  }
@@ -197,12 +229,15 @@ export default function agentAutocompleteExtension(pi: ExtensionAPI): void {
197
229
  const agentList = mentions.map((n) => `"${n}" (${agentMap.get(n)!.displayName})`).join(", ");
198
230
 
199
231
  return {
200
- systemPrompt:
201
- event.systemPrompt +
202
- `\n\nThe user's prompt references these subagent types: ${agentList}. ` +
203
- `You MUST use the Agent tool for EACH mentioned subagent to delegate the relevant parts of the request. ` +
204
- `Handle different subagents separately — do NOT merge their tasks into a single Agent call. ` +
205
- `For example, if the user mentions @coder and @explore, make two separate Agent tool calls, one with subagent_type="coder" and another with subagent_type="explore".`,
232
+ message: {
233
+ customType: SUBAGENT_DELEGATION_CUSTOM_TYPE,
234
+ content:
235
+ `The user's prompt references these subagent types: ${agentList}. ` +
236
+ `You MUST use the Agent tool for EACH mentioned subagent to delegate the relevant parts of the request. ` +
237
+ `Handle different subagents separately — do NOT merge their tasks into a single Agent call. ` +
238
+ `For example, if the user mentions @subagent:[coder] and @subagent:[explore], make two separate Agent tool calls, one with subagent_type="coder" and another with subagent_type="explore".`,
239
+ display: false,
240
+ },
206
241
  };
207
242
  });
208
243
  }