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,286 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+
4
+ /**
5
+ * Kanban card repository class
6
+ */
7
+ export class KanbanCardRepository extends BaseRepository {
8
+ constructor() {
9
+ super('kanban_cards', KanbanCardRepository.#mapCard);
10
+ }
11
+
12
+ static #mapCard(row) {
13
+ const card = {
14
+ id: row.id,
15
+ laneId: row.lane_id,
16
+ sortOrder: row.sort_order,
17
+ createdAt: row.created_at,
18
+ updatedAt: row.updated_at,
19
+ };
20
+
21
+ // If session data is joined, include it
22
+ if (row.session_id !== undefined) {
23
+ card.sessions = row.session_id
24
+ ? [
25
+ {
26
+ id: row.session_id,
27
+ name: row.session_name,
28
+ status: row.session_status,
29
+ mode: row.session_mode,
30
+ costUsd: row.session_cost_usd,
31
+ starred: Boolean(row.session_starred),
32
+ prUrl: row.session_pr_url,
33
+ createdAt: row.session_created_at,
34
+ updatedAt: row.session_updated_at,
35
+ },
36
+ ]
37
+ : [];
38
+ }
39
+
40
+ return card;
41
+ }
42
+
43
+ /**
44
+ * Get all cards for a lane with session data, ordered by sort_order
45
+ * @param {string} laneId
46
+ * @returns {Array}
47
+ */
48
+ getByLaneId(laneId) {
49
+ const rows = this.db
50
+ .prepare(
51
+ `SELECT kc.*,
52
+ kcs.session_id,
53
+ s.name as session_name,
54
+ s.status as session_status,
55
+ s.mode as session_mode,
56
+ s.cost_usd as session_cost_usd,
57
+ s.starred as session_starred,
58
+ s.pr_url as session_pr_url,
59
+ s.created_at as session_created_at,
60
+ s.updated_at as session_updated_at
61
+ FROM kanban_cards kc
62
+ LEFT JOIN kanban_card_sessions kcs ON kc.id = kcs.card_id
63
+ LEFT JOIN sessions s ON kcs.session_id = s.id
64
+ WHERE kc.lane_id = ?
65
+ ORDER BY kc.sort_order`
66
+ )
67
+ .all(laneId);
68
+ return this.mapAll(rows);
69
+ }
70
+
71
+ /**
72
+ * Get all cards for a board with session data
73
+ * @param {string} boardId
74
+ * @returns {Array}
75
+ */
76
+ getByBoardId(boardId) {
77
+ const rows = this.db
78
+ .prepare(
79
+ `SELECT kc.*,
80
+ kcs.session_id,
81
+ s.name as session_name,
82
+ s.status as session_status,
83
+ s.mode as session_mode,
84
+ s.cost_usd as session_cost_usd,
85
+ s.starred as session_starred,
86
+ s.pr_url as session_pr_url,
87
+ s.created_at as session_created_at,
88
+ s.updated_at as session_updated_at
89
+ FROM kanban_cards kc
90
+ JOIN kanban_lanes kl ON kc.lane_id = kl.id
91
+ LEFT JOIN kanban_card_sessions kcs ON kc.id = kcs.card_id
92
+ LEFT JOIN sessions s ON kcs.session_id = s.id
93
+ WHERE kl.board_id = ?
94
+ ORDER BY kl.sort_order, kc.sort_order`
95
+ )
96
+ .all(boardId);
97
+ return this.mapAll(rows);
98
+ }
99
+
100
+ /**
101
+ * Get the card for a specific session
102
+ * @param {string} sessionId
103
+ * @returns {Object|null}
104
+ */
105
+ getBySessionId(sessionId) {
106
+ const row = this.db
107
+ .prepare(
108
+ `SELECT kc.*,
109
+ kcs.session_id,
110
+ s.name as session_name,
111
+ s.status as session_status,
112
+ s.mode as session_mode,
113
+ s.cost_usd as session_cost_usd,
114
+ s.starred as session_starred,
115
+ s.pr_url as session_pr_url,
116
+ s.created_at as session_created_at,
117
+ s.updated_at as session_updated_at
118
+ FROM kanban_cards kc
119
+ JOIN kanban_card_sessions kcs ON kc.id = kcs.card_id
120
+ LEFT JOIN sessions s ON kcs.session_id = s.id
121
+ WHERE kcs.session_id = ?`
122
+ )
123
+ .get(sessionId);
124
+ return this.map(row);
125
+ }
126
+
127
+ /**
128
+ * Create a card for a session in a lane
129
+ * @param {string} laneId
130
+ * @param {string} sessionId
131
+ * @param {Object} [options]
132
+ * @param {number} [options.sortOrder]
133
+ * @returns {Object}
134
+ */
135
+ create(laneId, sessionId, options = {}) {
136
+ const cardId = databaseManager.generateId();
137
+ const cardSessionId = databaseManager.generateId();
138
+ const now = Date.now();
139
+
140
+ // If no sortOrder provided, put it at the end
141
+ let sortOrder = options.sortOrder;
142
+ if (sortOrder === undefined || sortOrder === null) {
143
+ const maxRow = this.db
144
+ .prepare('SELECT MAX(sort_order) as max_order FROM kanban_cards WHERE lane_id = ?')
145
+ .get(laneId);
146
+ sortOrder = (maxRow?.max_order ?? -1) + 1;
147
+ }
148
+
149
+ return databaseManager.transaction(() => {
150
+ // Create the card
151
+ this.db
152
+ .prepare(
153
+ `INSERT INTO kanban_cards (id, lane_id, sort_order, created_at, updated_at)
154
+ VALUES (?, ?, ?, ?, ?)`
155
+ )
156
+ .run(cardId, laneId, sortOrder, now, now);
157
+
158
+ // Link the session to the card
159
+ this.db
160
+ .prepare(
161
+ `INSERT INTO kanban_card_sessions (id, card_id, session_id, created_at)
162
+ VALUES (?, ?, ?, ?)`
163
+ )
164
+ .run(cardSessionId, cardId, sessionId, now);
165
+
166
+ return this.getBySessionId(sessionId);
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Move a card to a different lane
172
+ * @param {string} cardId
173
+ * @param {string} targetLaneId
174
+ * @param {number} [sortOrder]
175
+ * @returns {Object}
176
+ */
177
+ moveToLane(cardId, targetLaneId, sortOrder) {
178
+ const now = Date.now();
179
+
180
+ // If no sortOrder provided, put it at the end of the target lane
181
+ let order = sortOrder;
182
+ if (order === undefined || order === null) {
183
+ const maxRow = this.db
184
+ .prepare('SELECT MAX(sort_order) as max_order FROM kanban_cards WHERE lane_id = ?')
185
+ .get(targetLaneId);
186
+ order = (maxRow?.max_order ?? -1) + 1;
187
+ }
188
+
189
+ this.db
190
+ .prepare('UPDATE kanban_cards SET lane_id = ?, sort_order = ?, updated_at = ? WHERE id = ?')
191
+ .run(targetLaneId, order, now, cardId);
192
+
193
+ return this.getById(cardId);
194
+ }
195
+
196
+ /**
197
+ * Reorder cards within a lane
198
+ * @param {string} laneId
199
+ * @param {string[]} cardIds - Ordered array of card IDs
200
+ */
201
+ reorder(laneId, cardIds) {
202
+ const now = Date.now();
203
+
204
+ databaseManager.transaction(() => {
205
+ const updateStmt = this.db.prepare(
206
+ 'UPDATE kanban_cards SET sort_order = ?, updated_at = ? WHERE id = ? AND lane_id = ?'
207
+ );
208
+
209
+ cardIds.forEach((cardId, index) => {
210
+ updateStmt.run(index, now, cardId, laneId);
211
+ });
212
+ });
213
+ }
214
+
215
+ /**
216
+ * Delete a card (does not delete the session)
217
+ * @param {string} cardId
218
+ */
219
+ delete(cardId) {
220
+ super.delete(cardId);
221
+ }
222
+
223
+ /**
224
+ * Get card by ID with full session data
225
+ * @param {string} id
226
+ * @returns {Object|null}
227
+ */
228
+ getById(id) {
229
+ const row = this.db
230
+ .prepare(
231
+ `SELECT kc.*,
232
+ kcs.session_id,
233
+ s.name as session_name,
234
+ s.status as session_status,
235
+ s.mode as session_mode,
236
+ s.cost_usd as session_cost_usd,
237
+ s.starred as session_starred,
238
+ s.pr_url as session_pr_url,
239
+ s.created_at as session_created_at,
240
+ s.updated_at as session_updated_at
241
+ FROM kanban_cards kc
242
+ LEFT JOIN kanban_card_sessions kcs ON kc.id = kcs.card_id
243
+ LEFT JOIN sessions s ON kcs.session_id = s.id
244
+ WHERE kc.id = ?`
245
+ )
246
+ .get(id);
247
+ return this.map(row);
248
+ }
249
+
250
+ /**
251
+ * Get card with lane info (useful for knowing current lane when moving)
252
+ * @param {string} id
253
+ * @returns {Object|null}
254
+ */
255
+ getByIdWithLane(id) {
256
+ const row = this.db
257
+ .prepare(
258
+ `SELECT kc.*,
259
+ kl.board_id,
260
+ kl.name as lane_name,
261
+ kcs.session_id,
262
+ s.name as session_name,
263
+ s.status as session_status,
264
+ s.mode as session_mode,
265
+ s.cost_usd as session_cost_usd,
266
+ s.starred as session_starred,
267
+ s.pr_url as session_pr_url,
268
+ s.created_at as session_created_at,
269
+ s.updated_at as session_updated_at
270
+ FROM kanban_cards kc
271
+ JOIN kanban_lanes kl ON kc.lane_id = kl.id
272
+ LEFT JOIN kanban_card_sessions kcs ON kc.id = kcs.card_id
273
+ LEFT JOIN sessions s ON kcs.session_id = s.id
274
+ WHERE kc.id = ?`
275
+ )
276
+ .get(id);
277
+
278
+ if (!row) return null;
279
+
280
+ return {
281
+ ...this.map(row),
282
+ boardId: row.board_id,
283
+ laneName: row.lane_name,
284
+ };
285
+ }
286
+ }
@@ -0,0 +1,279 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+
4
+ /**
5
+ * Convert a boolean value to SQLite integer (1/0) or null.
6
+ * @param {boolean|null|undefined} value
7
+ * @param {number|null} [defaultValue] - Default value if undefined
8
+ * @returns {number|null}
9
+ */
10
+ function boolToSqlite(value, defaultValue = null) {
11
+ if (value === undefined) return defaultValue;
12
+ if (value === null) return null;
13
+ return value ? 1 : 0;
14
+ }
15
+
16
+ /**
17
+ * Prepare lane insert values from data object.
18
+ * @param {Object} data - Lane data
19
+ * @returns {Array} Array of values for INSERT
20
+ */
21
+ function prepareLaneValues(data) {
22
+ return [
23
+ data.onEnterTemplateId || null,
24
+ data.onEnterPrompt || null,
25
+ data.onEnterMode || null,
26
+ data.onEnterModel || null,
27
+ data.onEnterEffortLevel || null,
28
+ boolToSqlite(data.onEnterThinkingEnabled),
29
+ data.onEnterAutoRescheduleEnabled ? 1 : 0,
30
+ data.onEnterRescheduleDelayMinutes ?? 15,
31
+ boolToSqlite(data.onEnterRescheduleOnTokenLimit, 1),
32
+ boolToSqlite(data.onEnterRescheduleOnServiceError, 1),
33
+ data.onEnterMaxRescheduleCount ?? null,
34
+ data.onEnterMaxTotalTokens ?? null,
35
+ data.onEnterRescheduleAtTokenCount ?? null,
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * Boolean field configurations for update operations.
41
+ * - nullable: true means null values are preserved (converts to null in DB)
42
+ * - nullable: false means values are coerced to 0/1
43
+ */
44
+ const BOOLEAN_FIELDS = {
45
+ onEnterThinkingEnabled: { nullable: true },
46
+ onEnterAutoRescheduleEnabled: { nullable: false },
47
+ onEnterRescheduleOnTokenLimit: { nullable: false },
48
+ onEnterRescheduleOnServiceError: { nullable: false },
49
+ };
50
+
51
+ /**
52
+ * Convert a field value for SQL update, handling booleans specially.
53
+ * @param {string} fieldName - The camelCase field name
54
+ * @param {*} value - The value to convert
55
+ * @returns {*} The converted value
56
+ */
57
+ function convertFieldValue(fieldName, value) {
58
+ const boolConfig = BOOLEAN_FIELDS[fieldName];
59
+ if (!boolConfig) {
60
+ return value;
61
+ }
62
+ if (boolConfig.nullable && value === null) {
63
+ return null;
64
+ }
65
+ return value ? 1 : 0;
66
+ }
67
+
68
+ /**
69
+ * Kanban lane repository class
70
+ */
71
+ export class KanbanLaneRepository extends BaseRepository {
72
+ constructor() {
73
+ super('kanban_lanes', KanbanLaneRepository.#mapLane);
74
+ }
75
+
76
+ static #mapLane(row) {
77
+ return {
78
+ id: row.id,
79
+ boardId: row.board_id,
80
+ name: row.name,
81
+ sortOrder: row.sort_order,
82
+ onEnterTemplateId: row.on_enter_template_id,
83
+ onEnterPrompt: row.on_enter_prompt,
84
+ onEnterMode: row.on_enter_mode,
85
+ onEnterModel: row.on_enter_model,
86
+ onEnterEffortLevel: row.on_enter_effort_level,
87
+ onEnterThinkingEnabled: row.on_enter_thinking_enabled === null ? null : Boolean(row.on_enter_thinking_enabled),
88
+ onEnterAutoRescheduleEnabled: Boolean(row.on_enter_auto_reschedule_enabled),
89
+ onEnterRescheduleDelayMinutes: row.on_enter_reschedule_delay_minutes,
90
+ onEnterRescheduleOnTokenLimit: row.on_enter_reschedule_on_token_limit === null ? null : Boolean(row.on_enter_reschedule_on_token_limit),
91
+ onEnterRescheduleOnServiceError: row.on_enter_reschedule_on_service_error === null ? null : Boolean(row.on_enter_reschedule_on_service_error),
92
+ onEnterMaxRescheduleCount: row.on_enter_max_reschedule_count,
93
+ onEnterMaxTotalTokens: row.on_enter_max_total_tokens,
94
+ onEnterRescheduleAtTokenCount: row.on_enter_reschedule_at_token_count,
95
+ createdAt: row.created_at,
96
+ updatedAt: row.updated_at,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Get all lanes for a board, ordered by sort_order
102
+ * @param {string} boardId
103
+ * @returns {Array}
104
+ */
105
+ getByBoardId(boardId) {
106
+ const rows = this.db
107
+ .prepare('SELECT * FROM kanban_lanes WHERE board_id = ? ORDER BY sort_order')
108
+ .all(boardId);
109
+ return this.mapAll(rows);
110
+ }
111
+
112
+ /**
113
+ * Create a new lane
114
+ * @param {string} boardId
115
+ * @param {Object} data
116
+ * @param {string} data.name
117
+ * @param {number} [data.sortOrder]
118
+ * @param {string|null} [data.onEnterTemplateId]
119
+ * @param {string|null} [data.onEnterPrompt]
120
+ * @returns {Object}
121
+ */
122
+ create(boardId, data) {
123
+ const id = databaseManager.generateId();
124
+ const now = Date.now();
125
+ const sortOrder = this.#resolveSortOrder(boardId, data.sortOrder);
126
+ const laneValues = prepareLaneValues(data);
127
+
128
+ this.db
129
+ .prepare(
130
+ `INSERT INTO kanban_lanes (
131
+ id, board_id, name, sort_order, on_enter_template_id, on_enter_prompt,
132
+ on_enter_mode, on_enter_model, on_enter_effort_level, on_enter_thinking_enabled,
133
+ on_enter_auto_reschedule_enabled, on_enter_reschedule_delay_minutes,
134
+ on_enter_reschedule_on_token_limit, on_enter_reschedule_on_service_error,
135
+ on_enter_max_reschedule_count, on_enter_max_total_tokens,
136
+ on_enter_reschedule_at_token_count,
137
+ created_at, updated_at
138
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
139
+ )
140
+ .run(id, boardId, data.name, sortOrder, ...laneValues, now, now);
141
+
142
+ return this.getById(id);
143
+ }
144
+
145
+ /**
146
+ * Resolve sort order, defaulting to end of list if not provided.
147
+ * @param {string} boardId
148
+ * @param {number|undefined|null} sortOrder
149
+ * @returns {number}
150
+ */
151
+ #resolveSortOrder(boardId, sortOrder) {
152
+ if (sortOrder !== undefined && sortOrder !== null) {
153
+ return sortOrder;
154
+ }
155
+ const maxRow = this.db
156
+ .prepare('SELECT MAX(sort_order) as max_order FROM kanban_lanes WHERE board_id = ?')
157
+ .get(boardId);
158
+ return (maxRow?.max_order ?? -1) + 1;
159
+ }
160
+
161
+ /**
162
+ * Update a lane
163
+ * @param {string} id
164
+ * @param {Object} data
165
+ * @param {string} [data.name]
166
+ * @param {number} [data.sortOrder]
167
+ * @param {string|null} [data.onEnterTemplateId]
168
+ * @param {string|null} [data.onEnterPrompt]
169
+ * @returns {Object}
170
+ */
171
+ update(id, data) {
172
+ // Field mapping: camelCase -> snake_case
173
+ const fieldMap = {
174
+ name: 'name',
175
+ sortOrder: 'sort_order',
176
+ onEnterTemplateId: 'on_enter_template_id',
177
+ onEnterPrompt: 'on_enter_prompt',
178
+ onEnterMode: 'on_enter_mode',
179
+ onEnterModel: 'on_enter_model',
180
+ onEnterEffortLevel: 'on_enter_effort_level',
181
+ onEnterThinkingEnabled: 'on_enter_thinking_enabled',
182
+ onEnterAutoRescheduleEnabled: 'on_enter_auto_reschedule_enabled',
183
+ onEnterRescheduleDelayMinutes: 'on_enter_reschedule_delay_minutes',
184
+ onEnterRescheduleOnTokenLimit: 'on_enter_reschedule_on_token_limit',
185
+ onEnterRescheduleOnServiceError: 'on_enter_reschedule_on_service_error',
186
+ onEnterMaxRescheduleCount: 'on_enter_max_reschedule_count',
187
+ onEnterMaxTotalTokens: 'on_enter_max_total_tokens',
188
+ onEnterRescheduleAtTokenCount: 'on_enter_reschedule_at_token_count',
189
+ };
190
+
191
+ const updates = [];
192
+ const values = [];
193
+
194
+ // Build update clauses dynamically
195
+ for (const [camelKey, snakeKey] of Object.entries(fieldMap)) {
196
+ if (data[camelKey] !== undefined) {
197
+ updates.push(`${snakeKey} = ?`);
198
+ values.push(convertFieldValue(camelKey, data[camelKey]));
199
+ }
200
+ }
201
+
202
+ if (updates.length === 0) return this.getById(id);
203
+
204
+ updates.push('updated_at = ?');
205
+ values.push(Date.now());
206
+ values.push(id);
207
+
208
+ this.db.prepare(`UPDATE kanban_lanes SET ${updates.join(', ')} WHERE id = ?`).run(...values);
209
+
210
+ return this.getById(id);
211
+ }
212
+
213
+ /**
214
+ * Reorder lanes based on an array of lane IDs
215
+ * @param {string} boardId
216
+ * @param {string[]} laneIds - Ordered array of lane IDs
217
+ */
218
+ reorder(boardId, laneIds) {
219
+ const now = Date.now();
220
+
221
+ databaseManager.transaction(() => {
222
+ const updateStmt = this.db.prepare(
223
+ 'UPDATE kanban_lanes SET sort_order = ?, updated_at = ? WHERE id = ? AND board_id = ?'
224
+ );
225
+
226
+ laneIds.forEach((laneId, index) => {
227
+ updateStmt.run(index, now, laneId, boardId);
228
+ });
229
+ });
230
+ }
231
+
232
+ /**
233
+ * Get a single lane with its board info
234
+ * @param {string} id
235
+ * @returns {Object|null}
236
+ */
237
+ getById(id) {
238
+ const row = this.db.prepare('SELECT * FROM kanban_lanes WHERE id = ?').get(id);
239
+ return this.map(row);
240
+ }
241
+
242
+ /**
243
+ * Get lane by ID with template info (for on-enter triggers)
244
+ * @param {string} id
245
+ * @returns {Object|null}
246
+ */
247
+ getByIdWithTemplate(id) {
248
+ const row = this.db
249
+ .prepare(
250
+ `SELECT kl.*, st.name as template_name, st.prompt as template_prompt
251
+ FROM kanban_lanes kl
252
+ LEFT JOIN session_templates st ON kl.on_enter_template_id = st.id
253
+ WHERE kl.id = ?`
254
+ )
255
+ .get(id);
256
+
257
+ if (!row) return null;
258
+
259
+ const mappedLane = this.map(row);
260
+ return {
261
+ ...mappedLane,
262
+ template: row.template_name
263
+ ? {
264
+ id: row.on_enter_template_id,
265
+ name: row.template_name,
266
+ prompt: row.template_prompt,
267
+ }
268
+ : null,
269
+ };
270
+ }
271
+
272
+ /**
273
+ * Delete a lane
274
+ * @param {string} id
275
+ */
276
+ delete(id) {
277
+ super.delete(id);
278
+ }
279
+ }