@code-yeongyu/senpi 2026.7.31 → 2026.8.1

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 (491) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/dist/core/agent-session.d.ts +49 -13
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +120 -37
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  7. package/dist/core/dynamic-prompt/build.js +4 -0
  8. package/dist/core/dynamic-prompt/build.js.map +1 -1
  9. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts +2 -2
  10. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.d.ts.map +1 -1
  11. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js +25 -25
  12. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-command.js.map +1 -1
  13. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts.map +1 -1
  14. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js.map +1 -1
  15. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts +1 -1
  16. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.d.ts.map +1 -1
  17. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js +2 -2
  18. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-management.js.map +1 -1
  19. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts +9 -9
  20. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js +2 -2
  22. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/accounts.js.map +1 -1
  23. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts +1 -1
  24. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js +3 -3
  26. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/affinity.js.map +1 -1
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts +21 -0
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.d.ts.map +1 -0
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js +30 -0
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-attempt.js.map +1 -0
  31. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.d.ts +8 -4
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -0
  33. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/auth-lane.js +34 -25
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -0
  35. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js.map +1 -1
  37. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js.map +1 -1
  39. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts +1 -1
  40. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js +1 -1
  42. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/errors.js.map +1 -1
  43. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js.map +1 -1
  45. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js +1 -1
  47. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.js.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts +14 -0
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts.map +1 -0
  50. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/guidance.js +37 -1
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js.map +1 -0
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -0
  54. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/index.js +12 -10
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -0
  56. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts +3 -3
  57. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/oauth-login.js +2 -2
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -0
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts +18 -0
  61. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/options.js +70 -10
  63. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -0
  64. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.js +32 -19
  66. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -0
  67. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts +1 -0
  68. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js.map +1 -1
  70. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts +30 -0
  71. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -0
  72. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +197 -0
  73. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -0
  74. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts +18 -0
  75. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.d.ts.map +1 -0
  76. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js +33 -0
  77. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-state.js.map +1 -0
  78. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts +3 -0
  79. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -0
  80. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +134 -0
  81. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -0
  82. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +85 -0
  83. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -0
  84. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +270 -0
  85. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -0
  86. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts +17 -0
  87. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -0
  88. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +217 -0
  89. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -0
  90. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts +49 -0
  91. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +204 -0
  93. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -0
  94. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts +28 -0
  95. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +107 -0
  97. package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -0
  98. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts +2 -0
  99. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts.map +1 -0
  100. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js +10 -0
  101. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js.map +1 -0
  102. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js.map +1 -1
  104. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.d.ts +1 -1
  105. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -0
  106. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream.js +72 -53
  107. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -0
  108. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts +3 -0
  109. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.d.ts.map +1 -0
  110. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js +25 -0
  111. package/dist/core/extensions/builtin/claude-sdk-oauth/system-prompt.js.map +1 -0
  112. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts +1 -1
  113. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.d.ts.map +1 -1
  114. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js +2 -2
  115. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tool-watch.js.map +1 -1
  116. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts.map +1 -1
  117. package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js.map +1 -1
  118. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +18 -0
  119. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -0
  120. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +69 -0
  121. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -0
  122. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  123. package/dist/core/extensions/builtin/compaction/index.js +28 -2
  124. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  125. package/dist/core/extensions/builtin/compaction/speculative.d.ts +4 -1
  126. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  127. package/dist/core/extensions/builtin/compaction/speculative.js +22 -17
  128. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  129. package/dist/core/extensions/builtin/compaction/task-intent.d.ts +2 -6
  130. package/dist/core/extensions/builtin/compaction/task-intent.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/compaction/task-intent.js +10 -9
  132. package/dist/core/extensions/builtin/compaction/task-intent.js.map +1 -1
  133. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +6 -0
  134. package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -0
  135. package/dist/core/extensions/builtin/goal/continuation-recovery.js +20 -0
  136. package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -0
  137. package/dist/core/extensions/builtin/goal/continuation.d.ts +2 -4
  138. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  139. package/dist/core/extensions/builtin/goal/continuation.js +2 -8
  140. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  141. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts +19 -0
  142. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts.map +1 -0
  143. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +48 -0
  144. package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -0
  145. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  146. package/dist/core/extensions/builtin/goal/index.js +17 -15
  147. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  148. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  149. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +12 -10
  150. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  151. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +5 -1
  152. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  153. package/dist/core/extensions/builtin/goal/monitor-continuation.js +94 -52
  154. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  155. package/dist/core/extensions/builtin/goal/persistence.d.ts +16 -0
  156. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -1
  157. package/dist/core/extensions/builtin/goal/persistence.js +185 -11
  158. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  159. package/dist/core/extensions/builtin/goal/ui.d.ts +1 -0
  160. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  161. package/dist/core/extensions/builtin/goal/ui.js +11 -2
  162. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  163. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  164. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +15 -0
  165. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  166. package/dist/core/extensions/builtin/gpt-apply-patch/tool.d.ts.map +1 -1
  167. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js +30 -3
  168. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js.map +1 -1
  169. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  170. package/dist/core/extensions/builtin/index.js +5 -2
  171. package/dist/core/extensions/builtin/index.js.map +1 -1
  172. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts +31 -0
  173. package/dist/core/extensions/builtin/loop-guard/detectors.d.ts.map +1 -0
  174. package/dist/core/extensions/builtin/loop-guard/detectors.js +111 -0
  175. package/dist/core/extensions/builtin/loop-guard/detectors.js.map +1 -0
  176. package/dist/core/extensions/builtin/loop-guard/index.d.ts +3 -0
  177. package/dist/core/extensions/builtin/loop-guard/index.d.ts.map +1 -0
  178. package/dist/core/extensions/builtin/loop-guard/index.js +31 -0
  179. package/dist/core/extensions/builtin/loop-guard/index.js.map +1 -0
  180. package/dist/core/extensions/builtin/loop-guard/notice.d.ts +5 -0
  181. package/dist/core/extensions/builtin/loop-guard/notice.d.ts.map +1 -0
  182. package/dist/core/extensions/builtin/loop-guard/notice.js +42 -0
  183. package/dist/core/extensions/builtin/loop-guard/notice.js.map +1 -0
  184. package/dist/core/extensions/builtin/loop-guard/policy.d.ts +30 -0
  185. package/dist/core/extensions/builtin/loop-guard/policy.d.ts.map +1 -0
  186. package/dist/core/extensions/builtin/loop-guard/policy.js +30 -0
  187. package/dist/core/extensions/builtin/loop-guard/policy.js.map +1 -0
  188. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts +4 -0
  189. package/dist/core/extensions/builtin/loop-guard/renderer.d.ts.map +1 -0
  190. package/dist/core/extensions/builtin/loop-guard/renderer.js +50 -0
  191. package/dist/core/extensions/builtin/loop-guard/renderer.js.map +1 -0
  192. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts +13 -0
  193. package/dist/core/extensions/builtin/loop-guard/similarity.d.ts.map +1 -0
  194. package/dist/core/extensions/builtin/loop-guard/similarity.js +51 -0
  195. package/dist/core/extensions/builtin/loop-guard/similarity.js.map +1 -0
  196. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts +13 -0
  197. package/dist/core/extensions/builtin/loop-guard/tracker.d.ts.map +1 -0
  198. package/dist/core/extensions/builtin/loop-guard/tracker.js +39 -0
  199. package/dist/core/extensions/builtin/loop-guard/tracker.js.map +1 -0
  200. package/dist/core/extensions/builtin/monitor-state-event.d.ts +10 -0
  201. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  202. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  203. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.d.ts +3 -0
  204. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.d.ts.map +1 -0
  205. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.js +10 -0
  206. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.js.map +1 -0
  207. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.d.ts +3 -0
  208. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.d.ts.map +1 -0
  209. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.js +10 -0
  210. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.js.map +1 -0
  211. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.d.ts +3 -0
  212. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.d.ts.map +1 -0
  213. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.js +11 -0
  214. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.js.map +1 -0
  215. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.d.ts +13 -0
  216. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.d.ts.map +1 -0
  217. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.js +60 -0
  218. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.js.map +1 -0
  219. package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
  220. package/dist/core/extensions/builtin/prompt-preset/index.js +8 -4
  221. package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
  222. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  223. package/dist/core/extensions/builtin/prompt-preset/presets.js +42 -0
  224. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  225. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  226. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  227. package/dist/core/extensions/builtin/prompt-preset/settings.js +3 -0
  228. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  229. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  230. package/dist/core/extensions/builtin/recommended-models/index.js +2 -1
  231. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  232. package/dist/core/extensions/builtin/rules/index.js +4 -3
  233. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  234. package/dist/core/extensions/builtin/rules/rules/constants.d.ts +11 -0
  235. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  236. package/dist/core/extensions/builtin/rules/rules/constants.js +11 -0
  237. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  238. package/dist/core/extensions/builtin/rules/rules/formatter.d.ts.map +1 -1
  239. package/dist/core/extensions/builtin/rules/rules/formatter.js +15 -1
  240. package/dist/core/extensions/builtin/rules/rules/formatter.js.map +1 -1
  241. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  242. package/dist/core/extensions/builtin/service-tier.js +23 -21
  243. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  244. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  245. package/dist/core/extensions/builtin/terminal/extension.js +21 -7
  246. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  247. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  248. package/dist/core/extensions/builtin/terminal/monitor-notify.js +42 -5
  249. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  250. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
  251. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  252. package/dist/core/extensions/builtin/terminal/monitor-registry.js +2 -0
  253. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  254. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts +37 -0
  255. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.d.ts.map +1 -0
  256. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js +61 -0
  257. package/dist/core/extensions/builtin/terminal/monitor-status-ticker.js.map +1 -0
  258. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts +9 -1
  259. package/dist/core/extensions/builtin/terminal/monitor-status.d.ts.map +1 -1
  260. package/dist/core/extensions/builtin/terminal/monitor-status.js +35 -2
  261. package/dist/core/extensions/builtin/terminal/monitor-status.js.map +1 -1
  262. package/dist/core/extensions/builtin/terminal/tools/monitor.js +1 -1
  263. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  264. package/dist/core/extensions/builtin/todotools/commands.d.ts +2 -2
  265. package/dist/core/extensions/builtin/todotools/commands.d.ts.map +1 -1
  266. package/dist/core/extensions/builtin/todotools/commands.js.map +1 -1
  267. package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
  268. package/dist/core/extensions/builtin/todotools/index.js +6 -3
  269. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  270. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  271. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  272. package/dist/core/extensions/builtin/todotools/state.js +1 -1
  273. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  274. package/dist/core/extensions/builtin/todotools/todo-widget-component.d.ts +19 -0
  275. package/dist/core/extensions/builtin/todotools/todo-widget-component.d.ts.map +1 -0
  276. package/dist/core/extensions/builtin/todotools/todo-widget-component.js +78 -0
  277. package/dist/core/extensions/builtin/todotools/todo-widget-component.js.map +1 -0
  278. package/dist/core/extensions/builtin/todotools/todo-widget.d.ts +13 -1
  279. package/dist/core/extensions/builtin/todotools/todo-widget.d.ts.map +1 -1
  280. package/dist/core/extensions/builtin/todotools/todo-widget.js +32 -14
  281. package/dist/core/extensions/builtin/todotools/todo-widget.js.map +1 -1
  282. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +2 -2
  283. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  284. package/dist/core/extensions/builtin/todotools/tools/todo.js +1 -1
  285. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  286. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts +1 -1
  287. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.d.ts.map +1 -1
  288. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js +88 -29
  289. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-anthropic-payload.js.map +1 -1
  290. package/dist/core/extensions/builtin/tps.d.ts.map +1 -1
  291. package/dist/core/extensions/builtin/tps.js +5 -2
  292. package/dist/core/extensions/builtin/tps.js.map +1 -1
  293. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts +4 -0
  294. package/dist/core/extensions/builtin/ttsr/builtin-rules.d.ts.map +1 -0
  295. package/dist/core/extensions/builtin/ttsr/builtin-rules.js +20 -0
  296. package/dist/core/extensions/builtin/ttsr/builtin-rules.js.map +1 -0
  297. package/dist/core/extensions/builtin/ttsr/commands.js +9 -1
  298. package/dist/core/extensions/builtin/ttsr/commands.js.map +1 -1
  299. package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
  300. package/dist/core/extensions/builtin/ttsr/index.js +4 -3
  301. package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
  302. package/dist/core/extensions/builtin/ttsr/manager.js +1 -1
  303. package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
  304. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  305. package/dist/core/extensions/builtin/websearch/websearch/config.js +1 -0
  306. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  307. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
  308. package/dist/core/extensions/builtin/websearch/websearch/native.js +16 -5
  309. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
  310. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  311. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +1 -0
  312. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  313. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.d.ts +4 -1
  314. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.d.ts.map +1 -1
  315. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.js +44 -37
  316. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.js.map +1 -1
  317. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.d.ts +3 -0
  318. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.d.ts.map +1 -0
  319. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.js +12 -0
  320. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.js.map +1 -0
  321. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -1
  322. package/dist/core/extensions/builtin/websearch/websearch/providers.js +2 -0
  323. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -1
  324. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  325. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +3 -3
  326. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  327. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  328. package/dist/core/extensions/builtin/websearch/websearch/search.js +1 -3
  329. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  330. package/dist/core/extensions/builtin/websearch/websearch/tool.js +2 -2
  331. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  332. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  333. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  334. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  335. package/dist/core/extensions/index.d.ts +1 -1
  336. package/dist/core/extensions/index.d.ts.map +1 -1
  337. package/dist/core/extensions/index.js.map +1 -1
  338. package/dist/core/extensions/loader.d.ts.map +1 -1
  339. package/dist/core/extensions/loader.js +5 -0
  340. package/dist/core/extensions/loader.js.map +1 -1
  341. package/dist/core/extensions/runner.d.ts +1 -1
  342. package/dist/core/extensions/runner.d.ts.map +1 -1
  343. package/dist/core/extensions/runner.js +3 -1
  344. package/dist/core/extensions/runner.js.map +1 -1
  345. package/dist/core/extensions/types.d.ts +22 -1
  346. package/dist/core/extensions/types.d.ts.map +1 -1
  347. package/dist/core/extensions/types.js.map +1 -1
  348. package/dist/core/model-resolver.js +2 -2
  349. package/dist/core/model-resolver.js.map +1 -1
  350. package/dist/core/thinking-levels.d.ts +5 -0
  351. package/dist/core/thinking-levels.d.ts.map +1 -1
  352. package/dist/core/thinking-levels.js +9 -39
  353. package/dist/core/thinking-levels.js.map +1 -1
  354. package/dist/index.d.ts +1 -1
  355. package/dist/index.d.ts.map +1 -1
  356. package/dist/index.js.map +1 -1
  357. package/dist/modes/app-server/server/account.d.ts +1 -1
  358. package/dist/modes/app-server/server/account.js +1 -1
  359. package/dist/modes/app-server/server/account.js.map +1 -1
  360. package/dist/modes/app-server/server/server-core.js +1 -1
  361. package/dist/modes/app-server/server/server-core.js.map +1 -1
  362. package/dist/modes/interactive/compaction-queue-transfer.d.ts +2 -0
  363. package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -1
  364. package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -1
  365. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  366. package/dist/modes/interactive/components/footer.js +9 -5
  367. package/dist/modes/interactive/components/footer.js.map +1 -1
  368. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  369. package/dist/modes/interactive/interactive-mode.js +38 -12
  370. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  371. package/dist/modes/interactive/risky-main-model-warning.d.ts +1 -1
  372. package/dist/modes/interactive/risky-main-model-warning.d.ts.map +1 -1
  373. package/dist/modes/interactive/risky-main-model-warning.js +1 -1
  374. package/dist/modes/interactive/risky-main-model-warning.js.map +1 -1
  375. package/dist/modes/rpc/connection-handler.js +3 -3
  376. package/dist/modes/rpc/connection-handler.js.map +1 -1
  377. package/docs/extensions.md +10 -0
  378. package/docs/providers.md +21 -5
  379. package/docs/release-guide.md +2 -2
  380. package/docs/settings.md +1 -1
  381. package/examples/extensions/overlay-test.ts +1 -1
  382. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +33 -0
  383. package/node_modules/@code-yeongyu/senpi-codemode/README.md +6 -3
  384. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  385. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status-ticker.ts +79 -0
  386. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +36 -3
  387. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +26 -12
  388. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-execution.ts +146 -0
  389. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +21 -119
  390. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +157 -0
  391. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +62 -208
  392. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-notification.ts +98 -0
  393. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +81 -0
  394. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-state.ts +24 -0
  395. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +140 -0
  396. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-notification-queue.ts +53 -0
  397. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +45 -0
  398. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +45 -0
  399. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +20 -342
  400. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  401. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +1 -0
  402. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  403. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  404. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +10 -15
  406. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  407. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +2 -2
  408. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.d.ts +24 -0
  410. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.d.ts.map +1 -0
  411. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.js +70 -0
  412. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.js.map +1 -0
  413. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +2 -16
  414. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +10 -58
  416. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  417. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +2 -2
  418. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.d.ts +1 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.d.ts.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.js +7 -0
  422. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.js.map +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -2
  424. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts +2 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts.map +1 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/model.js.map +1 -1
  428. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +14 -0
  429. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/models.js +95 -19
  431. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  432. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  434. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +5 -0
  443. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts +3 -0
  446. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.d.ts.map +1 -0
  447. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js +36 -0
  448. package/node_modules/@earendil-works/pi-ai/dist/utils/unavailable-tool-text.js.map +1 -0
  449. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  450. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  451. package/node_modules/@earendil-works/pi-tui/dist/mux.js +1 -1
  452. package/node_modules/@earendil-works/pi-tui/dist/mux.js.map +1 -1
  453. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +1 -0
  454. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  455. package/node_modules/@earendil-works/pi-tui/dist/tui.js +17 -3
  456. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  457. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  458. package/package.json +6 -6
  459. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.d.ts.map +0 -1
  460. package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.js.map +0 -1
  461. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts +0 -6
  462. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.d.ts.map +0 -1
  463. package/dist/core/extensions/builtin/claude-agent-sdk/guidance.js.map +0 -1
  464. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts +0 -4
  465. package/dist/core/extensions/builtin/claude-agent-sdk/index.d.ts.map +0 -1
  466. package/dist/core/extensions/builtin/claude-agent-sdk/index.js.map +0 -1
  467. package/dist/core/extensions/builtin/claude-agent-sdk/oauth-login.js.map +0 -1
  468. package/dist/core/extensions/builtin/claude-agent-sdk/options.d.ts +0 -16
  469. package/dist/core/extensions/builtin/claude-agent-sdk/options.js.map +0 -1
  470. package/dist/core/extensions/builtin/claude-agent-sdk/prompt-bridge.js.map +0 -1
  471. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts +0 -15
  472. package/dist/core/extensions/builtin/claude-agent-sdk/settings.d.ts.map +0 -1
  473. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js +0 -41
  474. package/dist/core/extensions/builtin/claude-agent-sdk/settings.js.map +0 -1
  475. package/dist/core/extensions/builtin/claude-agent-sdk/stream.d.ts.map +0 -1
  476. package/dist/core/extensions/builtin/claude-agent-sdk/stream.js.map +0 -1
  477. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.d.ts +0 -0
  478. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/account-events.js +0 -0
  479. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.d.ts +0 -0
  480. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools-schema.js +0 -0
  481. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.d.ts +0 -0
  482. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/custom-tools.js +0 -0
  483. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.d.ts +0 -0
  484. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/executable.js +0 -0
  485. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/failover.d.ts +0 -0
  486. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/prompt-bridge.d.ts +0 -0
  487. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/sdk-boundary.js +0 -0
  488. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.d.ts +0 -0
  489. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/stream-protocol.js +0 -0
  490. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.d.ts +0 -0
  491. /package/dist/core/extensions/builtin/{claude-agent-sdk → claude-sdk-oauth}/tools.js +0 -0
@@ -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"]}
@@ -85,7 +85,7 @@ export function createMonitorTool(ctx) {
85
85
  return {
86
86
  name: TERMINAL_MONITOR_TOOL,
87
87
  label: "monitor",
88
- description: "Subscribe to events from a command instead of polling for them: each stdout line arrives as an injected event while you keep working. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.",
88
+ description: "Subscribe to events from a command instead of polling for them: each stdout line arrives as an injected event while you keep working. Updates identical to a monitor's previous batch are dropped, so a watcher reprinting unchanged status does not re-wake the session. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.",
89
89
  promptSnippet: "Subscribe to a command's stdout lines as injected events instead of polling",
90
90
  promptGuidelines: [
91
91
  "Waiting on observable state (CI checks, builds, log patterns, deploys) means a monitor, never a foreground sleep/poll loop.",
@@ -1 +1 @@
1
- {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,WAAW,EAAqD,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAC;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,IAAI,CAAC,QAAQ,CACpB,UAAU,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAU,EAAE;QACxC,WAAW,EAAE,wEAAwE;KACrF,CAAC,CACF;IACD,WAAW,EAAE,IAAI,CAAC,QAAQ,CACzB,IAAI,CAAC,MAAM,CAAC;QACX,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,GAAG;QACd,WAAW,EAAE,wFAAwF;KACrG,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EAAE,oFAAoF;KACjG,CAAC,CACF;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC,CAAC;IACnH,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,sBAAsB;QAC/B,WAAW,EAAE,oFAAoF;KACjG,CAAC,CACF;IACD,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,uEAAuE,EAAE,CAAC,CACtG;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC,CAAC;CAC3G,CAAC,CAAC;AAKH,SAAS,aAAa,CAAC,KAAmB;IACzC,OAAO,CACN,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CACxB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAyB,EAAE,QAAgB;IACpE,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjF,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAyB;IAClD,MAAM,OAAO,GAAG,KAAK,IAAI,0BAA0B,CAAC;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,aAAa,CAAC,MAA0B;IAChD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,aAAa,CAC3B,GAAwB,EACxB,QAAyB,EACzB,KAAyB,EACzB,OAAqC;IAErC,IAAI,MAA0B,CAAC;IAC/B,IAAI,CAAC;QACJ,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,WAAW,CAAC,iCAAiC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE;QACtD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,IAAI,YAAY,CAAC;QAClE,IAAI,EAAE,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,IAAI,YAAY,CAAC;QAClE,GAAG,EAAE,OAAO,EAAE,GAAG;QACjB,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;KAC9E,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3E,OAAO,UAAU,CAAC,4BAA4B,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,iBAAiB,CAAC,GAAwB;IACzD,IAAI,gBAA6C,CAAC;IAClD,MAAM,WAAW,GAAG,GAAoB,EAAE;QACzC,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;QAC5C,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC;QAC5C,gBAAgB,KAAK,IAAI,eAAe,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACjF,OAAO,gBAAgB,CAAC;IACzB,CAAC,CAAC;IACF,OAAO;QACN,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,SAAS;QAChB,WAAW,EACV,kNAAkN;QACnN,aAAa,EAAE,6EAA6E;QAC5F,gBAAgB,EAAE;YACjB,6HAA6H;SAC7H;QACD,UAAU,EAAE,aAAa;QACzB,UAAU,EAAE,iBAAiB;QAC7B,KAAK,CAAC,OAAO,CACZ,WAAmB,EACnB,KAAmB,EACnB,OAAqB,EACrB,SAAqB,EACrB,OAA0B;YAE1B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC7B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,WAAW,CAAC,iCAAiC,CAAC,CAAC;gBACvG,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACvC,IAAI,OAAO,KAAK,WAAW;oBAAE,OAAO,WAAW,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAC;gBAC9F,IAAI,OAAO,KAAK,YAAY;oBAAE,OAAO,UAAU,CAAC,WAAW,MAAM,kCAAkC,CAAC,CAAC;gBACrG,GAAG,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC/B,OAAO,UAAU,CAAC,WAAW,MAAM,YAAY,CAAC,CAAC;YAClD,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,WAAW,CAAC,8DAA8D,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { MonitorRegistry } from \"../monitor-registry.ts\";\nimport { DEFAULT_COLS, DEFAULT_ROWS, TERMINAL_MONITOR_TOOL } from \"../shared.ts\";\nimport { errorResult, type TerminalToolContext, type TerminalToolResult, textResult } from \"./context.ts\";\nimport { renderMonitorCall } from \"./render.ts\";\nimport { spawnCommandSession } from \"./spawn.ts\";\n\nexport const DEFAULT_MONITOR_TIMEOUT_MS = 300_000;\nexport const MAX_MONITOR_TIMEOUT_MS = 3_600_000;\n\n/**\n * One flat object schema, no top-level union: several provider payload paths\n * (e.g. Anthropic's legacy input_schema conversion) rebuild tool schemas from\n * top-level `properties` only, so a root anyOf would reach the model as an\n * empty schema. Branch requirements are enforced at runtime in `execute`.\n */\nexport const monitorSchema = Type.Object({\n\taction: Type.Optional(\n\t\tStringEnum([\"create\", \"rearm\"] as const, {\n\t\t\tdescription: \"Defaults to create. rearm resumes a monitor paused by the wake budget.\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 200,\n\t\t\tdescription: \"Create (required): specific label shown with every event, e.g. 'errors in deploy.log'.\",\n\t\t}),\n\t),\n\tcommand: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Create (required): shell command to run and watch in a PTY-backed monitor session.\",\n\t\t}),\n\t),\n\tfilter: Type.Optional(Type.String({ description: \"Only stdout lines matching this regex become monitor events.\" })),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({\n\t\t\tminimum: 1,\n\t\t\tmaximum: MAX_MONITOR_TIMEOUT_MS,\n\t\t\tdescription: \"Watcher deadline in milliseconds (default 300000; ignored by persistent monitors).\",\n\t\t}),\n\t),\n\tpersistent: Type.Optional(\n\t\tType.Boolean({ description: \"Keep watching until the command exits or kill_bash stops its bash_id.\" }),\n\t),\n\tbash_id: Type.Optional(Type.String({ description: \"Rearm (required): paused monitor bash_id to resume.\" })),\n});\nexport type MonitorInput = Static<typeof monitorSchema>;\n\ntype MonitorCreateInput = MonitorInput & { description: string; command: string };\n\nfunction isCreateInput(input: MonitorInput): input is MonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.command === \"string\" &&\n\t\tinput.command.length > 0\n\t);\n}\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction resolveTimeoutMs(value: number | undefined): number {\n\tconst timeout = value ?? DEFAULT_MONITOR_TIMEOUT_MS;\n\treturn Math.min(Math.max(Math.trunc(timeout), 1), MAX_MONITOR_TIMEOUT_MS);\n}\n\nfunction compileFilter(filter: string | undefined): RegExp | undefined {\n\tif (filter === undefined) return undefined;\n\treturn new RegExp(filter);\n}\n\nasync function createMonitor(\n\tctx: TerminalToolContext,\n\tregistry: MonitorRegistry,\n\tinput: MonitorCreateInput,\n\texecCtx: { cwd?: string } | undefined,\n): Promise<TerminalToolResult> {\n\tlet filter: RegExp | undefined;\n\ttry {\n\t\tfilter = compileFilter(input.filter);\n\t} catch {\n\t\treturn errorResult(`Invalid monitor filter regex: ${input.filter}`);\n\t}\n\n\tconst { id, runtime } = await spawnCommandSession(ctx, {\n\t\tcommand: input.command,\n\t\tcols: resolveDimension(undefined, ctx.defaultCols || DEFAULT_COLS),\n\t\trows: resolveDimension(undefined, ctx.defaultRows || DEFAULT_ROWS),\n\t\tcwd: execCtx?.cwd,\n\t\t...(input.persistent ? {} : { timeoutMs: resolveTimeoutMs(input.timeout_ms) }),\n\t});\n\tregistry.register({ id, description: input.description, runtime, filter });\n\treturn textResult(`Monitor started with ID: ${id}`, { details: { bash_id: id, monitor: true } });\n}\n\n/** Build the PTY-backed monitor tool. Monitor handles share TerminalManager's bash_N namespace. */\nexport function createMonitorTool(ctx: TerminalToolContext) {\n\tlet fallbackRegistry: MonitorRegistry | undefined;\n\tconst getRegistry = (): MonitorRegistry => {\n\t\tconst sessionRegistry = ctx.monitorRegistry;\n\t\tif (sessionRegistry) return sessionRegistry;\n\t\tfallbackRegistry ??= new MonitorRegistry((event) => ctx.onMonitorEvent?.(event));\n\t\treturn fallbackRegistry;\n\t};\n\treturn {\n\t\tname: TERMINAL_MONITOR_TOOL,\n\t\tlabel: \"monitor\",\n\t\tdescription:\n\t\t\t\"Subscribe to events from a command instead of polling for them: each stdout line arrives as an injected event while you keep working. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.\",\n\t\tpromptSnippet: \"Subscribe to a command's stdout lines as injected events instead of polling\",\n\t\tpromptGuidelines: [\n\t\t\t\"Waiting on observable state (CI checks, builds, log patterns, deploys) means a monitor, never a foreground sleep/poll loop.\",\n\t\t],\n\t\tparameters: monitorSchema,\n\t\trenderCall: renderMonitorCall,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: MonitorInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?: undefined,\n\t\t\texecCtx?: { cwd?: string },\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst registry = getRegistry();\n\t\t\tif (input.action === \"rearm\") {\n\t\t\t\tconst bashId = input.bash_id;\n\t\t\t\tif (bashId === undefined || bashId.length === 0) return errorResult(\"monitor rearm requires bash_id.\");\n\t\t\t\tconst outcome = registry.rearm(bashId);\n\t\t\t\tif (outcome === \"not_found\") return errorResult(`No active monitor found with id: ${bashId}`);\n\t\t\t\tif (outcome === \"not_paused\") return textResult(`Monitor ${bashId} is not paused; no action taken.`);\n\t\t\t\tctx.onMonitorRearmed?.(bashId);\n\t\t\t\treturn textResult(`Monitor ${bashId} re-armed.`);\n\t\t\t}\n\t\t\tif (!isCreateInput(input)) {\n\t\t\t\treturn errorResult(\"monitor requires description and command to start a watcher.\");\n\t\t\t}\n\t\t\treturn createMonitor(ctx, registry, input, execCtx);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/monitor.ts"],"names":[],"mappings":"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","sourcesContent":["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { MonitorRegistry } from \"../monitor-registry.ts\";\nimport { DEFAULT_COLS, DEFAULT_ROWS, TERMINAL_MONITOR_TOOL } from \"../shared.ts\";\nimport { errorResult, type TerminalToolContext, type TerminalToolResult, textResult } from \"./context.ts\";\nimport { renderMonitorCall } from \"./render.ts\";\nimport { spawnCommandSession } from \"./spawn.ts\";\n\nexport const DEFAULT_MONITOR_TIMEOUT_MS = 300_000;\nexport const MAX_MONITOR_TIMEOUT_MS = 3_600_000;\n\n/**\n * One flat object schema, no top-level union: several provider payload paths\n * (e.g. Anthropic's legacy input_schema conversion) rebuild tool schemas from\n * top-level `properties` only, so a root anyOf would reach the model as an\n * empty schema. Branch requirements are enforced at runtime in `execute`.\n */\nexport const monitorSchema = Type.Object({\n\taction: Type.Optional(\n\t\tStringEnum([\"create\", \"rearm\"] as const, {\n\t\t\tdescription: \"Defaults to create. rearm resumes a monitor paused by the wake budget.\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(\n\t\tType.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 200,\n\t\t\tdescription: \"Create (required): specific label shown with every event, e.g. 'errors in deploy.log'.\",\n\t\t}),\n\t),\n\tcommand: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Create (required): shell command to run and watch in a PTY-backed monitor session.\",\n\t\t}),\n\t),\n\tfilter: Type.Optional(Type.String({ description: \"Only stdout lines matching this regex become monitor events.\" })),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({\n\t\t\tminimum: 1,\n\t\t\tmaximum: MAX_MONITOR_TIMEOUT_MS,\n\t\t\tdescription: \"Watcher deadline in milliseconds (default 300000; ignored by persistent monitors).\",\n\t\t}),\n\t),\n\tpersistent: Type.Optional(\n\t\tType.Boolean({ description: \"Keep watching until the command exits or kill_bash stops its bash_id.\" }),\n\t),\n\tbash_id: Type.Optional(Type.String({ description: \"Rearm (required): paused monitor bash_id to resume.\" })),\n});\nexport type MonitorInput = Static<typeof monitorSchema>;\n\ntype MonitorCreateInput = MonitorInput & { description: string; command: string };\n\nfunction isCreateInput(input: MonitorInput): input is MonitorCreateInput {\n\treturn (\n\t\ttypeof input.description === \"string\" &&\n\t\tinput.description.length > 0 &&\n\t\ttypeof input.command === \"string\" &&\n\t\tinput.command.length > 0\n\t);\n}\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction resolveTimeoutMs(value: number | undefined): number {\n\tconst timeout = value ?? DEFAULT_MONITOR_TIMEOUT_MS;\n\treturn Math.min(Math.max(Math.trunc(timeout), 1), MAX_MONITOR_TIMEOUT_MS);\n}\n\nfunction compileFilter(filter: string | undefined): RegExp | undefined {\n\tif (filter === undefined) return undefined;\n\treturn new RegExp(filter);\n}\n\nasync function createMonitor(\n\tctx: TerminalToolContext,\n\tregistry: MonitorRegistry,\n\tinput: MonitorCreateInput,\n\texecCtx: { cwd?: string } | undefined,\n): Promise<TerminalToolResult> {\n\tlet filter: RegExp | undefined;\n\ttry {\n\t\tfilter = compileFilter(input.filter);\n\t} catch {\n\t\treturn errorResult(`Invalid monitor filter regex: ${input.filter}`);\n\t}\n\n\tconst { id, runtime } = await spawnCommandSession(ctx, {\n\t\tcommand: input.command,\n\t\tcols: resolveDimension(undefined, ctx.defaultCols || DEFAULT_COLS),\n\t\trows: resolveDimension(undefined, ctx.defaultRows || DEFAULT_ROWS),\n\t\tcwd: execCtx?.cwd,\n\t\t...(input.persistent ? {} : { timeoutMs: resolveTimeoutMs(input.timeout_ms) }),\n\t});\n\tregistry.register({ id, description: input.description, runtime, filter });\n\treturn textResult(`Monitor started with ID: ${id}`, { details: { bash_id: id, monitor: true } });\n}\n\n/** Build the PTY-backed monitor tool. Monitor handles share TerminalManager's bash_N namespace. */\nexport function createMonitorTool(ctx: TerminalToolContext) {\n\tlet fallbackRegistry: MonitorRegistry | undefined;\n\tconst getRegistry = (): MonitorRegistry => {\n\t\tconst sessionRegistry = ctx.monitorRegistry;\n\t\tif (sessionRegistry) return sessionRegistry;\n\t\tfallbackRegistry ??= new MonitorRegistry((event) => ctx.onMonitorEvent?.(event));\n\t\treturn fallbackRegistry;\n\t};\n\treturn {\n\t\tname: TERMINAL_MONITOR_TOOL,\n\t\tlabel: \"monitor\",\n\t\tdescription:\n\t\t\t\"Subscribe to events from a command instead of polling for them: each stdout line arrives as an injected event while you keep working. Updates identical to a monitor's previous batch are dropped, so a watcher reprinting unchanged status does not re-wake the session. Returns a bash_id immediately; peek with bash_output, stop with kill_bash.\",\n\t\tpromptSnippet: \"Subscribe to a command's stdout lines as injected events instead of polling\",\n\t\tpromptGuidelines: [\n\t\t\t\"Waiting on observable state (CI checks, builds, log patterns, deploys) means a monitor, never a foreground sleep/poll loop.\",\n\t\t],\n\t\tparameters: monitorSchema,\n\t\trenderCall: renderMonitorCall,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: MonitorInput,\n\t\t\t_signal?: AbortSignal,\n\t\t\t_onUpdate?: undefined,\n\t\t\texecCtx?: { cwd?: string },\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst registry = getRegistry();\n\t\t\tif (input.action === \"rearm\") {\n\t\t\t\tconst bashId = input.bash_id;\n\t\t\t\tif (bashId === undefined || bashId.length === 0) return errorResult(\"monitor rearm requires bash_id.\");\n\t\t\t\tconst outcome = registry.rearm(bashId);\n\t\t\t\tif (outcome === \"not_found\") return errorResult(`No active monitor found with id: ${bashId}`);\n\t\t\t\tif (outcome === \"not_paused\") return textResult(`Monitor ${bashId} is not paused; no action taken.`);\n\t\t\t\tctx.onMonitorRearmed?.(bashId);\n\t\t\t\treturn textResult(`Monitor ${bashId} re-armed.`);\n\t\t\t}\n\t\t\tif (!isCreateInput(input)) {\n\t\t\t\treturn errorResult(\"monitor requires description and command to start a watcher.\");\n\t\t\t}\n\t\t\treturn createMonitor(ctx, registry, input, execCtx);\n\t\t},\n\t};\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
2
- import { type TodoItem, type TodoPhase } from "./state.ts";
2
+ import { type TodoCompletionTransition, type TodoItem, type TodoPhase } from "./state.ts";
3
3
  export type TodoCommandAccessors = {
4
4
  getCurrentPhases: () => TodoPhase[];
5
5
  setCurrentPhases: (phases: TodoPhase[]) => void;
6
- syncWidget: (ctx: ExtensionContext) => void;
6
+ syncWidget: (ctx: ExtensionContext, completedTasks?: readonly TodoCompletionTransition[]) => void;
7
7
  };
8
8
  /** Tokenizer honoring double-quoted strings and backslash escapes. */
9
9
  export declare function tokenizeTodoArgs(input: string): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/commands.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAA2B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE9F,OAAO,EAKN,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,MAAM,YAAY,CAAC;AAkBpB,MAAM,MAAM,oBAAoB,GAAG;IAClC,gBAAgB,EAAE,MAAM,SAAS,EAAE,CAAC;IACpC,gBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BxD;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAUxF;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAkBlH;AA8BD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAmS3F"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/commands.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAA2B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE9F,OAAO,EAKN,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,MAAM,YAAY,CAAC;AAkBpB,MAAM,MAAM,oBAAoB,GAAG;IAClC,gBAAgB,EAAE,MAAM,SAAS,EAAE,CAAC;IACpC,gBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,cAAc,CAAC,EAAE,SAAS,wBAAwB,EAAE,KAAK,IAAI,CAAC;CAClG,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BxD;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAUxF;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAkBlH;AA8BD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAmS3F"}
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/commands.ts"],"names":[],"mappings":"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","sourcesContent":["// /todo slash command: user-facing todo management.\n//\n// Ported and adapted from oh-my-pi's\n// `packages/coding-agent/src/modes/controllers/todo-command-controller.ts`\n// (MIT — see NOTICE.md). senpi adaptations: the command registers through the\n// extension API, edits happen in the built-in `ctx.ui.editor` overlay instead\n// of a suspended external $EDITOR, and user edits persist as `senpi.todo-state`\n// entries with `source: \"user\"` so the branch scanner and compaction bridge\n// pick them up unchanged.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { copyToClipboard } from \"../../../../utils/clipboard.ts\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"../../types.ts\";\nimport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nimport {\n\tapplyOpsToPhases,\n\tclonePhases,\n\tDEFAULT_INIT_PHASE,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoItem,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n} from \"./state.ts\";\n\nconst USAGE = [\n\t\"Usage: /todo <verb> [args]\",\n\t\" /todo Show current todos\",\n\t\" /todo edit Edit todos as Markdown in an overlay\",\n\t\" /todo copy Copy todos as Markdown to clipboard\",\n\t\" /todo export [<path>] Write todos to file (default: TODO.md)\",\n\t\" /todo import [<path>] Replace todos from file (default: TODO.md)\",\n\t\" /todo append [<phase>] <task...> Append a task; phase fuzzy-matched or created\",\n\t\" /todo start <task> Mark task in_progress (fuzzy match)\",\n\t\" /todo done [<task|phase>] Mark task/phase/all completed\",\n\t\" /todo drop [<task|phase>] Mark task/phase/all abandoned\",\n\t\" /todo rm [<task|phase>] Remove task/phase/all\",\n].join(\"\\n\");\n\nconst VERBS = [\"edit\", \"copy\", \"export\", \"import\", \"append\", \"start\", \"done\", \"drop\", \"rm\", \"help\"] as const;\n\nexport type TodoCommandAccessors = {\n\tgetCurrentPhases: () => TodoPhase[];\n\tsetCurrentPhases: (phases: TodoPhase[]) => void;\n\tsyncWidget: (ctx: ExtensionContext) => void;\n};\n\n/** Tokenizer honoring double-quoted strings and backslash escapes. */\nexport function tokenizeTodoArgs(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQuote = false;\n\tfor (let index = 0; index < input.length; index += 1) {\n\t\tconst char = input[index];\n\t\tif (char === \"\\\\\" && index + 1 < input.length) {\n\t\t\tcurrent += input[index + 1];\n\t\t\tindex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"') {\n\t\t\tinQuote = !inQuote;\n\t\t\tcontinue;\n\t\t}\n\t\tif (!inQuote && /\\s/.test(char)) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += char;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n\n/** Exact name first, then unique prefix, then unique substring (case-insensitive). */\nexport function findPhaseFuzzy(phases: TodoPhase[], query: string): TodoPhase | undefined {\n\tconst q = query.trim().toLowerCase();\n\tif (!q) return undefined;\n\tconst byName = phases.find((phase) => phase.name.toLowerCase() === q);\n\tif (byName) return byName;\n\tconst prefixMatches = phases.filter((phase) => phase.name.toLowerCase().startsWith(q));\n\tif (prefixMatches.length === 1) return prefixMatches[0];\n\tconst substringMatches = phases.filter((phase) => phase.name.toLowerCase().includes(q));\n\tif (substringMatches.length === 1) return substringMatches[0];\n\treturn undefined;\n}\n\n/** Exact content first, then unique substring; ambiguity resolved toward open work. */\nexport function findTaskFuzzy(phases: TodoPhase[], query: string): { task: TodoItem; phase: TodoPhase } | undefined {\n\tconst q = query.trim().toLowerCase();\n\tif (!q) return undefined;\n\tfor (const phase of phases) {\n\t\tfor (const task of phase.tasks) {\n\t\t\tif (task.content.toLowerCase() === q) return { task, phase };\n\t\t}\n\t}\n\tconst matches: Array<{ task: TodoItem; phase: TodoPhase }> = [];\n\tfor (const phase of phases) {\n\t\tfor (const task of phase.tasks) {\n\t\t\tif (task.content.toLowerCase().includes(q)) matches.push({ task, phase });\n\t\t}\n\t}\n\tif (matches.length === 1) return matches[0];\n\tconst open = matches.filter((hit) => hit.task.status === \"in_progress\" || hit.task.status === \"pending\");\n\tif (open.length === 1) return open[0];\n\treturn undefined;\n}\n\nfunction titleCaseWords(text: string): string {\n\treturn text\n\t\t.split(/\\s+/)\n\t\t.filter(Boolean)\n\t\t.map((word) => word[0].toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n}\n\nfunction titleCaseSentence(text: string): string {\n\tconst trimmed = text.trim();\n\tif (!trimmed) return trimmed;\n\treturn trimmed[0].toUpperCase() + trimmed.slice(1);\n}\n\nfunction buildUserEditReminder(action: string, phases: readonly TodoPhase[], removed: boolean): string {\n\tconst markdown = phases.length === 0 ? \"(empty)\" : phasesToMarkdown(phases).trimEnd();\n\tconst lines = [\"<system-reminder>\", `The user manually modified the todo list (${action}).`];\n\tif (removed) {\n\t\tlines.push(\n\t\t\tphases.length === 0\n\t\t\t\t? \"The user intentionally cleared the todo list. Do NOT recreate or re-populate it unless the user explicitly asks; continue the current request without a todo list.\"\n\t\t\t\t: \"The user intentionally removed the entries no longer shown below. Do NOT re-add them unless the user explicitly asks.\",\n\t\t);\n\t}\n\tlines.push(\"Current todo list:\", \"\", markdown, \"</system-reminder>\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function registerTodoCommand(pi: ExtensionAPI, accessors: TodoCommandAccessors): void {\n\tfunction commit(\n\t\tctx: ExtensionCommandContext,\n\t\tnextPhases: TodoPhase[],\n\t\taction: string,\n\t\toptions?: { removed?: boolean },\n\t): void {\n\t\taccessors.setCurrentPhases(clonePhases(nextPhases));\n\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, {\n\t\t\tschema: \"v2\",\n\t\t\tphases: clonePhases(nextPhases),\n\t\t\tsource: \"user\",\n\t\t\taction,\n\t\t} satisfies TodoStateEntry & { source: string; action: string });\n\t\taccessors.syncWidget(ctx);\n\t\tpi.sendMessage(\n\t\t\t{\n\t\t\t\tcustomType: \"todotools.user-edit\",\n\t\t\t\tcontent: buildUserEditReminder(action, nextPhases, options?.removed ?? false),\n\t\t\t\tdisplay: false,\n\t\t\t},\n\t\t\t{ triggerTurn: false, deliverAs: \"nextTurn\" },\n\t\t);\n\t}\n\n\tfunction showCurrent(ctx: ExtensionCommandContext): void {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos. Use /todo append <task> to start one.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.notify(phasesToMarkdown(phases).trimEnd(), \"info\");\n\t}\n\n\tasync function editInOverlay(ctx: ExtensionCommandContext): Promise<void> {\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst initialMarkdown =\n\t\t\tcurrent.length > 0\n\t\t\t\t? phasesToMarkdown(current)\n\t\t\t\t: `# ${DEFAULT_INIT_PHASE}\\n- [ ] (replace this with your tasks)\\n`;\n\t\tconst edited = await ctx.ui.editor(\"Edit todos (Markdown checklist)\", initialMarkdown);\n\t\tif (edited === undefined || edited === initialMarkdown) {\n\t\t\tctx.ui.notify(\"Todos unchanged.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = markdownToPhases(edited);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(`Could not parse Markdown:\\n ${errors.join(\"\\n \")}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, \"/todo edit\");\n\t\tconst taskCount = phases.reduce((sum, phase) => sum + phase.tasks.length, 0);\n\t\tctx.ui.notify(`Todos updated: ${phases.length} phase(s), ${taskCount} task(s).`, \"info\");\n\t}\n\n\tasync function copyMarkdown(ctx: ExtensionCommandContext): Promise<void> {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos to copy.\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait copyToClipboard(phasesToMarkdown(phases));\n\t\t\tctx.ui.notify(\"Copied todos as Markdown to clipboard.\", \"info\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t}\n\t}\n\n\tasync function exportToFile(ctx: ExtensionCommandContext, rest: string): Promise<void> {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos to export.\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst target = resolveTodoMarkdownPath(rest, ctx.cwd);\n\t\t\tawait writeFile(target, phasesToMarkdown(phases), \"utf8\");\n\t\t\tctx.ui.notify(`Wrote todos to ${target}`, \"info\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(`Failed to write todos: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n\t\t}\n\t}\n\n\tasync function importFromFile(ctx: ExtensionCommandContext, rest: string): Promise<void> {\n\t\tlet source = \"\";\n\t\tlet content: string;\n\t\ttry {\n\t\t\tsource = resolveTodoMarkdownPath(rest, ctx.cwd);\n\t\t\tcontent = await readFile(source, \"utf8\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(`Failed to read todos: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = markdownToPhases(content);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(`Could not parse ${source}:\\n ${errors.join(\"\\n \")}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, `/todo import ${source}`);\n\t\tconst taskCount = phases.reduce((sum, phase) => sum + phase.tasks.length, 0);\n\t\tctx.ui.notify(`Imported ${phases.length} phase(s), ${taskCount} task(s) from ${source}.`, \"info\");\n\t}\n\n\tfunction append(ctx: ExtensionCommandContext, rest: string): void {\n\t\tconst tokens = tokenizeTodoArgs(rest);\n\t\tif (tokens.length === 0) {\n\t\t\tctx.ui.notify(\"Usage: /todo append [<phase>] <task...>\", \"error\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst next = clonePhases(accessors.getCurrentPhases());\n\t\tlet phaseName: string | undefined;\n\t\tlet content: string;\n\t\tif (tokens.length === 1) {\n\t\t\tcontent = tokens[0];\n\t\t} else {\n\t\t\tphaseName = tokens[0];\n\t\t\tcontent = tokens.slice(1).join(\" \");\n\t\t}\n\n\t\tlet targetPhase: TodoPhase | undefined;\n\t\tif (phaseName) {\n\t\t\ttargetPhase = findPhaseFuzzy(next, phaseName);\n\t\t\tif (!targetPhase) {\n\t\t\t\ttargetPhase = { name: titleCaseWords(phaseName), tasks: [] };\n\t\t\t\tnext.push(targetPhase);\n\t\t\t}\n\t\t} else if (next.length > 0) {\n\t\t\ttargetPhase = next[next.length - 1];\n\t\t} else {\n\t\t\ttargetPhase = { name: DEFAULT_INIT_PHASE, tasks: [] };\n\t\t\tnext.push(targetPhase);\n\t\t}\n\n\t\tconst finalContent = titleCaseSentence(content);\n\t\ttargetPhase.tasks.push({ content: finalContent, status: \"pending\" });\n\t\tcommit(ctx, next, `/todo append → ${targetPhase.name}`);\n\t\tctx.ui.notify(`Appended to ${targetPhase.name}: ${finalContent}`, \"info\");\n\t}\n\n\tfunction start(ctx: ExtensionCommandContext, rest: string): void {\n\t\tif (!rest) {\n\t\t\tctx.ui.notify(\"Usage: /todo start <task>\", \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst hit = findTaskFuzzy(current, rest);\n\t\tif (!hit) {\n\t\t\tctx.ui.notify(`No task matched \"${rest}\". Use /todo to list current tasks.`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"start\", task: hit.task.content }]);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, `/todo start ${hit.task.content}`);\n\t\tctx.ui.notify(`Started: ${hit.task.content}`, \"info\");\n\t}\n\n\tfunction mutateStatus(ctx: ExtensionCommandContext, rest: string, target: \"completed\" | \"abandoned\"): void {\n\t\tconst op = target === \"completed\" ? (\"done\" as const) : (\"drop\" as const);\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst trimmed = rest.trim();\n\t\tif (!trimmed) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} (all)`);\n\t\t\tctx.ui.notify(`Marked all tasks ${target}.`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst taskHit = findTaskFuzzy(current, trimmed);\n\t\tif (taskHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op, task: taskHit.task.content }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} ${taskHit.task.content}`);\n\t\t\tctx.ui.notify(`Marked ${target}: ${taskHit.task.content}`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst phaseHit = findPhaseFuzzy(current, trimmed);\n\t\tif (phaseHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op, phase: phaseHit.name }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} ${phaseHit.name}`);\n\t\t\tctx.ui.notify(`Marked phase ${phaseHit.name} ${target}.`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tctx.ui.notify(`No task or phase matched \"${trimmed}\".`, \"error\");\n\t}\n\n\tfunction remove(ctx: ExtensionCommandContext, rest: string): void {\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst trimmed = rest.trim();\n\t\tif (!trimmed) {\n\t\t\tcommit(ctx, [], \"/todo rm (all)\", { removed: true });\n\t\t\tctx.ui.notify(\"Cleared all todos.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst taskHit = findTaskFuzzy(current, trimmed);\n\t\tif (taskHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"rm\", task: taskHit.task.content }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo rm ${taskHit.task.content}`, { removed: true });\n\t\t\tctx.ui.notify(`Removed: ${taskHit.task.content}`, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst phaseHit = findPhaseFuzzy(current, trimmed);\n\t\tif (phaseHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"rm\", phase: phaseHit.name }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo rm ${phaseHit.name}`, { removed: true });\n\t\t\tctx.ui.notify(`Removed phase: ${phaseHit.name}`, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.notify(`No task or phase matched \"${trimmed}\".`, \"error\");\n\t}\n\n\tpi.registerCommand(\"todo\", {\n\t\tdescription: \"Show or edit the todo list (edit/copy/export/import/append/start/done/drop/rm)\",\n\t\tgetArgumentCompletions: (argumentPrefix: string) => {\n\t\t\tconst prefix = argumentPrefix.trim().toLowerCase();\n\t\t\tconst matches = VERBS.filter((verb) => verb.startsWith(prefix));\n\t\t\tif (matches.length === 0) return null;\n\t\t\treturn matches.map((verb) => ({ value: verb, label: verb }));\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContext) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tshowCurrent(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst spaceIndex = trimmed.search(/\\s/);\n\t\t\tconst verb = (spaceIndex === -1 ? trimmed : trimmed.slice(0, spaceIndex)).toLowerCase();\n\t\t\tconst rest = spaceIndex === -1 ? \"\" : trimmed.slice(spaceIndex + 1).trim();\n\n\t\t\tswitch (verb) {\n\t\t\t\tcase \"edit\":\n\t\t\t\t\tawait editInOverlay(ctx);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\tawait copyMarkdown(ctx);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"export\":\n\t\t\t\t\tawait exportToFile(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"import\":\n\t\t\t\t\tawait importFromFile(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"help\":\n\t\t\t\tcase \"?\":\n\t\t\t\t\tctx.ui.notify(USAGE, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"append\":\n\t\t\t\t\tappend(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"start\":\n\t\t\t\t\tstart(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"done\":\n\t\t\t\t\tmutateStatus(ctx, rest, \"completed\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"drop\":\n\t\t\t\t\tmutateStatus(ctx, rest, \"abandoned\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"rm\":\n\t\t\t\t\tremove(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tctx.ui.notify(`Unknown /todo verb \"${verb}\".\\n${USAGE}`, \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/commands.ts"],"names":[],"mappings":"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","sourcesContent":["// /todo slash command: user-facing todo management.\n//\n// Ported and adapted from oh-my-pi's\n// `packages/coding-agent/src/modes/controllers/todo-command-controller.ts`\n// (MIT — see NOTICE.md). senpi adaptations: the command registers through the\n// extension API, edits happen in the built-in `ctx.ui.editor` overlay instead\n// of a suspended external $EDITOR, and user edits persist as `senpi.todo-state`\n// entries with `source: \"user\"` so the branch scanner and compaction bridge\n// pick them up unchanged.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { copyToClipboard } from \"../../../../utils/clipboard.ts\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"../../types.ts\";\nimport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nimport {\n\tapplyOpsToPhases,\n\tclonePhases,\n\tDEFAULT_INIT_PHASE,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n} from \"./state.ts\";\n\nconst USAGE = [\n\t\"Usage: /todo <verb> [args]\",\n\t\" /todo Show current todos\",\n\t\" /todo edit Edit todos as Markdown in an overlay\",\n\t\" /todo copy Copy todos as Markdown to clipboard\",\n\t\" /todo export [<path>] Write todos to file (default: TODO.md)\",\n\t\" /todo import [<path>] Replace todos from file (default: TODO.md)\",\n\t\" /todo append [<phase>] <task...> Append a task; phase fuzzy-matched or created\",\n\t\" /todo start <task> Mark task in_progress (fuzzy match)\",\n\t\" /todo done [<task|phase>] Mark task/phase/all completed\",\n\t\" /todo drop [<task|phase>] Mark task/phase/all abandoned\",\n\t\" /todo rm [<task|phase>] Remove task/phase/all\",\n].join(\"\\n\");\n\nconst VERBS = [\"edit\", \"copy\", \"export\", \"import\", \"append\", \"start\", \"done\", \"drop\", \"rm\", \"help\"] as const;\n\nexport type TodoCommandAccessors = {\n\tgetCurrentPhases: () => TodoPhase[];\n\tsetCurrentPhases: (phases: TodoPhase[]) => void;\n\tsyncWidget: (ctx: ExtensionContext, completedTasks?: readonly TodoCompletionTransition[]) => void;\n};\n\n/** Tokenizer honoring double-quoted strings and backslash escapes. */\nexport function tokenizeTodoArgs(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQuote = false;\n\tfor (let index = 0; index < input.length; index += 1) {\n\t\tconst char = input[index];\n\t\tif (char === \"\\\\\" && index + 1 < input.length) {\n\t\t\tcurrent += input[index + 1];\n\t\t\tindex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"') {\n\t\t\tinQuote = !inQuote;\n\t\t\tcontinue;\n\t\t}\n\t\tif (!inQuote && /\\s/.test(char)) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += char;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n\n/** Exact name first, then unique prefix, then unique substring (case-insensitive). */\nexport function findPhaseFuzzy(phases: TodoPhase[], query: string): TodoPhase | undefined {\n\tconst q = query.trim().toLowerCase();\n\tif (!q) return undefined;\n\tconst byName = phases.find((phase) => phase.name.toLowerCase() === q);\n\tif (byName) return byName;\n\tconst prefixMatches = phases.filter((phase) => phase.name.toLowerCase().startsWith(q));\n\tif (prefixMatches.length === 1) return prefixMatches[0];\n\tconst substringMatches = phases.filter((phase) => phase.name.toLowerCase().includes(q));\n\tif (substringMatches.length === 1) return substringMatches[0];\n\treturn undefined;\n}\n\n/** Exact content first, then unique substring; ambiguity resolved toward open work. */\nexport function findTaskFuzzy(phases: TodoPhase[], query: string): { task: TodoItem; phase: TodoPhase } | undefined {\n\tconst q = query.trim().toLowerCase();\n\tif (!q) return undefined;\n\tfor (const phase of phases) {\n\t\tfor (const task of phase.tasks) {\n\t\t\tif (task.content.toLowerCase() === q) return { task, phase };\n\t\t}\n\t}\n\tconst matches: Array<{ task: TodoItem; phase: TodoPhase }> = [];\n\tfor (const phase of phases) {\n\t\tfor (const task of phase.tasks) {\n\t\t\tif (task.content.toLowerCase().includes(q)) matches.push({ task, phase });\n\t\t}\n\t}\n\tif (matches.length === 1) return matches[0];\n\tconst open = matches.filter((hit) => hit.task.status === \"in_progress\" || hit.task.status === \"pending\");\n\tif (open.length === 1) return open[0];\n\treturn undefined;\n}\n\nfunction titleCaseWords(text: string): string {\n\treturn text\n\t\t.split(/\\s+/)\n\t\t.filter(Boolean)\n\t\t.map((word) => word[0].toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n}\n\nfunction titleCaseSentence(text: string): string {\n\tconst trimmed = text.trim();\n\tif (!trimmed) return trimmed;\n\treturn trimmed[0].toUpperCase() + trimmed.slice(1);\n}\n\nfunction buildUserEditReminder(action: string, phases: readonly TodoPhase[], removed: boolean): string {\n\tconst markdown = phases.length === 0 ? \"(empty)\" : phasesToMarkdown(phases).trimEnd();\n\tconst lines = [\"<system-reminder>\", `The user manually modified the todo list (${action}).`];\n\tif (removed) {\n\t\tlines.push(\n\t\t\tphases.length === 0\n\t\t\t\t? \"The user intentionally cleared the todo list. Do NOT recreate or re-populate it unless the user explicitly asks; continue the current request without a todo list.\"\n\t\t\t\t: \"The user intentionally removed the entries no longer shown below. Do NOT re-add them unless the user explicitly asks.\",\n\t\t);\n\t}\n\tlines.push(\"Current todo list:\", \"\", markdown, \"</system-reminder>\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function registerTodoCommand(pi: ExtensionAPI, accessors: TodoCommandAccessors): void {\n\tfunction commit(\n\t\tctx: ExtensionCommandContext,\n\t\tnextPhases: TodoPhase[],\n\t\taction: string,\n\t\toptions?: { removed?: boolean },\n\t): void {\n\t\taccessors.setCurrentPhases(clonePhases(nextPhases));\n\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, {\n\t\t\tschema: \"v2\",\n\t\t\tphases: clonePhases(nextPhases),\n\t\t\tsource: \"user\",\n\t\t\taction,\n\t\t} satisfies TodoStateEntry & { source: string; action: string });\n\t\taccessors.syncWidget(ctx);\n\t\tpi.sendMessage(\n\t\t\t{\n\t\t\t\tcustomType: \"todotools.user-edit\",\n\t\t\t\tcontent: buildUserEditReminder(action, nextPhases, options?.removed ?? false),\n\t\t\t\tdisplay: false,\n\t\t\t},\n\t\t\t{ triggerTurn: false, deliverAs: \"nextTurn\" },\n\t\t);\n\t}\n\n\tfunction showCurrent(ctx: ExtensionCommandContext): void {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos. Use /todo append <task> to start one.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.notify(phasesToMarkdown(phases).trimEnd(), \"info\");\n\t}\n\n\tasync function editInOverlay(ctx: ExtensionCommandContext): Promise<void> {\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst initialMarkdown =\n\t\t\tcurrent.length > 0\n\t\t\t\t? phasesToMarkdown(current)\n\t\t\t\t: `# ${DEFAULT_INIT_PHASE}\\n- [ ] (replace this with your tasks)\\n`;\n\t\tconst edited = await ctx.ui.editor(\"Edit todos (Markdown checklist)\", initialMarkdown);\n\t\tif (edited === undefined || edited === initialMarkdown) {\n\t\t\tctx.ui.notify(\"Todos unchanged.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = markdownToPhases(edited);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(`Could not parse Markdown:\\n ${errors.join(\"\\n \")}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, \"/todo edit\");\n\t\tconst taskCount = phases.reduce((sum, phase) => sum + phase.tasks.length, 0);\n\t\tctx.ui.notify(`Todos updated: ${phases.length} phase(s), ${taskCount} task(s).`, \"info\");\n\t}\n\n\tasync function copyMarkdown(ctx: ExtensionCommandContext): Promise<void> {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos to copy.\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tawait copyToClipboard(phasesToMarkdown(phases));\n\t\t\tctx.ui.notify(\"Copied todos as Markdown to clipboard.\", \"info\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t}\n\t}\n\n\tasync function exportToFile(ctx: ExtensionCommandContext, rest: string): Promise<void> {\n\t\tconst phases = accessors.getCurrentPhases();\n\t\tif (phases.length === 0) {\n\t\t\tctx.ui.notify(\"No todos to export.\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst target = resolveTodoMarkdownPath(rest, ctx.cwd);\n\t\t\tawait writeFile(target, phasesToMarkdown(phases), \"utf8\");\n\t\t\tctx.ui.notify(`Wrote todos to ${target}`, \"info\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(`Failed to write todos: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n\t\t}\n\t}\n\n\tasync function importFromFile(ctx: ExtensionCommandContext, rest: string): Promise<void> {\n\t\tlet source = \"\";\n\t\tlet content: string;\n\t\ttry {\n\t\t\tsource = resolveTodoMarkdownPath(rest, ctx.cwd);\n\t\t\tcontent = await readFile(source, \"utf8\");\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(`Failed to read todos: ${error instanceof Error ? error.message : String(error)}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = markdownToPhases(content);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(`Could not parse ${source}:\\n ${errors.join(\"\\n \")}`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, `/todo import ${source}`);\n\t\tconst taskCount = phases.reduce((sum, phase) => sum + phase.tasks.length, 0);\n\t\tctx.ui.notify(`Imported ${phases.length} phase(s), ${taskCount} task(s) from ${source}.`, \"info\");\n\t}\n\n\tfunction append(ctx: ExtensionCommandContext, rest: string): void {\n\t\tconst tokens = tokenizeTodoArgs(rest);\n\t\tif (tokens.length === 0) {\n\t\t\tctx.ui.notify(\"Usage: /todo append [<phase>] <task...>\", \"error\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst next = clonePhases(accessors.getCurrentPhases());\n\t\tlet phaseName: string | undefined;\n\t\tlet content: string;\n\t\tif (tokens.length === 1) {\n\t\t\tcontent = tokens[0];\n\t\t} else {\n\t\t\tphaseName = tokens[0];\n\t\t\tcontent = tokens.slice(1).join(\" \");\n\t\t}\n\n\t\tlet targetPhase: TodoPhase | undefined;\n\t\tif (phaseName) {\n\t\t\ttargetPhase = findPhaseFuzzy(next, phaseName);\n\t\t\tif (!targetPhase) {\n\t\t\t\ttargetPhase = { name: titleCaseWords(phaseName), tasks: [] };\n\t\t\t\tnext.push(targetPhase);\n\t\t\t}\n\t\t} else if (next.length > 0) {\n\t\t\ttargetPhase = next[next.length - 1];\n\t\t} else {\n\t\t\ttargetPhase = { name: DEFAULT_INIT_PHASE, tasks: [] };\n\t\t\tnext.push(targetPhase);\n\t\t}\n\n\t\tconst finalContent = titleCaseSentence(content);\n\t\ttargetPhase.tasks.push({ content: finalContent, status: \"pending\" });\n\t\tcommit(ctx, next, `/todo append → ${targetPhase.name}`);\n\t\tctx.ui.notify(`Appended to ${targetPhase.name}: ${finalContent}`, \"info\");\n\t}\n\n\tfunction start(ctx: ExtensionCommandContext, rest: string): void {\n\t\tif (!rest) {\n\t\t\tctx.ui.notify(\"Usage: /todo start <task>\", \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst hit = findTaskFuzzy(current, rest);\n\t\tif (!hit) {\n\t\t\tctx.ui.notify(`No task matched \"${rest}\". Use /todo to list current tasks.`, \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"start\", task: hit.task.content }]);\n\t\tif (errors.length > 0) {\n\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\treturn;\n\t\t}\n\t\tcommit(ctx, phases, `/todo start ${hit.task.content}`);\n\t\tctx.ui.notify(`Started: ${hit.task.content}`, \"info\");\n\t}\n\n\tfunction mutateStatus(ctx: ExtensionCommandContext, rest: string, target: \"completed\" | \"abandoned\"): void {\n\t\tconst op = target === \"completed\" ? (\"done\" as const) : (\"drop\" as const);\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst trimmed = rest.trim();\n\t\tif (!trimmed) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} (all)`);\n\t\t\tctx.ui.notify(`Marked all tasks ${target}.`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst taskHit = findTaskFuzzy(current, trimmed);\n\t\tif (taskHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op, task: taskHit.task.content }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} ${taskHit.task.content}`);\n\t\t\tctx.ui.notify(`Marked ${target}: ${taskHit.task.content}`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst phaseHit = findPhaseFuzzy(current, trimmed);\n\t\tif (phaseHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op, phase: phaseHit.name }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo ${op} ${phaseHit.name}`);\n\t\t\tctx.ui.notify(`Marked phase ${phaseHit.name} ${target}.`, \"info\");\n\t\t\treturn;\n\t\t}\n\n\t\tctx.ui.notify(`No task or phase matched \"${trimmed}\".`, \"error\");\n\t}\n\n\tfunction remove(ctx: ExtensionCommandContext, rest: string): void {\n\t\tconst current = accessors.getCurrentPhases();\n\t\tconst trimmed = rest.trim();\n\t\tif (!trimmed) {\n\t\t\tcommit(ctx, [], \"/todo rm (all)\", { removed: true });\n\t\t\tctx.ui.notify(\"Cleared all todos.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst taskHit = findTaskFuzzy(current, trimmed);\n\t\tif (taskHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"rm\", task: taskHit.task.content }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo rm ${taskHit.task.content}`, { removed: true });\n\t\t\tctx.ui.notify(`Removed: ${taskHit.task.content}`, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tconst phaseHit = findPhaseFuzzy(current, trimmed);\n\t\tif (phaseHit) {\n\t\t\tconst { phases, errors } = applyOpsToPhases(current, [{ op: \"rm\", phase: phaseHit.name }]);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tctx.ui.notify(errors.join(\"; \"), \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcommit(ctx, phases, `/todo rm ${phaseHit.name}`, { removed: true });\n\t\t\tctx.ui.notify(`Removed phase: ${phaseHit.name}`, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.notify(`No task or phase matched \"${trimmed}\".`, \"error\");\n\t}\n\n\tpi.registerCommand(\"todo\", {\n\t\tdescription: \"Show or edit the todo list (edit/copy/export/import/append/start/done/drop/rm)\",\n\t\tgetArgumentCompletions: (argumentPrefix: string) => {\n\t\t\tconst prefix = argumentPrefix.trim().toLowerCase();\n\t\t\tconst matches = VERBS.filter((verb) => verb.startsWith(prefix));\n\t\t\tif (matches.length === 0) return null;\n\t\t\treturn matches.map((verb) => ({ value: verb, label: verb }));\n\t\t},\n\t\thandler: async (args: string, ctx: ExtensionCommandContext) => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tshowCurrent(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst spaceIndex = trimmed.search(/\\s/);\n\t\t\tconst verb = (spaceIndex === -1 ? trimmed : trimmed.slice(0, spaceIndex)).toLowerCase();\n\t\t\tconst rest = spaceIndex === -1 ? \"\" : trimmed.slice(spaceIndex + 1).trim();\n\n\t\t\tswitch (verb) {\n\t\t\t\tcase \"edit\":\n\t\t\t\t\tawait editInOverlay(ctx);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\tawait copyMarkdown(ctx);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"export\":\n\t\t\t\t\tawait exportToFile(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"import\":\n\t\t\t\t\tawait importFromFile(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"help\":\n\t\t\t\tcase \"?\":\n\t\t\t\t\tctx.ui.notify(USAGE, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"append\":\n\t\t\t\t\tappend(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"start\":\n\t\t\t\t\tstart(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"done\":\n\t\t\t\t\tmutateStatus(ctx, rest, \"completed\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"drop\":\n\t\t\t\t\tmutateStatus(ctx, rest, \"abandoned\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"rm\":\n\t\t\t\t\tremove(ctx, rest);\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tctx.ui.notify(`Unknown /todo verb \"${verb}\".\\n${USAGE}`, \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAUrE,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAkCjE;AAED,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,EAChC,+BAA+B,EAC/B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAiBrE,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAsCjE;AAED,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,EAChC,+BAA+B,EAC/B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { registerTodoCommand } from "./commands.js";
2
2
  import { TASK_MANAGEMENT_SECTION } from "./prompt.js";
3
- import { clonePhases, getLatestPhasesFromBranchEntries, getTodoWidgetLines } from "./state.js";
3
+ import { clonePhases, getLatestPhasesFromBranchEntries, } from "./state.js";
4
+ import { getTodoWidgetModel } from "./todo-widget.js";
5
+ import { TodoWidgetComponent } from "./todo-widget-component.js";
4
6
  import { registerTodoTool } from "./tools/todo.js";
5
7
  function getLatestPhases(ctx) {
6
8
  return getLatestPhasesFromBranchEntries(ctx.sessionManager.getBranch());
@@ -11,8 +13,9 @@ export default function todotoolsExtension(pi) {
11
13
  const setCurrentPhases = (phases) => {
12
14
  currentPhases = clonePhases(phases);
13
15
  };
14
- const syncWidget = (ctx) => {
15
- ctx.ui.setWidget("todo-sidebar", getTodoWidgetLines(currentPhases));
16
+ const syncWidget = (ctx, completedTasks = []) => {
17
+ const model = getTodoWidgetModel(currentPhases);
18
+ ctx.ui.setWidget("todo-sidebar", model ? (tui, theme) => new TodoWidgetComponent(tui, theme, model, completedTasks) : undefined);
16
19
  };
17
20
  const syncFromSession = (ctx) => {
18
21
  currentPhases = getLatestPhases(ctx);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,gCAAgC,EAAE,kBAAkB,EAAkB,MAAM,YAAY,CAAC;AAC/G,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,SAAS,eAAe,CAAC,GAAqB;IAC7C,OAAO,gCAAgC,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAgB;IAC1D,IAAI,aAAa,GAAgB,EAAE,CAAC;IAEpC,MAAM,gBAAgB,GAAG,GAAgB,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;IAEvE,MAAM,gBAAgB,GAAG,CAAC,MAAmB,EAAQ,EAAE;QACtD,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,GAAqB,EAAQ,EAAE;QAClD,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,CAAC,GAAqB,EAAQ,EAAE;QACvD,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACrC,UAAU,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC5C,eAAe,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,eAAe,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC3C,OAAO;YACN,YAAY,EAAE,GAAG,KAAK,CAAC,YAAY,KAAK,uBAAuB,EAAE;SACjE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAC;IACzE,mBAAmB,CAAC,EAAE,EAAE,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,EAChC,+BAA+B,EAC/B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GASrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerTodoCommand } from \"./commands.ts\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nimport { clonePhases, getLatestPhasesFromBranchEntries, getTodoWidgetLines, type TodoPhase } from \"./state.ts\";\nimport { registerTodoTool } from \"./tools/todo.ts\";\n\nfunction getLatestPhases(ctx: ExtensionContext): TodoPhase[] {\n\treturn getLatestPhasesFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentPhases: TodoPhase[] = [];\n\n\tconst getCurrentPhases = (): TodoPhase[] => clonePhases(currentPhases);\n\n\tconst setCurrentPhases = (phases: TodoPhase[]): void => {\n\t\tcurrentPhases = clonePhases(phases);\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext): void => {\n\t\tctx.ui.setWidget(\"todo-sidebar\", getTodoWidgetLines(currentPhases));\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentPhases = getLatestPhases(ctx);\n\t\tsyncWidget(ctx);\n\t};\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`,\n\t\t};\n\t});\n\n\tregisterTodoTool(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n\tregisterTodoCommand(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n}\n\nexport { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from \"./commands.ts\";\nexport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tclonePhases,\n\tcloneTask,\n\tDEFAULT_INIT_PHASE,\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tgetTaskTargets,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tinitPhases,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n\tremoveTasks,\n\tresolvePhaseOrError,\n\tresolveTaskOrError,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./state.ts\";\nexport { phaseRomanNumeral } from \"./tools/todo.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerTodoCommand } from \"./commands.ts\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nimport {\n\tclonePhases,\n\tgetLatestPhasesFromBranchEntries,\n\ttype TodoCompletionTransition,\n\ttype TodoPhase,\n} from \"./state.ts\";\nimport { getTodoWidgetModel } from \"./todo-widget.ts\";\nimport { TodoWidgetComponent } from \"./todo-widget-component.ts\";\nimport { registerTodoTool } from \"./tools/todo.ts\";\n\nfunction getLatestPhases(ctx: ExtensionContext): TodoPhase[] {\n\treturn getLatestPhasesFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentPhases: TodoPhase[] = [];\n\n\tconst getCurrentPhases = (): TodoPhase[] => clonePhases(currentPhases);\n\n\tconst setCurrentPhases = (phases: TodoPhase[]): void => {\n\t\tcurrentPhases = clonePhases(phases);\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext, completedTasks: readonly TodoCompletionTransition[] = []): void => {\n\t\tconst model = getTodoWidgetModel(currentPhases);\n\t\tctx.ui.setWidget(\n\t\t\t\"todo-sidebar\",\n\t\t\tmodel ? (tui, theme) => new TodoWidgetComponent(tui, theme, model, completedTasks) : undefined,\n\t\t);\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentPhases = getLatestPhases(ctx);\n\t\tsyncWidget(ctx);\n\t};\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`,\n\t\t};\n\t});\n\n\tregisterTodoTool(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n\tregisterTodoCommand(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n}\n\nexport { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from \"./commands.ts\";\nexport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tclonePhases,\n\tcloneTask,\n\tDEFAULT_INIT_PHASE,\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tgetTaskTargets,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tinitPhases,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n\tremoveTasks,\n\tresolvePhaseOrError,\n\tresolveTaskOrError,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./state.ts\";\nexport { phaseRomanNumeral } from \"./tools/todo.ts\";\n"]}
@@ -4,5 +4,5 @@ export { findPhaseByName, findTaskByContent, getCompletionTransitions, nextActio
4
4
  export { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from "./todo-resolution.ts";
5
5
  export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.ts";
6
6
  export { DEFAULT_INIT_PHASE, TODO_STATE_ENTRY_TYPE, type TodoCompletionTransition, type TodoItem, type TodoOpEntry, type TodoOperation, type TodoPhase, type TodoStateEntry, type TodoStatus, type TodoToolDetails, } from "./todo-types.ts";
7
- export { getTodoWidgetLines } from "./todo-widget.ts";
7
+ export { getTodoWidgetLines, getTodoWidgetModel, type TodoWidgetModel, type TodoWidgetRow, } from "./todo-widget.ts";
8
8
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,+BAA+B,EAC/B,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,+BAA+B,EAC/B,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,GAClB,MAAM,kBAAkB,CAAC"}
@@ -8,5 +8,5 @@ export { findPhaseByName, findTaskByContent, getCompletionTransitions, nextActio
8
8
  export { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from "./todo-resolution.js";
9
9
  export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.js";
10
10
  export { DEFAULT_INIT_PHASE, TODO_STATE_ENTRY_TYPE, } from "./todo-types.js";
11
- export { getTodoWidgetLines } from "./todo-widget.js";
11
+ export { getTodoWidgetLines, getTodoWidgetModel, } from "./todo-widget.js";
12
12
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,OAAO,EACN,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,+BAA+B,EAC/B,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,qBAAqB,GASrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["// Ported and adapted from oh-my-pi's todo tool (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nexport {\n\tformatSummary,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tsanitizeTodoText,\n} from \"./todo-format.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tinitPhases,\n\tremoveTasks,\n} from \"./todo-operations.ts\";\nexport {\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tgetCompletionTransitions,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n} from \"./todo-query.ts\";\nexport { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from \"./todo-resolution.ts\";\nexport {\n\tclonePhases,\n\tcloneTask,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n} from \"./todo-storage.ts\";\nexport {\n\tDEFAULT_INIT_PHASE,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./todo-types.ts\";\nexport { getTodoWidgetLines } from \"./todo-widget.ts\";\n"]}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,OAAO,EACN,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,+BAA+B,EAC/B,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,qBAAqB,GASrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,kBAAkB,EAClB,kBAAkB,GAGlB,MAAM,kBAAkB,CAAC","sourcesContent":["// Ported and adapted from oh-my-pi's todo tool (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nexport {\n\tformatSummary,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tsanitizeTodoText,\n} from \"./todo-format.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tinitPhases,\n\tremoveTasks,\n} from \"./todo-operations.ts\";\nexport {\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tgetCompletionTransitions,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n} from \"./todo-query.ts\";\nexport { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from \"./todo-resolution.ts\";\nexport {\n\tclonePhases,\n\tcloneTask,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n} from \"./todo-storage.ts\";\nexport {\n\tDEFAULT_INIT_PHASE,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./todo-types.ts\";\nexport {\n\tgetTodoWidgetLines,\n\tgetTodoWidgetModel,\n\ttype TodoWidgetModel,\n\ttype TodoWidgetRow,\n} from \"./todo-widget.ts\";\n"]}
@@ -0,0 +1,19 @@
1
+ import { Text, type TUI } from "@earendil-works/pi-tui";
2
+ import type { Theme } from "../../../../modes/interactive/theme/theme.ts";
3
+ import type { TodoCompletionTransition } from "./todo-types.ts";
4
+ import type { TodoWidgetModel } from "./todo-widget.ts";
5
+ export declare class TodoWidgetComponent extends Text {
6
+ private readonly tui;
7
+ private readonly theme;
8
+ private readonly model;
9
+ private readonly completionKeys;
10
+ private frame;
11
+ private intervalId;
12
+ constructor(tui: TUI, theme: Theme, model: TodoWidgetModel, completedTasks: readonly TodoCompletionTransition[]);
13
+ dispose(): void;
14
+ private startAnimation;
15
+ private stopAnimation;
16
+ private tick;
17
+ private updateDisplay;
18
+ }
19
+ //# sourceMappingURL=todo-widget-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-widget-component.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-widget-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAOxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,KAAK,EAAE,wBAAwB,EAAY,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AA6CxD,qBAAa,mBAAoB,SAAQ,IAAI;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IACrD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAA6B;IAE/C,YAAY,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,wBAAwB,EAAE,EAS9G;IAED,OAAO,IAAI,IAAI,CAEd;IAED,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,aAAa;CASrB"}
@@ -0,0 +1,78 @@
1
+ import { Text } from "@earendil-works/pi-tui";
2
+ import { partialStrikethrough, strikeRevealCount, TODO_STRIKE_FRAME_INTERVAL_MS, TODO_STRIKE_TOTAL_FRAMES, } from "../../../../modes/interactive/components/todo-strike.js";
3
+ import { getTodoMarker, sanitizeTodoText } from "./todo-format.js";
4
+ function formatTask(task, theme, completionKeys, frame) {
5
+ const line = `${getTodoMarker(task.status)} ${sanitizeTodoText(task.content)}`;
6
+ switch (task.status) {
7
+ case "completed": {
8
+ const reveal = completionKeys.has(task.content) ? strikeRevealCount(line, frame) : undefined;
9
+ return reveal === undefined
10
+ ? theme.fg("dim", theme.strikethrough(line))
11
+ : theme.fg("dim", partialStrikethrough(line, reveal, (text) => theme.strikethrough(text)));
12
+ }
13
+ case "in_progress":
14
+ return theme.fg("accent", theme.bold(line));
15
+ case "abandoned":
16
+ return theme.fg("dim", line);
17
+ case "pending":
18
+ return line;
19
+ }
20
+ }
21
+ function getAnimatedCompletionKeys(model, completedTasks) {
22
+ const visibleCompletedTasks = new Set();
23
+ for (const row of model.rows) {
24
+ if (row.kind === "task" && row.task.status === "completed") {
25
+ visibleCompletedTasks.add(row.task.content);
26
+ }
27
+ }
28
+ return new Set(completedTasks
29
+ .filter((transition) => transition.phase === model.phaseName && visibleCompletedTasks.has(transition.content))
30
+ .map((transition) => transition.content));
31
+ }
32
+ export class TodoWidgetComponent extends Text {
33
+ constructor(tui, theme, model, completedTasks) {
34
+ super("", 1, 0);
35
+ this.tui = tui;
36
+ this.theme = theme;
37
+ this.model = model;
38
+ this.completionKeys = getAnimatedCompletionKeys(model, completedTasks);
39
+ this.frame = this.completionKeys.size > 0 ? 0 : undefined;
40
+ this.updateDisplay();
41
+ if (this.frame !== undefined)
42
+ this.startAnimation();
43
+ }
44
+ dispose() {
45
+ this.stopAnimation();
46
+ }
47
+ startAnimation() {
48
+ const handle = setInterval(() => this.tick(), TODO_STRIKE_FRAME_INTERVAL_MS);
49
+ handle.unref();
50
+ this.intervalId = handle;
51
+ }
52
+ stopAnimation() {
53
+ if (this.intervalId === undefined)
54
+ return;
55
+ clearInterval(this.intervalId);
56
+ this.intervalId = undefined;
57
+ }
58
+ tick() {
59
+ if (this.frame === undefined)
60
+ return;
61
+ const nextFrame = this.frame + 1;
62
+ if (nextFrame >= TODO_STRIKE_TOTAL_FRAMES) {
63
+ this.frame = undefined;
64
+ this.stopAnimation();
65
+ }
66
+ else {
67
+ this.frame = nextFrame;
68
+ }
69
+ this.updateDisplay();
70
+ this.tui.requestRender();
71
+ }
72
+ updateDisplay() {
73
+ this.setText(this.model.rows
74
+ .map((row) => row.kind === "label" ? row.text : formatTask(row.task, this.theme, this.completionKeys, this.frame))
75
+ .join("\n"));
76
+ }
77
+ }
78
+ //# sourceMappingURL=todo-widget-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-widget-component.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-widget-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACN,oBAAoB,EACpB,iBAAiB,EACjB,6BAA6B,EAC7B,wBAAwB,GACxB,MAAM,yDAAyD,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAInE,SAAS,UAAU,CAClB,IAAc,EACd,KAAY,EACZ,cAAmC,EACnC,KAAyB;IAEzB,MAAM,IAAI,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/E,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACrB,KAAK,WAAW,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7F,OAAO,MAAM,KAAK,SAAS;gBAC1B,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC,CAAC,KAAK,CAAC,EAAE,CACR,KAAK,EACL,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CACvE,CAAC;QACL,CAAC;QACD,KAAK,aAAa;YACjB,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,KAAK,WAAW;YACf,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9B,KAAK,SAAS;YACb,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,SAAS,yBAAyB,CACjC,KAAsB,EACtB,cAAmD;IAEnD,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC5D,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;IACD,OAAO,IAAI,GAAG,CACb,cAAc;SACZ,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,KAAK,KAAK,CAAC,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;SAC7G,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CACzC,CAAC;AACH,CAAC;AAED,MAAM,OAAO,mBAAoB,SAAQ,IAAI;IAQ5C,YAAY,GAAQ,EAAE,KAAY,EAAE,KAAsB,EAAE,cAAmD;QAC9G,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,cAAc,GAAG,yBAAyB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACvE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1D,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,EAAE,CAAC;IACrD,CAAC;IAED,OAAO;QACN,IAAI,CAAC,aAAa,EAAE,CAAC;IACtB,CAAC;IAEO,cAAc;QACrB,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,6BAA6B,CAAC,CAAC;QAC7E,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;IAC1B,CAAC;IAEO,aAAa;QACpB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO;QAC1C,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEO,IAAI;QACX,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACjC,IAAI,SAAS,IAAI,wBAAwB,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,IAAI,CAAC,aAAa,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IAEO,aAAa;QACpB,IAAI,CAAC,OAAO,CACX,IAAI,CAAC,KAAK,CAAC,IAAI;aACb,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACZ,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CACnG;aACA,IAAI,CAAC,IAAI,CAAC,CACZ,CAAC;IACH,CAAC;CACD","sourcesContent":["import { Text, type TUI } from \"@earendil-works/pi-tui\";\nimport {\n\tpartialStrikethrough,\n\tstrikeRevealCount,\n\tTODO_STRIKE_FRAME_INTERVAL_MS,\n\tTODO_STRIKE_TOTAL_FRAMES,\n} from \"../../../../modes/interactive/components/todo-strike.ts\";\nimport type { Theme } from \"../../../../modes/interactive/theme/theme.ts\";\nimport { getTodoMarker, sanitizeTodoText } from \"./todo-format.ts\";\nimport type { TodoCompletionTransition, TodoItem } from \"./todo-types.ts\";\nimport type { TodoWidgetModel } from \"./todo-widget.ts\";\n\nfunction formatTask(\n\ttask: TodoItem,\n\ttheme: Theme,\n\tcompletionKeys: ReadonlySet<string>,\n\tframe: number | undefined,\n): string {\n\tconst line = `${getTodoMarker(task.status)} ${sanitizeTodoText(task.content)}`;\n\tswitch (task.status) {\n\t\tcase \"completed\": {\n\t\t\tconst reveal = completionKeys.has(task.content) ? strikeRevealCount(line, frame) : undefined;\n\t\t\treturn reveal === undefined\n\t\t\t\t? theme.fg(\"dim\", theme.strikethrough(line))\n\t\t\t\t: theme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\tpartialStrikethrough(line, reveal, (text) => theme.strikethrough(text)),\n\t\t\t\t\t);\n\t\t}\n\t\tcase \"in_progress\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(line));\n\t\tcase \"abandoned\":\n\t\t\treturn theme.fg(\"dim\", line);\n\t\tcase \"pending\":\n\t\t\treturn line;\n\t}\n}\n\nfunction getAnimatedCompletionKeys(\n\tmodel: TodoWidgetModel,\n\tcompletedTasks: readonly TodoCompletionTransition[],\n): ReadonlySet<string> {\n\tconst visibleCompletedTasks = new Set<string>();\n\tfor (const row of model.rows) {\n\t\tif (row.kind === \"task\" && row.task.status === \"completed\") {\n\t\t\tvisibleCompletedTasks.add(row.task.content);\n\t\t}\n\t}\n\treturn new Set(\n\t\tcompletedTasks\n\t\t\t.filter((transition) => transition.phase === model.phaseName && visibleCompletedTasks.has(transition.content))\n\t\t\t.map((transition) => transition.content),\n\t);\n}\n\nexport class TodoWidgetComponent extends Text {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly model: TodoWidgetModel;\n\tprivate readonly completionKeys: ReadonlySet<string>;\n\tprivate frame: number | undefined;\n\tprivate intervalId: NodeJS.Timeout | undefined;\n\n\tconstructor(tui: TUI, theme: Theme, model: TodoWidgetModel, completedTasks: readonly TodoCompletionTransition[]) {\n\t\tsuper(\"\", 1, 0);\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.model = model;\n\t\tthis.completionKeys = getAnimatedCompletionKeys(model, completedTasks);\n\t\tthis.frame = this.completionKeys.size > 0 ? 0 : undefined;\n\t\tthis.updateDisplay();\n\t\tif (this.frame !== undefined) this.startAnimation();\n\t}\n\n\tdispose(): void {\n\t\tthis.stopAnimation();\n\t}\n\n\tprivate startAnimation(): void {\n\t\tconst handle = setInterval(() => this.tick(), TODO_STRIKE_FRAME_INTERVAL_MS);\n\t\thandle.unref();\n\t\tthis.intervalId = handle;\n\t}\n\n\tprivate stopAnimation(): void {\n\t\tif (this.intervalId === undefined) return;\n\t\tclearInterval(this.intervalId);\n\t\tthis.intervalId = undefined;\n\t}\n\n\tprivate tick(): void {\n\t\tif (this.frame === undefined) return;\n\t\tconst nextFrame = this.frame + 1;\n\t\tif (nextFrame >= TODO_STRIKE_TOTAL_FRAMES) {\n\t\t\tthis.frame = undefined;\n\t\t\tthis.stopAnimation();\n\t\t} else {\n\t\t\tthis.frame = nextFrame;\n\t\t}\n\t\tthis.updateDisplay();\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.setText(\n\t\t\tthis.model.rows\n\t\t\t\t.map((row) =>\n\t\t\t\t\trow.kind === \"label\" ? row.text : formatTask(row.task, this.theme, this.completionKeys, this.frame),\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\"),\n\t\t);\n\t}\n}\n"]}
@@ -1,3 +1,15 @@
1
- import type { TodoPhase } from "./todo-types.ts";
1
+ import type { TodoItem, TodoPhase } from "./todo-types.ts";
2
+ export type TodoWidgetRow = {
3
+ readonly kind: "label";
4
+ readonly text: string;
5
+ } | {
6
+ readonly kind: "task";
7
+ readonly task: TodoItem;
8
+ };
9
+ export type TodoWidgetModel = {
10
+ readonly phaseName: string;
11
+ readonly rows: readonly TodoWidgetRow[];
12
+ };
13
+ export declare function getTodoWidgetModel(phases: readonly TodoPhase[]): TodoWidgetModel | undefined;
2
14
  export declare function getTodoWidgetLines(phases: readonly TodoPhase[]): string[] | undefined;
3
15
  //# sourceMappingURL=todo-widget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"todo-widget.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-widget.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAoB3D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CA6BrF"}
1
+ {"version":3,"file":"todo-widget.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-widget.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM3D,MAAM,MAAM,aAAa,GACtB;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACrB,GACD;IACA,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;CACvB,CAAC;AAEL,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;CACxC,CAAC;AAwBF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,eAAe,GAAG,SAAS,CAoC5F;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAIrF"}
@@ -19,14 +19,24 @@ function formatOmittedTasks(count, direction) {
19
19
  function formatTask(todo) {
20
20
  return `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`;
21
21
  }
22
- export function getTodoWidgetLines(phases) {
22
+ function label(text) {
23
+ return { kind: "label", text };
24
+ }
25
+ function taskRow(task) {
26
+ return { kind: "task", task };
27
+ }
28
+ export function getTodoWidgetModel(phases) {
23
29
  const activePhase = getActivePhase(phases);
24
30
  if (!activePhase)
25
31
  return undefined;
26
- const header = ["Todo", sanitizeTodoText(activePhase.name)];
27
- const taskLines = activePhase.tasks.map(formatTask);
28
- if (header.length + taskLines.length <= TODO_WIDGET_MAX_LINES)
29
- return [...header, ...taskLines];
32
+ const header = [label("Todo"), label(sanitizeTodoText(activePhase.name))];
33
+ const taskRows = activePhase.tasks.map(taskRow);
34
+ if (header.length + taskRows.length <= TODO_WIDGET_MAX_LINES) {
35
+ return {
36
+ phaseName: activePhase.name,
37
+ rows: [...header, ...taskRows],
38
+ };
39
+ }
30
40
  const activeTask = nextActionableTask([activePhase]);
31
41
  if (!activeTask)
32
42
  return undefined;
@@ -34,19 +44,27 @@ export function getTodoWidgetLines(phases) {
34
44
  const firstVisibleTask = Math.max(0, activeIndex - TODO_WIDGET_RECENT_TASKS);
35
45
  const earlierOmitted = firstVisibleTask;
36
46
  const bodyBudget = TODO_WIDGET_MAX_LINES - TODO_WIDGET_HEADER_LINES;
37
- const recentAndActive = taskLines.slice(firstVisibleTask, activeIndex + 1);
47
+ const recentAndActive = activePhase.tasks.slice(firstVisibleTask, activeIndex + 1).map(taskRow);
38
48
  const earlierMarkerRows = earlierOmitted > 0 ? 1 : 0;
39
49
  const pendingAfterActive = activePhase.tasks.slice(activeIndex + 1).filter((todo) => todo.status === "pending");
40
50
  const upcomingBudget = bodyBudget - recentAndActive.length - earlierMarkerRows;
41
51
  const visibleUpcomingCount = pendingAfterActive.length > upcomingBudget ? Math.max(0, upcomingBudget - 1) : pendingAfterActive.length;
42
52
  const laterOmitted = pendingAfterActive.length - visibleUpcomingCount;
43
- return [
44
- "Todo",
45
- sanitizeTodoText(activePhase.name),
46
- ...(earlierOmitted > 0 ? [formatOmittedTasks(earlierOmitted, "earlier")] : []),
47
- ...recentAndActive,
48
- ...pendingAfterActive.slice(0, visibleUpcomingCount).map(formatTask),
49
- ...(laterOmitted > 0 ? [formatOmittedTasks(laterOmitted, "later")] : []),
50
- ];
53
+ return {
54
+ phaseName: activePhase.name,
55
+ rows: [
56
+ ...header,
57
+ ...(earlierOmitted > 0 ? [label(formatOmittedTasks(earlierOmitted, "earlier"))] : []),
58
+ ...recentAndActive,
59
+ ...pendingAfterActive.slice(0, visibleUpcomingCount).map(taskRow),
60
+ ...(laterOmitted > 0 ? [label(formatOmittedTasks(laterOmitted, "later"))] : []),
61
+ ],
62
+ };
63
+ }
64
+ export function getTodoWidgetLines(phases) {
65
+ const model = getTodoWidgetModel(phases);
66
+ if (!model)
67
+ return undefined;
68
+ return model.rows.map((row) => (row.kind === "label" ? row.text : formatTask(row.task)));
51
69
  }
52
70
  //# sourceMappingURL=todo-widget.js.map