@code-yeongyu/senpi 2026.9.10 → 2026.9.12-2

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 (422) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  3. package/dist/core/agent-session-runtime.js +5 -1
  4. package/dist/core/agent-session-runtime.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +70 -9
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +183 -140
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/auth-storage.d.ts +2 -0
  10. package/dist/core/auth-storage.d.ts.map +1 -1
  11. package/dist/core/auth-storage.js +49 -17
  12. package/dist/core/auth-storage.js.map +1 -1
  13. package/dist/core/brand.d.ts +5 -0
  14. package/dist/core/brand.d.ts.map +1 -1
  15. package/dist/core/brand.js +13 -0
  16. package/dist/core/brand.js.map +1 -1
  17. package/dist/core/changelog-source.d.ts +8 -0
  18. package/dist/core/changelog-source.d.ts.map +1 -0
  19. package/dist/core/changelog-source.js +19 -0
  20. package/dist/core/changelog-source.js.map +1 -0
  21. package/dist/core/credential-accounts.d.ts +3 -0
  22. package/dist/core/credential-accounts.d.ts.map +1 -1
  23. package/dist/core/credential-accounts.js +20 -1
  24. package/dist/core/credential-accounts.js.map +1 -1
  25. package/dist/core/credential-pool/classify.d.ts.map +1 -1
  26. package/dist/core/credential-pool/classify.js +8 -0
  27. package/dist/core/credential-pool/classify.js.map +1 -1
  28. package/dist/core/cursor-history-admission.d.ts +50 -0
  29. package/dist/core/cursor-history-admission.d.ts.map +1 -0
  30. package/dist/core/cursor-history-admission.js +130 -0
  31. package/dist/core/cursor-history-admission.js.map +1 -0
  32. package/dist/core/extensions/builtin/account/index.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/account/index.js +7 -3
  34. package/dist/core/extensions/builtin/account/index.js.map +1 -1
  35. package/dist/core/extensions/builtin/account-display-name.d.ts +7 -0
  36. package/dist/core/extensions/builtin/account-display-name.d.ts.map +1 -0
  37. package/dist/core/extensions/builtin/account-display-name.js +40 -0
  38. package/dist/core/extensions/builtin/account-display-name.js.map +1 -0
  39. package/dist/core/extensions/builtin/ask-user/format.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/ask-user/format.js +7 -2
  41. package/dist/core/extensions/builtin/ask-user/format.js.map +1 -1
  42. package/dist/core/extensions/builtin/ask-user/pending.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/ask-user/pending.js +3 -0
  44. package/dist/core/extensions/builtin/ask-user/pending.js.map +1 -1
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +21 -9
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts +1 -0
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js +11 -6
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js.map +1 -1
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts +9 -0
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js +10 -1
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js.map +1 -1
  56. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +3 -0
  57. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  58. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +19 -10
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
  61. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +3 -9
  63. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -1
  64. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/config-reload/routine-settings.js +1 -0
  66. package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -1
  67. package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +5 -3
  69. package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js.map +1 -1
  70. package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts +1 -0
  71. package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts.map +1 -1
  72. package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.js.map +1 -1
  73. package/dist/core/extensions/builtin/cursor-cli-oauth/models.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/cursor-cli-oauth/models.js +2 -1
  75. package/dist/core/extensions/builtin/cursor-cli-oauth/models.js.map +1 -1
  76. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts.map +1 -1
  77. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js +3 -9
  78. package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js.map +1 -1
  79. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
  80. package/dist/core/extensions/builtin/goal/agent-end-continuation.js +13 -1
  81. package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
  82. package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/goal/prompt.js +11 -8
  84. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
  85. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts +1 -0
  86. package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/goal/terminal-provider-error.js +28 -0
  88. package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
  89. package/dist/core/extensions/builtin/goal/todo-gate.js +2 -2
  90. package/dist/core/extensions/builtin/goal/todo-gate.js.map +1 -1
  91. package/dist/core/extensions/builtin/goal/tool-registration.js +2 -2
  92. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  93. package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
  94. package/dist/core/extensions/builtin/gpt-account.js +19 -8
  95. package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
  96. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts +3 -0
  97. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts.map +1 -0
  98. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js +19 -0
  99. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js.map +1 -0
  100. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +6 -6
  101. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
  102. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +26 -7
  103. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
  104. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  105. package/dist/core/extensions/builtin/prompt-preset/presets.js +29 -0
  106. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  107. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  108. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  110. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  111. package/dist/core/high-reasoning-warning.d.ts.map +1 -1
  112. package/dist/core/high-reasoning-warning.js +5 -1
  113. package/dist/core/high-reasoning-warning.js.map +1 -1
  114. package/dist/core/manual-continue.d.ts +14 -0
  115. package/dist/core/manual-continue.d.ts.map +1 -1
  116. package/dist/core/manual-continue.js +13 -0
  117. package/dist/core/manual-continue.js.map +1 -1
  118. package/dist/core/model-runtime.d.ts.map +1 -1
  119. package/dist/core/model-runtime.js +2 -2
  120. package/dist/core/model-runtime.js.map +1 -1
  121. package/dist/core/remote-catalog-merge.d.ts +16 -0
  122. package/dist/core/remote-catalog-merge.d.ts.map +1 -0
  123. package/dist/core/remote-catalog-merge.js +75 -0
  124. package/dist/core/remote-catalog-merge.js.map +1 -0
  125. package/dist/core/remote-catalog-provider.d.ts +3 -0
  126. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  127. package/dist/core/remote-catalog-provider.js +12 -40
  128. package/dist/core/remote-catalog-provider.js.map +1 -1
  129. package/dist/core/session-entry-materializer.d.ts +12 -0
  130. package/dist/core/session-entry-materializer.d.ts.map +1 -0
  131. package/dist/core/session-entry-materializer.js +26 -0
  132. package/dist/core/session-entry-materializer.js.map +1 -0
  133. package/dist/core/session-manager.d.ts +38 -1
  134. package/dist/core/session-manager.d.ts.map +1 -1
  135. package/dist/core/session-manager.js +60 -21
  136. package/dist/core/session-manager.js.map +1 -1
  137. package/dist/core/session-write-reservation.d.ts +9 -0
  138. package/dist/core/session-write-reservation.d.ts.map +1 -1
  139. package/dist/core/session-write-reservation.js +33 -0
  140. package/dist/core/session-write-reservation.js.map +1 -1
  141. package/dist/core/settings-manager.d.ts +3 -0
  142. package/dist/core/settings-manager.d.ts.map +1 -1
  143. package/dist/core/settings-manager.js +10 -0
  144. package/dist/core/settings-manager.js.map +1 -1
  145. package/dist/modes/app-server/daemon/process.d.ts +6 -1
  146. package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
  147. package/dist/modes/app-server/daemon/process.js +23 -4
  148. package/dist/modes/app-server/daemon/process.js.map +1 -1
  149. package/dist/modes/app-server/protocol/account.d.ts +2 -0
  150. package/dist/modes/app-server/protocol/account.d.ts.map +1 -1
  151. package/dist/modes/app-server/protocol/account.js.map +1 -1
  152. package/dist/modes/interactive/components/ask-user-async-widget.d.ts +2 -0
  153. package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
  154. package/dist/modes/interactive/components/ask-user-async-widget.js +17 -1
  155. package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
  156. package/dist/modes/interactive/components/ask-user-question-keys.d.ts +1 -1
  157. package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
  158. package/dist/modes/interactive/components/ask-user-question-keys.js +65 -17
  159. package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
  160. package/dist/modes/interactive/components/ask-user-question-render.d.ts +2 -1
  161. package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
  162. package/dist/modes/interactive/components/ask-user-question-render.js +39 -9
  163. package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
  164. package/dist/modes/interactive/components/ask-user-question-state.d.ts +14 -4
  165. package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
  166. package/dist/modes/interactive/components/ask-user-question-state.js +63 -6
  167. package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
  168. package/dist/modes/interactive/components/ask-user-question.d.ts +2 -0
  169. package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/ask-user-question.js +27 -14
  171. package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
  172. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  173. package/dist/modes/interactive/components/footer.js +51 -19
  174. package/dist/modes/interactive/components/footer.js.map +1 -1
  175. package/dist/modes/interactive/components/login-dialog.d.ts +11 -0
  176. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  177. package/dist/modes/interactive/components/login-dialog.js +29 -9
  178. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  179. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  180. package/dist/modes/interactive/components/tree-selector.js +7 -0
  181. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  182. package/dist/modes/interactive/help-content.d.ts.map +1 -1
  183. package/dist/modes/interactive/help-content.js +4 -0
  184. package/dist/modes/interactive/help-content.js.map +1 -1
  185. package/dist/modes/interactive/interactive-mode.d.ts +13 -4
  186. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  187. package/dist/modes/interactive/interactive-mode.js +46 -17
  188. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  189. package/dist/modes/interactive/tips/catalog/input-tips.js +1 -1
  190. package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
  191. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  192. package/dist/modes/rpc/connection-handler.js +3 -1
  193. package/dist/modes/rpc/connection-handler.js.map +1 -1
  194. package/dist/modes/rpc/connection-question-bridge.js +1 -1
  195. package/dist/modes/rpc/connection-question-bridge.js.map +1 -1
  196. package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
  197. package/dist/modes/rpc/host-ensure.js +33 -11
  198. package/dist/modes/rpc/host-ensure.js.map +1 -1
  199. package/dist/modes/rpc/host-lifecycle.d.ts +14 -0
  200. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  201. package/dist/modes/rpc/host-lifecycle.js +31 -5
  202. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  203. package/dist/modes/rpc/rpc-input-validation.d.ts.map +1 -1
  204. package/dist/modes/rpc/rpc-input-validation.js +2 -0
  205. package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
  206. package/dist/modes/rpc/rpc-types.d.ts +4 -1
  207. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  208. package/dist/modes/rpc/rpc-types.js +1 -0
  209. package/dist/modes/rpc/rpc-types.js.map +1 -1
  210. package/dist/modes/rpc/session-path-reservations.d.ts +30 -0
  211. package/dist/modes/rpc/session-path-reservations.d.ts.map +1 -0
  212. package/dist/modes/rpc/session-path-reservations.js +58 -0
  213. package/dist/modes/rpc/session-path-reservations.js.map +1 -0
  214. package/dist/modes/rpc/session-registry.d.ts +3 -1
  215. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  216. package/dist/modes/rpc/session-registry.js.map +1 -1
  217. package/dist/modes/rpc/session-worker-client.d.ts +10 -8
  218. package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
  219. package/dist/modes/rpc/session-worker-client.js +14 -23
  220. package/dist/modes/rpc/session-worker-client.js.map +1 -1
  221. package/dist/modes/rpc/session-worker-credit.d.ts +17 -0
  222. package/dist/modes/rpc/session-worker-credit.d.ts.map +1 -0
  223. package/dist/modes/rpc/session-worker-credit.js +39 -0
  224. package/dist/modes/rpc/session-worker-credit.js.map +1 -0
  225. package/dist/modes/rpc/session-worker-protocol.d.ts +10 -0
  226. package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -1
  227. package/dist/modes/rpc/session-worker-protocol.js +2 -0
  228. package/dist/modes/rpc/session-worker-protocol.js.map +1 -1
  229. package/dist/modes/rpc/session-worker-signals.d.ts +7 -0
  230. package/dist/modes/rpc/session-worker-signals.d.ts.map +1 -0
  231. package/dist/modes/rpc/session-worker-signals.js +19 -0
  232. package/dist/modes/rpc/session-worker-signals.js.map +1 -0
  233. package/dist/modes/rpc/session-worker.js +12 -16
  234. package/dist/modes/rpc/session-worker.js.map +1 -1
  235. package/dist/modes/rpc/worker-session-registry.d.ts +12 -0
  236. package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -1
  237. package/dist/modes/rpc/worker-session-registry.js +51 -24
  238. package/dist/modes/rpc/worker-session-registry.js.map +1 -1
  239. package/dist/utils/changelog.d.ts +3 -1
  240. package/dist/utils/changelog.d.ts.map +1 -1
  241. package/dist/utils/changelog.js +89 -23
  242. package/dist/utils/changelog.js.map +1 -1
  243. package/dist/utils/paths.d.ts +5 -0
  244. package/dist/utils/paths.d.ts.map +1 -1
  245. package/dist/utils/paths.js +14 -1
  246. package/dist/utils/paths.js.map +1 -1
  247. package/docs/app-server.md +6 -0
  248. package/docs/extensions.md +19 -3
  249. package/docs/rpc.md +24 -6
  250. package/docs/settings.md +2 -1
  251. package/docs/tui.md +1 -1
  252. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +52 -0
  253. package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -4
  254. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  255. package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output-buffer.ts +58 -0
  256. package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output.ts +9 -64
  257. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +1 -1
  258. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  259. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +11 -0
  260. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -1
  261. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +18 -0
  262. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -1
  263. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
  265. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +5 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts +19 -0
  268. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts.map +1 -0
  269. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js +135 -0
  270. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js.map +1 -0
  271. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts +23 -0
  272. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts.map +1 -0
  273. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js +71 -0
  274. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js.map +1 -0
  275. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts +1261 -0
  276. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts.map +1 -0
  277. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js +431 -0
  278. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js.map +1 -0
  279. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts +42 -0
  280. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts.map +1 -0
  281. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js +68 -0
  282. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js.map +1 -0
  283. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts +43 -0
  284. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts.map +1 -0
  285. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js +43 -0
  286. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js.map +1 -0
  287. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts +36 -0
  288. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts.map +1 -0
  289. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js +158 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js.map +1 -0
  291. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts +26 -0
  292. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts.map +1 -0
  293. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js +145 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js.map +1 -0
  295. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts +16 -0
  296. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts.map +1 -0
  297. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js +69 -0
  298. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js.map +1 -0
  299. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts +12 -0
  300. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts.map +1 -0
  301. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js +3 -0
  302. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js.map +1 -0
  303. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts +26 -0
  304. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts.map +1 -0
  305. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js +61 -0
  306. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js.map +1 -0
  307. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts +8 -0
  308. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts.map +1 -0
  309. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js +8 -0
  310. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js.map +1 -0
  311. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts +22 -0
  312. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts.map +1 -0
  313. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js +217 -0
  314. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js.map +1 -0
  315. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +5 -0
  316. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -0
  317. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +23 -0
  318. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js.map +1 -0
  319. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts +25 -0
  320. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts.map +1 -0
  321. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js +124 -0
  322. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js.map +1 -0
  323. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts +18 -0
  324. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts.map +1 -0
  325. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js +101 -0
  326. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js.map +1 -0
  327. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts +19 -0
  328. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts.map +1 -0
  329. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js +116 -0
  330. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js.map +1 -0
  331. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  332. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js +5 -1
  333. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts +24 -0
  335. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts.map +1 -0
  336. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js +86 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js.map +1 -0
  338. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +2 -0
  339. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -1
  340. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +5 -0
  341. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -1
  342. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +51 -4
  343. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  344. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +196 -7
  345. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  346. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +8 -0
  347. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +10 -0
  349. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  350. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +9 -1
  351. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  352. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  353. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -1
  354. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +2 -0
  355. package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -1
  356. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +1 -0
  357. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  358. package/node_modules/@earendil-works/pi-ai/dist/compat.js +3 -0
  359. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  360. package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts +32 -0
  361. package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts.map +1 -0
  362. package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js +62 -0
  363. package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js.map +1 -0
  364. package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.d.ts.map +1 -1
  365. package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js +2 -1
  366. package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js.map +1 -1
  367. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +4 -4
  368. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  369. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -1
  370. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  371. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -1
  372. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  373. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts +11 -1
  374. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts.map +1 -1
  375. package/node_modules/@earendil-works/pi-ai/dist/model.js.map +1 -1
  376. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +1 -1
  377. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  378. package/node_modules/@earendil-works/pi-ai/dist/models.js +14 -5
  379. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  380. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  381. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -0
  382. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  383. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts.map +1 -1
  384. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js +2 -1
  385. package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js.map +1 -1
  386. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  387. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
  389. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  391. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  392. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  393. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/providers/data/venice.json +1 -1
  395. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.d.ts +12 -0
  397. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.d.ts.map +1 -0
  398. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js +62 -0
  399. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js.map +1 -0
  400. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts +12 -0
  401. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts.map +1 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js +37 -0
  403. package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js.map +1 -0
  404. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +3 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  407. package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.d.ts +12 -0
  408. package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.d.ts.map +1 -0
  409. package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js +93 -0
  410. package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js.map +1 -0
  411. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  412. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +4 -0
  413. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  414. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  415. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  416. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  417. package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.d.ts +1 -1
  418. package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js +55 -16
  420. package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  422. package/package.json +7 -7
package/docs/rpc.md CHANGED
@@ -8,6 +8,14 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
8
8
 
9
9
  **Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@code-yeongyu/senpi` instead of spawning a subprocess. See [`src/core/agent-session.ts`](../src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts).
10
10
 
11
+ ## Account display names
12
+
13
+ `get_provider_accounts` returns secret-free descriptors containing `name`, `source`, `blocked`, `pinned`, and optional `displayName`. Render a named account as `displayName (name)`; keep using the immutable `name` for `account_pin`, `account_remove`, and comparisons. Legacy accounts omit `displayName`.
14
+
15
+ Use `/account <provider> rename <id> <display name...>` or the corresponding `/gpt-account` and `/claude-account` commands to name saved accounts; `clear-name <id>` removes only the label. `/gpt-account add` offers optional naming after login is saved, and only when Senpi generated the account ID itself; the Claude lane names accounts through its own login prompt and never asks twice. Blank input or cancellation keeps that login usable. Environment accounts cannot be renamed.
16
+
17
+ A label is stored NFC-normalized with internal whitespace collapsed, must contain at least one visible character, and may not exceed 32 terminal columns (measured in grapheme clusters, so CJK and emoji count two columns each). Uniqueness within a provider folds case, Unicode compatibility forms, invisible code points, and Cyrillic lookalikes, so two labels that render identically are refused.
18
+
11
19
  ## Starting RPC Mode
12
20
 
13
21
  ### RPC client lifecycle
@@ -147,6 +155,8 @@ The command response reports only `{ cancelled }`, so this event is the only pus
147
155
 
148
156
  The lifecycle supervisor is also available to bundled/rebranded runtimes through the hidden internal launch route `--internal-rpc-host-supervisor`. This route is wire-invisible and intended only for desktop launchers: it receives the public socket, ownership directory, and the runtime command/arguments to wrap, then runs the same `host-lifecycle.ts` implementation used by `ensureHost()`. Normal CLI modes do not use or advertise this route. Compiled standalone binaries also re-enter themselves through this route automatically: a bun executable always boots its embedded entrypoint, so the script-path re-entry used under a JS runtime would be parsed as CLI arguments (`Unknown option: --socket`) and the host could never start.
149
157
 
158
+ On win32 the supervisor's internal hop lives under `<agentDir>/rpc-host-daemon/internal-<uuid>`, and that directory is created recursively. Before allocating the internal hop or spawning a child, the supervisor ensures `<publicSocket>.secret` exists, creating its parent directories and a 32-byte secret with mode `0600` when needed. An existing valid secret, including one written by `ensureHost()`, is reused unchanged. Direct launch therefore works on a fresh profile without caller-side secret provisioning. Provisioning failures identify the bootstrap step and secret path; the public endpoint still requires the secret handshake before forwarding RPC traffic.
159
+
150
160
  Hosts started through `ensureHost()` are wrapped by a lifecycle supervisor that owns the public socket and spawns the
151
161
  real RPC host on a private internal hop. The policy lives in `<agentDir>/rpc-host-daemon/settings.json`:
152
162
 
@@ -212,10 +222,17 @@ and only then constructs its session writer and runtime. A conflicting alias att
212
222
  explicitly before opening another writer.
213
223
 
214
224
  SessionManager writes, switches, forks, new sessions and imports obtain the same grant before writer creation or
215
- append-side normalization. Acquired paths are conservatively retained for that worker's entire lifetime, including
216
- superseded paths after a switch. Each worker may reserve at most 64 paths; an exhausted reservation budget fails
217
- explicitly. Close or an opening deadline requests worker termination, but does not release reservations or worker
218
- capacity until the actual exit event. A syscall that cannot yet be interrupted can therefore keep an entry
225
+ append-side normalization. A grant is bound to a LIVE writer, not to the worker's lifetime: every snapshot a fully
226
+ open worker publishes names the session files its live session writers still own, and the host releases each granted
227
+ path that list (and the worker's current session path) no longer names. A session replaced by `new_session`,
228
+ `switch_session`, a fork or an import therefore frees its previous file as soon as the replacement is published:
229
+ another `open_session` for that superseded path opens its own worker instead of attaching or failing, and the
230
+ previous opening spelling stops resolving to the replaced owner. Each worker may reserve at most 64 live paths
231
+ at once; a request past that budget first reconciles against the latest snapshot and only then fails with
232
+ `session_reservation_limit`, which is distinct from `session_path_in_use` (another owner holds the path). Only a
233
+ fully open entry reconciles. An entry that is opening, closing or quarantined keeps every acquired path, because a
234
+ worker stuck in a syscall can still be writing a path it can no longer report. Close or an opening deadline requests
235
+ worker termination, but does not release reservations or worker capacity until the actual exit event. A syscall that cannot yet be interrupted can therefore keep an entry
219
236
  internally quarantined after the routing handle has closed. `list_sessions` continues to publish `closing`, not a
220
237
  new status: existing clients must not mistake a quarantined worker for a live reattach target. Retry the path only
221
238
  after that entry disappears.
@@ -286,7 +303,8 @@ In the response `error` field, machine-matchable:
286
303
 
287
304
  - `unknown_session`
288
305
  - `session_closing`
289
- - `session_path_in_use` (path held by an opening, closing, quarantined, or superseded owner; a fully-open current owner is attached instead)
306
+ - `session_path_in_use` (path held by an opening, closing, or quarantined owner; a fully-open current owner is attached instead, and a path a live owner has superseded is released rather than held)
307
+ - `session_reservation_limit` (this worker already holds 64 live session paths; the open or session replacement was refused without disturbing the existing session)
290
308
  - `missing_session_id` (session-scoped command without `sessionId` in multi mode)
291
309
  - `multi_session_disabled` (`open_session` in classic mode)
292
310
  - `invalid_path` (relative `sessionPath`/`cwd`)
@@ -303,7 +321,7 @@ Strict FIFO per session; one total stdout order; cross-session order unspecified
303
321
 
304
322
  ### Duplicate/idempotency
305
323
 
306
- Duplicate `open_session` while a path reservation is held by a fully-open session → ATTACH (`attached: true`, same handle); while held by an `opening`/`closing` entry (including internal quarantine) → `session_path_in_use`. `close_session` releases one attachment; the runtime is disposed only when the last attachment closes. A close for an entry already `closing` joins its in-flight teardown. `close_session` on unknown/already-closed → `unknown_session` error. The grace window is configurable by the host through `SENPI_RPC_CLOSE_GRACE_MS`. Request `id`s are client-owned; the server echoes them without dedup.
324
+ Duplicate `open_session` while a path reservation is held by a fully-open session → ATTACH (`attached: true`, same handle); while held by an `opening`/`closing` entry (including internal quarantine) → `session_path_in_use`. A path whose owner has already replaced it with another session file is no longer held: that open allocates a new worker and resumes the file. `close_session` releases one attachment; the runtime is disposed only when the last attachment closes. A close for an entry already `closing` joins its in-flight teardown. `close_session` on unknown/already-closed → `unknown_session` error. The grace window is configurable by the host through `SENPI_RPC_CLOSE_GRACE_MS`. Request `id`s are client-owned; the server echoes them without dedup.
307
325
 
308
326
  ## Protocol Overview
309
327
 
package/docs/settings.md CHANGED
@@ -88,7 +88,7 @@ Permission rules are a confirmation policy, not a sandbox. Senpi, extensions, pa
88
88
  | `modelThinkingLevels` | object | - | Per-model reasoning effort memory (`"provider/id": "level"`) |
89
89
  | `modelLastOnThinkingLevels` | object | - | Per-model last non-off reasoning level, used by `/reasoning on` to restore the previous effort |
90
90
  | `modelServiceTiers` | object | - | Per-model service tier memory (`"provider/id": "auto" \| "priority"`) |
91
- | `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-fable-5-1"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, `"gpt-5.6"`, or `"gpt-6-astra"` |
91
+ | `promptPreset` | string | `"auto"` | Force a system prompt preset: `"auto"`, `"kimi-k2-6"`, `"kimi-k2-7"`, `"kimi-k3"`, `"glm-5.2"`, `"glm-5.3"`, `"grok-4.5"`, `"grok-4.6"`, `"claude-fable-5"`, `"claude-fable-5-1"`, `"claude-opus-5"`, `"claude-opus-4-5"`, `"claude-opus-4-6"`, `"claude-opus-4-7"`, `"claude-opus-4-8"`, `"deepseek-v4-flash"`, `"deepseek-v4-flash-0731"`, `"deepseek-v4-1-flash"`, `"deepseek-v4-pro"`, `"gpt-5"`, `"gpt-5.2"`, `"gpt-5.3-codex"`, `"gpt-5.4"`, `"gpt-5.5"`, `"gpt-5.6"`, or `"gpt-6-astra"` |
92
92
  | `hideThinkingBlock` | boolean | `false` | Hide thinking blocks in output |
93
93
  | `showCacheMissNotices` | boolean | `false` | Show transcript notices for significant prompt-cache misses, compaction or branch-summary usage, and provider recovery diagnostics such as dropped Anthropic thinking blocks |
94
94
  | `thinkingBudgets` | object | - | Custom token budgets per thinking level. Anthropic, Google, and Bedrock use these natively. OpenAI-compatible models use them when `compat.thinkingTokenBudgetField` (or `supportsThinkingTokenBudget`) is set. |
@@ -130,6 +130,7 @@ When this value is anything other than `"auto"`, it overrides any model-level `p
130
130
  | `tipsHistory` | object | - | Internal record of which tips were shown last (managed automatically) |
131
131
  | `defaultProjectTrust` | string | `"ask"` | Fallback project trust behavior: `"ask"`, `"always"`, or `"never"`. Global setting only |
132
132
  | `collapseChangelog` | boolean | `false` | Show condensed changelog after updates |
133
+ | `changelogSeen` | object | - | Internal per-source record of the latest changelog version acknowledged (managed automatically) |
133
134
  | `enableInstallTelemetry` | boolean | `true` | Send an anonymous install/update version ping after first install or changelog-detected updates. This does not control update checks |
134
135
  | `enableAnalytics` | boolean | `false` | Opt-in analytics data sharing. Currently only asked for during the experimental first-time setup (`PI_EXPERIMENTAL=1`) |
135
136
  | `trackingId` | string | - | Analytics tracking identifier, generated when `enableAnalytics` is turned on |
package/docs/tui.md CHANGED
@@ -178,7 +178,7 @@ Use `handle.unfocus()` when a visible overlay should stop owning input and let T
178
178
 
179
179
  ### Question Overlay and Async Widget
180
180
 
181
- When the agent asks a blocking question (`waitForAnswer: true`), a full-screen overlay appears with a tab bar for each question, numbered options (digits or arrows to select, Space to toggle multi-select), and a comment editor at the bottom. Press Enter to submit what you have. Unanswered questions are reported back as unanswered. Esc cancels.
181
+ When the agent asks a blocking question (`waitForAnswer: true`), a full-screen overlay appears with a tab for each question and a final Submit tab. Use digits or arrows to choose options, Space to toggle multi-select choices, and Enter to confirm and advance. The Submit tab contains the optional comment editor and accepts partial answers after confirmation; unanswered questions are reported back as unanswered. Esc backs out of an editor or asks for confirmation before discarding a draft.
182
182
 
183
183
  For async questions (`waitForAnswer: false`), a one-line widget appears above the editor showing the question count and a countdown. The agent keeps working while you decide. Type your reply in the editor at any time and press Enter to send it as a comment, or open the full overlay with the shortcut shown in the widget.
184
184
 
@@ -12,6 +12,58 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.9.12-2] - 2026-09-12
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ ### Removed
26
+
27
+ ## [2026.9.12] - 2026-09-12
28
+
29
+ ### Breaking Changes
30
+
31
+ ### Added
32
+
33
+ ### Changed
34
+
35
+ ### Fixed
36
+
37
+ ### Removed
38
+
39
+ ## [2026.9.11] - 2026-09-11
40
+
41
+ ### Breaking Changes
42
+
43
+ ### Added
44
+
45
+ ### Changed
46
+
47
+ - The eval tool instructions now tell callers to emit large text in bounded chunks or through offset-based file reads, and to treat a truncation notice as incomplete data that must be recovered from the full-output path instead of being read as the whole result ([#1600](https://github.com/code-yeongyu/senpi/pull/1600)).
48
+
49
+ ### Fixed
50
+
51
+ - Column-capped eval output now preserves a recoverable full-output artifact, so a cell whose output is clipped by a narrow terminal column cap still exposes the complete text through the artifact path ([#1600](https://github.com/code-yeongyu/senpi/pull/1600)).
52
+
53
+ ### Removed
54
+
55
+ ## [2026.9.10-2] - 2026-09-10
56
+
57
+ ### Breaking Changes
58
+
59
+ ### Added
60
+
61
+ ### Changed
62
+
63
+ ### Fixed
64
+
65
+ ### Removed
66
+
15
67
  ## [2026.9.10] - 2026-09-10
16
68
 
17
69
  ### Breaking Changes
@@ -218,10 +218,11 @@ empty pipe (`true | ( … )`) while a cell is active. Output, exit codes, `cwd`,
218
218
  ## Output and artifacts
219
219
 
220
220
  Cell output is streamed while the cell runs. Large streams spill to an absolute
221
- file after the default 50 KiB threshold. With a session file such as
222
- `/path/session.jsonl`, artifacts live in `/path/session-artifacts/`; sessions
223
- without a file use a unique temporary directory. Truncated results include a
224
- plain-path notice such as `[Full output: /absolute/path/eval-….log]`.
221
+ file after the default 50 KiB threshold or when the output column cap drops
222
+ bytes. With a session file such as `/path/session.jsonl`, artifacts live in
223
+ `/path/session-artifacts/`; sessions without a file use a unique temporary
224
+ directory. Truncated results include a plain-path notice such as
225
+ `[Full output: /absolute/path/eval-….log]`.
225
226
 
226
227
  ## Deliberate differences from oh-my-pi
227
228
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.9.10",
3
+ "version": "2026.9.12-2",
4
4
  "private": true,
5
5
  "description": "Source-only senpi extension package for codemode evaluation tools",
6
6
  "type": "module",
@@ -31,14 +31,14 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/parser": "8.0.4",
34
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.10",
34
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.12-2",
35
35
  "typebox": "1.3.18"
36
36
  },
37
37
  "peerDependencies": {
38
- "@code-yeongyu/senpi": "2026.9.10"
38
+ "@code-yeongyu/senpi": "2026.9.12-2"
39
39
  },
40
40
  "devDependencies": {
41
- "@code-yeongyu/senpi": "2026.9.10"
41
+ "@code-yeongyu/senpi": "2026.9.12-2"
42
42
  },
43
43
  "keywords": [
44
44
  "senpi",
@@ -0,0 +1,58 @@
1
+ interface ByteSlice {
2
+ readonly text: string;
3
+ readonly bytes: number;
4
+ }
5
+
6
+ export function truncateHeadBytes(text: string, maxBytes: number): ByteSlice {
7
+ if (maxBytes <= 0) return { text: "", bytes: 0 };
8
+ const buffer = Buffer.from(text, "utf8");
9
+ if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
10
+ let end = maxBytes;
11
+ while (end > 0 && (buffer[end] & 0xc0) === 0x80) end--;
12
+ const slice = buffer.subarray(0, end);
13
+ return { text: slice.toString("utf8"), bytes: slice.length };
14
+ }
15
+
16
+ export function truncateTailBytes(text: string, maxBytes: number): ByteSlice {
17
+ if (maxBytes <= 0) return { text: "", bytes: 0 };
18
+ const buffer = Buffer.from(text, "utf8");
19
+ if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
20
+ let start = buffer.length - maxBytes;
21
+ while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) start++;
22
+ const slice = buffer.subarray(start);
23
+ return { text: slice.toString("utf8"), bytes: slice.length };
24
+ }
25
+
26
+ export class TailBuffer {
27
+ readonly #maxBytes: number;
28
+ #text = "";
29
+ #bytes = 0;
30
+
31
+ constructor(maxBytes: number) {
32
+ this.#maxBytes = Math.max(0, Math.floor(maxBytes));
33
+ }
34
+
35
+ append(text: string): void {
36
+ if (text.length === 0) return;
37
+ if (this.#maxBytes === 0) {
38
+ this.#text = "";
39
+ this.#bytes = 0;
40
+ return;
41
+ }
42
+ const incomingBytes = Buffer.byteLength(text, "utf8");
43
+ const next =
44
+ incomingBytes >= this.#maxBytes
45
+ ? truncateTailBytes(text, this.#maxBytes)
46
+ : truncateTailBytes(this.#text + text, this.#maxBytes);
47
+ this.#text = next.text;
48
+ this.#bytes = next.bytes;
49
+ }
50
+
51
+ text(): string {
52
+ return this.#text;
53
+ }
54
+
55
+ bytes(): number {
56
+ return this.#bytes;
57
+ }
58
+ }
@@ -2,9 +2,11 @@ import { createWriteStream, mkdirSync, type WriteStream } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "../host-sdk.ts";
4
4
  import { formatMiddleElisionMarker } from "./output-meta.ts";
5
+ import { TailBuffer, truncateHeadBytes } from "./streaming-output-buffer.ts";
5
6
 
6
7
  export { artifactNotice, formatMiddleElisionMarker, resolveSessionArtifactsDir } from "./output-meta.ts";
7
- export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail };
8
+ export { truncateHeadBytes, truncateTailBytes } from "./streaming-output-buffer.ts";
9
+ export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, TailBuffer, truncateTail };
8
10
 
9
11
  export const ARTIFACT_DEFAULT_HEAD_BYTES = 3 * 1024 * 1024;
10
12
 
@@ -31,11 +33,6 @@ export interface OutputSinkOptions {
31
33
  readonly chunkThrottleMs?: number;
32
34
  }
33
35
 
34
- interface ByteSlice {
35
- readonly text: string;
36
- readonly bytes: number;
37
- }
38
-
39
36
  function countNewlines(text: string): number {
40
37
  let count = 0;
41
38
  let cursor = text.indexOf("\n");
@@ -50,60 +47,6 @@ function lineCount(text: string): number {
50
47
  return text.length === 0 ? 0 : countNewlines(text) + 1;
51
48
  }
52
49
 
53
- function truncateHeadBytes(text: string, maxBytes: number): ByteSlice {
54
- if (maxBytes <= 0) return { text: "", bytes: 0 };
55
- const buffer = Buffer.from(text, "utf8");
56
- if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
57
- let end = maxBytes;
58
- while (end > 0 && (buffer[end] & 0xc0) === 0x80) end--;
59
- const slice = buffer.subarray(0, end);
60
- return { text: slice.toString("utf8"), bytes: slice.length };
61
- }
62
-
63
- function truncateTailBytes(text: string, maxBytes: number): ByteSlice {
64
- if (maxBytes <= 0) return { text: "", bytes: 0 };
65
- const buffer = Buffer.from(text, "utf8");
66
- if (buffer.length <= maxBytes) return { text, bytes: buffer.length };
67
- let start = buffer.length - maxBytes;
68
- while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) start++;
69
- const slice = buffer.subarray(start);
70
- return { text: slice.toString("utf8"), bytes: slice.length };
71
- }
72
-
73
- export class TailBuffer {
74
- readonly #maxBytes: number;
75
- #text = "";
76
- #bytes = 0;
77
-
78
- constructor(maxBytes: number) {
79
- this.#maxBytes = Math.max(0, Math.floor(maxBytes));
80
- }
81
-
82
- append(text: string): void {
83
- if (text.length === 0) return;
84
- if (this.#maxBytes === 0) {
85
- this.#text = "";
86
- this.#bytes = 0;
87
- return;
88
- }
89
- const incomingBytes = Buffer.byteLength(text, "utf8");
90
- const next =
91
- incomingBytes >= this.#maxBytes
92
- ? truncateTailBytes(text, this.#maxBytes)
93
- : truncateTailBytes(this.#text + text, this.#maxBytes);
94
- this.#text = next.text;
95
- this.#bytes = next.bytes;
96
- }
97
-
98
- text(): string {
99
- return this.#text;
100
- }
101
-
102
- bytes(): number {
103
- return this.#bytes;
104
- }
105
- }
106
-
107
50
  export class OutputSink {
108
51
  readonly #artifactPath: string | undefined;
109
52
  readonly #spillThreshold: number;
@@ -146,8 +89,10 @@ export class OutputSink {
146
89
  this.#totalBytes += rawBytes;
147
90
  this.#totalNewlines += countNewlines(chunk);
148
91
  this.#sawData = true;
149
- this.#mirrorRaw(chunk);
150
- this.#retain(this.#maxColumns > 0 ? this.#clampColumns(chunk) : chunk);
92
+ const droppedBefore = this.#columnDroppedBytes;
93
+ const retained = this.#maxColumns > 0 ? this.#clampColumns(chunk) : chunk;
94
+ this.#mirrorRaw(chunk, this.#columnDroppedBytes > droppedBefore);
95
+ this.#retain(retained);
151
96
  }
152
97
 
153
98
  dump(notice?: string): Promise<OutputSummary> {
@@ -167,13 +112,13 @@ export class OutputSink {
167
112
  this.#pendingChunk += chunk;
168
113
  }
169
114
 
170
- #mirrorRaw(chunk: string): void {
115
+ #mirrorRaw(chunk: string, columnCapDropped: boolean): void {
171
116
  if (this.#artifactPath === undefined) return;
172
117
  if (this.#file !== undefined) {
173
118
  this.#file.write(chunk);
174
119
  return;
175
120
  }
176
- if (this.#totalBytes <= this.#spillThreshold) {
121
+ if (!columnCapDropped && this.#totalBytes <= this.#spillThreshold) {
177
122
  this.#beforeSpill += chunk;
178
123
  return;
179
124
  }
@@ -1,7 +1,7 @@
1
1
  export const EVAL_PROMPT_TEMPLATE = `Run one step of code in a persistent kernel.
2
2
 
3
3
  <instruction>
4
- **One eval call = one cell = one logical step.** Top-level names persist per language across eval calls{{#if spawns}}, tool calls and \`task\` subagents{{else}} and tool calls{{/if}}: define helpers and clients once and reuse them instead of re-importing or re-reading. Rebuild state only after \`reset\`, a kernel restart, or a \`NameError\`/\`ReferenceError\`, and check a sentinel variable first so a re-run cannot duplicate side effects.
4
+ **One eval call = one cell = one logical step.** Top-level names persist per language across eval calls{{#if spawns}}, tool calls and \`task\` subagents{{else}} and tool calls{{/if}}: define helpers and clients once and reuse them instead of re-importing or re-reading. For large text, use bounded chunks or write it to a file and read it with offsets; treat truncation notices as incomplete data and follow the full-output path. Rebuild state only after \`reset\`, a kernel restart, or a \`NameError\`/\`ReferenceError\`, and check a sentinel variable first so a re-run cannot duplicate side effects.
5
5
 
6
6
  {{#if styleClaude}}<eval_first_batching>
7
7
  Batch a step's independent calls in one cell with \`parallel(thunks)\`; write real code around them - loops, branches, joins, a try/except per risky item - and keep every failed or missing item in the result verbatim; re-read truncated output before deciding.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-agent-core",
3
- "version": "2026.9.10",
3
+ "version": "2026.9.12-2",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,8 +35,8 @@
35
35
  "prepublishOnly": "npm run build"
36
36
  },
37
37
  "dependencies": {
38
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.10",
39
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.10",
38
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.12-2",
39
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.12-2",
40
40
  "diff": "9.0.0",
41
41
  "ignore": "7.0.6",
42
42
  "typebox": "1.3.18",
@@ -15,6 +15,17 @@ export declare function buildCursorHistoryForTest(messages: Message[], activeUse
15
15
  turnUserMessagesJson: unknown[];
16
16
  turnStepMessagesJson: unknown[][];
17
17
  };
18
+ /**
19
+ * Serialized byte cost of the MODEL INPUT alone: the `rootPromptMessagesJson`
20
+ * blobs Cursor's server replays as the prompt. `measureCursorHistorySerializedBytes`
21
+ * additionally counts the `turns[]` display copies of the same conversation, so
22
+ * it reports roughly twice this number and overstates what the model ingests.
23
+ * Each referenced blob is counted once per reference, because a blob replayed
24
+ * twice occupies the prompt twice.
25
+ *
26
+ * First proposed in #1614.
27
+ */
28
+ export declare function measureCursorModelInputSerializedBytes(messages: Message[], activeUserMessageIndex?: number): number;
18
29
  export declare function measureCursorHistorySerializedBytes(messages: Message[], activeUserMessageIndex?: number): number;
19
30
  export declare function buildCursorHistoryWireBytesForTest(messages: Message[], activeUserMessageIndex?: number): Uint8Array[];
20
31
  //# sourceMappingURL=measure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../src/api/cursor-agent/measure.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkC,OAAO,EAA4C,MAAM,gBAAgB,CAAC;AAwJxH;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CASzG;AAwPD,yFAAyF;AACzF,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD;IACF,sBAAsB,EAAE,OAAO,EAAE,CAAC;IAClC,oBAAoB,EAAE,OAAO,EAAE,CAAC;IAChC,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;CAClC,CAsBA;AAoCD,wBAAgB,mCAAmC,CAClD,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD,MAAM,CAKR;AACD,wBAAgB,kCAAkC,CACjD,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD,UAAU,EAAE,CAKd"}
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../src/api/cursor-agent/measure.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkC,OAAO,EAA4C,MAAM,gBAAgB,CAAC;AAwJxH;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CASzG;AAwPD,yFAAyF;AACzF,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD;IACF,sBAAsB,EAAE,OAAO,EAAE,CAAC;IAClC,oBAAoB,EAAE,OAAO,EAAE,CAAC;IAChC,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;CAClC,CAsBA;AAoCD;;;;;;;;;GASG;AACH,wBAAgB,sCAAsC,CACrD,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD,MAAM,CAOR;AAED,wBAAgB,mCAAmC,CAClD,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD,MAAM,CAKR;AACD,wBAAgB,kCAAkC,CACjD,QAAQ,EAAE,OAAO,EAAE,EACnB,sBAAsB,SAAqC,GACzD,UAAU,EAAE,CAKd"}
@@ -431,6 +431,24 @@ function extractImages(content) {
431
431
  },
432
432
  }));
433
433
  }
434
+ /**
435
+ * Serialized byte cost of the MODEL INPUT alone: the `rootPromptMessagesJson`
436
+ * blobs Cursor's server replays as the prompt. `measureCursorHistorySerializedBytes`
437
+ * additionally counts the `turns[]` display copies of the same conversation, so
438
+ * it reports roughly twice this number and overstates what the model ingests.
439
+ * Each referenced blob is counted once per reference, because a blob replayed
440
+ * twice occupies the prompt twice.
441
+ *
442
+ * First proposed in #1614.
443
+ */
444
+ export function measureCursorModelInputSerializedBytes(messages, activeUserMessageIndex = findLastUserMessageIndex(messages)) {
445
+ const blobStore = new Map();
446
+ let total = 0;
447
+ for (const blobId of buildRootPromptMessagesJson(messages, [], blobStore, activeUserMessageIndex)) {
448
+ total += readCursorBlob(blobStore, blobId).byteLength;
449
+ }
450
+ return total;
451
+ }
434
452
  export function measureCursorHistorySerializedBytes(messages, activeUserMessageIndex = findLastUserMessageIndex(messages)) {
435
453
  return buildCursorHistoryWireBytesForTest(messages, activeUserMessageIndex).reduce((total, bytes) => total + bytes.byteLength, 0);
436
454
  }