circuschief 0.1.0

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 (319) hide show
  1. package/package.json +33 -0
  2. package/packages/server/bin/cli.js +4 -0
  3. package/packages/server/src/agents/AgentGateway.js +64 -0
  4. package/packages/server/src/agents/BaseAgent.js +41 -0
  5. package/packages/server/src/agents/LoggingAgentWrapper.js +73 -0
  6. package/packages/server/src/agents/adapters/ClaudeCodeAdapter.js +33 -0
  7. package/packages/server/src/agents/adapters/CodexAdapter.js +26 -0
  8. package/packages/server/src/agents/types.js +43 -0
  9. package/packages/server/src/agents/vcr/CassetteStore.js +111 -0
  10. package/packages/server/src/agents/vcr/VCRAgentAdapter.js +126 -0
  11. package/packages/server/src/agents/vcr/VCRSummaryWrapper.js +71 -0
  12. package/packages/server/src/api/canvas-helpers.js +249 -0
  13. package/packages/server/src/api/canvas-trash-routes.js +205 -0
  14. package/packages/server/src/api/canvas.js +331 -0
  15. package/packages/server/src/api/commandButtons.js +312 -0
  16. package/packages/server/src/api/commands.js +169 -0
  17. package/packages/server/src/api/filesystem.js +62 -0
  18. package/packages/server/src/api/git.js +85 -0
  19. package/packages/server/src/api/index.js +44 -0
  20. package/packages/server/src/api/kanban.js +342 -0
  21. package/packages/server/src/api/metrics.js +194 -0
  22. package/packages/server/src/api/projects-helpers.js +43 -0
  23. package/packages/server/src/api/projects-session-helpers.js +295 -0
  24. package/packages/server/src/api/projects.js +384 -0
  25. package/packages/server/src/api/providers.js +249 -0
  26. package/packages/server/src/api/quickResponses.js +129 -0
  27. package/packages/server/src/api/sessions-archive.js +69 -0
  28. package/packages/server/src/api/sessions-commands.js +220 -0
  29. package/packages/server/src/api/sessions-conversations.js +168 -0
  30. package/packages/server/src/api/sessions-draft.js +72 -0
  31. package/packages/server/src/api/sessions-lifecycle.js +190 -0
  32. package/packages/server/src/api/sessions-messages.js +141 -0
  33. package/packages/server/src/api/sessions-notes.js +51 -0
  34. package/packages/server/src/api/sessions-patch.js +252 -0
  35. package/packages/server/src/api/sessions-streaming.js +86 -0
  36. package/packages/server/src/api/sessions.js +269 -0
  37. package/packages/server/src/api/settings.js +194 -0
  38. package/packages/server/src/api/templates.js +63 -0
  39. package/packages/server/src/app.js +51 -0
  40. package/packages/server/src/database.js +58 -0
  41. package/packages/server/src/db/AgentCallLogRepository.js +322 -0
  42. package/packages/server/src/db/AttachmentRepository.js +191 -0
  43. package/packages/server/src/db/BaseRepository.js +39 -0
  44. package/packages/server/src/db/CanvasItemRepository.js +315 -0
  45. package/packages/server/src/db/CommandButtonRepository.js +75 -0
  46. package/packages/server/src/db/CommandRunRepository.js +219 -0
  47. package/packages/server/src/db/ConversationRepository.js +379 -0
  48. package/packages/server/src/db/DatabaseManager.js +91 -0
  49. package/packages/server/src/db/KanbanBoardRepository.js +92 -0
  50. package/packages/server/src/db/KanbanCardRepository.js +286 -0
  51. package/packages/server/src/db/KanbanLaneRepository.js +279 -0
  52. package/packages/server/src/db/MessageRepository.js +156 -0
  53. package/packages/server/src/db/ProjectDefaultsRepository.js +173 -0
  54. package/packages/server/src/db/ProjectRepository.js +110 -0
  55. package/packages/server/src/db/ProviderRepository.js +307 -0
  56. package/packages/server/src/db/QuickResponseRepository.js +186 -0
  57. package/packages/server/src/db/SessionNoteRepository.js +60 -0
  58. package/packages/server/src/db/SessionRepository.js +314 -0
  59. package/packages/server/src/db/SessionSummaryRepository.js +200 -0
  60. package/packages/server/src/db/SessionTemplateRepository.js +171 -0
  61. package/packages/server/src/db/SettingsRepository.js +211 -0
  62. package/packages/server/src/db/TodoRepository.js +132 -0
  63. package/packages/server/src/db/WorkLogRepository.js +122 -0
  64. package/packages/server/src/db/conversation-helpers.js +119 -0
  65. package/packages/server/src/db/index.js +100 -0
  66. package/packages/server/src/db/migrations/canvasItemsMigrations.js +109 -0
  67. package/packages/server/src/db/migrations/conversationsMigrations.js +183 -0
  68. package/packages/server/src/db/migrations/index.js +199 -0
  69. package/packages/server/src/db/migrations/kanbanMigrations.js +99 -0
  70. package/packages/server/src/db/migrations/migrationUtils.js +55 -0
  71. package/packages/server/src/db/migrations/miscMigrations.js +242 -0
  72. package/packages/server/src/db/migrations/projectsMigrations.js +95 -0
  73. package/packages/server/src/db/migrations/sessionsMigrations.js +282 -0
  74. package/packages/server/src/db/session-helpers.js +150 -0
  75. package/packages/server/src/index.js +106 -0
  76. package/packages/server/src/logger.js +22 -0
  77. package/packages/server/src/middleware/sessionLookup.js +57 -0
  78. package/packages/server/src/middleware/upload.js +94 -0
  79. package/packages/server/src/schema.sql +363 -0
  80. package/packages/server/src/services/agentCallLogger.js +116 -0
  81. package/packages/server/src/services/canvasStore.js +56 -0
  82. package/packages/server/src/services/childSessionContext.js +61 -0
  83. package/packages/server/src/services/commandRunner.js +422 -0
  84. package/packages/server/src/services/conversationContext.js +72 -0
  85. package/packages/server/src/services/diffService.js +172 -0
  86. package/packages/server/src/services/draftSessionService.js +181 -0
  87. package/packages/server/src/services/encryption.js +134 -0
  88. package/packages/server/src/services/ghService.js +169 -0
  89. package/packages/server/src/services/gitService.js +520 -0
  90. package/packages/server/src/services/gitSessionSetup.js +48 -0
  91. package/packages/server/src/services/hookService.js +60 -0
  92. package/packages/server/src/services/kanbanService.js +262 -0
  93. package/packages/server/src/services/kanbanTriggers.js +273 -0
  94. package/packages/server/src/services/nodeSpawnHelper.js +63 -0
  95. package/packages/server/src/services/prStatusService.js +204 -0
  96. package/packages/server/src/services/prUrlService.js +224 -0
  97. package/packages/server/src/services/providerTestService.js +81 -0
  98. package/packages/server/src/services/scheduleService.js +110 -0
  99. package/packages/server/src/services/schedulerService.js +281 -0
  100. package/packages/server/src/services/sessionDuplicator.js +63 -0
  101. package/packages/server/src/services/sessionErrors.js +173 -0
  102. package/packages/server/src/services/sessionExecution.js +378 -0
  103. package/packages/server/src/services/sessionManager.js +356 -0
  104. package/packages/server/src/services/sessionPrompts.js +427 -0
  105. package/packages/server/src/services/sessionProvider.js +107 -0
  106. package/packages/server/src/services/slashCommandDiscovery.js +258 -0
  107. package/packages/server/src/services/slashCommandPluginDiscovery.js +216 -0
  108. package/packages/server/src/services/slashCommandService.js +306 -0
  109. package/packages/server/src/services/streamEventCallbacks.js +170 -0
  110. package/packages/server/src/services/streamEventHandler.js +488 -0
  111. package/packages/server/src/services/streamUsageHandler.js +228 -0
  112. package/packages/server/src/services/summaryBroadcast.js +61 -0
  113. package/packages/server/src/services/summaryClaudeClient.js +180 -0
  114. package/packages/server/src/services/summaryPrompts.js +169 -0
  115. package/packages/server/src/services/summaryService.js +552 -0
  116. package/packages/server/src/services/summaryStaleCheck.js +35 -0
  117. package/packages/server/src/services/systemMonitor.js +281 -0
  118. package/packages/server/src/services/templateTriggerService.js +197 -0
  119. package/packages/server/src/services/terminalOutput.js +160 -0
  120. package/packages/server/src/services/todoStore.js +58 -0
  121. package/packages/server/src/services/usageTracker.js +69 -0
  122. package/packages/server/src/services/withConcurrencyGuard.js +110 -0
  123. package/packages/server/src/websocket.js +10 -0
  124. package/packages/server/src/ws/WebSocketManager.js +240 -0
  125. package/packages/server/src/ws/index.js +50 -0
  126. package/packages/shared/package.json +27 -0
  127. package/packages/shared/src/constants.js +44 -0
  128. package/packages/shared/src/contracts/canvas.js +25 -0
  129. package/packages/shared/src/contracts/commandButtons.js +36 -0
  130. package/packages/shared/src/contracts/kanban.js +142 -0
  131. package/packages/shared/src/contracts/projects.js +63 -0
  132. package/packages/shared/src/contracts/providers.js +81 -0
  133. package/packages/shared/src/contracts/quickResponses.js +44 -0
  134. package/packages/shared/src/contracts/sessions.js +112 -0
  135. package/packages/shared/src/contracts/templates.js +51 -0
  136. package/packages/shared/src/index.js +5 -0
  137. package/packages/shared/src/protocol.js +76 -0
  138. package/packages/shared/src/routeParams.js +36 -0
  139. package/packages/shared/src/types.js +167 -0
  140. package/packages/shared/src/utils.js +101 -0
  141. package/packages/web/dist/assets/ActiveSessionsView-BQc76Jc8.js +1 -0
  142. package/packages/web/dist/assets/ActiveSessionsView-ofSvx-K1.css +1 -0
  143. package/packages/web/dist/assets/AgentLogsView-CTCjHjsu.js +2 -0
  144. package/packages/web/dist/assets/AgentLogsView-D90PnQVk.css +1 -0
  145. package/packages/web/dist/assets/ApiClient-Dbs1H78V.js +1 -0
  146. package/packages/web/dist/assets/ArchiveConfirmModal-CCxSZ52u.js +1 -0
  147. package/packages/web/dist/assets/ArchiveConfirmModal-CQZeuYBz.css +1 -0
  148. package/packages/web/dist/assets/CommandButtonDetailView-CF_-LXpU.js +1 -0
  149. package/packages/web/dist/assets/CommandButtonDetailView-DBm3rzhw.css +1 -0
  150. package/packages/web/dist/assets/EffortLevelSelector-BQaQmU2d.css +1 -0
  151. package/packages/web/dist/assets/EffortLevelSelector-DPofLvm-.js +1 -0
  152. package/packages/web/dist/assets/GeneralSettingsView-BCf53fpC.css +1 -0
  153. package/packages/web/dist/assets/GeneralSettingsView-BY1G-Kv8.js +1 -0
  154. package/packages/web/dist/assets/InterpolationHelp-CgdbNcJB.js +1 -0
  155. package/packages/web/dist/assets/InterpolationHelp-iNxTxmhs.css +1 -0
  156. package/packages/web/dist/assets/MarkdownEditor-CqT1U8lo.js +2 -0
  157. package/packages/web/dist/assets/MarkdownEditor-enuH2yvP.css +1 -0
  158. package/packages/web/dist/assets/ModelSelector-BBn_Ve0D.js +1 -0
  159. package/packages/web/dist/assets/ModelSelector-DPPD-92R.css +1 -0
  160. package/packages/web/dist/assets/NewSessionView-Bo5l49nu.js +3 -0
  161. package/packages/web/dist/assets/NewSessionView-Byoi1XdQ.css +1 -0
  162. package/packages/web/dist/assets/PathChooser-BoMGzeg2.css +1 -0
  163. package/packages/web/dist/assets/PathChooser-Cx9gQ-Qt.js +1 -0
  164. package/packages/web/dist/assets/ProjectEditView-BFuscj-V.js +1 -0
  165. package/packages/web/dist/assets/ProjectEditView-DNwBUNRk.css +1 -0
  166. package/packages/web/dist/assets/ProjectListView-C55H1JHQ.css +1 -0
  167. package/packages/web/dist/assets/ProjectListView-Dj0jBZ46.js +1 -0
  168. package/packages/web/dist/assets/ProjectNewView-Brdp-xUu.js +1 -0
  169. package/packages/web/dist/assets/ProjectNewView-CpgE4R-l.css +1 -0
  170. package/packages/web/dist/assets/ProvidersView-B_QQF3RM.css +1 -0
  171. package/packages/web/dist/assets/ProvidersView-Cxc-1skq.js +1 -0
  172. package/packages/web/dist/assets/QuickResponseSettings-B2eVAtHW.js +1 -0
  173. package/packages/web/dist/assets/QuickResponseSettings-B8188A1D.css +1 -0
  174. package/packages/web/dist/assets/QuickResponsesPanel-DIBQFj0W.css +1 -0
  175. package/packages/web/dist/assets/QuickResponsesPanel-lU8pW2B0.js +1 -0
  176. package/packages/web/dist/assets/ResizableTextarea-B5nAA0RV.css +1 -0
  177. package/packages/web/dist/assets/ResizableTextarea-DSy1mWGY.js +1 -0
  178. package/packages/web/dist/assets/SessionCard-BvjLwVYg.js +1 -0
  179. package/packages/web/dist/assets/SessionCard-D20G3bX8.css +1 -0
  180. package/packages/web/dist/assets/SessionDetailView-BQbPg-RJ.js +36 -0
  181. package/packages/web/dist/assets/SessionDetailView-BrMG4p2-.css +1 -0
  182. package/packages/web/dist/assets/SessionFormOptions-BgqFR-5f.js +1 -0
  183. package/packages/web/dist/assets/SessionFormOptions-BuLlDF-7.css +1 -0
  184. package/packages/web/dist/assets/SessionListView-BAIBtJF7.css +1 -0
  185. package/packages/web/dist/assets/SessionListView-CYIHI8qF.js +1 -0
  186. package/packages/web/dist/assets/SessionLogStream-B-FwUMJQ.js +18 -0
  187. package/packages/web/dist/assets/SessionLogStream-zPUTiGbe.css +1 -0
  188. package/packages/web/dist/assets/SettingsView-DC8-hTQ-.css +1 -0
  189. package/packages/web/dist/assets/SettingsView-fZxpiGp7.js +1 -0
  190. package/packages/web/dist/assets/SlashCommandWizard-BB30cSvo.css +1 -0
  191. package/packages/web/dist/assets/SlashCommandWizard-BgaOw9W3.js +1 -0
  192. package/packages/web/dist/assets/SummarySettingsView-DcsmSVJI.css +1 -0
  193. package/packages/web/dist/assets/SummarySettingsView-eeu1Xq86.js +1 -0
  194. package/packages/web/dist/assets/TemplateDetailView-DEPKSwDo.js +1 -0
  195. package/packages/web/dist/assets/TemplateDetailView-DT2m06W7.css +1 -0
  196. package/packages/web/dist/assets/apl-B4CMkyY2.js +1 -0
  197. package/packages/web/dist/assets/asciiarmor-Df11BRmG.js +1 -0
  198. package/packages/web/dist/assets/asn1-EdZsLKOL.js +1 -0
  199. package/packages/web/dist/assets/asterisk-B-8jnY81.js +1 -0
  200. package/packages/web/dist/assets/brainfuck-C4LP7Hcl.js +1 -0
  201. package/packages/web/dist/assets/clike-B9uivgTg.js +1 -0
  202. package/packages/web/dist/assets/clojure-BMjYHr_A.js +1 -0
  203. package/packages/web/dist/assets/cmake-BQqOBYOt.js +1 -0
  204. package/packages/web/dist/assets/cobol-CWcv1MsR.js +1 -0
  205. package/packages/web/dist/assets/coffeescript-S37ZYGWr.js +1 -0
  206. package/packages/web/dist/assets/commandButtons-DNSHH8IA.js +4 -0
  207. package/packages/web/dist/assets/commonlisp-DBKNyK5s.js +1 -0
  208. package/packages/web/dist/assets/crystal-SjHAIU92.js +1 -0
  209. package/packages/web/dist/assets/css-BnMrqG3P.js +1 -0
  210. package/packages/web/dist/assets/cypher-C_CwsFkJ.js +1 -0
  211. package/packages/web/dist/assets/d-pRatUO7H.js +1 -0
  212. package/packages/web/dist/assets/diff-DbItnlRl.js +1 -0
  213. package/packages/web/dist/assets/dockerfile-BKs6k2Af.js +1 -0
  214. package/packages/web/dist/assets/dtd-DF_7sFjM.js +1 -0
  215. package/packages/web/dist/assets/dylan-DwRh75JA.js +1 -0
  216. package/packages/web/dist/assets/ebnf-CDyGwa7X.js +1 -0
  217. package/packages/web/dist/assets/ecl-Cabwm37j.js +1 -0
  218. package/packages/web/dist/assets/eiffel-CnydiIhH.js +1 -0
  219. package/packages/web/dist/assets/elm-vLlmbW-K.js +1 -0
  220. package/packages/web/dist/assets/erlang-BNw1qcRV.js +1 -0
  221. package/packages/web/dist/assets/factor-kuTfRLto.js +1 -0
  222. package/packages/web/dist/assets/fcl-Kvtd6kyn.js +1 -0
  223. package/packages/web/dist/assets/forth-Ffai-XNe.js +1 -0
  224. package/packages/web/dist/assets/fortran-DYz_wnZ1.js +1 -0
  225. package/packages/web/dist/assets/gas-Bneqetm1.js +1 -0
  226. package/packages/web/dist/assets/gherkin-heZmZLOM.js +1 -0
  227. package/packages/web/dist/assets/groovy-D9Dt4D0W.js +1 -0
  228. package/packages/web/dist/assets/haskell-BWDZoCOh.js +1 -0
  229. package/packages/web/dist/assets/haxe-H-WmDvRZ.js +1 -0
  230. package/packages/web/dist/assets/http-DBlCnlav.js +1 -0
  231. package/packages/web/dist/assets/idl-BEugSyMb.js +1 -0
  232. package/packages/web/dist/assets/index-BZlHgDSz.js +1 -0
  233. package/packages/web/dist/assets/index-BhWX8AfE.js +2 -0
  234. package/packages/web/dist/assets/index-Bi3XvF_f.js +1 -0
  235. package/packages/web/dist/assets/index-BqXoPf_D.js +1 -0
  236. package/packages/web/dist/assets/index-CAuTOZSD.js +1 -0
  237. package/packages/web/dist/assets/index-CKYk-fkb.js +1 -0
  238. package/packages/web/dist/assets/index-CTumW_tV.js +318 -0
  239. package/packages/web/dist/assets/index-CVOJVSsC.js +82 -0
  240. package/packages/web/dist/assets/index-CXK2Z3_z.js +1 -0
  241. package/packages/web/dist/assets/index-CYllQ3Vd.js +1 -0
  242. package/packages/web/dist/assets/index-CpsfI08O.js +1 -0
  243. package/packages/web/dist/assets/index-DQkhDeTA.js +3 -0
  244. package/packages/web/dist/assets/index-DWP8iCBp.js +1 -0
  245. package/packages/web/dist/assets/index-DkVb9W_J.js +1 -0
  246. package/packages/web/dist/assets/index-DmKHPbIa.js +1 -0
  247. package/packages/web/dist/assets/index-DrlQi03X.js +1 -0
  248. package/packages/web/dist/assets/index-gmCCsCQ1.css +1 -0
  249. package/packages/web/dist/assets/index-prTEzzgO.js +1 -0
  250. package/packages/web/dist/assets/index-wqgejMCM.js +1 -0
  251. package/packages/web/dist/assets/index-yh0ZHIWw.js +7 -0
  252. package/packages/web/dist/assets/javascript-qCveANmP.js +1 -0
  253. package/packages/web/dist/assets/julia-DuME0IfC.js +1 -0
  254. package/packages/web/dist/assets/livescript-BwQOo05w.js +1 -0
  255. package/packages/web/dist/assets/lua-BgMRiT3U.js +1 -0
  256. package/packages/web/dist/assets/mathematica-DTrFuWx2.js +1 -0
  257. package/packages/web/dist/assets/mbox-CNhZ1qSd.js +1 -0
  258. package/packages/web/dist/assets/mirc-CjQqDB4T.js +1 -0
  259. package/packages/web/dist/assets/mllike-CXdrOF99.js +1 -0
  260. package/packages/web/dist/assets/modelica-Dc1JOy9r.js +1 -0
  261. package/packages/web/dist/assets/mscgen-BA5vi2Kp.js +1 -0
  262. package/packages/web/dist/assets/mumps-BT43cFF4.js +1 -0
  263. package/packages/web/dist/assets/nginx-DdIZxoE0.js +1 -0
  264. package/packages/web/dist/assets/nsis-LdVXkNf5.js +1 -0
  265. package/packages/web/dist/assets/ntriples-BfvgReVJ.js +1 -0
  266. package/packages/web/dist/assets/octave-Ck1zUtKM.js +1 -0
  267. package/packages/web/dist/assets/oz-BzwKVEFT.js +1 -0
  268. package/packages/web/dist/assets/pascal--L3eBynH.js +1 -0
  269. package/packages/web/dist/assets/perl-CdXCOZ3F.js +1 -0
  270. package/packages/web/dist/assets/pig-CevX1Tat.js +1 -0
  271. package/packages/web/dist/assets/powershell-CFHJl5sT.js +1 -0
  272. package/packages/web/dist/assets/projects-DbBQQH-V.js +1 -0
  273. package/packages/web/dist/assets/properties-C78fOPTZ.js +1 -0
  274. package/packages/web/dist/assets/protobuf-ChK-085T.js +1 -0
  275. package/packages/web/dist/assets/providers-ceCc4xRU.js +1 -0
  276. package/packages/web/dist/assets/pug-DukmZTjD.js +1 -0
  277. package/packages/web/dist/assets/puppet-DMA9R1ak.js +1 -0
  278. package/packages/web/dist/assets/python-BuPzkPfP.js +1 -0
  279. package/packages/web/dist/assets/q-pXgVlZs6.js +1 -0
  280. package/packages/web/dist/assets/r-DUYO_cvP.js +1 -0
  281. package/packages/web/dist/assets/rpm-CTu-6PCP.js +1 -0
  282. package/packages/web/dist/assets/ruby-B2Rjki9n.js +1 -0
  283. package/packages/web/dist/assets/sas-B4kiWyti.js +1 -0
  284. package/packages/web/dist/assets/scheme-C41bIUwD.js +1 -0
  285. package/packages/web/dist/assets/sessions-D681M81k.js +1 -0
  286. package/packages/web/dist/assets/settings-D0evez2V.js +1 -0
  287. package/packages/web/dist/assets/shell-CjFT_Tl9.js +1 -0
  288. package/packages/web/dist/assets/sieve-C3Gn_uJK.js +1 -0
  289. package/packages/web/dist/assets/simple-mode-GW_nhZxv.js +1 -0
  290. package/packages/web/dist/assets/smalltalk-CnHTOXQT.js +1 -0
  291. package/packages/web/dist/assets/solr-DehyRSwq.js +1 -0
  292. package/packages/web/dist/assets/sparql-DkYu6x3z.js +1 -0
  293. package/packages/web/dist/assets/spreadsheet-BCZA_wO0.js +1 -0
  294. package/packages/web/dist/assets/sql-D0XecflT.js +1 -0
  295. package/packages/web/dist/assets/stex-C3f8Ysf7.js +1 -0
  296. package/packages/web/dist/assets/style-BTin-zR_.css +1 -0
  297. package/packages/web/dist/assets/stylus-B533Al4x.js +1 -0
  298. package/packages/web/dist/assets/swift-BzpIVaGY.js +1 -0
  299. package/packages/web/dist/assets/tcl-DVfN8rqt.js +1 -0
  300. package/packages/web/dist/assets/textile-CnDTJFAw.js +1 -0
  301. package/packages/web/dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  302. package/packages/web/dist/assets/tiki-DGYXhP31.js +1 -0
  303. package/packages/web/dist/assets/toml-Bm5Em-hy.js +1 -0
  304. package/packages/web/dist/assets/troff-wAsdV37c.js +1 -0
  305. package/packages/web/dist/assets/ttcn-CfJYG6tj.js +1 -0
  306. package/packages/web/dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  307. package/packages/web/dist/assets/turtle-B1tBg_DP.js +1 -0
  308. package/packages/web/dist/assets/vb-CmGdzxic.js +1 -0
  309. package/packages/web/dist/assets/vbscript-BuJXcnF6.js +1 -0
  310. package/packages/web/dist/assets/velocity-D8B20fx6.js +1 -0
  311. package/packages/web/dist/assets/verilog-C6RDOZhf.js +1 -0
  312. package/packages/web/dist/assets/vhdl-lSbBsy5d.js +1 -0
  313. package/packages/web/dist/assets/webidl-ZXfAyPTL.js +1 -0
  314. package/packages/web/dist/assets/xquery-CQfU5ijd.js +1 -0
  315. package/packages/web/dist/assets/yacas-BJ4BC0dw.js +1 -0
  316. package/packages/web/dist/assets/z80-Hz9HOZM7.js +1 -0
  317. package/packages/web/dist/favicon.png +0 -0
  318. package/packages/web/dist/index.html +17 -0
  319. package/packages/web/dist/logo.png +0 -0
@@ -0,0 +1,194 @@
1
+ import { Router } from 'express';
2
+ import { agentCallLogger } from '../services/agentCallLogger.js';
3
+ import { agentCallLogs } from '../database.js';
4
+ import { databaseManager } from '../db/DatabaseManager.js';
5
+
6
+ const router = Router();
7
+
8
+ /**
9
+ * Resolve metadata to a JSON string. Uses provided metadata or derives from session effortLevel.
10
+ */
11
+ function resolveMetadataJson(providedMetadata, sessionId) {
12
+ let metadata = providedMetadata || {};
13
+ if (!providedMetadata) {
14
+ const session = agentCallLogs.db
15
+ .prepare('SELECT effort_level FROM sessions WHERE id = ?')
16
+ .get(sessionId);
17
+ if (session && session.effort_level) {
18
+ metadata = { effortLevel: session.effort_level };
19
+ }
20
+ }
21
+ return Object.keys(metadata).length > 0 ? JSON.stringify(metadata) : null;
22
+ }
23
+
24
+ // GET /api/sessions/:sessionId/agent-stats
25
+ // Returns aggregated stats for a session grouped by call_type
26
+ router.get('/sessions/:sessionId/agent-stats', (req, res) => {
27
+ const stats = agentCallLogger.getSessionStats(req.params.sessionId);
28
+ res.json(stats);
29
+ });
30
+
31
+ // GET /api/sessions/:sessionId/agent-calls?limit=100&offset=0
32
+ // Returns detailed call log entries for a session
33
+ router.get('/sessions/:sessionId/agent-calls', (req, res) => {
34
+ const { limit = 100, offset = 0 } = req.query;
35
+ const calls = agentCallLogs.getBySessionId(req.params.sessionId, {
36
+ limit: parseInt(limit),
37
+ offset: parseInt(offset),
38
+ });
39
+ res.json(calls);
40
+ });
41
+
42
+ // GET /api/agent-stats?startDate=...&endDate=...
43
+ // Returns global stats grouped by agent_type and call_type
44
+ router.get('/agent-stats', (req, res) => {
45
+ const now = Date.now();
46
+ const start = req.query.startDate
47
+ ? parseInt(req.query.startDate)
48
+ : now - 7 * 24 * 60 * 60 * 1000;
49
+ const end = req.query.endDate ? parseInt(req.query.endDate) : now;
50
+ const stats = agentCallLogger.getGlobalStats(start, end);
51
+ res.json(stats);
52
+ });
53
+
54
+ // GET /api/agent-calls/filter-options
55
+ // Returns distinct values for filter dropdowns
56
+ router.get('/agent-calls/filter-options', (req, res) => {
57
+ try {
58
+ const options = agentCallLogger.getFilterOptions();
59
+ res.json(options);
60
+ } catch (err) {
61
+ console.error('Failed to get filter options:', err);
62
+ res.status(500).json({ error: 'Failed to get filter options' });
63
+ }
64
+ });
65
+
66
+ // GET /api/agent-calls?limit=25&offset=0&agentType=...&callType=...&status=...&model=...&sessionId=...&startDate=...&endDate=...&sortBy=...&sortOrder=...
67
+ // Returns paginated call logs with optional filters
68
+ router.get('/agent-calls', (req, res) => {
69
+ try {
70
+ const limit = req.query.limit ? parseInt(req.query.limit) : 25;
71
+ const offset = req.query.offset ? parseInt(req.query.offset) : 0;
72
+ const startDate = req.query.startDate ? parseInt(req.query.startDate) : undefined;
73
+ const endDate = req.query.endDate ? parseInt(req.query.endDate) : undefined;
74
+
75
+ const result = agentCallLogger.getAll({
76
+ limit,
77
+ offset,
78
+ agentType: req.query.agentType,
79
+ callType: req.query.callType,
80
+ status: req.query.status,
81
+ model: req.query.model,
82
+ sessionId: req.query.sessionId,
83
+ startDate,
84
+ endDate,
85
+ sortBy: req.query.sortBy,
86
+ sortOrder: req.query.sortOrder,
87
+ });
88
+
89
+ res.json({
90
+ logs: result.rows,
91
+ pagination: {
92
+ total: result.total,
93
+ limit,
94
+ offset,
95
+ hasMore: offset + limit < result.total,
96
+ },
97
+ });
98
+ } catch (err) {
99
+ console.error('Failed to get agent call logs:', err);
100
+ res.status(500).json({ error: 'Failed to get agent call logs' });
101
+ }
102
+ });
103
+
104
+ // POST /api/agent-calls
105
+ // Seed a fully-formed agent call log entry (for E2E testing only).
106
+ // Accepts all fields directly, including computed ones (totalTokens, durationMs).
107
+ router.post('/agent-calls', (req, res) => {
108
+ try {
109
+ const {
110
+ sessionId,
111
+ agentType = 'claude-code',
112
+ callType = 'runSession',
113
+ model = null,
114
+ status = 'completed',
115
+ inputTokens = 0,
116
+ outputTokens = 0,
117
+ thinkingTokens = 0,
118
+ cacheReadTokens = 0,
119
+ cacheWriteTokens = 0,
120
+ durationMs = null,
121
+ startedAt = null,
122
+ errorMessage = null,
123
+ metadata: providedMetadata,
124
+ } = req.body;
125
+
126
+ if (!sessionId) {
127
+ return res.status(400).json({ error: 'sessionId is required' });
128
+ }
129
+
130
+ const metadataJson = resolveMetadataJson(providedMetadata, sessionId);
131
+
132
+ const id = databaseManager.generateId();
133
+ const now = Date.now();
134
+ const finalStartedAt = startedAt ?? now;
135
+ const completedAt =
136
+ status === 'completed' || status === 'error'
137
+ ? durationMs != null
138
+ ? finalStartedAt + durationMs
139
+ : now
140
+ : null;
141
+ const totalTokens =
142
+ inputTokens + outputTokens + thinkingTokens + cacheReadTokens + cacheWriteTokens;
143
+ const finalDurationMs = completedAt != null ? completedAt - finalStartedAt : null;
144
+
145
+ // Direct INSERT — bypasses create()/complete() flow to allow full control over all fields,
146
+ // including computed ones like totalTokens, durationMs, and startedAt.
147
+ const db = agentCallLogs.db;
148
+ db.prepare(`
149
+ INSERT INTO agent_call_logs (
150
+ id, session_id, agent_type, model, call_type, prompt_length,
151
+ input_tokens, output_tokens, thinking_tokens, cache_read_tokens, cache_write_tokens,
152
+ total_tokens, started_at, completed_at, duration_ms, status, error_message, metadata, created_at
153
+ ) VALUES (?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
154
+ `).run(
155
+ id,
156
+ sessionId,
157
+ agentType,
158
+ model,
159
+ callType,
160
+ inputTokens,
161
+ outputTokens,
162
+ thinkingTokens,
163
+ cacheReadTokens,
164
+ cacheWriteTokens,
165
+ totalTokens,
166
+ finalStartedAt,
167
+ completedAt,
168
+ finalDurationMs,
169
+ status,
170
+ errorMessage,
171
+ metadataJson,
172
+ now
173
+ );
174
+
175
+ res.status(201).json(agentCallLogs.getById(id));
176
+ } catch (err) {
177
+ console.error('Failed to seed agent call log:', err);
178
+ res.status(500).json({ error: err.message });
179
+ }
180
+ });
181
+
182
+ // DELETE /api/agent-calls
183
+ // Deletes all agent call logs from the database and clears the in-memory active calls map
184
+ router.delete('/agent-calls', (req, res) => {
185
+ try {
186
+ const deleted = agentCallLogger.deleteAllLogs();
187
+ res.json({ success: true, deleted });
188
+ } catch (err) {
189
+ console.error('Failed to delete agent call logs:', err);
190
+ res.status(500).json({ error: 'Failed to delete agent call logs' });
191
+ }
192
+ });
193
+
194
+ export default router;
@@ -0,0 +1,43 @@
1
+ import { isGitRepo } from '../services/gitService.js';
2
+
3
+ /**
4
+ * Validate that git projects have required gitMode and gitBranch settings.
5
+ * @param {Object} config - The session configuration
6
+ * @param {Object} project - The project object
7
+ * @returns {Promise<string|null>} Error message if validation fails, null otherwise.
8
+ */
9
+ export async function validateGitSettings(config, project) {
10
+ if (!config.gitMode || !config.gitBranch) {
11
+ const isGit = await isGitRepo(project.workingDirectory);
12
+ if (isGit) {
13
+ return 'Git projects require both gitMode and gitBranch. Set project defaults or provide them per-session.';
14
+ }
15
+ }
16
+ return null;
17
+ }
18
+
19
+ /**
20
+ * Build a merged index of latest command runs per session.
21
+ * Running commands from memory take precedence over completed DB runs.
22
+ * @param {Array} dbRuns - Completed runs from the database
23
+ * @param {Array} runningRuns - Currently running commands from memory
24
+ * @returns {Object} sessionId -> { buttonId -> run }
25
+ */
26
+ export function buildRunsBySession(dbRuns, runningRuns) {
27
+ const runsBySession = {};
28
+ for (const run of dbRuns) {
29
+ if (!runsBySession[run.sessionId]) runsBySession[run.sessionId] = {};
30
+ runsBySession[run.sessionId][run.buttonId] = {
31
+ buttonId: run.buttonId, status: run.status, exitCode: run.exitCode,
32
+ runId: run.id, startedAt: run.startedAt, completedAt: run.completedAt,
33
+ };
34
+ }
35
+ for (const run of runningRuns) {
36
+ if (!runsBySession[run.sessionId]) runsBySession[run.sessionId] = {};
37
+ runsBySession[run.sessionId][run.buttonId] = {
38
+ buttonId: run.buttonId, status: 'running', exitCode: null,
39
+ runId: run.runId, startedAt: run.startedAt,
40
+ };
41
+ }
42
+ return runsBySession;
43
+ }
@@ -0,0 +1,295 @@
1
+ import { sessions, sessionTemplates, attachments } from '../database.js';
2
+ import * as slashCommandService from '../services/slashCommandService.js';
3
+ import { setupGitForSession } from '../services/gitSessionSetup.js';
4
+ import { executeHookAsync } from '../services/hookService.js';
5
+ import { broadcastToProject } from '../websocket.js';
6
+ import { WS_MESSAGE_TYPES } from '../../../shared/src/index.js';
7
+
8
+ /**
9
+ * Generate an initial session name from the prompt
10
+ * This will be replaced by a better name when the summary is generated
11
+ * @param {string} prompt - The user's initial prompt
12
+ * @returns {string} A truncated version of the prompt (max 50 chars)
13
+ */
14
+ export function generateInitialName(prompt) {
15
+ const cleaned = prompt.trim().replace(/\s+/g, ' ');
16
+ if (cleaned.length <= 50) return cleaned;
17
+ const truncated = cleaned.substring(0, 50);
18
+ const lastSpace = truncated.lastIndexOf(' ');
19
+ return `${lastSpace > 20 ? truncated.substring(0, lastSpace) : truncated }...`;
20
+ }
21
+
22
+ /**
23
+ * Parse a boolean-like value from a request body field.
24
+ * Handles true, false, 'true', 'false', and undefined/null.
25
+ * @param {*} value - The raw value from request body
26
+ * @returns {{ explicit: boolean, provided: boolean }} parsed result
27
+ */
28
+ export function parseBooleanField(value) {
29
+ if (value === true || value === 'true') return { explicit: true, provided: true };
30
+ if (value === false || value === 'false') return { explicit: false, provided: true };
31
+ return { explicit: undefined, provided: false };
32
+ }
33
+
34
+ /**
35
+ * Resolve a value with cascading defaults: explicit > project default > system default
36
+ * @param {*} explicit - Explicitly provided value
37
+ * @param {*} projectDefault - Project-level default
38
+ * @param {*} systemDefault - System-level default
39
+ * @returns {*} The resolved value
40
+ */
41
+ export function resolveDefault(explicit, projectDefault, systemDefault) {
42
+ if (explicit) return explicit;
43
+ if (projectDefault) return projectDefault;
44
+ return systemDefault;
45
+ }
46
+
47
+ /**
48
+ * Resolve thinkingEnabled with special boolean handling.
49
+ * @param {object} body - Request body
50
+ * @param {object|null} projectDefs - Project defaults
51
+ * @param {object} systemDefaults - System defaults
52
+ * @returns {boolean}
53
+ */
54
+ export function resolveThinkingEnabled(body, projectDefs, systemDefaults) {
55
+ const thinkingParsed = parseBooleanField(body.thinkingEnabled);
56
+ if (thinkingParsed.provided) {
57
+ return thinkingParsed.explicit;
58
+ }
59
+ if (projectDefs?.thinkingEnabled !== undefined && projectDefs?.thinkingEnabled !== null) {
60
+ return projectDefs.thinkingEnabled;
61
+ }
62
+ return systemDefaults.thinkingEnabled;
63
+ }
64
+
65
+ /**
66
+ * Parse scheduling fields from request body.
67
+ * @param {object} body - Request body
68
+ * @returns {object} Scheduling configuration
69
+ */
70
+ export function parseSchedulingConfig(body) {
71
+ return {
72
+ scheduledAt: body.scheduledAt ? parseInt(body.scheduledAt, 10) : undefined,
73
+ autoRescheduleEnabled: body.autoRescheduleEnabled === true || body.autoRescheduleEnabled === 'true',
74
+ rescheduleDelayMinutes: body.rescheduleDelayMinutes ? parseInt(body.rescheduleDelayMinutes, 10) : 15,
75
+ rescheduleOnTokenLimit: body.rescheduleOnTokenLimit !== false && body.rescheduleOnTokenLimit !== 'false',
76
+ rescheduleOnServiceError: body.rescheduleOnServiceError !== false && body.rescheduleOnServiceError !== 'false',
77
+ maxRescheduleCount: body.maxRescheduleCount ? parseInt(body.maxRescheduleCount, 10) : null,
78
+ maxTotalTokens: body.maxTotalTokens ? parseInt(body.maxTotalTokens, 10) : null,
79
+ rescheduleAtTokenCount: body.rescheduleAtTokenCount ? parseInt(body.rescheduleAtTokenCount, 10) : null,
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Resolve startImmediately with special boolean handling.
85
+ * Default is true unless overridden by project/system defaults.
86
+ * @param {object} body - Request body
87
+ * @param {object|null} projectDefs - Project defaults
88
+ * @param {object} systemDefaults - System defaults
89
+ * @returns {boolean}
90
+ */
91
+ export function resolveStartImmediately(body, projectDefs, systemDefaults) {
92
+ let startImmediately = body.startImmediately !== false && body.startImmediately !== 'false';
93
+ if (body.startImmediately === undefined || body.startImmediately === null) {
94
+ if (projectDefs?.startImmediately !== undefined && projectDefs?.startImmediately !== null) {
95
+ startImmediately = projectDefs.startImmediately;
96
+ } else {
97
+ startImmediately = systemDefaults.startImmediately;
98
+ }
99
+ }
100
+ return startImmediately;
101
+ }
102
+
103
+ /**
104
+ * Build session configuration from request body, project defaults, and system defaults.
105
+ * @param {object} body - The request body
106
+ * @param {object|null} projectDefs - Project-level defaults
107
+ * @param {object} systemDefaults - System-level defaults
108
+ * @returns {object} Session configuration
109
+ */
110
+ export function prepareSessionConfig(body, projectDefs, systemDefaults) {
111
+ let effortLevel = resolveDefault(body.effortLevel || null, projectDefs?.effortLevel, systemDefaults.effortLevel);
112
+ // Normalize 'auto' to null
113
+ if (effortLevel === 'auto') {
114
+ effortLevel = null;
115
+ }
116
+
117
+ return {
118
+ prompt: body.prompt,
119
+ name: body.name,
120
+ mode: resolveDefault(body.mode, projectDefs?.mode, systemDefaults.mode),
121
+ model: resolveDefault(body.model, projectDefs?.model, systemDefaults.model || null),
122
+ effortLevel,
123
+ gitBranch: resolveDefault(body.gitBranch, projectDefs?.gitBranch, null),
124
+ gitMode: resolveDefault(body.gitMode, projectDefs?.gitMode, null),
125
+ templateId: body.templateId,
126
+ parentSessionId: body.parentSessionId || null,
127
+ files: [],
128
+ thinkingEnabled: resolveThinkingEnabled(body, projectDefs, systemDefaults),
129
+ startImmediately: resolveStartImmediately(body, projectDefs, systemDefaults),
130
+ ...parseSchedulingConfig(body),
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Apply template overrides to session config.
136
+ * Mutates the config object in place.
137
+ * @param {object} configInput - Session config to modify
138
+ */
139
+ export function applyTemplateOverrides(configInput) {
140
+ const config = configInput;
141
+ if (!config.templateId) return;
142
+
143
+ const template = sessionTemplates.getById(config.templateId);
144
+ if (!template) return;
145
+
146
+ if (template.thinkingEnabled !== null && template.thinkingEnabled !== undefined) {
147
+ config.thinkingEnabled = template.thinkingEnabled;
148
+ }
149
+ if (template.gitBranch) {
150
+ config.gitBranch = template.gitBranch;
151
+ }
152
+ if (template.gitMode) {
153
+ config.gitMode = template.gitMode;
154
+ }
155
+ if (template.effortLevel !== null && template.effortLevel !== undefined) {
156
+ config.effortLevel = template.effortLevel;
157
+ // Normalize 'auto' to null (same as prepareSessionConfig)
158
+ if (config.effortLevel === 'auto') {
159
+ config.effortLevel = null;
160
+ }
161
+ }
162
+ config.nextTemplateId = config.templateId;
163
+ }
164
+
165
+ /**
166
+ * Resolve the nextTemplateId from explicit body value or template-derived value.
167
+ * @param {object} body - Request body
168
+ * @param {string|null} derivedNextTemplateId - nextTemplateId derived from templateId
169
+ * @returns {{ nextTemplateId: string|null, error: string|null }}
170
+ */
171
+ export function resolveNextTemplateId(body, derivedNextTemplateId) {
172
+ if (body.nextTemplateId === undefined) {
173
+ return { nextTemplateId: derivedNextTemplateId, error: null };
174
+ }
175
+
176
+ if (body.nextTemplateId === null) {
177
+ return { nextTemplateId: null, error: null };
178
+ }
179
+
180
+ const nextTemplate = sessionTemplates.getById(body.nextTemplateId);
181
+ if (!nextTemplate) {
182
+ return { nextTemplateId: null, error: 'nextTemplateId references a non-existent template' };
183
+ }
184
+ return { nextTemplateId: body.nextTemplateId, error: null };
185
+ }
186
+
187
+ /**
188
+ * Determine the initial session status based on config.
189
+ * @param {object} config - Session config
190
+ * @returns {string|undefined} Initial status, or undefined for default
191
+ */
192
+ export function determineInitialStatus(config) {
193
+ if (config.scheduledAt && config.scheduledAt > Date.now()) return 'scheduled';
194
+ if (!config.startImmediately) return 'waiting';
195
+ return undefined;
196
+ }
197
+
198
+ /**
199
+ * Build the scheduling update object from config.
200
+ * @param {object} config - Session config
201
+ * @param {string|undefined} initialStatus - Initial session status
202
+ * @returns {object} Fields to update on the session for scheduling
203
+ */
204
+ export function buildSchedulingUpdate(config, initialStatus) {
205
+ const update = {};
206
+ if (config.scheduledAt !== undefined) update.scheduledAt = config.scheduledAt;
207
+ if (config.autoRescheduleEnabled !== undefined) update.autoRescheduleEnabled = config.autoRescheduleEnabled;
208
+ if (config.rescheduleDelayMinutes !== undefined) update.rescheduleDelayMinutes = config.rescheduleDelayMinutes;
209
+ if (config.rescheduleOnTokenLimit !== undefined) update.rescheduleOnTokenLimit = config.rescheduleOnTokenLimit;
210
+ if (config.rescheduleOnServiceError !== undefined) update.rescheduleOnServiceError = config.rescheduleOnServiceError;
211
+ if (config.maxRescheduleCount !== undefined) update.maxRescheduleCount = config.maxRescheduleCount;
212
+ if (config.maxTotalTokens !== undefined) update.maxTotalTokens = config.maxTotalTokens;
213
+ if (config.rescheduleAtTokenCount !== undefined) update.rescheduleAtTokenCount = config.rescheduleAtTokenCount;
214
+
215
+ if (initialStatus === 'waiting' || initialStatus === 'scheduled') {
216
+ update.pendingPrompt = config.prompt;
217
+ update.pendingModel = config.model;
218
+ }
219
+
220
+ return update;
221
+ }
222
+
223
+ /**
224
+ * Handle git setup, session start, broadcasts, and hooks after session creation.
225
+ * @param {object} params
226
+ * @param {object} params.session - The created session record
227
+ * @param {object} params.config - Session config
228
+ * @param {object} params.project - Project record
229
+ * @param {string} params.projectId - Project ID
230
+ * @param {Array} params.files - Uploaded files
231
+ * @returns {Promise<{ updatedSession: object }>}
232
+ */
233
+ export async function setupAndStartSession({ session, config, project, projectId, files }) {
234
+ let workingDirectory;
235
+ let gitWorktree = null;
236
+
237
+ // If this is a child session and the parent has a worktree, inherit it
238
+ // (mirrors templateTriggerService behavior)
239
+ const parentSession = config.parentSessionId ? sessions.getById(config.parentSessionId) : null;
240
+ if (parentSession?.gitWorktree) {
241
+ workingDirectory = parentSession.gitWorktree;
242
+ gitWorktree = parentSession.gitWorktree;
243
+ } else {
244
+ const gitSetup = await setupGitForSession({
245
+ projectDir: project.workingDirectory,
246
+ gitMode: config.gitMode || null,
247
+ gitBranch: config.gitBranch || null,
248
+ sessionId: session.id,
249
+ });
250
+ workingDirectory = gitSetup.workingDirectory;
251
+ gitWorktree = gitSetup.gitWorktree;
252
+ }
253
+
254
+ if (gitWorktree) {
255
+ sessions.update(session.id, { gitWorktree });
256
+ }
257
+
258
+ const sessionAttachments = attachments.createBatch(session.id, null, files, workingDirectory);
259
+
260
+ const isScheduled = config.scheduledAt && config.scheduledAt > Date.now();
261
+ if (config.startImmediately && !isScheduled) {
262
+ const resolved = await slashCommandService.resolvePromptSkillOrCommand(
263
+ workingDirectory, config.prompt, project.systemPrompt
264
+ );
265
+ const finalPrompt = resolved ? resolved.userMessage : config.prompt;
266
+ const finalSystemPrompt = resolved ? resolved.systemPrompt : project.systemPrompt;
267
+
268
+ const { runSession } = await import('../services/sessionManager.js');
269
+ runSession(session.id, finalPrompt, workingDirectory, {
270
+ systemPrompt: finalSystemPrompt,
271
+ fileAttachments: sessionAttachments,
272
+ model: config.model,
273
+ }).catch((error) => {
274
+ console.error('Session error:', error);
275
+ sessions.update(session.id, { status: 'error', error: error.message });
276
+ });
277
+ }
278
+
279
+ const updatedSession = sessions.getById(session.id);
280
+
281
+ broadcastToProject(projectId, WS_MESSAGE_TYPES.SESSION_CREATED, {
282
+ projectId,
283
+ session: updatedSession,
284
+ });
285
+
286
+ if (project.onSessionCreated) {
287
+ executeHookAsync(project.onSessionCreated, workingDirectory, {
288
+ sessionId: session.id,
289
+ projectId: project.id,
290
+ sessionName: session.name,
291
+ });
292
+ }
293
+
294
+ return { updatedSession };
295
+ }