@code-yeongyu/senpi 2026.7.30 → 2026.7.31-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 (529) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/README.md +3 -0
  3. package/dist/core/agent-session.d.ts +55 -12
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +141 -21
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/compaction.d.ts +1 -0
  8. package/dist/core/compaction/compaction.d.ts.map +1 -1
  9. package/dist/core/compaction/compaction.js +1 -0
  10. package/dist/core/compaction/compaction.js.map +1 -1
  11. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  12. package/dist/core/dynamic-prompt/build.js +4 -0
  13. package/dist/core/dynamic-prompt/build.js.map +1 -1
  14. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts +2 -2
  15. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js +25 -25
  17. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js.map +1 -1
  18. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts.map +1 -1
  19. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js.map +1 -1
  20. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts +1 -1
  21. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts.map +1 -1
  22. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js +2 -2
  23. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js.map +1 -1
  24. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts +9 -9
  25. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts.map +1 -1
  26. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js +2 -2
  27. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js.map +1 -1
  28. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts +1 -1
  29. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js +3 -3
  31. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js.map +1 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts +21 -0
  33. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts.map +1 -0
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js +30 -0
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js.map +1 -0
  36. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.d.ts +8 -4
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -0
  38. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.js +34 -25
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -0
  40. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js.map +1 -1
  42. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js.map +1 -1
  44. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts +1 -1
  45. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js +1 -1
  47. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js.map +1 -1
  48. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js.map +1 -1
  50. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js +1 -1
  52. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js.map +1 -1
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts +14 -0
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts.map +1 -0
  55. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/guidance.js +37 -1
  56. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js.map +1 -0
  57. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
  58. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -0
  59. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/index.js +12 -10
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -0
  61. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts +3 -3
  62. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.js +2 -2
  64. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -0
  65. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts +18 -0
  66. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.js +70 -10
  68. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -0
  69. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts.map +1 -1
  70. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.js +32 -19
  71. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -0
  72. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts +1 -0
  73. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js.map +1 -1
  75. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts +30 -0
  76. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +197 -0
  78. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -0
  79. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts +18 -0
  80. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts.map +1 -0
  81. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js +33 -0
  82. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js.map +1 -0
  83. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts +3 -0
  84. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -0
  85. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +134 -0
  86. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -0
  87. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +85 -0
  88. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -0
  89. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +270 -0
  90. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -0
  91. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts +17 -0
  92. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -0
  93. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +217 -0
  94. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -0
  95. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts +49 -0
  96. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -0
  97. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +204 -0
  98. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -0
  99. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts +28 -0
  100. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -0
  101. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +107 -0
  102. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -0
  103. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts +2 -0
  104. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts.map +1 -0
  105. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js +10 -0
  106. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js.map +1 -0
  107. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts.map +1 -1
  108. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js.map +1 -1
  109. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.d.ts +1 -1
  110. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -0
  111. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.js +72 -53
  112. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -0
  113. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts +3 -0
  114. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts.map +1 -0
  115. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js +25 -0
  116. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js.map +1 -0
  117. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts +1 -1
  118. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts.map +1 -1
  119. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js +2 -2
  120. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js.map +1 -1
  121. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js.map +1 -1
  123. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +18 -0
  124. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -0
  125. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +69 -0
  126. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -0
  127. package/dist/core/extensions/builtin/compaction/idle.d.ts +16 -0
  128. package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -0
  129. package/dist/core/extensions/builtin/compaction/idle.js +21 -0
  130. package/dist/core/extensions/builtin/compaction/idle.js.map +1 -0
  131. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  132. package/dist/core/extensions/builtin/compaction/index.js +45 -2
  133. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  134. package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
  135. package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
  136. package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
  137. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -0
  138. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
  139. package/dist/core/extensions/builtin/compaction/openai-remote.js +15 -4
  140. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
  141. package/dist/core/extensions/builtin/compaction/speculative.d.ts +4 -1
  142. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/compaction/speculative.js +39 -20
  144. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  145. package/dist/core/extensions/builtin/compaction/task-intent.d.ts +2 -6
  146. package/dist/core/extensions/builtin/compaction/task-intent.d.ts.map +1 -1
  147. package/dist/core/extensions/builtin/compaction/task-intent.js +10 -9
  148. package/dist/core/extensions/builtin/compaction/task-intent.js.map +1 -1
  149. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +6 -0
  150. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -0
  151. package/dist/core/extensions/builtin/goal/continuation-recovery.js +20 -0
  152. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -0
  153. package/dist/core/extensions/builtin/goal/continuation.d.ts +4 -4
  154. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  155. package/dist/core/extensions/builtin/goal/continuation.js +14 -8
  156. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  157. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts +19 -0
  158. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts.map +1 -0
  159. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +48 -0
  160. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -0
  161. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  162. package/dist/core/extensions/builtin/goal/index.js +21 -16
  163. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  164. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  165. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +12 -10
  166. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  167. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +5 -1
  168. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  169. package/dist/core/extensions/builtin/goal/monitor-continuation.js +109 -63
  170. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  171. package/dist/core/extensions/builtin/goal/persistence.d.ts +1 -0
  172. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -1
  173. package/dist/core/extensions/builtin/goal/persistence.js +49 -7
  174. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  175. package/dist/core/extensions/builtin/goal/ui.d.ts +1 -0
  176. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  177. package/dist/core/extensions/builtin/goal/ui.js +11 -2
  178. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  179. package/dist/core/extensions/builtin/gpt-apply-patch/apply.d.ts +1 -1
  180. package/dist/core/extensions/builtin/gpt-apply-patch/apply.d.ts.map +1 -1
  181. package/dist/core/extensions/builtin/gpt-apply-patch/apply.js +67 -66
  182. package/dist/core/extensions/builtin/gpt-apply-patch/apply.js.map +1 -1
  183. package/dist/core/extensions/builtin/gpt-apply-patch/recovery.d.ts +4 -0
  184. package/dist/core/extensions/builtin/gpt-apply-patch/recovery.d.ts.map +1 -0
  185. package/dist/core/extensions/builtin/gpt-apply-patch/recovery.js +35 -0
  186. package/dist/core/extensions/builtin/gpt-apply-patch/recovery.js.map +1 -0
  187. package/dist/core/extensions/builtin/gpt-apply-patch/tool.d.ts.map +1 -1
  188. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js +0 -5
  189. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js.map +1 -1
  190. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts +2 -0
  191. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts.map +1 -1
  192. package/dist/core/extensions/builtin/gpt-apply-patch/types.js.map +1 -1
  193. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  194. package/dist/core/extensions/builtin/index.js +5 -2
  195. package/dist/core/extensions/builtin/index.js.map +1 -1
  196. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts +31 -0
  197. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts.map +1 -0
  198. package/dist/core/extensions/builtin/loop-guard/detectors.js +111 -0
  199. package/dist/core/extensions/builtin/loop-guard/detectors.js.map +1 -0
  200. package/dist/core/extensions/builtin/loop-guard/index.d.ts +3 -0
  201. package/dist/core/extensions/builtin/loop-guard/index.d.ts.map +1 -0
  202. package/dist/core/extensions/builtin/loop-guard/index.js +31 -0
  203. package/dist/core/extensions/builtin/loop-guard/index.js.map +1 -0
  204. package/dist/core/extensions/builtin/loop-guard/notice.d.ts +5 -0
  205. package/dist/core/extensions/builtin/loop-guard/notice.d.ts.map +1 -0
  206. package/dist/core/extensions/builtin/loop-guard/notice.js +42 -0
  207. package/dist/core/extensions/builtin/loop-guard/notice.js.map +1 -0
  208. package/dist/core/extensions/builtin/loop-guard/policy.d.ts +30 -0
  209. package/dist/core/extensions/builtin/loop-guard/policy.d.ts.map +1 -0
  210. package/dist/core/extensions/builtin/loop-guard/policy.js +30 -0
  211. package/dist/core/extensions/builtin/loop-guard/policy.js.map +1 -0
  212. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts +4 -0
  213. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts.map +1 -0
  214. package/dist/core/extensions/builtin/loop-guard/renderer.js +50 -0
  215. package/dist/core/extensions/builtin/loop-guard/renderer.js.map +1 -0
  216. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts +13 -0
  217. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts.map +1 -0
  218. package/dist/core/extensions/builtin/loop-guard/similarity.js +51 -0
  219. package/dist/core/extensions/builtin/loop-guard/similarity.js.map +1 -0
  220. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts +13 -0
  221. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts.map +1 -0
  222. package/dist/core/extensions/builtin/loop-guard/tracker.js +39 -0
  223. package/dist/core/extensions/builtin/loop-guard/tracker.js.map +1 -0
  224. package/dist/core/extensions/builtin/monitor-state-event.d.ts +10 -0
  225. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  226. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  227. package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
  228. package/dist/core/extensions/builtin/prompt-preset/index.js +8 -4
  229. package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
  230. package/dist/core/extensions/builtin/rules/index.js +4 -3
  231. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  232. package/dist/core/extensions/builtin/rules/rules/constants.d.ts +11 -0
  233. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  234. package/dist/core/extensions/builtin/rules/rules/constants.js +11 -0
  235. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  236. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -1
  237. package/dist/core/extensions/builtin/rules/rules/formatter.js +15 -1
  238. package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -1
  239. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  240. package/dist/core/extensions/builtin/service-tier.js +23 -21
  241. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  242. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  243. package/dist/core/extensions/builtin/terminal/extension.js +21 -7
  244. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  245. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
  246. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  247. package/dist/core/extensions/builtin/terminal/monitor-registry.js +2 -0
  248. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  249. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts +37 -0
  250. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts.map +1 -0
  251. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js +61 -0
  252. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js.map +1 -0
  253. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts +9 -1
  254. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts.map +1 -1
  255. package/dist/core/extensions/builtin/terminal/monitor-status.js +35 -2
  256. package/dist/core/extensions/builtin/terminal/monitor-status.js.map +1 -1
  257. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts +1 -1
  258. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts.map +1 -1
  259. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js +88 -29
  260. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js.map +1 -1
  261. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts +4 -0
  262. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts.map +1 -0
  263. package/dist/core/extensions/builtin/ttsr/builtin-rules.js +20 -0
  264. package/dist/core/extensions/builtin/ttsr/builtin-rules.js.map +1 -0
  265. package/dist/core/extensions/builtin/ttsr/commands.js +9 -1
  266. package/dist/core/extensions/builtin/ttsr/commands.js.map +1 -1
  267. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  268. package/dist/core/extensions/builtin/ttsr/index.js +4 -3
  269. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  270. package/dist/core/extensions/builtin/ttsr/manager.js +1 -1
  271. package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
  272. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  273. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +1 -1
  274. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  275. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  276. package/dist/core/extensions/builtin/websearch/websearch/search.js +1 -3
  277. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  278. package/dist/core/extensions/index.d.ts +1 -1
  279. package/dist/core/extensions/index.d.ts.map +1 -1
  280. package/dist/core/extensions/index.js.map +1 -1
  281. package/dist/core/extensions/loader.d.ts.map +1 -1
  282. package/dist/core/extensions/loader.js +5 -0
  283. package/dist/core/extensions/loader.js.map +1 -1
  284. package/dist/core/extensions/runner.d.ts +1 -1
  285. package/dist/core/extensions/runner.d.ts.map +1 -1
  286. package/dist/core/extensions/runner.js +3 -1
  287. package/dist/core/extensions/runner.js.map +1 -1
  288. package/dist/core/extensions/types.d.ts +22 -1
  289. package/dist/core/extensions/types.d.ts.map +1 -1
  290. package/dist/core/extensions/types.js.map +1 -1
  291. package/dist/core/high-reasoning-warning.d.ts +10 -0
  292. package/dist/core/high-reasoning-warning.d.ts.map +1 -0
  293. package/dist/core/high-reasoning-warning.js +28 -0
  294. package/dist/core/high-reasoning-warning.js.map +1 -0
  295. package/dist/core/model-runtime.d.ts.map +1 -1
  296. package/dist/core/model-runtime.js +3 -11
  297. package/dist/core/model-runtime.js.map +1 -1
  298. package/dist/core/settings-manager.d.ts +2 -0
  299. package/dist/core/settings-manager.d.ts.map +1 -1
  300. package/dist/core/settings-manager.js +1 -0
  301. package/dist/core/settings-manager.js.map +1 -1
  302. package/dist/core/thinking-levels.d.ts.map +1 -1
  303. package/dist/core/thinking-levels.js +23 -3
  304. package/dist/core/thinking-levels.js.map +1 -1
  305. package/dist/index.d.ts +1 -1
  306. package/dist/index.d.ts.map +1 -1
  307. package/dist/index.js.map +1 -1
  308. package/dist/modes/app-server/server/account.d.ts +1 -1
  309. package/dist/modes/app-server/server/account.js +1 -1
  310. package/dist/modes/app-server/server/account.js.map +1 -1
  311. package/dist/modes/app-server/server/server-core.js +1 -1
  312. package/dist/modes/app-server/server/server-core.js.map +1 -1
  313. package/dist/modes/interactive/compaction-queue-transfer.d.ts +2 -0
  314. package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -1
  315. package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -1
  316. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  317. package/dist/modes/interactive/components/footer.js +9 -5
  318. package/dist/modes/interactive/components/footer.js.map +1 -1
  319. package/dist/modes/interactive/interactive-mode.d.ts +8 -1
  320. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  321. package/dist/modes/interactive/interactive-mode.js +96 -24
  322. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  323. package/dist/modes/interactive/risky-main-model-warning.d.ts +5 -0
  324. package/dist/modes/interactive/risky-main-model-warning.d.ts.map +1 -0
  325. package/dist/modes/interactive/risky-main-model-warning.js +8 -0
  326. package/dist/modes/interactive/risky-main-model-warning.js.map +1 -0
  327. package/dist/modes/interactive/tips/catalog/subagent-tips.d.ts.map +1 -1
  328. package/dist/modes/interactive/tips/catalog/subagent-tips.js +30 -0
  329. package/dist/modes/interactive/tips/catalog/subagent-tips.js.map +1 -1
  330. package/dist/modes/rpc/connection-handler.js +3 -3
  331. package/dist/modes/rpc/connection-handler.js.map +1 -1
  332. package/dist/modes/rpc/rpc-types.d.ts +6 -0
  333. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  334. package/dist/modes/rpc/rpc-types.js.map +1 -1
  335. package/dist/utils/version-check.d.ts.map +1 -1
  336. package/dist/utils/version-check.js +22 -2
  337. package/dist/utils/version-check.js.map +1 -1
  338. package/docs/docs.json +4 -0
  339. package/docs/extensions.md +10 -0
  340. package/docs/providers.md +21 -5
  341. package/docs/quickstart.md +3 -0
  342. package/docs/release-guide.md +636 -0
  343. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +39 -0
  344. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  345. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status-ticker.ts +79 -0
  346. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +36 -3
  347. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +26 -12
  348. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +9 -0
  349. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  350. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +3 -2
  351. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  352. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts +4 -0
  353. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -0
  354. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +106 -0
  355. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -0
  356. package/node_modules/@earendil-works/pi-agent-core/dist/stream-fn.d.ts +1 -0
  357. package/node_modules/@earendil-works/pi-agent-core/dist/stream-fn.d.ts.map +1 -1
  358. package/node_modules/@earendil-works/pi-agent-core/dist/stream-fn.js +1 -0
  359. package/node_modules/@earendil-works/pi-agent-core/dist/stream-fn.js.map +1 -1
  360. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  361. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  362. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +10 -15
  363. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  364. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +2 -2
  365. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  366. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +2 -2
  367. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  368. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +2 -2
  369. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  370. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -2
  371. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  372. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -1
  373. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  374. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -1
  375. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  376. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +1 -0
  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 +69 -19
  379. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  380. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  381. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  382. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  383. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  384. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  385. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  386. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  387. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  389. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts +2 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
  391. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +13 -0
  392. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
  393. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.js +2 -2
  394. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/recovery-stream.js.map +1 -1
  395. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery-stream.d.ts +3 -0
  396. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery-stream.d.ts.map +1 -0
  397. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery-stream.js +29 -0
  398. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery-stream.js.map +1 -0
  399. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery.d.ts +3 -0
  400. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery.d.ts.map +1 -0
  401. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery.js +82 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/kimi-xtml/thinking-recovery.js.map +1 -0
  403. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +5 -0
  404. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts +3 -0
  407. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts.map +1 -0
  408. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js +36 -0
  409. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js.map +1 -0
  410. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  411. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  412. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  413. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.d.ts.map +1 -1
  414. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.js +1 -12
  415. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.js.map +1 -1
  416. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.d.ts +7 -0
  417. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.d.ts.map +1 -1
  418. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.js +9 -3
  419. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/stdio.js.map +1 -1
  420. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts.map +1 -1
  421. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js +5 -3
  422. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js.map +1 -1
  423. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.d.ts.map +1 -1
  424. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js +1 -12
  425. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js.map +1 -1
  426. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.d.ts +5 -0
  427. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.d.ts.map +1 -0
  428. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.js +17 -0
  429. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/sseKeepAlive.js.map +1 -0
  430. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.d.ts +9 -1
  431. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.d.ts.map +1 -1
  432. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js +10 -4
  433. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js.map +1 -1
  434. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.d.ts +21 -0
  435. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.d.ts.map +1 -1
  436. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.js +239 -41
  437. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/webStandardStreamableHttp.js.map +1 -1
  438. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.d.ts.map +1 -1
  439. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js +25 -6
  440. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js.map +1 -1
  441. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.d.ts +32 -0
  442. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.d.ts.map +1 -0
  443. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.js +64 -0
  444. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/mediaType.js.map +1 -0
  445. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.d.ts +5 -0
  446. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.d.ts.map +1 -1
  447. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js +10 -1
  448. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js.map +1 -1
  449. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.d.ts.map +1 -1
  450. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js +2 -13
  451. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js.map +1 -1
  452. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.d.ts +7 -0
  453. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.d.ts.map +1 -1
  454. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js +9 -3
  455. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js.map +1 -1
  456. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts.map +1 -1
  457. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js +5 -3
  458. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js.map +1 -1
  459. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.d.ts.map +1 -1
  460. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js +2 -13
  461. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js.map +1 -1
  462. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.d.ts +5 -0
  463. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.d.ts.map +1 -0
  464. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js +13 -0
  465. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js.map +1 -0
  466. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.d.ts +9 -1
  467. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.d.ts.map +1 -1
  468. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js +10 -4
  469. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js.map +1 -1
  470. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.d.ts +21 -0
  471. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.d.ts.map +1 -1
  472. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js +239 -41
  473. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js.map +1 -1
  474. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.d.ts.map +1 -1
  475. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js +25 -6
  476. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js.map +1 -1
  477. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.d.ts +32 -0
  478. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.d.ts.map +1 -0
  479. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js +57 -0
  480. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js.map +1 -0
  481. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.d.ts +5 -0
  482. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.d.ts.map +1 -1
  483. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js +9 -0
  484. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js.map +1 -1
  485. package/node_modules/@modelcontextprotocol/sdk/package.json +4 -3
  486. package/node_modules/brace-expansion/README.md +12 -0
  487. package/node_modules/brace-expansion/dist/commonjs/index.d.ts +2 -0
  488. package/node_modules/brace-expansion/dist/commonjs/index.d.ts.map +1 -1
  489. package/node_modules/brace-expansion/dist/commonjs/index.js +138 -86
  490. package/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -1
  491. package/node_modules/brace-expansion/dist/esm/index.d.ts +2 -0
  492. package/node_modules/brace-expansion/dist/esm/index.d.ts.map +1 -1
  493. package/node_modules/brace-expansion/dist/esm/index.js +137 -85
  494. package/node_modules/brace-expansion/dist/esm/index.js.map +1 -1
  495. package/node_modules/brace-expansion/package.json +2 -2
  496. package/package.json +7 -7
  497. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.d.ts.map +0 -1
  498. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.js.map +0 -1
  499. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts +0 -6
  500. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts.map +0 -1
  501. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.js.map +0 -1
  502. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts +0 -4
  503. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts.map +0 -1
  504. package/dist/core/extensions/builtin/claude-agent-sdk/index.js.map +0 -1
  505. package/dist/core/extensions/builtin/claude-agent-sdk/oauth-login.js.map +0 -1
  506. package/dist/core/extensions/builtin/claude-agent-sdk/options.d.ts +0 -16
  507. package/dist/core/extensions/builtin/claude-agent-sdk/options.js.map +0 -1
  508. package/dist/core/extensions/builtin/claude-agent-sdk/prompt-bridge.js.map +0 -1
  509. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts +0 -15
  510. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts.map +0 -1
  511. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js +0 -41
  512. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js.map +0 -1
  513. package/dist/core/extensions/builtin/claude-agent-sdk/stream.d.ts.map +0 -1
  514. package/dist/core/extensions/builtin/claude-agent-sdk/stream.js.map +0 -1
  515. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts +0 -0
  516. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js +0 -0
  517. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts +0 -0
  518. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js +0 -0
  519. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts +0 -0
  520. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js +0 -0
  521. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts +0 -0
  522. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js +0 -0
  523. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts +0 -0
  524. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts +0 -0
  525. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js +0 -0
  526. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts +0 -0
  527. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js +0 -0
  528. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts +0 -0
  529. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-registry.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAkDhD;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAClB,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC5C,KAAK,CAAgC;IACrC,SAAS,CAAoE;IAEtF,YAAY,IAAmC,EAAE,OAAgC;QAChF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,QAAQ,CAAC;IACpC,CAAC;IAED,QAAQ;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACnD,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;SACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,OAA+B;QACvC,MAAM,MAAM,GAAkB;YAC7B,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,EAAE;YACd,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,SAAS;YAC5B,eAAe,EAAE,SAAS;SAC1B,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,yFAAyF;QACzF,6EAA6E;QAC7E,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACnF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,QAAQ;QACP,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM;gBAAE,SAAS;YAC5B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC;IACf,CAAC;IAED,KAAK,CAAC,EAAU;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO,WAAW,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,YAAY,CAAC;QACxC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO;QACN,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACzE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;IACtB,CAAC;IAED,aAAa;QACZ,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ,CAAC,MAAqB,EAAE,KAAa;QAC5C,IAAI,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjD,IAAI,SAAS,GAAG,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1C,SAAS,CAAC;YACT,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,OAAO,GAAG,CAAC;gBAAE,MAAM;YACvB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5C,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACrE,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YAC5E,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,OAAO,CAAC,MAAqB;QAC5B,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO;QAC3B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,GAAG,CAAC;QACnF,IAAI,CAAC,KAAK,CAAC;YACV,IAAI,EAAE,SAAS;YACf,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,WAAW,MAAM,GAAG,QAAQ,EAAE;SACvC,CAAC,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,MAAqB;QACnC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC;IAC5B,CAAC;CACD","sourcesContent":["import type { TerminalRuntimeSession } from \"./runtime-session.ts\";\nimport { describeExit } from \"./tools/spawn.ts\";\n\nexport interface MonitorLineEvent {\n\treadonly type: \"line\";\n\treadonly id: string;\n\treadonly description: string;\n\treadonly line: string;\n}\n\nexport interface MonitorSummaryEvent {\n\treadonly type: \"summary\";\n\treadonly id: string;\n\treadonly description: string;\n\treadonly summary: string;\n}\n\nexport type MonitorEvent = MonitorLineEvent | MonitorSummaryEvent;\n\nexport type MonitorRearmResult = \"rearmed\" | \"not_paused\" | \"not_found\";\n\nexport interface MonitorSnapshotEntry {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly paused: boolean;\n}\n\nexport interface MonitorRegistryOptions {\n\t/** Observes every registry transition (register/pause/rearm/settle/dispose) with the live snapshot. */\n\treadonly onChange?: (snapshot: readonly MonitorSnapshotEntry[]) => void;\n}\n\nexport interface RegisterMonitorOptions {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly runtime: TerminalRuntimeSession;\n\treadonly filter?: RegExp;\n}\n\ninterface MonitorRecord {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly runtime: TerminalRuntimeSession;\n\treadonly filter: RegExp | undefined;\n\tlineBuffer: string;\n\tpaused: boolean;\n\tsettled: boolean;\n\tunsubscribeOutput: (() => void) | undefined;\n\tunsubscribeExit: (() => void) | undefined;\n}\n\n/**\n * Tracks active monitor sessions alongside the terminal manager's existing bash-id registry.\n * Output is deliberately retained only by TerminalRuntimeSession's bounded history; this\n * registry holds at most one unfinished line for each live monitor.\n */\nexport class MonitorRegistry {\n\treadonly #records = new Map<string, MonitorRecord>();\n\treadonly #emit: (event: MonitorEvent) => void;\n\treadonly #onChange: ((snapshot: readonly MonitorSnapshotEntry[]) => void) | undefined;\n\n\tconstructor(emit: (event: MonitorEvent) => void, options?: MonitorRegistryOptions) {\n\t\tthis.#emit = emit;\n\t\tthis.#onChange = options?.onChange;\n\t}\n\n\tsnapshot(): readonly MonitorSnapshotEntry[] {\n\t\treturn [...this.#records.values()].map((record) => ({\n\t\t\tid: record.id,\n\t\t\tdescription: record.description,\n\t\t\tpaused: record.paused,\n\t\t}));\n\t}\n\n\tregister(options: RegisterMonitorOptions): void {\n\t\tconst record: MonitorRecord = {\n\t\t\tid: options.id,\n\t\t\tdescription: options.description,\n\t\t\truntime: options.runtime,\n\t\t\tfilter: options.filter,\n\t\t\tlineBuffer: \"\",\n\t\t\tpaused: false,\n\t\t\tsettled: false,\n\t\t\tunsubscribeOutput: undefined,\n\t\t\tunsubscribeExit: undefined,\n\t\t};\n\t\tthis.#records.set(record.id, record);\n\t\tthis.#notifyChange();\n\n\t\t// Runtime output is already bounded. Read what was produced before monitor registration,\n\t\t// then subscribe synchronously so a fast watcher cannot lose its first line.\n\t\tthis.#consume(record, record.runtime.fullOutput());\n\t\trecord.unsubscribeOutput = record.runtime.onOutput((chunk) => this.#consume(record, chunk));\n\t\trecord.unsubscribeExit = record.runtime.session.onExit(() => this.#settle(record));\n\t\tif (record.runtime.exited) this.#settle(record);\n\t}\n\n\tpauseAll(): string[] {\n\t\tconst paused: string[] = [];\n\t\tfor (const record of this.#records.values()) {\n\t\t\tif (record.paused) continue;\n\t\t\trecord.paused = true;\n\t\t\tpaused.push(record.id);\n\t\t}\n\t\tif (paused.length > 0) this.#notifyChange();\n\t\treturn paused;\n\t}\n\n\trearm(id: string): MonitorRearmResult {\n\t\tconst record = this.#records.get(id);\n\t\tif (!record) return \"not_found\";\n\t\tif (!record.paused) return \"not_paused\";\n\t\trecord.paused = false;\n\t\tthis.#notifyChange();\n\t\treturn \"rearmed\";\n\t}\n\n\tdispose(): void {\n\t\tfor (const record of this.#records.values()) this.#disposeRecord(record);\n\t\tthis.#records.clear();\n\t\tthis.#notifyChange();\n\t}\n\n\t#notifyChange(): void {\n\t\tthis.#onChange?.(this.snapshot());\n\t}\n\n\t#consume(record: MonitorRecord, chunk: string): void {\n\t\tif (record.settled || chunk.length === 0) return;\n\t\tlet remaining = record.lineBuffer + chunk;\n\t\tfor (;;) {\n\t\t\tconst newline = remaining.indexOf(\"\\n\");\n\t\t\tif (newline < 0) break;\n\t\t\tconst rawLine = remaining.slice(0, newline);\n\t\t\tremaining = remaining.slice(newline + 1);\n\t\t\tconst line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n\t\t\tif (record.paused || (record.filter && !record.filter.test(line))) continue;\n\t\t\tthis.#emit({ type: \"line\", id: record.id, description: record.description, line });\n\t\t}\n\t\trecord.lineBuffer = remaining;\n\t}\n\n\t#settle(record: MonitorRecord): void {\n\t\tif (record.settled) return;\n\t\trecord.settled = true;\n\t\trecord.unsubscribeOutput?.();\n\t\trecord.unsubscribeExit?.();\n\t\tthis.#records.delete(record.id);\n\t\tthis.#notifyChange();\n\t\tconst status = describeExit(record.runtime) ?? \"exited\";\n\t\tconst code = record.runtime.exitResult?.exitCode;\n\t\tconst codeText = code === null || code === undefined ? \"\" : ` (exit code ${code})`;\n\t\tthis.#emit({\n\t\t\ttype: \"summary\",\n\t\t\tid: record.id,\n\t\t\tdescription: record.description,\n\t\t\tsummary: `watcher ${status}${codeText}`,\n\t\t});\n\t}\n\n\t#disposeRecord(record: MonitorRecord): void {\n\t\trecord.settled = true;\n\t\trecord.unsubscribeOutput?.();\n\t\trecord.unsubscribeExit?.();\n\t}\n}\n"]}
1
+ {"version":3,"file":"monitor-registry.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TerminalRuntimeSession } from \"./runtime-session.ts\";\nimport { describeExit } from \"./tools/spawn.ts\";\n\nexport interface MonitorLineEvent {\n\treadonly type: \"line\";\n\treadonly id: string;\n\treadonly description: string;\n\treadonly line: string;\n}\n\nexport interface MonitorSummaryEvent {\n\treadonly type: \"summary\";\n\treadonly id: string;\n\treadonly description: string;\n\treadonly summary: string;\n}\n\nexport type MonitorEvent = MonitorLineEvent | MonitorSummaryEvent;\n\nexport type MonitorRearmResult = \"rearmed\" | \"not_paused\" | \"not_found\";\n\nexport interface MonitorSnapshotEntry {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly paused: boolean;\n\t/** Epoch milliseconds when the watch registered; feeds the footer's live elapsed label. */\n\treadonly startedAtMs: number;\n}\n\nexport interface MonitorRegistryOptions {\n\t/** Observes every registry transition (register/pause/rearm/settle/dispose) with the live snapshot. */\n\treadonly onChange?: (snapshot: readonly MonitorSnapshotEntry[]) => void;\n}\n\nexport interface RegisterMonitorOptions {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly runtime: TerminalRuntimeSession;\n\treadonly filter?: RegExp;\n}\n\ninterface MonitorRecord {\n\treadonly id: string;\n\treadonly description: string;\n\treadonly startedAtMs: number;\n\treadonly runtime: TerminalRuntimeSession;\n\treadonly filter: RegExp | undefined;\n\tlineBuffer: string;\n\tpaused: boolean;\n\tsettled: boolean;\n\tunsubscribeOutput: (() => void) | undefined;\n\tunsubscribeExit: (() => void) | undefined;\n}\n\n/**\n * Tracks active monitor sessions alongside the terminal manager's existing bash-id registry.\n * Output is deliberately retained only by TerminalRuntimeSession's bounded history; this\n * registry holds at most one unfinished line for each live monitor.\n */\nexport class MonitorRegistry {\n\treadonly #records = new Map<string, MonitorRecord>();\n\treadonly #emit: (event: MonitorEvent) => void;\n\treadonly #onChange: ((snapshot: readonly MonitorSnapshotEntry[]) => void) | undefined;\n\n\tconstructor(emit: (event: MonitorEvent) => void, options?: MonitorRegistryOptions) {\n\t\tthis.#emit = emit;\n\t\tthis.#onChange = options?.onChange;\n\t}\n\n\tsnapshot(): readonly MonitorSnapshotEntry[] {\n\t\treturn [...this.#records.values()].map((record) => ({\n\t\t\tid: record.id,\n\t\t\tdescription: record.description,\n\t\t\tpaused: record.paused,\n\t\t\tstartedAtMs: record.startedAtMs,\n\t\t}));\n\t}\n\n\tregister(options: RegisterMonitorOptions): void {\n\t\tconst record: MonitorRecord = {\n\t\t\tid: options.id,\n\t\t\tdescription: options.description,\n\t\t\tstartedAtMs: Date.now(),\n\t\t\truntime: options.runtime,\n\t\t\tfilter: options.filter,\n\t\t\tlineBuffer: \"\",\n\t\t\tpaused: false,\n\t\t\tsettled: false,\n\t\t\tunsubscribeOutput: undefined,\n\t\t\tunsubscribeExit: undefined,\n\t\t};\n\t\tthis.#records.set(record.id, record);\n\t\tthis.#notifyChange();\n\n\t\t// Runtime output is already bounded. Read what was produced before monitor registration,\n\t\t// then subscribe synchronously so a fast watcher cannot lose its first line.\n\t\tthis.#consume(record, record.runtime.fullOutput());\n\t\trecord.unsubscribeOutput = record.runtime.onOutput((chunk) => this.#consume(record, chunk));\n\t\trecord.unsubscribeExit = record.runtime.session.onExit(() => this.#settle(record));\n\t\tif (record.runtime.exited) this.#settle(record);\n\t}\n\n\tpauseAll(): string[] {\n\t\tconst paused: string[] = [];\n\t\tfor (const record of this.#records.values()) {\n\t\t\tif (record.paused) continue;\n\t\t\trecord.paused = true;\n\t\t\tpaused.push(record.id);\n\t\t}\n\t\tif (paused.length > 0) this.#notifyChange();\n\t\treturn paused;\n\t}\n\n\trearm(id: string): MonitorRearmResult {\n\t\tconst record = this.#records.get(id);\n\t\tif (!record) return \"not_found\";\n\t\tif (!record.paused) return \"not_paused\";\n\t\trecord.paused = false;\n\t\tthis.#notifyChange();\n\t\treturn \"rearmed\";\n\t}\n\n\tdispose(): void {\n\t\tfor (const record of this.#records.values()) this.#disposeRecord(record);\n\t\tthis.#records.clear();\n\t\tthis.#notifyChange();\n\t}\n\n\t#notifyChange(): void {\n\t\tthis.#onChange?.(this.snapshot());\n\t}\n\n\t#consume(record: MonitorRecord, chunk: string): void {\n\t\tif (record.settled || chunk.length === 0) return;\n\t\tlet remaining = record.lineBuffer + chunk;\n\t\tfor (;;) {\n\t\t\tconst newline = remaining.indexOf(\"\\n\");\n\t\t\tif (newline < 0) break;\n\t\t\tconst rawLine = remaining.slice(0, newline);\n\t\t\tremaining = remaining.slice(newline + 1);\n\t\t\tconst line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n\t\t\tif (record.paused || (record.filter && !record.filter.test(line))) continue;\n\t\t\tthis.#emit({ type: \"line\", id: record.id, description: record.description, line });\n\t\t}\n\t\trecord.lineBuffer = remaining;\n\t}\n\n\t#settle(record: MonitorRecord): void {\n\t\tif (record.settled) return;\n\t\trecord.settled = true;\n\t\trecord.unsubscribeOutput?.();\n\t\trecord.unsubscribeExit?.();\n\t\tthis.#records.delete(record.id);\n\t\tthis.#notifyChange();\n\t\tconst status = describeExit(record.runtime) ?? \"exited\";\n\t\tconst code = record.runtime.exitResult?.exitCode;\n\t\tconst codeText = code === null || code === undefined ? \"\" : ` (exit code ${code})`;\n\t\tthis.#emit({\n\t\t\ttype: \"summary\",\n\t\t\tid: record.id,\n\t\t\tdescription: record.description,\n\t\t\tsummary: `watcher ${status}${codeText}`,\n\t\t});\n\t}\n\n\t#disposeRecord(record: MonitorRecord): void {\n\t\trecord.settled = true;\n\t\trecord.unsubscribeOutput?.();\n\t\trecord.unsubscribeExit?.();\n\t}\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import type { MonitorSnapshotEntry } from "./monitor-registry.ts";
2
+ /** Footer live-elapsed refresh cadence while at least one watch is active. */
3
+ export declare const MONITOR_STATUS_TICK_INTERVAL_MS = 1000;
4
+ /** Receives the freshly formatted footer status text (undefined clears the status). */
5
+ export type MonitorStatusRender = (status: string | undefined) => void;
6
+ export interface MonitorStatusTickerOptions {
7
+ readonly render: MonitorStatusRender;
8
+ /** Injectable clock for tests; defaults to Date.now. */
9
+ readonly now?: () => number;
10
+ }
11
+ /**
12
+ * Drives a once-per-second footer refresh while monitors are active so the
13
+ * "◉ watching … (Ns)" elapsed label advances live instead of freezing between
14
+ * registry transitions. Mirrors the goal builtin's GoalElapsedTicker: the
15
+ * interval is unref'd so it never keeps the process alive, and ticks that
16
+ * produce the already-rendered label are skipped.
17
+ */
18
+ export declare class MonitorStatusTicker {
19
+ private readonly render;
20
+ private readonly now;
21
+ private intervalId;
22
+ private snapshot;
23
+ private lastRenderedStatus;
24
+ private hasRendered;
25
+ constructor(options: MonitorStatusTickerOptions);
26
+ get running(): boolean;
27
+ /**
28
+ * Point the ticker at the current monitor snapshot, render once immediately,
29
+ * and start the interval when watches are live (or stop it when none remain).
30
+ */
31
+ sync(snapshot: readonly MonitorSnapshotEntry[]): void;
32
+ /** Stop the interval and drop the retained snapshot. */
33
+ stop(): void;
34
+ private stopInterval;
35
+ private tick;
36
+ }
37
+ //# sourceMappingURL=monitor-status-ticker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor-status-ticker.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status-ticker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,8EAA8E;AAC9E,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAEpD,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,wDAAwD;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,OAAO,EAAE,0BAA0B,EAG9C;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,IAAI,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,IAAI,CAYpD;IAED,wDAAwD;IACxD,IAAI,IAAI,IAAI,CAKX;IAED,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,IAAI;CAOZ"}
@@ -0,0 +1,61 @@
1
+ import { formatMonitorStatus } from "./monitor-status.js";
2
+ /** Footer live-elapsed refresh cadence while at least one watch is active. */
3
+ export const MONITOR_STATUS_TICK_INTERVAL_MS = 1000;
4
+ /**
5
+ * Drives a once-per-second footer refresh while monitors are active so the
6
+ * "◉ watching … (Ns)" elapsed label advances live instead of freezing between
7
+ * registry transitions. Mirrors the goal builtin's GoalElapsedTicker: the
8
+ * interval is unref'd so it never keeps the process alive, and ticks that
9
+ * produce the already-rendered label are skipped.
10
+ */
11
+ export class MonitorStatusTicker {
12
+ constructor(options) {
13
+ this.snapshot = [];
14
+ this.hasRendered = false;
15
+ this.render = options.render;
16
+ this.now = options.now ?? Date.now;
17
+ }
18
+ get running() {
19
+ return this.intervalId !== undefined;
20
+ }
21
+ /**
22
+ * Point the ticker at the current monitor snapshot, render once immediately,
23
+ * and start the interval when watches are live (or stop it when none remain).
24
+ */
25
+ sync(snapshot) {
26
+ this.snapshot = snapshot;
27
+ this.hasRendered = false;
28
+ this.tick();
29
+ if (snapshot.length === 0) {
30
+ this.stopInterval();
31
+ return;
32
+ }
33
+ if (this.intervalId !== undefined)
34
+ return;
35
+ const handle = setInterval(() => this.tick(), MONITOR_STATUS_TICK_INTERVAL_MS);
36
+ handle.unref();
37
+ this.intervalId = handle;
38
+ }
39
+ /** Stop the interval and drop the retained snapshot. */
40
+ stop() {
41
+ this.stopInterval();
42
+ this.snapshot = [];
43
+ this.lastRenderedStatus = undefined;
44
+ this.hasRendered = false;
45
+ }
46
+ stopInterval() {
47
+ if (this.intervalId !== undefined) {
48
+ clearInterval(this.intervalId);
49
+ this.intervalId = undefined;
50
+ }
51
+ }
52
+ tick() {
53
+ const status = formatMonitorStatus(this.snapshot, this.now());
54
+ if (this.hasRendered && status === this.lastRenderedStatus)
55
+ return;
56
+ this.hasRendered = true;
57
+ this.lastRenderedStatus = status;
58
+ this.render(status);
59
+ }
60
+ }
61
+ //# sourceMappingURL=monitor-status-ticker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor-status-ticker.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status-ticker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,8EAA8E;AAC9E,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAWpD;;;;;;GAMG;AACH,MAAM,OAAO,mBAAmB;IAQ/B,YAAY,OAAmC;QAJvC,aAAQ,GAAoC,EAAE,CAAC;QAE/C,gBAAW,GAAG,KAAK,CAAC;QAG3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,QAAyC;QAC7C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO;QACR,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,+BAA+B,CAAC,CAAC;QAC/E,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,wDAAwD;IACxD,IAAI;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC1B,CAAC;IAEO,YAAY;QACnB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC7B,CAAC;IACF,CAAC;IAEO,IAAI;QACX,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,WAAW,IAAI,MAAM,KAAK,IAAI,CAAC,kBAAkB;YAAE,OAAO;QACnE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;CACD","sourcesContent":["import type { MonitorSnapshotEntry } from \"./monitor-registry.ts\";\nimport { formatMonitorStatus } from \"./monitor-status.ts\";\n\n/** Footer live-elapsed refresh cadence while at least one watch is active. */\nexport const MONITOR_STATUS_TICK_INTERVAL_MS = 1000;\n\n/** Receives the freshly formatted footer status text (undefined clears the status). */\nexport type MonitorStatusRender = (status: string | undefined) => void;\n\nexport interface MonitorStatusTickerOptions {\n\treadonly render: MonitorStatusRender;\n\t/** Injectable clock for tests; defaults to Date.now. */\n\treadonly now?: () => number;\n}\n\n/**\n * Drives a once-per-second footer refresh while monitors are active so the\n * \"◉ watching … (Ns)\" elapsed label advances live instead of freezing between\n * registry transitions. Mirrors the goal builtin's GoalElapsedTicker: the\n * interval is unref'd so it never keeps the process alive, and ticks that\n * produce the already-rendered label are skipped.\n */\nexport class MonitorStatusTicker {\n\tprivate readonly render: MonitorStatusRender;\n\tprivate readonly now: () => number;\n\tprivate intervalId: NodeJS.Timeout | undefined;\n\tprivate snapshot: readonly MonitorSnapshotEntry[] = [];\n\tprivate lastRenderedStatus: string | undefined;\n\tprivate hasRendered = false;\n\n\tconstructor(options: MonitorStatusTickerOptions) {\n\t\tthis.render = options.render;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tget running(): boolean {\n\t\treturn this.intervalId !== undefined;\n\t}\n\n\t/**\n\t * Point the ticker at the current monitor snapshot, render once immediately,\n\t * and start the interval when watches are live (or stop it when none remain).\n\t */\n\tsync(snapshot: readonly MonitorSnapshotEntry[]): void {\n\t\tthis.snapshot = snapshot;\n\t\tthis.hasRendered = false;\n\t\tthis.tick();\n\t\tif (snapshot.length === 0) {\n\t\t\tthis.stopInterval();\n\t\t\treturn;\n\t\t}\n\t\tif (this.intervalId !== undefined) return;\n\t\tconst handle = setInterval(() => this.tick(), MONITOR_STATUS_TICK_INTERVAL_MS);\n\t\thandle.unref();\n\t\tthis.intervalId = handle;\n\t}\n\n\t/** Stop the interval and drop the retained snapshot. */\n\tstop(): void {\n\t\tthis.stopInterval();\n\t\tthis.snapshot = [];\n\t\tthis.lastRenderedStatus = undefined;\n\t\tthis.hasRendered = false;\n\t}\n\n\tprivate stopInterval(): void {\n\t\tif (this.intervalId !== undefined) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = undefined;\n\t\t}\n\t}\n\n\tprivate tick(): void {\n\t\tconst status = formatMonitorStatus(this.snapshot, this.now());\n\t\tif (this.hasRendered && status === this.lastRenderedStatus) return;\n\t\tthis.hasRendered = true;\n\t\tthis.lastRenderedStatus = status;\n\t\tthis.render(status);\n\t}\n}\n"]}
@@ -1,5 +1,13 @@
1
1
  import type { MonitorSnapshotEntry } from "./monitor-registry.ts";
2
2
  export declare const MONITOR_STATUS_KEY = "monitors";
3
+ /**
4
+ * Goal-style compact elapsed label (`5s`, `3m`, `2h 30m`, `1d 2h 3m`). Mirrors
5
+ * `formatGoalElapsedSeconds` in the goal builtin; kept local so this builtin stays
6
+ * self-contained, matching the existing monitor/eval status-file duplication.
7
+ */
8
+ export declare function formatElapsedSeconds(value: number): string;
9
+ /** Whole seconds since the oldest watch registered; never negative when the clock moves backwards. */
10
+ export declare function monitorElapsedSeconds(snapshot: readonly MonitorSnapshotEntry[], nowMs: number): number;
3
11
  /** Brief footer text for the active monitors; undefined clears the status. */
4
- export declare function formatMonitorStatus(snapshot: readonly MonitorSnapshotEntry[]): string | undefined;
12
+ export declare function formatMonitorStatus(snapshot: readonly MonitorSnapshotEntry[], nowMs: number): string | undefined;
5
13
  //# sourceMappingURL=monitor-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-status.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,eAAO,MAAM,kBAAkB,aAAa,CAAC;AA2B7C,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,GAAG,SAAS,CAYjG"}
1
+ {"version":3,"file":"monitor-status.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,eAAO,MAAM,kBAAkB,aAAa,CAAC;AA2B7C;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED,sGAAsG;AACtG,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtG;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAahH"}
@@ -23,12 +23,45 @@ function packDescriptions(names, budget) {
23
23
  const tail = names.length > 1 ? ` +${names.length - 1} more` : "";
24
24
  return truncateEnd(names[0] ?? "", Math.max(1, budget - tail.length)) + tail;
25
25
  }
26
+ /**
27
+ * Goal-style compact elapsed label (`5s`, `3m`, `2h 30m`, `1d 2h 3m`). Mirrors
28
+ * `formatGoalElapsedSeconds` in the goal builtin; kept local so this builtin stays
29
+ * self-contained, matching the existing monitor/eval status-file duplication.
30
+ */
31
+ export function formatElapsedSeconds(value) {
32
+ const seconds = Math.max(0, Math.trunc(value));
33
+ if (seconds < 60)
34
+ return `${seconds}s`;
35
+ const minutes = Math.trunc(seconds / 60);
36
+ if (minutes < 60)
37
+ return `${minutes}m`;
38
+ const hours = Math.trunc(minutes / 60);
39
+ const remainingMinutes = minutes % 60;
40
+ if (hours >= 24) {
41
+ const days = Math.trunc(hours / 24);
42
+ const remainingHours = hours % 24;
43
+ return `${days}d ${remainingHours}h ${remainingMinutes}m`;
44
+ }
45
+ if (remainingMinutes === 0)
46
+ return `${hours}h`;
47
+ return `${hours}h ${remainingMinutes}m`;
48
+ }
49
+ /** Whole seconds since the oldest watch registered; never negative when the clock moves backwards. */
50
+ export function monitorElapsedSeconds(snapshot, nowMs) {
51
+ let oldest = Number.POSITIVE_INFINITY;
52
+ for (const entry of snapshot)
53
+ oldest = Math.min(oldest, entry.startedAtMs);
54
+ if (!Number.isFinite(oldest))
55
+ return 0;
56
+ return Math.max(0, Math.round((nowMs - oldest) / 1000));
57
+ }
26
58
  /** Brief footer text for the active monitors; undefined clears the status. */
27
- export function formatMonitorStatus(snapshot) {
59
+ export function formatMonitorStatus(snapshot, nowMs) {
28
60
  if (snapshot.length === 0)
29
61
  return undefined;
30
62
  const pausedCount = snapshot.filter((entry) => entry.paused).length;
31
- const suffix = pausedCount === 0 ? "" : pausedCount === snapshot.length ? " (paused)" : ` (${pausedCount} paused)`;
63
+ const pausedPart = pausedCount === 0 ? "" : pausedCount === snapshot.length ? ", paused" : `, ${pausedCount} paused`;
64
+ const suffix = ` (${formatElapsedSeconds(monitorElapsedSeconds(snapshot, nowMs))}${pausedPart})`;
32
65
  if (snapshot.length === 1) {
33
66
  const head = `${WATCH_GLYPH} watching `;
34
67
  const description = truncateEnd(snapshot[0]?.description ?? "", MAX_STATUS_LENGTH - head.length - suffix.length);
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-status.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C,gFAAgF;AAChF,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,gGAAgG;AAChG,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,SAAS,WAAW,CAAC,IAAY,EAAE,GAAW;IAC7C,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAAwB,EAAE,MAAc;IACjE,KAAK,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACjD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACxC,MAAM,IAAI,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,WAAW,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM;YAAE,OAAO,MAAM,GAAG,IAAI,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;AAC9E,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,QAAyC;IAC5E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACpE,MAAM,MAAM,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,UAAU,CAAC;IACnH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,WAAW,YAAY,CAAC;QACxC,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,EAAE,EAAE,iBAAiB,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACjH,OAAO,IAAI,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,WAAW,aAAa,QAAQ,CAAC,MAAM,IAAI,CAAC;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACzD,OAAO,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;AACjG,CAAC","sourcesContent":["import type { MonitorSnapshotEntry } from \"./monitor-registry.ts\";\n\nexport const MONITOR_STATUS_KEY = \"monitors\";\n\n/** The footer shares one status line with other extensions; keep this brief. */\nconst MAX_STATUS_LENGTH = 48;\n/** Marks the status as a live watch at a glance (same glyph family as the session selector). */\nconst WATCH_GLYPH = \"◉\";\n\nfunction truncateEnd(text: string, max: number): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, Math.max(0, max - 1))}…`;\n}\n\n/**\n * Fits as many whole descriptions as possible into the budget, folding the rest\n * into a `+N more` counter so the monitor count is never truncated away.\n */\nfunction packDescriptions(names: readonly string[], budget: number): string {\n\tfor (let kept = names.length; kept >= 1; kept--) {\n\t\tconst hiddenCount = names.length - kept;\n\t\tconst tail = hiddenCount > 0 ? ` +${hiddenCount} more` : \"\";\n\t\tconst joined = names.slice(0, kept).join(\", \");\n\t\tif (joined.length + tail.length <= budget) return joined + tail;\n\t}\n\tconst tail = names.length > 1 ? ` +${names.length - 1} more` : \"\";\n\treturn truncateEnd(names[0] ?? \"\", Math.max(1, budget - tail.length)) + tail;\n}\n\n/** Brief footer text for the active monitors; undefined clears the status. */\nexport function formatMonitorStatus(snapshot: readonly MonitorSnapshotEntry[]): string | undefined {\n\tif (snapshot.length === 0) return undefined;\n\tconst pausedCount = snapshot.filter((entry) => entry.paused).length;\n\tconst suffix = pausedCount === 0 ? \"\" : pausedCount === snapshot.length ? \" (paused)\" : ` (${pausedCount} paused)`;\n\tif (snapshot.length === 1) {\n\t\tconst head = `${WATCH_GLYPH} watching `;\n\t\tconst description = truncateEnd(snapshot[0]?.description ?? \"\", MAX_STATUS_LENGTH - head.length - suffix.length);\n\t\treturn head + description + suffix;\n\t}\n\tconst head = `${WATCH_GLYPH} watching ${snapshot.length}: `;\n\tconst names = snapshot.map((entry) => entry.description);\n\treturn head + packDescriptions(names, MAX_STATUS_LENGTH - head.length - suffix.length) + suffix;\n}\n"]}
1
+ {"version":3,"file":"monitor-status.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/monitor-status.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MonitorSnapshotEntry } from \"./monitor-registry.ts\";\n\nexport const MONITOR_STATUS_KEY = \"monitors\";\n\n/** The footer shares one status line with other extensions; keep this brief. */\nconst MAX_STATUS_LENGTH = 48;\n/** Marks the status as a live watch at a glance (same glyph family as the session selector). */\nconst WATCH_GLYPH = \"◉\";\n\nfunction truncateEnd(text: string, max: number): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, Math.max(0, max - 1))}…`;\n}\n\n/**\n * Fits as many whole descriptions as possible into the budget, folding the rest\n * into a `+N more` counter so the monitor count is never truncated away.\n */\nfunction packDescriptions(names: readonly string[], budget: number): string {\n\tfor (let kept = names.length; kept >= 1; kept--) {\n\t\tconst hiddenCount = names.length - kept;\n\t\tconst tail = hiddenCount > 0 ? ` +${hiddenCount} more` : \"\";\n\t\tconst joined = names.slice(0, kept).join(\", \");\n\t\tif (joined.length + tail.length <= budget) return joined + tail;\n\t}\n\tconst tail = names.length > 1 ? ` +${names.length - 1} more` : \"\";\n\treturn truncateEnd(names[0] ?? \"\", Math.max(1, budget - tail.length)) + tail;\n}\n\n/**\n * Goal-style compact elapsed label (`5s`, `3m`, `2h 30m`, `1d 2h 3m`). Mirrors\n * `formatGoalElapsedSeconds` in the goal builtin; kept local so this builtin stays\n * self-contained, matching the existing monitor/eval status-file duplication.\n */\nexport function formatElapsedSeconds(value: number): string {\n\tconst seconds = Math.max(0, Math.trunc(value));\n\tif (seconds < 60) return `${seconds}s`;\n\tconst minutes = Math.trunc(seconds / 60);\n\tif (minutes < 60) return `${minutes}m`;\n\tconst hours = Math.trunc(minutes / 60);\n\tconst remainingMinutes = minutes % 60;\n\tif (hours >= 24) {\n\t\tconst days = Math.trunc(hours / 24);\n\t\tconst remainingHours = hours % 24;\n\t\treturn `${days}d ${remainingHours}h ${remainingMinutes}m`;\n\t}\n\tif (remainingMinutes === 0) return `${hours}h`;\n\treturn `${hours}h ${remainingMinutes}m`;\n}\n\n/** Whole seconds since the oldest watch registered; never negative when the clock moves backwards. */\nexport function monitorElapsedSeconds(snapshot: readonly MonitorSnapshotEntry[], nowMs: number): number {\n\tlet oldest = Number.POSITIVE_INFINITY;\n\tfor (const entry of snapshot) oldest = Math.min(oldest, entry.startedAtMs);\n\tif (!Number.isFinite(oldest)) return 0;\n\treturn Math.max(0, Math.round((nowMs - oldest) / 1000));\n}\n\n/** Brief footer text for the active monitors; undefined clears the status. */\nexport function formatMonitorStatus(snapshot: readonly MonitorSnapshotEntry[], nowMs: number): string | undefined {\n\tif (snapshot.length === 0) return undefined;\n\tconst pausedCount = snapshot.filter((entry) => entry.paused).length;\n\tconst pausedPart = pausedCount === 0 ? \"\" : pausedCount === snapshot.length ? \", paused\" : `, ${pausedCount} paused`;\n\tconst suffix = ` (${formatElapsedSeconds(monitorElapsedSeconds(snapshot, nowMs))}${pausedPart})`;\n\tif (snapshot.length === 1) {\n\t\tconst head = `${WATCH_GLYPH} watching `;\n\t\tconst description = truncateEnd(snapshot[0]?.description ?? \"\", MAX_STATUS_LENGTH - head.length - suffix.length);\n\t\treturn head + description + suffix;\n\t}\n\tconst head = `${WATCH_GLYPH} watching ${snapshot.length}: `;\n\tconst names = snapshot.map((entry) => entry.description);\n\treturn head + packDescriptions(names, MAX_STATUS_LENGTH - head.length - suffix.length) + suffix;\n}\n"]}
@@ -1,3 +1,3 @@
1
- /** Removes orphan Anthropic tool_result blocks from provider payload messages. */
1
+ /** Repairs Anthropic client tool_use/tool_result adjacency at the final provider boundary. */
2
2
  export declare function sanitizeAnthropicPayload(payload: unknown): unknown;
3
3
  //# sourceMappingURL=sanitize-anthropic-payload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize-anthropic-payload.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.ts"],"names":[],"mappings":"AAiCA,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAuDlE"}
1
+ {"version":3,"file":"sanitize-anthropic-payload.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.ts"],"names":[],"mappings":"AAsGA,8FAA8F;AAC9F,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAoDlE"}
@@ -13,6 +13,7 @@ function isToolUseBlock(block) {
13
13
  function isToolResultBlock(block) {
14
14
  return block.type === "tool_result";
15
15
  }
16
+ const SYNTHETIC_OUTPUT = "Tool output unavailable (interrupted before result)";
16
17
  function isMessageWithArrayContent(value, role) {
17
18
  if (!isObject(value) || value.role !== role || !Array.isArray(value.content))
18
19
  return false;
@@ -22,48 +23,106 @@ function isMessageWithArrayContent(value, role) {
22
23
  }
23
24
  return true;
24
25
  }
25
- /** Removes orphan Anthropic tool_result blocks from provider payload messages. */
26
- export function sanitizeAnthropicPayload(payload) {
27
- if (!hasMessagesArray(payload))
28
- return payload;
29
- const toolUseIds = new Set();
30
- for (const unknownMessage of payload.messages) {
31
- if (!isMessageWithArrayContent(unknownMessage, "assistant"))
26
+ function isUserMessageWithStringContent(value) {
27
+ return isObject(value) && value.role === "user" && typeof value.content === "string";
28
+ }
29
+ function getToolUseIds(message) {
30
+ const ids = [];
31
+ const seen = new Set();
32
+ for (const block of message.content) {
33
+ if (!isToolUseBlock(block) || block.id.length === 0 || seen.has(block.id))
34
+ continue;
35
+ seen.add(block.id);
36
+ ids.push(block.id);
37
+ }
38
+ return ids;
39
+ }
40
+ function syntheticToolResult(toolUseId) {
41
+ return {
42
+ type: "tool_result",
43
+ tool_use_id: toolUseId,
44
+ content: SYNTHETIC_OUTPUT,
45
+ is_error: true,
46
+ };
47
+ }
48
+ function sameBlocks(left, right) {
49
+ return left.length === right.length && left.every((block, index) => block === right[index]);
50
+ }
51
+ function repairFollowingUserMessage(message, expectedIds) {
52
+ const expected = new Set(expectedIds);
53
+ const found = new Set();
54
+ const results = [];
55
+ const ordinary = [];
56
+ for (const block of message.content) {
57
+ if (!isToolResultBlock(block)) {
58
+ ordinary.push(block);
32
59
  continue;
33
- for (const unknownBlock of unknownMessage.content) {
34
- if (isToolUseBlock(unknownBlock) && unknownBlock.id.length > 0)
35
- toolUseIds.add(unknownBlock.id);
36
60
  }
61
+ const id = block.tool_use_id;
62
+ if (typeof id !== "string" || !expected.has(id) || found.has(id))
63
+ continue;
64
+ found.add(id);
65
+ results.push(block);
66
+ }
67
+ for (const id of expectedIds) {
68
+ if (!found.has(id))
69
+ results.push(syntheticToolResult(id));
37
70
  }
71
+ const content = [...results, ...ordinary];
72
+ if (sameBlocks(content, message.content))
73
+ return { message, changed: false };
74
+ return { message: { ...message, content }, changed: true };
75
+ }
76
+ function removeOrphanResults(message) {
77
+ const content = message.content.filter((block) => !isToolResultBlock(block));
78
+ if (content.length === message.content.length)
79
+ return { message, changed: false };
80
+ if (content.length === 0)
81
+ return { changed: true };
82
+ return { message: { ...message, content }, changed: true };
83
+ }
84
+ /** Repairs Anthropic client tool_use/tool_result adjacency at the final provider boundary. */
85
+ export function sanitizeAnthropicPayload(payload) {
86
+ if (!hasMessagesArray(payload))
87
+ return payload;
38
88
  let changed = false;
39
89
  const sanitizedMessages = [];
40
- for (const unknownMessage of payload.messages) {
41
- if (!isMessageWithArrayContent(unknownMessage, "user")) {
90
+ for (let index = 0; index < payload.messages.length; index++) {
91
+ const unknownMessage = payload.messages[index];
92
+ if (isMessageWithArrayContent(unknownMessage, "assistant")) {
42
93
  sanitizedMessages.push(unknownMessage);
43
- continue;
44
- }
45
- const originalContent = unknownMessage.content;
46
- const nextContent = [];
47
- let messageChanged = false;
48
- for (const block of originalContent) {
49
- if (!isToolResultBlock(block)) {
50
- nextContent.push(block);
94
+ const expectedIds = getToolUseIds(unknownMessage);
95
+ if (expectedIds.length === 0)
96
+ continue;
97
+ const nextMessage = payload.messages[index + 1];
98
+ if (isMessageWithArrayContent(nextMessage, "user")) {
99
+ const repaired = repairFollowingUserMessage(nextMessage, expectedIds);
100
+ sanitizedMessages.push(repaired.message);
101
+ changed ||= repaired.changed;
102
+ index++;
51
103
  continue;
52
104
  }
53
- const toolUseId = block.tool_use_id;
54
- if (typeof toolUseId !== "string" || toolUseId.length === 0 || !toolUseIds.has(toolUseId)) {
55
- messageChanged = true;
105
+ if (isUserMessageWithStringContent(nextMessage)) {
106
+ sanitizedMessages.push({
107
+ ...nextMessage,
108
+ content: [...expectedIds.map(syntheticToolResult), { type: "text", text: nextMessage.content }],
109
+ });
110
+ changed = true;
111
+ index++;
56
112
  continue;
57
113
  }
58
- nextContent.push(block);
59
- }
60
- if (nextContent.length === 0) {
114
+ sanitizedMessages.push({
115
+ role: "user",
116
+ content: expectedIds.map(syntheticToolResult),
117
+ });
61
118
  changed = true;
62
119
  continue;
63
120
  }
64
- if (messageChanged) {
65
- changed = true;
66
- sanitizedMessages.push({ ...unknownMessage, content: nextContent });
121
+ if (isMessageWithArrayContent(unknownMessage, "user")) {
122
+ const repaired = removeOrphanResults(unknownMessage);
123
+ if (repaired.message)
124
+ sanitizedMessages.push(repaired.message);
125
+ changed ||= repaired.changed;
67
126
  continue;
68
127
  }
69
128
  sanitizedMessages.push(unknownMessage);
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize-anthropic-payload.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlockParam, MessageParam } from \"@anthropic-ai/sdk/resources/messages.js\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasMessagesArray(value: unknown): value is { messages: unknown[] } {\n\treturn isObject(value) && Array.isArray(value.messages);\n}\n\nfunction isContentBlockParam(value: unknown): value is ContentBlockParam {\n\treturn isObject(value) && typeof value.type === \"string\";\n}\n\nfunction isToolUseBlock(block: ContentBlockParam): block is Extract<ContentBlockParam, { type: \"tool_use\" }> {\n\treturn block.type === \"tool_use\" && \"id\" in block && typeof block.id === \"string\";\n}\n\nfunction isToolResultBlock(block: ContentBlockParam): block is Extract<ContentBlockParam, { type: \"tool_result\" }> {\n\treturn block.type === \"tool_result\";\n}\n\nfunction isMessageWithArrayContent(\n\tvalue: unknown,\n\trole: MessageParam[\"role\"],\n): value is MessageParam & { content: ContentBlockParam[] } {\n\tif (!isObject(value) || value.role !== role || !Array.isArray(value.content)) return false;\n\tfor (const block of value.content) {\n\t\tif (!isContentBlockParam(block)) return false;\n\t}\n\treturn true;\n}\n\n/** Removes orphan Anthropic tool_result blocks from provider payload messages. */\nexport function sanitizeAnthropicPayload(payload: unknown): unknown {\n\tif (!hasMessagesArray(payload)) return payload;\n\n\tconst toolUseIds = new Set<string>();\n\tfor (const unknownMessage of payload.messages) {\n\t\tif (!isMessageWithArrayContent(unknownMessage, \"assistant\")) continue;\n\t\tfor (const unknownBlock of unknownMessage.content) {\n\t\t\tif (isToolUseBlock(unknownBlock) && unknownBlock.id.length > 0) toolUseIds.add(unknownBlock.id);\n\t\t}\n\t}\n\n\tlet changed = false;\n\tconst sanitizedMessages: unknown[] = [];\n\n\tfor (const unknownMessage of payload.messages) {\n\t\tif (!isMessageWithArrayContent(unknownMessage, \"user\")) {\n\t\t\tsanitizedMessages.push(unknownMessage);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst originalContent = unknownMessage.content;\n\t\tconst nextContent: ContentBlockParam[] = [];\n\t\tlet messageChanged = false;\n\n\t\tfor (const block of originalContent) {\n\t\t\tif (!isToolResultBlock(block)) {\n\t\t\t\tnextContent.push(block);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst toolUseId = block.tool_use_id;\n\t\t\tif (typeof toolUseId !== \"string\" || toolUseId.length === 0 || !toolUseIds.has(toolUseId)) {\n\t\t\t\tmessageChanged = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tnextContent.push(block);\n\t\t}\n\n\t\tif (nextContent.length === 0) {\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (messageChanged) {\n\t\t\tchanged = true;\n\t\t\tsanitizedMessages.push({ ...unknownMessage, content: nextContent });\n\t\t\tcontinue;\n\t\t}\n\n\t\tsanitizedMessages.push(unknownMessage);\n\t}\n\n\tif (!changed) return payload;\n\treturn { ...payload, messages: sanitizedMessages };\n}\n"]}
1
+ {"version":3,"file":"sanitize-anthropic-payload.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlockParam, MessageParam } from \"@anthropic-ai/sdk/resources/messages.js\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction hasMessagesArray(value: unknown): value is { messages: unknown[] } {\n\treturn isObject(value) && Array.isArray(value.messages);\n}\n\nfunction isContentBlockParam(value: unknown): value is ContentBlockParam {\n\treturn isObject(value) && typeof value.type === \"string\";\n}\n\nfunction isToolUseBlock(block: ContentBlockParam): block is Extract<ContentBlockParam, { type: \"tool_use\" }> {\n\treturn block.type === \"tool_use\" && \"id\" in block && typeof block.id === \"string\";\n}\n\nfunction isToolResultBlock(block: ContentBlockParam): block is Extract<ContentBlockParam, { type: \"tool_result\" }> {\n\treturn block.type === \"tool_result\";\n}\n\nconst SYNTHETIC_OUTPUT = \"Tool output unavailable (interrupted before result)\";\n\nfunction isMessageWithArrayContent<Role extends MessageParam[\"role\"]>(\n\tvalue: unknown,\n\trole: Role,\n): value is MessageParam & { role: Role; content: ContentBlockParam[] } {\n\tif (!isObject(value) || value.role !== role || !Array.isArray(value.content)) return false;\n\tfor (const block of value.content) {\n\t\tif (!isContentBlockParam(block)) return false;\n\t}\n\treturn true;\n}\n\nfunction isUserMessageWithStringContent(value: unknown): value is MessageParam & { role: \"user\"; content: string } {\n\treturn isObject(value) && value.role === \"user\" && typeof value.content === \"string\";\n}\n\nfunction getToolUseIds(message: MessageParam & { content: ContentBlockParam[] }): string[] {\n\tconst ids: string[] = [];\n\tconst seen = new Set<string>();\n\tfor (const block of message.content) {\n\t\tif (!isToolUseBlock(block) || block.id.length === 0 || seen.has(block.id)) continue;\n\t\tseen.add(block.id);\n\t\tids.push(block.id);\n\t}\n\treturn ids;\n}\n\nfunction syntheticToolResult(toolUseId: string): Extract<ContentBlockParam, { type: \"tool_result\" }> {\n\treturn {\n\t\ttype: \"tool_result\",\n\t\ttool_use_id: toolUseId,\n\t\tcontent: SYNTHETIC_OUTPUT,\n\t\tis_error: true,\n\t};\n}\n\nfunction sameBlocks(left: ContentBlockParam[], right: ContentBlockParam[]): boolean {\n\treturn left.length === right.length && left.every((block, index) => block === right[index]);\n}\n\nfunction repairFollowingUserMessage(\n\tmessage: MessageParam & { role: \"user\"; content: ContentBlockParam[] },\n\texpectedIds: string[],\n): { message: MessageParam; changed: boolean } {\n\tconst expected = new Set(expectedIds);\n\tconst found = new Set<string>();\n\tconst results: ContentBlockParam[] = [];\n\tconst ordinary: ContentBlockParam[] = [];\n\n\tfor (const block of message.content) {\n\t\tif (!isToolResultBlock(block)) {\n\t\t\tordinary.push(block);\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = block.tool_use_id;\n\t\tif (typeof id !== \"string\" || !expected.has(id) || found.has(id)) continue;\n\t\tfound.add(id);\n\t\tresults.push(block);\n\t}\n\n\tfor (const id of expectedIds) {\n\t\tif (!found.has(id)) results.push(syntheticToolResult(id));\n\t}\n\n\tconst content = [...results, ...ordinary];\n\tif (sameBlocks(content, message.content)) return { message, changed: false };\n\treturn { message: { ...message, content }, changed: true };\n}\n\nfunction removeOrphanResults(message: MessageParam & { role: \"user\"; content: ContentBlockParam[] }): {\n\tmessage?: MessageParam;\n\tchanged: boolean;\n} {\n\tconst content = message.content.filter((block) => !isToolResultBlock(block));\n\tif (content.length === message.content.length) return { message, changed: false };\n\tif (content.length === 0) return { changed: true };\n\treturn { message: { ...message, content }, changed: true };\n}\n\n/** Repairs Anthropic client tool_use/tool_result adjacency at the final provider boundary. */\nexport function sanitizeAnthropicPayload(payload: unknown): unknown {\n\tif (!hasMessagesArray(payload)) return payload;\n\n\tlet changed = false;\n\tconst sanitizedMessages: unknown[] = [];\n\n\tfor (let index = 0; index < payload.messages.length; index++) {\n\t\tconst unknownMessage = payload.messages[index];\n\t\tif (isMessageWithArrayContent(unknownMessage, \"assistant\")) {\n\t\t\tsanitizedMessages.push(unknownMessage);\n\t\t\tconst expectedIds = getToolUseIds(unknownMessage);\n\t\t\tif (expectedIds.length === 0) continue;\n\n\t\t\tconst nextMessage = payload.messages[index + 1];\n\t\t\tif (isMessageWithArrayContent(nextMessage, \"user\")) {\n\t\t\t\tconst repaired = repairFollowingUserMessage(nextMessage, expectedIds);\n\t\t\t\tsanitizedMessages.push(repaired.message);\n\t\t\t\tchanged ||= repaired.changed;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isUserMessageWithStringContent(nextMessage)) {\n\t\t\t\tsanitizedMessages.push({\n\t\t\t\t\t...nextMessage,\n\t\t\t\t\tcontent: [...expectedIds.map(syntheticToolResult), { type: \"text\", text: nextMessage.content }],\n\t\t\t\t});\n\t\t\t\tchanged = true;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tsanitizedMessages.push({\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: expectedIds.map(syntheticToolResult),\n\t\t\t});\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isMessageWithArrayContent(unknownMessage, \"user\")) {\n\t\t\tconst repaired = removeOrphanResults(unknownMessage);\n\t\t\tif (repaired.message) sanitizedMessages.push(repaired.message);\n\t\t\tchanged ||= repaired.changed;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsanitizedMessages.push(unknownMessage);\n\t}\n\n\tif (!changed) return payload;\n\treturn { ...payload, messages: sanitizedMessages };\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { TtsrRule } from "./types.ts";
2
+ export declare const FABRICATED_UNAVAILABLE_TOOL_CALL_RULE_NAME = "fabricated-unavailable-tool-call";
3
+ export declare const BUILTIN_TTSR_RULES: readonly TtsrRule[];
4
+ //# sourceMappingURL=builtin-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin-rules.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/builtin-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,0CAA0C,qCAAqC,CAAC;AAE7F,eAAO,MAAM,kBAAkB,EAAE,SAAS,QAAQ,EAiBjD,CAAC"}
@@ -0,0 +1,20 @@
1
+ export const FABRICATED_UNAVAILABLE_TOOL_CALL_RULE_NAME = "fabricated-unavailable-tool-call";
2
+ export const BUILTIN_TTSR_RULES = [
3
+ {
4
+ name: FABRICATED_UNAVAILABLE_TOOL_CALL_RULE_NAME,
5
+ content: [
6
+ "Your previous output imitated an unavailable historical tool call as inert text instead of taking action.",
7
+ "Redo the interrupted step now. Call your real tools that are actually available to you, such as edit or write for file changes.",
8
+ "Do not print or imitate unavailable-tool transcript envelopes.",
9
+ ].join("\n"),
10
+ description: "Interrupt fabricated unavailable-tool calls emitted as assistant text.",
11
+ condition: [
12
+ "(?i)<\\s*unavailable-tool-call\\b",
13
+ "(?i)\\[called\\s+tool\\s+[\"'][^\"'\\r\\n]+[\"']\\s+\\(no\\s+longer\\s+available\\s+in\\s+this\\s+session\\)",
14
+ ],
15
+ scope: { allowText: true, allowThinking: false, toolScopes: [] },
16
+ interruptMode: "always",
17
+ source: "builtin",
18
+ },
19
+ ];
20
+ //# sourceMappingURL=builtin-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin-rules.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/builtin-rules.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,0CAA0C,GAAG,kCAAkC,CAAC;AAE7F,MAAM,CAAC,MAAM,kBAAkB,GAAwB;IACtD;QACC,IAAI,EAAE,0CAA0C;QAChD,OAAO,EAAE;YACR,2GAA2G;YAC3G,iIAAiI;YACjI,gEAAgE;SAChE,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,wEAAwE;QACrF,SAAS,EAAE;YACV,mCAAmC;YACnC,8GAA8G;SAC9G;QACD,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE;QAChE,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,SAAS;KACjB;CACD,CAAC","sourcesContent":["import type { TtsrRule } from \"./types.ts\";\n\nexport const FABRICATED_UNAVAILABLE_TOOL_CALL_RULE_NAME = \"fabricated-unavailable-tool-call\";\n\nexport const BUILTIN_TTSR_RULES: readonly TtsrRule[] = [\n\t{\n\t\tname: FABRICATED_UNAVAILABLE_TOOL_CALL_RULE_NAME,\n\t\tcontent: [\n\t\t\t\"Your previous output imitated an unavailable historical tool call as inert text instead of taking action.\",\n\t\t\t\"Redo the interrupted step now. Call your real tools that are actually available to you, such as edit or write for file changes.\",\n\t\t\t\"Do not print or imitate unavailable-tool transcript envelopes.\",\n\t\t].join(\"\\n\"),\n\t\tdescription: \"Interrupt fabricated unavailable-tool calls emitted as assistant text.\",\n\t\tcondition: [\n\t\t\t\"(?i)<\\\\s*unavailable-tool-call\\\\b\",\n\t\t\t\"(?i)\\\\[called\\\\s+tool\\\\s+[\\\"'][^\\\"'\\\\r\\\\n]+[\\\"']\\\\s+\\\\(no\\\\s+longer\\\\s+available\\\\s+in\\\\s+this\\\\s+session\\\\)\",\n\t\t],\n\t\tscope: { allowText: true, allowThinking: false, toolScopes: [] },\n\t\tinterruptMode: \"always\",\n\t\tsource: \"builtin\",\n\t},\n];\n"]}
@@ -23,6 +23,8 @@ export function registerTtsrCommands(pi, getState) {
23
23
  });
24
24
  }
25
25
  function formatTtsrStatus(state) {
26
+ const builtinRules = state.rules.filter((rule) => rule.source === "builtin");
27
+ const userRules = state.rules.filter((rule) => rule.source !== "builtin");
26
28
  return [
27
29
  "TTSR stream rules",
28
30
  "",
@@ -30,10 +32,13 @@ function formatTtsrStatus(state) {
30
32
  state.disabled ? "disabled (ttsr-disabled flag set)" : "enabled",
31
33
  "",
32
34
  "BUILTIN RULES",
35
+ "DETECTORS",
33
36
  ...BUILTIN_RULES.map(formatBuiltinRule),
37
+ "STREAM RULES",
38
+ ...(builtinRules.length === 0 ? ["(none)"] : builtinRules.map(formatBuiltinStreamRule)),
34
39
  "",
35
40
  "USER RULES",
36
- ...formatUserRules(state.rules),
41
+ ...formatUserRules(userRules),
37
42
  "",
38
43
  "INJECTED",
39
44
  state.injectedRuleNames.length === 0 ? "(none)" : state.injectedRuleNames.join(", "),
@@ -46,6 +51,9 @@ function formatBuiltinRule(rule) {
46
51
  `(mode: ${rule.remediation.retryMode}, scope: ${rule.remediation.corruptionScope})`,
47
52
  ].join(" ");
48
53
  }
54
+ function formatBuiltinStreamRule(rule) {
55
+ return `${rule.name} [stream rule, scope: ${formatScope(rule.scope)}]`;
56
+ }
49
57
  function formatUserRules(rules) {
50
58
  if (rules.length === 0)
51
59
  return ["(none)"];
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../../types.ts\";\nimport { COLLAPSE_RULE_NAME, CONTROL_LEAK_RULE_NAME } from \"./prompts.ts\";\nimport {\n\tCOLLAPSE_REMEDIATION,\n\tCONTROL_LEAK_REMEDIATION,\n\ttype RuleRemediation,\n\ttype TtsrRule,\n\ttype TtsrScope,\n} from \"./types.ts\";\n\nexport interface TtsrPublicState {\n\treadonly rules: readonly TtsrRule[];\n\treadonly injectedRuleNames: readonly string[];\n\treadonly disabled: boolean;\n}\n\ninterface BuiltinRuleStatus {\n\treadonly name: string;\n\treadonly detector: string;\n\treadonly remediation: RuleRemediation;\n\treadonly summary: string;\n}\n\nconst BUILTIN_RULES: readonly BuiltinRuleStatus[] = [\n\t{\n\t\tname: COLLAPSE_RULE_NAME,\n\t\tdetector: \"collapse\",\n\t\tremediation: COLLAPSE_REMEDIATION,\n\t\tsummary: \"abort the stream, truncate the garbage from history, inject a corrective nudge, then continue\",\n\t},\n\t{\n\t\tname: CONTROL_LEAK_RULE_NAME,\n\t\tdetector: \"control-leak\",\n\t\tremediation: CONTROL_LEAK_REMEDIATION,\n\t\tsummary: \"abort the stream, replace the generation with an error shell, then resample via bounded provider retry\",\n\t},\n];\n\nexport function registerTtsrCommands(pi: ExtensionAPI, getState: () => TtsrPublicState): void {\n\tpi.registerCommand(\"ttsr\", {\n\t\tdescription: \"Show TTSR stream-rule status: builtin detectors, user rules, injected rules.\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tctx.ui.notify(formatTtsrStatus(getState()), \"info\");\n\t\t},\n\t});\n}\n\nfunction formatTtsrStatus(state: TtsrPublicState): string {\n\treturn [\n\t\t\"TTSR stream rules\",\n\t\t\"\",\n\t\t\"STATUS\",\n\t\tstate.disabled ? \"disabled (ttsr-disabled flag set)\" : \"enabled\",\n\t\t\"\",\n\t\t\"BUILTIN RULES\",\n\t\t...BUILTIN_RULES.map(formatBuiltinRule),\n\t\t\"\",\n\t\t\"USER RULES\",\n\t\t...formatUserRules(state.rules),\n\t\t\"\",\n\t\t\"INJECTED\",\n\t\tstate.injectedRuleNames.length === 0 ? \"(none)\" : state.injectedRuleNames.join(\", \"),\n\t].join(\"\\n\");\n}\n\nfunction formatBuiltinRule(rule: BuiltinRuleStatus): string {\n\treturn [\n\t\t`${rule.name} [detector: ${rule.detector}]`,\n\t\t`remediation: ${rule.summary}`,\n\t\t`(mode: ${rule.remediation.retryMode}, scope: ${rule.remediation.corruptionScope})`,\n\t].join(\" \");\n}\n\nfunction formatUserRules(rules: readonly TtsrRule[]): string[] {\n\tif (rules.length === 0) return [\"(none)\"];\n\treturn rules.map((rule) => `${rule.name} [${rule.source}, scope: ${formatScope(rule.scope)}]`);\n}\n\nfunction formatScope(scope: TtsrScope): string {\n\tconst parts: string[] = [];\n\tif (scope.allowText) parts.push(\"text\");\n\tif (scope.allowThinking) parts.push(\"thinking\");\n\tfor (const toolScope of scope.toolScopes) {\n\t\tparts.push(\n\t\t\ttoolScope.pathGlob === undefined\n\t\t\t\t? `tool:${toolScope.toolName}`\n\t\t\t\t: `tool:${toolScope.toolName}(${toolScope.pathGlob})`,\n\t\t);\n\t}\n\treturn parts.length === 0 ? \"none\" : parts.join(\"+\");\n}\n"]}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../../types.ts\";\nimport { COLLAPSE_RULE_NAME, CONTROL_LEAK_RULE_NAME } from \"./prompts.ts\";\nimport {\n\tCOLLAPSE_REMEDIATION,\n\tCONTROL_LEAK_REMEDIATION,\n\ttype RuleRemediation,\n\ttype TtsrRule,\n\ttype TtsrScope,\n} from \"./types.ts\";\n\nexport interface TtsrPublicState {\n\treadonly rules: readonly TtsrRule[];\n\treadonly injectedRuleNames: readonly string[];\n\treadonly disabled: boolean;\n}\n\ninterface BuiltinRuleStatus {\n\treadonly name: string;\n\treadonly detector: string;\n\treadonly remediation: RuleRemediation;\n\treadonly summary: string;\n}\n\nconst BUILTIN_RULES: readonly BuiltinRuleStatus[] = [\n\t{\n\t\tname: COLLAPSE_RULE_NAME,\n\t\tdetector: \"collapse\",\n\t\tremediation: COLLAPSE_REMEDIATION,\n\t\tsummary: \"abort the stream, truncate the garbage from history, inject a corrective nudge, then continue\",\n\t},\n\t{\n\t\tname: CONTROL_LEAK_RULE_NAME,\n\t\tdetector: \"control-leak\",\n\t\tremediation: CONTROL_LEAK_REMEDIATION,\n\t\tsummary: \"abort the stream, replace the generation with an error shell, then resample via bounded provider retry\",\n\t},\n];\n\nexport function registerTtsrCommands(pi: ExtensionAPI, getState: () => TtsrPublicState): void {\n\tpi.registerCommand(\"ttsr\", {\n\t\tdescription: \"Show TTSR stream-rule status: builtin detectors, user rules, injected rules.\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tctx.ui.notify(formatTtsrStatus(getState()), \"info\");\n\t\t},\n\t});\n}\n\nfunction formatTtsrStatus(state: TtsrPublicState): string {\n\tconst builtinRules = state.rules.filter((rule) => rule.source === \"builtin\");\n\tconst userRules = state.rules.filter((rule) => rule.source !== \"builtin\");\n\treturn [\n\t\t\"TTSR stream rules\",\n\t\t\"\",\n\t\t\"STATUS\",\n\t\tstate.disabled ? \"disabled (ttsr-disabled flag set)\" : \"enabled\",\n\t\t\"\",\n\t\t\"BUILTIN RULES\",\n\t\t\"DETECTORS\",\n\t\t...BUILTIN_RULES.map(formatBuiltinRule),\n\t\t\"STREAM RULES\",\n\t\t...(builtinRules.length === 0 ? [\"(none)\"] : builtinRules.map(formatBuiltinStreamRule)),\n\t\t\"\",\n\t\t\"USER RULES\",\n\t\t...formatUserRules(userRules),\n\t\t\"\",\n\t\t\"INJECTED\",\n\t\tstate.injectedRuleNames.length === 0 ? \"(none)\" : state.injectedRuleNames.join(\", \"),\n\t].join(\"\\n\");\n}\n\nfunction formatBuiltinRule(rule: BuiltinRuleStatus): string {\n\treturn [\n\t\t`${rule.name} [detector: ${rule.detector}]`,\n\t\t`remediation: ${rule.summary}`,\n\t\t`(mode: ${rule.remediation.retryMode}, scope: ${rule.remediation.corruptionScope})`,\n\t].join(\" \");\n}\n\nfunction formatBuiltinStreamRule(rule: TtsrRule): string {\n\treturn `${rule.name} [stream rule, scope: ${formatScope(rule.scope)}]`;\n}\n\nfunction formatUserRules(rules: readonly TtsrRule[]): string[] {\n\tif (rules.length === 0) return [\"(none)\"];\n\treturn rules.map((rule) => `${rule.name} [${rule.source}, scope: ${formatScope(rule.scope)}]`);\n}\n\nfunction formatScope(scope: TtsrScope): string {\n\tconst parts: string[] = [];\n\tif (scope.allowText) parts.push(\"text\");\n\tif (scope.allowThinking) parts.push(\"thinking\");\n\tfor (const toolScope of scope.toolScopes) {\n\t\tparts.push(\n\t\t\ttoolScope.pathGlob === undefined\n\t\t\t\t? `tool:${toolScope.toolName}`\n\t\t\t\t: `tool:${toolScope.toolName}(${toolScope.pathGlob})`,\n\t\t);\n\t}\n\treturn parts.length === 0 ? \"none\" : parts.join(\"+\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAwC,MAAM,gBAAgB,CAAC;AAmDzF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA4L5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAwC,MAAM,gBAAgB,CAAC;AAoDzF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6L5D"}
@@ -1,4 +1,5 @@
1
1
  import { getKeybindings } from "@earendil-works/pi-tui";
2
+ import { BUILTIN_TTSR_RULES } from "./builtin-rules.js";
2
3
  import { registerTtsrCommands } from "./commands.js";
3
4
  import { claimAbort, createGenerationState, markUserCancelled } from "./coordinator.js";
4
5
  import { discoverTtsrRulesSync } from "./discovery.js";
@@ -88,6 +89,9 @@ export default function ttsrExtension(pi) {
88
89
  return Array.isArray(rules) ? rules.filter((rule) => typeof rule === "string") : [];
89
90
  });
90
91
  manager.restoreInjected(injectedNames);
92
+ for (const rule of BUILTIN_TTSR_RULES) {
93
+ manager.addRule(rule);
94
+ }
91
95
  const discovered = discoverTtsrRulesSync(ctx.cwd);
92
96
  for (const rule of discovered.rules) {
93
97
  manager.addRule(rule);
@@ -143,12 +147,9 @@ export default function ttsrExtension(pi) {
143
147
  const source = deltaEvent.type === "text_delta" ? "text" : "thinking";
144
148
  const streamKey = `${source}:${String(deltaEvent.contentIndex)}`;
145
149
  const outcome = watcher.handleDelta(source, streamKey, deltaEvent.delta, generation);
146
- if (outcome.resolution !== null)
147
- console.log("TTSRDBG claim pre:", genState.abortClaimed, genState.userCancelled);
148
150
  if (outcome.resolution !== null && claimAbort(genState, outcome.resolution)) {
149
151
  pendingRemediation = { resolution: outcome.resolution, streamKind: source };
150
152
  notify(ctx, outcome.resolution.owner);
151
- console.log("TTSRDBG abort call");
152
153
  ctx.abort();
153
154
  return;
154
155
  }