@code-yeongyu/senpi 2026.5.29 → 2026.6.3

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 (310) hide show
  1. package/CHANGELOG.md +131 -1
  2. package/README.md +12 -2
  3. package/dist/cli/args.d.ts +3 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +28 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +9 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/core/agent-session-services.d.ts +1 -0
  11. package/dist/core/agent-session-services.d.ts.map +1 -1
  12. package/dist/core/agent-session-services.js +1 -0
  13. package/dist/core/agent-session-services.js.map +1 -1
  14. package/dist/core/agent-session.d.ts +9 -2
  15. package/dist/core/agent-session.d.ts.map +1 -1
  16. package/dist/core/agent-session.js +36 -13
  17. package/dist/core/agent-session.js.map +1 -1
  18. package/dist/core/compaction/branch-summarization.d.ts +3 -1
  19. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  20. package/dist/core/compaction/branch-summarization.js +9 -3
  21. package/dist/core/compaction/branch-summarization.js.map +1 -1
  22. package/dist/core/extensions/index.d.ts +1 -1
  23. package/dist/core/extensions/index.d.ts.map +1 -1
  24. package/dist/core/extensions/index.js.map +1 -1
  25. package/dist/core/extensions/runner.d.ts +5 -3
  26. package/dist/core/extensions/runner.d.ts.map +1 -1
  27. package/dist/core/extensions/runner.js +21 -3
  28. package/dist/core/extensions/runner.js.map +1 -1
  29. package/dist/core/extensions/types.d.ts +14 -6
  30. package/dist/core/extensions/types.d.ts.map +1 -1
  31. package/dist/core/extensions/types.js.map +1 -1
  32. package/dist/core/footer-data-provider.d.ts +2 -0
  33. package/dist/core/footer-data-provider.d.ts.map +1 -1
  34. package/dist/core/footer-data-provider.js +29 -1
  35. package/dist/core/footer-data-provider.js.map +1 -1
  36. package/dist/core/model-registry.d.ts.map +1 -1
  37. package/dist/core/model-registry.js +82 -21
  38. package/dist/core/model-registry.js.map +1 -1
  39. package/dist/core/model-resolver.d.ts.map +1 -1
  40. package/dist/core/model-resolver.js +2 -1
  41. package/dist/core/model-resolver.js.map +1 -1
  42. package/dist/core/provider-attribution.d.ts +4 -0
  43. package/dist/core/provider-attribution.d.ts.map +1 -0
  44. package/dist/core/provider-attribution.js +73 -0
  45. package/dist/core/provider-attribution.js.map +1 -0
  46. package/dist/core/provider-display-names.d.ts.map +1 -1
  47. package/dist/core/provider-display-names.js +1 -0
  48. package/dist/core/provider-display-names.js.map +1 -1
  49. package/dist/core/resolve-config-value.d.ts +9 -1
  50. package/dist/core/resolve-config-value.d.ts.map +1 -1
  51. package/dist/core/resolve-config-value.js +134 -11
  52. package/dist/core/resolve-config-value.js.map +1 -1
  53. package/dist/core/sdk.d.ts +2 -0
  54. package/dist/core/sdk.d.ts.map +1 -1
  55. package/dist/core/sdk.js +18 -40
  56. package/dist/core/sdk.js.map +1 -1
  57. package/dist/core/session-manager.d.ts +6 -7
  58. package/dist/core/session-manager.d.ts.map +1 -1
  59. package/dist/core/session-manager.js +167 -96
  60. package/dist/core/session-manager.js.map +1 -1
  61. package/dist/core/settings-manager.d.ts +3 -1
  62. package/dist/core/settings-manager.d.ts.map +1 -1
  63. package/dist/core/settings-manager.js +15 -11
  64. package/dist/core/settings-manager.js.map +1 -1
  65. package/dist/core/system-prompt.d.ts.map +1 -1
  66. package/dist/core/system-prompt.js +0 -3
  67. package/dist/core/system-prompt.js.map +1 -1
  68. package/dist/core/thinking-levels.d.ts.map +1 -1
  69. package/dist/core/thinking-levels.js +6 -2
  70. package/dist/core/thinking-levels.js.map +1 -1
  71. package/dist/core/tools/edit.d.ts.map +1 -1
  72. package/dist/core/tools/edit.js +7 -10
  73. package/dist/core/tools/edit.js.map +1 -1
  74. package/dist/core/tools/find.d.ts.map +1 -1
  75. package/dist/core/tools/find.js.map +1 -1
  76. package/dist/core/tools/grep.d.ts.map +1 -1
  77. package/dist/core/tools/grep.js.map +1 -1
  78. package/dist/core/tools/ls.d.ts.map +1 -1
  79. package/dist/core/tools/ls.js +5 -7
  80. package/dist/core/tools/ls.js.map +1 -1
  81. package/dist/core/tools/read.d.ts.map +1 -1
  82. package/dist/core/tools/read.js +6 -7
  83. package/dist/core/tools/read.js.map +1 -1
  84. package/dist/core/tools/render-utils.d.ts +5 -2
  85. package/dist/core/tools/render-utils.d.ts.map +1 -1
  86. package/dist/core/tools/render-utils.js +17 -1
  87. package/dist/core/tools/render-utils.js.map +1 -1
  88. package/dist/core/tools/write.d.ts.map +1 -1
  89. package/dist/core/tools/write.js +5 -6
  90. package/dist/core/tools/write.js.map +1 -1
  91. package/dist/index.d.ts +2 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +2 -0
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.d.ts.map +1 -1
  96. package/dist/main.js +76 -16
  97. package/dist/main.js.map +1 -1
  98. package/dist/migrations.d.ts.map +1 -1
  99. package/dist/migrations.js +118 -1
  100. package/dist/migrations.js.map +1 -1
  101. package/dist/modes/interactive/components/login-dialog.d.ts +1 -3
  102. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/login-dialog.js +2 -4
  104. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  105. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/tool-execution.js +25 -1
  107. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  108. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  109. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  110. package/dist/modes/interactive/interactive-mode.js +64 -6
  111. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  112. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  113. package/dist/modes/interactive/theme/theme.js +10 -0
  114. package/dist/modes/interactive/theme/theme.js.map +1 -1
  115. package/dist/modes/print-mode.d.ts.map +1 -1
  116. package/dist/modes/print-mode.js +1 -0
  117. package/dist/modes/print-mode.js.map +1 -1
  118. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  119. package/dist/modes/rpc/rpc-mode.js +4 -1
  120. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  121. package/dist/modes/rpc/rpc-types.d.ts +1 -0
  122. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  123. package/dist/modes/rpc/rpc-types.js.map +1 -1
  124. package/dist/utils/deprecation.d.ts +4 -0
  125. package/dist/utils/deprecation.d.ts.map +1 -0
  126. package/dist/utils/deprecation.js +13 -0
  127. package/dist/utils/deprecation.js.map +1 -0
  128. package/dist/utils/json.d.ts +3 -0
  129. package/dist/utils/json.d.ts.map +1 -0
  130. package/dist/utils/json.js +7 -0
  131. package/dist/utils/json.js.map +1 -0
  132. package/docs/custom-provider.md +13 -10
  133. package/docs/extensions.md +47 -17
  134. package/docs/models.md +25 -12
  135. package/docs/providers.md +15 -5
  136. package/docs/quickstart.md +1 -0
  137. package/docs/rpc.md +3 -2
  138. package/docs/sdk.md +6 -0
  139. package/docs/session-format.md +1 -1
  140. package/docs/sessions.md +8 -0
  141. package/docs/settings.md +4 -2
  142. package/docs/terminal-setup.md +2 -0
  143. package/docs/tui.md +12 -3
  144. package/docs/usage.md +10 -1
  145. package/examples/extensions/README.md +1 -0
  146. package/examples/extensions/custom-header.ts +1 -1
  147. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  148. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  149. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  150. package/examples/extensions/custom-provider-gitlab-duo/index.ts +54 -3
  151. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  152. package/examples/extensions/doom-overlay/index.ts +1 -1
  153. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  154. package/examples/extensions/handoff.ts +1 -1
  155. package/examples/extensions/input-transform-streaming.ts +39 -0
  156. package/examples/extensions/interactive-shell.ts +1 -1
  157. package/examples/extensions/overlay-qa-tests.ts +152 -81
  158. package/examples/extensions/qna.ts +1 -1
  159. package/examples/extensions/question.ts +1 -1
  160. package/examples/extensions/questionnaire.ts +1 -1
  161. package/examples/extensions/sandbox/package-lock.json +2 -2
  162. package/examples/extensions/sandbox/package.json +1 -1
  163. package/examples/extensions/snake.ts +1 -1
  164. package/examples/extensions/space-invaders.ts +1 -1
  165. package/examples/extensions/summarize.ts +1 -1
  166. package/examples/extensions/tic-tac-toe.ts +1 -1
  167. package/examples/extensions/todo.ts +1 -1
  168. package/examples/extensions/tools.ts +5 -0
  169. package/examples/extensions/with-deps/package-lock.json +2 -2
  170. package/examples/extensions/with-deps/package.json +1 -1
  171. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +1 -0
  172. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  173. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +15 -0
  174. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  175. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts +5 -2
  176. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  177. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +81 -18
  178. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  179. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  180. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js +1 -0
  181. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -1
  182. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
  183. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -0
  184. package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
  185. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +1 -0
  186. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  187. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +14 -1
  188. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  189. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +22 -8
  190. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  191. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  192. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  193. package/node_modules/@earendil-works/pi-ai/README.md +5 -3
  194. package/node_modules/@earendil-works/pi-ai/dist/cli.js +0 -0
  195. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -0
  197. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +15 -0
  199. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  200. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +15 -0
  201. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +2 -2
  203. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +1294 -412
  205. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +1278 -652
  207. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/models.js +9 -4
  209. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +89 -21
  213. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +27 -14
  216. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +5 -9
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
  221. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js.map +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/google.d.ts.map +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +5 -3
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js.map +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.d.ts.map +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js +2 -3
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/images/openrouter.js.map +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js +2 -3
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +118 -52
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  236. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +27 -17
  237. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
  238. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts +1 -0
  239. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +5 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  243. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +5 -9
  244. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +1 -0
  247. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.d.ts +7 -0
  249. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.js +8 -4
  251. package/node_modules/@earendil-works/pi-ai/dist/providers/transform-messages.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/stream.d.ts.map +1 -1
  253. package/node_modules/@earendil-works/pi-ai/dist/stream.js +18 -4
  254. package/node_modules/@earendil-works/pi-ai/dist/stream.js.map +1 -1
  255. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +21 -5
  256. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts +6 -0
  259. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.d.ts.map +1 -0
  260. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js +34 -0
  261. package/node_modules/@earendil-works/pi-ai/dist/utils/abort-signals.js.map +1 -0
  262. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts +9 -7
  263. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.d.ts.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js +8 -7
  265. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/device-code.js.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts +10 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +179 -79
  276. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  277. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  278. package/node_modules/@earendil-works/pi-tui/README.md +15 -3
  279. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  280. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +9 -53
  281. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  282. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -1
  283. package/node_modules/@earendil-works/pi-tui/dist/components/input.js +6 -54
  284. package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -1
  285. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  286. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  287. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  288. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +1 -1
  289. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  290. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +34 -7
  291. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  292. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +33 -10
  293. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  294. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +173 -39
  295. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  296. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +18 -3
  297. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  298. package/node_modules/@earendil-works/pi-tui/dist/tui.js +166 -22
  299. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -0
  301. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/utils.js +11 -3
  303. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +25 -0
  305. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +1 -0
  306. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +96 -0
  307. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +1 -0
  308. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  309. package/npm-shrinkwrap.json +56 -56
  310. package/package.json +5 -5
@@ -15,9 +15,9 @@ if (typeof process !== "undefined" && (process.versions?.node || process.version
15
15
  _os = m;
16
16
  });
17
17
  }
18
- import { getEnvApiKey } from "../env-api-keys.js";
19
18
  import { clampThinkingLevel, supportsXhigh } from "../models.js";
20
19
  import { registerSessionResourceCleanup } from "../session-resources.js";
20
+ import { combineAbortSignals } from "../utils/abort-signals.js";
21
21
  import { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic, formatThrownValue, } from "../utils/diagnostics.js";
22
22
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
23
23
  import { headersToRecord } from "../utils/headers.js";
@@ -32,6 +32,8 @@ const JWT_CLAIM_PATH = "https://api.openai.com/auth";
32
32
  const DEFAULT_MAX_RETRIES = 0;
33
33
  const BASE_DELAY_MS = 1000;
34
34
  const DEFAULT_MAX_RETRY_DELAY_MS = 60_000;
35
+ const DEFAULT_SSE_HEADER_TIMEOUT_MS = 10_000;
36
+ const DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS = 15_000;
35
37
  const CODEX_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode"]);
36
38
  const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009;
37
39
  const CODEX_RESPONSE_STATUSES = new Set([
@@ -96,6 +98,27 @@ function sleep(ms, signal) {
96
98
  });
97
99
  });
98
100
  }
101
+ function normalizeTimeoutMs(value) {
102
+ if (value === undefined)
103
+ return undefined;
104
+ if (!Number.isFinite(value) || value < 0) {
105
+ throw new Error(`Invalid timeoutMs: ${String(value)}`);
106
+ }
107
+ return Math.floor(value);
108
+ }
109
+ function createSSEHeaderTimeout() {
110
+ const controller = new AbortController();
111
+ let error;
112
+ const timeout = setTimeout(() => {
113
+ error = new Error(`Codex SSE response headers timed out after ${DEFAULT_SSE_HEADER_TIMEOUT_MS}ms`);
114
+ controller.abort(error);
115
+ }, DEFAULT_SSE_HEADER_TIMEOUT_MS);
116
+ return {
117
+ signal: controller.signal,
118
+ clear: () => clearTimeout(timeout),
119
+ error: () => error,
120
+ };
121
+ }
99
122
  // ============================================================================
100
123
  // Main Stream Function
101
124
  // ============================================================================
@@ -120,7 +143,7 @@ export const streamOpenAICodexResponses = (model, context, options) => {
120
143
  timestamp: Date.now(),
121
144
  };
122
145
  try {
123
- const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
146
+ const apiKey = options?.apiKey;
124
147
  if (!apiKey) {
125
148
  throw new Error(`No API key for provider: ${model.provider}`);
126
149
  }
@@ -134,6 +157,8 @@ export const streamOpenAICodexResponses = (model, context, options) => {
134
157
  const sseHeaders = buildSSEHeaders(model.headers, options?.headers, accountId, apiKey, options?.sessionId);
135
158
  const websocketHeaders = buildWebSocketHeaders(model.headers, options?.headers, accountId, apiKey, websocketRequestId);
136
159
  const bodyJson = JSON.stringify(body);
160
+ const idleTimeoutMs = normalizeTimeoutMs(options?.timeoutMs);
161
+ const websocketConnectTimeoutMs = normalizeTimeoutMs(options?.websocketConnectTimeoutMs);
137
162
  const transport = options?.transport || "auto";
138
163
  const websocketDisabledForSession = transport !== "sse" && isWebSocketSseFallbackActive(options?.sessionId);
139
164
  if (websocketDisabledForSession) {
@@ -144,7 +169,7 @@ export const streamOpenAICodexResponses = (model, context, options) => {
144
169
  try {
145
170
  await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), body, websocketHeaders, output, stream, model, () => {
146
171
  websocketStarted = true;
147
- }, options);
172
+ }, idleTimeoutMs, websocketConnectTimeoutMs, options);
148
173
  if (options?.signal?.aborted) {
149
174
  throw new Error("Request was aborted");
150
175
  }
@@ -184,12 +209,24 @@ export const streamOpenAICodexResponses = (model, context, options) => {
184
209
  throw new Error("Request was aborted");
185
210
  }
186
211
  try {
187
- response = await fetch(resolveCodexUrl(model.baseUrl), {
188
- method: "POST",
189
- headers: sseHeaders,
190
- body: bodyJson,
191
- signal: options?.signal,
192
- });
212
+ const headerTimeout = createSSEHeaderTimeout();
213
+ const combinedSignal = combineAbortSignals([options?.signal, headerTimeout.signal]);
214
+ try {
215
+ response = await fetch(resolveCodexUrl(model.baseUrl), {
216
+ method: "POST",
217
+ headers: sseHeaders,
218
+ body: bodyJson,
219
+ signal: combinedSignal.signal,
220
+ });
221
+ }
222
+ catch (error) {
223
+ const timeoutError = headerTimeout.error();
224
+ throw timeoutError && !options?.signal?.aborted ? timeoutError : error;
225
+ }
226
+ finally {
227
+ combinedSignal.cleanup();
228
+ headerTimeout.clear();
229
+ }
193
230
  await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
194
231
  if (response.ok) {
195
232
  break;
@@ -257,7 +294,7 @@ export const streamOpenAICodexResponses = (model, context, options) => {
257
294
  return stream;
258
295
  };
259
296
  export const streamSimpleOpenAICodexResponses = (model, context, options) => {
260
- const apiKey = options?.apiKey || getEnvApiKey(model.provider);
297
+ const apiKey = options?.apiKey;
261
298
  if (!apiKey) {
262
299
  throw new Error(`No API key for provider: ${model.provider}`);
263
300
  }
@@ -277,6 +314,7 @@ function buildRequestBody(model, context, options) {
277
314
  const messages = convertResponsesMessages(model, context, CODEX_TOOL_CALL_PROVIDERS, {
278
315
  includeSystemPrompt: false,
279
316
  preserveThinking: reasoningRequested,
317
+ preserveTextSignatures: true,
280
318
  });
281
319
  const body = {
282
320
  model: model.id,
@@ -360,7 +398,7 @@ function resolveCodexWebSocketUrl(baseUrl) {
360
398
  // Response Processing
361
399
  // ============================================================================
362
400
  async function processStream(response, output, stream, model, options) {
363
- await processResponsesStream(mapCodexEvents(parseSSE(response)), output, stream, model, {
401
+ await processResponsesStream(mapCodexEvents(parseSSE(response, options?.signal)), output, stream, model, {
364
402
  serviceTier: options?.serviceTier,
365
403
  resolveServiceTier: resolveCodexServiceTier,
366
404
  applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),
@@ -428,15 +466,25 @@ function normalizeCodexStatus(status) {
428
466
  // ============================================================================
429
467
  // SSE Parsing
430
468
  // ============================================================================
431
- async function* parseSSE(response) {
469
+ async function* parseSSE(response, signal) {
432
470
  if (!response.body)
433
471
  return;
434
472
  const reader = response.body.getReader();
435
473
  const decoder = new TextDecoder();
436
474
  let buffer = "";
475
+ const onAbort = () => {
476
+ void reader.cancel().catch(() => { });
477
+ };
478
+ signal?.addEventListener("abort", onAbort, { once: true });
437
479
  try {
438
480
  while (true) {
481
+ if (signal?.aborted) {
482
+ throw new Error("Request was aborted");
483
+ }
439
484
  const { done, value } = await reader.read();
485
+ if (signal?.aborted) {
486
+ throw new Error("Request was aborted");
487
+ }
440
488
  if (done)
441
489
  break;
442
490
  buffer += decoder.decode(value, { stream: true });
@@ -467,6 +515,7 @@ async function* parseSSE(response) {
467
515
  }
468
516
  }
469
517
  finally {
518
+ signal?.removeEventListener("abort", onAbort);
470
519
  try {
471
520
  await reader.cancel();
472
521
  }
@@ -642,7 +691,7 @@ function scheduleSessionWebSocketExpiry(sessionId, entry) {
642
691
  websocketSessionCache.delete(sessionId);
643
692
  }, SESSION_WEBSOCKET_CACHE_TTL_MS);
644
693
  }
645
- async function connectWebSocket(url, headers, signal) {
694
+ async function connectWebSocket(url, headers, signal, connectTimeoutMs = DEFAULT_WEBSOCKET_CONNECT_TIMEOUT_MS) {
646
695
  const WebSocketCtor = await getWebSocketConstructor();
647
696
  if (!WebSocketCtor) {
648
697
  throw new Error("WebSocket transport is not available in this runtime");
@@ -651,6 +700,7 @@ async function connectWebSocket(url, headers, signal) {
651
700
  delete wsHeaders["OpenAI-Beta"];
652
701
  return new Promise((resolve, reject) => {
653
702
  let settled = false;
703
+ let timeout;
654
704
  let socket;
655
705
  try {
656
706
  socket = new WebSocketCtor(url, { headers: wsHeaders });
@@ -659,62 +709,63 @@ async function connectWebSocket(url, headers, signal) {
659
709
  reject(error instanceof Error ? error : new Error(String(error)));
660
710
  return;
661
711
  }
662
- const onOpen = () => {
663
- if (settled)
664
- return;
665
- settled = true;
666
- cleanup();
667
- resolve(socket);
712
+ const cleanup = () => {
713
+ if (timeout) {
714
+ clearTimeout(timeout);
715
+ timeout = undefined;
716
+ }
717
+ socket.removeEventListener("open", onOpen);
718
+ socket.removeEventListener("error", onError);
719
+ socket.removeEventListener("close", onClose);
720
+ signal?.removeEventListener("abort", onAbort);
668
721
  };
669
- const onError = (event) => {
670
- const error = extractWebSocketError(event);
722
+ const fail = (error, closeReason) => {
671
723
  if (settled)
672
724
  return;
673
725
  settled = true;
674
726
  cleanup();
727
+ if (closeReason) {
728
+ closeWebSocketSilently(socket, 1000, closeReason);
729
+ }
675
730
  reject(error);
676
731
  };
677
- const onClose = (event) => {
678
- const error = extractWebSocketCloseError(event);
732
+ const onOpen = () => {
679
733
  if (settled)
680
734
  return;
681
735
  settled = true;
682
736
  cleanup();
683
- reject(error);
737
+ resolve(socket);
684
738
  };
685
- const onAbort = () => {
686
- if (settled)
687
- return;
688
- settled = true;
689
- cleanup();
690
- socket.close(1000, "aborted");
691
- reject(new Error("Request was aborted"));
739
+ const onError = (event) => {
740
+ fail(extractWebSocketError(event));
692
741
  };
693
- const cleanup = () => {
694
- socket.removeEventListener("open", onOpen);
695
- socket.removeEventListener("error", onError);
696
- socket.removeEventListener("close", onClose);
697
- signal?.removeEventListener("abort", onAbort);
742
+ const onClose = (event) => {
743
+ fail(extractWebSocketCloseError(event));
744
+ };
745
+ const onAbort = () => {
746
+ fail(new Error("Request was aborted"), "aborted");
698
747
  };
699
748
  socket.addEventListener("open", onOpen);
700
749
  socket.addEventListener("error", onError);
701
750
  socket.addEventListener("close", onClose);
702
751
  signal?.addEventListener("abort", onAbort);
752
+ if (connectTimeoutMs > 0) {
753
+ timeout = setTimeout(() => {
754
+ fail(new Error(`WebSocket connect timeout after ${connectTimeoutMs}ms`), "connect_timeout");
755
+ }, connectTimeoutMs);
756
+ }
757
+ if (signal?.aborted) {
758
+ onAbort();
759
+ }
703
760
  });
704
761
  }
705
- async function acquireWebSocket(url, headers, sessionId, signal) {
762
+ async function acquireWebSocket(url, headers, sessionId, signal, connectTimeoutMs) {
706
763
  if (!sessionId) {
707
- const socket = await connectWebSocket(url, headers, signal);
764
+ const socket = await connectWebSocket(url, headers, signal, connectTimeoutMs);
708
765
  return {
709
766
  socket,
710
767
  reused: false,
711
- release: ({ keep } = {}) => {
712
- if (keep === false) {
713
- closeWebSocketSilently(socket);
714
- return;
715
- }
716
- closeWebSocketSilently(socket);
717
- },
768
+ release: () => closeWebSocketSilently(socket),
718
769
  };
719
770
  }
720
771
  const cached = websocketSessionCache.get(sessionId);
@@ -741,7 +792,7 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
741
792
  };
742
793
  }
743
794
  if (cached.busy) {
744
- const socket = await connectWebSocket(url, headers, signal);
795
+ const socket = await connectWebSocket(url, headers, signal, connectTimeoutMs);
745
796
  return {
746
797
  socket,
747
798
  reused: false,
@@ -755,7 +806,7 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
755
806
  websocketSessionCache.delete(sessionId);
756
807
  }
757
808
  }
758
- const socket = await connectWebSocket(url, headers, signal);
809
+ const socket = await connectWebSocket(url, headers, signal, connectTimeoutMs);
759
810
  const entry = { socket, busy: true };
760
811
  websocketSessionCache.set(sessionId, entry);
761
812
  return {
@@ -831,7 +882,7 @@ async function decodeWebSocketData(data) {
831
882
  }
832
883
  return null;
833
884
  }
834
- async function* parseWebSocket(socket, signal) {
885
+ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
835
886
  const queue = [];
836
887
  let pending = null;
837
888
  let done = false;
@@ -909,8 +960,23 @@ async function* parseWebSocket(socket, signal) {
909
960
  }
910
961
  if (done)
911
962
  break;
912
- await new Promise((resolve) => {
963
+ let timeout;
964
+ await new Promise((resolve, reject) => {
913
965
  pending = resolve;
966
+ if (idleTimeoutMs !== undefined && idleTimeoutMs > 0) {
967
+ timeout = setTimeout(() => {
968
+ const error = new Error(`WebSocket idle timeout after ${idleTimeoutMs}ms`);
969
+ failed = error;
970
+ done = true;
971
+ pending = null;
972
+ closeWebSocketSilently(socket, 1000, "idle_timeout");
973
+ reject(error);
974
+ }, idleTimeoutMs);
975
+ }
976
+ }).finally(() => {
977
+ if (timeout) {
978
+ clearTimeout(timeout);
979
+ }
914
980
  });
915
981
  }
916
982
  if (failed) {
@@ -979,8 +1045,8 @@ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onStart
979
1045
  yield event;
980
1046
  }
981
1047
  }
982
- async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options) {
983
- const { socket, entry, reused, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
1048
+ async function processWebSocketStream(url, body, headers, output, stream, model, onStart, idleTimeoutMs, websocketConnectTimeoutMs, options) {
1049
+ const { socket, entry, reused, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal, websocketConnectTimeoutMs);
984
1050
  let keepConnection = true;
985
1051
  const useCachedContext = options?.transport === "websocket-cached" || options?.transport === "auto";
986
1052
  // ChatGPT Codex Responses rejects `store: true` ("Store must be set to false").
@@ -1012,7 +1078,7 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
1012
1078
  }
1013
1079
  try {
1014
1080
  socket.send(JSON.stringify({ type: "response.create", ...requestBody }));
1015
- await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal)), output, stream, onStart), output, stream, model, {
1081
+ await processResponsesStream(startWebSocketOutputOnFirstEvent(mapCodexEvents(parseWebSocket(socket, options?.signal, idleTimeoutMs)), output, stream, onStart), output, stream, model, {
1016
1082
  serviceTier: options?.serviceTier,
1017
1083
  resolveServiceTier: resolveCodexServiceTier,
1018
1084
  applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model),