@code-yeongyu/senpi 2026.7.10 → 2026.7.13

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 (547) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +4 -2
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +56 -15
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/extensions/builtin/bash-timeout/timeout.js +2 -2
  8. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  9. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  10. package/dist/core/extensions/builtin/compaction/index.js +10 -1
  11. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  12. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  13. package/dist/core/extensions/builtin/goal/store.js +88 -3
  14. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  15. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +3 -0
  16. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -0
  17. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +134 -0
  18. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -0
  19. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/prompt-preset/presets.js +6 -0
  21. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  22. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  23. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  25. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  26. package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -3
  27. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/terminal/notify.js +7 -4
  29. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  30. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -3
  31. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/terminal/runtime-session.js +32 -16
  33. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  34. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +1 -1
  35. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +10 -4
  37. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  38. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/todotools/tools/todowrite.js +5 -8
  40. package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +1 -1
  41. package/dist/core/extensions/runner.d.ts +1 -0
  42. package/dist/core/extensions/runner.d.ts.map +1 -1
  43. package/dist/core/extensions/runner.js +5 -0
  44. package/dist/core/extensions/runner.js.map +1 -1
  45. package/dist/core/extensions/types.d.ts +5 -8
  46. package/dist/core/extensions/types.d.ts.map +1 -1
  47. package/dist/core/extensions/types.js.map +1 -1
  48. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  49. package/dist/core/extensions/wrapper.js +22 -3
  50. package/dist/core/extensions/wrapper.js.map +1 -1
  51. package/dist/core/keybindings.d.ts +8 -3
  52. package/dist/core/keybindings.d.ts.map +1 -1
  53. package/dist/core/keybindings.js +7 -3
  54. package/dist/core/keybindings.js.map +1 -1
  55. package/dist/core/model-registry.d.ts +1 -6
  56. package/dist/core/model-registry.d.ts.map +1 -1
  57. package/dist/core/model-registry.js +19 -6
  58. package/dist/core/model-registry.js.map +1 -1
  59. package/dist/core/resource-loader.d.ts +1 -0
  60. package/dist/core/resource-loader.d.ts.map +1 -1
  61. package/dist/core/resource-loader.js +20 -2
  62. package/dist/core/resource-loader.js.map +1 -1
  63. package/dist/core/settings-manager.d.ts +4 -3
  64. package/dist/core/settings-manager.d.ts.map +1 -1
  65. package/dist/core/settings-manager.js +2 -1
  66. package/dist/core/settings-manager.js.map +1 -1
  67. package/dist/index.d.ts +1 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +1 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/modes/interactive/compaction-queue-transfer.d.ts +22 -0
  72. package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -0
  73. package/dist/modes/interactive/compaction-queue-transfer.js +82 -0
  74. package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -0
  75. package/dist/modes/interactive/components/custom-editor.js +1 -1
  76. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  77. package/dist/modes/interactive/components/login-dialog.d.ts +4 -0
  78. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  79. package/dist/modes/interactive/components/login-dialog.js +9 -2
  80. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  81. package/dist/modes/interactive/components/settings-selector.js +1 -1
  82. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  83. package/dist/modes/interactive/components/thinking-selector.js +1 -1
  84. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  85. package/dist/modes/interactive/components/tool-execution-fallback.d.ts +6 -0
  86. package/dist/modes/interactive/components/tool-execution-fallback.d.ts.map +1 -0
  87. package/dist/modes/interactive/components/tool-execution-fallback.js +40 -0
  88. package/dist/modes/interactive/components/tool-execution-fallback.js.map +1 -0
  89. package/dist/modes/interactive/components/tool-execution-images.d.ts +23 -0
  90. package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
  91. package/dist/modes/interactive/components/tool-execution-images.js +104 -0
  92. package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
  93. package/dist/modes/interactive/components/tool-execution-renderer.d.ts +28 -0
  94. package/dist/modes/interactive/components/tool-execution-renderer.d.ts.map +1 -0
  95. package/dist/modes/interactive/components/tool-execution-renderer.js +135 -0
  96. package/dist/modes/interactive/components/tool-execution-renderer.js.map +1 -0
  97. package/dist/modes/interactive/components/tool-execution-types.d.ts +23 -0
  98. package/dist/modes/interactive/components/tool-execution-types.d.ts.map +1 -0
  99. package/dist/modes/interactive/components/tool-execution-types.js +2 -0
  100. package/dist/modes/interactive/components/tool-execution-types.js.map +1 -0
  101. package/dist/modes/interactive/components/tool-execution.d.ts +13 -39
  102. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/tool-execution.js +51 -294
  104. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  105. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts +17 -0
  106. package/dist/modes/interactive/components/tool-renderer-boundary.d.ts.map +1 -0
  107. package/dist/modes/interactive/components/tool-renderer-boundary.js +75 -0
  108. package/dist/modes/interactive/components/tool-renderer-boundary.js.map +1 -0
  109. package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
  110. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/tree-selector.js +50 -17
  112. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  113. package/dist/modes/interactive/interactive-mode.d.ts +5 -2
  114. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  115. package/dist/modes/interactive/interactive-mode.js +127 -109
  116. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  117. package/dist/modes/interactive/theme/dark.json +1 -0
  118. package/dist/modes/interactive/theme/light.json +1 -0
  119. package/dist/modes/interactive/theme/theme-schema.json +6 -2
  120. package/dist/modes/interactive/theme/theme.d.ts +3 -2
  121. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  122. package/dist/modes/interactive/theme/theme.js +11 -4
  123. package/dist/modes/interactive/theme/theme.js.map +1 -1
  124. package/dist/utils/clipboard-native.d.ts +1 -0
  125. package/dist/utils/clipboard-native.d.ts.map +1 -1
  126. package/dist/utils/clipboard-native.js.map +1 -1
  127. package/dist/utils/clipboard.d.ts +2 -0
  128. package/dist/utils/clipboard.d.ts.map +1 -1
  129. package/dist/utils/clipboard.js +13 -0
  130. package/dist/utils/clipboard.js.map +1 -1
  131. package/docs/custom-provider.md +4 -3
  132. package/docs/extensions.md +140 -1
  133. package/docs/keybindings.md +1 -0
  134. package/docs/models.md +45 -4
  135. package/docs/providers.md +3 -0
  136. package/docs/quickstart.md +1 -1
  137. package/docs/rpc.md +2 -2
  138. package/docs/sdk.md +1 -1
  139. package/docs/settings.md +3 -3
  140. package/docs/themes.md +5 -3
  141. package/docs/tui.md +1 -1
  142. package/docs/usage.md +2 -1
  143. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  144. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  145. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  146. package/examples/extensions/gondolin/package-lock.json +2 -2
  147. package/examples/extensions/gondolin/package.json +1 -1
  148. package/examples/extensions/sandbox/package-lock.json +2 -2
  149. package/examples/extensions/sandbox/package.json +1 -1
  150. package/examples/extensions/with-deps/package-lock.json +2 -2
  151. package/examples/extensions/with-deps/package.json +1 -1
  152. package/node_modules/@babel/helper-string-parser/LICENSE +22 -0
  153. package/node_modules/@babel/helper-string-parser/README.md +19 -0
  154. package/node_modules/@babel/helper-string-parser/lib/index.js +295 -0
  155. package/node_modules/@babel/helper-string-parser/lib/index.js.map +1 -0
  156. package/node_modules/@babel/helper-string-parser/package.json +31 -0
  157. package/node_modules/@babel/helper-validator-identifier/LICENSE +22 -0
  158. package/node_modules/@babel/helper-validator-identifier/README.md +19 -0
  159. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js +70 -0
  160. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js.map +1 -0
  161. package/node_modules/@babel/helper-validator-identifier/lib/index.js +57 -0
  162. package/node_modules/@babel/helper-validator-identifier/lib/index.js.map +1 -0
  163. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js +35 -0
  164. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js.map +1 -0
  165. package/node_modules/@babel/helper-validator-identifier/package.json +31 -0
  166. package/node_modules/@babel/parser/LICENSE +19 -0
  167. package/node_modules/@babel/parser/README.md +19 -0
  168. package/node_modules/@babel/parser/bin/babel-parser.js +15 -0
  169. package/node_modules/@babel/parser/lib/index.js +14599 -0
  170. package/node_modules/@babel/parser/lib/index.js.map +1 -0
  171. package/node_modules/@babel/parser/package.json +50 -0
  172. package/node_modules/@babel/parser/typings/babel-parser.d.ts +262 -0
  173. package/node_modules/@babel/types/LICENSE +22 -0
  174. package/node_modules/@babel/types/README.md +19 -0
  175. package/node_modules/@babel/types/lib/asserts/assertNode.js +16 -0
  176. package/node_modules/@babel/types/lib/asserts/assertNode.js.map +1 -0
  177. package/node_modules/@babel/types/lib/asserts/generated/index.js +1251 -0
  178. package/node_modules/@babel/types/lib/asserts/generated/index.js.map +1 -0
  179. package/node_modules/@babel/types/lib/ast-types/generated/index.js +3 -0
  180. package/node_modules/@babel/types/lib/ast-types/generated/index.js.map +1 -0
  181. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js +18 -0
  182. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js.map +1 -0
  183. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js +31 -0
  184. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js.map +1 -0
  185. package/node_modules/@babel/types/lib/builders/generated/index.js +29 -0
  186. package/node_modules/@babel/types/lib/builders/generated/index.js.map +1 -0
  187. package/node_modules/@babel/types/lib/builders/generated/lowercase.js +2902 -0
  188. package/node_modules/@babel/types/lib/builders/generated/lowercase.js.map +1 -0
  189. package/node_modules/@babel/types/lib/builders/generated/uppercase.js +272 -0
  190. package/node_modules/@babel/types/lib/builders/generated/uppercase.js.map +1 -0
  191. package/node_modules/@babel/types/lib/builders/productions.js +12 -0
  192. package/node_modules/@babel/types/lib/builders/productions.js.map +1 -0
  193. package/node_modules/@babel/types/lib/builders/react/buildChildren.js +24 -0
  194. package/node_modules/@babel/types/lib/builders/react/buildChildren.js.map +1 -0
  195. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js +22 -0
  196. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js.map +1 -0
  197. package/node_modules/@babel/types/lib/builders/validateNode.js +21 -0
  198. package/node_modules/@babel/types/lib/builders/validateNode.js.map +1 -0
  199. package/node_modules/@babel/types/lib/clone/clone.js +12 -0
  200. package/node_modules/@babel/types/lib/clone/clone.js.map +1 -0
  201. package/node_modules/@babel/types/lib/clone/cloneDeep.js +12 -0
  202. package/node_modules/@babel/types/lib/clone/cloneDeep.js.map +1 -0
  203. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js +12 -0
  204. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js.map +1 -0
  205. package/node_modules/@babel/types/lib/clone/cloneNode.js +107 -0
  206. package/node_modules/@babel/types/lib/clone/cloneNode.js.map +1 -0
  207. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js +12 -0
  208. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js.map +1 -0
  209. package/node_modules/@babel/types/lib/comments/addComment.js +15 -0
  210. package/node_modules/@babel/types/lib/comments/addComment.js.map +1 -0
  211. package/node_modules/@babel/types/lib/comments/addComments.js +22 -0
  212. package/node_modules/@babel/types/lib/comments/addComments.js.map +1 -0
  213. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js +12 -0
  214. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js.map +1 -0
  215. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js +12 -0
  216. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js.map +1 -0
  217. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js +12 -0
  218. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js.map +1 -0
  219. package/node_modules/@babel/types/lib/comments/inheritsComments.js +17 -0
  220. package/node_modules/@babel/types/lib/comments/inheritsComments.js.map +1 -0
  221. package/node_modules/@babel/types/lib/comments/removeComments.js +15 -0
  222. package/node_modules/@babel/types/lib/comments/removeComments.js.map +1 -0
  223. package/node_modules/@babel/types/lib/constants/generated/index.js +60 -0
  224. package/node_modules/@babel/types/lib/constants/generated/index.js.map +1 -0
  225. package/node_modules/@babel/types/lib/constants/index.js +31 -0
  226. package/node_modules/@babel/types/lib/constants/index.js.map +1 -0
  227. package/node_modules/@babel/types/lib/converters/ensureBlock.js +14 -0
  228. package/node_modules/@babel/types/lib/converters/ensureBlock.js.map +1 -0
  229. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js +65 -0
  230. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js.map +1 -0
  231. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js +14 -0
  232. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js.map +1 -0
  233. package/node_modules/@babel/types/lib/converters/toBlock.js +29 -0
  234. package/node_modules/@babel/types/lib/converters/toBlock.js.map +1 -0
  235. package/node_modules/@babel/types/lib/converters/toComputedKey.js +14 -0
  236. package/node_modules/@babel/types/lib/converters/toComputedKey.js.map +1 -0
  237. package/node_modules/@babel/types/lib/converters/toExpression.js +28 -0
  238. package/node_modules/@babel/types/lib/converters/toExpression.js.map +1 -0
  239. package/node_modules/@babel/types/lib/converters/toIdentifier.js +25 -0
  240. package/node_modules/@babel/types/lib/converters/toIdentifier.js.map +1 -0
  241. package/node_modules/@babel/types/lib/converters/toKeyAlias.js +38 -0
  242. package/node_modules/@babel/types/lib/converters/toKeyAlias.js.map +1 -0
  243. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js +19 -0
  244. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js.map +1 -0
  245. package/node_modules/@babel/types/lib/converters/toStatement.js +39 -0
  246. package/node_modules/@babel/types/lib/converters/toStatement.js.map +1 -0
  247. package/node_modules/@babel/types/lib/converters/valueToNode.js +89 -0
  248. package/node_modules/@babel/types/lib/converters/valueToNode.js.map +1 -0
  249. package/node_modules/@babel/types/lib/definitions/core.js +1725 -0
  250. package/node_modules/@babel/types/lib/definitions/core.js.map +1 -0
  251. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js +11 -0
  252. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js.map +1 -0
  253. package/node_modules/@babel/types/lib/definitions/experimental.js +124 -0
  254. package/node_modules/@babel/types/lib/definitions/experimental.js.map +1 -0
  255. package/node_modules/@babel/types/lib/definitions/flow.js +495 -0
  256. package/node_modules/@babel/types/lib/definitions/flow.js.map +1 -0
  257. package/node_modules/@babel/types/lib/definitions/index.js +106 -0
  258. package/node_modules/@babel/types/lib/definitions/index.js.map +1 -0
  259. package/node_modules/@babel/types/lib/definitions/jsx.js +157 -0
  260. package/node_modules/@babel/types/lib/definitions/jsx.js.map +1 -0
  261. package/node_modules/@babel/types/lib/definitions/misc.js +31 -0
  262. package/node_modules/@babel/types/lib/definitions/misc.js.map +1 -0
  263. package/node_modules/@babel/types/lib/definitions/placeholders.js +27 -0
  264. package/node_modules/@babel/types/lib/definitions/placeholders.js.map +1 -0
  265. package/node_modules/@babel/types/lib/definitions/typescript.js +528 -0
  266. package/node_modules/@babel/types/lib/definitions/typescript.js.map +1 -0
  267. package/node_modules/@babel/types/lib/definitions/utils.js +296 -0
  268. package/node_modules/@babel/types/lib/definitions/utils.js.map +1 -0
  269. package/node_modules/@babel/types/lib/index-legacy.d.ts +2797 -0
  270. package/node_modules/@babel/types/lib/index.d.ts +3617 -0
  271. package/node_modules/@babel/types/lib/index.js +582 -0
  272. package/node_modules/@babel/types/lib/index.js.flow +2650 -0
  273. package/node_modules/@babel/types/lib/index.js.map +1 -0
  274. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js +15 -0
  275. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js.map +1 -0
  276. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js +65 -0
  277. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js.map +1 -0
  278. package/node_modules/@babel/types/lib/modifications/inherits.js +28 -0
  279. package/node_modules/@babel/types/lib/modifications/inherits.js.map +1 -0
  280. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js +17 -0
  281. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js.map +1 -0
  282. package/node_modules/@babel/types/lib/modifications/removeProperties.js +24 -0
  283. package/node_modules/@babel/types/lib/modifications/removeProperties.js.map +1 -0
  284. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js +14 -0
  285. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js.map +1 -0
  286. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js +66 -0
  287. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js.map +1 -0
  288. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js +48 -0
  289. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js.map +1 -0
  290. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js +102 -0
  291. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js.map +1 -0
  292. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js +63 -0
  293. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js.map +1 -0
  294. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js +13 -0
  295. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js.map +1 -0
  296. package/node_modules/@babel/types/lib/traverse/traverse.js +50 -0
  297. package/node_modules/@babel/types/lib/traverse/traverse.js.map +1 -0
  298. package/node_modules/@babel/types/lib/traverse/traverseFast.js +40 -0
  299. package/node_modules/@babel/types/lib/traverse/traverseFast.js.map +1 -0
  300. package/node_modules/@babel/types/lib/utils/deprecationWarning.js +44 -0
  301. package/node_modules/@babel/types/lib/utils/deprecationWarning.js.map +1 -0
  302. package/node_modules/@babel/types/lib/utils/inherit.js +13 -0
  303. package/node_modules/@babel/types/lib/utils/inherit.js.map +1 -0
  304. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js +40 -0
  305. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js.map +1 -0
  306. package/node_modules/@babel/types/lib/utils/shallowEqual.js +17 -0
  307. package/node_modules/@babel/types/lib/utils/shallowEqual.js.map +1 -0
  308. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js +13 -0
  309. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js.map +1 -0
  310. package/node_modules/@babel/types/lib/validators/generated/index.js +2797 -0
  311. package/node_modules/@babel/types/lib/validators/generated/index.js.map +1 -0
  312. package/node_modules/@babel/types/lib/validators/is.js +27 -0
  313. package/node_modules/@babel/types/lib/validators/is.js.map +1 -0
  314. package/node_modules/@babel/types/lib/validators/isBinding.js +27 -0
  315. package/node_modules/@babel/types/lib/validators/isBinding.js.map +1 -0
  316. package/node_modules/@babel/types/lib/validators/isBlockScoped.js +13 -0
  317. package/node_modules/@babel/types/lib/validators/isBlockScoped.js.map +1 -0
  318. package/node_modules/@babel/types/lib/validators/isImmutable.js +21 -0
  319. package/node_modules/@babel/types/lib/validators/isImmutable.js.map +1 -0
  320. package/node_modules/@babel/types/lib/validators/isLet.js +13 -0
  321. package/node_modules/@babel/types/lib/validators/isLet.js.map +1 -0
  322. package/node_modules/@babel/types/lib/validators/isNode.js +12 -0
  323. package/node_modules/@babel/types/lib/validators/isNode.js.map +1 -0
  324. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js +57 -0
  325. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js.map +1 -0
  326. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js +15 -0
  327. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js.map +1 -0
  328. package/node_modules/@babel/types/lib/validators/isReferenced.js +96 -0
  329. package/node_modules/@babel/types/lib/validators/isReferenced.js.map +1 -0
  330. package/node_modules/@babel/types/lib/validators/isScope.js +18 -0
  331. package/node_modules/@babel/types/lib/validators/isScope.js.map +1 -0
  332. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js +14 -0
  333. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js.map +1 -0
  334. package/node_modules/@babel/types/lib/validators/isType.js +17 -0
  335. package/node_modules/@babel/types/lib/validators/isType.js.map +1 -0
  336. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js +13 -0
  337. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js.map +1 -0
  338. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js +18 -0
  339. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js.map +1 -0
  340. package/node_modules/@babel/types/lib/validators/isVar.js +15 -0
  341. package/node_modules/@babel/types/lib/validators/isVar.js.map +1 -0
  342. package/node_modules/@babel/types/lib/validators/matchesPattern.js +44 -0
  343. package/node_modules/@babel/types/lib/validators/matchesPattern.js.map +1 -0
  344. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js +11 -0
  345. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js.map +1 -0
  346. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js +11 -0
  347. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js.map +1 -0
  348. package/node_modules/@babel/types/lib/validators/validate.js +42 -0
  349. package/node_modules/@babel/types/lib/validators/validate.js.map +1 -0
  350. package/node_modules/@babel/types/package.json +39 -0
  351. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +13 -2
  352. package/node_modules/@code-yeongyu/senpi-codemode/README.md +128 -78
  353. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -3
  354. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +22 -9
  355. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/reserved.ts +9 -0
  356. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +197 -0
  357. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +96 -0
  358. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/schema-injection.ts +3 -0
  359. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/handler.ts +95 -26
  360. package/node_modules/@code-yeongyu/senpi-codemode/src/completion/tool-bridge.ts +14 -2
  361. package/node_modules/@code-yeongyu/senpi-codemode/src/config/settings.ts +96 -8
  362. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +92 -10
  363. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +187 -27
  364. package/node_modules/@code-yeongyu/senpi-codemode/src/interpreters/detect.ts +1 -1
  365. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +252 -48
  366. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +263 -83
  367. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +198 -149
  368. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker-entry.js +23 -0
  369. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +4 -175
  370. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +38 -0
  371. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/local-module-loader.ts +108 -0
  372. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +8 -6
  373. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/rewrite-imports.ts +164 -0
  374. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/run-queue.ts +82 -0
  375. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +13 -4
  376. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-host.ts +117 -0
  377. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +307 -41
  378. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +32 -0
  379. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +232 -199
  380. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +792 -79
  381. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/process.ts +119 -0
  382. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +237 -0
  383. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +234 -21
  384. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/runner.rb +154 -51
  385. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +22 -0
  386. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +214 -189
  387. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-process.ts +174 -0
  388. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +101 -0
  389. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-run.ts +98 -0
  390. package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +89 -0
  391. package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output.ts +296 -0
  392. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +107 -30
  393. package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/bridge-timeout.ts +2 -0
  394. package/node_modules/@code-yeongyu/senpi-codemode/src/timeouts/idle-timeout.ts +8 -19
  395. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +267 -0
  396. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +226 -211
  397. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +274 -0
  398. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/json-tree.ts +247 -0
  399. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +828 -35
  400. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +12 -0
  401. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +30 -1
  402. package/node_modules/@earendil-works/pi-agent-core/README.md +1 -1
  403. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -0
  404. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  405. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +4 -3
  406. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  407. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  408. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  409. package/node_modules/@earendil-works/pi-ai/README.md +4 -2
  410. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +89 -40
  412. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts +1 -1
  414. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  416. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  417. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +7 -7
  418. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +1 -1
  420. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +10 -3
  422. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +1 -1
  424. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +5 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +3 -1
  428. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  429. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +35 -4
  430. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  431. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +1 -1
  432. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +7 -3
  434. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +8 -3
  437. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +4 -3
  440. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/compat.js +2 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +483 -61
  446. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  447. package/node_modules/@earendil-works/pi-ai/dist/models.js +13 -4
  448. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  450. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +5 -1
  451. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  452. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +62 -5
  453. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  454. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +32 -20
  455. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
  456. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +11 -1
  457. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
  458. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +6 -4
  459. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
  460. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts +7 -8
  461. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  462. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js +20 -21
  463. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js.map +1 -1
  464. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +11 -1
  465. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  466. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +6 -4
  467. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  468. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.d.ts.map +1 -1
  469. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js +9 -6
  470. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-auth.js.map +1 -1
  471. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts +2 -2
  472. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts.map +1 -1
  473. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js +2 -2
  474. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js.map +1 -1
  475. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts +2 -2
  476. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts.map +1 -1
  477. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js +2 -2
  478. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js.map +1 -1
  479. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +100 -2
  480. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  481. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +64 -5
  482. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  483. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts +56 -0
  484. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts.map +1 -1
  485. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js +20 -9
  486. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js.map +1 -1
  487. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts +77 -8
  488. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts.map +1 -1
  489. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js +37 -24
  490. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js.map +1 -1
  491. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +3 -3
  492. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
  493. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +3 -3
  494. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
  495. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +80 -4
  496. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  497. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +64 -8
  498. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  499. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +25 -22
  500. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  501. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +68 -83
  502. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  503. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +45 -1
  504. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  505. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +49 -13
  506. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  507. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts +1 -1
  508. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  509. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js +1 -1
  510. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js.map +1 -1
  511. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts +1 -1
  512. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts.map +1 -1
  513. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js +1 -1
  514. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js.map +1 -1
  515. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +30 -7
  516. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  517. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  518. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts +9 -0
  519. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.d.ts.map +1 -0
  520. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js +36 -0
  521. package/node_modules/@earendil-works/pi-ai/dist/utils/deferred-tools.js.map +1 -0
  522. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts +3 -3
  523. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts.map +1 -1
  524. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js +35 -14
  525. package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js.map +1 -1
  526. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  527. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  528. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -1
  529. package/node_modules/@earendil-works/pi-tui/dist/components/image.js +2 -1
  530. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -1
  531. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -1
  532. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  533. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -1
  534. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  535. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +1 -1
  536. package/node_modules/@earendil-works/pi-tui/dist/keys.js +6 -5
  537. package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +1 -1
  538. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
  539. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  540. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -9
  541. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  542. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts +4 -0
  543. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.d.ts.map +1 -0
  544. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js +18 -0
  545. package/node_modules/@earendil-works/pi-tui/dist/terminal-text.js.map +1 -0
  546. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  547. package/package.json +6 -6
@@ -1,241 +1,266 @@
1
- import type { ChildProcessWithoutNullStreams } from "node:child_process";
2
- import { spawn as nodeSpawn } from "node:child_process";
3
- import { createInterface } from "node:readline";
4
- import type { BridgeConnectionConfig, HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
5
- import { decodeBridgeFrame, encodeBridgeFrame } from "../../bridge/protocol.ts";
6
-
7
- export interface KernelRunInput {
8
- readonly cellId: string;
9
- readonly code: string;
10
- readonly timeoutMs?: number;
11
- }
12
-
13
- export type KernelResult = Extract<KernelToHostMessage, { type: "result" }>;
14
- export type ToolCallMessage = Extract<KernelToHostMessage, { type: "tool-call" }>;
1
+ import type { HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
2
+ import { decodeBridgeFrame, encodeBridgeFrame, isKernelToHostMessage } from "../../bridge/protocol.ts";
3
+ import type { KernelResult, KernelRunInput, SubprocessKernelOptions, ToolCallMessage } from "./subprocess-contract.ts";
4
+ import { type SubprocessLike, SubprocessProcess, type SubprocessSpawn, spawnSubprocess } from "./subprocess-process.ts";
5
+ import { SubprocessRunQueue } from "./subprocess-queue.ts";
6
+ import {
7
+ CellInterruptedError,
8
+ failureResult,
9
+ KernelClosedError,
10
+ KernelClosingError,
11
+ KernelExitedError,
12
+ KernelProcessError,
13
+ KernelResetError,
14
+ KernelRetirementError,
15
+ KernelStartupError,
16
+ type PendingRun,
17
+ timeoutResult,
18
+ } from "./subprocess-run.ts";
15
19
 
16
- export interface SubprocessLike {
17
- readonly pid?: number;
18
- readonly stdin: { write(chunk: string): unknown };
19
- readonly stdout: NodeJS.ReadableStream;
20
- readonly stderr: NodeJS.ReadableStream;
21
- once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
22
- kill(signal?: NodeJS.Signals): boolean;
23
- }
24
-
25
- export type SubprocessSpawn = (
26
- command: string,
27
- args: readonly string[],
28
- options: { readonly cwd?: string; readonly env?: NodeJS.ProcessEnv },
29
- ) => SubprocessLike;
30
-
31
- export interface SubprocessKernelOptions {
32
- readonly command: string;
33
- readonly args: readonly string[];
34
- readonly cwd?: string;
35
- readonly env?: NodeJS.ProcessEnv;
36
- readonly sessionId: string;
37
- readonly connection: BridgeConnectionConfig;
38
- readonly spawn?: SubprocessSpawn;
39
- readonly onMessage?: (message: KernelToHostMessage) => void;
40
- }
20
+ export type { KernelResult, KernelRunInput, SubprocessKernelOptions, ToolCallMessage } from "./subprocess-contract.ts";
21
+ export type { SubprocessLike, SubprocessSpawn };
41
22
 
42
23
  export class SubprocessKernel {
43
- private process!: SubprocessLike;
44
24
  private readonly options: SubprocessKernelOptions;
45
25
  private readonly onMessage?: (message: KernelToHostMessage) => void;
46
- private readonly processes = new Set<SubprocessLike>();
47
- private readonly exitPromises = new WeakMap<SubprocessLike, Promise<void>>();
48
- private readonly terminatingProcesses = new WeakSet<SubprocessLike>();
49
- private readonly pendingRuns = new Map<
50
- string,
51
- { readonly resolve: (message: KernelResult) => void; readonly timer: NodeJS.Timeout | null }
52
- >();
53
- private readonly retiringProcesses = new WeakSet<SubprocessLike>();
54
- private readonly pendingCalls: ToolCallMessage[] = [];
55
- private readonly callWaiters: ((message: ToolCallMessage) => void)[] = [];
26
+ private readonly runs = new SubprocessRunQueue();
27
+ private process: SubprocessProcess | null = null;
28
+ private retirementPromise: Promise<void> | null = null;
29
+ private retirementProcess: SubprocessProcess | null = null;
30
+ private retirementFailure: Error | null = null;
31
+ private failure: Error | null = null;
56
32
  private closed = false;
57
33
 
58
34
  constructor(options: SubprocessKernelOptions) {
59
35
  this.options = options;
60
36
  this.onMessage = options.onMessage;
61
- this.process = this.spawnProcess();
37
+ this.spawnProcess();
62
38
  }
63
39
 
64
40
  run(input: KernelRunInput): Promise<KernelResult> {
65
- if (this.closed) throw new Error("Kernel is closed");
66
- const message: HostToKernelMessage = {
67
- type: "run",
68
- cellId: input.cellId,
69
- code: input.code,
70
- timeoutMs: input.timeoutMs,
71
- };
72
- this.send(message);
73
- return new Promise((resolve) => {
74
- const timeoutMs = input.timeoutMs;
75
- const timer =
76
- timeoutMs === undefined
77
- ? null
78
- : setTimeout(() => {
79
- this.pendingRuns.delete(input.cellId);
80
- resolve({
81
- type: "result",
82
- cellId: input.cellId,
83
- ok: false,
84
- error: { message: `Cell timed out after ${timeoutMs}ms` },
85
- durationMs: timeoutMs,
86
- });
87
- this.restartProcess();
88
- }, timeoutMs);
89
- this.pendingRuns.set(input.cellId, { resolve, timer });
90
- });
41
+ if (this.closed) throw new KernelClosedError();
42
+ const run = this.runs.enqueue(input);
43
+ this.pumpRuns();
44
+ return run;
45
+ }
46
+
47
+ async interrupt(reason = "interrupted"): Promise<void> {
48
+ if (this.closed) return;
49
+ if (!this.runs.active) {
50
+ if (!this.retirementPromise) return;
51
+ const queued = this.runs.takeWaiting();
52
+ if (queued) this.runs.settle(queued, failureResult(queued, new CellInterruptedError(reason)));
53
+ return;
54
+ }
55
+ const process = this.process;
56
+ process?.retire();
57
+ this.runs.clearToolCalls();
58
+ const run = this.runs.active;
59
+ if (!run) return;
60
+ this.runs.releaseActive(run);
61
+ this.runs.settle(run, failureResult(run, new CellInterruptedError(reason)));
62
+ const signal = globalThis.process.platform === "win32" ? "SIGTERM" : "SIGINT";
63
+ await this.restartProcess(process, signal, 5_000);
64
+ if (this.failure) throw this.failure;
91
65
  }
92
66
 
93
67
  nextToolCall(): Promise<ToolCallMessage> {
94
- const queued = this.pendingCalls.shift();
95
- if (queued !== undefined) return Promise.resolve(queued);
96
- return new Promise((resolve) => this.callWaiters.push(resolve));
68
+ return this.runs.nextToolCall();
97
69
  }
98
70
 
99
71
  deliverToolReply(message: Extract<HostToKernelMessage, { type: "tool-reply" }>): void {
100
- this.send(message);
72
+ this.process?.send(encodeBridgeFrame(message));
101
73
  }
102
74
 
103
75
  async reset(): Promise<void> {
104
- this.restartProcess();
105
- this.pendingRuns.clear();
106
- this.pendingCalls.length = 0;
107
- this.callWaiters.length = 0;
76
+ if (this.closed) throw new KernelClosedError();
77
+ this.settleAll(new KernelResetError());
78
+ this.runs.clearToolCalls();
79
+ await this.restartProcess(this.process);
80
+ if (this.failure) throw this.failure;
108
81
  }
109
82
 
110
83
  async close(): Promise<void> {
111
- if (this.closed) return;
84
+ const wasClosed = this.closed;
112
85
  this.closed = true;
113
- this.send({ type: "close" });
114
- await Promise.all([...this.processes].map((process) => this.terminateProcess(process)));
115
- }
116
-
117
- private attachReaders(): void {
118
- const activeProcess = this.process;
119
- this.processes.add(activeProcess);
120
- const exitPromise = new Promise<void>((resolve) => {
121
- activeProcess.once("exit", () => {
122
- this.processes.delete(activeProcess);
123
- resolve();
124
- });
125
- });
126
- this.exitPromises.set(activeProcess, exitPromise);
127
- const stdout = createInterface({ input: this.process.stdout });
128
- stdout.on("line", (line) => {
129
- if (this.process !== activeProcess) return;
130
- this.handleLine(`${line}\n`);
131
- });
132
- this.process.stderr.on("data", (chunk) => {
133
- if (this.process !== activeProcess) return;
134
- this.handleMessage({ type: "text", stream: "stderr", data: String(chunk) });
135
- });
136
- this.process.once("exit", (code, signal) => {
137
- if (this.retiringProcesses.has(activeProcess)) return;
138
- if (this.process !== activeProcess) return;
139
- this.closed = true;
140
- const error = { message: `Kernel exited before completing the cell (${signal ?? code ?? "unknown"})` };
141
- for (const [cellId, pending] of this.pendingRuns) {
142
- if (pending.timer) clearTimeout(pending.timer);
143
- pending.resolve({ type: "result", cellId, ok: false, error, durationMs: 0 });
144
- }
145
- this.pendingRuns.clear();
86
+ if (!wasClosed) {
87
+ this.settleAll(new KernelClosingError());
88
+ this.runs.clearToolCalls();
89
+ }
90
+ if (this.retirementPromise) {
91
+ await this.retirementPromise;
92
+ if (this.retirementFailure) throw this.retirementFailure;
93
+ return;
94
+ }
95
+ const process = this.process;
96
+ if (!process) return;
97
+ const closeFrame = wasClosed ? undefined : encodeBridgeFrame({ type: "close" });
98
+ if (!(await process.shutdown(closeFrame))) {
99
+ const error = new KernelRetirementError();
100
+ this.retirementFailure = error;
101
+ throw error;
102
+ }
103
+ if (this.process === process) this.process = null;
104
+ this.retirementFailure = null;
105
+ }
106
+
107
+ private pumpRuns(): void {
108
+ const process = this.process;
109
+ if (this.closed || this.runs.active || !process || process.isRetiring) return;
110
+ const run = this.runs.startNext(performance.now());
111
+ if (!run) return;
112
+ const timeoutMs = run.input.timeoutMs;
113
+ if (timeoutMs !== undefined) run.timer = setTimeout(() => this.handleTimeout(run, timeoutMs), timeoutMs);
114
+ try {
115
+ process.send(encodeBridgeFrame({ type: "run", cellId: run.input.cellId, code: run.input.code, timeoutMs }));
116
+ } catch (error) {
117
+ this.failClosed(new KernelProcessError(error instanceof Error ? error.message : String(error)));
118
+ }
119
+ }
120
+
121
+ private handleTimeout(run: PendingRun, timeoutMs: number): void {
122
+ if (this.runs.active !== run || run.settled) return;
123
+ const process = this.process;
124
+ process?.retire();
125
+ this.runs.clearToolCalls();
126
+ this.runs.releaseActive(run);
127
+ this.runs.settle(run, timeoutResult(run, timeoutMs));
128
+ void this.restartProcess(process);
129
+ }
130
+
131
+ private spawnProcess(): void {
132
+ const child = spawnSubprocess(this.options.spawn, this.options);
133
+ const process = new SubprocessProcess(child, {
134
+ onLine: (source, line) => this.handleLine(source, line),
135
+ onStderr: (source, data) => this.handleMessage(source, { type: "text", stream: "stderr", data }),
136
+ onExit: (source, code, signal) => this.handleExit(source, code, signal),
137
+ onError: (source, error) => {
138
+ if (this.accepts(source)) this.failClosed(new KernelProcessError(error.message));
139
+ },
146
140
  });
141
+ this.process = process;
142
+ try {
143
+ process.send(
144
+ encodeBridgeFrame({ type: "init", sessionId: this.options.sessionId, connection: this.options.connection }),
145
+ );
146
+ } catch (error) {
147
+ const failure = new KernelStartupError(error instanceof Error ? error.message : String(error));
148
+ this.failClosed(failure);
149
+ throw failure;
150
+ }
147
151
  }
148
152
 
149
- private handleLine(line: string): void {
153
+ private handleLine(process: SubprocessProcess, line: string): void {
154
+ if (!this.accepts(process)) return;
150
155
  const decoded = decodeBridgeFrame(line);
151
156
  if (!decoded.ok) {
152
- this.handleMessage({ type: "text", stream: "stderr", data: `${decoded.error.message}\n` });
157
+ this.handleMessage(process, { type: "text", stream: "stderr", data: `${decoded.error.message}\n` });
153
158
  return;
154
159
  }
155
- this.handleMessage(decoded.message as KernelToHostMessage);
160
+ if (isKernelToHostMessage(decoded.message)) this.handleMessage(process, decoded.message);
156
161
  }
157
162
 
158
- private handleMessage(message: KernelToHostMessage): void {
159
- this.onMessage?.(message);
160
- if (message.type === "tool-call") {
161
- const waiter = this.callWaiters.shift();
162
- if (waiter) waiter(message);
163
- else this.pendingCalls.push(message);
164
- return;
165
- }
166
- if (message.type === "result") {
167
- const pending = this.pendingRuns.get(message.cellId);
168
- if (pending?.timer) clearTimeout(pending.timer);
169
- pending?.resolve(message);
170
- this.pendingRuns.delete(message.cellId);
171
- }
163
+ private handleMessage(process: SubprocessProcess, message: KernelToHostMessage): void {
164
+ if (!this.accepts(process)) return;
165
+ if (this.runs.handleMessage(message, this.onMessage)) this.pumpRuns();
172
166
  }
173
167
 
174
- private send(message: HostToKernelMessage): void {
175
- this.process.stdin.write(encodeBridgeFrame(message));
168
+ private handleExit(process: SubprocessProcess, code: number | null, signal: NodeJS.Signals | null): void {
169
+ if (this.process !== process) return;
170
+ if (process.isRetiring) {
171
+ this.process = null;
172
+ this.retirementFailure = null;
173
+ return;
174
+ }
175
+ this.process = null;
176
+ this.failClosed(new KernelExitedError(signal ?? code ?? "unknown"));
176
177
  }
177
178
 
178
- private restartProcess(): void {
179
- const activeProcess = this.process;
180
- this.retiringProcesses.add(activeProcess);
181
- this.process = this.spawnProcess();
182
- void this.terminateProcess(activeProcess);
179
+ private accepts(process: SubprocessProcess): boolean {
180
+ return !this.closed && this.process === process && !process.isRetiring;
183
181
  }
184
182
 
185
- private spawnProcess(): SubprocessLike {
186
- const spawn = this.options.spawn ?? defaultSpawn;
187
- this.closed = false;
188
- const child = spawn(this.options.command, this.options.args, { cwd: this.options.cwd, env: this.options.env });
189
- this.process = child;
190
- this.attachReaders();
191
- this.send({ type: "init", sessionId: this.options.sessionId, connection: this.options.connection });
192
- return child;
183
+ private restartProcess(
184
+ process: SubprocessProcess | null,
185
+ initialSignal: NodeJS.Signals = "SIGTERM",
186
+ escalationMs = 1_500,
187
+ ): Promise<void> {
188
+ if (!process || this.closed) return Promise.resolve();
189
+ if (this.retirementPromise) return this.retirementPromise;
190
+ process.retire();
191
+ const retirement = this.replaceAfterRetirement(process, initialSignal, escalationMs);
192
+ return this.trackRetirement(process, retirement);
193
193
  }
194
194
 
195
- private async terminateProcess(process: SubprocessLike): Promise<void> {
196
- if (!this.terminatingProcesses.has(process)) {
197
- this.terminatingProcesses.add(process);
198
- this.killProcess(process, "SIGTERM");
195
+ private async replaceAfterRetirement(
196
+ process: SubprocessProcess,
197
+ initialSignal: NodeJS.Signals,
198
+ escalationMs: number,
199
+ ): Promise<void> {
200
+ const termination = await process.terminateSafely(initialSignal, escalationMs);
201
+ if (!termination.ok) {
202
+ const error = new KernelProcessError(termination.error.message);
203
+ this.retirementFailure = error;
204
+ this.failClosed(error);
205
+ return;
199
206
  }
200
- const exitPromise = this.exitPromises.get(process);
201
- if (!exitPromise) return;
202
- let forceTimer: NodeJS.Timeout | undefined;
207
+ if (!termination.exited) {
208
+ const error = new KernelRetirementError();
209
+ this.retirementFailure = error;
210
+ this.failClosed(error);
211
+ return;
212
+ }
213
+ if (this.process === process) this.process = null;
214
+ this.retirementFailure = null;
215
+ if (this.closed) return;
203
216
  try {
204
- await Promise.race([
205
- exitPromise,
206
- new Promise<void>((resolve) => {
207
- forceTimer = setTimeout(() => {
208
- this.killProcess(process, "SIGKILL");
209
- resolve();
210
- }, 1_500);
211
- }),
212
- ]);
213
- await exitPromise;
214
- } finally {
215
- if (forceTimer) clearTimeout(forceTimer);
217
+ this.spawnProcess();
218
+ } catch (error) {
219
+ if (!(error instanceof KernelStartupError)) {
220
+ this.failClosed(new KernelStartupError(error instanceof Error ? error.message : String(error)));
221
+ }
222
+ return;
216
223
  }
224
+ this.pumpRuns();
225
+ }
226
+
227
+ private settleAll(error: Error): void {
228
+ this.runs.settleAll(error);
229
+ }
230
+
231
+ private failClosed(error: Error): void {
232
+ const process = this.process;
233
+ this.failure = error;
234
+ this.closed = true;
235
+ process?.retire();
236
+ this.runs.clearToolCalls();
237
+ this.settleAll(error);
238
+ if (!process || this.retirementProcess === process) return;
239
+ this.trackRetirement(process, this.terminateOwnedProcess(process));
217
240
  }
218
241
 
219
- private killProcess(process: SubprocessLike, signal: NodeJS.Signals): void {
220
- if (process.pid !== undefined) {
221
- try {
222
- globalThis.process.kill(-process.pid, signal);
223
- return;
224
- } catch {}
242
+ private async terminateOwnedProcess(process: SubprocessProcess): Promise<void> {
243
+ const termination = await process.terminateSafely();
244
+ if (!termination.ok) {
245
+ this.retirementFailure = new KernelProcessError(termination.error.message);
246
+ return;
247
+ }
248
+ if (!termination.exited) {
249
+ this.retirementFailure = new KernelRetirementError();
250
+ return;
225
251
  }
226
- process.kill(signal);
252
+ if (this.process === process) this.process = null;
253
+ this.retirementFailure = null;
227
254
  }
228
- }
229
255
 
230
- function defaultSpawn(
231
- command: string,
232
- args: readonly string[],
233
- options: { readonly cwd?: string; readonly env?: NodeJS.ProcessEnv },
234
- ): SubprocessLike {
235
- return nodeSpawn(command, [...args], {
236
- cwd: options.cwd,
237
- detached: true,
238
- env: options.env,
239
- stdio: "pipe",
240
- }) as ChildProcessWithoutNullStreams;
256
+ private trackRetirement(process: SubprocessProcess, retirement: Promise<void>): Promise<void> {
257
+ this.retirementProcess = process;
258
+ this.retirementPromise = retirement;
259
+ void retirement.then(() => {
260
+ if (this.retirementPromise !== retirement) return;
261
+ this.retirementPromise = null;
262
+ this.retirementProcess = null;
263
+ });
264
+ return retirement;
265
+ }
241
266
  }
@@ -0,0 +1,174 @@
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
+ import { createInterface, type Interface as ReadlineInterface } from "node:readline";
3
+
4
+ export interface SubprocessLike {
5
+ readonly pid?: number;
6
+ readonly stdin: { write(chunk: string): unknown };
7
+ readonly stdout: NodeJS.ReadableStream;
8
+ readonly stderr: NodeJS.ReadableStream;
9
+ on(event: "error", listener: (error: Error) => void): this;
10
+ once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
11
+ removeListener(event: "error", listener: (error: Error) => void): this;
12
+ kill(signal?: NodeJS.Signals): boolean;
13
+ }
14
+
15
+ export type SubprocessSpawn = (
16
+ command: string,
17
+ args: readonly string[],
18
+ options: { readonly cwd?: string; readonly env?: NodeJS.ProcessEnv },
19
+ ) => SubprocessLike;
20
+
21
+ export interface SubprocessSpawnRequest {
22
+ readonly command: string;
23
+ readonly args: readonly string[];
24
+ readonly cwd?: string;
25
+ readonly env?: NodeJS.ProcessEnv;
26
+ }
27
+
28
+ interface SubprocessProcessHandlers {
29
+ readonly onLine: (process: SubprocessProcess, line: string) => void;
30
+ readonly onStderr: (process: SubprocessProcess, data: string) => void;
31
+ readonly onExit: (process: SubprocessProcess, code: number | null, signal: NodeJS.Signals | null) => void;
32
+ readonly onError: (process: SubprocessProcess, error: Error) => void;
33
+ }
34
+
35
+ export type SubprocessTermination =
36
+ | { readonly ok: true; readonly exited: boolean }
37
+ | { readonly ok: false; readonly error: Error };
38
+
39
+ const gracefulExitWaitMs = 1_500;
40
+ const forcedExitWaitMs = 500;
41
+
42
+ export class SubprocessProcess {
43
+ readonly child: SubprocessLike;
44
+ private readonly handlers: SubprocessProcessHandlers;
45
+ private readonly exit = Promise.withResolvers<void>();
46
+ private readonly stdoutReader: ReadlineInterface;
47
+ private readonly stderrListener: (chunk: string | Buffer) => void;
48
+ private readonly errorListener: (error: Error) => void;
49
+ private exited = false;
50
+ private retiring = false;
51
+ private outputDetached = false;
52
+ private errorReported = false;
53
+ private terminationPromise: Promise<boolean> | null = null;
54
+
55
+ constructor(child: SubprocessLike, handlers: SubprocessProcessHandlers) {
56
+ this.child = child;
57
+ this.handlers = handlers;
58
+ this.stdoutReader = createInterface({ input: child.stdout });
59
+ this.stderrListener = (chunk) => {
60
+ if (!this.retiring) this.handlers.onStderr(this, String(chunk));
61
+ };
62
+ this.errorListener = (error) => {
63
+ if (this.errorReported) return;
64
+ this.errorReported = true;
65
+ this.handlers.onError(this, error);
66
+ };
67
+ this.stdoutReader.on("line", (line) => {
68
+ if (!this.retiring) this.handlers.onLine(this, `${line}\n`);
69
+ });
70
+ child.stderr.on("data", this.stderrListener);
71
+ child.on("error", this.errorListener);
72
+ child.once("exit", (code, signal) => {
73
+ this.exited = true;
74
+ this.detachOutput();
75
+ child.removeListener("error", this.errorListener);
76
+ this.exit.resolve();
77
+ this.handlers.onExit(this, code, signal);
78
+ });
79
+ }
80
+
81
+ get isRetiring(): boolean {
82
+ return this.retiring;
83
+ }
84
+
85
+ send(frame: string): boolean {
86
+ if (this.retiring) return false;
87
+ this.child.stdin.write(frame);
88
+ return true;
89
+ }
90
+
91
+ retire(): void {
92
+ if (this.retiring) return;
93
+ this.retiring = true;
94
+ this.detachOutput();
95
+ }
96
+
97
+ terminate(initialSignal: NodeJS.Signals = "SIGTERM", escalationMs = gracefulExitWaitMs): Promise<boolean> {
98
+ if (this.exited) return Promise.resolve(true);
99
+ if (this.terminationPromise) return this.terminationPromise;
100
+ this.terminationPromise = this.performTermination(initialSignal, escalationMs);
101
+ return this.terminationPromise;
102
+ }
103
+
104
+ async terminateSafely(initialSignal?: NodeJS.Signals, escalationMs?: number): Promise<SubprocessTermination> {
105
+ try {
106
+ return { ok: true, exited: await this.terminate(initialSignal, escalationMs) };
107
+ } catch (error) {
108
+ return { ok: false, error: error instanceof Error ? error : new Error(String(error)) };
109
+ }
110
+ }
111
+
112
+ async shutdown(frame?: string): Promise<boolean> {
113
+ if (frame !== undefined) {
114
+ try {
115
+ this.send(frame);
116
+ } catch (error) {
117
+ if (!(error instanceof Error)) throw error;
118
+ }
119
+ }
120
+ this.retire();
121
+ return await this.terminate();
122
+ }
123
+
124
+ private async performTermination(initialSignal: NodeJS.Signals, escalationMs: number): Promise<boolean> {
125
+ this.retire();
126
+ if (this.exited) return true;
127
+ this.kill(initialSignal);
128
+ if (await this.waitForExit(escalationMs)) return true;
129
+ this.kill("SIGKILL");
130
+ return await this.waitForExit(forcedExitWaitMs);
131
+ }
132
+
133
+ private async waitForExit(timeoutMs: number): Promise<boolean> {
134
+ if (this.exited) return true;
135
+ let timer: NodeJS.Timeout | undefined;
136
+ const timeout = new Promise<false>((resolve) => {
137
+ timer = setTimeout(() => resolve(false), timeoutMs);
138
+ });
139
+ try {
140
+ return await Promise.race([this.exit.promise.then(() => true as const), timeout]);
141
+ } finally {
142
+ if (timer) clearTimeout(timer);
143
+ }
144
+ }
145
+
146
+ private detachOutput(): void {
147
+ if (this.outputDetached) return;
148
+ this.outputDetached = true;
149
+ this.stdoutReader.close();
150
+ this.child.stderr.removeListener("data", this.stderrListener);
151
+ }
152
+
153
+ private kill(signal: NodeJS.Signals): void {
154
+ if (this.child.pid !== undefined) {
155
+ try {
156
+ globalThis.process.kill(-this.child.pid, signal);
157
+ return;
158
+ } catch (error) {
159
+ if (!(error instanceof Error)) throw error;
160
+ }
161
+ }
162
+ this.child.kill(signal);
163
+ }
164
+ }
165
+
166
+ export function spawnSubprocess(spawn: SubprocessSpawn | undefined, request: SubprocessSpawnRequest): SubprocessLike {
167
+ if (spawn) return spawn(request.command, request.args, { cwd: request.cwd, env: request.env });
168
+ return nodeSpawn(request.command, [...request.args], {
169
+ cwd: request.cwd,
170
+ detached: true,
171
+ env: request.env,
172
+ stdio: ["pipe", "pipe", "pipe"],
173
+ });
174
+ }