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,315 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+
4
+ /**
5
+ * Canvas item repository class
6
+ */
7
+ export class CanvasItemRepository extends BaseRepository {
8
+ constructor() {
9
+ super('canvas_items', CanvasItemRepository.#mapCanvasItem);
10
+ }
11
+
12
+ static #mapCanvasItem(row) {
13
+ // Parse JSON data for json type
14
+ let data = row.data;
15
+ if (row.type === 'json' && typeof data === 'string') {
16
+ try {
17
+ data = JSON.parse(data);
18
+ } catch (e) {
19
+ // If parsing fails, keep as string
20
+ }
21
+ }
22
+
23
+ return {
24
+ id: row.id,
25
+ sessionId: row.session_id,
26
+ type: row.type,
27
+ content: row.content,
28
+ data,
29
+ mimeType: row.mime_type,
30
+ filename: row.filename,
31
+ width: row.width,
32
+ height: row.height,
33
+ deletedAt: row.deleted_at,
34
+ createdAt: row.created_at,
35
+ updatedAt: row.updated_at,
36
+ };
37
+ }
38
+
39
+ create(sessionId, data) {
40
+ const id = databaseManager.generateId();
41
+ const now = Date.now();
42
+
43
+ // Serialize data field to JSON if it's an object
44
+ let dataValue = data.data || null;
45
+ if (dataValue !== null && typeof dataValue === 'object') {
46
+ dataValue = JSON.stringify(dataValue);
47
+ }
48
+
49
+ this.db
50
+ .prepare(
51
+ `INSERT INTO canvas_items (id, session_id, type, content, data, mime_type, filename, width, height, created_at, updated_at)
52
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
53
+ )
54
+ .run(
55
+ id,
56
+ sessionId,
57
+ data.type,
58
+ data.content || null,
59
+ dataValue,
60
+ data.mimeType || null,
61
+ data.filename || null,
62
+ data.width || null,
63
+ data.height || null,
64
+ now,
65
+ now
66
+ );
67
+ return this.getById(id);
68
+ }
69
+
70
+ getBySessionId(sessionId) {
71
+ const rows = this.db
72
+ .prepare('SELECT * FROM canvas_items WHERE session_id = ? AND deleted_at IS NULL ORDER BY created_at DESC')
73
+ .all(sessionId);
74
+ return this.mapAll(rows);
75
+ }
76
+
77
+ /**
78
+ * Get only the latest version of each file for a session (for agent-facing API)
79
+ * Returns one item per unique filename, always the newest version
80
+ * @param {string} sessionId
81
+ * @returns {Array} Array of latest canvas items (one per filename)
82
+ */
83
+ getLatestVersionsBySessionId(sessionId) {
84
+ // Use a subquery to get the max rowid (which is unique and auto-incrementing) for each filename
85
+ // rowid is more reliable than created_at since items can have identical timestamps
86
+ const rows = this.db
87
+ .prepare(
88
+ `SELECT ci.*
89
+ FROM canvas_items ci
90
+ INNER JOIN (
91
+ SELECT filename, MAX(rowid) as max_rowid
92
+ FROM canvas_items
93
+ WHERE session_id = ? AND deleted_at IS NULL
94
+ GROUP BY filename
95
+ ) latest ON ci.filename = latest.filename AND ci.rowid = latest.max_rowid
96
+ WHERE ci.session_id = ? AND ci.deleted_at IS NULL
97
+ ORDER BY ci.created_at DESC`
98
+ )
99
+ .all(sessionId, sessionId);
100
+ return this.mapAll(rows);
101
+ }
102
+
103
+ /**
104
+ * Get all versions of a file by filename, ordered newest first
105
+ * @param {string} sessionId
106
+ * @param {string} filename
107
+ * @returns {Array} Array of canvas items with matching filename
108
+ */
109
+ getAllVersionsByFilename(sessionId, filename) {
110
+ const rows = this.db
111
+ .prepare(
112
+ `SELECT * FROM canvas_items
113
+ WHERE session_id = ? AND filename = ? AND deleted_at IS NULL
114
+ ORDER BY created_at DESC, rowid DESC`
115
+ )
116
+ .all(sessionId, filename);
117
+ return this.mapAll(rows);
118
+ }
119
+
120
+ /**
121
+ * Get only deleted items for trash view
122
+ * @param {string} sessionId
123
+ * @returns {Array} Array of deleted canvas items
124
+ */
125
+ getDeletedBySessionId(sessionId) {
126
+ const rows = this.db
127
+ .prepare('SELECT * FROM canvas_items WHERE session_id = ? AND deleted_at IS NOT NULL ORDER BY deleted_at DESC')
128
+ .all(sessionId);
129
+ return this.mapAll(rows);
130
+ }
131
+
132
+ /**
133
+ * Soft delete: set deleted_at timestamp
134
+ * @param {string} itemId
135
+ * @returns {Object} The updated item
136
+ */
137
+ softDelete(itemId) {
138
+ const now = Date.now();
139
+ this.db
140
+ .prepare('UPDATE canvas_items SET deleted_at = ? WHERE id = ?')
141
+ .run(now, itemId);
142
+ return this.getById(itemId);
143
+ }
144
+
145
+ /**
146
+ * Recover: clear deleted_at timestamp
147
+ * @param {string} itemId
148
+ * @returns {Object} The recovered item
149
+ */
150
+ recover(itemId) {
151
+ const now = Date.now();
152
+ this.db
153
+ .prepare('UPDATE canvas_items SET deleted_at = NULL, updated_at = ? WHERE id = ?')
154
+ .run(now, itemId);
155
+ return this.getById(itemId);
156
+ }
157
+
158
+ /**
159
+ * Recover all versions of a file
160
+ * @param {string} sessionId
161
+ * @param {string} filename
162
+ */
163
+ recoverByFilename(sessionId, filename) {
164
+ const now = Date.now();
165
+ this.db
166
+ .prepare('UPDATE canvas_items SET deleted_at = NULL, updated_at = ? WHERE session_id = ? AND filename = ? AND deleted_at IS NOT NULL')
167
+ .run(now, sessionId, filename);
168
+ }
169
+
170
+ /**
171
+ * Permanent delete (for emptying trash)
172
+ * @param {string} itemId
173
+ */
174
+ permanentDelete(itemId) {
175
+ this.db.prepare('DELETE FROM canvas_items WHERE id = ?').run(itemId);
176
+ }
177
+
178
+ /**
179
+ * Expand item IDs to include all versions sharing the same filename.
180
+ * For each given ID, finds the item's filename + session, then collects
181
+ * all items with that filename in that session.
182
+ * @param {string[]} itemIds - Array of item IDs
183
+ * @param {object} options
184
+ * @param {boolean} [options.deletedOnly] - Only include deleted items (for trash operations)
185
+ * @param {boolean} [options.activeOnly] - Only include active (non-deleted) items
186
+ * @returns {string[]} Expanded array of item IDs (deduplicated)
187
+ */
188
+ expandToAllVersions(itemIds, { deletedOnly = false, activeOnly = false } = {}) {
189
+ if (!itemIds || itemIds.length === 0) return [];
190
+
191
+ const allIds = new Set();
192
+
193
+ for (const itemId of itemIds) {
194
+ const item = this.getById(itemId);
195
+ if (!item || !item.filename) {
196
+ allIds.add(itemId);
197
+ continue;
198
+ }
199
+
200
+ let filter = 'session_id = ? AND filename = ?';
201
+ if (deletedOnly) filter += ' AND deleted_at IS NOT NULL';
202
+ if (activeOnly) filter += ' AND deleted_at IS NULL';
203
+
204
+ const siblings = this.db
205
+ .prepare(`SELECT id FROM canvas_items WHERE ${filter}`)
206
+ .all(item.sessionId, item.filename);
207
+
208
+ for (const sibling of siblings) {
209
+ allIds.add(sibling.id);
210
+ }
211
+ }
212
+
213
+ return [...allIds];
214
+ }
215
+
216
+ /**
217
+ * Duplicates all canvas items from one session to another.
218
+ * Only copies non-deleted items.
219
+ * @param {string} sourceSessionId - Source session ID
220
+ * @param {string} targetSessionId - Target session ID
221
+ */
222
+ /**
223
+ * Update the content of an existing canvas item in-place
224
+ * @param {string} itemId
225
+ * @param {string} content
226
+ * @returns {Object|undefined} The updated item, or undefined if not found
227
+ */
228
+ updateContent(itemId, content) {
229
+ const now = Date.now();
230
+ const result = this.db
231
+ .prepare('UPDATE canvas_items SET content = ?, updated_at = ? WHERE id = ?')
232
+ .run(content, now, itemId);
233
+ if (result.changes === 0) return undefined;
234
+ return this.getById(itemId);
235
+ }
236
+
237
+ duplicateForSession(sourceSessionId, targetSessionId) {
238
+ const items = this.getBySessionId(sourceSessionId);
239
+
240
+ for (const item of items) {
241
+ this.create(targetSessionId, {
242
+ type: item.type,
243
+ content: item.content,
244
+ data: item.data,
245
+ mimeType: item.mimeType,
246
+ filename: item.filename,
247
+ width: item.width,
248
+ height: item.height,
249
+ });
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Soft delete multiple items atomically
255
+ * @param {string[]} itemIds - Array of item IDs to soft delete
256
+ * @returns {number} Count of items actually deleted
257
+ */
258
+ softDeleteBatch(itemIds) {
259
+ if (!itemIds || itemIds.length === 0) {
260
+ return 0;
261
+ }
262
+
263
+ const now = Date.now();
264
+ const placeholders = itemIds.map(() => '?').join(',');
265
+
266
+ const updateStmt = this.db.prepare(
267
+ `UPDATE canvas_items SET deleted_at = ? WHERE id IN (${placeholders}) AND deleted_at IS NULL`
268
+ );
269
+
270
+ const result = updateStmt.run(now, ...itemIds);
271
+ return result.changes || 0;
272
+ }
273
+
274
+ /**
275
+ * Recover multiple items atomically
276
+ * @param {string[]} itemIds - Array of item IDs to recover
277
+ * @returns {number} Count of items actually recovered
278
+ */
279
+ recoverBatch(itemIds) {
280
+ if (!itemIds || itemIds.length === 0) {
281
+ return 0;
282
+ }
283
+
284
+ const now = Date.now();
285
+ const placeholders = itemIds.map(() => '?').join(',');
286
+
287
+ const updateStmt = this.db.prepare(
288
+ `UPDATE canvas_items SET deleted_at = NULL, updated_at = ? WHERE id IN (${placeholders}) AND deleted_at IS NOT NULL`
289
+ );
290
+
291
+ const result = updateStmt.run(now, ...itemIds);
292
+ return result.changes || 0;
293
+ }
294
+
295
+ /**
296
+ * Permanently delete multiple items atomically
297
+ * @param {string[]} itemIds - Array of item IDs to permanently delete (must be from trash)
298
+ * @returns {number} Count of items actually deleted
299
+ */
300
+ permanentDeleteBatch(itemIds) {
301
+ if (!itemIds || itemIds.length === 0) {
302
+ return 0;
303
+ }
304
+
305
+ // Only allow permanent deletion of items that are in trash (deleted_at IS NOT NULL)
306
+ const placeholders = itemIds.map(() => '?').join(',');
307
+
308
+ const deleteStmt = this.db.prepare(
309
+ `DELETE FROM canvas_items WHERE id IN (${placeholders}) AND deleted_at IS NOT NULL`
310
+ );
311
+
312
+ const result = deleteStmt.run(...itemIds);
313
+ return result.changes || 0;
314
+ }
315
+ }
@@ -0,0 +1,75 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+ import { databaseManager } from './DatabaseManager.js';
3
+
4
+ /**
5
+ * Command button repository class
6
+ */
7
+ export class CommandButtonRepository extends BaseRepository {
8
+ constructor() {
9
+ super('command_buttons', CommandButtonRepository.#mapButton);
10
+ }
11
+
12
+ static #mapButton(row) {
13
+ return {
14
+ id: row.id,
15
+ projectId: row.project_id,
16
+ label: row.label,
17
+ command: row.command,
18
+ sortOrder: row.sort_order,
19
+ showOnList: row.show_on_list === 1,
20
+ createdAt: row.created_at,
21
+ updatedAt: row.updated_at,
22
+ };
23
+ }
24
+
25
+ create({ projectId, label, command, sortOrder = 0, showOnList = false }) {
26
+ const id = databaseManager.generateId();
27
+ const now = Date.now();
28
+ this.db
29
+ .prepare(
30
+ `INSERT INTO command_buttons (id, project_id, label, command, sort_order, show_on_list, created_at, updated_at)
31
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
32
+ )
33
+ .run(id, projectId, label, command, sortOrder, showOnList ? 1 : 0, now, now);
34
+ return this.getById(id);
35
+ }
36
+
37
+ getByProjectId(projectId) {
38
+ const rows = this.db
39
+ .prepare('SELECT * FROM command_buttons WHERE project_id = ? ORDER BY sort_order ASC, created_at ASC')
40
+ .all(projectId);
41
+ return this.mapAll(rows);
42
+ }
43
+
44
+ update(id, data) {
45
+ const updates = [];
46
+ const values = [];
47
+
48
+ if (data.label !== undefined) {
49
+ updates.push('label = ?');
50
+ values.push(data.label);
51
+ }
52
+ if (data.command !== undefined) {
53
+ updates.push('command = ?');
54
+ values.push(data.command);
55
+ }
56
+ if (data.sortOrder !== undefined) {
57
+ updates.push('sort_order = ?');
58
+ values.push(data.sortOrder);
59
+ }
60
+ if (data.showOnList !== undefined) {
61
+ updates.push('show_on_list = ?');
62
+ values.push(data.showOnList ? 1 : 0);
63
+ }
64
+
65
+ if (updates.length === 0) return this.getById(id);
66
+
67
+ updates.push('updated_at = ?');
68
+ values.push(Date.now());
69
+ values.push(id);
70
+
71
+ this.db.prepare(`UPDATE command_buttons SET ${updates.join(', ')} WHERE id = ?`).run(...values);
72
+
73
+ return this.getById(id);
74
+ }
75
+ }
@@ -0,0 +1,219 @@
1
+ import { BaseRepository } from './BaseRepository.js';
2
+
3
+ /**
4
+ * Command run repository class for persisting command execution history
5
+ */
6
+ export class CommandRunRepository extends BaseRepository {
7
+ constructor() {
8
+ super('command_runs', CommandRunRepository.#mapRun);
9
+ }
10
+
11
+ static #mapRun(row) {
12
+ return {
13
+ id: row.id,
14
+ sessionId: row.session_id,
15
+ buttonId: row.button_id,
16
+ status: row.status,
17
+ output: row.output || '',
18
+ exitCode: row.exit_code,
19
+ startedAt: row.started_at,
20
+ completedAt: row.completed_at,
21
+ };
22
+ }
23
+
24
+ create({ id, sessionId, buttonId }) {
25
+ const now = Date.now();
26
+ this.db
27
+ .prepare(
28
+ `INSERT INTO command_runs (id, session_id, button_id, status, output, started_at)
29
+ VALUES (?, ?, ?, 'running', '', ?)`
30
+ )
31
+ .run(id, sessionId, buttonId, now);
32
+ return this.getById(id);
33
+ }
34
+
35
+ /**
36
+ * Append text to run output (buffered for performance)
37
+ */
38
+ appendOutput(runId, text) {
39
+ if (!text) return;
40
+ this.db
41
+ .prepare(`UPDATE command_runs SET output = output || ? WHERE id = ?`)
42
+ .run(text, runId);
43
+ }
44
+
45
+ /**
46
+ * Mark run as completed with exit code and final output
47
+ */
48
+ complete(runId, exitCode, finalOutput) {
49
+ const status = exitCode === 0 ? 'success' : 'error';
50
+ const now = Date.now();
51
+ this.db
52
+ .prepare(
53
+ `UPDATE command_runs SET status = ?, output = ?, exit_code = ?, completed_at = ? WHERE id = ?`
54
+ )
55
+ .run(status, finalOutput, exitCode, now, runId);
56
+ }
57
+
58
+ /**
59
+ * Mark run as killed
60
+ */
61
+ markKilled(runId, finalOutput) {
62
+ const now = Date.now();
63
+ this.db
64
+ .prepare(
65
+ `UPDATE command_runs SET status = 'killed', output = ?, completed_at = ? WHERE id = ?`
66
+ )
67
+ .run(finalOutput, now, runId);
68
+ }
69
+
70
+ /**
71
+ * Get all runs for a session (both running and recent completed)
72
+ */
73
+ getBySessionId(sessionId) {
74
+ const rows = this.db
75
+ .prepare('SELECT * FROM command_runs WHERE session_id = ? ORDER BY started_at DESC')
76
+ .all(sessionId);
77
+ return this.mapAll(rows);
78
+ }
79
+
80
+ /**
81
+ * Get runs for a session from last X milliseconds (recent runs)
82
+ * If includeRunning is true, also include running commands regardless of age
83
+ */
84
+ getRecentBySessionId(sessionId, windowMs = 3600000, includeRunning = true) {
85
+ const cutoffTime = Date.now() - windowMs;
86
+ let query = `SELECT * FROM command_runs WHERE session_id = ?`;
87
+
88
+ if (includeRunning) {
89
+ query += ` AND (started_at > ? OR status = 'running')`;
90
+ } else {
91
+ query += ` AND started_at > ?`;
92
+ }
93
+
94
+ query += ` ORDER BY started_at DESC`;
95
+
96
+ const rows = this.db.prepare(query).all(sessionId, cutoffTime);
97
+ return this.mapAll(rows);
98
+ }
99
+
100
+ /**
101
+ * Get a single run by ID
102
+ */
103
+ getById(id) {
104
+ const row = this.db.prepare('SELECT * FROM command_runs WHERE id = ?').get(id);
105
+ return this.map(row);
106
+ }
107
+
108
+ /**
109
+ * Get most recent run for a button
110
+ */
111
+ getLastRunForButton(buttonId) {
112
+ const row = this.db
113
+ .prepare('SELECT * FROM command_runs WHERE button_id = ? ORDER BY started_at DESC LIMIT 1')
114
+ .get(buttonId);
115
+ return this.map(row);
116
+ }
117
+
118
+ /**
119
+ * Delete runs older than specified milliseconds
120
+ */
121
+ deleteOlderThan(ageMs) {
122
+ const cutoffTime = Date.now() - ageMs;
123
+ const result = this.db
124
+ .prepare('DELETE FROM command_runs WHERE completed_at < ?')
125
+ .run(cutoffTime);
126
+ return result.changes;
127
+ }
128
+
129
+ /**
130
+ * Delete a single run by ID
131
+ * @param {string} id - Run ID
132
+ * @returns {number} Number of rows deleted (0 or 1)
133
+ */
134
+ deleteById(id) {
135
+ const result = this.db.prepare('DELETE FROM command_runs WHERE id = ?').run(id);
136
+ return result.changes;
137
+ }
138
+
139
+ /**
140
+ * Delete all non-running runs for a button within a session.
141
+ * Returns info about deleted runs (needed for WebSocket broadcasting).
142
+ * @param {string} buttonId - Button ID
143
+ * @param {string} sessionId - Session ID
144
+ * @returns {{ deletedCount: number, deletedRuns: Array<{ id: string, buttonId: string }> }}
145
+ */
146
+ deleteByButtonAndSession(buttonId, sessionId) {
147
+ const deleteRuns = this.db.transaction(() => {
148
+ // First get the IDs of runs we'll delete (for broadcasting)
149
+ const runs = this.db
150
+ .prepare('SELECT id, button_id FROM command_runs WHERE button_id = ? AND session_id = ? AND status != ?')
151
+ .all(buttonId, sessionId, 'running');
152
+
153
+ const result = this.db
154
+ .prepare('DELETE FROM command_runs WHERE button_id = ? AND session_id = ? AND status != ?')
155
+ .run(buttonId, sessionId, 'running');
156
+
157
+ return {
158
+ deletedCount: result.changes,
159
+ deletedRuns: runs.map(r => ({ id: r.id, buttonId: r.button_id })),
160
+ };
161
+ });
162
+
163
+ return deleteRuns();
164
+ }
165
+
166
+ /**
167
+ * Delete all runs for a session (useful for testing or cleanup)
168
+ */
169
+ deleteBySessionId(sessionId) {
170
+ const result = this.db
171
+ .prepare('DELETE FROM command_runs WHERE session_id = ?')
172
+ .run(sessionId);
173
+ return result.changes;
174
+ }
175
+
176
+ /**
177
+ * Get the latest run for each (session_id, button_id) combination within a project
178
+ * Returns the most recent run per button per session regardless of age
179
+ */
180
+ getLatestRunsForProject(projectId) {
181
+ const rows = this.db
182
+ .prepare(
183
+ `SELECT *
184
+ FROM (
185
+ SELECT cr.id, cr.session_id, cr.button_id, cr.status, cr.exit_code, cr.started_at, cr.completed_at,
186
+ ROW_NUMBER() OVER (PARTITION BY cr.session_id, cr.button_id ORDER BY COALESCE(cr.completed_at, cr.started_at) DESC, cr.id DESC) as rn
187
+ FROM command_runs cr
188
+ INNER JOIN sessions s ON cr.session_id = s.id
189
+ WHERE s.project_id = ?
190
+ )
191
+ WHERE rn = 1
192
+ ORDER BY COALESCE(completed_at, started_at) DESC, id DESC`
193
+ )
194
+ .all(projectId);
195
+ return this.mapAll(rows);
196
+ }
197
+
198
+ /**
199
+ * Get the latest run for each button in a session (one per button)
200
+ * @param {string} sessionId - Session ID
201
+ * @returns {Array} Array of CommandRun objects
202
+ */
203
+ getLatestRunsForSession(sessionId) {
204
+ const rows = this.db
205
+ .prepare(
206
+ `SELECT *
207
+ FROM (
208
+ SELECT cr.id, cr.session_id, cr.button_id, cr.status, cr.exit_code, cr.output, cr.started_at, cr.completed_at,
209
+ ROW_NUMBER() OVER (PARTITION BY cr.button_id ORDER BY COALESCE(cr.completed_at, cr.started_at) DESC, cr.id DESC) as rn
210
+ FROM command_runs cr
211
+ WHERE cr.session_id = ?
212
+ )
213
+ WHERE rn = 1
214
+ ORDER BY COALESCE(completed_at, started_at) DESC, id DESC`
215
+ )
216
+ .all(sessionId);
217
+ return this.mapAll(rows);
218
+ }
219
+ }