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,281 @@
1
+ import { sessions, messages, conversations, projects, attachments } from '../database.js';
2
+ import { broadcastToSession } from '../websocket.js';
3
+ import { WS_MESSAGE_TYPES } from '../../../shared/src/index.js';
4
+ import * as slashCommandService from './slashCommandService.js';
5
+
6
+ /**
7
+ * Service for managing scheduled session execution
8
+ * Polls for due sessions every 30 seconds and handles rescheduling logic
9
+ */
10
+ class SchedulerService {
11
+ constructor() {
12
+ this.pollInterval = 30000; // 30 seconds
13
+ this.intervalId = null;
14
+ this.sessionManager = null; // Will be set during initialization
15
+ }
16
+
17
+ /**
18
+ * Initialize the scheduler with dependencies
19
+ * @param {object} sessionManager - Session manager instance
20
+ */
21
+ initialize(sessionManager) {
22
+ this.sessionManager = sessionManager;
23
+ }
24
+
25
+ /**
26
+ * Start the scheduler polling
27
+ */
28
+ start() {
29
+ if (this.intervalId) {
30
+ console.log('[SchedulerService] Already running');
31
+ return;
32
+ }
33
+
34
+ console.log('[SchedulerService] Starting scheduler with', this.pollInterval, 'ms interval');
35
+ this.intervalId = setInterval(() => this.checkScheduledSessions(), this.pollInterval);
36
+
37
+ // Also check immediately on startup
38
+ this.checkScheduledSessions();
39
+ }
40
+
41
+ /**
42
+ * Stop the scheduler polling
43
+ */
44
+ stop() {
45
+ if (this.intervalId) {
46
+ console.log('[SchedulerService] Stopping scheduler');
47
+ clearInterval(this.intervalId);
48
+ this.intervalId = null;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Check for scheduled sessions that are due to start
54
+ */
55
+ async checkScheduledSessions() {
56
+ const now = Date.now();
57
+ const dueSessions = sessions.getScheduledSessionsDue(now);
58
+
59
+ if (dueSessions.length > 0) {
60
+ console.log(`[SchedulerService] Found ${dueSessions.length} session(s) due to start`);
61
+ }
62
+
63
+ for (const session of dueSessions) {
64
+ try {
65
+ await this.startScheduledSession(session);
66
+ } catch (error) {
67
+ console.error(`[SchedulerService] Error starting scheduled session ${session.id}:`, error);
68
+ // Mark session as error
69
+ sessions.update(session.id, {
70
+ status: 'error',
71
+ error: `Failed to start scheduled session: ${error.message}`,
72
+ });
73
+ broadcastToSession(session.id, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId: session.id, status: 'error' });
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Start a scheduled session
80
+ * @param {object} session - Session to start
81
+ */
82
+ async startScheduledSession(session) {
83
+ if (!this.sessionManager) {
84
+ throw new Error('SchedulerService not initialized with sessionManager');
85
+ }
86
+
87
+ console.log(`[SchedulerService] Starting scheduled session ${session.id}: ${session.name}`);
88
+
89
+ // Get the project for working directory and system prompt
90
+ const project = projects.getById(session.projectId);
91
+ if (!project) {
92
+ throw new Error(`Project not found for session ${session.id}`);
93
+ }
94
+
95
+ // Determine working directory
96
+ const workingDirectory = session.gitWorktree || project.workingDirectory;
97
+
98
+ // Use pendingPrompt as the message to send
99
+ if (!session.pendingPrompt || session.pendingPrompt.trim() === '') {
100
+ throw new Error(`No pendingPrompt found for session ${session.id}`);
101
+ }
102
+
103
+ const prompt = session.pendingPrompt.trim();
104
+
105
+ // Get the session messages to determine if this is initial or continuation
106
+ const sessionMessages = messages.getBySessionId(session.id);
107
+ const hasAssistantResponses = sessionMessages.some((msg) => msg.role === 'assistant');
108
+
109
+ // Get attachments for context
110
+ const sessionAttachments = attachments.getBySessionId(session.id);
111
+
112
+ // Resolve skill/command invocations so skill body goes into system prompt
113
+ const resolved = await slashCommandService.resolvePromptSkillOrCommand(
114
+ workingDirectory, prompt, project.systemPrompt
115
+ );
116
+ const effectivePrompt = resolved ? resolved.userMessage : prompt;
117
+ const effectiveSystemPrompt = resolved ? resolved.systemPrompt : project.systemPrompt;
118
+
119
+ // Determine if this is an initial run or a continuation
120
+ if (hasAssistantResponses) {
121
+ // Session has conversation history - this is a scheduled continuation
122
+
123
+ // Update status from 'scheduled' to 'starting' and clear pendingPrompt
124
+ sessions.update(session.id, {
125
+ status: 'starting',
126
+ scheduledAt: null,
127
+ pendingPrompt: null,
128
+ });
129
+ broadcastToSession(session.id, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId: session.id, status: 'starting' });
130
+
131
+ await this.sessionManager.continueSession(
132
+ session.id,
133
+ effectivePrompt,
134
+ workingDirectory,
135
+ { systemPrompt: effectiveSystemPrompt, fileAttachments: sessionAttachments, model: session.pendingModel }
136
+ );
137
+ } else {
138
+ // Fresh session - initial run
139
+ // First, create the user message so it appears in the conversation
140
+
141
+ // Get the active conversation
142
+ const activeConv = conversations.getActiveBySessionId(session.id);
143
+ if (!activeConv) {
144
+ throw new Error(`No active conversation found for session ${session.id}`);
145
+ }
146
+
147
+ // Create the initial user message
148
+ const userMessage = messages.create(session.id, 'user', prompt, { toolUse: null, conversationId: activeConv.id });
149
+
150
+ // Broadcast the new message so UI updates
151
+ broadcastToSession(session.id, WS_MESSAGE_TYPES.MESSAGE_CREATED, {
152
+ sessionId: session.id,
153
+ message: userMessage,
154
+ });
155
+
156
+ // Update status from 'scheduled' to 'starting' and clear pendingPrompt
157
+ sessions.update(session.id, {
158
+ status: 'starting',
159
+ scheduledAt: null,
160
+ pendingPrompt: null,
161
+ });
162
+ broadcastToSession(session.id, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId: session.id, status: 'starting' });
163
+
164
+ await this.sessionManager.runSession(
165
+ session.id,
166
+ effectivePrompt,
167
+ workingDirectory,
168
+ { systemPrompt: effectiveSystemPrompt, fileAttachments: sessionAttachments, model: session.pendingModel }
169
+ );
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Reschedule a session with a delay
175
+ * @param {string} sessionId - Session ID to reschedule
176
+ * @param {string} reason - Reason for rescheduling
177
+ * @returns {boolean} True if rescheduled, false if limits reached
178
+ */
179
+ async rescheduleSession(sessionId, reason) {
180
+ const session = sessions.getById(sessionId);
181
+ if (!session) {
182
+ console.error(`[SchedulerService] Session not found: ${sessionId}`);
183
+ return false;
184
+ }
185
+
186
+ // Check reschedule limits
187
+ if (this.hasReachedLimits(session)) {
188
+ console.log(`[SchedulerService] Session ${sessionId} has reached reschedule limits`);
189
+ sessions.update(sessionId, {
190
+ status: 'error',
191
+ error: `Reschedule limits reached. ${reason}`,
192
+ });
193
+ broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId, status: 'error' });
194
+ return false;
195
+ }
196
+
197
+ // Get the last user message to use as pendingPrompt for restart
198
+ const sessionMessages = messages.getBySessionId(sessionId);
199
+ const lastUserMessage = [...sessionMessages].reverse().find(msg => msg.role === 'user');
200
+
201
+ if (!lastUserMessage) {
202
+ console.error(`[SchedulerService] No user message found for session ${sessionId}`);
203
+ sessions.update(sessionId, {
204
+ status: 'error',
205
+ error: `Cannot reschedule: No user message found. ${reason}`,
206
+ });
207
+ broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId, status: 'error' });
208
+ return false;
209
+ }
210
+
211
+ // Calculate new scheduled time
212
+ const newScheduledAt = Date.now() + session.rescheduleDelayMinutes * 60 * 1000;
213
+ const delayMinutes = session.rescheduleDelayMinutes;
214
+ const newRescheduleCount = session.rescheduleCount + 1;
215
+
216
+ console.log(
217
+ `[SchedulerService] Rescheduling session ${sessionId} for ${delayMinutes} minutes from now (attempt ${newRescheduleCount})`
218
+ );
219
+
220
+ // Update session to scheduled status with new time and pendingPrompt
221
+ sessions.update(sessionId, {
222
+ status: 'scheduled',
223
+ scheduledAt: newScheduledAt, // Fixed: camelCase
224
+ rescheduleCount: newRescheduleCount, // Fixed: camelCase
225
+ pendingPrompt: lastUserMessage.content, // Set prompt for scheduler
226
+ error: `Rescheduled (${newRescheduleCount}x): ${reason}`,
227
+ });
228
+
229
+ broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId, status: 'scheduled' });
230
+
231
+ return true;
232
+ }
233
+
234
+ /**
235
+ * Check if a session has reached its reschedule limits
236
+ * @param {object} session - Session to check
237
+ * @returns {boolean} True if limits reached
238
+ */
239
+ hasReachedLimits(session) {
240
+ // Check max reschedule count
241
+ if (session.maxRescheduleCount !== null && session.rescheduleCount >= session.maxRescheduleCount) {
242
+ console.log(
243
+ `[SchedulerService] Max reschedule count reached: ${session.rescheduleCount}/${session.maxRescheduleCount}`
244
+ );
245
+ return true;
246
+ }
247
+
248
+ // Check max total tokens
249
+ if (session.maxTotalTokens !== null) {
250
+ const totalTokens = session.inputTokens + session.outputTokens;
251
+ if (totalTokens >= session.maxTotalTokens) {
252
+ console.log(
253
+ `[SchedulerService] Max total tokens reached: ${totalTokens.toLocaleString()}/${session.maxTotalTokens.toLocaleString()}`
254
+ );
255
+ return true;
256
+ }
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Check if a session should be proactively rescheduled based on token threshold
264
+ * @param {object} session - Session to check
265
+ * @returns {boolean} True if should reschedule
266
+ */
267
+ shouldProactivelyReschedule(session) {
268
+ if (!session.rescheduleAtTokenCount) {
269
+ return false;
270
+ }
271
+
272
+ const totalTokens = session.inputTokens + session.outputTokens;
273
+ return totalTokens >= session.rescheduleAtTokenCount;
274
+ }
275
+ }
276
+
277
+ // Singleton instance
278
+ export const schedulerService = new SchedulerService();
279
+
280
+ // Export class for testing
281
+ export { SchedulerService };
@@ -0,0 +1,63 @@
1
+ import {
2
+ sessions,
3
+ conversations,
4
+ messages,
5
+ canvasItems,
6
+ sessionNotes,
7
+ sessionSummaries,
8
+ projects,
9
+ } from '../db/index.js';
10
+
11
+ /**
12
+ * Duplicates a session including all related data.
13
+ * Handles git setup based on the source session's configuration.
14
+ *
15
+ * @param {string} sourceSessionId - ID of session to duplicate
16
+ * @param {object} options - Duplication options
17
+ * @param {string} [options.name] - Custom name for new session
18
+ * @returns {Promise<object>} The new session with all data duplicated
19
+ */
20
+ export async function duplicateSession(sourceSessionId, options = {}) {
21
+ // 1. Get source session and project
22
+ const sourceSession = sessions.getById(sourceSessionId);
23
+ if (!sourceSession) {
24
+ throw new Error(`Session not found: ${sourceSessionId}`);
25
+ }
26
+
27
+ const project = projects.getById(sourceSession.projectId);
28
+ if (!project) {
29
+ throw new Error(`Project not found: ${sourceSession.projectId}`);
30
+ }
31
+
32
+ // 2. Duplicate session record (without git worktree path)
33
+ const newSession = sessions.duplicate(sourceSessionId, {
34
+ name: options.name,
35
+ });
36
+
37
+ try {
38
+ // 3. Duplicate conversations and get ID mapping
39
+ const conversationMapping = conversations.duplicateForSession(
40
+ sourceSessionId,
41
+ newSession.id
42
+ );
43
+
44
+ // 4. Duplicate messages using conversation mapping
45
+ messages.duplicateForConversations(conversationMapping, newSession.id);
46
+
47
+ // 5. Duplicate canvas items
48
+ canvasItems.duplicateForSession(sourceSessionId, newSession.id);
49
+
50
+ // 6. Duplicate session notes
51
+ sessionNotes.duplicateForSession(sourceSessionId, newSession.id);
52
+
53
+ // 7. Duplicate session summary (if exists)
54
+ sessionSummaries.duplicateForSession(sourceSessionId, newSession.id);
55
+
56
+ // Return the updated session
57
+ return sessions.getById(newSession.id);
58
+ } catch (error) {
59
+ // Cleanup: delete the new session if duplication fails
60
+ sessions.delete(newSession.id);
61
+ throw error;
62
+ }
63
+ }
@@ -0,0 +1,173 @@
1
+ import { sessions, messages } from '../database.js';
2
+ import { schedulerService } from './schedulerService.js';
3
+
4
+ /**
5
+ * Check if error message matches token limit patterns
6
+ * @param {string} message - Error message to check
7
+ * @returns {boolean} True if matches token limit error
8
+ */
9
+ export function matchesTokenLimitError(message) {
10
+ const patterns = [
11
+ 'token',
12
+ 'context length',
13
+ 'max_tokens',
14
+ 'context window',
15
+ 'limit', // catches "You've hit your limit"
16
+ 'quota',
17
+ 'rate limit',
18
+ 'exceeded', // catches usage exceeded messages
19
+ 'cap', // catches usage cap messages
20
+ ];
21
+
22
+ return patterns.some(pattern => message.includes(pattern));
23
+ }
24
+
25
+ /**
26
+ * Check if error message matches service error patterns
27
+ * @param {string} message - Error message to check
28
+ * @returns {boolean} True if matches service error
29
+ */
30
+ export function matchesServiceError(message) {
31
+ const patterns = [
32
+ 'overloaded',
33
+ 'rate limit',
34
+ '503',
35
+ '529',
36
+ 'unavailable',
37
+ 'service unavailable',
38
+ 'too many requests',
39
+ ];
40
+
41
+ return patterns.some(pattern => message.includes(pattern));
42
+ }
43
+
44
+ /**
45
+ * Get the last assistant message for a session
46
+ * @param {string} sessionId - Session ID
47
+ * @returns {object|null} Last assistant message or null
48
+ */
49
+ function getLastAssistantMessage(sessionId) {
50
+ try {
51
+ const sessionMessages = messages.getBySessionId(sessionId);
52
+ const assistantMessages = sessionMessages.filter(msg => msg.role === 'assistant');
53
+ return assistantMessages.length > 0 ? assistantMessages[assistantMessages.length - 1] : null;
54
+ } catch (error) {
55
+ console.error('[SessionManager] Error getting last assistant message:', error);
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Check if error message matches a rescheduling trigger and log the result
62
+ * @param {object} session - Session object
63
+ * @param {string} message - Message to check (lowercase)
64
+ * @param {string} source - Source description for logging (e.g., "error", "assistant message")
65
+ * @returns {boolean} True if matches a rescheduling trigger
66
+ */
67
+ function checkRescheduleTrigger(session, message, source) {
68
+ if (session.rescheduleOnTokenLimit && matchesTokenLimitError(message)) {
69
+ console.log(`[SessionManager] Token limit detected in ${source}, rescheduling`);
70
+ console.log(`[SessionManager] ${source}:`, message);
71
+ console.log('[SessionManager] Session config: rescheduleOnTokenLimit=true, rescheduleDelayMinutes=', session.rescheduleDelayMinutes);
72
+ return true;
73
+ }
74
+
75
+ if (session.rescheduleOnServiceError && matchesServiceError(message)) {
76
+ console.log(`[SessionManager] Service error detected in ${source}, rescheduling`);
77
+ console.log(`[SessionManager] ${source}:`, message);
78
+ console.log('[SessionManager] Session config: rescheduleOnServiceError=true, rescheduleDelayMinutes=', session.rescheduleDelayMinutes);
79
+ return true;
80
+ }
81
+
82
+ return false;
83
+ }
84
+
85
+ /**
86
+ * Log when a rescheduling check is skipped
87
+ * @param {string} setting - The setting name that was disabled
88
+ */
89
+ function logSkippedReschedule(setting) {
90
+ console.log(`[SessionManager] ${setting} is false, skipping ${setting.replace('reschedule', '').toLowerCase()} rescheduling`);
91
+ }
92
+
93
+ /**
94
+ * Check if an error should trigger automatic rescheduling
95
+ * @param {object} session - Session object
96
+ * @param {Error} error - Error that occurred
97
+ * @param {string} sessionId - Session ID
98
+ * @returns {boolean} True if should reschedule
99
+ */
100
+ export function shouldRescheduleOnError(session, error, sessionId = null) {
101
+ // Check if auto-reschedule is enabled first (master switch)
102
+ if (!session.autoRescheduleEnabled) {
103
+ console.log('[SessionManager] autoRescheduleEnabled is false, skipping all rescheduling');
104
+ return false;
105
+ }
106
+
107
+ const errorMessage = error.message.toLowerCase();
108
+
109
+ // Log skipped checks for debugging
110
+ if (!session.rescheduleOnTokenLimit) logSkippedReschedule('rescheduleOnTokenLimit');
111
+ if (!session.rescheduleOnServiceError) logSkippedReschedule('rescheduleOnServiceError');
112
+
113
+ // Check error message for rescheduling triggers
114
+ if (checkRescheduleTrigger(session, errorMessage, 'error')) {
115
+ return true;
116
+ }
117
+
118
+ // Also check last assistant message if available
119
+ if (sessionId) {
120
+ const lastAssistantMessage = getLastAssistantMessage(sessionId);
121
+ if (lastAssistantMessage) {
122
+ const messageContent = lastAssistantMessage.content.toLowerCase();
123
+ if (checkRescheduleTrigger(session, messageContent, 'assistant message')) {
124
+ return true;
125
+ }
126
+ }
127
+ }
128
+
129
+ console.log('[SessionManager] Error does not match any rescheduling triggers');
130
+ console.log('[SessionManager] Session config: rescheduleOnTokenLimit=', session.rescheduleOnTokenLimit, ', rescheduleOnServiceError=', session.rescheduleOnServiceError);
131
+ return false;
132
+ }
133
+
134
+ /**
135
+ * Check if session should be proactively rescheduled based on token count
136
+ * Called after processing each message to check token thresholds
137
+ * @param {string} sessionId - Session ID
138
+ * @returns {Promise<boolean>} True if rescheduled
139
+ */
140
+ export async function _checkProactiveReschedule(sessionId) {
141
+ const session = sessions.getById(sessionId);
142
+ if (!session || !session.rescheduleAtTokenCount) {
143
+ return false;
144
+ }
145
+
146
+ // Check if auto-reschedule is enabled first (master switch)
147
+ if (!session.autoRescheduleEnabled) {
148
+ console.log('[SessionManager] autoRescheduleEnabled is false, skipping proactive rescheduling');
149
+ return false;
150
+ }
151
+
152
+ const totalTokens = session.inputTokens + session.outputTokens;
153
+ if (totalTokens >= session.rescheduleAtTokenCount) {
154
+ console.log(
155
+ `[SessionManager] Proactive token threshold reached: ${totalTokens.toLocaleString()}/${session.rescheduleAtTokenCount.toLocaleString()}`
156
+ );
157
+
158
+ // Check if we've reached limits
159
+ if (schedulerService.hasReachedLimits(session)) {
160
+ console.log('[SessionManager] Cannot reschedule - limits reached');
161
+ return false;
162
+ }
163
+
164
+ // Gracefully reschedule
165
+ await schedulerService.rescheduleSession(
166
+ sessionId,
167
+ `Token threshold reached (${totalTokens.toLocaleString()} tokens)`
168
+ );
169
+ return true;
170
+ }
171
+
172
+ return false;
173
+ }