@code-yeongyu/senpi 2026.7.25 → 2026.7.26

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 (575) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +1 -1
  3. package/dist/beta/omo-local-update.d.ts +207 -0
  4. package/dist/beta/omo-local-update.d.ts.map +1 -0
  5. package/dist/beta/omo-local-update.js +708 -0
  6. package/dist/beta/omo-local-update.js.map +1 -0
  7. package/dist/cli/args.d.ts +4 -16
  8. package/dist/cli/args.d.ts.map +1 -1
  9. package/dist/cli/args.js +9 -25
  10. package/dist/cli/args.js.map +1 -1
  11. package/dist/cli/grok-neo-gate.d.ts +12 -0
  12. package/dist/cli/grok-neo-gate.d.ts.map +1 -0
  13. package/dist/cli/grok-neo-gate.js +18 -0
  14. package/dist/cli/grok-neo-gate.js.map +1 -0
  15. package/dist/cli-main.js +4 -0
  16. package/dist/cli-main.js.map +1 -1
  17. package/dist/cli.js +2 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/core/agent-session-runtime.d.ts +2 -0
  20. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  21. package/dist/core/agent-session-runtime.js +33 -8
  22. package/dist/core/agent-session-runtime.js.map +1 -1
  23. package/dist/core/agent-session.d.ts +22 -3
  24. package/dist/core/agent-session.d.ts.map +1 -1
  25. package/dist/core/agent-session.js +202 -58
  26. package/dist/core/agent-session.js.map +1 -1
  27. package/dist/core/auth-providers.d.ts +2 -2
  28. package/dist/core/auth-providers.js +2 -2
  29. package/dist/core/auth-providers.js.map +1 -1
  30. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/bash-timeout/timeout.js +3 -2
  32. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  33. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/index.js +30 -2
  35. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/compaction/speculative.js +28 -0
  38. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  39. package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/config-reload/index.js +20 -17
  41. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  42. package/dist/core/extensions/builtin/config-reload/log.d.ts +4 -1
  43. package/dist/core/extensions/builtin/config-reload/log.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/config-reload/log.js +3 -0
  45. package/dist/core/extensions/builtin/config-reload/log.js.map +1 -1
  46. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts +15 -0
  47. package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -0
  48. package/dist/core/extensions/builtin/config-reload/routine-settings.js +102 -0
  49. package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -0
  50. package/dist/core/extensions/builtin/goal/command-registration.js +2 -2
  51. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  52. package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
  53. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/goal/format.js +9 -2
  55. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  56. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/goal/index.js +38 -23
  58. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  59. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +6 -0
  60. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -0
  61. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +19 -0
  62. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -0
  63. package/dist/core/extensions/builtin/goal/persistence.d.ts +6 -0
  64. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -0
  65. package/dist/core/extensions/builtin/goal/persistence.js +141 -0
  66. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -0
  67. package/dist/core/extensions/builtin/goal/store.d.ts +7 -3
  68. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/goal/store.js +66 -181
  70. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
  72. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/goal/tool-registration.js +26 -15
  74. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  75. package/dist/core/extensions/builtin/goal/transitions.d.ts +3 -0
  76. package/dist/core/extensions/builtin/goal/transitions.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/goal/transitions.js +45 -0
  78. package/dist/core/extensions/builtin/goal/transitions.js.map +1 -0
  79. package/dist/core/extensions/builtin/goal/types.d.ts +10 -4
  80. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/goal/types.js +2 -2
  82. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  83. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  84. package/dist/core/extensions/builtin/goal/ui.js +2 -0
  85. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  86. package/dist/core/extensions/builtin/goal/validation.d.ts +8 -1
  87. package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/goal/validation.js +24 -12
  89. package/dist/core/extensions/builtin/goal/validation.js.map +1 -1
  90. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  91. package/dist/core/extensions/builtin/index.js +0 -2
  92. package/dist/core/extensions/builtin/index.js.map +1 -1
  93. package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
  94. package/dist/core/extensions/builtin/mcp/index.js +8 -5
  95. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  96. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/permission-system/parsers.js +1 -0
  98. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  99. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +48 -0
  100. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +88 -64
  102. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  104. package/dist/core/extensions/builtin/terminal/extension.js +32 -0
  105. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  106. package/dist/core/extensions/builtin/terminal/index.d.ts +1 -1
  107. package/dist/core/extensions/builtin/terminal/index.d.ts.map +1 -1
  108. package/dist/core/extensions/builtin/terminal/index.js +1 -1
  109. package/dist/core/extensions/builtin/terminal/index.js.map +1 -1
  110. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +29 -0
  111. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -0
  112. package/dist/core/extensions/builtin/terminal/monitor-notify.js +185 -0
  113. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -0
  114. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +35 -0
  115. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -0
  116. package/dist/core/extensions/builtin/terminal/monitor-registry.js +98 -0
  117. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -0
  118. package/dist/core/extensions/builtin/terminal/notify.d.ts +9 -0
  119. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  120. package/dist/core/extensions/builtin/terminal/notify.js +30 -14
  121. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  122. package/dist/core/extensions/builtin/terminal/prompt.d.ts +1 -1
  123. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  124. package/dist/core/extensions/builtin/terminal/prompt.js +13 -5
  125. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  126. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +3 -12
  127. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/terminal/runtime-session.js +4 -59
  129. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  130. package/dist/core/extensions/builtin/terminal/settings.d.ts +8 -0
  131. package/dist/core/extensions/builtin/terminal/settings.d.ts.map +1 -1
  132. package/dist/core/extensions/builtin/terminal/settings.js +16 -2
  133. package/dist/core/extensions/builtin/terminal/settings.js.map +1 -1
  134. package/dist/core/extensions/builtin/terminal/shared.d.ts +2 -2
  135. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  136. package/dist/core/extensions/builtin/terminal/shared.js +2 -1
  137. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  138. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +10 -4
  139. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +17 -96
  141. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  142. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -0
  143. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  144. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  145. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +41 -0
  146. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -0
  147. package/dist/core/extensions/builtin/terminal/tools/monitor.js +97 -0
  148. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -0
  149. package/dist/core/extensions/builtin/terminal/tools/render.d.ts +3 -0
  150. package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
  151. package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
  152. package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
  153. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts +19 -0
  154. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts.map +1 -0
  155. package/dist/core/extensions/builtin/todotools/fuzzy-match.js +70 -0
  156. package/dist/core/extensions/builtin/todotools/fuzzy-match.js.map +1 -0
  157. package/dist/core/extensions/builtin/todotools/normalize.d.ts +8 -0
  158. package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -0
  159. package/dist/core/extensions/builtin/todotools/normalize.js +174 -0
  160. package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -0
  161. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
  162. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  163. package/dist/core/extensions/builtin/todotools/prompt.js +4 -2
  164. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  165. package/dist/core/extensions/builtin/todotools/state.d.ts +9 -8
  166. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  167. package/dist/core/extensions/builtin/todotools/state.js +99 -48
  168. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  169. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +1 -1
  170. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  171. package/dist/core/extensions/builtin/todotools/tools/todo.js +65 -38
  172. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  173. package/dist/core/extensions/builtin/websearch/index.d.ts.map +1 -1
  174. package/dist/core/extensions/builtin/websearch/index.js +2 -4
  175. package/dist/core/extensions/builtin/websearch/index.js.map +1 -1
  176. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  177. package/dist/core/extensions/builtin/websearch/websearch/config.js +4 -1
  178. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  179. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
  180. package/dist/core/extensions/builtin/websearch/websearch/native.js +2 -4
  181. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
  182. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  183. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +20 -8
  184. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  185. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +6 -1
  186. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  187. package/dist/core/extensions/builtin/websearch/websearch/search.js +15 -11
  188. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  189. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
  190. package/dist/core/extensions/builtin/websearch/websearch/tool.js +5 -10
  191. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  192. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -0
  193. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  194. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  195. package/dist/core/extensions/loader.d.ts.map +1 -1
  196. package/dist/core/extensions/loader.js +12 -0
  197. package/dist/core/extensions/loader.js.map +1 -1
  198. package/dist/core/extensions/runner.d.ts +5 -0
  199. package/dist/core/extensions/runner.d.ts.map +1 -1
  200. package/dist/core/extensions/runner.js +12 -1
  201. package/dist/core/extensions/runner.js.map +1 -1
  202. package/dist/core/extensions/types.d.ts +25 -1
  203. package/dist/core/extensions/types.d.ts.map +1 -1
  204. package/dist/core/extensions/types.js.map +1 -1
  205. package/dist/core/keybindings.d.ts +0 -5
  206. package/dist/core/keybindings.d.ts.map +1 -1
  207. package/dist/core/keybindings.js +0 -2
  208. package/dist/core/keybindings.js.map +1 -1
  209. package/dist/core/messages.d.ts +32 -0
  210. package/dist/core/messages.d.ts.map +1 -1
  211. package/dist/core/messages.js +91 -0
  212. package/dist/core/messages.js.map +1 -1
  213. package/dist/core/model-resolver.d.ts +10 -1
  214. package/dist/core/model-resolver.d.ts.map +1 -1
  215. package/dist/core/model-resolver.js +13 -3
  216. package/dist/core/model-resolver.js.map +1 -1
  217. package/dist/core/model-runtime.d.ts +2 -0
  218. package/dist/core/model-runtime.d.ts.map +1 -1
  219. package/dist/core/model-runtime.js +4 -3
  220. package/dist/core/model-runtime.js.map +1 -1
  221. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  222. package/dist/core/remote-catalog-provider.js +19 -1
  223. package/dist/core/remote-catalog-provider.js.map +1 -1
  224. package/dist/core/resource-loader.d.ts +9 -0
  225. package/dist/core/resource-loader.d.ts.map +1 -1
  226. package/dist/core/resource-loader.js +13 -2
  227. package/dist/core/resource-loader.js.map +1 -1
  228. package/dist/core/retry-fallback/controller.d.ts +7 -0
  229. package/dist/core/retry-fallback/controller.d.ts.map +1 -1
  230. package/dist/core/retry-fallback/controller.js +13 -0
  231. package/dist/core/retry-fallback/controller.js.map +1 -1
  232. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
  233. package/dist/core/retry-fallback/cooldown.js +5 -0
  234. package/dist/core/retry-fallback/cooldown.js.map +1 -1
  235. package/dist/core/sdk.d.ts.map +1 -1
  236. package/dist/core/sdk.js +11 -35
  237. package/dist/core/sdk.js.map +1 -1
  238. package/dist/core/settings-manager.d.ts +12 -16
  239. package/dist/core/settings-manager.d.ts.map +1 -1
  240. package/dist/core/settings-manager.js +10 -13
  241. package/dist/core/settings-manager.js.map +1 -1
  242. package/dist/core/slash-commands.d.ts.map +1 -1
  243. package/dist/core/slash-commands.js +1 -0
  244. package/dist/core/slash-commands.js.map +1 -1
  245. package/dist/core/thinking-levels.d.ts.map +1 -1
  246. package/dist/core/thinking-levels.js +9 -2
  247. package/dist/core/thinking-levels.js.map +1 -1
  248. package/dist/core/timings.d.ts +7 -2
  249. package/dist/core/timings.d.ts.map +1 -1
  250. package/dist/core/timings.js +11 -0
  251. package/dist/core/timings.js.map +1 -1
  252. package/dist/extensions/llama/provider.d.ts.map +1 -1
  253. package/dist/extensions/llama/provider.js +6 -0
  254. package/dist/extensions/llama/provider.js.map +1 -1
  255. package/dist/inspector-policy.d.ts +22 -0
  256. package/dist/inspector-policy.d.ts.map +1 -0
  257. package/dist/inspector-policy.js +84 -0
  258. package/dist/inspector-policy.js.map +1 -0
  259. package/dist/main.d.ts +6 -0
  260. package/dist/main.d.ts.map +1 -1
  261. package/dist/main.js +20 -23
  262. package/dist/main.js.map +1 -1
  263. package/dist/modes/app-server/runtime.d.ts.map +1 -1
  264. package/dist/modes/app-server/runtime.js +1 -0
  265. package/dist/modes/app-server/runtime.js.map +1 -1
  266. package/dist/modes/app-server/threads/goal-handlers.js +4 -2
  267. package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
  268. package/dist/modes/app-server/threads/goal-wire.d.ts.map +1 -1
  269. package/dist/modes/app-server/threads/goal-wire.js +1 -0
  270. package/dist/modes/app-server/threads/goal-wire.js.map +1 -1
  271. package/dist/modes/app-server/threads/handlers.d.ts +1 -0
  272. package/dist/modes/app-server/threads/handlers.d.ts.map +1 -1
  273. package/dist/modes/app-server/threads/handlers.js +2 -0
  274. package/dist/modes/app-server/threads/handlers.js.map +1 -1
  275. package/dist/modes/app-server/threads/turn-runtime.d.ts +1 -0
  276. package/dist/modes/app-server/threads/turn-runtime.d.ts.map +1 -1
  277. package/dist/modes/app-server/threads/turn-runtime.js.map +1 -1
  278. package/dist/modes/app-server/threads/turns.d.ts.map +1 -1
  279. package/dist/modes/app-server/threads/turns.js +47 -3
  280. package/dist/modes/app-server/threads/turns.js.map +1 -1
  281. package/dist/modes/interactive/components/custom-message.d.ts +3 -1
  282. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/custom-message.js +9 -2
  284. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  285. package/dist/modes/interactive/components/status-indicator.d.ts +1 -0
  286. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  287. package/dist/modes/interactive/components/status-indicator.js +29 -4
  288. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  289. package/dist/modes/interactive/components/tool-execution.d.ts +5 -1
  290. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  291. package/dist/modes/interactive/components/tool-execution.js +43 -17
  292. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  293. package/dist/modes/interactive/grok/chrome-tokens.d.ts +22 -0
  294. package/dist/modes/interactive/grok/chrome-tokens.d.ts.map +1 -0
  295. package/dist/modes/interactive/grok/chrome-tokens.js +27 -0
  296. package/dist/modes/interactive/grok/chrome-tokens.js.map +1 -0
  297. package/dist/modes/interactive/grok/chrome.d.ts +51 -0
  298. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -0
  299. package/dist/modes/interactive/grok/chrome.js +105 -0
  300. package/dist/modes/interactive/grok/chrome.js.map +1 -0
  301. package/dist/modes/interactive/grok/footer.d.ts +14 -0
  302. package/dist/modes/interactive/grok/footer.d.ts.map +1 -0
  303. package/dist/modes/interactive/grok/footer.js +27 -0
  304. package/dist/modes/interactive/grok/footer.js.map +1 -0
  305. package/dist/modes/interactive/grok/input-card.d.ts +9 -0
  306. package/dist/modes/interactive/grok/input-card.d.ts.map +1 -0
  307. package/dist/modes/interactive/grok/input-card.js +30 -0
  308. package/dist/modes/interactive/grok/input-card.js.map +1 -0
  309. package/dist/modes/interactive/grok/palette.d.ts +145 -0
  310. package/dist/modes/interactive/grok/palette.d.ts.map +1 -0
  311. package/dist/modes/interactive/grok/palette.js +92 -0
  312. package/dist/modes/interactive/grok/palette.js.map +1 -0
  313. package/dist/modes/interactive/grok/tool-row.d.ts +17 -0
  314. package/dist/modes/interactive/grok/tool-row.d.ts.map +1 -0
  315. package/dist/modes/interactive/grok/tool-row.js +26 -0
  316. package/dist/modes/interactive/grok/tool-row.js.map +1 -0
  317. package/dist/modes/interactive/grok/welcome-card.d.ts +10 -0
  318. package/dist/modes/interactive/grok/welcome-card.d.ts.map +1 -0
  319. package/dist/modes/interactive/grok/welcome-card.js +30 -0
  320. package/dist/modes/interactive/grok/welcome-card.js.map +1 -0
  321. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  322. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  323. package/dist/modes/interactive/interactive-mode.js +117 -54
  324. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  325. package/dist/modes/interactive/theme/grok-day.json +77 -0
  326. package/dist/modes/interactive/theme/grok-night.json +93 -0
  327. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  328. package/dist/modes/interactive/theme/theme.js +4 -0
  329. package/dist/modes/interactive/theme/theme.js.map +1 -1
  330. package/dist/modes/rpc/connection-handler.d.ts +3 -3
  331. package/dist/modes/rpc/connection-handler.js +6 -6
  332. package/dist/modes/rpc/connection-handler.js.map +1 -1
  333. package/dist/modes/rpc/custom-capability.d.ts +6 -7
  334. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  335. package/dist/modes/rpc/custom-capability.js +6 -7
  336. package/dist/modes/rpc/custom-capability.js.map +1 -1
  337. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  338. package/dist/modes/rpc/rpc-mode.js +5 -5
  339. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  340. package/dist/package-manager-cli.d.ts.map +1 -1
  341. package/dist/package-manager-cli.js +11 -0
  342. package/dist/package-manager-cli.js.map +1 -1
  343. package/dist/senpi +2 -0
  344. package/docs/docs.json +4 -0
  345. package/docs/environment-variables.md +1 -0
  346. package/docs/extensions.md +2 -2
  347. package/docs/grok-neo.md +77 -0
  348. package/docs/keybindings.md +0 -1
  349. package/docs/settings.md +14 -3
  350. package/docs/terminal-tools.md +6 -3
  351. package/docs/usage.md +1 -1
  352. package/examples/extensions/message-renderer.ts +2 -2
  353. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +47 -0
  354. package/node_modules/@code-yeongyu/senpi-codemode/README.md +39 -19
  355. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  356. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +6 -1
  357. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +0 -1
  358. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-notifier.ts +40 -0
  359. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +46 -66
  360. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +5 -2
  361. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -0
  362. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +19 -4
  363. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +7 -0
  364. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +8 -5
  365. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +23 -5
  366. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +322 -0
  367. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +253 -18
  368. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +58 -0
  369. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +28 -6
  370. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +20 -0
  371. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +65 -22
  372. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  373. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +4 -41
  374. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  375. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +6 -0
  376. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  377. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +4 -0
  378. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  379. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +10 -0
  380. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -0
  381. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +38 -0
  382. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -0
  383. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
  384. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  385. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  386. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  387. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  388. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +210 -26
  389. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  390. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
  391. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +16 -8
  392. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  393. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +39 -20
  395. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  396. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts.map +1 -1
  397. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +9 -2
  398. package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
  399. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  400. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +4 -3
  401. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  402. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts.map +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +12 -2
  404. package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
  405. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +19 -11
  407. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  408. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +121 -23
  410. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  412. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +67 -31
  414. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  416. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +13 -8
  417. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  418. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js +1 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts +3 -2
  422. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.d.ts.map +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js +37 -35
  424. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js.map +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
  426. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +11 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
  428. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  429. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  430. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  431. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  432. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts +5 -0
  433. package/node_modules/@earendil-works/pi-ai/dist/models-store.d.ts.map +1 -1
  434. package/node_modules/@earendil-works/pi-ai/dist/models-store.js.map +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/models.js +5 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  446. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +9 -0
  447. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  448. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.d.ts.map +1 -1
  450. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js +8 -3
  451. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js.map +1 -1
  452. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  453. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +10 -0
  454. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  455. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +30 -0
  456. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -0
  457. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +70 -0
  458. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -0
  459. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +1 -1
  460. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -1
  461. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +7 -3
  462. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -1
  463. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts +9 -0
  464. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts.map +1 -0
  465. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js +16 -0
  466. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js.map +1 -0
  467. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  468. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  469. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +1 -0
  470. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  471. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +35 -3
  472. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  473. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -0
  474. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  475. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  476. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +32 -0
  477. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
  478. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +15 -7
  479. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
  480. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  481. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  482. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  483. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  484. package/package.json +8 -8
  485. package/dist/cli/neo/build-argv.d.ts +0 -19
  486. package/dist/cli/neo/build-argv.d.ts.map +0 -1
  487. package/dist/cli/neo/build-argv.js +0 -84
  488. package/dist/cli/neo/build-argv.js.map +0 -1
  489. package/dist/cli/neo/daemon-launch.d.ts +0 -25
  490. package/dist/cli/neo/daemon-launch.d.ts.map +0 -1
  491. package/dist/cli/neo/daemon-launch.js +0 -97
  492. package/dist/cli/neo/daemon-launch.js.map +0 -1
  493. package/dist/cli/neo/gate.d.ts +0 -15
  494. package/dist/cli/neo/gate.d.ts.map +0 -1
  495. package/dist/cli/neo/gate.js +0 -21
  496. package/dist/cli/neo/gate.js.map +0 -1
  497. package/dist/cli/neo/launch.d.ts +0 -24
  498. package/dist/cli/neo/launch.d.ts.map +0 -1
  499. package/dist/cli/neo/launch.js +0 -66
  500. package/dist/cli/neo/launch.js.map +0 -1
  501. package/dist/cli/neo/platform.d.ts +0 -38
  502. package/dist/cli/neo/platform.d.ts.map +0 -1
  503. package/dist/cli/neo/platform.js +0 -54
  504. package/dist/cli/neo/platform.js.map +0 -1
  505. package/dist/cli/neo/resolve-binary.d.ts +0 -39
  506. package/dist/cli/neo/resolve-binary.d.ts.map +0 -1
  507. package/dist/cli/neo/resolve-binary.js +0 -66
  508. package/dist/cli/neo/resolve-binary.js.map +0 -1
  509. package/dist/core/extensions/builtin/session-observer/index.d.ts +0 -5
  510. package/dist/core/extensions/builtin/session-observer/index.d.ts.map +0 -1
  511. package/dist/core/extensions/builtin/session-observer/index.js +0 -36
  512. package/dist/core/extensions/builtin/session-observer/index.js.map +0 -1
  513. package/dist/core/extensions/builtin/session-observer/loader.d.ts +0 -3
  514. package/dist/core/extensions/builtin/session-observer/loader.d.ts.map +0 -1
  515. package/dist/core/extensions/builtin/session-observer/loader.js +0 -20
  516. package/dist/core/extensions/builtin/session-observer/loader.js.map +0 -1
  517. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts +0 -7
  518. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts.map +0 -1
  519. package/dist/core/extensions/builtin/session-observer/overlay-format.js +0 -30
  520. package/dist/core/extensions/builtin/session-observer/overlay-format.js.map +0 -1
  521. package/dist/core/extensions/builtin/session-observer/overlay.d.ts +0 -51
  522. package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +0 -1
  523. package/dist/core/extensions/builtin/session-observer/overlay.js +0 -229
  524. package/dist/core/extensions/builtin/session-observer/overlay.js.map +0 -1
  525. package/dist/core/extensions/builtin/session-observer/scanner.d.ts +0 -10
  526. package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +0 -1
  527. package/dist/core/extensions/builtin/session-observer/scanner.js +0 -142
  528. package/dist/core/extensions/builtin/session-observer/scanner.js.map +0 -1
  529. package/dist/core/extensions/builtin/session-observer/text.d.ts +0 -7
  530. package/dist/core/extensions/builtin/session-observer/text.d.ts.map +0 -1
  531. package/dist/core/extensions/builtin/session-observer/text.js +0 -37
  532. package/dist/core/extensions/builtin/session-observer/text.js.map +0 -1
  533. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts +0 -7
  534. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts.map +0 -1
  535. package/dist/core/extensions/builtin/session-observer/transcript-entries.js +0 -71
  536. package/dist/core/extensions/builtin/session-observer/transcript-entries.js.map +0 -1
  537. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts +0 -11
  538. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts.map +0 -1
  539. package/dist/core/extensions/builtin/session-observer/transcript-format.js +0 -65
  540. package/dist/core/extensions/builtin/session-observer/transcript-format.js.map +0 -1
  541. package/dist/core/extensions/builtin/session-observer/transcript.d.ts +0 -4
  542. package/dist/core/extensions/builtin/session-observer/transcript.d.ts.map +0 -1
  543. package/dist/core/extensions/builtin/session-observer/transcript.js +0 -81
  544. package/dist/core/extensions/builtin/session-observer/transcript.js.map +0 -1
  545. package/dist/core/extensions/builtin/session-observer/types.d.ts +0 -33
  546. package/dist/core/extensions/builtin/session-observer/types.d.ts.map +0 -1
  547. package/dist/core/extensions/builtin/session-observer/types.js +0 -2
  548. package/dist/core/extensions/builtin/session-observer/types.js.map +0 -1
  549. package/dist/modes/rpc/neo-daemon-child-worker.d.ts +0 -29
  550. package/dist/modes/rpc/neo-daemon-child-worker.d.ts.map +0 -1
  551. package/dist/modes/rpc/neo-daemon-child-worker.js +0 -95
  552. package/dist/modes/rpc/neo-daemon-child-worker.js.map +0 -1
  553. package/dist/modes/rpc/neo-daemon-mode.d.ts +0 -110
  554. package/dist/modes/rpc/neo-daemon-mode.d.ts.map +0 -1
  555. package/dist/modes/rpc/neo-daemon-mode.js +0 -267
  556. package/dist/modes/rpc/neo-daemon-mode.js.map +0 -1
  557. package/dist/modes/rpc/neo-daemon-protocol.d.ts +0 -50
  558. package/dist/modes/rpc/neo-daemon-protocol.d.ts.map +0 -1
  559. package/dist/modes/rpc/neo-daemon-protocol.js +0 -66
  560. package/dist/modes/rpc/neo-daemon-protocol.js.map +0 -1
  561. package/dist/modes/rpc/neo-daemon-registry.d.ts +0 -98
  562. package/dist/modes/rpc/neo-daemon-registry.d.ts.map +0 -1
  563. package/dist/modes/rpc/neo-daemon-registry.js +0 -209
  564. package/dist/modes/rpc/neo-daemon-registry.js.map +0 -1
  565. package/dist/modes/rpc/neo-runtime-options-argv.d.ts +0 -17
  566. package/dist/modes/rpc/neo-runtime-options-argv.d.ts.map +0 -1
  567. package/dist/modes/rpc/neo-runtime-options-argv.js +0 -79
  568. package/dist/modes/rpc/neo-runtime-options-argv.js.map +0 -1
  569. package/dist/modes/rpc/neo-runtime-options.d.ts +0 -84
  570. package/dist/modes/rpc/neo-runtime-options.d.ts.map +0 -1
  571. package/dist/modes/rpc/neo-runtime-options.js +0 -92
  572. package/dist/modes/rpc/neo-runtime-options.js.map +0 -1
  573. package/docs/neo.md +0 -111
  574. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/runtime.ts +0 -258
  575. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/tools.ts +0 -106
@@ -1,9 +1,13 @@
1
- import type { Goal, GoalAccountingMode, GoalStoreRef, GoalUpdate, TokenUsageSnapshot } from "./types.ts";
2
- export declare function goalFilePath(ref: GoalStoreRef): string;
1
+ import type { Goal, GoalAccountingMode, GoalStoreRef, GoalUpdate, GoalUpdateSource, TokenUsageSnapshot } from "./types.ts";
2
+ export { goalFilePath } from "./persistence.ts";
3
+ export declare function goalHistoryFilePath(ref: GoalStoreRef): string;
4
+ export declare function objectiveFullTextFileName(ref: GoalStoreRef): string;
5
+ export declare function objectiveFullTextFilePath(ref: GoalStoreRef): string;
3
6
  export declare function readGoal(ref: GoalStoreRef): Promise<Goal | null>;
4
7
  export declare function writeGoal(ref: GoalStoreRef, goal: Goal | null): Promise<void>;
5
8
  export declare function createGoal(ref: GoalStoreRef, objective: string, tokenBudget?: number): Promise<Goal>;
6
- export declare function updateGoal(ref: GoalStoreRef, update: GoalUpdate): Promise<Goal>;
9
+ export declare function updateGoal(ref: GoalStoreRef, update: GoalUpdate, source?: GoalUpdateSource): Promise<Goal>;
10
+ export declare function archiveGoal(ref: GoalStoreRef, goal: Goal): Promise<void>;
7
11
  export declare function clearGoal(ref: GoalStoreRef): Promise<boolean>;
8
12
  export declare function accountGoalUsage(ref: GoalStoreRef, usage: TokenUsageSnapshot, elapsedSeconds: number, mode?: GoalAccountingMode, expectedGoalId?: string): Promise<Goal | null>;
9
13
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAY,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAYnH,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAEtD;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAStE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnF;AAoBD,wBAAsB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB1G;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDrF;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAInE;AAED,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,kBAAkB,EACzB,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,kBAA6B,EACnC,cAAc,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAetB"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACX,IAAI,EACJ,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAE7D;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAEnE;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAEnE;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAEtE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB1G;AAED,wBAAsB,UAAU,CAC/B,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,gBAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAQD,wBAAsB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAInE;AAED,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,kBAAkB,EACzB,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,kBAA6B,EACnC,cAAc,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAatB"}
@@ -1,57 +1,41 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
2
+ import { appendFile, mkdir, writeFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
- import { GoalAlreadyExistsError, GoalNotFoundError, InvalidGoalStoreError, UnsupportedGoalStoreVersionError, } from "./errors.js";
5
- import { isRecord } from "./types.js";
6
- import { isGoalStatus, isNonNegativeSafeInteger, resolveTokenBudget, validateObjective, validateTokenBudget, } from "./validation.js";
7
- const STORE_VERSION = 1;
8
- export function goalFilePath(ref) {
9
- return join(ref.baseDir, `${encodeURIComponent(ref.threadId)}.json`);
4
+ import { GoalAlreadyExistsError, GoalNotFoundError } from "./errors.js";
5
+ import { encodedThreadId, readGoalFile, writeGoalFile } from "./persistence.js";
6
+ import { transitionGoalStatus } from "./transitions.js";
7
+ import { resolveTokenBudget, validateObjective, validateTokenBudget } from "./validation.js";
8
+ export { goalFilePath } from "./persistence.js";
9
+ export function goalHistoryFilePath(ref) {
10
+ return join(ref.baseDir, `${encodedThreadId(ref)}.history.jsonl`);
11
+ }
12
+ export function objectiveFullTextFileName(ref) {
13
+ return `${encodedThreadId(ref)}.objective-full.txt`;
14
+ }
15
+ export function objectiveFullTextFilePath(ref) {
16
+ return join(ref.baseDir, objectiveFullTextFileName(ref));
10
17
  }
11
18
  export async function readGoal(ref) {
12
- const filePath = goalFilePath(ref);
13
- try {
14
- const raw = await readFile(filePath, "utf8");
15
- return parseGoalFile(raw).goal;
16
- }
17
- catch (error) {
18
- if (isMissingFile(error))
19
- return null;
20
- throw error;
21
- }
19
+ return readGoalFile(ref);
22
20
  }
23
21
  export async function writeGoal(ref, goal) {
24
- const filePath = goalFilePath(ref);
25
- await mkdir(dirname(filePath), { recursive: true });
26
- const file = { version: STORE_VERSION, goal };
27
- await writeGoalFileAtomic(filePath, `${JSON.stringify(file, null, 2)}\n`);
28
- }
29
- async function writeGoalFileAtomic(filePath, contents) {
30
- const tempPath = join(dirname(filePath), `.goal-${randomUUID()}.tmp`);
31
- try {
32
- await writeFile(tempPath, contents, { encoding: "utf8", mode: 0o600 });
33
- await rename(tempPath, filePath);
34
- }
35
- catch (error) {
36
- try {
37
- await rm(tempPath, { force: true });
38
- }
39
- catch (cleanupError) {
40
- throw new AggregateError([error, cleanupError], "goal store write failed and its temporary file could not be removed");
41
- }
42
- throw error;
43
- }
22
+ await writeGoalFile(ref, goal);
44
23
  }
45
24
  export async function createGoal(ref, objective, tokenBudget) {
46
- if ((await readGoal(ref)) !== null) {
25
+ const validatedObjective = validateObjective(objective, objectiveFullTextFileName(ref));
26
+ const current = await readGoal(ref);
27
+ if (current !== null && current.status !== "complete") {
47
28
  throw new GoalAlreadyExistsError("cannot create a new goal because this thread already has a goal");
48
29
  }
49
- const normalizedObjective = validateObjective(objective);
50
- const now = Math.trunc(Date.now() / 1000);
30
+ if (validatedObjective.truncated)
31
+ await writeFullObjectiveText(ref, objective);
32
+ if (current?.status === "complete")
33
+ await archiveGoal(ref, current);
34
+ const now = nowSeconds();
51
35
  const goal = {
52
36
  id: randomUUID(),
53
37
  threadId: ref.threadId,
54
- objective: normalizedObjective,
38
+ objective: validatedObjective.objective,
55
39
  status: "active",
56
40
  tokensUsed: 0,
57
41
  timeUsedSeconds: 0,
@@ -63,16 +47,21 @@ export async function createGoal(ref, objective, tokenBudget) {
63
47
  await writeGoal(ref, goal);
64
48
  return goal;
65
49
  }
66
- export async function updateGoal(ref, update) {
50
+ export async function updateGoal(ref, update, source = "model") {
67
51
  const current = await readGoal(ref);
68
52
  if (!current)
69
53
  throw new GoalNotFoundError("cannot update goal: no goal exists");
70
- const objective = update.objective === undefined ? current.objective : validateObjective(update.objective);
71
- const now = Math.trunc(Date.now() / 1000), tokenBudget = resolveTokenBudget(current.tokenBudget, update.tokenBudget);
72
- const hasObjectiveUpdate = update.objective !== undefined, replacesGoal = hasObjectiveUpdate && (objective !== current.objective || current.status === "complete");
54
+ const validatedObjective = update.objective === undefined ? undefined : validateObjective(update.objective, objectiveFullTextFileName(ref));
55
+ const objective = validatedObjective?.objective ?? current.objective;
56
+ const tokenBudget = resolveTokenBudget(current.tokenBudget, update.tokenBudget);
57
+ const now = nextUpdatedAt(current.updatedAt);
58
+ const hasObjectiveUpdate = update.objective !== undefined;
59
+ const replacesGoal = hasObjectiveUpdate && (objective !== current.objective || current.status === "complete");
73
60
  const requestedStatus = update.status ?? (hasObjectiveUpdate ? "active" : undefined);
74
61
  if (replacesGoal) {
75
62
  const status = requestedStatus ?? "active";
63
+ if (status === "blocked")
64
+ throw new Error("objective replacement cannot create a blocked goal");
76
65
  const next = {
77
66
  id: randomUUID(),
78
67
  threadId: ref.threadId,
@@ -88,32 +77,31 @@ export async function updateGoal(ref, update) {
88
77
  next.lastStartedAt = now;
89
78
  if (status === "complete")
90
79
  next.completedAt = now;
80
+ if (validatedObjective?.truncated)
81
+ await writeFullObjectiveText(ref, update.objective ?? "");
91
82
  await writeGoal(ref, next);
92
83
  return next;
93
84
  }
94
- const status = requestedStatus ?? current.status;
95
- const next = {
96
- ...current,
97
- objective,
98
- status,
99
- updatedAt: now,
100
- };
101
- Object.assign(next, tokenBudget === undefined ? { tokenBudget: undefined } : { tokenBudget });
102
- if (status === "active" && current.status !== "active") {
103
- next.lastStartedAt = now;
104
- }
105
- else if (status !== "active") {
106
- delete next.lastStartedAt;
107
- }
108
- if (status === "complete") {
109
- next.completedAt = current.completedAt ?? now;
110
- }
111
- else {
112
- delete next.completedAt;
113
- }
85
+ const next = transitionGoalStatus({ ...current, objective }, requestedStatus ?? current.status, source, update.reason, now);
86
+ if (tokenBudget === undefined)
87
+ delete next.tokenBudget;
88
+ else
89
+ next.tokenBudget = tokenBudget;
90
+ if (validatedObjective?.truncated)
91
+ await writeFullObjectiveText(ref, update.objective ?? "");
114
92
  await writeGoal(ref, next);
115
93
  return next;
116
94
  }
95
+ export async function archiveGoal(ref, goal) {
96
+ const filePath = goalHistoryFilePath(ref);
97
+ await mkdir(dirname(filePath), { recursive: true });
98
+ await appendFile(filePath, `${JSON.stringify(goal)}\n`, "utf8");
99
+ }
100
+ async function writeFullObjectiveText(ref, objective) {
101
+ const filePath = objectiveFullTextFilePath(ref);
102
+ await mkdir(dirname(filePath), { recursive: true });
103
+ await writeFile(filePath, objective, "utf8");
104
+ }
117
105
  export async function clearGoal(ref) {
118
106
  const hadGoal = (await readGoal(ref)) !== null;
119
107
  await writeGoal(ref, null);
@@ -121,132 +109,29 @@ export async function clearGoal(ref) {
121
109
  }
122
110
  export async function accountGoalUsage(ref, usage, elapsedSeconds, mode = "active", expectedGoalId) {
123
111
  const goal = await readGoal(ref);
124
- if (!goal)
112
+ if (!goal || (expectedGoalId !== undefined && goal.id !== expectedGoalId) || !canAccountGoalUsage(goal, mode)) {
125
113
  return goal;
126
- if (expectedGoalId !== undefined && goal.id !== expectedGoalId)
127
- return goal;
128
- if (!canAccountGoalUsage(goal, mode))
129
- return goal;
130
- const now = Math.trunc(Date.now() / 1000);
114
+ }
131
115
  const next = {
132
116
  ...goal,
133
- tokensUsed: goal.tokensUsed + goalTokenDeltaForUsage(usage),
117
+ tokensUsed: goal.tokensUsed + Math.max(0, usage.input) + Math.max(0, usage.output),
134
118
  timeUsedSeconds: goal.timeUsedSeconds + Math.max(0, Math.trunc(elapsedSeconds)),
135
- updatedAt: now,
119
+ updatedAt: nextUpdatedAt(goal.updatedAt),
136
120
  };
137
121
  await writeGoal(ref, next);
138
122
  return next;
139
123
  }
140
124
  function canAccountGoalUsage(goal, mode) {
141
- switch (mode) {
142
- case "active":
143
- return goal.status === "active";
144
- case "activeOrComplete":
145
- return goal.status === "active" || goal.status === "complete";
146
- }
147
- }
148
- function goalTokenDeltaForUsage(usage) {
149
- return Math.max(0, usage.input) + Math.max(0, usage.output);
150
- }
151
- function parseGoalFile(raw) {
152
- let parsed;
153
- try {
154
- parsed = JSON.parse(raw);
155
- }
156
- catch (error) {
157
- if (!(error instanceof SyntaxError))
158
- throw error;
159
- const recovered = recoverGoalFileWithStaleClosingBraces(raw);
160
- if (recovered === undefined)
161
- throw error;
162
- try {
163
- parsed = JSON.parse(recovered);
164
- }
165
- catch {
166
- throw error;
167
- }
168
- }
169
- if (!isRecord(parsed))
170
- throw new InvalidGoalStoreError("goal store must be a JSON object");
171
- if (parsed.version !== STORE_VERSION)
172
- throw new UnsupportedGoalStoreVersionError("unsupported goal store version");
173
- const goal = parsed.goal;
174
- if (goal !== null && !isGoal(goal))
175
- throw new InvalidGoalStoreError("goal store contains an invalid goal");
176
- return {
177
- version: STORE_VERSION,
178
- goal,
179
- };
180
- }
181
- function recoverGoalFileWithStaleClosingBraces(raw) {
182
- let rootStart = 0;
183
- while (rootStart < raw.length && /[\t\n\r ]/.test(raw[rootStart] ?? ""))
184
- rootStart += 1;
185
- if (raw[rootStart] !== "{")
186
- return undefined;
187
- let depth = 0;
188
- let inString = false;
189
- let escaped = false;
190
- for (let index = rootStart; index < raw.length; index += 1) {
191
- const character = raw[index];
192
- if (inString) {
193
- if (escaped) {
194
- escaped = false;
195
- }
196
- else if (character === "\\") {
197
- escaped = true;
198
- }
199
- else if (character === '"') {
200
- inString = false;
201
- }
202
- continue;
203
- }
204
- if (character === '"') {
205
- inString = true;
206
- }
207
- else if (character === "{" || character === "[") {
208
- depth += 1;
209
- }
210
- else if (character === "}" || character === "]") {
211
- depth -= 1;
212
- if (depth < 0)
213
- return undefined;
214
- if (depth === 0) {
215
- let hasStaleClosingBrace = false;
216
- for (let suffixIndex = index + 1; suffixIndex < raw.length; suffixIndex += 1) {
217
- const suffixCharacter = raw[suffixIndex];
218
- if (suffixCharacter === "}") {
219
- hasStaleClosingBrace = true;
220
- }
221
- else if (suffixCharacter !== " " &&
222
- suffixCharacter !== "\t" &&
223
- suffixCharacter !== "\n" &&
224
- suffixCharacter !== "\r") {
225
- return undefined;
226
- }
227
- }
228
- return hasStaleClosingBrace ? raw.slice(0, index + 1) : undefined;
229
- }
230
- }
231
- }
232
- return undefined;
125
+ if (mode === "active")
126
+ return goal.status === "active";
127
+ if (mode === "activeOrBlocked")
128
+ return goal.status === "active" || goal.status === "blocked";
129
+ return goal.status === "active" || goal.status === "complete";
233
130
  }
234
- function isMissingFile(error) {
235
- return error instanceof Error && "code" in error && error.code === "ENOENT";
131
+ function nextUpdatedAt(previousUpdatedAt) {
132
+ return Math.max(nowSeconds(), previousUpdatedAt + 1);
236
133
  }
237
- function isGoal(value) {
238
- if (!isRecord(value))
239
- return false;
240
- return (typeof value.id === "string" &&
241
- typeof value.threadId === "string" &&
242
- typeof value.objective === "string" &&
243
- isGoalStatus(value.status) &&
244
- (value.tokenBudget === undefined || isNonNegativeSafeInteger(value.tokenBudget)) &&
245
- isNonNegativeSafeInteger(value.tokensUsed) &&
246
- isNonNegativeSafeInteger(value.timeUsedSeconds) &&
247
- isNonNegativeSafeInteger(value.createdAt) &&
248
- isNonNegativeSafeInteger(value.updatedAt) &&
249
- (value.lastStartedAt === undefined || isNonNegativeSafeInteger(value.lastStartedAt)) &&
250
- (value.completedAt === undefined || isNonNegativeSafeInteger(value.completedAt)));
134
+ function nowSeconds() {
135
+ return Math.trunc(Date.now() / 1000);
251
136
  }
252
137
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport {\n\tGoalAlreadyExistsError,\n\tGoalNotFoundError,\n\tInvalidGoalStoreError,\n\tUnsupportedGoalStoreVersionError,\n} from \"./errors.ts\";\nimport type { Goal, GoalAccountingMode, GoalFile, GoalStoreRef, GoalUpdate, TokenUsageSnapshot } from \"./types.ts\";\nimport { isRecord } from \"./types.ts\";\nimport {\n\tisGoalStatus,\n\tisNonNegativeSafeInteger,\n\tresolveTokenBudget,\n\tvalidateObjective,\n\tvalidateTokenBudget,\n} from \"./validation.ts\";\n\nconst STORE_VERSION = 1;\n\nexport function goalFilePath(ref: GoalStoreRef): string {\n\treturn join(ref.baseDir, `${encodeURIComponent(ref.threadId)}.json`);\n}\n\nexport async function readGoal(ref: GoalStoreRef): Promise<Goal | null> {\n\tconst filePath = goalFilePath(ref);\n\ttry {\n\t\tconst raw = await readFile(filePath, \"utf8\");\n\t\treturn parseGoalFile(raw).goal;\n\t} catch (error) {\n\t\tif (isMissingFile(error)) return null;\n\t\tthrow error;\n\t}\n}\n\nexport async function writeGoal(ref: GoalStoreRef, goal: Goal | null): Promise<void> {\n\tconst filePath = goalFilePath(ref);\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tconst file: GoalFile = { version: STORE_VERSION, goal };\n\tawait writeGoalFileAtomic(filePath, `${JSON.stringify(file, null, 2)}\\n`);\n}\n\nasync function writeGoalFileAtomic(filePath: string, contents: string): Promise<void> {\n\tconst tempPath = join(dirname(filePath), `.goal-${randomUUID()}.tmp`);\n\ttry {\n\t\tawait writeFile(tempPath, contents, { encoding: \"utf8\", mode: 0o600 });\n\t\tawait rename(tempPath, filePath);\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait rm(tempPath, { force: true });\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError(\n\t\t\t\t[error, cleanupError],\n\t\t\t\t\"goal store write failed and its temporary file could not be removed\",\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport async function createGoal(ref: GoalStoreRef, objective: string, tokenBudget?: number): Promise<Goal> {\n\tif ((await readGoal(ref)) !== null) {\n\t\tthrow new GoalAlreadyExistsError(\"cannot create a new goal because this thread already has a goal\");\n\t}\n\n\tconst normalizedObjective = validateObjective(objective);\n\tconst now = Math.trunc(Date.now() / 1000);\n\tconst goal: Goal = {\n\t\tid: randomUUID(),\n\t\tthreadId: ref.threadId,\n\t\tobjective: normalizedObjective,\n\t\tstatus: \"active\",\n\t\ttokensUsed: 0,\n\t\ttimeUsedSeconds: 0,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\tlastStartedAt: now,\n\t\t...(tokenBudget === undefined ? {} : { tokenBudget: validateTokenBudget(tokenBudget) }),\n\t};\n\tawait writeGoal(ref, goal);\n\treturn goal;\n}\n\nexport async function updateGoal(ref: GoalStoreRef, update: GoalUpdate): Promise<Goal> {\n\tconst current = await readGoal(ref);\n\tif (!current) throw new GoalNotFoundError(\"cannot update goal: no goal exists\");\n\n\tconst objective = update.objective === undefined ? current.objective : validateObjective(update.objective);\n\tconst now = Math.trunc(Date.now() / 1000),\n\t\ttokenBudget = resolveTokenBudget(current.tokenBudget, update.tokenBudget);\n\tconst hasObjectiveUpdate = update.objective !== undefined,\n\t\treplacesGoal = hasObjectiveUpdate && (objective !== current.objective || current.status === \"complete\");\n\tconst requestedStatus = update.status ?? (hasObjectiveUpdate ? \"active\" : undefined);\n\n\tif (replacesGoal) {\n\t\tconst status = requestedStatus ?? \"active\";\n\t\tconst next: Goal = {\n\t\t\tid: randomUUID(),\n\t\t\tthreadId: ref.threadId,\n\t\t\tobjective,\n\t\t\tstatus,\n\t\t\ttokensUsed: 0,\n\t\t\ttimeUsedSeconds: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t\t...(tokenBudget === undefined ? {} : { tokenBudget }),\n\t\t};\n\t\tif (status === \"active\") next.lastStartedAt = now;\n\t\tif (status === \"complete\") next.completedAt = now;\n\t\tawait writeGoal(ref, next);\n\t\treturn next;\n\t}\n\n\tconst status = requestedStatus ?? current.status;\n\tconst next: Goal = {\n\t\t...current,\n\t\tobjective,\n\t\tstatus,\n\t\tupdatedAt: now,\n\t};\n\tObject.assign(next, tokenBudget === undefined ? { tokenBudget: undefined } : { tokenBudget });\n\n\tif (status === \"active\" && current.status !== \"active\") {\n\t\tnext.lastStartedAt = now;\n\t} else if (status !== \"active\") {\n\t\tdelete next.lastStartedAt;\n\t}\n\n\tif (status === \"complete\") {\n\t\tnext.completedAt = current.completedAt ?? now;\n\t} else {\n\t\tdelete next.completedAt;\n\t}\n\n\tawait writeGoal(ref, next);\n\treturn next;\n}\n\nexport async function clearGoal(ref: GoalStoreRef): Promise<boolean> {\n\tconst hadGoal = (await readGoal(ref)) !== null;\n\tawait writeGoal(ref, null);\n\treturn hadGoal;\n}\n\nexport async function accountGoalUsage(\n\tref: GoalStoreRef,\n\tusage: TokenUsageSnapshot,\n\telapsedSeconds: number,\n\tmode: GoalAccountingMode = \"active\",\n\texpectedGoalId?: string,\n): Promise<Goal | null> {\n\tconst goal = await readGoal(ref);\n\tif (!goal) return goal;\n\tif (expectedGoalId !== undefined && goal.id !== expectedGoalId) return goal;\n\tif (!canAccountGoalUsage(goal, mode)) return goal;\n\n\tconst now = Math.trunc(Date.now() / 1000);\n\tconst next: Goal = {\n\t\t...goal,\n\t\ttokensUsed: goal.tokensUsed + goalTokenDeltaForUsage(usage),\n\t\ttimeUsedSeconds: goal.timeUsedSeconds + Math.max(0, Math.trunc(elapsedSeconds)),\n\t\tupdatedAt: now,\n\t};\n\tawait writeGoal(ref, next);\n\treturn next;\n}\n\nfunction canAccountGoalUsage(goal: Goal, mode: GoalAccountingMode): boolean {\n\tswitch (mode) {\n\t\tcase \"active\":\n\t\t\treturn goal.status === \"active\";\n\t\tcase \"activeOrComplete\":\n\t\t\treturn goal.status === \"active\" || goal.status === \"complete\";\n\t}\n}\n\nfunction goalTokenDeltaForUsage(usage: TokenUsageSnapshot): number {\n\treturn Math.max(0, usage.input) + Math.max(0, usage.output);\n}\n\nfunction parseGoalFile(raw: string): GoalFile {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (error) {\n\t\tif (!(error instanceof SyntaxError)) throw error;\n\t\tconst recovered = recoverGoalFileWithStaleClosingBraces(raw);\n\t\tif (recovered === undefined) throw error;\n\t\ttry {\n\t\t\tparsed = JSON.parse(recovered);\n\t\t} catch {\n\t\t\tthrow error;\n\t\t}\n\t}\n\tif (!isRecord(parsed)) throw new InvalidGoalStoreError(\"goal store must be a JSON object\");\n\tif (parsed.version !== STORE_VERSION) throw new UnsupportedGoalStoreVersionError(\"unsupported goal store version\");\n\tconst goal = parsed.goal;\n\tif (goal !== null && !isGoal(goal)) throw new InvalidGoalStoreError(\"goal store contains an invalid goal\");\n\treturn {\n\t\tversion: STORE_VERSION,\n\t\tgoal,\n\t};\n}\n\nfunction recoverGoalFileWithStaleClosingBraces(raw: string): string | undefined {\n\tlet rootStart = 0;\n\twhile (rootStart < raw.length && /[\\t\\n\\r ]/.test(raw[rootStart] ?? \"\")) rootStart += 1;\n\tif (raw[rootStart] !== \"{\") return undefined;\n\n\tlet depth = 0;\n\tlet inString = false;\n\tlet escaped = false;\n\tfor (let index = rootStart; index < raw.length; index += 1) {\n\t\tconst character = raw[index];\n\t\tif (inString) {\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t} else if (character === \"\\\\\") {\n\t\t\t\tescaped = true;\n\t\t\t} else if (character === '\"') {\n\t\t\t\tinString = false;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (character === '\"') {\n\t\t\tinString = true;\n\t\t} else if (character === \"{\" || character === \"[\") {\n\t\t\tdepth += 1;\n\t\t} else if (character === \"}\" || character === \"]\") {\n\t\t\tdepth -= 1;\n\t\t\tif (depth < 0) return undefined;\n\t\t\tif (depth === 0) {\n\t\t\t\tlet hasStaleClosingBrace = false;\n\t\t\t\tfor (let suffixIndex = index + 1; suffixIndex < raw.length; suffixIndex += 1) {\n\t\t\t\t\tconst suffixCharacter = raw[suffixIndex];\n\t\t\t\t\tif (suffixCharacter === \"}\") {\n\t\t\t\t\t\thasStaleClosingBrace = true;\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tsuffixCharacter !== \" \" &&\n\t\t\t\t\t\tsuffixCharacter !== \"\\t\" &&\n\t\t\t\t\t\tsuffixCharacter !== \"\\n\" &&\n\t\t\t\t\t\tsuffixCharacter !== \"\\r\"\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn hasStaleClosingBrace ? raw.slice(0, index + 1) : undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction isMissingFile(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && (error as { code: unknown }).code === \"ENOENT\";\n}\n\nfunction isGoal(value: unknown): value is Goal {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.threadId === \"string\" &&\n\t\ttypeof value.objective === \"string\" &&\n\t\tisGoalStatus(value.status) &&\n\t\t(value.tokenBudget === undefined || isNonNegativeSafeInteger(value.tokenBudget)) &&\n\t\tisNonNegativeSafeInteger(value.tokensUsed) &&\n\t\tisNonNegativeSafeInteger(value.timeUsedSeconds) &&\n\t\tisNonNegativeSafeInteger(value.createdAt) &&\n\t\tisNonNegativeSafeInteger(value.updatedAt) &&\n\t\t(value.lastStartedAt === undefined || isNonNegativeSafeInteger(value.lastStartedAt)) &&\n\t\t(value.completedAt === undefined || isNonNegativeSafeInteger(value.completedAt))\n\t);\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { GoalAlreadyExistsError, GoalNotFoundError } from \"./errors.ts\";\nimport { encodedThreadId, readGoalFile, writeGoalFile } from \"./persistence.ts\";\nimport { transitionGoalStatus } from \"./transitions.ts\";\nimport type {\n\tGoal,\n\tGoalAccountingMode,\n\tGoalStoreRef,\n\tGoalUpdate,\n\tGoalUpdateSource,\n\tTokenUsageSnapshot,\n} from \"./types.ts\";\nimport { resolveTokenBudget, validateObjective, validateTokenBudget } from \"./validation.ts\";\n\nexport { goalFilePath } from \"./persistence.ts\";\n\nexport function goalHistoryFilePath(ref: GoalStoreRef): string {\n\treturn join(ref.baseDir, `${encodedThreadId(ref)}.history.jsonl`);\n}\n\nexport function objectiveFullTextFileName(ref: GoalStoreRef): string {\n\treturn `${encodedThreadId(ref)}.objective-full.txt`;\n}\n\nexport function objectiveFullTextFilePath(ref: GoalStoreRef): string {\n\treturn join(ref.baseDir, objectiveFullTextFileName(ref));\n}\n\nexport async function readGoal(ref: GoalStoreRef): Promise<Goal | null> {\n\treturn readGoalFile(ref);\n}\n\nexport async function writeGoal(ref: GoalStoreRef, goal: Goal | null): Promise<void> {\n\tawait writeGoalFile(ref, goal);\n}\n\nexport async function createGoal(ref: GoalStoreRef, objective: string, tokenBudget?: number): Promise<Goal> {\n\tconst validatedObjective = validateObjective(objective, objectiveFullTextFileName(ref));\n\tconst current = await readGoal(ref);\n\tif (current !== null && current.status !== \"complete\") {\n\t\tthrow new GoalAlreadyExistsError(\"cannot create a new goal because this thread already has a goal\");\n\t}\n\tif (validatedObjective.truncated) await writeFullObjectiveText(ref, objective);\n\tif (current?.status === \"complete\") await archiveGoal(ref, current);\n\tconst now = nowSeconds();\n\tconst goal: Goal = {\n\t\tid: randomUUID(),\n\t\tthreadId: ref.threadId,\n\t\tobjective: validatedObjective.objective,\n\t\tstatus: \"active\",\n\t\ttokensUsed: 0,\n\t\ttimeUsedSeconds: 0,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\tlastStartedAt: now,\n\t\t...(tokenBudget === undefined ? {} : { tokenBudget: validateTokenBudget(tokenBudget) }),\n\t};\n\tawait writeGoal(ref, goal);\n\treturn goal;\n}\n\nexport async function updateGoal(\n\tref: GoalStoreRef,\n\tupdate: GoalUpdate,\n\tsource: GoalUpdateSource = \"model\",\n): Promise<Goal> {\n\tconst current = await readGoal(ref);\n\tif (!current) throw new GoalNotFoundError(\"cannot update goal: no goal exists\");\n\n\tconst validatedObjective =\n\t\tupdate.objective === undefined ? undefined : validateObjective(update.objective, objectiveFullTextFileName(ref));\n\tconst objective = validatedObjective?.objective ?? current.objective;\n\tconst tokenBudget = resolveTokenBudget(current.tokenBudget, update.tokenBudget);\n\tconst now = nextUpdatedAt(current.updatedAt);\n\tconst hasObjectiveUpdate = update.objective !== undefined;\n\tconst replacesGoal = hasObjectiveUpdate && (objective !== current.objective || current.status === \"complete\");\n\tconst requestedStatus = update.status ?? (hasObjectiveUpdate ? \"active\" : undefined);\n\n\tif (replacesGoal) {\n\t\tconst status = requestedStatus ?? \"active\";\n\t\tif (status === \"blocked\") throw new Error(\"objective replacement cannot create a blocked goal\");\n\t\tconst next: Goal = {\n\t\t\tid: randomUUID(),\n\t\t\tthreadId: ref.threadId,\n\t\t\tobjective,\n\t\t\tstatus,\n\t\t\ttokensUsed: 0,\n\t\t\ttimeUsedSeconds: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t\t...(tokenBudget === undefined ? {} : { tokenBudget }),\n\t\t};\n\t\tif (status === \"active\") next.lastStartedAt = now;\n\t\tif (status === \"complete\") next.completedAt = now;\n\t\tif (validatedObjective?.truncated) await writeFullObjectiveText(ref, update.objective ?? \"\");\n\t\tawait writeGoal(ref, next);\n\t\treturn next;\n\t}\n\n\tconst next = transitionGoalStatus(\n\t\t{ ...current, objective },\n\t\trequestedStatus ?? current.status,\n\t\tsource,\n\t\tupdate.reason,\n\t\tnow,\n\t);\n\tif (tokenBudget === undefined) delete next.tokenBudget;\n\telse next.tokenBudget = tokenBudget;\n\tif (validatedObjective?.truncated) await writeFullObjectiveText(ref, update.objective ?? \"\");\n\tawait writeGoal(ref, next);\n\treturn next;\n}\n\nexport async function archiveGoal(ref: GoalStoreRef, goal: Goal): Promise<void> {\n\tconst filePath = goalHistoryFilePath(ref);\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tawait appendFile(filePath, `${JSON.stringify(goal)}\\n`, \"utf8\");\n}\n\nasync function writeFullObjectiveText(ref: GoalStoreRef, objective: string): Promise<void> {\n\tconst filePath = objectiveFullTextFilePath(ref);\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tawait writeFile(filePath, objective, \"utf8\");\n}\n\nexport async function clearGoal(ref: GoalStoreRef): Promise<boolean> {\n\tconst hadGoal = (await readGoal(ref)) !== null;\n\tawait writeGoal(ref, null);\n\treturn hadGoal;\n}\n\nexport async function accountGoalUsage(\n\tref: GoalStoreRef,\n\tusage: TokenUsageSnapshot,\n\telapsedSeconds: number,\n\tmode: GoalAccountingMode = \"active\",\n\texpectedGoalId?: string,\n): Promise<Goal | null> {\n\tconst goal = await readGoal(ref);\n\tif (!goal || (expectedGoalId !== undefined && goal.id !== expectedGoalId) || !canAccountGoalUsage(goal, mode)) {\n\t\treturn goal;\n\t}\n\tconst next: Goal = {\n\t\t...goal,\n\t\ttokensUsed: goal.tokensUsed + Math.max(0, usage.input) + Math.max(0, usage.output),\n\t\ttimeUsedSeconds: goal.timeUsedSeconds + Math.max(0, Math.trunc(elapsedSeconds)),\n\t\tupdatedAt: nextUpdatedAt(goal.updatedAt),\n\t};\n\tawait writeGoal(ref, next);\n\treturn next;\n}\n\nfunction canAccountGoalUsage(goal: Goal, mode: GoalAccountingMode): boolean {\n\tif (mode === \"active\") return goal.status === \"active\";\n\tif (mode === \"activeOrBlocked\") return goal.status === \"active\" || goal.status === \"blocked\";\n\treturn goal.status === \"active\" || goal.status === \"complete\";\n}\n\nfunction nextUpdatedAt(previousUpdatedAt: number): number {\n\treturn Math.max(nowSeconds(), previousUpdatedAt + 1);\n}\n\nfunction nowSeconds(): number {\n\treturn Math.trunc(Date.now() / 1000);\n}\n"]}
@@ -4,6 +4,7 @@ export type GoalToolRegistrationDeps = {
4
4
  readonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;
5
5
  readonly accountCurrentAgentTurn: (ctx: ExtensionContext, mode: GoalAccountingMode) => Promise<Goal | null>;
6
6
  readonly beginAgentGoalAccounting: (goal: Goal) => void;
7
+ readonly markGoalBlockedThisTurn: (goal: Goal) => void;
7
8
  readonly markGoalCompletedThisTurn: (goal: Goal) => void;
8
9
  readonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal | null) => void;
9
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/tool-registration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtF,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKzE,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,YAAY,CAAC;IAC/D,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5G,QAAQ,CAAC,wBAAwB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,yBAAyB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3E,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,wBAAwB,GAAG,IAAI,CAuExF"}
1
+ {"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/tool-registration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtF,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAMzE,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,YAAY,CAAC;IAC/D,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5G,QAAQ,CAAC,wBAAwB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,yBAAyB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3E,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,wBAAwB,GAAG,IAAI,CAuFxF"}
@@ -1,44 +1,55 @@
1
1
  import { Type } from "typebox";
2
2
  import { formatGoalToolResponse } from "./format.js";
3
- import { createGoal, readGoal, updateGoal } from "./store.js";
4
- import { COMPLETABLE_GOAL_STATUS_VALUES } from "./types.js";
3
+ import { createGoal, objectiveFullTextFileName, readGoal, updateGoal } from "./store.js";
4
+ import { MODEL_SETTABLE_GOAL_STATUS_VALUES } from "./types.js";
5
+ import { objectiveTruncationNotice, validateObjective } from "./validation.js";
5
6
  export function registerGoalTools(pi, deps) {
6
7
  pi.registerTool({
7
8
  name: "create_goal",
8
9
  label: "Create Goal",
9
- description: "Create a goal only when explicitly requested by the user or system/developer instructions; do not infer goals from ordinary tasks.\nFails if a goal already exists; use update_goal only for status.",
10
+ description: "Create a goal only when explicitly requested by the user or system/developer instructions; do not infer goals from ordinary tasks.\nObjectives are limited to 4,000 characters. For longer instructions, put the full objective in a file and refer to that file.\nReplaces the current goal when it is complete and archives it; fails if an unfinished goal exists.",
10
11
  parameters: Type.Object({
11
12
  objective: Type.String({
12
- description: "Required. The concrete objective to start pursuing. This starts a new active goal only when no goal is currently defined; if a goal already exists, this tool fails.",
13
+ description: "Required. The concrete objective to start pursuing. Limit: 4,000 characters. For longer instructions, put the full objective in a file and refer to that file.",
13
14
  }),
14
15
  }, { additionalProperties: false }),
15
16
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
16
17
  const ref = deps.goalStoreRef(ctx);
17
- if ((await readGoal(ref)) !== null) {
18
- throw new Error("cannot create a new goal because this thread already has a goal; use update_goal only when the existing goal is complete");
18
+ const current = await readGoal(ref);
19
+ if (current !== null && current.status !== "complete") {
20
+ throw new Error("cannot create a new goal because this thread already has an unfinished goal; use update_goal only when the existing goal is complete");
19
21
  }
22
+ const validatedObjective = validateObjective(params.objective, objectiveFullTextFileName(ref));
20
23
  const goal = await createGoal(ref, params.objective);
21
24
  deps.beginAgentGoalAccounting(goal);
22
25
  deps.refreshGoalUi(ctx, goal);
23
- return toolText(formatGoalToolResponse(goal));
26
+ return toolText(formatGoalToolResponse(goal, validatedObjective.truncated ? objectiveTruncationNotice(objectiveFullTextFileName(ref)) : undefined));
24
27
  },
25
28
  });
26
29
  pi.registerTool({
27
30
  name: "update_goal",
28
31
  label: "Update Goal",
29
- description: "Update the existing goal.\nUse this tool only to mark the goal achieved.\nSet status to `complete` only when the objective has actually been achieved and no required work remains.\nDo not mark a goal complete merely because you are stopping work.\nYou cannot use this tool to pause or resume a goal; those status changes are controlled by the user or system.\nWhen marking the goal achieved with status `complete`, report the final elapsed time and token usage from the tool result to the user.",
32
+ description: "Update the existing goal.\nSet status to `complete` only when the objective has actually been achieved and no required work remains. Do not mark a goal complete merely because you are stopping work.\nSet status to `blocked` only after the same blocking condition recurs for at least 3 consecutive goal turns. After resuming, begin a fresh blocked audit after resume. Never mark a goal blocked merely because the work is hard, slow, or uncertain.\nA non-empty reason is required when blocking; reason must not be provided when completing.\nYou cannot use this tool to pause or resume a goal; those status changes are controlled by the user or system.\nWhen marking the goal achieved with status `complete`, report the final elapsed time and token usage from the tool result to the user.",
30
33
  parameters: Type.Object({
31
- status: Type.Union(COMPLETABLE_GOAL_STATUS_VALUES.map((status) => Type.Literal(status)), {
32
- description: "Required. Set to complete only when the objective is achieved and no required work remains.",
33
- }),
34
+ status: Type.Union(MODEL_SETTABLE_GOAL_STATUS_VALUES.map((status) => Type.Literal(status)), { description: "Required. Set to complete when achieved or blocked with a non-empty reason." }),
35
+ reason: Type.Optional(Type.String({
36
+ description: "Required and non-empty when status is blocked; rejected when status is complete.",
37
+ })),
34
38
  }, { additionalProperties: false }),
35
39
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
36
- if (params.status !== "complete") {
37
- throw new Error("update_goal can only mark the existing goal complete; pause and resume are controlled by the user or system");
40
+ const reason = params.reason?.trim();
41
+ if (params.status === "blocked" && (reason === undefined || reason.length === 0)) {
42
+ throw new Error("reason is required when status is blocked");
43
+ }
44
+ if (params.status === "complete" && params.reason !== undefined) {
45
+ throw new Error("reason must not be provided when status is complete");
38
46
  }
39
47
  await deps.accountCurrentAgentTurn(ctx, "active");
40
- const goal = await updateGoal(deps.goalStoreRef(ctx), { status: "complete" });
41
- deps.markGoalCompletedThisTurn(goal);
48
+ const goal = await updateGoal(deps.goalStoreRef(ctx), params.status === "blocked" ? { status: "blocked", reason } : { status: "complete" }, "model");
49
+ if (goal.status === "blocked")
50
+ deps.markGoalBlockedThisTurn(goal);
51
+ else
52
+ deps.markGoalCompletedThisTurn(goal);
42
53
  deps.refreshGoalUi(ctx, goal);
43
54
  return toolText(formatGoalToolResponse(goal));
44
55
  },
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registration.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/tool-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"typebox\";\nimport type { AgentToolResult, ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { formatGoalToolResponse } from \"./format.ts\";\nimport { createGoal, readGoal, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\nimport { COMPLETABLE_GOAL_STATUS_VALUES } from \"./types.ts\";\n\ntype GoalToolResult = AgentToolResult<Record<string, never>>;\n\nexport type GoalToolRegistrationDeps = {\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly accountCurrentAgentTurn: (ctx: ExtensionContext, mode: GoalAccountingMode) => Promise<Goal | null>;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly markGoalCompletedThisTurn: (goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal | null) => void;\n};\n\nexport function registerGoalTools(pi: ExtensionAPI, deps: GoalToolRegistrationDeps): void {\n\tpi.registerTool({\n\t\tname: \"create_goal\",\n\t\tlabel: \"Create Goal\",\n\t\tdescription:\n\t\t\t\"Create a goal only when explicitly requested by the user or system/developer instructions; do not infer goals from ordinary tasks.\\nFails if a goal already exists; use update_goal only for status.\",\n\t\tparameters: Type.Object(\n\t\t\t{\n\t\t\t\tobjective: Type.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Required. The concrete objective to start pursuing. This starts a new active goal only when no goal is currently defined; if a goal already exists, this tool fails.\",\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{ additionalProperties: false },\n\t\t),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst ref = deps.goalStoreRef(ctx);\n\t\t\tif ((await readGoal(ref)) !== null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because this thread already has a goal; use update_goal only when the existing goal is complete\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst goal = await createGoal(ref, params.objective);\n\t\t\tdeps.beginAgentGoalAccounting(goal);\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(formatGoalToolResponse(goal));\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\tname: \"update_goal\",\n\t\tlabel: \"Update Goal\",\n\t\tdescription:\n\t\t\t\"Update the existing goal.\\nUse this tool only to mark the goal achieved.\\nSet status to `complete` only when the objective has actually been achieved and no required work remains.\\nDo not mark a goal complete merely because you are stopping work.\\nYou cannot use this tool to pause or resume a goal; those status changes are controlled by the user or system.\\nWhen marking the goal achieved with status `complete`, report the final elapsed time and token usage from the tool result to the user.\",\n\t\tparameters: Type.Object(\n\t\t\t{\n\t\t\t\tstatus: Type.Union(\n\t\t\t\t\tCOMPLETABLE_GOAL_STATUS_VALUES.map((status) => Type.Literal(status)),\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Required. Set to complete only when the objective is achieved and no required work remains.\",\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t\t{ additionalProperties: false },\n\t\t),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tif (params.status !== \"complete\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"update_goal can only mark the existing goal complete; pause and resume are controlled by the user or system\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\tconst goal = await updateGoal(deps.goalStoreRef(ctx), { status: \"complete\" });\n\t\t\tdeps.markGoalCompletedThisTurn(goal);\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(formatGoalToolResponse(goal));\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\tname: \"get_goal\",\n\t\tlabel: \"Get Goal\",\n\t\tdescription: \"Get the current goal for this thread, including status, token and elapsed-time usage.\",\n\t\tparameters: Type.Object({}, { additionalProperties: false }),\n\t\tasync execute(_toolCallId, _params, _signal, _onUpdate, ctx) {\n\t\t\tconst goal = await deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(formatGoalToolResponse(goal));\n\t\t},\n\t});\n}\n\nfunction toolText(text: string): GoalToolResult {\n\treturn { content: [{ type: \"text\" as const, text }], details: {} };\n}\n"]}
1
+ {"version":3,"file":"tool-registration.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/tool-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"typebox\";\nimport type { AgentToolResult, ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { formatGoalToolResponse } from \"./format.ts\";\nimport { createGoal, objectiveFullTextFileName, readGoal, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\nimport { MODEL_SETTABLE_GOAL_STATUS_VALUES } from \"./types.ts\";\nimport { objectiveTruncationNotice, validateObjective } from \"./validation.ts\";\n\ntype GoalToolResult = AgentToolResult<Record<string, never>>;\n\nexport type GoalToolRegistrationDeps = {\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly accountCurrentAgentTurn: (ctx: ExtensionContext, mode: GoalAccountingMode) => Promise<Goal | null>;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly markGoalBlockedThisTurn: (goal: Goal) => void;\n\treadonly markGoalCompletedThisTurn: (goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal | null) => void;\n};\n\nexport function registerGoalTools(pi: ExtensionAPI, deps: GoalToolRegistrationDeps): void {\n\tpi.registerTool({\n\t\tname: \"create_goal\",\n\t\tlabel: \"Create Goal\",\n\t\tdescription:\n\t\t\t\"Create a goal only when explicitly requested by the user or system/developer instructions; do not infer goals from ordinary tasks.\\nObjectives are limited to 4,000 characters. For longer instructions, put the full objective in a file and refer to that file.\\nReplaces the current goal when it is complete and archives it; fails if an unfinished goal exists.\",\n\t\tparameters: Type.Object(\n\t\t\t{\n\t\t\t\tobjective: Type.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Required. The concrete objective to start pursuing. Limit: 4,000 characters. For longer instructions, put the full objective in a file and refer to that file.\",\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{ additionalProperties: false },\n\t\t),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst ref = deps.goalStoreRef(ctx);\n\t\t\tconst current = await readGoal(ref);\n\t\t\tif (current !== null && current.status !== \"complete\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"cannot create a new goal because this thread already has an unfinished goal; use update_goal only when the existing goal is complete\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst validatedObjective = validateObjective(params.objective, objectiveFullTextFileName(ref));\n\t\t\tconst goal = await createGoal(ref, params.objective);\n\t\t\tdeps.beginAgentGoalAccounting(goal);\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(\n\t\t\t\tformatGoalToolResponse(\n\t\t\t\t\tgoal,\n\t\t\t\t\tvalidatedObjective.truncated ? objectiveTruncationNotice(objectiveFullTextFileName(ref)) : undefined,\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\tname: \"update_goal\",\n\t\tlabel: \"Update Goal\",\n\t\tdescription:\n\t\t\t\"Update the existing goal.\\nSet status to `complete` only when the objective has actually been achieved and no required work remains. Do not mark a goal complete merely because you are stopping work.\\nSet status to `blocked` only after the same blocking condition recurs for at least 3 consecutive goal turns. After resuming, begin a fresh blocked audit after resume. Never mark a goal blocked merely because the work is hard, slow, or uncertain.\\nA non-empty reason is required when blocking; reason must not be provided when completing.\\nYou cannot use this tool to pause or resume a goal; those status changes are controlled by the user or system.\\nWhen marking the goal achieved with status `complete`, report the final elapsed time and token usage from the tool result to the user.\",\n\t\tparameters: Type.Object(\n\t\t\t{\n\t\t\t\tstatus: Type.Union(\n\t\t\t\t\tMODEL_SETTABLE_GOAL_STATUS_VALUES.map((status) => Type.Literal(status)),\n\t\t\t\t\t{ description: \"Required. Set to complete when achieved or blocked with a non-empty reason.\" },\n\t\t\t\t),\n\t\t\t\treason: Type.Optional(\n\t\t\t\t\tType.String({\n\t\t\t\t\t\tdescription: \"Required and non-empty when status is blocked; rejected when status is complete.\",\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t},\n\t\t\t{ additionalProperties: false },\n\t\t),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst reason = params.reason?.trim();\n\t\t\tif (params.status === \"blocked\" && (reason === undefined || reason.length === 0)) {\n\t\t\t\tthrow new Error(\"reason is required when status is blocked\");\n\t\t\t}\n\t\t\tif (params.status === \"complete\" && params.reason !== undefined) {\n\t\t\t\tthrow new Error(\"reason must not be provided when status is complete\");\n\t\t\t}\n\t\t\tawait deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\tconst goal = await updateGoal(\n\t\t\t\tdeps.goalStoreRef(ctx),\n\t\t\t\tparams.status === \"blocked\" ? { status: \"blocked\", reason } : { status: \"complete\" },\n\t\t\t\t\"model\",\n\t\t\t);\n\t\t\tif (goal.status === \"blocked\") deps.markGoalBlockedThisTurn(goal);\n\t\t\telse deps.markGoalCompletedThisTurn(goal);\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(formatGoalToolResponse(goal));\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\tname: \"get_goal\",\n\t\tlabel: \"Get Goal\",\n\t\tdescription: \"Get the current goal for this thread, including status, token and elapsed-time usage.\",\n\t\tparameters: Type.Object({}, { additionalProperties: false }),\n\t\tasync execute(_toolCallId, _params, _signal, _onUpdate, ctx) {\n\t\t\tconst goal = await deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\treturn toolText(formatGoalToolResponse(goal));\n\t\t},\n\t});\n}\n\nfunction toolText(text: string): GoalToolResult {\n\treturn { content: [{ type: \"text\" as const, text }], details: {} };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { Goal, GoalStatus, GoalUpdateSource } from "./types.ts";
2
+ export declare function transitionGoalStatus(current: Goal, status: GoalStatus, source: GoalUpdateSource, reason: string | undefined, updatedAt: number): Goal;
3
+ //# sourceMappingURL=transitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/transitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,IAAI,EACb,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,MAAM,GACf,IAAI,CAgBN"}
@@ -0,0 +1,45 @@
1
+ export function transitionGoalStatus(current, status, source, reason, updatedAt) {
2
+ assertGoalTransition(current.status, status, source);
3
+ if (status === "complete" && reason !== undefined)
4
+ throw new Error("reason must not be provided when status is complete");
5
+ const next = { ...current, status, updatedAt };
6
+ if (status === "blocked")
7
+ applyBlockedFields(next, current, reason, updatedAt);
8
+ else {
9
+ delete next.blockedReason;
10
+ delete next.blockedAt;
11
+ }
12
+ if (status === "active" && current.status !== "active")
13
+ next.lastStartedAt = updatedAt;
14
+ else if (status !== "active")
15
+ delete next.lastStartedAt;
16
+ if (status === "complete")
17
+ next.completedAt = current.completedAt ?? updatedAt;
18
+ else
19
+ delete next.completedAt;
20
+ return next;
21
+ }
22
+ function assertGoalTransition(current, next, source) {
23
+ if (current === next || isAllowedTransition(current, next, source))
24
+ return;
25
+ throw new Error(`illegal goal transition: ${current} -> ${next}`);
26
+ }
27
+ function isAllowedTransition(current, next, source) {
28
+ if (source === "model") {
29
+ return ((current === "active" && (next === "blocked" || next === "complete")) ||
30
+ (current === "blocked" && next === "complete"));
31
+ }
32
+ return ((current === "active" && next === "paused") ||
33
+ (current === "paused" && next === "active") ||
34
+ (current === "blocked" && next === "active"));
35
+ }
36
+ function applyBlockedFields(next, current, reason, updatedAt) {
37
+ if (current.status === "blocked")
38
+ return;
39
+ const blockedReason = reason?.trim();
40
+ if (blockedReason === undefined || blockedReason.length === 0)
41
+ throw new Error("reason is required when status is blocked");
42
+ next.blockedReason = blockedReason;
43
+ next.blockedAt = updatedAt;
44
+ }
45
+ //# sourceMappingURL=transitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/transitions.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CACnC,OAAa,EACb,MAAkB,EAClB,MAAwB,EACxB,MAA0B,EAC1B,SAAiB;IAEjB,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,SAAS;QAChD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAExE,MAAM,IAAI,GAAS,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACrD,IAAI,MAAM,KAAK,SAAS;QAAE,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;SAC1E,CAAC;QACL,OAAO,IAAI,CAAC,aAAa,CAAC;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ;QAAE,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;SAClF,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,aAAa,CAAC;IACxD,IAAI,MAAM,KAAK,UAAU;QAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,SAAS,CAAC;;QAC1E,OAAO,IAAI,CAAC,WAAW,CAAC;IAC7B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAmB,EAAE,IAAgB,EAAE,MAAwB;IAC5F,IAAI,OAAO,KAAK,IAAI,IAAI,mBAAmB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC;QAAE,OAAO;IAC3E,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAmB,EAAE,IAAgB,EAAE,MAAwB;IAC3F,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,CACN,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC;YACrE,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,CAAC,CAC9C,CAAC;IACH,CAAC;IACD,OAAO,CACN,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC;QAC3C,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC;QAC3C,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAC5C,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAU,EAAE,OAAa,EAAE,MAA0B,EAAE,SAAiB;IACnG,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO;IACzC,MAAM,aAAa,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;IACrC,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC9D,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;AAC5B,CAAC","sourcesContent":["import type { Goal, GoalStatus, GoalUpdateSource } from \"./types.ts\";\n\nexport function transitionGoalStatus(\n\tcurrent: Goal,\n\tstatus: GoalStatus,\n\tsource: GoalUpdateSource,\n\treason: string | undefined,\n\tupdatedAt: number,\n): Goal {\n\tassertGoalTransition(current.status, status, source);\n\tif (status === \"complete\" && reason !== undefined)\n\t\tthrow new Error(\"reason must not be provided when status is complete\");\n\n\tconst next: Goal = { ...current, status, updatedAt };\n\tif (status === \"blocked\") applyBlockedFields(next, current, reason, updatedAt);\n\telse {\n\t\tdelete next.blockedReason;\n\t\tdelete next.blockedAt;\n\t}\n\tif (status === \"active\" && current.status !== \"active\") next.lastStartedAt = updatedAt;\n\telse if (status !== \"active\") delete next.lastStartedAt;\n\tif (status === \"complete\") next.completedAt = current.completedAt ?? updatedAt;\n\telse delete next.completedAt;\n\treturn next;\n}\n\nfunction assertGoalTransition(current: GoalStatus, next: GoalStatus, source: GoalUpdateSource): void {\n\tif (current === next || isAllowedTransition(current, next, source)) return;\n\tthrow new Error(`illegal goal transition: ${current} -> ${next}`);\n}\n\nfunction isAllowedTransition(current: GoalStatus, next: GoalStatus, source: GoalUpdateSource): boolean {\n\tif (source === \"model\") {\n\t\treturn (\n\t\t\t(current === \"active\" && (next === \"blocked\" || next === \"complete\")) ||\n\t\t\t(current === \"blocked\" && next === \"complete\")\n\t\t);\n\t}\n\treturn (\n\t\t(current === \"active\" && next === \"paused\") ||\n\t\t(current === \"paused\" && next === \"active\") ||\n\t\t(current === \"blocked\" && next === \"active\")\n\t);\n}\n\nfunction applyBlockedFields(next: Goal, current: Goal, reason: string | undefined, updatedAt: number): void {\n\tif (current.status === \"blocked\") return;\n\tconst blockedReason = reason?.trim();\n\tif (blockedReason === undefined || blockedReason.length === 0)\n\t\tthrow new Error(\"reason is required when status is blocked\");\n\tnext.blockedReason = blockedReason;\n\tnext.blockedAt = updatedAt;\n}\n"]}