@herbertgao/pi-extensions 2026.9.20 → 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 (282) hide show
  1. package/README.md +13 -8
  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 +50 -50
  7. package/node_modules/@herbertgao/pi-cc-extensions/README.md +7 -7
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +25 -2
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +24 -1
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -4
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +47 -5
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/mcp-chip.ts +136 -0
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +56 -11
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +36 -4
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +11 -2
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +303 -0
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-header.ts +1 -1
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-highlight.ts +36 -0
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +2 -2
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +2 -2
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +88 -34
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +6 -5
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-execution.ts +1 -1
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +31 -6
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/message-display.ts +3 -3
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +3 -0
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +173 -36
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-text.ts +1 -0
  29. package/node_modules/@herbertgao/pi-cc-extensions/package.json +6 -4
  30. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  31. package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
  32. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +3 -2
  33. package/node_modules/@herbertgao/sol-pi/CONTRIBUTING.md +22 -0
  34. package/node_modules/@herbertgao/sol-pi/README.md +36 -17
  35. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +10 -6
  36. package/node_modules/@herbertgao/sol-pi/agents-install.md +15 -12
  37. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +24 -8
  38. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +2 -2
  39. package/node_modules/@herbertgao/sol-pi/docs/star-history.md +18 -0
  40. package/node_modules/@herbertgao/sol-pi/package.json +4 -2
  41. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +1 -1
  42. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +1 -1
  43. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +23 -4
  44. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +32 -1
  45. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +3 -2
  46. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +1 -1
  47. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +27 -7
  48. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +137 -41
  49. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +1 -0
  50. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +2 -1
  51. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/projection.ts +58 -0
  52. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +28 -6
  53. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +2 -1
  54. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +15 -2
  55. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  56. package/node_modules/@pi-plugins/fast-mode/README.md +7 -1
  57. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  58. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +7 -1
  59. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  60. package/node_modules/@pi-plugins/fast-mode/package.json +5 -5
  61. package/node_modules/pi-antigravity/README.md +3 -0
  62. package/node_modules/pi-antigravity/package.json +8 -8
  63. package/node_modules/pi-antigravity/src/auth/oauth.ts +6 -3
  64. package/node_modules/pi-antigravity/src/index.ts +114 -110
  65. package/node_modules/pi-antigravity/src/stream/stream.ts +1 -1
  66. package/node_modules/pi-antigravity/src/utils/util.ts +18 -1
  67. package/node_modules/pi-multi-account/CHANGELOG.md +20 -0
  68. package/node_modules/pi-multi-account/README.md +46 -8
  69. package/node_modules/pi-multi-account/config-file-transaction.ts +42 -0
  70. package/node_modules/pi-multi-account/index.ts +255 -269
  71. package/node_modules/pi-multi-account/model-pins.ts +36 -0
  72. package/node_modules/pi-multi-account/package.json +9 -7
  73. package/node_modules/pi-multi-account/slot-proxy-auth.ts +12 -2
  74. package/node_modules/pi-multi-account/slot-proxy.ts +27 -5
  75. package/node_modules/pi-web-access/CHANGELOG.md +17 -0
  76. package/node_modules/pi-web-access/README.md +6 -3
  77. package/node_modules/pi-web-access/brave-rate-limit.ts +170 -0
  78. package/node_modules/pi-web-access/brave.ts +28 -11
  79. package/node_modules/pi-web-access/dist/index.js +202 -33
  80. package/node_modules/pi-web-access/gemini-search.ts +2 -5
  81. package/node_modules/pi-web-access/index.ts +13 -7
  82. package/node_modules/pi-web-access/openai-search.ts +24 -10
  83. package/node_modules/pi-web-access/package.json +1 -1
  84. package/node_modules/pi-web-access/summary-review.ts +8 -2
  85. package/node_modules/{@herbertgao/resume-from → resume-from}/README.md +16 -12
  86. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -5
  87. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.js +2 -3
  88. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.d.ts +2 -2
  89. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.d.ts +3 -0
  90. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.js +27 -15
  91. package/node_modules/{@herbertgao/resume-from/dist/adapters/pi → resume-from/dist/adapters/claude-code}/redaction.js +16 -3
  92. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.d.ts +2 -4
  93. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.js +1 -1
  94. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.d.ts +2 -4
  95. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.js +1 -2
  96. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/read.d.ts +16 -0
  97. package/node_modules/resume-from/dist/adapters/codex/read.js +723 -0
  98. package/node_modules/{@herbertgao/resume-from/dist/adapters/claude-code → resume-from/dist/adapters/codex}/redaction.js +16 -3
  99. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.d.ts +44 -4
  100. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.js +88 -4
  101. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.d.ts +2 -2
  102. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.js +2 -2
  103. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.d.ts +5 -1
  104. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.js +10 -6
  105. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.d.ts +2 -2
  106. package/node_modules/{@herbertgao/resume-from/dist/adapters/codex → resume-from/dist/adapters/pi}/redaction.js +16 -3
  107. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.d.ts +2 -4
  108. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.js +2 -2
  109. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.d.ts +1 -1
  110. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.js +4 -4
  111. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.js +2 -2
  112. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.d.ts +2 -2
  113. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.js +31 -8
  114. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.d.ts +1 -1
  115. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.js +1 -2
  116. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.d.ts +4 -1
  117. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.js +2 -2
  118. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.d.ts +8 -6
  119. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.d.ts +10 -5
  120. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/finder.d.ts +2 -1
  121. package/node_modules/resume-from/dist/import/discovery/finder.js +269 -0
  122. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.d.ts +3 -3
  123. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.js +3 -3
  124. package/node_modules/resume-from/dist/import/pipeline.d.ts +28 -0
  125. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/pipeline.js +31 -11
  126. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.d.ts +2 -2
  127. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.js +9 -5
  128. package/node_modules/resume-from/dist/import/preview/warnings.d.ts +14 -0
  129. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/warnings.js +26 -20
  130. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.js +12 -2
  131. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.d.ts +9 -3
  132. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.d.ts +4 -4
  133. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.js +7 -4
  134. package/node_modules/resume-from/dist/platform/repo/reader.d.ts +3 -0
  135. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/reader.js +60 -20
  136. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.d.ts +8 -1
  137. package/node_modules/{@herbertgao/resume-from → resume-from}/package.json +19 -32
  138. package/node_modules/{@herbertgao/resume-from → resume-from}/shims/pi/extensions/resume-from.js +2 -2
  139. package/package.json +17 -17
  140. package/node_modules/@herbertgao/resume-from/dist/adapters/codex/read.js +0 -270
  141. package/node_modules/@herbertgao/resume-from/dist/import/discovery/finder.js +0 -129
  142. package/node_modules/@herbertgao/resume-from/dist/import/pipeline.d.ts +0 -17
  143. package/node_modules/@herbertgao/resume-from/dist/import/preview/warnings.d.ts +0 -11
  144. package/node_modules/@herbertgao/resume-from/dist/platform/repo/reader.d.ts +0 -8
  145. /package/node_modules/{@herbertgao/resume-from → resume-from}/LICENSE +0 -0
  146. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.js +0 -0
  147. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  148. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.js +0 -0
  149. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  150. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.js +0 -0
  151. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  152. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.js +0 -0
  153. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  154. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.js +0 -0
  155. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  156. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  157. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.js +0 -0
  158. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.js +0 -0
  159. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.d.ts +0 -0
  160. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  161. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.js +0 -0
  162. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  163. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  164. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.js +0 -0
  165. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.js +0 -0
  166. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  167. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.js +0 -0
  168. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.d.ts +0 -0
  169. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.js +0 -0
  170. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.d.ts +0 -0
  171. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.js +0 -0
  172. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  173. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.js +0 -0
  174. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  175. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  176. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.js +0 -0
  177. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.d.ts +0 -0
  178. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.js +0 -0
  179. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.d.ts +0 -0
  180. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.js +0 -0
  181. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.d.ts +0 -0
  182. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.js +0 -0
  183. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.d.ts +0 -0
  184. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.js +0 -0
  185. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.d.ts +0 -0
  186. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.js +0 -0
  187. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.d.ts +0 -0
  188. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.js +0 -0
  189. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.d.ts +0 -0
  190. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.js +0 -0
  191. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.d.ts +0 -0
  192. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.js +0 -0
  193. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.d.ts +0 -0
  194. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.js +0 -0
  195. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.d.ts +0 -0
  196. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.js +0 -0
  197. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  198. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  199. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.js +0 -0
  200. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  201. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.js +0 -0
  202. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  203. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.js +0 -0
  204. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  205. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.js +0 -0
  206. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  207. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.js +0 -0
  208. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  209. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.js +0 -0
  210. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.d.ts +0 -0
  211. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.js +0 -0
  212. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.d.ts +0 -0
  213. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.js +0 -0
  214. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.js +0 -0
  215. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.js +0 -0
  216. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.d.ts +0 -0
  217. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.js +0 -0
  218. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.d.ts +0 -0
  219. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.js +0 -0
  220. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.d.ts +0 -0
  221. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.js +0 -0
  222. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  223. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.js +0 -0
  224. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.d.ts +0 -0
  225. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.js +0 -0
  226. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.d.ts +0 -0
  227. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.js +0 -0
  228. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.js +0 -0
  229. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.d.ts +0 -0
  230. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.js +0 -0
  231. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.d.ts +0 -0
  232. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.js +0 -0
  233. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.d.ts +0 -0
  234. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.js +0 -0
  235. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.d.ts +0 -0
  236. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.d.ts +0 -0
  237. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.js +0 -0
  238. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.d.ts +0 -0
  239. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.js +0 -0
  240. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.d.ts +0 -0
  241. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.js +0 -0
  242. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.d.ts +0 -0
  243. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.js +0 -0
  244. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.d.ts +0 -0
  245. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.js +0 -0
  246. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.d.ts +0 -0
  247. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.js +0 -0
  248. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.d.ts +0 -0
  249. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.js +0 -0
  250. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.d.ts +0 -0
  251. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.d.ts +0 -0
  252. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.js +0 -0
  253. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.d.ts +0 -0
  254. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.js +0 -0
  255. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.d.ts +0 -0
  256. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.js +0 -0
  257. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.d.ts +0 -0
  258. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.js +0 -0
  259. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.d.ts +0 -0
  260. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.js +0 -0
  261. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.d.ts +0 -0
  262. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.js +0 -0
  263. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.d.ts +0 -0
  264. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.js +0 -0
  265. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.d.ts +0 -0
  266. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.js +0 -0
  267. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.js +0 -0
  268. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.d.ts +0 -0
  269. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.js +0 -0
  270. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.d.ts +0 -0
  271. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.js +0 -0
  272. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  273. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.js +0 -0
  274. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.d.ts +0 -0
  275. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.js +0 -0
  276. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  277. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.js +0 -0
  278. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  279. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.js +0 -0
  280. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.d.ts +0 -0
  281. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.js +0 -0
  282. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.js +0 -0
package/README.md CHANGED
@@ -8,7 +8,7 @@ Aggregate installer for HerbertGao-maintained Pi extensions and pinned upstream
8
8
  pi install npm:@herbertgao/pi-extensions
9
9
  ```
10
10
 
11
- Requires Node.js 24 or newer and Pi 0.85.1 or newer.
11
+ Requires Node.js 24 or newer and Pi 1.0.4 or newer.
12
12
 
13
13
  ## Native MCP
14
14
 
@@ -18,14 +18,14 @@ When migrating from `pi-mcp-adapter`, remove any standalone adapter install as w
18
18
 
19
19
  ## Bundled extensions
20
20
 
21
- The package bundles 5 active `@herbertgao/*` child packages—`pi-bark`, `pi-cc-extensions`, `resume-from`, `pi-subagents`, and `sol-pi`—plus the following upstream packages under their original names:
21
+ The package bundles 4 active `@herbertgao/*` child packages—`pi-bark`, `pi-cc-extensions`, `pi-subagents`, and `sol-pi`—plus the following upstream packages under their original names:
22
22
 
23
- - `pi-antigravity@0.8.1`
23
+ - `pi-antigravity@0.9.0`
24
24
  - `@dietrichgebert/ponytail@4.10.0`
25
- - `@juicesharp/rpiv-ask-user-question@2.11.0`
25
+ - `@juicesharp/rpiv-ask-user-question@2.12.0`
26
26
  - `@narumitw/pi-btw@0.61.1`
27
27
  - `@narumitw/pi-caffeinate@0.49.8`
28
- - `@pi-plugins/fast-mode@0.1.12`
28
+ - `@pi-plugins/fast-mode@0.1.13`
29
29
  - `@tifan/pi-copy-response@0.2.7`
30
30
  - `@tifan/pi-handoff@2.2.2`
31
31
  - `@tifan/pi-inline-skills@1.0.6`
@@ -34,15 +34,20 @@ The package bundles 5 active `@herbertgao/*` child packages—`pi-bark`, `pi-cc-
34
34
  - `@tifan/pi-recap@0.4.7`
35
35
  - `@tifan/pi-rename@0.6.0`
36
36
  - `pi-typesafe@0.8.1`
37
- - `pi-multi-account@1.23.2`
37
+ - `pi-multi-account@1.24.0`
38
38
  - `pi-next-cue@1.0.7`
39
39
  - `pi-jev-auto-mode@0.5.0`
40
40
  - `pi-lens@4.3.0`
41
- - `pi-web-access@0.34.0`
41
+ - `pi-web-access@0.35.0`
42
42
  - `remote-pi@0.7.0`
43
+ - `resume-from@0.4.1`
43
44
 
44
45
  Pi loads their extensions and skills through `node_modules/` paths inside one package root. The upstream companions are pinned and bundled, not forked or renamed.
45
46
 
47
+ The local `@herbertgao/resume-from` fork is retired. If it is installed separately, remove that package before upgrading the aggregate to avoid registering `/resume-from` twice. The aggregate now uses upstream `resume-from@0.4.1`; its v0.4.0 start-directory fix supersedes our local patch.
48
+
49
+ The locally customized CC and SoL-Pi packages now follow complete upstream baselines `pi-cc-extensions@0.9.10` and SoL-Pi main `e1a586af`, with local behavior replayed on top. Action Fusion and ccstyle write rich diffs coexist without disabling either feature. All four SoL-Pi features remain opt-in; its new non-persistent-session evidence archives remain on disk for consumers and require host or caller cleanup.
50
+
46
51
  ### Bark notifications
47
52
 
48
53
  `@herbertgao/pi-bark` sends localized Bark pushes when a user-facing Pi run fully settles or `@juicesharp/rpiv-ask-user-question` needs an answer. Notifications include emoji-labeled machine/path metadata and support the bundled official Pi badge through Bark's `icon` parameter. Configure it in `$PI_CODING_AGENT_DIR/bark.json` (normally `~/.pi/agent/bark.json`); see the [package README](../pi-bark/README.md). Without a valid endpoint it stays inactive.
@@ -51,7 +56,7 @@ Pi loads their extensions and skills through `node_modules/` paths inside one pa
51
56
 
52
57
  `pi-jev-auto-mode@0.5.0` adds fail-closed Jev safety gates for shell commands and file changes. `pi-typesafe@0.8.1` adds the `/typesafe` command and `typesafe_evaluate` tool for explicit structured decisions; both use the TypeSafe API after login.
53
58
 
54
- `@herbertgao/resume-from@0.2.0` keeps Claude Code sessions associated with their original repository when the active transcript later moves into a nested cwd. `@herbertgao/sol-pi@0.1.0` adds opt-in Action Fusion, ObservationPack, Evidence-Preserving Reducer, and Online Context Compact; see its [configuration guide](../sol-pi/docs/configuration.md). `pi-lens@4.3.0` expands language routing and bounds retained diagnostic facts across multi-root sessions. `pi-web-access@0.34.0` provides configurable web search and fetch tools; its `toolActivation` defaults to `auto`, choosing eager or dynamic tool activation per model. `pi-antigravity@0.8.1` reads Pi 0.86+ transcript system messages, so Antigravity requests carry Pi's system prompt and tools; it also registers `google_search` and `generate_image` tools that use the signed-in Antigravity account. Preferred Thinking 1.0.2 preserves an explicit subagent `--thinking` choice. Deprecated `@tifan/pi-titlebar-spinner` is no longer bundled; Rename remains the single owner of Herdr tab naming.
59
+ `resume-from@0.4.1` continues sessions across Pi, Claude Code, and Codex; it keeps a Claude Code session matched to its start directory when the active transcript later moves into a nested cwd. `@herbertgao/sol-pi` adds opt-in Action Fusion, ObservationPack, Evidence-Preserving Reducer, and Online Context Compact; see its [configuration guide](../sol-pi/docs/configuration.md). `pi-lens@4.3.0` expands language routing and bounds retained diagnostic facts across multi-root sessions. `pi-web-access@0.35.0` provides configurable web search and fetch tools; its `toolActivation` defaults to `auto`, choosing eager or dynamic tool activation per model. `pi-antigravity@0.9.0` reads Pi 0.86+ transcript system messages, so Antigravity requests carry Pi's system prompt and tools; it also registers `google_search` and `generate_image` tools that use the signed-in Antigravity account. Preferred Thinking 1.0.2 preserves an explicit subagent `--thinking` choice. Deprecated `@tifan/pi-titlebar-spinner` is no longer bundled; Rename remains the single owner of Herdr tab naming.
55
60
 
56
61
  `pi-stash` is no longer bundled: `/btw` already preserves the main editor draft while handling side questions outside the main conversation. Prior `@herbertgao/pi-stash` releases remain available but are no longer maintained here.
57
62
 
@@ -34,6 +34,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
34
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35
35
  THE SOFTWARE.
36
36
 
37
+ ## `resume-from`
38
+
39
+ The aggregate bundles [`resume-from`](https://github.com/alexei-led/resume-from) version 0.4.1 under its original MIT license:
40
+
41
+ MIT License
42
+
43
+ Copyright (c) 2026 Alexei Led
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining a copy
46
+ of this software and associated documentation files (the "Software"), to deal
47
+ in the Software without restriction, including without limitation the rights
48
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49
+ copies of the Software, and to permit persons to whom the Software is
50
+ furnished to do so, subject to the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be included in all
53
+ copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
61
+ SOFTWARE.
62
+
37
63
  ## `@narumitw/pi-caffeinate`
38
64
 
39
65
  The aggregate bundles [`@narumitw/pi-caffeinate`](https://github.com/narumiruna/pi-extensions/tree/main/packages/pi-caffeinate) version 0.49.7 under its original MIT license:
@@ -62,7 +88,7 @@ SOFTWARE.
62
88
 
63
89
  ## `@herbertgao/sol-pi`
64
90
 
65
- The aggregate bundles [`@herbertgao/sol-pi`](https://github.com/HerbertGao/pi-extensions/tree/master/packages/sol-pi) version 0.1.0. Its source is republished from [`NVlabs/SoL-Pi`](https://github.com/NVlabs/SoL-Pi) under the MIT license:
91
+ The aggregate bundles [`@herbertgao/sol-pi`](https://github.com/HerbertGao/pi-extensions/tree/master/packages/sol-pi), adapted from [`NVlabs/SoL-Pi`](https://github.com/NVlabs/SoL-Pi) commit `e1a586af0ad8956f42ae5b26bba20e48fbf30e00` under the MIT license:
66
92
 
67
93
  Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
68
94
 
@@ -86,7 +112,7 @@ THE SOFTWARE.
86
112
 
87
113
  ## `pi-antigravity`
88
114
 
89
- The aggregate bundles the MIT-licensed [`pi-antigravity`](https://github.com/Rahularya01/pi-antigravity) package version 0.8.1 under its original attribution:
115
+ The aggregate bundles the MIT-licensed [`pi-antigravity`](https://github.com/Rahularya01/pi-antigravity) package version 0.9.0 under its original attribution:
90
116
 
91
117
  MIT License
92
118
 
@@ -163,7 +189,7 @@ THE SOFTWARE.
163
189
 
164
190
  ## `pi-multi-account`
165
191
 
166
- The aggregate bundles the MIT-licensed [`pi-multi-account`](https://github.com/Sarrius/pi-multi-account) package version 1.23.2 under its original attribution:
192
+ The aggregate bundles the MIT-licensed [`pi-multi-account`](https://github.com/Sarrius/pi-multi-account) package version 1.24.0 under its original attribution:
167
193
 
168
194
  MIT License
169
195
 
@@ -1,6 +1,6 @@
1
1
  # @herbertgao/pi-bark
2
2
 
3
- Bark notifications for user-facing Pi sessions. It sends a notification when Pi fully settles and when [`@juicesharp/rpiv-ask-user-question`](https://github.com/juicesharp/rpiv-mono) opens a questionnaire. Requests follow Bark's official [POST form API](https://github.com/Finb/Bark/blob/master/docs/en-us/tutorial.md#request-methods).
3
+ Bark notifications for user-facing Pi sessions. It sends a notification when Pi fully settles and when Pi blocks on a user-facing dialog — an approval, a select, an input prompt, a custom panel, or an [`@juicesharp/rpiv-ask-user-question`](https://github.com/juicesharp/rpiv-mono) questionnaire. Requests follow Bark's official [POST form API](https://github.com/Finb/Bark/blob/master/docs/en-us/tutorial.md#request-methods).
4
4
 
5
5
  ## Install
6
6
 
@@ -21,17 +21,53 @@ Create `$PI_CODING_AGENT_DIR/bark.json` (normally `~/.pi/agent/bark.json`):
21
21
  "locale": "zh-CN",
22
22
  "events": {
23
23
  "agentSettled": true,
24
- "askUserQuestion": true
24
+ "needsInput": true
25
25
  },
26
26
  "params": {
27
27
  "group": "pi",
28
28
  "icon": "https://raw.githubusercontent.com/HerbertGao/pi-extensions/master/packages/pi-bark/assets/pi-icon.png"
29
29
  },
30
+ "title": {
31
+ "source": "session",
32
+ "maxLength": 40
33
+ },
34
+ "minDurationMs": 30000,
30
35
  "timeoutMs": 4000
31
36
  }
32
37
  ```
33
38
 
34
- `endpoint` is required. `locale` accepts `auto` (default), `zh-CN`, `zh-TW`, or `en`; unsupported languages fall back to English. `params` accepts additional Bark POST parameters such as `group`, `sound`, `icon`, and `level`; dynamic `title` and `body` values always take precedence. Set `"enabled": false` to disable all notifications without removing the package.
39
+ `endpoint` is required. `locale` accepts `auto` (default), `zh-CN`, `zh-TW`, or `en`; unsupported languages fall back to English. `params` accepts additional Bark POST parameters such as `group`, `sound`, `icon`, and `level`; dynamic `title` and `body` values always take precedence. Set `"enabled": false` to disable all notifications without removing the package. `events.needsInput` covers every blocking dialog; `events.askUserQuestion` is the older name and is still honored as an alias.
40
+
41
+ ### Session titles
42
+
43
+ The default `title.source` is `"fixed"`, which keeps Pi's localized copy (`✅ Pi 跑完了` / `🟡 Pi 等你回答`) as the notification title. Set it to `"session"` to title the notification with the session instead — Pi's session name when one is set, otherwise the first user message, which is the label hosts such as Paseo already show for the session:
44
+
45
+ ```json
46
+ { "title": { "source": "session", "maxLength": 40 } }
47
+ ```
48
+
49
+ `maxLength` defaults to `40`, counts Unicode code points without splitting emoji surrogate pairs, and includes the ellipsis. Non-finite values or values below `1` fall back to the default. With `"session"`, the event state moves to the first line of the body:
50
+
51
+ ```
52
+ title: Please reply with exactly the single wo…
53
+ body: ✅ 已完成 · 用时 2m14s
54
+ 💻 MacBook Pro M1 Max
55
+ 📁 /Users/herbertgao/VSCodeProject/pi
56
+ ```
57
+
58
+ The title is resolved when the notification is sent, so a session that is renamed or that has only just received its first message still gets the right one.
59
+
60
+ ### Short runs
61
+
62
+ `minDurationMs` defaults to `0` (always notify). Raise it to skip the settle notification when the run finished faster, so one-line replies stop producing notification noise:
63
+
64
+ ```json
65
+ { "minDurationMs": 30000 }
66
+ ```
67
+
68
+ `minDurationMs` never suppresses needs-input notifications. Input notifications wait 400ms so an unsupported, cancelled, or quickly answered UI call does not send a stale alert. Pending alerts are cancelled when the prompt, run, or session ends. Questionnaire fallback events use a 1.5s de-duplication window because they have no shared dialog ID; separate fallback-only prompts inside that window may be merged. Native dialogs are tracked independently.
69
+
70
+ Completion notifications await the Bark request before Pi finishes settling, including during session switching or exit. This can delay those operations up to `timeoutMs` (default 4 seconds). Errors and timeouts are ignored; delivery is best-effort, with no persistent queue or retries.
35
71
 
36
72
  The notification body uses `💻` for the configured machine name and `📁` for Pi's full working directory. Questionnaire text is intentionally not sent because it may contain sensitive context. Only sessions with a user-facing UI notify, so nested `pi-subagents` sessions do not create duplicate pushes.
37
73
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-bark",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Send Bark notifications when Pi finishes or needs user input.",
5
5
  "keywords": [
6
6
  "bark",
@@ -1,39 +1,75 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"
1
+ import type {
2
+ ExtensionAPI,
3
+ ExtensionContext,
4
+ } from "@earendil-works/pi-coding-agent"
2
5
  import { readFileSync } from "node:fs"
3
6
  import { homedir, hostname } from "node:os"
4
7
  import { join } from "node:path"
5
8
 
6
9
  const ASK_USER_PROMPT_EVENT = "rpiv:ask-user:prompt"
10
+ /** Give closed/unsupported UI calls time to finish before notifying. */
11
+ const NEEDS_INPUT_DELAY_MS = 400
12
+ // ponytail: fallback events lack dialog IDs; this window can merge distinct fallback prompts.
13
+ // Replace it with dialog IDs if the event source provides them.
14
+ const NEEDS_INPUT_DEDUP_MS = 1_500
7
15
  const DEFAULT_TIMEOUT_MS = 4_000
16
+ const DEFAULT_MAX_TITLE_LENGTH = 40
17
+ const DEFAULT_MIN_DURATION_MS = 0
8
18
 
9
19
  export type BarkLocale = "en" | "zh-CN" | "zh-TW"
10
- type NotificationEvent = "agentSettled" | "askUserQuestion"
20
+ type NotificationEvent = "agentSettled" | "needsInput"
21
+ export type BarkTitleSource = "fixed" | "session"
11
22
 
12
- const COPY: Record<BarkLocale, Record<NotificationEvent, string>> = {
23
+ const COPY: Record<
24
+ BarkLocale,
25
+ {
26
+ agentSettled: string
27
+ settledWithDuration: (duration: string) => string
28
+ needsInput: string
29
+ needsInputBody: string
30
+ }
31
+ > = {
13
32
  en: {
14
33
  agentSettled: "✅ Pi finished",
15
- askUserQuestion: "🟡 Pi needs your input",
34
+ settledWithDuration: (duration) => `✅ Pi finished · ${duration}`,
35
+ needsInput: "🟡 Pi needs your input",
36
+ needsInputBody: "🟡 Needs your reply",
16
37
  },
17
38
  "zh-CN": {
18
39
  agentSettled: "✅ Pi 跑完了",
19
- askUserQuestion: "🟡 Pi 等你回答",
40
+ settledWithDuration: (duration) => `✅ 已完成 · 用时 ${duration}`,
41
+ needsInput: "🟡 Pi 等你回答",
42
+ needsInputBody: "🟡 需要你回复",
20
43
  },
21
44
  "zh-TW": {
22
45
  agentSettled: "✅ Pi 已完成",
23
- askUserQuestion: "🟡 Pi 等你回覆",
46
+ settledWithDuration: (duration) => `✅ 已完成 · 耗時 ${duration}`,
47
+ needsInput: "🟡 Pi 等你回覆",
48
+ needsInputBody: "🟡 需要你回覆",
24
49
  },
25
50
  }
26
51
 
52
+ export interface BarkTitleOptions {
53
+ /** "fixed" keeps the localized Pi copy as the title (default). "session" uses the session title. */
54
+ source: BarkTitleSource
55
+ /** Maximum title length before truncation. */
56
+ maxLength: number
57
+ }
58
+
27
59
  export interface BarkConfig {
28
60
  endpoint: string
29
61
  machine: string
30
62
  locale: BarkLocale
31
63
  events: {
32
64
  agentSettled: boolean
33
- askUserQuestion: boolean
65
+ /** Any blocking user-facing dialog: approval, select, input, custom, ask_user_question. */
66
+ needsInput: boolean
34
67
  }
35
68
  params: Record<string, string | number | boolean>
36
69
  timeoutMs: number
70
+ title: BarkTitleOptions
71
+ /** Skip the settle notification when the run finished faster than this. 0 notifies always. */
72
+ minDurationMs: number
37
73
  }
38
74
 
39
75
  export function getConfigPath(): string {
@@ -61,6 +97,85 @@ export function notificationTitle(
61
97
  return COPY[locale][event]
62
98
  }
63
99
 
100
+ /** Render a bounded, human-readable duration such as `45s`, `2m14s`, or `1h3m`. */
101
+ export function formatDuration(ms: number): string {
102
+ const total = Math.max(0, Math.round(ms / 1000))
103
+ if (total < 60) return `${total}s`
104
+ const minutes = Math.floor(total / 60)
105
+ const seconds = total % 60
106
+ if (minutes < 60) return seconds ? `${minutes}m${seconds}s` : `${minutes}m`
107
+ const hours = Math.floor(minutes / 60)
108
+ const remainder = minutes % 60
109
+ return remainder ? `${hours}h${remainder}m` : `${hours}h`
110
+ }
111
+
112
+ function normalizeText(value: unknown): string {
113
+ if (typeof value !== "string") return ""
114
+ return value
115
+ .replace(/[\r\n\t]+/g, " ")
116
+ .replace(/\s{2,}/g, " ")
117
+ .trim()
118
+ }
119
+
120
+ export function truncateTitle(text: string, maxLength: number): string {
121
+ const characters = Array.from(normalizeText(text))
122
+ if (!maxLength || characters.length <= maxLength) return characters.join("")
123
+ return `${characters
124
+ .slice(0, maxLength - 1)
125
+ .join("")
126
+ .trimEnd()}…`
127
+ }
128
+
129
+ /** Read the text of a message content value (string or content-part array). */
130
+ export function readMessageText(content: unknown): string {
131
+ if (typeof content === "string") return content
132
+ if (!Array.isArray(content)) return ""
133
+ return content
134
+ .filter(
135
+ (part) =>
136
+ part &&
137
+ typeof part === "object" &&
138
+ (part as { type?: string }).type === "text" &&
139
+ typeof (part as { text?: unknown }).text === "string",
140
+ )
141
+ .map((part) => (part as { text: string }).text)
142
+ .join(" ")
143
+ }
144
+
145
+ /**
146
+ * Pi session name if the user set one, else the first user message — the same
147
+ * label most hosts show for the session.
148
+ */
149
+ export function resolveSessionTitle(
150
+ ctx: Pick<ExtensionContext, "sessionManager"> | undefined,
151
+ getSessionName?: () => string | undefined,
152
+ ): string {
153
+ try {
154
+ const named = getSessionName?.()
155
+ if (typeof named === "string" && named.trim()) return named.trim()
156
+ } catch {
157
+ // fall through
158
+ }
159
+ try {
160
+ const manager = ctx?.sessionManager
161
+ const named = manager?.getSessionName?.()
162
+ if (typeof named === "string" && named.trim()) return named.trim()
163
+ } catch {
164
+ // fall through
165
+ }
166
+ try {
167
+ const entries = ctx?.sessionManager?.getEntries?.() ?? []
168
+ for (const entry of entries) {
169
+ if (entry?.type !== "message" || entry.message?.role !== "user") continue
170
+ const text = normalizeText(readMessageText(entry.message.content))
171
+ if (text) return text
172
+ }
173
+ } catch {
174
+ // fall through
175
+ }
176
+ return ""
177
+ }
178
+
64
179
  export function normalizeConfig(input: unknown): BarkConfig | undefined {
65
180
  if (!input || typeof input !== "object") return undefined
66
181
  const source = input as Record<string, unknown>
@@ -92,6 +207,10 @@ export function normalizeConfig(input: unknown): BarkConfig | undefined {
92
207
  source.timeoutMs > 0
93
208
  ? source.timeoutMs
94
209
  : DEFAULT_TIMEOUT_MS
210
+ const titleSource =
211
+ source.title && typeof source.title === "object"
212
+ ? (source.title as Record<string, unknown>)
213
+ : {}
95
214
 
96
215
  return {
97
216
  endpoint: source.endpoint,
@@ -102,10 +221,27 @@ export function normalizeConfig(input: unknown): BarkConfig | undefined {
102
221
  locale: resolveLocale(source.locale),
103
222
  events: {
104
223
  agentSettled: eventSource.agentSettled !== false,
105
- askUserQuestion: eventSource.askUserQuestion !== false,
224
+ // `askUserQuestion` is the pre-0.2 name and is still honored.
225
+ needsInput:
226
+ (eventSource.needsInput ?? eventSource.askUserQuestion) !== false,
106
227
  },
107
228
  params,
108
229
  timeoutMs,
230
+ title: {
231
+ source: titleSource.source === "session" ? "session" : "fixed",
232
+ maxLength:
233
+ typeof titleSource.maxLength === "number" &&
234
+ Number.isFinite(titleSource.maxLength) &&
235
+ titleSource.maxLength >= 1
236
+ ? Math.floor(titleSource.maxLength)
237
+ : DEFAULT_MAX_TITLE_LENGTH,
238
+ },
239
+ minDurationMs:
240
+ typeof source.minDurationMs === "number" &&
241
+ Number.isFinite(source.minDurationMs) &&
242
+ source.minDurationMs >= 0
243
+ ? source.minDurationMs
244
+ : DEFAULT_MIN_DURATION_MS,
109
245
  }
110
246
  }
111
247
 
@@ -145,34 +281,158 @@ export default function piBark(pi: ExtensionAPI): void {
145
281
  let config: BarkConfig | undefined
146
282
  let cwd = process.cwd()
147
283
  let userFacingSession = false
284
+ let cachedTitle = ""
285
+ let runStartedAt: number | null = null
286
+ let pendingNeedsInput: ReturnType<typeof setTimeout> | undefined
287
+ let uiPromptActive = false
288
+ let lastFallbackAt = 0
289
+ let lastUIPromptEndAt = 0
148
290
 
149
- const notify = async (title: string): Promise<void> => {
291
+ const refreshTitle = (ctx: ExtensionContext | undefined): string => {
292
+ const resolved = resolveSessionTitle(ctx, () => pi.getSessionName?.())
293
+ if (resolved) cachedTitle = resolved
294
+ return cachedTitle
295
+ }
296
+
297
+ const titleFor = (
298
+ ctx: ExtensionContext | undefined,
299
+ event: NotificationEvent,
300
+ ): string => {
301
+ if (!config) return ""
302
+ if (config.title.source === "fixed")
303
+ return notificationTitle(config.locale, event)
304
+ const session = ctx ? refreshTitle(ctx) : cachedTitle
305
+ return truncateTitle(session || config.machine, config.title.maxLength)
306
+ }
307
+
308
+ const notify = async (title: string, body: string): Promise<void> => {
150
309
  if (!config || !userFacingSession) return
151
310
  try {
152
- await sendBark(config, title, formatBody(config, cwd))
311
+ await sendBark(config, title, body)
153
312
  } catch {
154
313
  // Notifications are best-effort and must never interrupt Pi.
155
314
  }
156
315
  }
157
316
 
317
+ const cancelNeedsInput = () => {
318
+ clearTimeout(pendingNeedsInput)
319
+ pendingNeedsInput = undefined
320
+ }
321
+
322
+ const resetNeedsInput = () => {
323
+ cancelNeedsInput()
324
+ uiPromptActive = false
325
+ lastFallbackAt = 0
326
+ lastUIPromptEndAt = 0
327
+ }
328
+
329
+ const scheduleNeedsInput = (ctx: ExtensionContext | undefined) => {
330
+ if (!config?.events.needsInput || !userFacingSession) return
331
+ cancelNeedsInput()
332
+ pendingNeedsInput = setTimeout(() => {
333
+ pendingNeedsInput = undefined
334
+ if (!config?.events.needsInput || !userFacingSession) return
335
+ if (!ctx) lastFallbackAt = Date.now()
336
+ const prefix =
337
+ config.title.source === "session"
338
+ ? `${COPY[config.locale].needsInputBody}\n`
339
+ : ""
340
+ void notify(
341
+ titleFor(ctx, "needsInput"),
342
+ `${prefix}${formatBody(config, cwd)}`,
343
+ )
344
+ }, NEEDS_INPUT_DELAY_MS)
345
+ }
346
+
158
347
  const unsubscribeAskUser = pi.events.on(ASK_USER_PROMPT_EVENT, () => {
159
- if (config?.events.askUserQuestion)
160
- void notify(notificationTitle(config.locale, "askUserQuestion"))
348
+ const now = Date.now()
349
+ if (
350
+ uiPromptActive ||
351
+ now - lastUIPromptEndAt < NEEDS_INPUT_DEDUP_MS ||
352
+ now - lastFallbackAt < NEEDS_INPUT_DEDUP_MS
353
+ )
354
+ return
355
+ scheduleNeedsInput(undefined)
356
+ })
357
+
358
+ // Native prompt lifecycle cancels notifications for UI calls that finish
359
+ // without opening a dialog, or that the user answers before the grace period.
360
+ pi.on("ui_prompt_start", (_event, ctx) => {
361
+ cwd = ctx.cwd
362
+ uiPromptActive = true
363
+ cancelNeedsInput()
364
+ if (Date.now() - lastFallbackAt >= NEEDS_INPUT_DEDUP_MS)
365
+ scheduleNeedsInput(ctx)
366
+ })
367
+
368
+ pi.on("ui_prompt_end", () => {
369
+ uiPromptActive = false
370
+ lastFallbackAt = 0
371
+ lastUIPromptEndAt = Date.now()
372
+ cancelNeedsInput()
161
373
  })
162
374
 
163
375
  pi.on("session_start", (_event, ctx) => {
376
+ resetNeedsInput()
164
377
  config = loadConfig()
165
378
  cwd = ctx.cwd
166
379
  userFacingSession = ctx.hasUI
380
+ runStartedAt = null
381
+ cachedTitle = ""
382
+ refreshTitle(ctx)
383
+ })
384
+
385
+ // Pi persists the user entry at message_end, not on submit, so the title cache has to be
386
+ // refreshed on message/turn events rather than only at agent_start.
387
+ pi.on("session_info_changed", (_event, ctx) => {
388
+ refreshTitle(ctx)
167
389
  })
168
390
 
169
- pi.on("agent_settled", (_event, ctx) => {
391
+ pi.on("message_end", (_event, ctx) => {
392
+ refreshTitle(ctx)
393
+ })
394
+
395
+ pi.on("turn_end", (_event, ctx) => {
396
+ refreshTitle(ctx)
397
+ })
398
+
399
+ pi.on("agent_start", (_event, ctx) => {
400
+ if (runStartedAt === null) {
401
+ resetNeedsInput()
402
+ runStartedAt = Date.now()
403
+ }
404
+ refreshTitle(ctx)
405
+ })
406
+
407
+ pi.on("agent_settled", async (_event, ctx) => {
170
408
  cwd = ctx.cwd
171
- if (config?.events.agentSettled)
172
- void notify(notificationTitle(config.locale, "agentSettled"))
409
+ resetNeedsInput()
410
+ const startedAt = runStartedAt
411
+ runStartedAt = null
412
+ if (!config?.events.agentSettled) return
413
+
414
+ const elapsed = startedAt === null ? null : Date.now() - startedAt
415
+ if (elapsed !== null && elapsed < config.minDurationMs) return
416
+
417
+ const copy = COPY[config.locale]
418
+ const prefix =
419
+ config.title.source === "session"
420
+ ? `${
421
+ elapsed === null
422
+ ? copy.agentSettled
423
+ : copy.settledWithDuration(formatDuration(elapsed))
424
+ }\n`
425
+ : ""
426
+ // Await the request so a settle that races process shutdown still delivers.
427
+ await notify(
428
+ titleFor(ctx, "agentSettled"),
429
+ `${prefix}${formatBody(config, cwd)}`,
430
+ )
173
431
  })
174
432
 
175
433
  pi.on("session_shutdown", () => {
434
+ userFacingSession = false
435
+ resetNeedsInput()
176
436
  unsubscribeAskUser()
177
437
  })
178
438
  }