@code-yeongyu/senpi 2026.7.10 → 2026.7.11

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 (311) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +4 -2
  3. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  4. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  5. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  6. package/dist/core/extensions/builtin/compaction/index.js +10 -1
  7. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  8. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  9. package/dist/core/extensions/builtin/goal/store.js +88 -3
  10. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  11. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +3 -0
  12. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -0
  13. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +83 -0
  14. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -0
  15. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/prompt-preset/presets.js +6 -0
  17. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  18. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  19. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  21. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  22. package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -3
  23. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/terminal/notify.js +7 -4
  25. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  26. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -3
  27. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/terminal/runtime-session.js +32 -16
  29. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  30. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +1 -1
  31. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +10 -4
  33. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  34. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/todotools/tools/todowrite.js +5 -8
  36. package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +1 -1
  37. package/dist/core/extensions/runner.d.ts +1 -0
  38. package/dist/core/extensions/runner.d.ts.map +1 -1
  39. package/dist/core/extensions/runner.js +5 -0
  40. package/dist/core/extensions/runner.js.map +1 -1
  41. package/dist/core/extensions/types.d.ts +5 -8
  42. package/dist/core/extensions/types.d.ts.map +1 -1
  43. package/dist/core/extensions/types.js.map +1 -1
  44. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  45. package/dist/core/extensions/wrapper.js +22 -3
  46. package/dist/core/extensions/wrapper.js.map +1 -1
  47. package/dist/core/keybindings.d.ts +8 -3
  48. package/dist/core/keybindings.d.ts.map +1 -1
  49. package/dist/core/keybindings.js +7 -3
  50. package/dist/core/keybindings.js.map +1 -1
  51. package/dist/core/model-registry.d.ts +1 -6
  52. package/dist/core/model-registry.d.ts.map +1 -1
  53. package/dist/core/model-registry.js +19 -6
  54. package/dist/core/model-registry.js.map +1 -1
  55. package/dist/core/settings-manager.d.ts +4 -3
  56. package/dist/core/settings-manager.d.ts.map +1 -1
  57. package/dist/core/settings-manager.js +2 -1
  58. package/dist/core/settings-manager.js.map +1 -1
  59. package/dist/index.d.ts +1 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/modes/interactive/components/custom-editor.js +1 -1
  64. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  65. package/dist/modes/interactive/components/login-dialog.d.ts +4 -0
  66. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  67. package/dist/modes/interactive/components/login-dialog.js +9 -2
  68. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  69. package/dist/modes/interactive/components/settings-selector.js +1 -1
  70. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  71. package/dist/modes/interactive/components/thinking-selector.js +1 -1
  72. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  73. package/dist/modes/interactive/components/tool-execution-fallback.d.ts +6 -0
  74. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -0
  75. package/dist/modes/interactive/components/tool-execution-fallback.js +40 -0
  76. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -0
  77. package/dist/modes/interactive/components/tool-execution-images.d.ts +23 -0
  78. package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
  79. package/dist/modes/interactive/components/tool-execution-images.js +104 -0
  80. package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
  81. package/dist/modes/interactive/components/tool-execution-renderer.d.ts +28 -0
  82. package/dist/modes/interactive/components/tool-execution-renderer.d.ts.map +1 -0
  83. package/dist/modes/interactive/components/tool-execution-renderer.js +135 -0
  84. package/dist/modes/interactive/components/tool-execution-renderer.js.map +1 -0
  85. package/dist/modes/interactive/components/tool-execution-types.d.ts +23 -0
  86. package/dist/modes/interactive/components/tool-execution-types.d.ts.map +1 -0
  87. package/dist/modes/interactive/components/tool-execution-types.js +2 -0
  88. package/dist/modes/interactive/components/tool-execution-types.js.map +1 -0
  89. package/dist/modes/interactive/components/tool-execution.d.ts +13 -39
  90. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  91. package/dist/modes/interactive/components/tool-execution.js +51 -294
  92. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  93. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts +17 -0
  94. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts.map +1 -0
  95. package/dist/modes/interactive/components/tool-renderer-boundary.js +75 -0
  96. package/dist/modes/interactive/components/tool-renderer-boundary.js.map +1 -0
  97. package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
  98. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  99. package/dist/modes/interactive/components/tree-selector.js +50 -17
  100. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  101. package/dist/modes/interactive/interactive-mode.d.ts +1 -2
  102. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  103. package/dist/modes/interactive/interactive-mode.js +44 -40
  104. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  105. package/dist/modes/interactive/theme/dark.json +1 -0
  106. package/dist/modes/interactive/theme/light.json +1 -0
  107. package/dist/modes/interactive/theme/theme-schema.json +6 -2
  108. package/dist/modes/interactive/theme/theme.d.ts +3 -2
  109. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  110. package/dist/modes/interactive/theme/theme.js +11 -4
  111. package/dist/modes/interactive/theme/theme.js.map +1 -1
  112. package/dist/utils/clipboard-native.d.ts +1 -0
  113. package/dist/utils/clipboard-native.d.ts.map +1 -1
  114. package/dist/utils/clipboard-native.js.map +1 -1
  115. package/dist/utils/clipboard.d.ts +2 -0
  116. package/dist/utils/clipboard.d.ts.map +1 -1
  117. package/dist/utils/clipboard.js +13 -0
  118. package/dist/utils/clipboard.js.map +1 -1
  119. package/docs/custom-provider.md +4 -3
  120. package/docs/extensions.md +140 -1
  121. package/docs/keybindings.md +1 -0
  122. package/docs/models.md +45 -4
  123. package/docs/providers.md +3 -0
  124. package/docs/quickstart.md +1 -1
  125. package/docs/rpc.md +2 -2
  126. package/docs/sdk.md +1 -1
  127. package/docs/settings.md +3 -3
  128. package/docs/themes.md +5 -3
  129. package/docs/tui.md +1 -1
  130. package/docs/usage.md +2 -1
  131. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  132. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  133. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  134. package/examples/extensions/gondolin/package-lock.json +2 -2
  135. package/examples/extensions/gondolin/package.json +1 -1
  136. package/examples/extensions/sandbox/package-lock.json +2 -2
  137. package/examples/extensions/sandbox/package.json +1 -1
  138. package/examples/extensions/with-deps/package-lock.json +2 -2
  139. package/examples/extensions/with-deps/package.json +1 -1
  140. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +3 -0
  141. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  142. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +7 -7
  143. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/tool-bridge.ts +3 -0
  144. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +69 -8
  145. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +39 -13
  146. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +191 -148
  147. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker-entry.js +23 -0
  148. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +4 -175
  149. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +38 -0
  150. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/run-queue.ts +82 -0
  151. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +7 -3
  152. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-host.ts +117 -0
  153. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +32 -0
  154. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +231 -199
  155. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/process.ts +119 -0
  156. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +237 -0
  157. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +22 -0
  158. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +214 -189
  159. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-process.ts +174 -0
  160. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +100 -0
  161. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-run.ts +98 -0
  162. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +205 -0
  163. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +208 -203
  164. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +215 -25
  165. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +1 -0
  166. package/node_modules/@earendil-works/pi-agent-core/README.md +1 -1
  167. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -0
  168. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  169. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +4 -3
  170. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  171. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  172. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  173. package/node_modules/@earendil-works/pi-ai/README.md +4 -2
  174. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +89 -40
  176. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts +1 -1
  178. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  180. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +7 -7
  182. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +1 -1
  184. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +10 -3
  186. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +1 -1
  188. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +5 -1
  190. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +3 -1
  192. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +35 -4
  194. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  195. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +7 -3
  198. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +8 -3
  201. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +4 -3
  204. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/compat.js +2 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +483 -61
  210. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/models.js +13 -4
  212. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  213. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +5 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  216. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +62 -5
  217. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +32 -20
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +11 -1
  221. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +6 -4
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts +7 -8
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js +20 -21
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +11 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +6 -4
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.d.ts.map +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js +9 -6
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js.map +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts +2 -2
  236. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts.map +1 -1
  237. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js +2 -2
  238. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts +2 -2
  240. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js +2 -2
  242. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js.map +1 -1
  243. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +100 -2
  244. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +64 -5
  246. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts +56 -0
  248. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts.map +1 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js +20 -9
  250. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js.map +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts +77 -8
  252. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js +37 -24
  254. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +3 -3
  256. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +3 -3
  258. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +80 -4
  260. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +64 -8
  262. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +25 -22
  264. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +64 -79
  266. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +45 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +43 -7
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts.map +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js.map +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +30 -7
  280. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts +9 -0
  283. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts.map +1 -0
  284. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js +36 -0
  285. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js.map +1 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts +3 -3
  287. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js +35 -14
  289. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js.map +1 -1
  290. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  291. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  292. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -1
  293. package/node_modules/@earendil-works/pi-tui/dist/components/image.js +2 -1
  294. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -1
  295. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -1
  296. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  297. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -1
  298. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  299. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/keys.js +6 -5
  301. package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
  303. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -9
  305. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts +4 -0
  307. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts.map +1 -0
  308. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js +18 -0
  309. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js.map +1 -0
  310. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  311. package/package.json +6 -6
@@ -158,9 +158,10 @@ export function parseBridgeJsonLine(line: string, options: BridgeFrameOptions =
158
158
  };
159
159
  }
160
160
  try {
161
- return { ok: true, value: JSON.parse(trimmedLine) as unknown };
161
+ return { ok: true, value: JSON.parse(trimmedLine) };
162
162
  } catch (error) {
163
- return { ok: false, error: { code: "malformed_json", message: errorMessage(error) } };
163
+ const message = error instanceof Error ? error.message : "Invalid JSON bridge frame";
164
+ return { ok: false, error: { code: "malformed_json", message } };
164
165
  }
165
166
  }
166
167
 
@@ -175,11 +176,10 @@ export function decodeBridgeFrame(line: string, options: BridgeFrameOptions = {}
175
176
  return { ok: false, error: { code: "invalid_message", message } };
176
177
  }
177
178
 
178
- function tokenHash(token: string): Buffer {
179
- return createHash("sha256").update(token, "utf8").digest();
179
+ export function isKernelToHostMessage(message: BridgeMessage): message is KernelToHostMessage {
180
+ return Value.Check(kernelToHostMessageSchema, message);
180
181
  }
181
182
 
182
- function errorMessage(error: unknown): string {
183
- if (error instanceof Error) return error.message;
184
- return "Invalid JSON bridge frame";
183
+ function tokenHash(token: string): Buffer {
184
+ return createHash("sha256").update(token, "utf8").digest();
185
185
  }
@@ -8,6 +8,7 @@ export interface CompletionToolCallOptions {
8
8
  readonly kernel: EvalKernel;
9
9
  readonly complete: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>;
10
10
  readonly ctx: ExtensionContext;
11
+ readonly isActive: () => boolean;
11
12
  }
12
13
 
13
14
  export type CompletionToolCallSummary = { readonly ok: true } | { readonly ok: false; readonly error: string };
@@ -15,10 +16,12 @@ export type CompletionToolCallSummary = { readonly ok: true } | { readonly ok: f
15
16
  export async function handleCompletionToolCall(options: CompletionToolCallOptions): Promise<CompletionToolCallSummary> {
16
17
  try {
17
18
  const value = await options.complete(toCompletionRequest(options.message.args), options.ctx);
19
+ if (!options.isActive()) return { ok: false, error: "completion() result ignored after eval finalization" };
18
20
  options.kernel.deliverToolReply({ type: "tool-reply", callId: options.message.callId, ok: true, value });
19
21
  return { ok: true };
20
22
  } catch (error) {
21
23
  const message = error instanceof Error ? error.message : String(error);
24
+ if (!options.isActive()) return { ok: false, error: message };
22
25
  options.kernel.deliverToolReply({
23
26
  type: "tool-reply",
24
27
  callId: options.message.callId,
@@ -33,12 +33,31 @@ export async function createCodemodeSessionManager(
33
33
  return manager;
34
34
  }
35
35
 
36
+ class CodemodeSessionDisposedError extends Error {
37
+ readonly name = "CodemodeSessionDisposedError";
38
+
39
+ constructor() {
40
+ super("codemode session manager is disposed");
41
+ }
42
+ }
43
+
44
+ class CodemodeContextUnavailableError extends Error {
45
+ readonly name = "CodemodeContextUnavailableError";
46
+
47
+ constructor() {
48
+ super("codemode completion context is unavailable");
49
+ }
50
+ }
51
+
36
52
  class DefaultCodemodeSessionManager implements CodemodeSessionManager {
37
53
  readonly #options: CreateCodemodeSessionManagerOptions;
38
54
  #bridge: BridgeServerHandle | undefined;
39
55
  #kernels = new Map<EvalLanguage, EvalKernel>();
56
+ #kernelCreations = new Map<EvalLanguage, Promise<EvalKernel>>();
40
57
  #onMessageRefs = new Map<EvalLanguage, (message: KernelToHostMessage) => void>();
41
58
  #context: ExtensionContext | undefined;
59
+ #generation = 0;
60
+ #disposePromise: Promise<void> | undefined;
42
61
 
43
62
  constructor(options: CreateCodemodeSessionManagerOptions) {
44
63
  this.#options = options;
@@ -55,6 +74,7 @@ class DefaultCodemodeSessionManager implements CodemodeSessionManager {
55
74
  }
56
75
 
57
76
  async getKernel(language: EvalLanguage, onMessage: (message: KernelToHostMessage) => void): Promise<EvalKernel> {
77
+ if (this.#disposePromise) throw new CodemodeSessionDisposedError();
58
78
  // Persistent kernels are reused across cells, but each cell needs its OWN
59
79
  // onMessage (bound to that cell's streaming state). Rebind on every call via
60
80
  // a stable dispatcher so the 2nd+ cell's text/display/log output is attributed
@@ -62,10 +82,17 @@ class DefaultCodemodeSessionManager implements CodemodeSessionManager {
62
82
  this.#onMessageRefs.set(language, onMessage);
63
83
  const existing = this.#kernels.get(language);
64
84
  if (existing) return existing;
85
+ const pending = this.#kernelCreations.get(language);
86
+ if (pending) return await pending;
65
87
  const dispatch = (message: KernelToHostMessage): void => this.#onMessageRefs.get(language)?.(message);
66
- const kernel = await this.#createKernel(language, dispatch);
67
- this.#kernels.set(language, kernel);
68
- return kernel;
88
+ const generation = this.#generation;
89
+ const creation = this.#createAndStoreKernel(language, dispatch, generation);
90
+ this.#kernelCreations.set(language, creation);
91
+ try {
92
+ return await creation;
93
+ } finally {
94
+ if (this.#kernelCreations.get(language) === creation) this.#kernelCreations.delete(language);
95
+ }
69
96
  }
70
97
 
71
98
  async complete(request: CompletionRequest, ctx: ExtensionContext): Promise<CompletionResult> {
@@ -76,12 +103,46 @@ class DefaultCodemodeSessionManager implements CodemodeSessionManager {
76
103
  this.#context = ctx;
77
104
  }
78
105
 
79
- async dispose(): Promise<void> {
106
+ dispose(): Promise<void> {
107
+ if (this.#disposePromise) return this.#disposePromise;
108
+ this.#generation++;
109
+ this.#disposePromise = this.#disposeGeneration();
110
+ return this.#disposePromise;
111
+ }
112
+
113
+ async #disposeGeneration(): Promise<void> {
114
+ await Promise.allSettled(this.#kernelCreations.values());
80
115
  const kernels = [...this.#kernels.values()];
116
+ const bridge = this.#bridge;
81
117
  this.#kernels.clear();
82
- await Promise.all(kernels.map((kernel) => kernel.close()));
83
- await this.#bridge?.close();
118
+ this.#onMessageRefs.clear();
84
119
  this.#bridge = undefined;
120
+ this.#context = undefined;
121
+ const failures: unknown[] = [];
122
+ for (const outcome of await Promise.allSettled(kernels.map((kernel) => kernel.close()))) {
123
+ if (outcome.status === "rejected") failures.push(outcome.reason);
124
+ }
125
+ if (bridge) {
126
+ const [outcome] = await Promise.allSettled([bridge.close()]);
127
+ if (outcome?.status === "rejected") failures.push(outcome.reason);
128
+ }
129
+ if (failures.length > 0) {
130
+ throw new AggregateError(failures, "Failed to dispose codemode session manager");
131
+ }
132
+ }
133
+
134
+ async #createAndStoreKernel(
135
+ language: EvalLanguage,
136
+ onMessage: (message: KernelToHostMessage) => void,
137
+ generation: number,
138
+ ): Promise<EvalKernel> {
139
+ const kernel = await this.#createKernel(language, onMessage);
140
+ if (generation !== this.#generation) {
141
+ await kernel.close();
142
+ throw new CodemodeSessionDisposedError();
143
+ }
144
+ this.#kernels.set(language, kernel);
145
+ return kernel;
85
146
  }
86
147
 
87
148
  async #createKernel(language: EvalLanguage, onMessage: (message: KernelToHostMessage) => void): Promise<EvalKernel> {
@@ -127,7 +188,7 @@ class DefaultCodemodeSessionManager implements CodemodeSessionManager {
127
188
 
128
189
  #contextFor(signal: AbortSignal): ExtensionContext {
129
190
  const ctx = this.#context;
130
- if (!ctx) return { signal } as ExtensionContext;
131
- return ctx;
191
+ if (!ctx) throw new CodemodeContextUnavailableError();
192
+ return { ...ctx, signal: ctx.signal ? AbortSignal.any([ctx.signal, signal]) : signal };
132
193
  }
133
194
  }
@@ -1,4 +1,4 @@
1
- import type { ExtensionAPI, ExtensionContext } from "@code-yeongyu/senpi";
1
+ import type { ExtensionContext } from "@code-yeongyu/senpi";
2
2
  import type { KernelToHostMessage } from "./bridge/protocol.ts";
3
3
  import { type CompletionRequest, type CompletionResult, createCompletionHandler } from "./completion/handler.ts";
4
4
  import { type CodemodeSettings, loadCodemodeSettings } from "./config/settings.ts";
@@ -13,8 +13,15 @@ import {
13
13
  type InterpreterAvailability,
14
14
  } from "./interpreters/detect.ts";
15
15
  import { createEvalTool } from "./tool/eval-tool.ts";
16
- import type { EvalKernel, EvalLanguage } from "./tool/types.ts";
17
- import { evalLanguageOrder } from "./tool/types.ts";
16
+ import type { EvalKernel, EvalLanguage, ExecuteTool } from "./tool/types.ts";
17
+
18
+ type SessionLifecycleEvent = "session_start" | "session_shutdown" | "session_before_switch" | "session_before_fork";
19
+
20
+ export interface CodemodeExtensionAPI {
21
+ registerTool(tool: ReturnType<typeof createEvalTool>): void;
22
+ on(event: SessionLifecycleEvent, handler: (event: unknown, ctx: ExtensionContext) => Promise<void> | void): void;
23
+ executeTool: ExecuteTool;
24
+ }
18
25
 
19
26
  export interface SenpiCodemodeOptions {
20
27
  readonly createSessionManager?: (
@@ -23,7 +30,7 @@ export interface SenpiCodemodeOptions {
23
30
  readonly complete?: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>;
24
31
  }
25
32
 
26
- export default function senpiCodemode(pi: ExtensionAPI, options: SenpiCodemodeOptions = {}): void {
33
+ export default function senpiCodemode(pi: CodemodeExtensionAPI, options: SenpiCodemodeOptions = {}): void {
27
34
  const manager = new SessionManagerProxy();
28
35
  const complete = options.complete ?? ((request, ctx) => createCompletionHandler()(ctx)(request));
29
36
  pi.registerTool(
@@ -37,7 +44,8 @@ export default function senpiCodemode(pi: ExtensionAPI, options: SenpiCodemodeOp
37
44
  );
38
45
 
39
46
  pi.on("session_start", async (event, ctx) => {
40
- await manager.replace(await createManager(pi, ctx, event, complete, options));
47
+ const generation = manager.beginReplacement();
48
+ await manager.replace(generation, await createManager(pi, ctx, event, complete, options));
41
49
  });
42
50
  pi.on("session_shutdown", async () => manager.dispose());
43
51
  pi.on("session_before_switch", async () => manager.dispose());
@@ -46,9 +54,25 @@ export default function senpiCodemode(pi: ExtensionAPI, options: SenpiCodemodeOp
46
54
 
47
55
  class SessionManagerProxy implements CodemodeSessionManager {
48
56
  #current: CodemodeSessionManager | undefined;
57
+ #generation = 0;
58
+
59
+ beginReplacement(): number {
60
+ this.#generation++;
61
+ return this.#generation;
62
+ }
49
63
 
50
- async replace(next: CodemodeSessionManager): Promise<void> {
51
- await this.dispose();
64
+ async replace(generation: number, next: CodemodeSessionManager): Promise<void> {
65
+ if (generation !== this.#generation) {
66
+ await next.dispose();
67
+ return;
68
+ }
69
+ const current = this.#current;
70
+ this.#current = undefined;
71
+ await current?.dispose();
72
+ if (generation !== this.#generation) {
73
+ await next.dispose();
74
+ return;
75
+ }
52
76
  this.#current = next;
53
77
  }
54
78
 
@@ -67,6 +91,7 @@ class SessionManagerProxy implements CodemodeSessionManager {
67
91
  }
68
92
 
69
93
  async dispose(): Promise<void> {
94
+ this.#generation++;
70
95
  const current = this.#current;
71
96
  this.#current = undefined;
72
97
  await current?.dispose();
@@ -74,7 +99,7 @@ class SessionManagerProxy implements CodemodeSessionManager {
74
99
  }
75
100
 
76
101
  async function createManager(
77
- pi: ExtensionAPI,
102
+ pi: CodemodeExtensionAPI,
78
103
  ctx: ExtensionContext,
79
104
  event: unknown,
80
105
  complete: (request: CompletionRequest, ctx: ExtensionContext) => Promise<CompletionResult>,
@@ -104,9 +129,10 @@ export function enabledLanguagesFrom(
104
129
  settings: CodemodeSettings,
105
130
  availability: InterpreterAvailability,
106
131
  ): Record<EvalLanguage, boolean> {
107
- const enabled = {} as Record<EvalLanguage, boolean>;
108
- for (const language of evalLanguageOrder) {
109
- enabled[language] = settings.languages[language] && availability[language].detected.ok;
110
- }
111
- return enabled;
132
+ return {
133
+ py: settings.languages.py && availability.py.detected.ok,
134
+ js: settings.languages.js && availability.js.detected.ok,
135
+ rb: settings.languages.rb && availability.rb.detected.ok,
136
+ jl: settings.languages.jl && availability.jl.detected.ok,
137
+ };
112
138
  }