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,379 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+ import { mapConversationRow, executeBranch } from './conversation-helpers.js';
4
+
5
+ /**
6
+ * Conversation repository class for managing conversation threads within sessions
7
+ */
8
+ export class ConversationRepository extends BaseRepository {
9
+ constructor() {
10
+ super('conversations', mapConversationRow);
11
+ }
12
+
13
+ /**
14
+ * Create a new conversation for a session
15
+ * @param {string} sessionId - The session ID
16
+ * @param {string} [name] - Optional name for the conversation
17
+ * @param {boolean} [isActive=true] - Whether this is the active conversation
18
+ * @returns {Object} The created conversation
19
+ */
20
+ create(sessionId, name = null, isActive = true) {
21
+ const id = databaseManager.generateId();
22
+ const now = Date.now();
23
+
24
+ // If this conversation should be active, deactivate others first
25
+ if (isActive) {
26
+ this.db
27
+ .prepare('UPDATE conversations SET is_active = 0, updated_at = ? WHERE session_id = ?')
28
+ .run(now, sessionId);
29
+ }
30
+
31
+ this.db
32
+ .prepare(
33
+ `INSERT INTO conversations (id, session_id, name, is_active, created_at, updated_at)
34
+ VALUES (?, ?, ?, ?, ?, ?)`
35
+ )
36
+ .run(id, sessionId, name, isActive ? 1 : 0, now, now);
37
+
38
+ return this.getById(id);
39
+ }
40
+
41
+ /**
42
+ * Get all conversations for a session
43
+ * @param {string} sessionId - The session ID
44
+ * @returns {Array} List of conversations ordered by creation time
45
+ */
46
+ getBySessionId(sessionId) {
47
+ const rows = this.db
48
+ .prepare('SELECT * FROM conversations WHERE session_id = ? ORDER BY created_at ASC')
49
+ .all(sessionId);
50
+ return this.mapAll(rows);
51
+ }
52
+
53
+ /**
54
+ * Get the active conversation for a session
55
+ * @param {string} sessionId - The session ID
56
+ * @returns {Object|null} The active conversation or null
57
+ */
58
+ getActiveBySessionId(sessionId) {
59
+ const row = this.db
60
+ .prepare('SELECT * FROM conversations WHERE session_id = ? AND is_active = 1')
61
+ .get(sessionId);
62
+ return this.map(row);
63
+ }
64
+
65
+ /**
66
+ * Get conversation with message count
67
+ * @param {string} sessionId - The session ID
68
+ * @returns {Array} Conversations with messageCount property
69
+ */
70
+ getBySessionIdWithMessageCount(sessionId) {
71
+ const rows = this.db
72
+ .prepare(`
73
+ SELECT c.*, COUNT(m.id) as message_count
74
+ FROM conversations c
75
+ LEFT JOIN conversation_messages m ON m.conversation_id = c.id
76
+ WHERE c.session_id = ?
77
+ GROUP BY c.id
78
+ ORDER BY c.created_at ASC
79
+ `)
80
+ .all(sessionId);
81
+
82
+ return rows.map((row) => ({
83
+ ...mapConversationRow(row),
84
+ messageCount: row.message_count,
85
+ }));
86
+ }
87
+
88
+ /**
89
+ * Update a conversation
90
+ * @param {string} id - The conversation ID
91
+ * @param {Object} data - Fields to update
92
+ * @returns {Object} The updated conversation
93
+ */
94
+ update(id, data) {
95
+ const updates = [];
96
+ const values = [];
97
+
98
+ if (data.name !== undefined) {
99
+ updates.push('name = ?');
100
+ values.push(data.name);
101
+ }
102
+ if (data.summary !== undefined) {
103
+ updates.push('summary = ?');
104
+ values.push(data.summary);
105
+ }
106
+ if (data.summaryGeneratedAt !== undefined) {
107
+ updates.push('summary_generated_at = ?');
108
+ values.push(data.summaryGeneratedAt);
109
+ }
110
+ if (data.claudeSessionId !== undefined) {
111
+ updates.push('claude_session_id = ?');
112
+ values.push(data.claudeSessionId);
113
+ }
114
+ if (data.isActive !== undefined) {
115
+ // If setting this conversation as active, deactivate others first
116
+ if (data.isActive) {
117
+ const conv = this.getById(id);
118
+ if (conv) {
119
+ this.db
120
+ .prepare('UPDATE conversations SET is_active = 0, updated_at = ? WHERE session_id = ? AND id != ?')
121
+ .run(Date.now(), conv.sessionId, id);
122
+ }
123
+ }
124
+ updates.push('is_active = ?');
125
+ values.push(data.isActive ? 1 : 0);
126
+ }
127
+
128
+ if (updates.length === 0) {
129
+ return this.getById(id);
130
+ }
131
+
132
+ updates.push('updated_at = ?');
133
+ values.push(Date.now());
134
+ values.push(id);
135
+
136
+ this.db
137
+ .prepare(`UPDATE conversations SET ${updates.join(', ')} WHERE id = ?`)
138
+ .run(...values);
139
+
140
+ return this.getById(id);
141
+ }
142
+
143
+ /**
144
+ * Set a conversation as active (and deactivate others)
145
+ * @param {string} id - The conversation ID to activate
146
+ * @returns {Object} The updated conversation
147
+ */
148
+ setActive(id) {
149
+ return this.update(id, { isActive: true });
150
+ }
151
+
152
+ /**
153
+ * Delete a conversation and handle edge cases
154
+ * @param {string} id - The conversation ID
155
+ * @returns {Object|null} The new active conversation if one was auto-created
156
+ */
157
+ deleteAndHandleActive(id) {
158
+ const conv = this.getById(id);
159
+ if (!conv) return null;
160
+
161
+ const wasActive = conv.isActive;
162
+ const sessionId = conv.sessionId;
163
+
164
+ // Delete the conversation (messages will be cascade deleted)
165
+ this.delete(id);
166
+
167
+ // If we deleted the active conversation, activate another one
168
+ if (wasActive) {
169
+ const remaining = this.getBySessionId(sessionId);
170
+ if (remaining.length > 0) {
171
+ // Activate the most recent conversation
172
+ return this.setActive(remaining[remaining.length - 1].id);
173
+ } else {
174
+ // No conversations left - create a new empty one
175
+ return this.create(sessionId, 'New Conversation', true);
176
+ }
177
+ }
178
+
179
+ return null;
180
+ }
181
+
182
+ /**
183
+ * Ensure a session has at least one conversation, creating one if needed
184
+ * @param {string} sessionId - The session ID
185
+ * @returns {Object} The active conversation
186
+ */
187
+ ensureActiveConversation(sessionId) {
188
+ let active = this.getActiveBySessionId(sessionId);
189
+ if (!active) {
190
+ // Check if there are any conversations at all
191
+ const conversations = this.getBySessionId(sessionId);
192
+ if (conversations.length > 0) {
193
+ // Activate the first one
194
+ active = this.setActive(conversations[0].id);
195
+ } else {
196
+ // Create a new conversation
197
+ active = this.create(sessionId, 'Initial', true);
198
+ }
199
+ }
200
+ return active;
201
+ }
202
+
203
+ /**
204
+ * Auto-generate a conversation name from the first user message
205
+ * @param {string} id - The conversation ID
206
+ * @param {string} firstMessage - The first user message content
207
+ * @returns {Object} The updated conversation
208
+ */
209
+ autoName(id, firstMessage) {
210
+ // Take first 50 chars of the message, truncate at word boundary
211
+ let name = firstMessage.substring(0, 50);
212
+ const lastSpace = name.lastIndexOf(' ');
213
+ if (lastSpace > 30) {
214
+ name = name.substring(0, lastSpace);
215
+ }
216
+ if (firstMessage.length > 50) {
217
+ name += '...';
218
+ }
219
+
220
+ return this.update(id, { name });
221
+ }
222
+
223
+ /**
224
+ * Update token usage statistics for a conversation
225
+ * @param {string} id - Conversation ID
226
+ * @param {Object} usage - Usage data
227
+ * @param {number} usage.inputTokens
228
+ * @param {number} usage.outputTokens
229
+ * @param {number} usage.cacheReadInputTokens
230
+ * @param {number} usage.cacheCreationInputTokens
231
+ * @param {number} usage.webSearchRequests
232
+ * @param {number} usage.contextWindow
233
+ * @returns {Object|null} Updated conversation or null if not found
234
+ */
235
+ updateUsage(id, usage) {
236
+ const conversation = this.getById(id);
237
+ if (!conversation) {
238
+ return null;
239
+ }
240
+
241
+ const now = Date.now();
242
+ this.db
243
+ .prepare(
244
+ `UPDATE conversations SET
245
+ input_tokens = ?,
246
+ output_tokens = ?,
247
+ cache_read_input_tokens = ?,
248
+ cache_creation_input_tokens = ?,
249
+ web_search_requests = ?,
250
+ context_window = ?,
251
+ updated_at = ?
252
+ WHERE id = ?`
253
+ )
254
+ .run(
255
+ usage.inputTokens,
256
+ usage.outputTokens,
257
+ usage.cacheReadInputTokens,
258
+ usage.cacheCreationInputTokens,
259
+ usage.webSearchRequests,
260
+ usage.contextWindow,
261
+ now,
262
+ id
263
+ );
264
+ return this.getById(id);
265
+ }
266
+
267
+ /**
268
+ * Duplicates all conversations from one session to another.
269
+ * @param {string} sourceSessionId - Source session ID
270
+ * @param {string} targetSessionId - Target session ID
271
+ * @returns {Map<string, string>} Mapping of old conversation IDs to new IDs
272
+ */
273
+ duplicateForSession(sourceSessionId, targetSessionId) {
274
+ const sourceConversations = this.getBySessionId(sourceSessionId);
275
+ const idMapping = new Map();
276
+
277
+ for (const conv of sourceConversations) {
278
+ const id = databaseManager.generateId();
279
+ const now = Date.now();
280
+
281
+ this.db
282
+ .prepare(
283
+ `INSERT INTO conversations (id, session_id, name, summary, is_active, created_at, updated_at)
284
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
285
+ )
286
+ .run(
287
+ id,
288
+ targetSessionId,
289
+ conv.name,
290
+ conv.summary,
291
+ conv.isActive ? 1 : 0,
292
+ now,
293
+ now
294
+ );
295
+
296
+ idMapping.set(conv.id, id);
297
+ }
298
+
299
+ return idMapping;
300
+ }
301
+
302
+ /**
303
+ * Create a branch from an existing conversation at a specific message
304
+ * Copies all messages BEFORE the specified message to a new conversation,
305
+ * then adds the initialPrompt as a replacement for that message
306
+ * @param {string} conversationId - The source conversation ID
307
+ * @param {string} messageId - The message ID to branch from (messages before this are copied, this message is replaced)
308
+ * @param {string} [name] - Optional name for the new conversation (if not provided, auto-generated from prompt)
309
+ * @param {string} initialPrompt - Required: the new prompt that replaces the branch point message
310
+ * @returns {Object} The created branch conversation
311
+ */
312
+ branch(conversationId, messageId, name = null, initialPrompt = null) {
313
+ return executeBranch(this, conversationId, messageId, { name, initialPrompt });
314
+ }
315
+
316
+ /**
317
+ * Get conversations for a session with branch hierarchy info
318
+ * @param {string} sessionId - The session ID
319
+ * @returns {Array} Conversations with childCount property
320
+ */
321
+ getBySessionIdWithBranchInfo(sessionId) {
322
+ const rows = this.db
323
+ .prepare(`
324
+ SELECT c.*,
325
+ (SELECT COUNT(*) FROM conversations child WHERE child.parent_conversation_id = c.id) as child_count,
326
+ (SELECT COUNT(*) FROM conversation_messages m WHERE m.conversation_id = c.id) as message_count
327
+ FROM conversations c
328
+ WHERE c.session_id = ?
329
+ ORDER BY c.created_at ASC
330
+ `)
331
+ .all(sessionId);
332
+
333
+ return rows.map((row) => ({
334
+ ...mapConversationRow(row),
335
+ childCount: row.child_count || 0,
336
+ messageCount: row.message_count || 0,
337
+ }));
338
+ }
339
+
340
+ /**
341
+ * Get child conversations (branches) of a conversation
342
+ * @param {string} parentConversationId - The parent conversation ID
343
+ * @returns {Array} Child conversations
344
+ */
345
+ getChildren(parentConversationId) {
346
+ const rows = this.db
347
+ .prepare('SELECT * FROM conversations WHERE parent_conversation_id = ? ORDER BY created_at ASC')
348
+ .all(parentConversationId);
349
+ return this.mapAll(rows);
350
+ }
351
+
352
+ /**
353
+ * Get the branch point message for a conversation
354
+ * @param {string} conversationId - The conversation ID
355
+ * @returns {Object|null} The branch point message or null if not a branch
356
+ */
357
+ getBranchPointMessage(conversationId) {
358
+ const conv = this.getById(conversationId);
359
+ if (!conv || !conv.branchFromMessageId) {
360
+ return null;
361
+ }
362
+
363
+ const row = this.db
364
+ .prepare('SELECT * FROM conversation_messages WHERE id = ?')
365
+ .get(conv.branchFromMessageId);
366
+
367
+ if (!row) return null;
368
+
369
+ return {
370
+ id: row.id,
371
+ sessionId: row.session_id,
372
+ conversationId: row.conversation_id,
373
+ role: row.role,
374
+ content: row.content,
375
+ toolUse: row.tool_use ? JSON.parse(row.tool_use) : null,
376
+ timestamp: row.timestamp,
377
+ };
378
+ }
379
+ }
@@ -0,0 +1,91 @@
1
+ import Database from 'better-sqlite3';
2
+ import { readFileSync } from 'fs';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+ import crypto from 'crypto';
6
+ import { allMigrations } from './migrations/index.js';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ /**
12
+ * Database manager class - singleton pattern for managing SQLite connection
13
+ */
14
+ export class DatabaseManager {
15
+ #db = null;
16
+
17
+ /**
18
+ * Initialize database with WAL mode and foreign keys
19
+ * @param {string} dbPath - Path to database file (use ':memory:' for in-memory)
20
+ * @returns {Database.Database}
21
+ */
22
+ init(dbPath = 'circuschief.db') {
23
+ this.#db = new Database(dbPath);
24
+
25
+ // Enable WAL mode and foreign keys
26
+ this.#db.pragma('journal_mode = WAL');
27
+ this.#db.pragma('foreign_keys = ON');
28
+
29
+ // Run schema
30
+ const schema = readFileSync(join(__dirname, '..', 'schema.sql'), 'utf-8');
31
+ this.#db.exec(schema);
32
+
33
+ // Run migrations for existing databases
34
+ this.#runMigrations();
35
+
36
+ return this.#db;
37
+ }
38
+
39
+ /**
40
+ * Run database migrations for existing databases.
41
+ * Iterates over the flat, ordered list of migrations exported from
42
+ * the migrations/ directory.
43
+ * @private
44
+ */
45
+ #runMigrations() {
46
+ for (const migration of allMigrations) {
47
+ migration.up(this.#db);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Get the database instance
53
+ * @returns {Database.Database}
54
+ */
55
+ get() {
56
+ if (!this.#db) {
57
+ throw new Error('Database not initialized. Call init first.');
58
+ }
59
+ return this.#db;
60
+ }
61
+
62
+ /**
63
+ * Close the database connection
64
+ */
65
+ close() {
66
+ if (this.#db) {
67
+ this.#db.close();
68
+ this.#db = null;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Generate a UUID
74
+ * @returns {string}
75
+ */
76
+ generateId() {
77
+ return crypto.randomUUID();
78
+ }
79
+
80
+ /**
81
+ * Run a function inside a transaction
82
+ * @param {Function} fn - Function to run in transaction
83
+ * @returns {any}
84
+ */
85
+ transaction(fn) {
86
+ return this.get().transaction(fn)();
87
+ }
88
+ }
89
+
90
+ // Singleton instance
91
+ export const databaseManager = new DatabaseManager();
@@ -0,0 +1,92 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+
4
+ /**
5
+ * Kanban board repository class
6
+ */
7
+ export class KanbanBoardRepository extends BaseRepository {
8
+ constructor() {
9
+ super('kanban_boards', KanbanBoardRepository.#mapBoard);
10
+ }
11
+
12
+ static #mapBoard(row) {
13
+ return {
14
+ id: row.id,
15
+ projectId: row.project_id,
16
+ createdAt: row.created_at,
17
+ updatedAt: row.updated_at,
18
+ };
19
+ }
20
+
21
+ /**
22
+ * Get board by project ID
23
+ * @param {string} projectId
24
+ * @returns {Object|null}
25
+ */
26
+ getByProjectId(projectId) {
27
+ const row = this.db
28
+ .prepare('SELECT * FROM kanban_boards WHERE project_id = ?')
29
+ .get(projectId);
30
+ return this.map(row);
31
+ }
32
+
33
+ /**
34
+ * Create a new kanban board with default lanes
35
+ * @param {string} projectId
36
+ * @returns {Object}
37
+ */
38
+ create(projectId) {
39
+ const id = databaseManager.generateId();
40
+ const now = Date.now();
41
+
42
+ // Use a transaction to create board and default lanes together
43
+ return databaseManager.transaction(() => {
44
+ // Create the board
45
+ this.db
46
+ .prepare(
47
+ `INSERT INTO kanban_boards (id, project_id, created_at, updated_at)
48
+ VALUES (?, ?, ?, ?)`
49
+ )
50
+ .run(id, projectId, now, now);
51
+
52
+ // Create default lanes
53
+ const defaultLanes = ['To Do', 'In Progress', 'Review', 'Done'];
54
+ const insertLane = this.db.prepare(
55
+ `INSERT INTO kanban_lanes (id, board_id, name, sort_order, created_at, updated_at)
56
+ VALUES (?, ?, ?, ?, ?, ?)`
57
+ );
58
+
59
+ defaultLanes.forEach((name, index) => {
60
+ insertLane.run(databaseManager.generateId(), id, name, index, now, now);
61
+ });
62
+
63
+ return this.getById(id);
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Get or create a board for a project (lazy initialization)
69
+ * @param {string} projectId
70
+ * @returns {Object}
71
+ */
72
+ getOrCreateForProject(projectId) {
73
+ const existing = this.getByProjectId(projectId);
74
+ if (existing) {
75
+ return existing;
76
+ }
77
+ return this.create(projectId);
78
+ }
79
+
80
+ /**
81
+ * Delete a board and all its lanes and cards (cascade handled by FK)
82
+ * @param {string} id
83
+ */
84
+ delete(id) {
85
+ const now = Date.now();
86
+ // Update timestamp before delete for any listeners
87
+ this.db
88
+ .prepare('UPDATE kanban_boards SET updated_at = ? WHERE id = ?')
89
+ .run(now, id);
90
+ super.delete(id);
91
+ }
92
+ }