@roackb2/heddle 0.0.14 → 0.0.16

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 (392) hide show
  1. package/README.md +38 -9
  2. package/dist/examples/heartbeat-scheduler.js +3 -3
  3. package/dist/examples/heartbeat-scheduler.js.map +1 -1
  4. package/dist/examples/heartbeat.js +3 -3
  5. package/dist/examples/heartbeat.js.map +1 -1
  6. package/dist/examples/host-events.js +1 -1
  7. package/dist/examples/host-events.js.map +1 -1
  8. package/dist/examples/programmatic-loop.js +4 -4
  9. package/dist/examples/programmatic-loop.js.map +1 -1
  10. package/dist/src/cli/ask.js +1 -1
  11. package/dist/src/cli/ask.js.map +1 -1
  12. package/dist/src/cli/chat/App.d.ts.map +1 -1
  13. package/dist/src/cli/chat/App.js +4 -4
  14. package/dist/src/cli/chat/App.js.map +1 -1
  15. package/dist/src/cli/chat/components/ActivityPanel.d.ts +1 -1
  16. package/dist/src/cli/chat/components/ActivityPanel.d.ts.map +1 -1
  17. package/dist/src/cli/chat/components/ActivityPanel.js +1 -1
  18. package/dist/src/cli/chat/components/ActivityPanel.js.map +1 -1
  19. package/dist/src/cli/chat/components/ConversationPanel.d.ts +1 -1
  20. package/dist/src/cli/chat/components/ConversationPanel.d.ts.map +1 -1
  21. package/dist/src/cli/chat/hooks/useAgentRun.d.ts +2 -2
  22. package/dist/src/cli/chat/hooks/useAgentRun.d.ts.map +1 -1
  23. package/dist/src/cli/chat/hooks/useAgentRun.js +2 -2
  24. package/dist/src/cli/chat/hooks/useAgentRun.js.map +1 -1
  25. package/dist/src/cli/chat/hooks/useApprovalFlow.d.ts +2 -2
  26. package/dist/src/cli/chat/hooks/useApprovalFlow.d.ts.map +1 -1
  27. package/dist/src/cli/chat/hooks/useChatSessions.d.ts +2 -2
  28. package/dist/src/cli/chat/hooks/useChatSessions.d.ts.map +1 -1
  29. package/dist/src/cli/chat/hooks/useChatSessions.js +4 -4
  30. package/dist/src/cli/chat/hooks/useChatSessions.js.map +1 -1
  31. package/dist/src/cli/chat/state/approval-rules.d.ts +1 -1
  32. package/dist/src/cli/chat/state/approval-rules.d.ts.map +1 -1
  33. package/dist/src/cli/chat/state/approval-rules.js +67 -6
  34. package/dist/src/cli/chat/state/approval-rules.js.map +1 -1
  35. package/dist/src/cli/chat/state/compaction.d.ts +1 -16
  36. package/dist/src/cli/chat/state/compaction.d.ts.map +1 -1
  37. package/dist/src/cli/chat/state/compaction.js +1 -158
  38. package/dist/src/cli/chat/state/compaction.js.map +1 -1
  39. package/dist/src/cli/chat/state/local-commands.js +2 -2
  40. package/dist/src/cli/chat/state/local-commands.js.map +1 -1
  41. package/dist/src/cli/chat/state/storage.d.ts +1 -13
  42. package/dist/src/cli/chat/state/storage.d.ts.map +1 -1
  43. package/dist/src/cli/chat/state/storage.js +1 -146
  44. package/dist/src/cli/chat/state/storage.js.map +1 -1
  45. package/dist/src/cli/chat/state/types.d.ts +1 -76
  46. package/dist/src/cli/chat/state/types.d.ts.map +1 -1
  47. package/dist/src/cli/chat/utils/file-mentions.js +1 -1
  48. package/dist/src/cli/chat/utils/file-mentions.js.map +1 -1
  49. package/dist/src/cli/chat/utils/format.d.ts +3 -7
  50. package/dist/src/cli/chat/utils/format.d.ts.map +1 -1
  51. package/dist/src/cli/chat/utils/format.js +3 -181
  52. package/dist/src/cli/chat/utils/format.js.map +1 -1
  53. package/dist/src/cli/chat/utils/runtime.d.ts +3 -3
  54. package/dist/src/cli/chat/utils/runtime.d.ts.map +1 -1
  55. package/dist/src/cli/chat/utils/runtime.js +5 -10
  56. package/dist/src/cli/chat/utils/runtime.js.map +1 -1
  57. package/dist/src/cli/daemon.js +2 -2
  58. package/dist/src/cli/heartbeat.d.ts.map +1 -1
  59. package/dist/src/cli/heartbeat.js +137 -47
  60. package/dist/src/cli/heartbeat.js.map +1 -1
  61. package/dist/src/cli/main.js +108 -101
  62. package/dist/src/cli/main.js.map +1 -1
  63. package/dist/src/cli/session.d.ts +11 -0
  64. package/dist/src/cli/session.d.ts.map +1 -0
  65. package/dist/src/cli/session.js +30 -0
  66. package/dist/src/cli/session.js.map +1 -0
  67. package/dist/src/core/agent/history.d.ts.map +1 -0
  68. package/dist/src/core/agent/history.js.map +1 -0
  69. package/dist/src/core/agent/mutation-tracking.d.ts.map +1 -0
  70. package/dist/src/{run-agent → core/agent}/mutation-tracking.js +25 -8
  71. package/dist/src/core/agent/mutation-tracking.js.map +1 -0
  72. package/dist/src/core/agent/post-mutation.d.ts.map +1 -0
  73. package/dist/src/core/agent/post-mutation.js.map +1 -0
  74. package/dist/src/core/agent/progress-reminders.d.ts.map +1 -0
  75. package/dist/src/core/agent/progress-reminders.js.map +1 -0
  76. package/dist/src/{run-agent.d.ts → core/agent/run-agent.d.ts} +2 -2
  77. package/dist/src/core/agent/run-agent.d.ts.map +1 -0
  78. package/dist/src/{run-agent.js → core/agent/run-agent.js} +12 -16
  79. package/dist/src/core/agent/run-agent.js.map +1 -0
  80. package/dist/src/{run-agent → core/agent}/tool-dispatch.d.ts +1 -1
  81. package/dist/src/core/agent/tool-dispatch.d.ts.map +1 -0
  82. package/dist/src/core/agent/tool-dispatch.js.map +1 -0
  83. package/dist/src/core/agent/util.d.ts.map +1 -0
  84. package/dist/src/core/agent/util.js.map +1 -0
  85. package/dist/src/core/chat/compaction.d.ts +17 -0
  86. package/dist/src/core/chat/compaction.d.ts.map +1 -0
  87. package/dist/src/core/chat/compaction.js +159 -0
  88. package/dist/src/core/chat/compaction.js.map +1 -0
  89. package/dist/src/core/chat/format.d.ts +12 -0
  90. package/dist/src/core/chat/format.d.ts.map +1 -0
  91. package/dist/src/core/chat/format.js +139 -0
  92. package/dist/src/core/chat/format.js.map +1 -0
  93. package/dist/src/core/chat/session-submit.d.ts +22 -0
  94. package/dist/src/core/chat/session-submit.d.ts.map +1 -0
  95. package/dist/src/core/chat/session-submit.js +83 -0
  96. package/dist/src/core/chat/session-submit.js.map +1 -0
  97. package/dist/src/core/chat/storage.d.ts +33 -0
  98. package/dist/src/core/chat/storage.d.ts.map +1 -0
  99. package/dist/src/core/chat/storage.js +384 -0
  100. package/dist/src/core/chat/storage.js.map +1 -0
  101. package/dist/src/core/chat/trace.d.ts +3 -0
  102. package/dist/src/core/chat/trace.d.ts.map +1 -0
  103. package/dist/src/core/chat/trace.js +9 -0
  104. package/dist/src/core/chat/trace.js.map +1 -0
  105. package/dist/src/core/chat/types.d.ts +77 -0
  106. package/dist/src/core/chat/types.d.ts.map +1 -0
  107. package/dist/src/core/chat/types.js +2 -0
  108. package/dist/src/core/chat/types.js.map +1 -0
  109. package/dist/src/core/config.d.ts.map +1 -0
  110. package/dist/src/core/config.js.map +1 -0
  111. package/dist/src/core/llm/anthropic.d.ts.map +1 -0
  112. package/dist/src/core/llm/anthropic.js.map +1 -0
  113. package/dist/src/core/llm/factory.d.ts.map +1 -0
  114. package/dist/src/core/llm/factory.js.map +1 -0
  115. package/dist/src/core/llm/openai-models.d.ts.map +1 -0
  116. package/dist/src/core/llm/openai-models.js.map +1 -0
  117. package/dist/src/core/llm/openai.d.ts.map +1 -0
  118. package/dist/src/core/llm/openai.js.map +1 -0
  119. package/dist/src/core/llm/providers.d.ts.map +1 -0
  120. package/dist/src/core/llm/providers.js.map +1 -0
  121. package/dist/src/core/llm/types.d.ts.map +1 -0
  122. package/dist/src/core/llm/types.js.map +1 -0
  123. package/dist/src/core/prompts/system-prompt.d.ts.map +1 -0
  124. package/dist/src/core/prompts/system-prompt.js.map +1 -0
  125. package/dist/src/{runtime → core/runtime}/agent-loop.d.ts +1 -1
  126. package/dist/src/core/runtime/agent-loop.d.ts.map +1 -0
  127. package/dist/src/{runtime → core/runtime}/agent-loop.js +1 -1
  128. package/dist/src/core/runtime/agent-loop.js.map +1 -0
  129. package/dist/src/core/runtime/api-keys.d.ts.map +1 -0
  130. package/dist/src/core/runtime/api-keys.js.map +1 -0
  131. package/dist/src/core/runtime/default-tools.d.ts.map +1 -0
  132. package/dist/src/core/runtime/default-tools.js.map +1 -0
  133. package/dist/src/core/runtime/events.d.ts.map +1 -0
  134. package/dist/src/core/runtime/events.js.map +1 -0
  135. package/dist/src/core/runtime/heartbeat-lucid.d.ts.map +1 -0
  136. package/dist/src/core/runtime/heartbeat-lucid.js.map +1 -0
  137. package/dist/src/core/runtime/heartbeat-scheduler.d.ts.map +1 -0
  138. package/dist/src/core/runtime/heartbeat-scheduler.js.map +1 -0
  139. package/dist/src/core/runtime/heartbeat-store.d.ts.map +1 -0
  140. package/dist/src/core/runtime/heartbeat-store.js.map +1 -0
  141. package/dist/src/core/runtime/heartbeat-views.d.ts.map +1 -0
  142. package/dist/src/core/runtime/heartbeat-views.js.map +1 -0
  143. package/dist/src/core/runtime/heartbeat.d.ts.map +1 -0
  144. package/dist/src/{runtime → core/runtime}/heartbeat.js +0 -15
  145. package/dist/src/core/runtime/heartbeat.js.map +1 -0
  146. package/dist/src/core/tools/edit-file.d.ts.map +1 -0
  147. package/dist/src/core/tools/edit-file.js.map +1 -0
  148. package/dist/src/core/tools/execute-tool.d.ts.map +1 -0
  149. package/dist/src/core/tools/execute-tool.js.map +1 -0
  150. package/dist/src/core/tools/file-edit-core.d.ts.map +1 -0
  151. package/dist/src/core/tools/file-edit-core.js.map +1 -0
  152. package/dist/src/core/tools/list-files.d.ts.map +1 -0
  153. package/dist/src/core/tools/list-files.js.map +1 -0
  154. package/dist/src/core/tools/memory-notes.d.ts.map +1 -0
  155. package/dist/src/core/tools/memory-notes.js.map +1 -0
  156. package/dist/src/core/tools/read-file.d.ts.map +1 -0
  157. package/dist/src/core/tools/read-file.js.map +1 -0
  158. package/dist/src/core/tools/registry.d.ts.map +1 -0
  159. package/dist/src/core/tools/registry.js.map +1 -0
  160. package/dist/src/core/tools/report-state.d.ts.map +1 -0
  161. package/dist/src/core/tools/report-state.js.map +1 -0
  162. package/dist/src/core/tools/run-shell.d.ts.map +1 -0
  163. package/dist/src/core/tools/run-shell.js.map +1 -0
  164. package/dist/src/core/tools/search-files.d.ts.map +1 -0
  165. package/dist/src/core/tools/search-files.js.map +1 -0
  166. package/dist/src/core/tools/update-plan.d.ts.map +1 -0
  167. package/dist/src/core/tools/update-plan.js.map +1 -0
  168. package/dist/src/core/tools/view-image.d.ts.map +1 -0
  169. package/dist/src/core/tools/view-image.js.map +1 -0
  170. package/dist/src/core/tools/web-search.d.ts.map +1 -0
  171. package/dist/src/core/tools/web-search.js.map +1 -0
  172. package/dist/src/core/trace/format.d.ts.map +1 -0
  173. package/dist/src/core/trace/format.js.map +1 -0
  174. package/dist/src/core/trace/recorder.d.ts.map +1 -0
  175. package/dist/src/core/trace/recorder.js.map +1 -0
  176. package/dist/src/core/types.d.ts.map +1 -0
  177. package/dist/src/core/types.js.map +1 -0
  178. package/dist/src/core/utils/budget.d.ts.map +1 -0
  179. package/dist/src/core/utils/budget.js.map +1 -0
  180. package/dist/src/core/utils/errors.d.ts.map +1 -0
  181. package/dist/src/core/utils/errors.js.map +1 -0
  182. package/dist/src/core/utils/logger.d.ts.map +1 -0
  183. package/dist/src/core/utils/logger.js.map +1 -0
  184. package/dist/src/index.d.ts +59 -59
  185. package/dist/src/index.d.ts.map +1 -1
  186. package/dist/src/index.js +34 -34
  187. package/dist/src/index.js.map +1 -1
  188. package/dist/src/integrations/cyberloop-kinematics.d.ts +1 -1
  189. package/dist/src/integrations/cyberloop-kinematics.d.ts.map +1 -1
  190. package/dist/src/integrations/cyberloop-kinematics.js +1 -1
  191. package/dist/src/integrations/cyberloop-kinematics.js.map +1 -1
  192. package/dist/src/integrations/cyberloop.d.ts +1 -1
  193. package/dist/src/integrations/cyberloop.d.ts.map +1 -1
  194. package/dist/src/server/app.d.ts.map +1 -1
  195. package/dist/src/server/app.js +40 -0
  196. package/dist/src/server/app.js.map +1 -1
  197. package/dist/src/server/features/control-plane/router.d.ts +107 -0
  198. package/dist/src/server/features/control-plane/router.d.ts.map +1 -1
  199. package/dist/src/server/features/control-plane/router.js +102 -2
  200. package/dist/src/server/features/control-plane/router.js.map +1 -1
  201. package/dist/src/server/features/control-plane/services/chat-sessions.d.ts +44 -3
  202. package/dist/src/server/features/control-plane/services/chat-sessions.d.ts.map +1 -1
  203. package/dist/src/server/features/control-plane/services/chat-sessions.js +392 -11
  204. package/dist/src/server/features/control-plane/services/chat-sessions.js.map +1 -1
  205. package/dist/src/server/features/control-plane/services/control-plane-state.js +1 -1
  206. package/dist/src/server/features/control-plane/services/control-plane-state.js.map +1 -1
  207. package/dist/src/server/features/control-plane/services/workspace-files.d.ts +9 -0
  208. package/dist/src/server/features/control-plane/services/workspace-files.d.ts.map +1 -0
  209. package/dist/src/server/features/control-plane/services/workspace-files.js +71 -0
  210. package/dist/src/server/features/control-plane/services/workspace-files.js.map +1 -0
  211. package/dist/src/server/features/control-plane/types.d.ts +58 -1
  212. package/dist/src/server/features/control-plane/types.d.ts.map +1 -1
  213. package/dist/src/server/index.d.ts +2 -1
  214. package/dist/src/server/index.d.ts.map +1 -1
  215. package/dist/src/server/index.js +2 -1
  216. package/dist/src/server/index.js.map +1 -1
  217. package/dist/src/server/logger.js +1 -1
  218. package/dist/src/server/logger.js.map +1 -1
  219. package/dist/src/server/router.d.ts +107 -0
  220. package/dist/src/server/router.d.ts.map +1 -1
  221. package/dist/src/web/assets/favicon-CT3fFV8g.jpeg +0 -0
  222. package/dist/src/web/assets/index-C_kziU0x.css +1 -0
  223. package/dist/src/web/assets/index-DecqlZlx.js +12 -0
  224. package/dist/src/web/index.html +3 -2
  225. package/package.json +10 -1
  226. package/dist/src/config.d.ts.map +0 -1
  227. package/dist/src/config.js.map +0 -1
  228. package/dist/src/llm/anthropic.d.ts.map +0 -1
  229. package/dist/src/llm/anthropic.js.map +0 -1
  230. package/dist/src/llm/factory.d.ts.map +0 -1
  231. package/dist/src/llm/factory.js.map +0 -1
  232. package/dist/src/llm/openai-models.d.ts.map +0 -1
  233. package/dist/src/llm/openai-models.js.map +0 -1
  234. package/dist/src/llm/openai.d.ts.map +0 -1
  235. package/dist/src/llm/openai.js.map +0 -1
  236. package/dist/src/llm/providers.d.ts.map +0 -1
  237. package/dist/src/llm/providers.js.map +0 -1
  238. package/dist/src/llm/types.d.ts.map +0 -1
  239. package/dist/src/llm/types.js.map +0 -1
  240. package/dist/src/prompts/system-prompt.d.ts.map +0 -1
  241. package/dist/src/prompts/system-prompt.js.map +0 -1
  242. package/dist/src/run-agent/history.d.ts.map +0 -1
  243. package/dist/src/run-agent/history.js.map +0 -1
  244. package/dist/src/run-agent/mutation-tracking.d.ts.map +0 -1
  245. package/dist/src/run-agent/mutation-tracking.js.map +0 -1
  246. package/dist/src/run-agent/post-mutation.d.ts.map +0 -1
  247. package/dist/src/run-agent/post-mutation.js.map +0 -1
  248. package/dist/src/run-agent/progress-reminders.d.ts.map +0 -1
  249. package/dist/src/run-agent/progress-reminders.js.map +0 -1
  250. package/dist/src/run-agent/tool-dispatch.d.ts.map +0 -1
  251. package/dist/src/run-agent/tool-dispatch.js.map +0 -1
  252. package/dist/src/run-agent/util.d.ts.map +0 -1
  253. package/dist/src/run-agent/util.js.map +0 -1
  254. package/dist/src/run-agent.d.ts.map +0 -1
  255. package/dist/src/run-agent.js.map +0 -1
  256. package/dist/src/runtime/agent-loop.d.ts.map +0 -1
  257. package/dist/src/runtime/agent-loop.js.map +0 -1
  258. package/dist/src/runtime/api-keys.d.ts.map +0 -1
  259. package/dist/src/runtime/api-keys.js.map +0 -1
  260. package/dist/src/runtime/default-tools.d.ts.map +0 -1
  261. package/dist/src/runtime/default-tools.js.map +0 -1
  262. package/dist/src/runtime/events.d.ts.map +0 -1
  263. package/dist/src/runtime/events.js.map +0 -1
  264. package/dist/src/runtime/heartbeat-lucid.d.ts.map +0 -1
  265. package/dist/src/runtime/heartbeat-lucid.js.map +0 -1
  266. package/dist/src/runtime/heartbeat-scheduler.d.ts.map +0 -1
  267. package/dist/src/runtime/heartbeat-scheduler.js.map +0 -1
  268. package/dist/src/runtime/heartbeat-store.d.ts.map +0 -1
  269. package/dist/src/runtime/heartbeat-store.js.map +0 -1
  270. package/dist/src/runtime/heartbeat-views.d.ts.map +0 -1
  271. package/dist/src/runtime/heartbeat-views.js.map +0 -1
  272. package/dist/src/runtime/heartbeat.d.ts.map +0 -1
  273. package/dist/src/runtime/heartbeat.js.map +0 -1
  274. package/dist/src/tools/edit-file.d.ts.map +0 -1
  275. package/dist/src/tools/edit-file.js.map +0 -1
  276. package/dist/src/tools/execute-tool.d.ts.map +0 -1
  277. package/dist/src/tools/execute-tool.js.map +0 -1
  278. package/dist/src/tools/file-edit-core.d.ts.map +0 -1
  279. package/dist/src/tools/file-edit-core.js.map +0 -1
  280. package/dist/src/tools/list-files.d.ts.map +0 -1
  281. package/dist/src/tools/list-files.js.map +0 -1
  282. package/dist/src/tools/memory-notes.d.ts.map +0 -1
  283. package/dist/src/tools/memory-notes.js.map +0 -1
  284. package/dist/src/tools/read-file.d.ts.map +0 -1
  285. package/dist/src/tools/read-file.js.map +0 -1
  286. package/dist/src/tools/registry.d.ts.map +0 -1
  287. package/dist/src/tools/registry.js.map +0 -1
  288. package/dist/src/tools/report-state.d.ts.map +0 -1
  289. package/dist/src/tools/report-state.js.map +0 -1
  290. package/dist/src/tools/run-shell.d.ts.map +0 -1
  291. package/dist/src/tools/run-shell.js.map +0 -1
  292. package/dist/src/tools/search-files.d.ts.map +0 -1
  293. package/dist/src/tools/search-files.js.map +0 -1
  294. package/dist/src/tools/update-plan.d.ts.map +0 -1
  295. package/dist/src/tools/update-plan.js.map +0 -1
  296. package/dist/src/tools/view-image.d.ts.map +0 -1
  297. package/dist/src/tools/view-image.js.map +0 -1
  298. package/dist/src/tools/web-search.d.ts.map +0 -1
  299. package/dist/src/tools/web-search.js.map +0 -1
  300. package/dist/src/trace/format.d.ts.map +0 -1
  301. package/dist/src/trace/format.js.map +0 -1
  302. package/dist/src/trace/recorder.d.ts.map +0 -1
  303. package/dist/src/trace/recorder.js.map +0 -1
  304. package/dist/src/types.d.ts.map +0 -1
  305. package/dist/src/types.js.map +0 -1
  306. package/dist/src/utils/budget.d.ts.map +0 -1
  307. package/dist/src/utils/budget.js.map +0 -1
  308. package/dist/src/utils/errors.d.ts.map +0 -1
  309. package/dist/src/utils/errors.js.map +0 -1
  310. package/dist/src/utils/logger.d.ts.map +0 -1
  311. package/dist/src/utils/logger.js.map +0 -1
  312. package/dist/src/web/assets/index-DmYQXJQf.css +0 -1
  313. package/dist/src/web/assets/index-xFJTOaTY.js +0 -9
  314. /package/dist/src/{run-agent → core/agent}/history.d.ts +0 -0
  315. /package/dist/src/{run-agent → core/agent}/history.js +0 -0
  316. /package/dist/src/{run-agent → core/agent}/mutation-tracking.d.ts +0 -0
  317. /package/dist/src/{run-agent → core/agent}/post-mutation.d.ts +0 -0
  318. /package/dist/src/{run-agent → core/agent}/post-mutation.js +0 -0
  319. /package/dist/src/{run-agent → core/agent}/progress-reminders.d.ts +0 -0
  320. /package/dist/src/{run-agent → core/agent}/progress-reminders.js +0 -0
  321. /package/dist/src/{run-agent → core/agent}/tool-dispatch.js +0 -0
  322. /package/dist/src/{run-agent → core/agent}/util.d.ts +0 -0
  323. /package/dist/src/{run-agent → core/agent}/util.js +0 -0
  324. /package/dist/src/{config.d.ts → core/config.d.ts} +0 -0
  325. /package/dist/src/{config.js → core/config.js} +0 -0
  326. /package/dist/src/{llm → core/llm}/anthropic.d.ts +0 -0
  327. /package/dist/src/{llm → core/llm}/anthropic.js +0 -0
  328. /package/dist/src/{llm → core/llm}/factory.d.ts +0 -0
  329. /package/dist/src/{llm → core/llm}/factory.js +0 -0
  330. /package/dist/src/{llm → core/llm}/openai-models.d.ts +0 -0
  331. /package/dist/src/{llm → core/llm}/openai-models.js +0 -0
  332. /package/dist/src/{llm → core/llm}/openai.d.ts +0 -0
  333. /package/dist/src/{llm → core/llm}/openai.js +0 -0
  334. /package/dist/src/{llm → core/llm}/providers.d.ts +0 -0
  335. /package/dist/src/{llm → core/llm}/providers.js +0 -0
  336. /package/dist/src/{llm → core/llm}/types.d.ts +0 -0
  337. /package/dist/src/{llm → core/llm}/types.js +0 -0
  338. /package/dist/src/{prompts → core/prompts}/system-prompt.d.ts +0 -0
  339. /package/dist/src/{prompts → core/prompts}/system-prompt.js +0 -0
  340. /package/dist/src/{runtime → core/runtime}/api-keys.d.ts +0 -0
  341. /package/dist/src/{runtime → core/runtime}/api-keys.js +0 -0
  342. /package/dist/src/{runtime → core/runtime}/default-tools.d.ts +0 -0
  343. /package/dist/src/{runtime → core/runtime}/default-tools.js +0 -0
  344. /package/dist/src/{runtime → core/runtime}/events.d.ts +0 -0
  345. /package/dist/src/{runtime → core/runtime}/events.js +0 -0
  346. /package/dist/src/{runtime → core/runtime}/heartbeat-lucid.d.ts +0 -0
  347. /package/dist/src/{runtime → core/runtime}/heartbeat-lucid.js +0 -0
  348. /package/dist/src/{runtime → core/runtime}/heartbeat-scheduler.d.ts +0 -0
  349. /package/dist/src/{runtime → core/runtime}/heartbeat-scheduler.js +0 -0
  350. /package/dist/src/{runtime → core/runtime}/heartbeat-store.d.ts +0 -0
  351. /package/dist/src/{runtime → core/runtime}/heartbeat-store.js +0 -0
  352. /package/dist/src/{runtime → core/runtime}/heartbeat-views.d.ts +0 -0
  353. /package/dist/src/{runtime → core/runtime}/heartbeat-views.js +0 -0
  354. /package/dist/src/{runtime → core/runtime}/heartbeat.d.ts +0 -0
  355. /package/dist/src/{tools → core/tools}/edit-file.d.ts +0 -0
  356. /package/dist/src/{tools → core/tools}/edit-file.js +0 -0
  357. /package/dist/src/{tools → core/tools}/execute-tool.d.ts +0 -0
  358. /package/dist/src/{tools → core/tools}/execute-tool.js +0 -0
  359. /package/dist/src/{tools → core/tools}/file-edit-core.d.ts +0 -0
  360. /package/dist/src/{tools → core/tools}/file-edit-core.js +0 -0
  361. /package/dist/src/{tools → core/tools}/list-files.d.ts +0 -0
  362. /package/dist/src/{tools → core/tools}/list-files.js +0 -0
  363. /package/dist/src/{tools → core/tools}/memory-notes.d.ts +0 -0
  364. /package/dist/src/{tools → core/tools}/memory-notes.js +0 -0
  365. /package/dist/src/{tools → core/tools}/read-file.d.ts +0 -0
  366. /package/dist/src/{tools → core/tools}/read-file.js +0 -0
  367. /package/dist/src/{tools → core/tools}/registry.d.ts +0 -0
  368. /package/dist/src/{tools → core/tools}/registry.js +0 -0
  369. /package/dist/src/{tools → core/tools}/report-state.d.ts +0 -0
  370. /package/dist/src/{tools → core/tools}/report-state.js +0 -0
  371. /package/dist/src/{tools → core/tools}/run-shell.d.ts +0 -0
  372. /package/dist/src/{tools → core/tools}/run-shell.js +0 -0
  373. /package/dist/src/{tools → core/tools}/search-files.d.ts +0 -0
  374. /package/dist/src/{tools → core/tools}/search-files.js +0 -0
  375. /package/dist/src/{tools → core/tools}/update-plan.d.ts +0 -0
  376. /package/dist/src/{tools → core/tools}/update-plan.js +0 -0
  377. /package/dist/src/{tools → core/tools}/view-image.d.ts +0 -0
  378. /package/dist/src/{tools → core/tools}/view-image.js +0 -0
  379. /package/dist/src/{tools → core/tools}/web-search.d.ts +0 -0
  380. /package/dist/src/{tools → core/tools}/web-search.js +0 -0
  381. /package/dist/src/{trace → core/trace}/format.d.ts +0 -0
  382. /package/dist/src/{trace → core/trace}/format.js +0 -0
  383. /package/dist/src/{trace → core/trace}/recorder.d.ts +0 -0
  384. /package/dist/src/{trace → core/trace}/recorder.js +0 -0
  385. /package/dist/src/{types.d.ts → core/types.d.ts} +0 -0
  386. /package/dist/src/{types.js → core/types.js} +0 -0
  387. /package/dist/src/{utils → core/utils}/budget.d.ts +0 -0
  388. /package/dist/src/{utils → core/utils}/budget.js +0 -0
  389. /package/dist/src/{utils → core/utils}/errors.d.ts +0 -0
  390. /package/dist/src/{utils → core/utils}/errors.js +0 -0
  391. /package/dist/src/{utils → core/utils}/logger.d.ts +0 -0
  392. /package/dist/src/{utils → core/utils}/logger.js +0 -0
@@ -1,22 +1,113 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { z } from 'zod';
3
+ import { BUILT_IN_MODEL_GROUPS } from '../../../core/llm/openai-models.js';
3
4
  import { procedure, router } from '../../trpc.js';
4
- import { readChatSessionViews } from './services/chat-sessions.js';
5
+ import { cancelControlPlaneSessionRun, continueChatPrompt, createControlPlaneChatSession, getPendingControlPlaneApproval, isControlPlaneSessionRunning, readChatSessionDetail, readChatSessionViews, readChatTurnReview, resolvePendingControlPlaneApproval, submitChatPrompt, updateControlPlaneChatSessionSettings, } from './services/chat-sessions.js';
5
6
  import { loadControlPlaneState } from './services/control-plane-state.js';
6
7
  import { listControlPlaneHeartbeatRuns, listControlPlaneHeartbeatTasks } from './services/heartbeat.js';
8
+ import { searchWorkspaceFiles } from './services/workspace-files.js';
9
+ const sessionInputSchema = z.object({
10
+ id: z.string().min(1),
11
+ });
12
+ const createSessionInputSchema = z.object({
13
+ name: z.string().min(1).optional(),
14
+ }).optional();
15
+ const sessionMessageInputSchema = z.object({
16
+ sessionId: z.string().min(1),
17
+ prompt: z.string().min(1),
18
+ });
19
+ const turnReviewInputSchema = z.object({
20
+ sessionId: z.string().min(1),
21
+ turnId: z.string().min(1),
22
+ });
23
+ const sessionApprovalDecisionSchema = z.object({
24
+ sessionId: z.string().min(1),
25
+ approved: z.boolean(),
26
+ reason: z.string().optional(),
27
+ });
28
+ const sessionSettingsInputSchema = z.object({
29
+ id: z.string().min(1),
30
+ model: z.string().min(1).optional(),
31
+ driftEnabled: z.boolean().optional(),
32
+ });
7
33
  const heartbeatRunsInputSchema = z.object({
8
34
  taskId: z.string().min(1).optional(),
9
35
  limit: z.number().int().min(1).max(100).optional(),
10
36
  }).optional();
37
+ const fileSearchInputSchema = z.object({
38
+ query: z.string().max(200).optional(),
39
+ limit: z.number().int().min(1).max(50).optional(),
40
+ }).optional();
11
41
  export const controlPlaneRouter = router({
12
42
  state: procedure.query(async ({ ctx }) => {
13
43
  return await loadControlPlaneState(ctx);
14
44
  }),
15
45
  sessions: procedure.query(({ ctx }) => {
16
46
  return {
17
- sessions: readChatSessionViews(resolve(ctx.stateRoot, 'chat-sessions.json')),
47
+ sessions: readChatSessionViews(resolve(ctx.stateRoot, 'chat-sessions.catalog.json')),
48
+ };
49
+ }),
50
+ sessionCreate: procedure.input(createSessionInputSchema).mutation(({ ctx, input }) => {
51
+ return createControlPlaneChatSession({
52
+ sessionStoragePath: resolve(ctx.stateRoot, 'chat-sessions.catalog.json'),
53
+ suggestedName: input?.name,
54
+ });
55
+ }),
56
+ session: procedure.input(sessionInputSchema).query(({ ctx, input }) => {
57
+ return readChatSessionDetail(resolve(ctx.stateRoot, 'chat-sessions.catalog.json'), input.id) ?? null;
58
+ }),
59
+ modelOptions: procedure.query(() => {
60
+ return {
61
+ groups: BUILT_IN_MODEL_GROUPS,
62
+ };
63
+ }),
64
+ sessionSettingsUpdate: procedure.input(sessionSettingsInputSchema).mutation(({ ctx, input }) => {
65
+ return updateControlPlaneChatSessionSettings({
66
+ sessionStoragePath: resolve(ctx.stateRoot, 'chat-sessions.catalog.json'),
67
+ sessionId: input.id,
68
+ model: input.model,
69
+ driftEnabled: input.driftEnabled,
70
+ });
71
+ }),
72
+ sessionTurnReview: procedure.input(turnReviewInputSchema).query(({ ctx, input }) => {
73
+ return readChatTurnReview(resolve(ctx.stateRoot, 'chat-sessions.catalog.json'), input.sessionId, input.turnId) ?? null;
74
+ }),
75
+ sessionPendingApproval: procedure.input(sessionInputSchema).query(({ input }) => {
76
+ return getPendingControlPlaneApproval(input.id) ?? null;
77
+ }),
78
+ sessionRunning: procedure.input(sessionInputSchema).query(({ input }) => {
79
+ return { running: isControlPlaneSessionRunning(input.id) };
80
+ }),
81
+ sessionResolveApproval: procedure.input(sessionApprovalDecisionSchema).mutation(({ input }) => {
82
+ return {
83
+ resolved: resolvePendingControlPlaneApproval(input.sessionId, {
84
+ approved: input.approved,
85
+ reason: input.reason,
86
+ }),
87
+ };
88
+ }),
89
+ sessionCancel: procedure.input(sessionInputSchema).mutation(({ input }) => {
90
+ return {
91
+ cancelled: cancelControlPlaneSessionRun(input.id),
18
92
  };
19
93
  }),
94
+ sessionSendPrompt: procedure.input(sessionMessageInputSchema).mutation(async ({ ctx, input }) => {
95
+ return await submitChatPrompt({
96
+ workspaceRoot: ctx.workspaceRoot,
97
+ stateRoot: ctx.stateRoot,
98
+ sessionStoragePath: resolve(ctx.stateRoot, 'chat-sessions.catalog.json'),
99
+ sessionId: input.sessionId,
100
+ prompt: input.prompt,
101
+ });
102
+ }),
103
+ sessionContinue: procedure.input(sessionInputSchema).mutation(async ({ ctx, input }) => {
104
+ return await continueChatPrompt({
105
+ workspaceRoot: ctx.workspaceRoot,
106
+ stateRoot: ctx.stateRoot,
107
+ sessionStoragePath: resolve(ctx.stateRoot, 'chat-sessions.catalog.json'),
108
+ sessionId: input.id,
109
+ });
110
+ }),
20
111
  heartbeatTasks: procedure.query(async ({ ctx }) => {
21
112
  return {
22
113
  tasks: await listControlPlaneHeartbeatTasks(ctx.stateRoot),
@@ -30,5 +121,14 @@ export const controlPlaneRouter = router({
30
121
  }),
31
122
  };
32
123
  }),
124
+ workspaceFileSearch: procedure.input(fileSearchInputSchema).query(async ({ ctx, input }) => {
125
+ return {
126
+ files: await searchWorkspaceFiles({
127
+ workspaceRoot: ctx.workspaceRoot,
128
+ query: input?.query ?? '',
129
+ limit: input?.limit ?? 20,
130
+ }),
131
+ };
132
+ }),
33
133
  });
34
134
  //# sourceMappingURL=router.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../../src/server/features/control-plane/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAExG,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;IACvC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;QACvC,OAAO,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC1C,CAAC,CAAC;IACF,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QACpC,OAAO;YACL,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;SAC7E,CAAC;IACJ,CAAC,CAAC;IACF,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;QAChD,OAAO;YACL,KAAK,EAAE,MAAM,8BAA8B,CAAC,GAAG,CAAC,SAAS,CAAC;SAC3D,CAAC;IACJ,CAAC,CAAC;IACF,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QACtF,OAAO;YACL,IAAI,EAAE,MAAM,6BAA6B,CAAC,GAAG,CAAC,SAAS,EAAE;gBACvD,MAAM,EAAE,KAAK,EAAE,MAAM;gBACrB,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;aAC1B,CAAC;SACH,CAAC;IACJ,CAAC,CAAC;CACH,CAAC,CAAC"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../../src/server/features/control-plane/router.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,45 @@
1
- import type { ChatSessionView } from '../types.js';
2
- export declare function readChatSessionViews(sessionsPath: string): ChatSessionView[];
3
- export declare function projectChatSessionView(raw: unknown): ChatSessionView[];
1
+ import type { ChatSession } from '../../../../core/chat/types.js';
2
+ import type { ChatSessionDetail, ChatSessionView, ChatTurnReview, ControlPlanePendingApproval, ControlPlaneSessionLiveEvent } from '../types.js';
3
+ type SubmitChatPromptArgs = {
4
+ workspaceRoot: string;
5
+ stateRoot: string;
6
+ sessionStoragePath: string;
7
+ sessionId: string;
8
+ prompt: string;
9
+ };
10
+ export declare function createControlPlaneChatSession(args: {
11
+ sessionStoragePath: string;
12
+ suggestedName?: string;
13
+ }): ChatSessionDetail;
14
+ export declare function updateControlPlaneChatSessionSettings(args: {
15
+ sessionStoragePath: string;
16
+ sessionId: string;
17
+ model?: string;
18
+ driftEnabled?: boolean;
19
+ }): ChatSessionDetail;
20
+ export declare function submitChatPrompt(args: SubmitChatPromptArgs): Promise<{
21
+ session: ChatSessionDetail;
22
+ outcome: import("../../../../index.js").StopReason;
23
+ summary: string;
24
+ }>;
25
+ export declare function continueChatPrompt(args: Omit<SubmitChatPromptArgs, 'prompt'>): Promise<{
26
+ session: ChatSessionDetail;
27
+ outcome: import("../../../../index.js").StopReason;
28
+ summary: string;
29
+ }>;
30
+ export declare function subscribeToControlPlaneSessionEvents(sessionId: string, listener: (event: ControlPlaneSessionLiveEvent) => void): () => void;
31
+ export declare function getPendingControlPlaneApproval(sessionId: string): ControlPlanePendingApproval | undefined;
32
+ export declare function isControlPlaneSessionRunning(sessionId: string): boolean;
33
+ export declare function cancelControlPlaneSessionRun(sessionId: string): boolean;
34
+ export declare function resolvePendingControlPlaneApproval(sessionId: string, decision: {
35
+ approved: boolean;
36
+ reason?: string;
37
+ }): boolean;
38
+ export declare function readChatSessionViews(sessionStoragePath: string): ChatSessionView[];
39
+ export declare function readChatSessionDetail(sessionStoragePath: string, id: string): ChatSessionDetail | undefined;
40
+ export declare function readChatTurnReview(sessionStoragePath: string, sessionId: string, turnId: string): ChatTurnReview | undefined;
41
+ export declare function resolveChatSessionFilePath(stateRoot: string, sessionId: string): string;
42
+ export declare function projectChatSessionView(raw: unknown | ChatSession): ChatSessionView[];
43
+ export declare function projectChatSessionDetail(raw: unknown | ChatSession): ChatSessionDetail[];
44
+ export {};
4
45
  //# sourceMappingURL=chat-sessions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-sessions.d.ts","sourceRoot":"","sources":["../../../../../../src/server/features/control-plane/services/chat-sessions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE,CAgB5E;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,EAAE,CAqCtE"}
1
+ {"version":3,"file":"chat-sessions.d.ts","sourceRoot":"","sources":["../../../../../../src/server/features/control-plane/services/chat-sessions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,OAAO,KAAK,EAEV,iBAAiB,EAEjB,eAAe,EACf,cAAc,EAGd,2BAA2B,EAC3B,4BAA4B,EAC7B,MAAM,aAAa,CAAC;AAErB,KAAK,oBAAoB,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,iBAAiB,CAgBpB;AAED,wBAAgB,qCAAqC,CAAC,IAAI,EAAE;IAC1D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,iBAAiB,CAqBpB;AASD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB;;;;GA0DhE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC;;;;GAclF;AAED,wBAAgB,oCAAoC,CAClD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,GACtD,MAAM,IAAI,CAKZ;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS,CAEzG;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CASvE;AAED,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAST;AAED,wBAAgB,oBAAoB,CAAC,kBAAkB,EAAE,MAAM,GAAG,eAAe,EAAE,CAIlF;AAED,wBAAgB,qBAAqB,CAAC,kBAAkB,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAG3G;AAED,wBAAgB,kBAAkB,CAAC,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAQ5H;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,eAAe,EAAE,CAsCpF;AA4CD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,iBAAiB,EAAE,CAgBxF"}
@@ -1,20 +1,169 @@
1
+ import { EventEmitter } from 'node:events';
1
2
  import { existsSync, readFileSync } from 'node:fs';
2
- export function readChatSessionViews(sessionsPath) {
3
- if (!existsSync(sessionsPath)) {
4
- return [];
3
+ import { join } from 'node:path';
4
+ import { createChatSession, readChatSession, readChatSessionCatalog, saveChatSessions } from '../../../../core/chat/storage.js';
5
+ import { DEFAULT_OPENAI_MODEL } from '../../../../core/config.js';
6
+ import { resolveApiKeyForModel } from '../../../../core/runtime/api-keys.js';
7
+ import { submitChatSessionPrompt } from '../../../../core/chat/session-submit.js';
8
+ const DEFAULT_CONTINUE_PROMPT = 'Continue from where you left off.';
9
+ export function createControlPlaneChatSession(args) {
10
+ const existing = readChatSessionViews(args.sessionStoragePath);
11
+ const nextNumber = existing.length + 1;
12
+ const model = process.env.OPENAI_MODEL ?? process.env.ANTHROPIC_MODEL ?? DEFAULT_OPENAI_MODEL;
13
+ const session = createChatSession({
14
+ id: `session-${Date.now()}`,
15
+ name: args.suggestedName?.trim() || `Session ${nextNumber}`,
16
+ apiKeyPresent: Boolean(resolveApiKeyForModel(model)),
17
+ model,
18
+ });
19
+ const currentSessions = readChatSessionCatalog(args.sessionStoragePath)
20
+ .map((entry) => readChatSession(args.sessionStoragePath, entry.id, Boolean(resolveApiKeyForModel(model))))
21
+ .filter((candidate) => Boolean(candidate));
22
+ saveChatSessions(args.sessionStoragePath, [session, ...currentSessions]);
23
+ return projectChatSessionDetail(session)[0];
24
+ }
25
+ export function updateControlPlaneChatSessionSettings(args) {
26
+ const currentSessions = readChatSessionCatalog(args.sessionStoragePath)
27
+ .map((entry) => readChatSession(args.sessionStoragePath, entry.id, true))
28
+ .filter((candidate) => Boolean(candidate));
29
+ const nextSessions = currentSessions.map((session) => (session.id === args.sessionId ?
30
+ {
31
+ ...session,
32
+ model: args.model ?? session.model,
33
+ driftEnabled: args.driftEnabled ?? session.driftEnabled,
34
+ updatedAt: new Date().toISOString(),
35
+ }
36
+ : session));
37
+ const updated = nextSessions.find((session) => session.id === args.sessionId);
38
+ if (!updated) {
39
+ throw new Error(`Chat session not found: ${args.sessionId}`);
5
40
  }
41
+ saveChatSessions(args.sessionStoragePath, nextSessions);
42
+ return projectChatSessionDetail(updated)[0];
43
+ }
44
+ const sessionEventBus = new EventEmitter();
45
+ const pendingApprovals = new Map();
46
+ const inFlightRuns = new Map();
47
+ export async function submitChatPrompt(args) {
48
+ if (inFlightRuns.has(args.sessionId)) {
49
+ throw new Error('A run is already in progress for this session.');
50
+ }
51
+ const controller = new AbortController();
52
+ inFlightRuns.set(args.sessionId, controller);
6
53
  try {
7
- const parsed = JSON.parse(readFileSync(sessionsPath, 'utf8'));
8
- if (!Array.isArray(parsed)) {
9
- return [];
10
- }
11
- return parsed.flatMap(projectChatSessionView).sort((left, right) => {
12
- return (right.updatedAt ?? '').localeCompare(left.updatedAt ?? '');
54
+ const result = await submitChatSessionPrompt({
55
+ ...args,
56
+ abortSignal: controller.signal,
57
+ onEvent: (event) => {
58
+ sessionEventBus.emit(args.sessionId, {
59
+ sessionId: args.sessionId,
60
+ timestamp: new Date().toISOString(),
61
+ event,
62
+ });
63
+ },
64
+ approveToolCall: async (call, tool) => {
65
+ const decision = await new Promise((resolve) => {
66
+ pendingApprovals.set(args.sessionId, {
67
+ approval: {
68
+ tool: tool.name,
69
+ callId: call.id,
70
+ input: call.input,
71
+ requestedAt: new Date().toISOString(),
72
+ },
73
+ resolve,
74
+ });
75
+ sessionEventBus.emit(args.sessionId, {
76
+ sessionId: args.sessionId,
77
+ timestamp: new Date().toISOString(),
78
+ event: {
79
+ type: 'trace',
80
+ runId: 'pending-approval',
81
+ timestamp: new Date().toISOString(),
82
+ event: {
83
+ type: 'tool.approval_requested',
84
+ call,
85
+ step: 0,
86
+ timestamp: new Date().toISOString(),
87
+ },
88
+ },
89
+ });
90
+ });
91
+ pendingApprovals.delete(args.sessionId);
92
+ return decision;
93
+ },
13
94
  });
95
+ return {
96
+ ...result,
97
+ session: projectChatSessionDetail(result.session)[0] ?? null,
98
+ };
14
99
  }
15
- catch {
16
- return [];
100
+ finally {
101
+ pendingApprovals.delete(args.sessionId);
102
+ inFlightRuns.delete(args.sessionId);
103
+ }
104
+ }
105
+ export async function continueChatPrompt(args) {
106
+ const session = readChatSession(args.sessionStoragePath, args.sessionId, true);
107
+ if (!session) {
108
+ throw new Error(`Chat session not found: ${args.sessionId}`);
17
109
  }
110
+ if (!session.history.length || !session.lastContinuePrompt) {
111
+ throw new Error('There is no interrupted or prior run to continue yet.');
112
+ }
113
+ return await submitChatPrompt({
114
+ ...args,
115
+ prompt: DEFAULT_CONTINUE_PROMPT,
116
+ });
117
+ }
118
+ export function subscribeToControlPlaneSessionEvents(sessionId, listener) {
119
+ sessionEventBus.on(sessionId, listener);
120
+ return () => {
121
+ sessionEventBus.off(sessionId, listener);
122
+ };
123
+ }
124
+ export function getPendingControlPlaneApproval(sessionId) {
125
+ return pendingApprovals.get(sessionId)?.approval;
126
+ }
127
+ export function isControlPlaneSessionRunning(sessionId) {
128
+ return inFlightRuns.has(sessionId);
129
+ }
130
+ export function cancelControlPlaneSessionRun(sessionId) {
131
+ const controller = inFlightRuns.get(sessionId);
132
+ if (!controller) {
133
+ return false;
134
+ }
135
+ controller.abort();
136
+ pendingApprovals.delete(sessionId);
137
+ return true;
138
+ }
139
+ export function resolvePendingControlPlaneApproval(sessionId, decision) {
140
+ const pending = pendingApprovals.get(sessionId);
141
+ if (!pending) {
142
+ return false;
143
+ }
144
+ pendingApprovals.delete(sessionId);
145
+ pending.resolve(decision);
146
+ return true;
147
+ }
148
+ export function readChatSessionViews(sessionStoragePath) {
149
+ return readChatSessionCatalog(sessionStoragePath)
150
+ .flatMap(projectChatSessionView)
151
+ .sort((left, right) => (right.updatedAt ?? '').localeCompare(left.updatedAt ?? ''));
152
+ }
153
+ export function readChatSessionDetail(sessionStoragePath, id) {
154
+ const session = readChatSession(sessionStoragePath, id, true);
155
+ return session ? projectChatSessionDetail(session)[0] : undefined;
156
+ }
157
+ export function readChatTurnReview(sessionStoragePath, sessionId, turnId) {
158
+ const session = readChatSessionDetail(sessionStoragePath, sessionId);
159
+ const turn = session?.turns.find((candidate) => candidate.id === turnId);
160
+ if (!turn) {
161
+ return undefined;
162
+ }
163
+ return loadChatTurnReview(turn.traceFile);
164
+ }
165
+ export function resolveChatSessionFilePath(stateRoot, sessionId) {
166
+ return join(stateRoot, 'chat-sessions', `${sessionId}.json`);
18
167
  }
19
168
  export function projectChatSessionView(raw) {
20
169
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
@@ -37,6 +186,7 @@ export function projectChatSessionView(raw) {
37
186
  updatedAt: readString(candidate.updatedAt),
38
187
  model: readString(candidate.model),
39
188
  driftEnabled: typeof candidate.driftEnabled === 'boolean' ? candidate.driftEnabled : undefined,
189
+ driftLevel: readLatestDriftLevel(turns),
40
190
  messageCount: messages.length,
41
191
  turnCount: turns.length,
42
192
  lastPrompt: readString(lastTurn?.prompt),
@@ -51,12 +201,243 @@ export function projectChatSessionView(raw) {
51
201
  } : undefined,
52
202
  }];
53
203
  }
204
+ function readLatestDriftLevel(turns) {
205
+ for (let index = turns.length - 1; index >= 0; index--) {
206
+ const turn = readObject(turns[index]);
207
+ const traceFile = readString(turn?.traceFile);
208
+ const driftLevel = traceFile ? readLatestDriftLevelFromTrace(traceFile) : undefined;
209
+ if (driftLevel) {
210
+ return driftLevel;
211
+ }
212
+ }
213
+ return undefined;
214
+ }
215
+ function readLatestDriftLevelFromTrace(traceFile) {
216
+ if (!traceFile || !existsSync(traceFile)) {
217
+ return undefined;
218
+ }
219
+ try {
220
+ const parsed = JSON.parse(readFileSync(traceFile, 'utf8'));
221
+ if (!Array.isArray(parsed)) {
222
+ return undefined;
223
+ }
224
+ for (let index = parsed.length - 1; index >= 0; index--) {
225
+ const event = readObject(parsed[index]);
226
+ if (event?.type !== 'cyberloop.annotation') {
227
+ continue;
228
+ }
229
+ const driftLevel = readString(event.driftLevel);
230
+ if (driftLevel === 'unknown' || driftLevel === 'low' || driftLevel === 'medium' || driftLevel === 'high') {
231
+ return driftLevel;
232
+ }
233
+ }
234
+ }
235
+ catch {
236
+ return undefined;
237
+ }
238
+ return undefined;
239
+ }
240
+ export function projectChatSessionDetail(raw) {
241
+ const base = projectChatSessionView(raw)[0];
242
+ if (!base || !raw || typeof raw !== 'object' || Array.isArray(raw)) {
243
+ return [];
244
+ }
245
+ const candidate = raw;
246
+ const messages = Array.isArray(candidate.messages) ? candidate.messages.flatMap(projectChatSessionMessage) : [];
247
+ const turns = Array.isArray(candidate.turns) ? candidate.turns.flatMap(projectChatTurnView) : [];
248
+ return [{
249
+ ...base,
250
+ messages,
251
+ turns,
252
+ lastContinuePrompt: readString(candidate.lastContinuePrompt),
253
+ }];
254
+ }
255
+ function projectChatSessionMessage(raw) {
256
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
257
+ return [];
258
+ }
259
+ const candidate = raw;
260
+ const id = readString(candidate.id);
261
+ const role = candidate.role === 'user' || candidate.role === 'assistant' ? candidate.role : undefined;
262
+ const text = readString(candidate.text);
263
+ if (!id || !role || !text) {
264
+ return [];
265
+ }
266
+ return [{
267
+ id,
268
+ role,
269
+ text,
270
+ isStreaming: readBoolean(candidate.isStreaming),
271
+ isPending: readBoolean(candidate.isPending),
272
+ }];
273
+ }
274
+ function projectChatTurnView(raw) {
275
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
276
+ return [];
277
+ }
278
+ const candidate = raw;
279
+ const id = readString(candidate.id);
280
+ const prompt = readString(candidate.prompt);
281
+ const outcome = readString(candidate.outcome);
282
+ const summary = readString(candidate.summary);
283
+ const traceFile = readString(candidate.traceFile);
284
+ const steps = readNumber(candidate.steps);
285
+ const events = Array.isArray(candidate.events) ? candidate.events.filter((event) => typeof event === 'string') : [];
286
+ if (!id || !prompt || !outcome || !summary || !traceFile || steps === undefined) {
287
+ return [];
288
+ }
289
+ return [{
290
+ id,
291
+ prompt,
292
+ outcome,
293
+ summary,
294
+ steps,
295
+ traceFile,
296
+ events,
297
+ }];
298
+ }
299
+ function loadChatTurnReview(traceFile) {
300
+ if (!traceFile || !existsSync(traceFile)) {
301
+ return undefined;
302
+ }
303
+ try {
304
+ const parsed = JSON.parse(readFileSync(traceFile, 'utf8'));
305
+ if (!Array.isArray(parsed)) {
306
+ return undefined;
307
+ }
308
+ const reviewCommands = [];
309
+ const verificationCommands = [];
310
+ const mutationCommands = [];
311
+ const approvals = [];
312
+ let diffExcerpt;
313
+ let finalSummary;
314
+ for (const entry of parsed) {
315
+ const event = readObject(entry);
316
+ const type = readString(event?.type);
317
+ if (!event || !type) {
318
+ continue;
319
+ }
320
+ if (type === 'tool.result') {
321
+ const tool = readString(event.tool) ?? 'unknown';
322
+ const result = readObject(event.result);
323
+ const output = readObject(result?.output);
324
+ const evidence = output ? projectCommandEvidence(tool, output) : undefined;
325
+ if (!evidence) {
326
+ continue;
327
+ }
328
+ if (isReviewCommand(evidence.command)) {
329
+ reviewCommands.push(evidence);
330
+ if (!diffExcerpt && /^git diff(?:\s|$)/.test(evidence.command) && evidence.stdout) {
331
+ diffExcerpt = evidence.stdout;
332
+ }
333
+ continue;
334
+ }
335
+ if (isVerificationCommand(evidence.command)) {
336
+ verificationCommands.push(evidence);
337
+ continue;
338
+ }
339
+ if (tool === 'run_shell_mutate') {
340
+ mutationCommands.push(evidence);
341
+ }
342
+ continue;
343
+ }
344
+ if (type === 'tool.call') {
345
+ const call = readObject(event.call);
346
+ const tool = readString(call?.tool);
347
+ if (tool !== 'edit_file') {
348
+ continue;
349
+ }
350
+ const input = readObject(call?.input);
351
+ const path = readString(input?.path);
352
+ mutationCommands.push({
353
+ tool,
354
+ command: path ? `edit_file ${path}` : 'edit_file',
355
+ });
356
+ continue;
357
+ }
358
+ if (type === 'tool.approval_resolved') {
359
+ const call = readObject(event.call);
360
+ const tool = readString(call?.tool);
361
+ if (!tool) {
362
+ continue;
363
+ }
364
+ const input = readObject(call?.input);
365
+ approvals.push({
366
+ tool,
367
+ command: readString(input?.command) ?? readString(input?.path),
368
+ approved: readBoolean(event.approved) ?? false,
369
+ reason: readString(event.reason),
370
+ timestamp: readString(event.timestamp),
371
+ });
372
+ continue;
373
+ }
374
+ if (type === 'run.finished') {
375
+ finalSummary = readString(event.summary) ?? finalSummary;
376
+ }
377
+ }
378
+ return {
379
+ traceFile,
380
+ diffExcerpt,
381
+ finalSummary,
382
+ reviewCommands: dedupeEvidence(reviewCommands),
383
+ verificationCommands: dedupeEvidence(verificationCommands),
384
+ mutationCommands: dedupeEvidence(mutationCommands),
385
+ approvals,
386
+ };
387
+ }
388
+ catch {
389
+ return undefined;
390
+ }
391
+ }
392
+ function projectCommandEvidence(tool, output) {
393
+ const command = readString(output.command);
394
+ if (!command) {
395
+ return undefined;
396
+ }
397
+ return {
398
+ tool,
399
+ command,
400
+ exitCode: readNumber(output.exitCode),
401
+ stdout: normalizeCommandText(readString(output.stdout)),
402
+ stderr: normalizeCommandText(readString(output.stderr)),
403
+ };
404
+ }
405
+ function dedupeEvidence(evidence) {
406
+ const seen = new Set();
407
+ return evidence.filter((entry) => {
408
+ const key = `${entry.tool}:${entry.command}`;
409
+ if (seen.has(key)) {
410
+ return false;
411
+ }
412
+ seen.add(key);
413
+ return true;
414
+ });
415
+ }
416
+ function isReviewCommand(command) {
417
+ return /^git (?:status\b|diff\b|show\b|branch\b|remote\b)/.test(command);
418
+ }
419
+ function isVerificationCommand(command) {
420
+ return /^(?:yarn|npm|pnpm|bun|vitest|jest|tsx|tsc|go test|cargo test|pytest|ruff|eslint)\b/.test(command);
421
+ }
422
+ function normalizeCommandText(value) {
423
+ if (!value) {
424
+ return undefined;
425
+ }
426
+ const trimmed = value.trim();
427
+ if (!trimmed) {
428
+ return undefined;
429
+ }
430
+ return trimmed.length > 2400 ? `${trimmed.slice(0, 2399)}…` : trimmed;
431
+ }
54
432
  function readObject(value) {
55
433
  return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
56
434
  }
57
435
  function readString(value) {
58
436
  return typeof value === 'string' ? value : undefined;
59
437
  }
438
+ function readBoolean(value) {
439
+ return typeof value === 'boolean' ? value : undefined;
440
+ }
60
441
  function readNumber(value) {
61
442
  return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
62
443
  }