@herbertgao/pi-extensions 2026.9.20 → 2026.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/README.md +18 -13
  2. package/THIRD_PARTY_NOTICES.md +31 -5
  3. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +1 -1
  4. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +1 -1
  5. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +1 -1
  6. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +1 -1
  7. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +1 -1
  8. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/index.js +4 -0
  9. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +43 -3
  10. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +142 -59
  11. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
  12. package/node_modules/@dietrichgebert/ponytail/README.es.md +87 -204
  13. package/node_modules/@dietrichgebert/ponytail/README.ja.md +212 -0
  14. package/node_modules/@dietrichgebert/ponytail/README.ko.md +92 -226
  15. package/node_modules/@dietrichgebert/ponytail/README.md +58 -244
  16. package/node_modules/@dietrichgebert/ponytail/README.zh-CN.md +212 -0
  17. package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +3 -3
  18. package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +4 -4
  19. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +63 -16
  20. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +8 -7
  21. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +46 -23
  22. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +39 -7
  23. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +20 -3
  24. package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +3 -3
  25. package/node_modules/@dietrichgebert/ponytail/package.json +2 -2
  26. package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +47 -17
  27. package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +21 -7
  28. package/node_modules/@dietrichgebert/ponytail/skills/plugin.json +5 -0
  29. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +7 -2
  30. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +1 -1
  31. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +16 -14
  32. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +3 -3
  33. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +12 -7
  34. package/node_modules/@herbertgao/pi-bark/README.md +39 -3
  35. package/node_modules/@herbertgao/pi-bark/package.json +1 -1
  36. package/node_modules/@herbertgao/pi-bark/src/index.ts +275 -15
  37. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +50 -50
  38. package/node_modules/@herbertgao/pi-cc-extensions/README.md +7 -7
  39. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +25 -2
  40. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +24 -1
  41. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -4
  42. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +47 -5
  43. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/mcp-chip.ts +136 -0
  44. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +56 -11
  45. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +36 -4
  46. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +11 -2
  47. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +303 -0
  48. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-header.ts +1 -1
  49. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-highlight.ts +36 -0
  50. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +2 -2
  51. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +2 -2
  52. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +88 -34
  53. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +6 -5
  54. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-execution.ts +1 -1
  55. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +31 -6
  56. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/message-display.ts +3 -3
  57. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +3 -0
  58. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +173 -36
  59. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-text.ts +1 -0
  60. package/node_modules/@herbertgao/pi-cc-extensions/package.json +6 -4
  61. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  62. package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
  63. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +3 -2
  64. package/node_modules/@herbertgao/sol-pi/CONTRIBUTING.md +22 -0
  65. package/node_modules/@herbertgao/sol-pi/README.md +36 -17
  66. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +10 -6
  67. package/node_modules/@herbertgao/sol-pi/agents-install.md +15 -12
  68. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +24 -8
  69. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +2 -2
  70. package/node_modules/@herbertgao/sol-pi/docs/star-history.md +18 -0
  71. package/node_modules/@herbertgao/sol-pi/package.json +4 -2
  72. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +1 -1
  73. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +1 -1
  74. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +23 -4
  75. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +32 -1
  76. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +3 -2
  77. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +1 -1
  78. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +27 -7
  79. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +137 -41
  80. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +1 -0
  81. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +2 -1
  82. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/projection.ts +58 -0
  83. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +28 -6
  84. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +2 -1
  85. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +15 -2
  86. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  87. package/node_modules/@narumitw/pi-caffeinate/package.json +4 -4
  88. package/node_modules/@pi-plugins/fast-mode/README.md +7 -1
  89. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  90. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +7 -1
  91. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  92. package/node_modules/@pi-plugins/fast-mode/package.json +5 -5
  93. package/node_modules/pi-antigravity/README.md +3 -0
  94. package/node_modules/pi-antigravity/package.json +8 -8
  95. package/node_modules/pi-antigravity/src/auth/oauth.ts +6 -3
  96. package/node_modules/pi-antigravity/src/index.ts +114 -110
  97. package/node_modules/pi-antigravity/src/stream/stream.ts +1 -1
  98. package/node_modules/pi-antigravity/src/utils/util.ts +18 -1
  99. package/node_modules/pi-multi-account/CHANGELOG.md +20 -0
  100. package/node_modules/pi-multi-account/README.md +46 -8
  101. package/node_modules/pi-multi-account/config-file-transaction.ts +42 -0
  102. package/node_modules/pi-multi-account/index.ts +255 -269
  103. package/node_modules/pi-multi-account/model-pins.ts +36 -0
  104. package/node_modules/pi-multi-account/package.json +9 -7
  105. package/node_modules/pi-multi-account/slot-proxy-auth.ts +12 -2
  106. package/node_modules/pi-multi-account/slot-proxy.ts +27 -5
  107. package/node_modules/pi-typesafe/README.md +1 -1
  108. package/node_modules/pi-typesafe/dist/backends.d.ts +15 -5
  109. package/node_modules/pi-typesafe/dist/backends.js +18 -0
  110. package/node_modules/pi-typesafe/dist/client.d.ts +4 -3
  111. package/node_modules/pi-typesafe/dist/client.js +22 -7
  112. package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
  113. package/node_modules/pi-typesafe/dist/index.js +1 -1
  114. package/node_modules/pi-typesafe/dist/usage.d.ts +14 -4
  115. package/node_modules/pi-typesafe/dist/usage.js +147 -42
  116. package/node_modules/pi-typesafe/package.json +1 -1
  117. package/node_modules/pi-web-access/CHANGELOG.md +65 -0
  118. package/node_modules/pi-web-access/README.md +63 -14
  119. package/node_modules/pi-web-access/brave-rate-limit.ts +176 -0
  120. package/node_modules/pi-web-access/brave.ts +28 -11
  121. package/node_modules/pi-web-access/curator-page.ts +5 -1
  122. package/node_modules/pi-web-access/curator-server.ts +2 -0
  123. package/node_modules/pi-web-access/declared-web-links.ts +2 -2
  124. package/node_modules/pi-web-access/degoog.ts +323 -0
  125. package/node_modules/pi-web-access/dist/index.js +3647 -2740
  126. package/node_modules/pi-web-access/dist/mcp-cli.js +27443 -0
  127. package/node_modules/pi-web-access/exa.ts +5 -1
  128. package/node_modules/pi-web-access/extract.ts +41 -3
  129. package/node_modules/pi-web-access/firecrawl.ts +35 -4
  130. package/node_modules/pi-web-access/gemini-search.ts +36 -16
  131. package/node_modules/pi-web-access/gemini-web.ts +14 -9
  132. package/node_modules/pi-web-access/index.ts +164 -1207
  133. package/node_modules/pi-web-access/keenable.ts +221 -0
  134. package/node_modules/pi-web-access/mcp-cli.ts +40 -0
  135. package/node_modules/pi-web-access/mcp-server.ts +81 -0
  136. package/node_modules/pi-web-access/mcp-tool-definitions.ts +117 -0
  137. package/node_modules/pi-web-access/openai-search.ts +58 -11
  138. package/node_modules/pi-web-access/package.json +23 -5
  139. package/node_modules/pi-web-access/perplexity.ts +64 -56
  140. package/node_modules/pi-web-access/summary-review.ts +8 -2
  141. package/node_modules/pi-web-access/tool-arguments.ts +20 -0
  142. package/node_modules/pi-web-access/video-extract.ts +1 -1
  143. package/node_modules/pi-web-access/web-tool-contract.ts +86 -0
  144. package/node_modules/pi-web-access/web-tool-core.ts +1502 -0
  145. package/node_modules/pi-web-access/youtube-extract.ts +2 -5
  146. package/node_modules/{@herbertgao/resume-from → resume-from}/README.md +16 -12
  147. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -5
  148. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.js +2 -3
  149. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.d.ts +2 -2
  150. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.d.ts +3 -0
  151. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.js +27 -15
  152. package/node_modules/{@herbertgao/resume-from/dist/adapters/codex → resume-from/dist/adapters/claude-code}/redaction.js +16 -3
  153. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.d.ts +2 -4
  154. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.js +1 -1
  155. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.d.ts +2 -4
  156. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.js +1 -2
  157. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/read.d.ts +16 -0
  158. package/node_modules/resume-from/dist/adapters/codex/read.js +723 -0
  159. package/node_modules/{@herbertgao/resume-from/dist/adapters/pi → resume-from/dist/adapters/codex}/redaction.js +16 -3
  160. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.d.ts +44 -4
  161. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.js +88 -4
  162. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.d.ts +2 -2
  163. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.js +2 -2
  164. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.d.ts +5 -1
  165. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.js +10 -6
  166. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.d.ts +2 -2
  167. package/node_modules/{@herbertgao/resume-from/dist/adapters/claude-code → resume-from/dist/adapters/pi}/redaction.js +16 -3
  168. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.d.ts +2 -4
  169. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.js +2 -2
  170. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.d.ts +1 -1
  171. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.js +4 -4
  172. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.js +2 -2
  173. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.d.ts +2 -2
  174. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.js +31 -8
  175. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.d.ts +1 -1
  176. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.js +1 -2
  177. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.d.ts +4 -1
  178. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.js +2 -2
  179. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.d.ts +8 -6
  180. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.d.ts +10 -5
  181. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/finder.d.ts +2 -1
  182. package/node_modules/resume-from/dist/import/discovery/finder.js +269 -0
  183. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.d.ts +3 -3
  184. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.js +3 -3
  185. package/node_modules/resume-from/dist/import/pipeline.d.ts +28 -0
  186. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/pipeline.js +31 -11
  187. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.d.ts +2 -2
  188. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.js +9 -5
  189. package/node_modules/resume-from/dist/import/preview/warnings.d.ts +14 -0
  190. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/warnings.js +26 -20
  191. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.js +12 -2
  192. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.d.ts +9 -3
  193. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.d.ts +4 -4
  194. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.js +7 -4
  195. package/node_modules/resume-from/dist/platform/repo/reader.d.ts +3 -0
  196. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/reader.js +60 -20
  197. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.d.ts +8 -1
  198. package/node_modules/{@herbertgao/resume-from → resume-from}/package.json +19 -32
  199. package/node_modules/{@herbertgao/resume-from → resume-from}/shims/pi/extensions/resume-from.js +2 -2
  200. package/package.json +21 -21
  201. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +0 -21
  202. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +0 -62
  203. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
  204. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +0 -115
  205. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +0 -27
  206. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +0 -27
  207. package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
  208. package/node_modules/@dietrichgebert/ponytail/assets/retriever-icon.png +0 -0
  209. package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-dark.svg +0 -4
  210. package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-light.svg +0 -4
  211. package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
  212. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
  213. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
  214. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
  215. package/node_modules/@herbertgao/resume-from/dist/adapters/codex/read.js +0 -270
  216. package/node_modules/@herbertgao/resume-from/dist/import/discovery/finder.js +0 -129
  217. package/node_modules/@herbertgao/resume-from/dist/import/pipeline.d.ts +0 -17
  218. package/node_modules/@herbertgao/resume-from/dist/import/preview/warnings.d.ts +0 -11
  219. package/node_modules/@herbertgao/resume-from/dist/platform/repo/reader.d.ts +0 -8
  220. /package/node_modules/{@herbertgao/resume-from → resume-from}/LICENSE +0 -0
  221. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.js +0 -0
  222. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  223. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.js +0 -0
  224. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  225. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.js +0 -0
  226. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  227. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.js +0 -0
  228. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  229. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.js +0 -0
  230. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  231. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  232. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.js +0 -0
  233. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.js +0 -0
  234. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.d.ts +0 -0
  235. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  236. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.js +0 -0
  237. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  238. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  239. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.js +0 -0
  240. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.js +0 -0
  241. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  242. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.js +0 -0
  243. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.d.ts +0 -0
  244. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.js +0 -0
  245. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.d.ts +0 -0
  246. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.js +0 -0
  247. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  248. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.js +0 -0
  249. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  250. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  251. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.js +0 -0
  252. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.d.ts +0 -0
  253. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.js +0 -0
  254. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.d.ts +0 -0
  255. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.js +0 -0
  256. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.d.ts +0 -0
  257. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.js +0 -0
  258. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.d.ts +0 -0
  259. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.js +0 -0
  260. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.d.ts +0 -0
  261. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.js +0 -0
  262. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.d.ts +0 -0
  263. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.js +0 -0
  264. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.d.ts +0 -0
  265. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.js +0 -0
  266. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.d.ts +0 -0
  267. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.js +0 -0
  268. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.d.ts +0 -0
  269. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.js +0 -0
  270. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.d.ts +0 -0
  271. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.js +0 -0
  272. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  273. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  274. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.js +0 -0
  275. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  276. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.js +0 -0
  277. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  278. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.js +0 -0
  279. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  280. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.js +0 -0
  281. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  282. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.js +0 -0
  283. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  284. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.js +0 -0
  285. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.d.ts +0 -0
  286. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.js +0 -0
  287. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.d.ts +0 -0
  288. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.js +0 -0
  289. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.js +0 -0
  290. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.js +0 -0
  291. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.d.ts +0 -0
  292. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.js +0 -0
  293. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.d.ts +0 -0
  294. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.js +0 -0
  295. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.d.ts +0 -0
  296. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.js +0 -0
  297. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  298. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.js +0 -0
  299. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.d.ts +0 -0
  300. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.js +0 -0
  301. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.d.ts +0 -0
  302. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.js +0 -0
  303. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.js +0 -0
  304. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.d.ts +0 -0
  305. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.js +0 -0
  306. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.d.ts +0 -0
  307. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.js +0 -0
  308. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.d.ts +0 -0
  309. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.js +0 -0
  310. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.d.ts +0 -0
  311. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.d.ts +0 -0
  312. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.js +0 -0
  313. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.d.ts +0 -0
  314. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.js +0 -0
  315. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.d.ts +0 -0
  316. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.js +0 -0
  317. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.d.ts +0 -0
  318. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.js +0 -0
  319. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.d.ts +0 -0
  320. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.js +0 -0
  321. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.d.ts +0 -0
  322. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.js +0 -0
  323. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.d.ts +0 -0
  324. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.js +0 -0
  325. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.d.ts +0 -0
  326. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.d.ts +0 -0
  327. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.js +0 -0
  328. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.d.ts +0 -0
  329. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.js +0 -0
  330. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.d.ts +0 -0
  331. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.js +0 -0
  332. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.d.ts +0 -0
  333. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.js +0 -0
  334. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.d.ts +0 -0
  335. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.js +0 -0
  336. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.d.ts +0 -0
  337. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.js +0 -0
  338. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.d.ts +0 -0
  339. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.js +0 -0
  340. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.d.ts +0 -0
  341. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.js +0 -0
  342. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.js +0 -0
  343. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.d.ts +0 -0
  344. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.js +0 -0
  345. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.d.ts +0 -0
  346. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.js +0 -0
  347. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  348. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.js +0 -0
  349. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.d.ts +0 -0
  350. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.js +0 -0
  351. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  352. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.js +0 -0
  353. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  354. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.js +0 -0
  355. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.d.ts +0 -0
  356. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.js +0 -0
  357. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.js +0 -0
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import type { AgentMessage, AgentToolResult, ThinkingLevel } from "@earendil-works/pi-agent-core";
6
6
  import {
7
- buildSessionContext,
8
7
  estimateTokens,
9
8
  findCutPoint,
10
9
  sessionEntryToContextMessages,
@@ -20,11 +19,13 @@ import {
20
19
  type CompactionDecision,
21
20
  } from "./economics.ts";
22
21
  import { analyzePlanTransition, formatPlanSnapshot, parsePlanSteps } from "./plan.ts";
22
+ import { projectedEntryTokens } from "./projection.ts";
23
23
  import {
24
24
  appendOnlineState,
25
25
  initialOnlineState,
26
26
  recordBoundary,
27
27
  recordCompaction,
28
+ recordCompletedPlanHandoff,
28
29
  recordCorrection,
29
30
  recordProviderRequest,
30
31
  restoreOnlineState,
@@ -39,7 +40,17 @@ export const BOUNDARY_COMPACTION_INSTRUCTIONS =
39
40
  "Preserve completed work, verification results, important decisions, and remaining work.";
40
41
  export const POST_COMPACTION_PLAN_REMINDER =
41
42
  "Online context compaction finished. The parent task is still active. " +
42
- "Before continuing work, call update_plan with a fresh plan for the remaining work.";
43
+ "Continue the remaining work from the current plan. Preserve existing step IDs when updating progress.";
44
+ export const SKIPPED_COMPACTION_REMINDER =
45
+ "Online context compaction was skipped. The existing context is still available. " +
46
+ "Continue the remaining work from the current plan.";
47
+ // Pi rejects these before committing a replacement summary, so the current
48
+ // context is still usable. Unknown errors and user cancellation remain distinct.
49
+ const RECOVERABLE_COMPACTION_ERRORS = new Set([
50
+ "Nothing to compact (session too small)",
51
+ "Already compacted",
52
+ "Summarization failed: generation hit the token cap and the summary is incomplete",
53
+ ]);
43
54
 
44
55
  export type OnlineContextCompactOptions = {
45
56
  readonly cacheWriteReadRatio?: number | null;
@@ -49,6 +60,11 @@ export type OnlineContextCompactOptions = {
49
60
  type PendingBoundary = { readonly toolCallId: string };
50
61
  type SelectedCompaction = { readonly decision: CompactionDecision };
51
62
  type CacheDebt = { readonly debtTokens: number; readonly repaymentTokens: number };
63
+ type PendingContinuation = { readonly promise: Promise<void>; readonly resolve: () => void };
64
+
65
+ function releaseParentContinuation(continuation: PendingContinuation | undefined): void {
66
+ if (continuation) setTimeout(continuation.resolve, 0);
67
+ }
52
68
 
53
69
  const SUBAGENTS_MANAGER_KEY = Symbol.for("pi-subagents:manager");
54
70
 
@@ -100,13 +116,24 @@ function progressSummary(input: PlanUpdateInput, completedStepId: string): Progr
100
116
  };
101
117
  }
102
118
 
103
- function compactionMessageCount(entries: readonly SessionEntry[], startIndex: number, endIndex: number): number {
104
- let count = 0;
119
+ function compactionTokenEstimate(
120
+ entries: readonly SessionEntry[],
121
+ startIndex: number,
122
+ endIndex: number,
123
+ projected?: ReadonlyMap<string, number>,
124
+ ): number {
125
+ let tokens = 0;
105
126
  for (let index = startIndex; index < endIndex; index++) {
106
127
  const entry = entries[index];
107
- if (entry && entry.type !== "compaction" && sessionEntryToContextMessages(entry).length > 0) count++;
128
+ if (!entry || entry.type === "compaction") continue;
129
+ if (projected) {
130
+ tokens += projected.get(entry.id) ?? 0;
131
+ continue;
132
+ }
133
+ const message = sessionEntryToContextMessages(entry)[0];
134
+ if (message) tokens += estimateTokens(message);
108
135
  }
109
- return count;
136
+ return tokens;
110
137
  }
111
138
 
112
139
  function branchAfterAbort(entries: readonly SessionEntry[]): SessionEntry[] {
@@ -140,25 +167,33 @@ function branchAfterAbort(entries: readonly SessionEntry[]): SessionEntry[] {
140
167
  ];
141
168
  }
142
169
 
143
- function nativeCompactionFeasible(entries: readonly SessionEntry[], keepRecentTokens: number): boolean {
170
+ export function estimateNativeCompactionTokens(
171
+ entries: readonly SessionEntry[],
172
+ keepRecentTokens: number,
173
+ projectedMessages?: readonly AgentMessage[],
174
+ ): number {
144
175
  const path = branchAfterAbort(entries);
176
+ const projected = projectedMessages === undefined ? undefined : projectedEntryTokens(entries, projectedMessages);
145
177
  let startIndex = 0;
178
+ let previousSummaryTokens = 0;
146
179
  for (let index = path.length - 1; index >= 0; index--) {
147
180
  const entry = path[index];
148
181
  if (entry?.type !== "compaction") continue;
149
182
  const keptIndex = path.findIndex((item) => item.id === entry.firstKeptEntryId);
150
183
  startIndex = keptIndex >= 0 ? keptIndex : index + 1;
184
+ const previousSummary = sessionEntryToContextMessages(entry)[0];
185
+ previousSummaryTokens = projected
186
+ ? projected.get(entry.id) ?? 0
187
+ : previousSummary ? estimateTokens(previousSummary) : 0;
151
188
  break;
152
189
  }
153
190
 
191
+ // Keep Pi's native cut on session entries; price only the corresponding
192
+ // messages that the provider actually saw after context projection.
154
193
  const cut = findCutPoint(path, startIndex, path.length, keepRecentTokens);
155
- const historyEnd = cut.isSplitTurn ? cut.turnStartIndex : cut.firstKeptEntryIndex;
156
- const historyMessages = historyEnd > startIndex ? compactionMessageCount(path, startIndex, historyEnd) : 0;
157
- const prefixMessages =
158
- cut.isSplitTurn && cut.turnStartIndex >= 0
159
- ? compactionMessageCount(path, cut.turnStartIndex, cut.firstKeptEntryIndex)
160
- : 0;
161
- return historyMessages > 0 || prefixMessages > 0;
194
+ const firstKept = cut.firstKeptEntryIndex;
195
+ if (compactionTokenEstimate(path, startIndex, firstKept) === 0) return 0;
196
+ return previousSummaryTokens + compactionTokenEstimate(path, startIndex, firstKept, projected);
162
197
  }
163
198
 
164
199
  function validPositiveInteger(value: unknown): value is number {
@@ -209,18 +244,26 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
209
244
  let activeDebt: CacheDebt | undefined;
210
245
  let compactionInFlight = false;
211
246
  let compactionThinkingOverride: CompactionThinkingOverride | undefined;
247
+ let nextContinuation: PendingContinuation | undefined;
248
+ let compactionRefused = false;
249
+
250
+ const releaseContinuation = (): void => {
251
+ const continuation = nextContinuation;
252
+ nextContinuation = undefined;
253
+ continuation?.resolve();
254
+ };
212
255
 
213
256
  const restore = (context: ExtensionContext): void => {
257
+ releaseContinuation();
214
258
  state = restoreOnlineState(context.sessionManager.getBranch());
215
259
  restored = true;
216
- observedMessages = buildSessionContext(
217
- context.sessionManager.getEntries(),
218
- context.sessionManager.getLeafId(),
219
- ).messages;
260
+ // Restoring raw history is not evidence of a provider-visible projection.
261
+ observedMessages = [];
220
262
  pendingBoundary = undefined;
221
263
  selected = undefined;
222
264
  activeDebt = undefined;
223
265
  compactionInFlight = false;
266
+ compactionRefused = false;
224
267
  };
225
268
  const ensureRestored = (context: ExtensionContext): void => {
226
269
  if (!restored) restore(context);
@@ -245,7 +288,7 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
245
288
  if (completedIds.length > 0) {
246
289
  state = recordBoundary(state, steps, progressSummary(input, completedIds[0] ?? ""));
247
290
  if (!pendingBoundary) pendingBoundary = { toolCallId: input.toolCallId };
248
- } else if (JSON.stringify(state.plan) !== JSON.stringify(steps)) {
291
+ } else {
249
292
  state = { ...state, plan: [...steps] };
250
293
  }
251
294
  save();
@@ -279,10 +322,16 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
279
322
  });
280
323
 
281
324
  pi.on("input", (event, context) => {
325
+ compactionRefused = false;
326
+ ensureRestored(context);
282
327
  if (event.streamingBehavior !== "steer" && !event.text.startsWith("CORRECTION:")) {
328
+ const next = recordCompletedPlanHandoff(state);
329
+ if (next !== state) {
330
+ state = next;
331
+ save();
332
+ }
283
333
  return { action: "continue" as const };
284
334
  }
285
- ensureRestored(context);
286
335
  pendingBoundary = undefined;
287
336
  selected = undefined;
288
337
  activeDebt = undefined;
@@ -292,9 +341,12 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
292
341
  });
293
342
 
294
343
  pi.on("turn_end", (event, context) => {
344
+ // Plan chatter cannot make a rejected compact feasible. Require actual
345
+ // tool work or new user input before attempting another boundary.
346
+ if (event.toolResults.some((item) => item.toolName !== "update_plan" && !item.isError)) compactionRefused = false;
295
347
  const boundary = pendingBoundary;
296
348
  pendingBoundary = undefined;
297
- if (!boundary || selected || hasRunningSubagents()) return;
349
+ if (!boundary || selected || compactionRefused || hasRunningSubagents()) return;
298
350
  const toolResult = event.toolResults.find((item) => item.toolCallId === boundary.toolCallId);
299
351
  if (
300
352
  event.message.role !== "assistant" ||
@@ -309,8 +361,11 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
309
361
 
310
362
  const usage = context.getContextUsage();
311
363
  const writeTokens = contextTokens(context);
312
- const fixedTokens = tokenEstimate(context.getSystemPrompt());
313
- const archiveTokens = Math.max(0, writeTokens - fixedTokens - keepRecentTokens);
364
+ const archiveTokens = estimateNativeCompactionTokens(
365
+ context.sessionManager.getBranch(),
366
+ keepRecentTokens,
367
+ observedMessages,
368
+ );
314
369
  const contextWindowTokens = validPositiveInteger(usage?.contextWindow)
315
370
  ? usage.contextWindow
316
371
  : validPositiveInteger(context.model?.contextWindow)
@@ -330,13 +385,17 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
330
385
  averageContextTokenIncrement,
331
386
  contextWindowTokens,
332
387
  priorCompactionCount: state.nativeCompactionCount,
388
+ requestsSinceLastCompaction:
389
+ state.lastCompactionRequestCount === null
390
+ ? null
391
+ : state.requestCount - state.lastCompactionRequestCount,
333
392
  carriedDebtTokens: state.cacheDebtTokens,
334
393
  cacheDebtRepaymentTokens: state.cacheDebtRepaymentTokens,
335
394
  cacheWriteReadRatio,
336
395
  economics: DEFAULT_COMPACTION_ECONOMICS,
337
396
  });
338
397
  const decision: CompactionDecision =
339
- priced.compact && !nativeCompactionFeasible(context.sessionManager.getBranch(), keepRecentTokens)
398
+ priced.compact && archiveTokens === 0
340
399
  ? { ...priced, compact: false, reason: "native_not_compactable" }
341
400
  : priced;
342
401
  if (!decision.compact) return;
@@ -346,16 +405,24 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
346
405
  });
347
406
 
348
407
  pi.on("agent_settled", async (_event, context) => {
408
+ // Older hosts start a continuation synchronously; newer hosts defer it
409
+ // until settled handlers return. Preserve both print-mode barriers.
410
+ const parentContinuation = nextContinuation;
411
+ nextContinuation = undefined;
349
412
  const pending = selected;
350
413
  selected = undefined;
351
414
  if (!context.isIdle()) {
352
415
  selected = pending;
416
+ nextContinuation = parentContinuation;
417
+ return;
418
+ }
419
+ if (!pending || hasRunningSubagents()) {
420
+ releaseParentContinuation(parentContinuation);
353
421
  return;
354
422
  }
355
- if (!pending || hasRunningSubagents()) return;
356
423
 
357
424
  activeDebt = {
358
- debtTokens: pending.decision.writeTokens * (pending.decision.incrementalCacheCostRatio ?? 0),
425
+ debtTokens: pending.decision.postCompactionTokens * (pending.decision.incrementalCacheCostRatio ?? 0),
359
426
  repaymentTokens: Math.max(0, pending.decision.archiveTokens - pending.decision.memoTokens),
360
427
  };
361
428
  let compacted = false;
@@ -391,6 +458,7 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
391
458
  }
392
459
  },
393
460
  onError: (error) => {
461
+ activeDebt = undefined;
394
462
  compactionError = error;
395
463
  finish();
396
464
  },
@@ -399,36 +467,66 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
399
467
  restoreCompactionThinking(pi, compactionThinkingOverride);
400
468
  compactionThinkingOverride = undefined;
401
469
  compactionInFlight = false;
470
+ const recoverableError = compactionError !== undefined && RECOVERABLE_COMPACTION_ERRORS.has(compactionError.message);
402
471
  if (
403
472
  compactionError &&
473
+ !recoverableError &&
404
474
  compactionError.name !== "AbortError" &&
405
475
  compactionError.message !== "Compaction cancelled"
406
476
  ) {
407
477
  throw compactionError;
408
478
  }
409
479
 
410
- if (compacted) {
411
- // Pi >=0.87 defers this turn until agent_settled handlers finish and
412
- // awaits it before prompt() resolves, so print/JSON mode stays alive.
413
- pi.sendMessage(
414
- {
415
- customType: "sol-pi-online-context-compact",
416
- content: POST_COMPACTION_PLAN_REMINDER,
417
- display: false,
418
- },
419
- { triggerTurn: true },
420
- );
480
+ if (recoverableError) {
481
+ compactionRefused = true;
482
+ pi.appendEntry("sol-pi-online-context-compact-skipped", { reason: compactionError!.message });
483
+ if (context.mode === "tui") context.ui.notify(`Online compaction skipped: ${compactionError!.message}`, "warning");
484
+ }
485
+ if (compacted || recoverableError) {
486
+ let resolveContinuation!: () => void;
487
+ const continuation: PendingContinuation = {
488
+ promise: new Promise<void>((resolve) => {
489
+ resolveContinuation = resolve;
490
+ }),
491
+ resolve: () => resolveContinuation(),
492
+ };
493
+ nextContinuation = continuation;
494
+ try {
495
+ pi.sendMessage(
496
+ {
497
+ customType: "sol-pi-online-context-compact",
498
+ content: compacted ? POST_COMPACTION_PLAN_REMINDER : SKIPPED_COMPACTION_REMINDER,
499
+ display: false,
500
+ },
501
+ { triggerTurn: true },
502
+ );
503
+ } catch (error) {
504
+ if (nextContinuation === continuation) nextContinuation = undefined;
505
+ continuation.resolve();
506
+ throw error;
507
+ }
508
+ if (context.isIdle() && nextContinuation === continuation) {
509
+ // Newer Pi hosts defer runs until settled handlers return. Hand
510
+ // control back to that host instead of waiting on a deferred run.
511
+ nextContinuation = undefined;
512
+ continuation.resolve();
513
+ } else {
514
+ // Pi 0.85.1 starts synchronously; keep its print-mode barrier.
515
+ await continuation.promise;
516
+ }
421
517
  }
422
518
  } finally {
423
519
  restoreCompactionThinking(pi, compactionThinkingOverride);
424
520
  compactionThinkingOverride = undefined;
425
521
  compactionInFlight = false;
426
522
  activeDebt = undefined;
523
+ releaseParentContinuation(parentContinuation);
427
524
  }
428
525
  });
429
526
 
430
527
  pi.on("session_compact", (event, context) => {
431
528
  ensureRestored(context);
529
+ compactionRefused = false;
432
530
  state = recordCompaction(
433
531
  state,
434
532
  event.fromExtension || !activeDebt ? { debtTokens: 0, repaymentTokens: 0 } : activeDebt,
@@ -437,13 +535,11 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
437
535
  pendingBoundary = undefined;
438
536
  selected = undefined;
439
537
  activeDebt = undefined;
440
- observedMessages = buildSessionContext(
441
- context.sessionManager.getEntries(),
442
- context.sessionManager.getLeafId(),
443
- ).messages;
538
+ observedMessages = [];
444
539
  });
445
540
 
446
541
  pi.on("session_shutdown", () => {
542
+ releaseContinuation();
447
543
  restoreCompactionThinking(pi, compactionThinkingOverride);
448
544
  compactionThinkingOverride = undefined;
449
545
  pendingBoundary = undefined;
@@ -19,6 +19,7 @@ export {
19
19
  createOnlineContextCompactExtension,
20
20
  DEFAULT_KEEP_RECENT_TOKENS,
21
21
  DEFAULT_NATIVE_SUMMARY_TOKEN_ESTIMATE,
22
+ estimateNativeCompactionTokens,
22
23
  POST_COMPACTION_PLAN_REMINDER,
23
24
  type OnlineContextCompactOptions,
24
25
  resolveKeepRecentTokens,
@@ -59,7 +59,8 @@ export function analyzePlanTransition(previous: readonly PlanStep[], next: reado
59
59
 
60
60
  for (const step of next) {
61
61
  const prior = previousById.get(step.id);
62
- if ((!prior || prior.status !== "completed") && step.status === "completed") completedSteps.push(step);
62
+ // A newly introduced completed step establishes history, not a status transition.
63
+ if (prior && prior.status !== "completed" && step.status === "completed") completedSteps.push(step);
63
64
  if (prior && prior.goal !== step.goal) {
64
65
  advice.push(`Plan step ${JSON.stringify(step.id)} changed goal; reuse an id only for the same goal.`);
65
66
  }
@@ -0,0 +1,58 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
6
+ import { estimateTokens, sessionEntryToContextMessages, type SessionEntry } from "@earendil-works/pi-coding-agent";
7
+
8
+ /** ObservationPack changes tool-result content while preserving its call identity. */
9
+ function messageKey(message: AgentMessage): string {
10
+ return message.role === "toolResult"
11
+ ? `tool:${JSON.stringify([message.toolCallId, message.toolName, message.timestamp])}`
12
+ : JSON.stringify(message);
13
+ }
14
+
15
+ /** Map the last observed projection to source entries, without rerunning context hooks. */
16
+ export function projectedEntryTokens(
17
+ entries: readonly SessionEntry[],
18
+ projected: readonly AgentMessage[],
19
+ ): ReadonlyMap<string, number> {
20
+ const lastCompaction = entries.findLastIndex((entry) => entry.type === "compaction");
21
+ let active = entries;
22
+ if (lastCompaction >= 0) {
23
+ const compaction = entries[lastCompaction];
24
+ if (compaction?.type === "compaction") {
25
+ const firstKept = entries.findIndex((entry) => entry.id === compaction.firstKeptEntryId);
26
+ active = [compaction, ...(firstKept >= 0 ? entries.slice(firstKept, lastCompaction) : []), ...entries.slice(lastCompaction + 1)];
27
+ }
28
+ }
29
+ const sources = new Map<string, string[]>();
30
+ for (const entry of active) {
31
+ if (entry.type === "compaction" && entry !== entries[lastCompaction]) continue;
32
+ for (const message of sessionEntryToContextMessages(entry)) {
33
+ const key = messageKey(message);
34
+ const ids = sources.get(key) ?? [];
35
+ ids.push(entry.id);
36
+ sources.set(key, ids);
37
+ }
38
+ }
39
+ const visible = new Map<string, number[]>();
40
+ for (const message of projected) {
41
+ const key = messageKey(message);
42
+ const sizes = visible.get(key) ?? [];
43
+ sizes.push(estimateTokens(message));
44
+ visible.set(key, sizes);
45
+ }
46
+ const tokens = new Map<string, number>();
47
+ for (const [key, ids] of sources) {
48
+ const sizes = visible.get(key);
49
+ // Dropped, rewritten, newly appended, or ambiguously duplicated messages
50
+ // provide no proven savings. Never fall back to their raw content size.
51
+ if (!sizes || sizes.length !== ids.length || (key.startsWith("tool:") && ids.length > 1)) continue;
52
+ for (let index = 0; index < ids.length; index++) {
53
+ const id = ids[index]!;
54
+ tokens.set(id, (tokens.get(id) ?? 0) + sizes[index]!);
55
+ }
56
+ }
57
+ return tokens;
58
+ }
@@ -22,6 +22,8 @@ export type OnlineState = {
22
22
  readonly plan: readonly PlanStep[];
23
23
  readonly pendingProgress: readonly ProgressSummary[];
24
24
  readonly requestCount: number;
25
+ /** requestCount when the last compaction ran; null before the first compaction. */
26
+ readonly lastCompactionRequestCount: number | null;
25
27
  readonly lastBoundaryRequestCount: number;
26
28
  readonly completedBoundaryRequestCounts: readonly number[];
27
29
  readonly lastContextTokens: number | null;
@@ -39,6 +41,7 @@ export function initialOnlineState(): OnlineState {
39
41
  plan: [],
40
42
  pendingProgress: [],
41
43
  requestCount: 0,
44
+ lastCompactionRequestCount: null,
42
45
  lastBoundaryRequestCount: 0,
43
46
  completedBoundaryRequestCounts: [],
44
47
  lastContextTokens: null,
@@ -101,6 +104,8 @@ function parseOnlineState(value: unknown): OnlineState | undefined {
101
104
  !completedBoundaryRequestCounts ||
102
105
  !completedBoundaryRequestCounts.every(nonNegativeInteger) ||
103
106
  !nonNegativeInteger(record.epoch) ||
107
+ (typeof record.lastCompactionRequestCount !== "undefined" &&
108
+ !(record.lastCompactionRequestCount === null || nonNegativeInteger(record.lastCompactionRequestCount))) ||
104
109
  !nonNegativeInteger(record.requestCount) ||
105
110
  !nonNegativeInteger(record.lastBoundaryRequestCount) ||
106
111
  record.lastBoundaryRequestCount > record.requestCount ||
@@ -119,6 +124,7 @@ function parseOnlineState(value: unknown): OnlineState | undefined {
119
124
  plan,
120
125
  pendingProgress: pendingProgress as readonly ProgressSummary[],
121
126
  requestCount: record.requestCount,
127
+ lastCompactionRequestCount: record.lastCompactionRequestCount ?? null,
122
128
  lastBoundaryRequestCount: record.lastBoundaryRequestCount,
123
129
  completedBoundaryRequestCounts: completedBoundaryRequestCounts as readonly number[],
124
130
  lastContextTokens: record.lastContextTokens,
@@ -180,16 +186,16 @@ export function recordCompaction(
180
186
  return {
181
187
  ...state,
182
188
  epoch: state.epoch + 1,
183
- // Keep the plan so the post-compaction rebuild does not reclassify
184
- // already-completed steps as a new boundary.
189
+ // Preserve the plan and its progress samples. Compaction changes the
190
+ // context representation, not which steps have completed.
185
191
  plan: [...state.plan],
192
+ lastCompactionRequestCount: state.requestCount,
186
193
  pendingProgress: [],
194
+ // Do not compare context sizes across the replacement summary.
187
195
  lastContextTokens: null,
188
- positiveContextDeltaTotal: 0,
189
- positiveContextDeltaCount: 0,
190
196
  nativeCompactionCount: state.nativeCompactionCount + 1,
191
- cacheDebtTokens: Math.max(0, debt.debtTokens),
192
- cacheDebtRepaymentTokens: Math.max(0, debt.repaymentTokens),
197
+ cacheDebtTokens: state.cacheDebtTokens + Math.max(0, debt.debtTokens),
198
+ cacheDebtRepaymentTokens: state.cacheDebtRepaymentTokens + Math.max(0, debt.repaymentTokens),
193
199
  };
194
200
  }
195
201
 
@@ -208,3 +214,19 @@ export function recordCorrection(state: OnlineState): OnlineState {
208
214
  cacheDebtRepaymentTokens: 0,
209
215
  };
210
216
  }
217
+
218
+ /** A new user task must not inherit the completed task's request horizon. */
219
+ export function recordCompletedPlanHandoff(state: OnlineState): OnlineState {
220
+ if (state.plan.length === 0 || state.plan.some((step) => step.status !== "completed")) return state;
221
+ return {
222
+ ...state,
223
+ epoch: state.epoch + 1,
224
+ plan: [],
225
+ pendingProgress: [],
226
+ lastBoundaryRequestCount: state.requestCount,
227
+ completedBoundaryRequestCounts: [],
228
+ lastContextTokens: null,
229
+ positiveContextDeltaTotal: 0,
230
+ positiveContextDeltaCount: 0,
231
+ };
232
+ }
@@ -50,10 +50,11 @@ export function registerOnlineTools(pi: ExtensionAPI, handlers: OnlineToolHandle
50
50
  name: "update_plan",
51
51
  label: "Update plan",
52
52
  description:
53
- "Replace the complete working plan. A newly completed step becomes a safe point where SoL-Pi may compact context if doing so is economical.",
53
+ "Replace the complete working plan. Completing a previously registered unfinished step becomes a safe point where SoL-Pi may compact context if doing so is economical. Newly introduced completed steps are recorded as history.",
54
54
  promptSnippet: "Keep the working plan current",
55
55
  promptGuidelines: [
56
56
  "Send the complete plan on every update_plan call.",
57
+ "Preserve step IDs and register unfinished steps before reporting their completion.",
57
58
  "Keep at most one step in_progress and mark finished steps completed.",
58
59
  "When completing a step, include concise progress evidence when available.",
59
60
  ],
@@ -3,15 +3,28 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
+ import { mkdtempSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
6
8
  import { join } from "node:path";
7
9
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
8
10
 
11
+ const temporaryRoots = new Map<string, string>();
12
+
9
13
  export function runtimeRoot(ctx: ExtensionContext): string {
10
14
  const sessionDir = ctx.sessionManager.getSessionDir();
11
- if (!sessionDir) throw new Error("SoL-Pi requires a persistent Pi session directory");
12
15
  const sessionId = ctx.sessionManager.getSessionId();
13
16
  if (!/^[a-z0-9][a-z0-9._-]*$/iu.test(sessionId)) {
14
17
  throw new Error("SoL-Pi requires a safe Pi session id");
15
18
  }
16
- return join(sessionDir, "sol-pi", sessionId);
19
+ if (sessionDir) return join(sessionDir, "sol-pi", sessionId);
20
+
21
+ // --no-session and SDK in-memory sessions still need files for exact recall.
22
+ // Share the root across contexts and mechanisms, without sharing a predictable
23
+ // directory with other processes. Keep files after shutdown for parent workers.
24
+ let root = temporaryRoots.get(sessionId);
25
+ if (!root) {
26
+ root = mkdtempSync(join(tmpdir(), `sol-pi-${sessionId}-`));
27
+ temporaryRoots.set(sessionId, root);
28
+ }
29
+ return root;
17
30
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juicesharp/rpiv-ask-user-question",
3
- "version": "2.11.0",
3
+ "version": "2.12.0",
4
4
  "description": "Pi extension. A structured questionnaire the model can put to you when it would otherwise guess, with typed options instead of free-form replies.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -96,6 +96,6 @@
96
96
  }
97
97
  },
98
98
  "dependencies": {
99
- "@juicesharp/rpiv-config": "^2.11.0"
99
+ "@juicesharp/rpiv-config": "^2.12.0"
100
100
  }
101
101
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-caffeinate",
3
- "version": "0.49.8",
3
+ "version": "0.49.9",
4
4
  "description": "Pi extension that keeps the computer awake while the agent is running.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -35,8 +35,8 @@
35
35
  "@earendil-works/pi-coding-agent": "*"
36
36
  },
37
37
  "devDependencies": {
38
- "@earendil-works/pi-coding-agent": "0.86.0",
39
- "@types/node": "26.6.2",
38
+ "@earendil-works/pi-coding-agent": "1.0.0",
39
+ "@types/node": "26.6.4",
40
40
  "esbuild": "0.28.2",
41
41
  "typescript": "7.0.2"
42
42
  },
@@ -47,6 +47,6 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@narumitw/pi-tui-kit": "^0.59.0",
50
- "dbus-native": "^0.15.2"
50
+ "dbus-native": "^0.16.0"
51
51
  }
52
52
  }
@@ -59,12 +59,18 @@ Optionally create `<agent-dir>/extensions/fast-mode.json`, typically
59
59
  "openai/gpt-5.6-terra",
60
60
  "openai/gpt-5.6-luna",
61
61
  "openai/gpt-6-astra",
62
+ "openai/gpt-6-sol",
63
+ "openai/gpt-6-luna",
64
+ "openai/gpt-6.1-sol",
62
65
  "openai-codex/gpt-5.4",
63
66
  "openai-codex/gpt-5.5",
64
67
  "openai-codex/gpt-5.6-sol",
65
68
  "openai-codex/gpt-5.6-terra",
66
69
  "openai-codex/gpt-5.6-luna",
67
- "openai-codex/gpt-6-astra"
70
+ "openai-codex/gpt-6-astra",
71
+ "openai-codex/gpt-6-sol",
72
+ "openai-codex/gpt-6-luna",
73
+ "openai-codex/gpt-6.1-sol"
68
74
  ],
69
75
  "showStatus": true
70
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;iBAuEwB,SAAS,IAAI"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;iBA6EwB,SAAS,IAAI"}
@@ -20966,12 +20966,18 @@ const FastModeConfig = Struct({
20966
20966
  "openai/gpt-5.6-terra",
20967
20967
  "openai/gpt-5.6-luna",
20968
20968
  "openai/gpt-6-astra",
20969
+ "openai/gpt-6-sol",
20970
+ "openai/gpt-6-luna",
20971
+ "openai/gpt-6.1-sol",
20969
20972
  "openai-codex/gpt-5.4",
20970
20973
  "openai-codex/gpt-5.5",
20971
20974
  "openai-codex/gpt-5.6-sol",
20972
20975
  "openai-codex/gpt-5.6-terra",
20973
20976
  "openai-codex/gpt-5.6-luna",
20974
- "openai-codex/gpt-6-astra"
20977
+ "openai-codex/gpt-6-astra",
20978
+ "openai-codex/gpt-6-sol",
20979
+ "openai-codex/gpt-6-luna",
20980
+ "openai-codex/gpt-6.1-sol"
20975
20981
  ]))),
20976
20982
  showStatus: Boolean.pipe(withDecodingDefault(succeed$1(true)))
20977
20983
  });