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,109 @@
1
+ /**
2
+ * Migrations for the canvas_items table.
3
+ * Each export is an array of { name, up(db) } migration objects.
4
+ */
5
+ import { addColumnIfMissing, getColumns, getTableSql } from './migrationUtils.js';
6
+
7
+ /**
8
+ * Migrate canvas_items table to include 'code' in type CHECK constraint.
9
+ * SQLite doesn't support ALTER TABLE to modify constraints, so we recreate the table.
10
+ */
11
+ function migrateCanvasItemsTypeConstraint(db) {
12
+ const tableSql = getTableSql(db, 'canvas_items');
13
+
14
+ // If schema already includes 'code', no migration needed
15
+ if (tableSql?.includes("'code'")) {
16
+ return;
17
+ }
18
+
19
+ db.exec(`
20
+ CREATE TABLE canvas_items_new (
21
+ id TEXT PRIMARY KEY,
22
+ session_id TEXT REFERENCES sessions(id) ON DELETE CASCADE,
23
+ type TEXT NOT NULL CHECK (type IN ('image', 'markdown', 'text', 'json', 'pdf', 'code')),
24
+ content TEXT,
25
+ data TEXT,
26
+ mime_type TEXT,
27
+ filename TEXT,
28
+ label TEXT,
29
+ width INTEGER,
30
+ height INTEGER,
31
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
32
+ );
33
+
34
+ INSERT INTO canvas_items_new SELECT * FROM canvas_items;
35
+
36
+ DROP TABLE canvas_items;
37
+
38
+ ALTER TABLE canvas_items_new RENAME TO canvas_items;
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_canvas_session ON canvas_items(session_id);
41
+ `);
42
+ }
43
+
44
+ /**
45
+ * Migrate canvas_items table to drop label column.
46
+ */
47
+ function migrateCanvasItemsDropLabel(db) {
48
+ const columns = getColumns(db, 'canvas_items');
49
+
50
+ // If label column doesn't exist, migration already done
51
+ if (!columns.includes('label')) {
52
+ return;
53
+ }
54
+
55
+ db.exec(`
56
+ CREATE TABLE canvas_items_new (
57
+ id TEXT PRIMARY KEY,
58
+ session_id TEXT REFERENCES sessions(id) ON DELETE CASCADE,
59
+ type TEXT NOT NULL CHECK (type IN ('image', 'markdown', 'text', 'json', 'pdf', 'code')),
60
+ content TEXT,
61
+ data TEXT,
62
+ mime_type TEXT,
63
+ filename TEXT,
64
+ width INTEGER,
65
+ height INTEGER,
66
+ deleted_at INTEGER,
67
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
68
+ );
69
+
70
+ INSERT INTO canvas_items_new (id, session_id, type, content, data, mime_type, filename, width, height, deleted_at, created_at)
71
+ SELECT id, session_id, type, content, data, mime_type, filename, width, height, deleted_at, created_at FROM canvas_items;
72
+
73
+ DROP TABLE canvas_items;
74
+
75
+ ALTER TABLE canvas_items_new RENAME TO canvas_items;
76
+
77
+ CREATE INDEX IF NOT EXISTS idx_canvas_session ON canvas_items(session_id);
78
+ CREATE INDEX IF NOT EXISTS idx_canvas_deleted ON canvas_items(deleted_at);
79
+ `);
80
+ }
81
+
82
+ /** @type {Array<{name: string, up: (db: import('better-sqlite3').Database) => void}>} */
83
+ export const canvasItemsMigrations = [
84
+ {
85
+ name: 'canvas_items-migrate-type-constraint',
86
+ up(db) { migrateCanvasItemsTypeConstraint(db); },
87
+ },
88
+ {
89
+ name: 'canvas_items-add-deleted_at',
90
+ up(db) {
91
+ addColumnIfMissing(db, 'canvas_items', 'deleted_at', 'INTEGER');
92
+ db.exec('CREATE INDEX IF NOT EXISTS idx_canvas_deleted ON canvas_items(deleted_at)');
93
+ },
94
+ },
95
+ {
96
+ name: 'canvas_items-drop-label',
97
+ up(db) { migrateCanvasItemsDropLabel(db); },
98
+ },
99
+ {
100
+ name: 'canvas_items-add-updated_at',
101
+ up(db) {
102
+ const columns = getColumns(db, 'canvas_items');
103
+ if (!columns.includes('updated_at')) {
104
+ db.exec('ALTER TABLE canvas_items ADD COLUMN updated_at INTEGER');
105
+ db.exec('UPDATE canvas_items SET updated_at = created_at WHERE updated_at IS NULL');
106
+ }
107
+ },
108
+ },
109
+ ];
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Migrations for the conversations, conversation_messages, and message_attachments tables.
3
+ * Each export is an array of { name, up(db) } migration objects.
4
+ */
5
+ import crypto from 'crypto';
6
+ import { addColumnIfMissing, getColumns } from './migrationUtils.js';
7
+
8
+ // Table name constants for migrations
9
+ const TABLE_CONVERSATIONS = 'conversations';
10
+
11
+ // Column type constants
12
+ const COL_INTEGER_DEFAULT_0 = 'INTEGER DEFAULT 0';
13
+
14
+ /**
15
+ * Create default conversations for existing sessions that don't have any
16
+ * and associate orphaned messages with the default conversation.
17
+ */
18
+ function migrateExistingSessionsToConversations(db) {
19
+ const sessionsWithoutConversations = db
20
+ .prepare(
21
+ `
22
+ SELECT DISTINCT s.id FROM sessions s
23
+ LEFT JOIN conversations c ON c.session_id = s.id
24
+ WHERE c.id IS NULL
25
+ AND EXISTS (SELECT 1 FROM conversation_messages m WHERE m.session_id = s.id)
26
+ `
27
+ )
28
+ .all();
29
+
30
+ for (const session of sessionsWithoutConversations) {
31
+ const convId = crypto.randomUUID();
32
+ const now = Date.now();
33
+
34
+ db.prepare(
35
+ `INSERT INTO conversations (id, session_id, name, is_active, created_at, updated_at)
36
+ VALUES (?, ?, ?, 1, ?, ?)`
37
+ ).run(convId, session.id, 'Initial', now, now);
38
+
39
+ db.prepare(
40
+ `UPDATE conversation_messages SET conversation_id = ? WHERE session_id = ? AND conversation_id IS NULL`
41
+ ).run(convId, session.id);
42
+ }
43
+ }
44
+
45
+ /** @type {Array<{name: string, up: (db: import('better-sqlite3').Database) => void}>} */
46
+ export const conversationsMigrations = [
47
+ // --- Session summaries PR columns ---
48
+ {
49
+ name: 'session_summaries-add-pr_merged',
50
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'pr_merged', 'INTEGER'); },
51
+ },
52
+ {
53
+ name: 'session_summaries-add-pr_state',
54
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'pr_state', 'TEXT'); },
55
+ },
56
+ {
57
+ name: 'session_summaries-add-has_merge_conflicts',
58
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'has_merge_conflicts', 'INTEGER'); },
59
+ },
60
+ {
61
+ name: 'session_summaries-add-ci_status',
62
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'ci_status', 'TEXT'); },
63
+ },
64
+ {
65
+ name: 'session_summaries-add-ci_failures',
66
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'ci_failures', 'TEXT'); },
67
+ },
68
+ {
69
+ name: 'session_summaries-add-last_summarized_message_id',
70
+ up(db) { addColumnIfMissing(db, 'session_summaries', 'last_summarized_message_id', 'TEXT'); },
71
+ },
72
+
73
+ // --- Message attachments ---
74
+ {
75
+ name: 'message_attachments-add-file_path',
76
+ up(db) { addColumnIfMissing(db, 'message_attachments', 'file_path', 'TEXT'); },
77
+ },
78
+
79
+ // --- Conversation messages: conversation_id ---
80
+ {
81
+ name: 'conversation_messages-add-conversation_id',
82
+ up(db) {
83
+ const columns = getColumns(db, 'conversation_messages');
84
+ if (!columns.includes('conversation_id')) {
85
+ db.exec(
86
+ 'ALTER TABLE conversation_messages ADD COLUMN conversation_id TEXT REFERENCES conversations(id) ON DELETE CASCADE'
87
+ );
88
+ db.exec(
89
+ 'CREATE INDEX IF NOT EXISTS idx_messages_conversation ON conversation_messages(conversation_id)'
90
+ );
91
+ }
92
+ },
93
+ },
94
+
95
+ // --- Migrate existing sessions to conversations ---
96
+ {
97
+ name: 'conversations-migrate-existing-sessions',
98
+ up(db) { migrateExistingSessionsToConversations(db); },
99
+ },
100
+
101
+ // --- Conversations: claude_session_id ---
102
+ {
103
+ name: 'conversations-add-claude_session_id',
104
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'claude_session_id', 'TEXT'); },
105
+ },
106
+
107
+ // --- Conversations token usage ---
108
+ {
109
+ name: 'conversations-add-input_tokens',
110
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'input_tokens', COL_INTEGER_DEFAULT_0); },
111
+ },
112
+ {
113
+ name: 'conversations-add-output_tokens',
114
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'output_tokens', COL_INTEGER_DEFAULT_0); },
115
+ },
116
+ {
117
+ name: 'conversations-add-cache_read_input_tokens',
118
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'cache_read_input_tokens', COL_INTEGER_DEFAULT_0); },
119
+ },
120
+ {
121
+ name: 'conversations-add-cache_creation_input_tokens',
122
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'cache_creation_input_tokens', COL_INTEGER_DEFAULT_0); },
123
+ },
124
+ {
125
+ name: 'conversations-add-web_search_requests',
126
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'web_search_requests', COL_INTEGER_DEFAULT_0); },
127
+ },
128
+ {
129
+ name: 'conversations-add-context_window',
130
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'context_window', 'INTEGER DEFAULT 200000'); },
131
+ },
132
+ {
133
+ name: 'conversations-add-model',
134
+ up(db) { addColumnIfMissing(db, TABLE_CONVERSATIONS, 'model', 'TEXT'); },
135
+ },
136
+
137
+ // --- Conversation branching ---
138
+ {
139
+ name: 'conversations-add-parent_conversation_id',
140
+ up(db) {
141
+ const columns = getColumns(db, TABLE_CONVERSATIONS);
142
+ if (!columns.includes('parent_conversation_id')) {
143
+ db.exec(
144
+ 'ALTER TABLE conversations ADD COLUMN parent_conversation_id TEXT REFERENCES conversations(id) ON DELETE SET NULL'
145
+ );
146
+ db.exec(
147
+ 'CREATE INDEX IF NOT EXISTS idx_conversations_parent ON conversations(parent_conversation_id)'
148
+ );
149
+ }
150
+ },
151
+ },
152
+ {
153
+ name: 'conversations-add-branch_from_message_id',
154
+ up(db) {
155
+ addColumnIfMissing(
156
+ db, TABLE_CONVERSATIONS, 'branch_from_message_id',
157
+ 'TEXT REFERENCES conversation_messages(id) ON DELETE SET NULL'
158
+ );
159
+ },
160
+ },
161
+
162
+ // --- Session todos: conversation_id ---
163
+ {
164
+ name: 'session_todos-add-conversation_id',
165
+ up(db) {
166
+ const columns = getColumns(db, 'session_todos');
167
+ if (!columns.includes('conversation_id')) {
168
+ db.exec(
169
+ 'ALTER TABLE session_todos ADD COLUMN conversation_id TEXT REFERENCES conversations(id) ON DELETE CASCADE'
170
+ );
171
+ db.exec(
172
+ 'CREATE INDEX IF NOT EXISTS idx_todos_conversation ON session_todos(conversation_id)'
173
+ );
174
+ }
175
+ },
176
+ },
177
+
178
+ // --- Conversation messages: model ---
179
+ {
180
+ name: 'conversation_messages-add-model',
181
+ up(db) { addColumnIfMissing(db, 'conversation_messages', 'model', 'TEXT'); },
182
+ },
183
+ ];
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Central registry of all database migrations in execution order.
3
+ *
4
+ * Each migration is idempotent (checks before acting), so the exact ordering
5
+ * only matters where there are hard dependencies (e.g. a table must exist
6
+ * before a column references it via FK).
7
+ *
8
+ * The ordering below mirrors the original #runMigrations() top-to-bottom flow
9
+ * as closely as possible.
10
+ */
11
+ import { sessionsMigrations } from './sessionsMigrations.js';
12
+ import { projectsMigrations } from './projectsMigrations.js';
13
+ import { conversationsMigrations } from './conversationsMigrations.js';
14
+ import { canvasItemsMigrations } from './canvasItemsMigrations.js';
15
+ import { miscMigrations } from './miscMigrations.js';
16
+ import { kanbanMigrations } from './kanbanMigrations.js';
17
+
18
+ /**
19
+ * Build a lookup map from a migrations array keyed by migration name.
20
+ * @param {Array<{name: string, up: Function}>} migrations
21
+ * @returns {Map<string, {name: string, up: Function}>}
22
+ */
23
+ function toLookup(migrations) {
24
+ const map = new Map();
25
+ for (const m of migrations) {
26
+ map.set(m.name, m);
27
+ }
28
+ return map;
29
+ }
30
+
31
+ const s = toLookup(sessionsMigrations);
32
+ const p = toLookup(projectsMigrations);
33
+ const c = toLookup(conversationsMigrations);
34
+ const ci = toLookup(canvasItemsMigrations);
35
+ const m = toLookup(miscMigrations);
36
+ const k = toLookup(kanbanMigrations);
37
+
38
+ /**
39
+ * Flat, ordered list of every migration, matching the original execution order
40
+ * from DatabaseManager.#runMigrations().
41
+ *
42
+ * @type {Array<{name: string, up: (db: import('better-sqlite3').Database) => void}>}
43
+ */
44
+ // Validate that all migrations are properly defined
45
+ function validateMigrations(migrationsArray) {
46
+ for (const migration of migrationsArray) {
47
+ if (!migration || typeof migration.up !== 'function') {
48
+ const name = migration?.name || 'unknown';
49
+ throw new Error(`Migration "${name}" is undefined or missing an up() function`);
50
+ }
51
+ }
52
+ return migrationsArray;
53
+ }
54
+
55
+ export const allMigrations = validateMigrations([
56
+ // --- Sessions initial columns ---
57
+ s.get('sessions-add-cost_usd'),
58
+ s.get('sessions-add-claude_session_id'),
59
+ s.get('sessions-add-model'),
60
+ s.get('sessions-add-provider_id-early'),
61
+ s.get('sessions-add-effort_level'),
62
+
63
+ // --- Projects columns ---
64
+ p.get('projects-add-system_prompt'),
65
+ p.get('projects-add-on_session_created'),
66
+ p.get('projects-add-on_session_deleted'),
67
+ p.get('projects-add-repo_url'),
68
+ p.get('projects-drop-summary-columns'),
69
+
70
+ // --- Sessions scheduling columns ---
71
+ s.get('sessions-add-scheduled_at'),
72
+ s.get('sessions-add-reschedule_delay_minutes'),
73
+ s.get('sessions-add-auto_reschedule_enabled'),
74
+ s.get('sessions-add-reschedule_on_token_limit'),
75
+ s.get('sessions-add-reschedule_on_service_error'),
76
+ s.get('sessions-add-max_reschedule_count'),
77
+ s.get('sessions-add-max_total_tokens'),
78
+ s.get('sessions-add-reschedule_count'),
79
+ s.get('sessions-add-reschedule_at_token_count'),
80
+
81
+ // --- Sessions status constraint migration (table recreation) ---
82
+ s.get('sessions-migrate-status-constraint'),
83
+
84
+ // --- Session summaries PR columns ---
85
+ c.get('session_summaries-add-pr_merged'),
86
+ c.get('session_summaries-add-pr_state'),
87
+ c.get('session_summaries-add-has_merge_conflicts'),
88
+ c.get('session_summaries-add-ci_status'),
89
+ c.get('session_summaries-add-ci_failures'),
90
+ c.get('session_summaries-add-last_summarized_message_id'),
91
+
92
+ // --- Sessions template chaining ---
93
+ s.get('sessions-add-next_template_id'),
94
+ s.get('sessions-add-parent_session_id'),
95
+ s.get('sessions-template-chaining-indexes'),
96
+
97
+ // --- Message attachments ---
98
+ c.get('message_attachments-add-file_path'),
99
+
100
+ // --- Conversation messages: conversation_id ---
101
+ c.get('conversation_messages-add-conversation_id'),
102
+
103
+ // --- Migrate existing sessions to conversations ---
104
+ c.get('conversations-migrate-existing-sessions'),
105
+
106
+ // --- Canvas items ---
107
+ ci.get('canvas_items-migrate-type-constraint'),
108
+ ci.get('canvas_items-add-deleted_at'),
109
+ ci.get('canvas_items-drop-label'),
110
+ ci.get('canvas_items-add-updated_at'),
111
+
112
+ // --- Conversations: claude_session_id + token usage ---
113
+ c.get('conversations-add-claude_session_id'),
114
+ c.get('conversations-add-input_tokens'),
115
+ c.get('conversations-add-output_tokens'),
116
+ c.get('conversations-add-cache_read_input_tokens'),
117
+ c.get('conversations-add-cache_creation_input_tokens'),
118
+ c.get('conversations-add-web_search_requests'),
119
+ c.get('conversations-add-context_window'),
120
+ c.get('conversations-add-model'),
121
+
122
+ // --- Sessions token usage ---
123
+ s.get('sessions-add-input_tokens'),
124
+ s.get('sessions-add-output_tokens'),
125
+ s.get('sessions-add-cache_read_input_tokens'),
126
+ s.get('sessions-add-cache_creation_input_tokens'),
127
+ s.get('sessions-add-web_search_requests'),
128
+ s.get('sessions-add-context_window'),
129
+
130
+ // --- Sessions archived / starred / manually_named ---
131
+ s.get('sessions-add-archived'),
132
+ s.get('sessions-add-starred'),
133
+ s.get('sessions-add-manually_named'),
134
+
135
+ // --- Project session defaults table ---
136
+ p.get('project_session_defaults-create-table'),
137
+
138
+ // --- Command buttons ---
139
+ m.get('command_buttons-add-show_on_list'),
140
+
141
+ // --- Session todos ---
142
+ c.get('session_todos-add-conversation_id'),
143
+
144
+ // --- Conversation branching ---
145
+ c.get('conversations-add-parent_conversation_id'),
146
+ c.get('conversations-add-branch_from_message_id'),
147
+
148
+ // --- Sessions pending prompt / slash commands / pending model / auto send ---
149
+ s.get('sessions-add-pending_prompt'),
150
+ s.get('sessions-add-slash_commands'),
151
+ s.get('sessions-add-pending_model'),
152
+ s.get('sessions-add-auto_send_pending_prompt'),
153
+
154
+ // --- Session templates ---
155
+ m.get('session_templates-add-model'),
156
+ m.get('session_templates-add-mode'),
157
+ m.get('session_templates-add-effort_level'),
158
+
159
+ // --- Conversation messages model ---
160
+ c.get('conversation_messages-add-model'),
161
+
162
+ // --- App settings table ---
163
+ m.get('app_settings-create-table'),
164
+
165
+ // --- Legacy model_providers cleanup ---
166
+ m.get('model_providers-cleanup-legacy'),
167
+
168
+ // --- Providers + provider_models tables + seed ---
169
+ m.get('providers-create-tables'),
170
+ m.get('providers-seed-built-in'),
171
+
172
+ // --- Sessions provider_id (from providers FK) ---
173
+ s.get('sessions-add-provider_id-from-providers'),
174
+
175
+ // --- Project session defaults provider_id / effort_level ---
176
+ p.get('project_session_defaults-add-provider_id'),
177
+ p.get('project_session_defaults-add-effort_level'),
178
+
179
+ // --- Update built-in models ---
180
+ m.get('providers-update-built-in-models'),
181
+
182
+ // --- Sessions agent_type ---
183
+ s.get('sessions-add-agent_type'),
184
+
185
+ // --- Agent call logs table ---
186
+ m.get('agent_call_logs-create-table'),
187
+
188
+ // --- Kanban feature ---
189
+ k.get('projects-add-kanban_enabled'),
190
+ k.get('kanban-create-tables'),
191
+ k.get('sessions-add-target_lane_id'),
192
+ k.get('sessions-add-lane_trigger_depth'),
193
+ k.get('session_templates-add-target_lane_id'),
194
+ k.get('kanban_lanes-add-on_enter_prompt'),
195
+ k.get('kanban_lanes-add-agent-settings'),
196
+
197
+ // --- Seed default global quick responses ---
198
+ m.get('quick_responses-seed-defaults'),
199
+ ]);
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Migrations for Kanban board feature: kanban_boards, kanban_lanes,
3
+ * kanban_cards, kanban_card_sessions tables, and related columns on
4
+ * projects, sessions, and session_templates.
5
+ */
6
+ import { addColumnIfMissing } from './migrationUtils.js';
7
+
8
+ export const kanbanMigrations = [
9
+ {
10
+ name: 'projects-add-kanban_enabled',
11
+ up(db) {
12
+ addColumnIfMissing(db, 'projects', 'kanban_enabled', 'INTEGER NOT NULL DEFAULT 1');
13
+ },
14
+ },
15
+ {
16
+ name: 'kanban-create-tables',
17
+ up(db) {
18
+ db.exec(`
19
+ CREATE TABLE IF NOT EXISTS kanban_boards (
20
+ id TEXT PRIMARY KEY,
21
+ project_id TEXT NOT NULL UNIQUE REFERENCES projects(id) ON DELETE CASCADE,
22
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),
23
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
24
+ );
25
+
26
+ CREATE TABLE IF NOT EXISTS kanban_lanes (
27
+ id TEXT PRIMARY KEY,
28
+ board_id TEXT NOT NULL REFERENCES kanban_boards(id) ON DELETE CASCADE,
29
+ name TEXT NOT NULL,
30
+ sort_order INTEGER NOT NULL DEFAULT 0,
31
+ on_enter_template_id TEXT REFERENCES session_templates(id) ON DELETE SET NULL,
32
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),
33
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
34
+ );
35
+
36
+ CREATE TABLE IF NOT EXISTS kanban_cards (
37
+ id TEXT PRIMARY KEY,
38
+ lane_id TEXT NOT NULL REFERENCES kanban_lanes(id) ON DELETE CASCADE,
39
+ sort_order INTEGER NOT NULL DEFAULT 0,
40
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),
41
+ updated_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
42
+ );
43
+
44
+ CREATE TABLE IF NOT EXISTS kanban_card_sessions (
45
+ id TEXT PRIMARY KEY,
46
+ card_id TEXT NOT NULL REFERENCES kanban_cards(id) ON DELETE CASCADE,
47
+ session_id TEXT NOT NULL UNIQUE REFERENCES sessions(id) ON DELETE CASCADE,
48
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_kanban_boards_project ON kanban_boards(project_id);
52
+ CREATE INDEX IF NOT EXISTS idx_kanban_lanes_board ON kanban_lanes(board_id, sort_order);
53
+ CREATE INDEX IF NOT EXISTS idx_kanban_cards_lane ON kanban_cards(lane_id, sort_order);
54
+ CREATE INDEX IF NOT EXISTS idx_kanban_card_sessions_session ON kanban_card_sessions(session_id);
55
+ CREATE INDEX IF NOT EXISTS idx_kanban_card_sessions_card ON kanban_card_sessions(card_id);
56
+ `);
57
+ },
58
+ },
59
+ {
60
+ name: 'sessions-add-target_lane_id',
61
+ up(db) {
62
+ addColumnIfMissing(db, 'sessions', 'target_lane_id', 'TEXT REFERENCES kanban_lanes(id) ON DELETE SET NULL');
63
+ },
64
+ },
65
+ {
66
+ name: 'sessions-add-lane_trigger_depth',
67
+ up(db) {
68
+ addColumnIfMissing(db, 'sessions', 'lane_trigger_depth', 'INTEGER NOT NULL DEFAULT 0');
69
+ },
70
+ },
71
+ {
72
+ name: 'session_templates-add-target_lane_id',
73
+ up(db) {
74
+ addColumnIfMissing(db, 'session_templates', 'target_lane_id', 'TEXT REFERENCES kanban_lanes(id) ON DELETE SET NULL');
75
+ },
76
+ },
77
+ {
78
+ name: 'kanban_lanes-add-on_enter_prompt',
79
+ up(db) {
80
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_prompt', 'TEXT');
81
+ },
82
+ },
83
+ {
84
+ name: 'kanban_lanes-add-agent-settings',
85
+ up(db) {
86
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_mode', 'TEXT');
87
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_model', 'TEXT');
88
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_effort_level', 'TEXT');
89
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_thinking_enabled', 'INTEGER');
90
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_auto_reschedule_enabled', 'INTEGER DEFAULT 0');
91
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_reschedule_delay_minutes', 'INTEGER DEFAULT 15');
92
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_reschedule_on_token_limit', 'INTEGER DEFAULT 1');
93
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_reschedule_on_service_error', 'INTEGER DEFAULT 1');
94
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_max_reschedule_count', 'INTEGER');
95
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_max_total_tokens', 'INTEGER');
96
+ addColumnIfMissing(db, 'kanban_lanes', 'on_enter_reschedule_at_token_count', 'INTEGER');
97
+ },
98
+ },
99
+ ];
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Utility helpers shared by migration modules.
3
+ *
4
+ * These helpers keep each migration definition concise and avoid repeating
5
+ * the same PRAGMA + includes() pattern in every single migration object.
6
+ */
7
+
8
+ /**
9
+ * Return the column names for a given table.
10
+ * @param {import('better-sqlite3').Database} db
11
+ * @param {string} table
12
+ * @returns {string[]}
13
+ */
14
+ export function getColumns(db, table) {
15
+ return db.prepare(`PRAGMA table_info(${table})`).all().map((col) => col.name);
16
+ }
17
+
18
+ /**
19
+ * Add a column to a table only when it does not already exist.
20
+ * @param {import('better-sqlite3').Database} db
21
+ * @param {string} table
22
+ * @param {string} column
23
+ * @param {string} definition e.g. "TEXT", "INTEGER DEFAULT 0"
24
+ */
25
+ export function addColumnIfMissing(db, table, column, definition) {
26
+ const columns = getColumns(db, table);
27
+ if (!columns.includes(column)) {
28
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check whether a given table exists in the database.
34
+ * @param {import('better-sqlite3').Database} db
35
+ * @param {string} table
36
+ * @returns {boolean}
37
+ */
38
+ export function tableExists(db, table) {
39
+ return Boolean(db
40
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?")
41
+ .get(table));
42
+ }
43
+
44
+ /**
45
+ * Get the CREATE TABLE SQL for a table from sqlite_master.
46
+ * @param {import('better-sqlite3').Database} db
47
+ * @param {string} table
48
+ * @returns {string|undefined}
49
+ */
50
+ export function getTableSql(db, table) {
51
+ const row = db
52
+ .prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name=?")
53
+ .get(table);
54
+ return row?.sql;
55
+ }