@code-yeongyu/senpi 2026.8.13 → 2026.8.16

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 (514) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/README.md +1 -0
  3. package/dist/cli/args.d.ts +1 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +14 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-command.d.ts.map +1 -1
  8. package/dist/cli/auth-command.js +5 -4
  9. package/dist/cli/auth-command.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +80 -8
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +206 -31
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/auth-storage.d.ts.map +1 -1
  15. package/dist/core/auth-storage.js +19 -8
  16. package/dist/core/auth-storage.js.map +1 -1
  17. package/dist/core/experimental.d.ts +4 -0
  18. package/dist/core/experimental.d.ts.map +1 -1
  19. package/dist/core/experimental.js +4 -0
  20. package/dist/core/experimental.js.map +1 -1
  21. package/dist/core/export-html/template.js +31 -9
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.d.ts +4 -0
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.d.ts.map +1 -0
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.js +30 -0
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-environment.js.map +1 -0
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts +2 -0
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js +13 -47
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -1
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts +18 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js +64 -2
  33. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js.map +1 -1
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.d.ts +3 -0
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.d.ts.map +1 -0
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.js +27 -0
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/config-dir-credentials.js.map +1 -0
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +15 -2
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +45 -11
  41. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  42. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js +1 -0
  44. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -1
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +3 -1
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -0
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  50. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +17 -1
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +1 -0
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  56. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/compaction/index.js +225 -75
  58. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  59. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +2 -3
  60. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/compaction/lane-policy.js +2 -3
  62. package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
  63. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  64. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/compaction/log.js +2 -0
  66. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  67. package/dist/core/extensions/builtin/compaction/overflow-retry.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/compaction/overflow-retry.js +38 -4
  69. package/dist/core/extensions/builtin/compaction/overflow-retry.js.map +1 -1
  70. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/compaction/speculative.js +2 -1
  72. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  73. package/dist/core/extensions/builtin/compaction/summarization-turn-order.d.ts +33 -0
  74. package/dist/core/extensions/builtin/compaction/summarization-turn-order.d.ts.map +1 -0
  75. package/dist/core/extensions/builtin/compaction/summarization-turn-order.js +67 -0
  76. package/dist/core/extensions/builtin/compaction/summarization-turn-order.js.map +1 -0
  77. package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/config-reload/index.js +31 -8
  79. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  80. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/config-reload/routine-settings.js +11 -12
  82. package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
  84. package/dist/core/extensions/builtin/goal/terminal-provider-error.js +16 -0
  85. package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
  86. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/index.js +4 -0
  88. package/dist/core/extensions/builtin/index.js.map +1 -1
  89. package/dist/core/extensions/builtin/mcp/process-tree.js +6 -1
  90. package/dist/core/extensions/builtin/mcp/process-tree.js.map +1 -1
  91. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts +3 -0
  92. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts.map +1 -0
  93. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js +14 -0
  94. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js.map +1 -0
  95. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.d.ts +3 -0
  96. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.d.ts.map +1 -0
  97. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js +91 -0
  98. package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js.map +1 -0
  99. package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/prompt-preset/index.js +22 -2
  101. package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
  102. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/prompt-preset/presets.js +25 -0
  104. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  105. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  106. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/prompt-preset/settings.js +2 -0
  108. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  109. package/dist/core/extensions/builtin/reasoning/index.d.ts +3 -0
  110. package/dist/core/extensions/builtin/reasoning/index.d.ts.map +1 -0
  111. package/dist/core/extensions/builtin/reasoning/index.js +211 -0
  112. package/dist/core/extensions/builtin/reasoning/index.js.map +1 -0
  113. package/dist/core/extensions/builtin/service-tier.d.ts +44 -1
  114. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  115. package/dist/core/extensions/builtin/service-tier.js +176 -24
  116. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  117. package/dist/core/extensions/runner.d.ts.map +1 -1
  118. package/dist/core/extensions/runner.js +4 -4
  119. package/dist/core/extensions/runner.js.map +1 -1
  120. package/dist/core/extensions/types.d.ts +13 -1
  121. package/dist/core/extensions/types.d.ts.map +1 -1
  122. package/dist/core/extensions/types.js.map +1 -1
  123. package/dist/core/keybindings.d.ts +24 -0
  124. package/dist/core/keybindings.d.ts.map +1 -1
  125. package/dist/core/lockfile-policy.d.ts +15 -0
  126. package/dist/core/lockfile-policy.d.ts.map +1 -0
  127. package/dist/core/lockfile-policy.js +15 -0
  128. package/dist/core/lockfile-policy.js.map +1 -0
  129. package/dist/core/model-config.d.ts.map +1 -1
  130. package/dist/core/model-config.js +1 -0
  131. package/dist/core/model-config.js.map +1 -1
  132. package/dist/core/model-resolver.d.ts +34 -7
  133. package/dist/core/model-resolver.d.ts.map +1 -1
  134. package/dist/core/model-resolver.js +115 -27
  135. package/dist/core/model-resolver.js.map +1 -1
  136. package/dist/core/model-runtime.d.ts.map +1 -1
  137. package/dist/core/model-runtime.js +5 -3
  138. package/dist/core/model-runtime.js.map +1 -1
  139. package/dist/core/provider-api-key-auth.d.ts.map +1 -1
  140. package/dist/core/provider-api-key-auth.js +45 -2
  141. package/dist/core/provider-api-key-auth.js.map +1 -1
  142. package/dist/core/provider-composer.d.ts +12 -1
  143. package/dist/core/provider-composer.d.ts.map +1 -1
  144. package/dist/core/provider-composer.js.map +1 -1
  145. package/dist/core/provider-display-names.d.ts.map +1 -1
  146. package/dist/core/provider-display-names.js +1 -0
  147. package/dist/core/provider-display-names.js.map +1 -1
  148. package/dist/core/remote-catalog-provider.d.ts +13 -0
  149. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  150. package/dist/core/remote-catalog-provider.js +15 -0
  151. package/dist/core/remote-catalog-provider.js.map +1 -1
  152. package/dist/core/retry-fallback/controller.d.ts +1 -1
  153. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  154. package/dist/core/retry-fallback/controller.js +5 -3
  155. package/dist/core/retry-fallback/controller.js.map +1 -1
  156. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  157. package/dist/core/retry-fallback/settings.js +4 -1
  158. package/dist/core/retry-fallback/settings.js.map +1 -1
  159. package/dist/core/sdk.d.ts +5 -3
  160. package/dist/core/sdk.d.ts.map +1 -1
  161. package/dist/core/sdk.js +14 -8
  162. package/dist/core/sdk.js.map +1 -1
  163. package/dist/core/session-manager.d.ts.map +1 -1
  164. package/dist/core/session-manager.js +20 -4
  165. package/dist/core/session-manager.js.map +1 -1
  166. package/dist/core/settings-manager.d.ts +50 -1
  167. package/dist/core/settings-manager.d.ts.map +1 -1
  168. package/dist/core/settings-manager.js +258 -15
  169. package/dist/core/settings-manager.js.map +1 -1
  170. package/dist/core/system-prompt.js +1 -1
  171. package/dist/core/system-prompt.js.map +1 -1
  172. package/dist/core/thinking-levels.d.ts +22 -0
  173. package/dist/core/thinking-levels.d.ts.map +1 -1
  174. package/dist/core/thinking-levels.js +29 -0
  175. package/dist/core/thinking-levels.js.map +1 -1
  176. package/dist/core/tools/bash.d.ts.map +1 -1
  177. package/dist/core/tools/bash.js +2 -0
  178. package/dist/core/tools/bash.js.map +1 -1
  179. package/dist/core/tools/edit.d.ts.map +1 -1
  180. package/dist/core/tools/edit.js +2 -0
  181. package/dist/core/tools/edit.js.map +1 -1
  182. package/dist/core/tools/find.js +1 -1
  183. package/dist/core/tools/find.js.map +1 -1
  184. package/dist/core/tools/grep.js +1 -1
  185. package/dist/core/tools/grep.js.map +1 -1
  186. package/dist/core/tools/read.d.ts.map +1 -1
  187. package/dist/core/tools/read.js +2 -0
  188. package/dist/core/tools/read.js.map +1 -1
  189. package/dist/core/tools/write.d.ts.map +1 -1
  190. package/dist/core/tools/write.js +2 -0
  191. package/dist/core/tools/write.js.map +1 -1
  192. package/dist/index.d.ts +1 -1
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/index.js.map +1 -1
  195. package/dist/main.d.ts.map +1 -1
  196. package/dist/main.js +18 -1
  197. package/dist/main.js.map +1 -1
  198. package/dist/modes/interactive/components/extension-selector.d.ts +2 -0
  199. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  200. package/dist/modes/interactive/components/extension-selector.js +17 -1
  201. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  202. package/dist/modes/interactive/components/model-favorites.d.ts +2 -1
  203. package/dist/modes/interactive/components/model-favorites.d.ts.map +1 -1
  204. package/dist/modes/interactive/components/model-favorites.js +72 -6
  205. package/dist/modes/interactive/components/model-favorites.js.map +1 -1
  206. package/dist/modes/interactive/components/model-selector.d.ts +5 -1
  207. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  208. package/dist/modes/interactive/components/model-selector.js +10 -6
  209. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  210. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  211. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  212. package/dist/modes/interactive/components/settings-selector.js +10 -0
  213. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  214. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  215. package/dist/modes/interactive/components/tool-execution.js +22 -1
  216. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  217. package/dist/modes/interactive/interactive-mode.d.ts +14 -4
  218. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  219. package/dist/modes/interactive/interactive-mode.js +109 -50
  220. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  221. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  222. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  223. package/dist/modes/interactive/model-catalog-refresh.js +36 -0
  224. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  225. package/dist/modes/interactive/theme/dark.json +2 -0
  226. package/dist/modes/interactive/theme/grok-day.json +2 -0
  227. package/dist/modes/interactive/theme/grok-night.json +2 -0
  228. package/dist/modes/interactive/theme/light.json +2 -0
  229. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  230. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  231. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  232. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  233. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  234. package/dist/modes/interactive/theme/theme.d.ts +5 -3
  235. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  236. package/dist/modes/interactive/theme/theme.js +12 -2
  237. package/dist/modes/interactive/theme/theme.js.map +1 -1
  238. package/dist/modes/json-event.d.ts +4 -1
  239. package/dist/modes/json-event.d.ts.map +1 -1
  240. package/dist/modes/json-event.js +5 -2
  241. package/dist/modes/json-event.js.map +1 -1
  242. package/dist/modes/rpc/connection-handler.d.ts +10 -0
  243. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  244. package/dist/modes/rpc/connection-handler.js +87 -19
  245. package/dist/modes/rpc/connection-handler.js.map +1 -1
  246. package/dist/modes/rpc/multi-session-host.js +3 -3
  247. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  248. package/dist/modes/rpc/rpc-client.d.ts +26 -1
  249. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  250. package/dist/modes/rpc/rpc-client.js +25 -2
  251. package/dist/modes/rpc/rpc-client.js.map +1 -1
  252. package/dist/modes/rpc/rpc-types.d.ts +60 -0
  253. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  254. package/dist/modes/rpc/rpc-types.js.map +1 -1
  255. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  256. package/dist/modes/rpc/session-command-router.js +2 -14
  257. package/dist/modes/rpc/session-command-router.js.map +1 -1
  258. package/dist/modes/rpc/session-event-writer.d.ts +29 -10
  259. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  260. package/dist/modes/rpc/session-event-writer.js +229 -50
  261. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  262. package/dist/server/create-harness.d.ts.map +1 -1
  263. package/dist/server/create-harness.js +2 -0
  264. package/dist/server/create-harness.js.map +1 -1
  265. package/dist/utils/shell.d.ts +27 -0
  266. package/dist/utils/shell.d.ts.map +1 -1
  267. package/dist/utils/shell.js +79 -13
  268. package/dist/utils/shell.js.map +1 -1
  269. package/dist/utils/tools-manager.d.ts +10 -1
  270. package/dist/utils/tools-manager.d.ts.map +1 -1
  271. package/dist/utils/tools-manager.js +14 -19
  272. package/dist/utils/tools-manager.js.map +1 -1
  273. package/docs/compaction.md +3 -3
  274. package/docs/custom-provider.md +1 -1
  275. package/docs/environment-variables.md +8 -2
  276. package/docs/extensions.md +13 -1
  277. package/docs/json.md +9 -5
  278. package/docs/keybindings.md +8 -2
  279. package/docs/providers.md +9 -1
  280. package/docs/rpc.md +128 -6
  281. package/docs/sdk.md +9 -0
  282. package/docs/settings.md +93 -1
  283. package/docs/terminal-setup.md +23 -2
  284. package/docs/themes.md +24 -3
  285. package/docs/tui.md +2 -2
  286. package/docs/usage.md +24 -4
  287. package/examples/extensions/subagent/agents.ts +40 -9
  288. package/examples/extensions/subagent/index.ts +26 -3
  289. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +38 -0
  290. package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -0
  291. package/node_modules/@code-yeongyu/senpi-codemode/package.json +5 -4
  292. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +14 -1
  293. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/call-capture.ts +64 -0
  294. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +45 -61
  295. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +6 -0
  296. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-execution-event.ts +201 -0
  297. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +2 -0
  298. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +22 -0
  299. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts +25 -0
  300. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  301. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +77 -12
  302. package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  303. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.d.ts +43 -0
  304. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.d.ts.map +1 -0
  305. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.js +67 -0
  306. package/node_modules/@earendil-works/pi-agent-core/dist/harness/events.js.map +1 -0
  307. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.d.ts +4 -2
  308. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.d.ts.map +1 -1
  309. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js +127 -88
  310. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.d.ts +5 -1
  312. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.d.ts.map +1 -1
  313. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.js +9 -2
  314. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/errors.js.map +1 -1
  315. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.d.ts +12 -3
  316. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.d.ts.map +1 -1
  317. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.js +88 -45
  318. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/repo.js.map +1 -1
  319. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.d.ts +1 -1
  320. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.d.ts.map +1 -1
  321. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.js +28 -19
  322. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/storage.js.map +1 -1
  323. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.d.ts +1 -1
  324. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.d.ts.map +1 -1
  325. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/types.js.map +1 -1
  326. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.d.ts +1 -1
  327. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.d.ts.map +1 -1
  328. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/memory.js.map +1 -1
  329. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +6 -1
  330. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  331. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +7 -2
  332. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  333. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.d.ts +1 -1
  334. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.d.ts.map +1 -1
  335. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/state.js.map +1 -1
  336. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.d.ts.map +1 -1
  337. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.js +19 -0
  338. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/testing/conformance.js.map +1 -1
  339. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts +18 -5
  340. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts.map +1 -1
  341. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.js.map +1 -1
  342. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
  343. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  344. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
  345. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  346. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts +4 -1
  347. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts.map +1 -1
  348. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.js.map +1 -1
  349. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.d.ts +21 -0
  350. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.d.ts.map +1 -0
  351. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.js +2 -0
  352. package/node_modules/@earendil-works/pi-agent-core/dist/search/index.js.map +1 -0
  353. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.d.ts +29 -0
  354. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.d.ts.map +1 -0
  355. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.js +103 -0
  356. package/node_modules/@earendil-works/pi-agent-core/dist/search/scanning.js.map +1 -0
  357. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  358. package/node_modules/@earendil-works/pi-ai/README.md +2 -0
  359. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  360. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +40 -14
  361. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  362. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  363. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +16 -4
  364. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  365. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.d.ts +69 -0
  366. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.d.ts.map +1 -0
  367. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.js +159 -0
  368. package/node_modules/@earendil-works/pi-ai/dist/api/cloudflare-gateway-binding.js.map +1 -0
  369. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.d.ts +3 -0
  370. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.d.ts.map +1 -1
  371. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js +125 -5
  372. package/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js.map +1 -1
  373. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +7 -3
  374. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
  375. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts +1 -1
  376. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  377. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +13 -9
  378. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  379. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +7 -3
  380. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
  381. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts +1 -1
  382. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts.map +1 -1
  383. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js +208 -42
  384. package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js.map +1 -1
  385. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  386. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +13 -4
  387. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  389. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +10 -7
  390. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  391. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  392. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  393. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +31 -7
  394. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  395. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +8 -1
  397. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  398. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.d.ts +16 -0
  399. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.d.ts.map +1 -0
  400. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.js +234 -0
  401. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/cursor.js.map +1 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +6 -3
  404. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +2 -0
  406. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -1
  407. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +5 -0
  408. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +44 -9
  410. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +2 -0
  412. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  414. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +2 -0
  416. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -1
  417. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +15 -0
  418. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +15 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  422. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -0
  423. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  424. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts +15 -0
  425. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts.map +1 -0
  426. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js +32 -0
  427. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js.map +1 -0
  428. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  429. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  431. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  432. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/providers/data/deepseek.json +1 -1
  434. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google-vertex.json +1 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  446. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
  447. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  448. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  450. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  451. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -3
  452. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  453. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  454. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  455. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +2 -0
  456. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  457. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts +2 -0
  458. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.d.ts.map +1 -0
  459. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js +12 -0
  460. package/node_modules/@earendil-works/pi-ai/dist/utils/pi-user-agent.js.map +1 -0
  461. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  462. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +3 -2
  463. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  464. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  465. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -0
  466. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  467. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.d.ts.map +1 -1
  468. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.js +34 -0
  469. package/node_modules/@earendil-works/pi-ai/dist/utils/validation.js.map +1 -1
  470. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  471. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  472. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  473. package/node_modules/@earendil-works/pi-tui/README.md +1 -1
  474. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.d.ts +26 -0
  475. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.d.ts.map +1 -0
  476. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.js +121 -0
  477. package/node_modules/@earendil-works/pi-tui/dist/alt-screen-search.js.map +1 -0
  478. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.d.ts +6 -1
  479. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.d.ts.map +1 -1
  480. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.js +23 -7
  481. package/node_modules/@earendil-works/pi-tui/dist/components/scroll-view.js.map +1 -1
  482. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +4 -1
  483. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  484. package/node_modules/@earendil-works/pi-tui/dist/index.js +7 -1
  485. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  486. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +30 -0
  487. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +1 -1
  488. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +24 -0
  489. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -1
  490. package/node_modules/@earendil-works/pi-tui/dist/layout.d.ts.map +1 -1
  491. package/node_modules/@earendil-works/pi-tui/dist/layout.js +9 -2
  492. package/node_modules/@earendil-works/pi-tui/dist/layout.js.map +1 -1
  493. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +8 -2
  494. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  495. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +6 -2
  496. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
  497. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +6 -0
  498. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  499. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +18 -1
  500. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  501. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts +21 -0
  502. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
  503. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +243 -5
  504. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
  505. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -0
  506. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  507. package/node_modules/@earendil-works/pi-tui/dist/tui.js +33 -8
  508. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  509. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  510. package/package.json +7 -7
  511. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.d.ts +0 -19
  512. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.d.ts.map +0 -1
  513. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.js +0 -41
  514. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/search.js.map +0 -1
@@ -0,0 +1,201 @@
1
+ import type { AgentToolResult } from "@code-yeongyu/senpi";
2
+ import {
3
+ capCodePoints,
4
+ MAX_AGGREGATED_TOOL_NAMES,
5
+ MAX_CAPTURED_IDENTIFIER_CODE_POINTS,
6
+ MAX_ENRICHED_TOOL_CALLS,
7
+ MAX_RPC_EVENT_BYTES,
8
+ } from "./call-capture.ts";
9
+ import type { CellState } from "./cell-runtime.ts";
10
+ import type { EvalLanguage, EvalToolCallSummary, EvalToolDetails } from "./types.ts";
11
+
12
+ export const EVAL_EXECUTION_EVENT = "senpi.eval.execution";
13
+
14
+ export interface EvalToolAggregate {
15
+ readonly count: number;
16
+ readonly totalDurationMs: number;
17
+ readonly okCount: number;
18
+ readonly errorCount: number;
19
+ readonly pendingCount: number;
20
+ }
21
+
22
+ export type EvalToolAggregates = Record<string, EvalToolAggregate>;
23
+
24
+ interface EvalExecutionBasePayload {
25
+ readonly version: 1;
26
+ readonly cellId: string;
27
+ readonly language: EvalLanguage;
28
+ readonly ok: boolean;
29
+ readonly startedAt: number;
30
+ readonly completedAt: number;
31
+ readonly durationMs: number;
32
+ readonly kernelDurationMs?: number;
33
+ readonly detached: boolean;
34
+ readonly toolCallCount: number;
35
+ readonly pendingToolCallCount: number;
36
+ readonly distinctToolsCalled: readonly string[];
37
+ readonly toolAggregates: EvalToolAggregates;
38
+ readonly toolAggregatesTruncated: boolean;
39
+ readonly toolAggregateOverflow?: EvalToolAggregate;
40
+ }
41
+
42
+ export interface EvalExecutionEventPayload extends EvalExecutionBasePayload {
43
+ readonly detailLevel: "full";
44
+ readonly error?: string;
45
+ readonly toolCalls: readonly EvalToolCallSummary[];
46
+ }
47
+
48
+ export interface EvalExecutionRpcToolCallSummary {
49
+ readonly name: string;
50
+ readonly ok: boolean;
51
+ readonly durationMs?: number;
52
+ }
53
+
54
+ export interface EvalExecutionRpcPayload extends EvalExecutionBasePayload {
55
+ readonly detailLevel: "metadata";
56
+ readonly rpcTruncated: boolean;
57
+ readonly toolCalls: readonly EvalExecutionRpcToolCallSummary[];
58
+ }
59
+
60
+ export type EvalExecutionSettleOutcome =
61
+ | { readonly result: AgentToolResult<EvalToolDetails> }
62
+ | { readonly error: unknown };
63
+
64
+ export interface BuildEvalExecutionEventPayloadOptions {
65
+ readonly cellId: string;
66
+ readonly state: CellState;
67
+ readonly outcome: EvalExecutionSettleOutcome;
68
+ readonly completedAt: number;
69
+ readonly detached: boolean;
70
+ }
71
+
72
+ export function buildEvalExecutionEventPayload(
73
+ options: BuildEvalExecutionEventPayloadOptions,
74
+ ): EvalExecutionEventPayload {
75
+ const { cellId, state, outcome, completedAt, detached } = options;
76
+ const result = "result" in outcome ? outcome.result : undefined;
77
+ const ok = result?.details.isError !== true && !("error" in outcome);
78
+ const aggregateState = aggregateToolCalls(state, completedAt);
79
+ const error = ok ? undefined : settleError(state, outcome);
80
+ return {
81
+ version: 1,
82
+ detailLevel: "full",
83
+ cellId: capCodePoints(cellId, MAX_CAPTURED_IDENTIFIER_CODE_POINTS),
84
+ language: state.input.language,
85
+ ok,
86
+ ...(error === undefined ? {} : { error: capCodePoints(error, 512) }),
87
+ startedAt: state.startedAt,
88
+ completedAt,
89
+ durationMs: Math.max(0, completedAt - state.startedAt),
90
+ ...(result === undefined ? {} : { kernelDurationMs: result.details.durationMs }),
91
+ detached,
92
+ toolCallCount: state.toolCallMetrics.length,
93
+ pendingToolCallCount: aggregateState.pendingCount,
94
+ toolCalls: state.toolCalls.slice(0, MAX_ENRICHED_TOOL_CALLS),
95
+ distinctToolsCalled: [...aggregateState.aggregates.keys()],
96
+ toolAggregates: Object.fromEntries(aggregateState.aggregates),
97
+ toolAggregatesTruncated: aggregateState.overflow !== undefined,
98
+ ...(aggregateState.overflow === undefined ? {} : { toolAggregateOverflow: aggregateState.overflow }),
99
+ };
100
+ }
101
+
102
+ export function toEvalExecutionRpcPayload(payload: EvalExecutionEventPayload): EvalExecutionRpcPayload {
103
+ const candidate: EvalExecutionRpcPayload = {
104
+ version: payload.version,
105
+ detailLevel: "metadata",
106
+ rpcTruncated: false,
107
+ cellId: payload.cellId,
108
+ language: payload.language,
109
+ ok: payload.ok,
110
+ startedAt: payload.startedAt,
111
+ completedAt: payload.completedAt,
112
+ durationMs: payload.durationMs,
113
+ ...(payload.kernelDurationMs === undefined ? {} : { kernelDurationMs: payload.kernelDurationMs }),
114
+ detached: payload.detached,
115
+ toolCallCount: payload.toolCallCount,
116
+ pendingToolCallCount: payload.pendingToolCallCount,
117
+ toolCalls: payload.toolCalls.map((call) => ({
118
+ name: call.name,
119
+ ok: call.ok,
120
+ ...(call.durationMs === undefined ? {} : { durationMs: call.durationMs }),
121
+ })),
122
+ distinctToolsCalled: payload.distinctToolsCalled,
123
+ toolAggregates: payload.toolAggregates,
124
+ toolAggregatesTruncated: payload.toolAggregatesTruncated,
125
+ ...(payload.toolAggregateOverflow === undefined ? {} : { toolAggregateOverflow: payload.toolAggregateOverflow }),
126
+ };
127
+ if (serializedBytes(candidate) <= MAX_RPC_EVENT_BYTES) return candidate;
128
+ return {
129
+ ...candidate,
130
+ rpcTruncated: true,
131
+ toolCalls: [],
132
+ distinctToolsCalled: [],
133
+ toolAggregates: {},
134
+ toolAggregatesTruncated: true,
135
+ toolAggregateOverflow: totalAggregate(payload),
136
+ };
137
+ }
138
+
139
+ function aggregateToolCalls(
140
+ state: CellState,
141
+ completedAt: number,
142
+ ): {
143
+ readonly aggregates: Map<string, EvalToolAggregate>;
144
+ readonly overflow: EvalToolAggregate | undefined;
145
+ readonly pendingCount: number;
146
+ } {
147
+ const aggregates = new Map<string, EvalToolAggregate>();
148
+ let overflow: EvalToolAggregate | undefined;
149
+ let pendingCount = 0;
150
+ for (const metric of state.toolCallMetrics) {
151
+ const item: EvalToolAggregate = {
152
+ count: 1,
153
+ totalDurationMs: metric.durationMs ?? Math.max(0, completedAt - metric.startedAt),
154
+ okCount: metric.ok === true ? 1 : 0,
155
+ errorCount: metric.ok === false ? 1 : 0,
156
+ pendingCount: metric.ok === undefined ? 1 : 0,
157
+ };
158
+ pendingCount += item.pendingCount;
159
+ const existing = aggregates.get(metric.name);
160
+ if (existing !== undefined) {
161
+ aggregates.set(metric.name, addAggregate(existing, item));
162
+ continue;
163
+ }
164
+ if (aggregates.size < MAX_AGGREGATED_TOOL_NAMES) {
165
+ aggregates.set(metric.name, item);
166
+ continue;
167
+ }
168
+ overflow = overflow === undefined ? item : addAggregate(overflow, item);
169
+ }
170
+ return { aggregates, overflow, pendingCount };
171
+ }
172
+
173
+ function addAggregate(left: EvalToolAggregate, right: EvalToolAggregate): EvalToolAggregate {
174
+ return {
175
+ count: left.count + right.count,
176
+ totalDurationMs: left.totalDurationMs + right.totalDurationMs,
177
+ okCount: left.okCount + right.okCount,
178
+ errorCount: left.errorCount + right.errorCount,
179
+ pendingCount: left.pendingCount + right.pendingCount,
180
+ };
181
+ }
182
+
183
+ function totalAggregate(payload: EvalExecutionEventPayload): EvalToolAggregate {
184
+ let total: EvalToolAggregate = { count: 0, totalDurationMs: 0, okCount: 0, errorCount: 0, pendingCount: 0 };
185
+ for (const aggregate of Object.values(payload.toolAggregates)) total = addAggregate(total, aggregate);
186
+ if (payload.toolAggregateOverflow !== undefined) total = addAggregate(total, payload.toolAggregateOverflow);
187
+ return total;
188
+ }
189
+
190
+ function serializedBytes(value: unknown): number {
191
+ return new TextEncoder().encode(JSON.stringify(value)).byteLength;
192
+ }
193
+
194
+ function settleError(state: CellState, outcome: EvalExecutionSettleOutcome): string | undefined {
195
+ if (state.error !== undefined) return state.error;
196
+ if ("error" in outcome) return outcome.error instanceof Error ? outcome.error.message : String(outcome.error);
197
+ for (const part of outcome.result.content) {
198
+ if (part.type === "text" && part.text.length > 0) return part.text.trimEnd();
199
+ }
200
+ return undefined;
201
+ }
@@ -5,6 +5,7 @@ import type { ResolvedCodemodeSettings } from "../config/settings.ts";
5
5
  import type { EvalExecutionTracker } from "../extension/session-manager.ts";
6
6
  import type { EvalTimeoutFactory } from "./cell-execution.ts";
7
7
  import type { EvalDetachedCellManager } from "./detached-cell-manager.ts";
8
+ import type { EvalExecutionEventPayload } from "./eval-execution-event.ts";
8
9
  import type { EvalImageResizer } from "./image.ts";
9
10
  import type {
10
11
  EnabledEvalLanguages,
@@ -29,6 +30,7 @@ export interface CreateEvalToolOptions {
29
30
  readonly imageResizer?: EvalImageResizer;
30
31
  readonly executionTracker?: EvalExecutionTracker;
31
32
  readonly cellManager?: EvalDetachedCellManager;
33
+ readonly onCellSettled?: (payload: EvalExecutionEventPayload) => void;
32
34
  readonly timeoutFactory?: EvalTimeoutFactory;
33
35
  readonly proxyExecutor?: (params: EvalToolInput, signal?: AbortSignal) => Promise<AgentToolResult<EvalToolDetails>>;
34
36
  readonly renderers?: Pick<ToolDefinition<EvalInputSchema, EvalToolDetails>, "renderCall" | "renderResult">;
@@ -8,6 +8,7 @@ import { abortError, CellExecution, defaultTimeoutFactory } from "./cell-executi
8
8
  import { CellHandler, type CellState } from "./cell-handler.ts";
9
9
  import { EvalDetachedCellManager } from "./detached-cell-manager.ts";
10
10
  import { detachedKernelBusyError, executeEvalControl, resultAfterDetach } from "./detached-eval-result.ts";
11
+ import { buildEvalExecutionEventPayload, type EvalExecutionSettleOutcome } from "./eval-execution-event.ts";
11
12
  import { clampEvalSummary, evalTimeoutBehavior, isEvalControlRequest, parseEvalRequest } from "./eval-request.ts";
12
13
  import type { CreateEvalToolOptions, EvalCellInvocation } from "./eval-tool-options.ts";
13
14
  import { describeTimeoutState } from "./interrupt-note.ts";
@@ -99,18 +100,22 @@ async function runEvalCell(
99
100
  const bridgeContext: ExtensionContext = { ...invocation.ctx, signal: cellSignal };
100
101
  const state: CellState = {
101
102
  input: invocation.input,
103
+ startedAt: Date.now(),
102
104
  signal: cellSignal,
103
105
  onUpdate: invocation.onUpdate,
104
106
  toolCalls: [],
107
+ toolCallMetrics: [],
105
108
  pendingBridgeCalls: [],
106
109
  statusEvents: [],
107
110
  active: true,
108
111
  output: "",
109
112
  phase: undefined,
113
+ error: undefined,
110
114
  durationMs: 0,
111
115
  status: "pending",
112
116
  };
113
117
  const cell = cellManager.create(invocation.cellId, invocation.input);
118
+ let detached = false;
114
119
  let execution: CellExecution;
115
120
  execution = new CellExecution({
116
121
  callerSignal: invocation.signal,
@@ -119,6 +124,7 @@ async function runEvalCell(
119
124
  timeoutFactory: options.timeoutFactory ?? defaultTimeoutFactory,
120
125
  onTimeout: (error) => {
121
126
  if (timeoutBehavior === "detach" && cellManager.detach(cell)) {
127
+ detached = true;
122
128
  execution.detach();
123
129
  return;
124
130
  }
@@ -139,13 +145,29 @@ async function runEvalCell(
139
145
  bridgeContext,
140
146
  bridgeAbortController,
141
147
  );
148
+ let settleEventEmitted = false;
149
+ const emitSettled = (outcome: EvalExecutionSettleOutcome): void => {
150
+ if (settleEventEmitted) return;
151
+ settleEventEmitted = true;
152
+ options.onCellSettled?.(
153
+ buildEvalExecutionEventPayload({
154
+ cellId: invocation.cellId,
155
+ state,
156
+ outcome,
157
+ completedAt: Date.now(),
158
+ detached,
159
+ }),
160
+ );
161
+ };
142
162
  const finalized = running.then(
143
163
  (result) => {
144
164
  cellManager.complete(cell, result);
165
+ emitSettled({ result });
145
166
  return result;
146
167
  },
147
168
  (error: unknown) => {
148
169
  cellManager.fail(cell, error instanceof Error ? error : new Error(String(error)));
170
+ emitSettled({ error });
149
171
  throw error;
150
172
  },
151
173
  );
@@ -1,4 +1,29 @@
1
1
  import { type ExecutionEnv, ExecutionError, FileError, type FileInfo, type Result, type ShellExecOptions } from "../types.ts";
2
+ /**
3
+ * Ordered `taskkill` launchers to try, most reliable first.
4
+ *
5
+ * `spawn("taskkill", ...)` relies on a PATH lookup, so any session whose PATH lost
6
+ * `%SystemRoot%\System32` (a POSIX-style PATH inherited from a Git Bash/MSYS launcher,
7
+ * a truncated user PATH, a locked-down service account) fails to resolve it. A broken PATH
8
+ * must not cost us the process-tree kill, so every absolute System32 location that actually
9
+ * exists is tried before the bare PATH-resolved name.
10
+ */
11
+ export declare function windowsTaskkillCandidates(env?: NodeJS.ProcessEnv): string[];
12
+ /**
13
+ * Kill a process and all its children on Windows via `taskkill /T`.
14
+ *
15
+ * Synchronous on purpose. A caller that tears down and exits in the same tick would never
16
+ * observe an asynchronous killer's `error` event, leaving the target alive. `spawnSync`
17
+ * also reports a failed executable lookup on its returned `error` field instead of
18
+ * emitting it, so a PATH without `%SystemRoot%\System32` can no longer surface as an
19
+ * uncaught `spawn taskkill ENOENT`.
20
+ *
21
+ * The direct `process.kill` at the end is a degraded last resort reached only when no
22
+ * `taskkill.exe` can be launched at all. It maps to `TerminateProcess`, which does not
23
+ * touch descendants; nothing in-process can walk a Windows process tree without an
24
+ * external tool, so this still beats leaving the whole tree running.
25
+ */
26
+ export declare function killWindowsProcessTree(pid: number, taskkillPaths?: string[]): void;
2
27
  export declare class NodeExecutionEnv implements ExecutionEnv {
3
28
  cwd: string;
4
29
  private shellPath?;
@@ -1 +1 @@
1
- {"version":3,"file":"nodejs.d.ts","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodejs.d.ts","sourceRoot":"","sources":["../../../src/harness/env/nodejs.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { spawn } from "node:child_process";
1
+ import { spawn, spawnSync } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
- import { constants, createReadStream } from "node:fs";
3
+ import { constants, createReadStream, existsSync } from "node:fs";
4
4
  import { access, appendFile, lstat, mkdir, mkdtemp, readdir, readFile, realpath, rename, rm, writeFile, } from "node:fs/promises";
5
5
  import { homedir, tmpdir } from "node:os";
6
6
  import { basename, isAbsolute, join, resolve } from "node:path";
@@ -198,18 +198,83 @@ function getShellEnv(baseEnv, extraEnv, inheritEnv = true) {
198
198
  ...extraEnv,
199
199
  };
200
200
  }
201
+ /**
202
+ * Ordered `taskkill` launchers to try, most reliable first.
203
+ *
204
+ * `spawn("taskkill", ...)` relies on a PATH lookup, so any session whose PATH lost
205
+ * `%SystemRoot%\System32` (a POSIX-style PATH inherited from a Git Bash/MSYS launcher,
206
+ * a truncated user PATH, a locked-down service account) fails to resolve it. A broken PATH
207
+ * must not cost us the process-tree kill, so every absolute System32 location that actually
208
+ * exists is tried before the bare PATH-resolved name.
209
+ */
210
+ export function windowsTaskkillCandidates(env = process.env) {
211
+ // A bare `SystemDrive` is drive-relative ("C:"), so anchor it before joining.
212
+ const systemDrive = env.SystemDrive ? `${env.SystemDrive}\\` : undefined;
213
+ const roots = [env.SystemRoot, env.SYSTEMROOT, env.windir, systemDrive && join(systemDrive, "Windows")];
214
+ const candidates = [];
215
+ for (const root of roots) {
216
+ if (!root)
217
+ continue;
218
+ // Sysnative reaches the real 64-bit System32 from a 32-bit process, where System32
219
+ // is redirected to SysWOW64.
220
+ for (const systemDir of ["System32", "Sysnative"]) {
221
+ const absolute = join(root, systemDir, "taskkill.exe");
222
+ if (!candidates.includes(absolute) && existsSync(absolute))
223
+ candidates.push(absolute);
224
+ }
225
+ }
226
+ candidates.push("taskkill.exe");
227
+ return candidates;
228
+ }
229
+ function killProcessDirectly(pid) {
230
+ try {
231
+ process.kill(pid);
232
+ }
233
+ catch {
234
+ // Process already dead.
235
+ }
236
+ }
237
+ /** Upper bound on how long a teardown may block waiting for `taskkill` to finish. */
238
+ const TASKKILL_TIMEOUT_MS = 5_000;
239
+ function taskkillHandledTree(pid, taskkillPath) {
240
+ try {
241
+ const result = spawnSync(taskkillPath, ["/F", "/T", "/PID", String(pid)], {
242
+ stdio: "ignore",
243
+ windowsHide: true,
244
+ timeout: TASKKILL_TIMEOUT_MS,
245
+ });
246
+ // `error` means the launcher never started (ENOENT, EACCES); a null status means
247
+ // the timeout killed it. Any real taskkill exit code counts as handled.
248
+ return result.error === undefined && result.status !== null;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ }
254
+ /**
255
+ * Kill a process and all its children on Windows via `taskkill /T`.
256
+ *
257
+ * Synchronous on purpose. A caller that tears down and exits in the same tick would never
258
+ * observe an asynchronous killer's `error` event, leaving the target alive. `spawnSync`
259
+ * also reports a failed executable lookup on its returned `error` field instead of
260
+ * emitting it, so a PATH without `%SystemRoot%\System32` can no longer surface as an
261
+ * uncaught `spawn taskkill ENOENT`.
262
+ *
263
+ * The direct `process.kill` at the end is a degraded last resort reached only when no
264
+ * `taskkill.exe` can be launched at all. It maps to `TerminateProcess`, which does not
265
+ * touch descendants; nothing in-process can walk a Windows process tree without an
266
+ * external tool, so this still beats leaving the whole tree running.
267
+ */
268
+ export function killWindowsProcessTree(pid, taskkillPaths = windowsTaskkillCandidates()) {
269
+ for (const taskkillPath of taskkillPaths) {
270
+ if (taskkillHandledTree(pid, taskkillPath))
271
+ return;
272
+ }
273
+ killProcessDirectly(pid);
274
+ }
201
275
  function killProcessTree(pid) {
202
276
  if (process.platform === "win32") {
203
- try {
204
- spawn("taskkill", ["/F", "/T", "/PID", String(pid)], {
205
- stdio: "ignore",
206
- detached: true,
207
- windowsHide: true,
208
- });
209
- }
210
- catch {
211
- // Ignore errors.
212
- }
277
+ killWindowsProcessTree(pid);
213
278
  return;
214
279
  }
215
280
  try {