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,258 @@
1
+ import { readFile, readdir, access, constants } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import YAML from 'yaml';
5
+ import {
6
+ discoverPluginCommands,
7
+ discoverPluginSkills,
8
+ discoverMarketplaceCommands,
9
+ discoverMarketplaceSkills,
10
+ } from './slashCommandPluginDiscovery.js';
11
+
12
+ // Command source locations in priority order:
13
+ // 1. Project: .claude/commands/*.md
14
+ // 2. User: ~/.claude/commands/*.md
15
+ // 3. Plugins: ~/.claude/plugins/cache/.../{plugin}/.../commands/*.md
16
+ // 4. Built-in: hardcoded list below
17
+ const COMMANDS_DIR = '.claude/commands';
18
+ const SKILLS_DIR = '.claude/skills';
19
+
20
+ /**
21
+ * Parse YAML frontmatter from a markdown command file
22
+ * Supports our extended schema with typed arguments
23
+ *
24
+ * @param {string} content - The file content
25
+ * @returns {{ description: string, arguments: Array, body: string }}
26
+ */
27
+ export function parseCommandFile(content) {
28
+ // Check for frontmatter
29
+ if (!content.startsWith('---')) {
30
+ return { description: '', arguments: [], body: content.trim() };
31
+ }
32
+
33
+ // Find end of frontmatter
34
+ const endIndex = content.indexOf('---', 3);
35
+ if (endIndex === -1) {
36
+ return { description: '', arguments: [], body: content.trim() };
37
+ }
38
+
39
+ const frontmatterStr = content.slice(3, endIndex).trim();
40
+ const body = content.slice(endIndex + 3).trim();
41
+
42
+ try {
43
+ const frontmatter = YAML.parse(frontmatterStr);
44
+ const args = Array.isArray(frontmatter.arguments)
45
+ ? frontmatter.arguments.map(normalizeArgument)
46
+ : [];
47
+ return { description: frontmatter.description || '', arguments: args, body };
48
+ } catch (err) {
49
+ console.warn('Failed to parse command frontmatter:', err.message);
50
+ return { description: '', arguments: [], body: content.trim() };
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Normalize an argument definition to ensure it has all required fields
56
+ * @param {Object} arg - Argument from frontmatter
57
+ * @returns {Object} Normalized argument
58
+ */
59
+ function normalizeArgument(arg) {
60
+ if (!arg || typeof arg !== 'object') {
61
+ return null;
62
+ }
63
+
64
+ const normalized = {
65
+ name: arg.name || 'unnamed',
66
+ type: ['select', 'text', 'multiline'].includes(arg.type) ? arg.type : 'text',
67
+ label: arg.label || arg.name || 'Unnamed',
68
+ required: arg.required === true,
69
+ placeholder: arg.placeholder || '',
70
+ };
71
+
72
+ if (normalized.type === 'select' && Array.isArray(arg.options)) {
73
+ normalized.options = arg.options.map(opt => {
74
+ if (typeof opt === 'string') return { value: opt, label: opt };
75
+ return {
76
+ value: opt.value || opt.label || '',
77
+ label: opt.label || opt.value || '',
78
+ };
79
+ });
80
+ }
81
+
82
+ if (arg.default !== undefined) {
83
+ normalized.default = arg.default;
84
+ }
85
+
86
+ return normalized;
87
+ }
88
+
89
+ /**
90
+ * Parse a SKILL.md file with its extended frontmatter
91
+ * @param {string} content - File content
92
+ * @param {string} directoryName - The skill directory name (used as fallback name)
93
+ * @returns {Object} Parsed skill object
94
+ */
95
+ export function parseSkillFile(content, directoryName) {
96
+ const defaults = {
97
+ name: directoryName,
98
+ description: '',
99
+ argumentHint: null,
100
+ userInvocable: true,
101
+ disableModelInvocation: false,
102
+ };
103
+
104
+ if (!content.startsWith('---')) {
105
+ return { ...defaults, body: content.trim() };
106
+ }
107
+
108
+ const endIndex = content.indexOf('---', 3);
109
+ if (endIndex === -1) {
110
+ return { ...defaults, body: content.trim() };
111
+ }
112
+
113
+ const frontmatterStr = content.slice(3, endIndex).trim();
114
+ const body = content.slice(endIndex + 3).trim();
115
+
116
+ try {
117
+ const fm = YAML.parse(frontmatterStr);
118
+ return {
119
+ name: fm.name || directoryName,
120
+ description: fm.description || '',
121
+ argumentHint: fm['argument-hint'] || null,
122
+ userInvocable: fm['user-invocable'] !== false,
123
+ disableModelInvocation: fm['disable-model-invocation'] === true,
124
+ body,
125
+ };
126
+ } catch (err) {
127
+ console.warn('Failed to parse skill frontmatter:', err.message);
128
+ return { ...defaults, body: content.trim() };
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Discover commands from a directory
134
+ * @param {string} directory - Directory to scan
135
+ * @param {string} source - Source type ('project', 'user', or 'plugin')
136
+ * @param {string} [namespace] - Optional namespace prefix for plugin commands
137
+ * @returns {Promise<Array>} Array of command objects
138
+ */
139
+ async function discoverCommandsFromDir(directory, source, namespace = null) {
140
+ const commands = [];
141
+ try {
142
+ await access(directory, constants.R_OK);
143
+ const files = await readdir(directory);
144
+ for (const file of files) {
145
+ if (!file.endsWith('.md')) continue;
146
+ const baseName = file.replace(/\.md$/, '');
147
+ const name = namespace ? `${namespace}:${baseName}` : baseName;
148
+ const filePath = join(directory, file);
149
+ try {
150
+ const content = await readFile(filePath, 'utf-8');
151
+ const parsed = parseCommandFile(content);
152
+ commands.push({
153
+ name,
154
+ description: parsed.description,
155
+ arguments: parsed.arguments.filter(Boolean),
156
+ source,
157
+ filePath,
158
+ });
159
+ } catch (err) {
160
+ console.warn(`Failed to read command file ${filePath}:`, err.message);
161
+ }
162
+ }
163
+ } catch {
164
+ // Directory doesn't exist or isn't readable
165
+ }
166
+ return commands;
167
+ }
168
+
169
+ /**
170
+ * Discover skills from a directory
171
+ * Scans basePath/.claude/skills/SKILL.md
172
+ */
173
+ async function readSkillEntry(skillsDir, entryName, source, namespace) {
174
+ const skillMdPath = join(skillsDir, entryName, 'SKILL.md');
175
+ try {
176
+ const content = await readFile(skillMdPath, 'utf-8');
177
+ const parsed = parseSkillFile(content, entryName);
178
+ if (!parsed.userInvocable) return null;
179
+ const name = namespace ? `${namespace}:${parsed.name}` : parsed.name;
180
+ return {
181
+ name,
182
+ description: parsed.description,
183
+ arguments: [],
184
+ argumentHint: parsed.argumentHint,
185
+ source,
186
+ filePath: skillMdPath,
187
+ isSkill: true,
188
+ disableModelInvocation: parsed.disableModelInvocation,
189
+ };
190
+ } catch {
191
+ // SKILL.md doesn't exist or isn't readable
192
+ return null;
193
+ }
194
+ }
195
+
196
+ async function discoverSkillsFromDir(basePath, source, namespace = null) {
197
+ const skillsDir = join(basePath, SKILLS_DIR);
198
+ const skills = [];
199
+ try {
200
+ await access(skillsDir, constants.R_OK);
201
+ const entries = await readdir(skillsDir, { withFileTypes: true });
202
+ for (const entry of entries) {
203
+ if (!entry.isDirectory()) continue;
204
+ const skill = await readSkillEntry(skillsDir, entry.name, source, namespace);
205
+ if (skill) skills.push(skill);
206
+ }
207
+ } catch {
208
+ // Skills directory doesn't exist
209
+ }
210
+ return skills;
211
+ }
212
+
213
+ /**
214
+ * Discover all commands and skills for a working directory from all sources.
215
+ * Returns deduplicated list with skills taking precedence over commands.
216
+ *
217
+ * @param {string} workingDirectory - The project working directory
218
+ * @returns {Promise<Array>} Array of command/skill objects
219
+ */
220
+ export async function discoverAllCommands(workingDirectory) {
221
+ const projectCommands = await discoverCommandsFromDir(
222
+ join(workingDirectory, COMMANDS_DIR), 'project'
223
+ );
224
+ const userCommands = await discoverCommandsFromDir(
225
+ join(homedir(), COMMANDS_DIR), 'user'
226
+ );
227
+ const pluginCommands = await discoverPluginCommands(workingDirectory, discoverCommandsFromDir);
228
+ const marketplaceCommands = await discoverMarketplaceCommands(discoverCommandsFromDir);
229
+ const projectSkills = await discoverSkillsFromDir(workingDirectory, 'project-skill');
230
+ const userSkills = await discoverSkillsFromDir(homedir(), 'user-skill');
231
+ const pluginSkills = await discoverPluginSkills(workingDirectory);
232
+ const marketplaceSkills = await discoverMarketplaceSkills();
233
+
234
+ // Skills take precedence over commands with the same name (per Anthropic docs)
235
+ // Priority: project > user > installed-plugin > marketplace; then commands fill remaining slots
236
+ const seen = new Set();
237
+ const commands = [];
238
+
239
+ // Add all skills first (they take precedence)
240
+ // installed_plugins.json entries come before marketplace to win dedup
241
+ for (const skill of [...projectSkills, ...userSkills, ...pluginSkills, ...marketplaceSkills]) {
242
+ if (!seen.has(skill.name)) {
243
+ seen.add(skill.name);
244
+ commands.push(skill);
245
+ }
246
+ }
247
+
248
+ // Then add commands (only if name not already taken by a skill)
249
+ // installed_plugins.json entries come before marketplace to win dedup
250
+ for (const cmd of [...projectCommands, ...userCommands, ...pluginCommands, ...marketplaceCommands]) {
251
+ if (!seen.has(cmd.name)) {
252
+ seen.add(cmd.name);
253
+ commands.push(cmd);
254
+ }
255
+ }
256
+
257
+ return commands;
258
+ }
@@ -0,0 +1,216 @@
1
+ import { readFile, readdir, access, constants } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { parseSkillFile } from './slashCommandDiscovery.js';
5
+
6
+ /**
7
+ * Check if a working directory matches a plugin's project path
8
+ * Handles git worktrees which are subdirectories of the main repo
9
+ */
10
+ function isMatchingProject(workingDirectory, projectPath) {
11
+ if (workingDirectory === projectPath) return true;
12
+ if (workingDirectory.startsWith(`${projectPath}/.worktrees/`)) return true;
13
+ const worktreeMarker = '/.worktrees/';
14
+ const worktreeIndex = workingDirectory.indexOf(worktreeMarker);
15
+ if (worktreeIndex !== -1) {
16
+ const mainRepoPath = workingDirectory.substring(0, worktreeIndex);
17
+ if (mainRepoPath === projectPath) return true;
18
+ }
19
+ return false;
20
+ }
21
+
22
+ /**
23
+ * Find the relevant plugin installation for a given working directory
24
+ */
25
+ function findRelevantInstall(installations, workingDirectory) {
26
+ return installations.find(
27
+ install => install.scope === 'global' || isMatchingProject(workingDirectory, install.projectPath)
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Read and parse the installed_plugins.json file
33
+ * @returns {Promise<Object|null>} Parsed plugins object or null
34
+ */
35
+ async function readInstalledPlugins() {
36
+ try {
37
+ const path = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');
38
+ const content = await readFile(path, 'utf-8');
39
+ const data = JSON.parse(content);
40
+ return data.plugins || null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Read and parse the known_marketplaces.json file
48
+ * @returns {Promise<Object|null>} Parsed marketplaces object or null
49
+ */
50
+ async function readKnownMarketplaces() {
51
+ try {
52
+ const path = join(homedir(), '.claude', 'plugins', 'known_marketplaces.json');
53
+ const content = await readFile(path, 'utf-8');
54
+ return JSON.parse(content);
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Parse a single SKILL.md file and return skill object if valid
62
+ */
63
+ async function parseSkillFromPath(skillMdPath, namespace, directoryName) {
64
+ try {
65
+ const skillContent = await readFile(skillMdPath, 'utf-8');
66
+ const parsed = parseSkillFile(skillContent, directoryName);
67
+ if (!parsed.userInvocable) return null;
68
+ return {
69
+ name: `${namespace}:${parsed.name}`,
70
+ description: parsed.description,
71
+ arguments: [],
72
+ argumentHint: parsed.argumentHint,
73
+ source: 'plugin-skill',
74
+ filePath: skillMdPath,
75
+ isSkill: true,
76
+ disableModelInvocation: parsed.disableModelInvocation,
77
+ };
78
+ } catch {
79
+ return null;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Scan a skills directory and return all valid skills
85
+ */
86
+ export async function scanSkillsDirectory(skillsDir, namespace) {
87
+ const skills = [];
88
+ try {
89
+ await access(skillsDir, constants.R_OK);
90
+ const entries = await readdir(skillsDir, { withFileTypes: true });
91
+ for (const entry of entries) {
92
+ if (!entry.isDirectory()) continue;
93
+ const skillMdPath = join(skillsDir, entry.name, 'SKILL.md');
94
+ const skill = await parseSkillFromPath(skillMdPath, namespace, entry.name);
95
+ if (skill) skills.push(skill);
96
+ }
97
+ } catch { /* skills directory doesn't exist */ }
98
+ return skills;
99
+ }
100
+
101
+ /**
102
+ * Scan a plugins directory for skills
103
+ */
104
+ async function scanPluginsDirForSkills(pluginsDir) {
105
+ const skills = [];
106
+ try {
107
+ await access(pluginsDir, constants.R_OK);
108
+ const pluginDirs = await readdir(pluginsDir, { withFileTypes: true });
109
+ for (const pluginEntry of pluginDirs) {
110
+ if (!pluginEntry.isDirectory()) continue;
111
+ const namespace = pluginEntry.name;
112
+ const skillsDir = join(pluginsDir, pluginEntry.name, 'skills');
113
+ const pluginSkills = await scanSkillsDirectory(skillsDir, namespace);
114
+ skills.push(...pluginSkills);
115
+ }
116
+ } catch { /* plugins directory doesn't exist */ }
117
+ return skills;
118
+ }
119
+
120
+ /**
121
+ * Scan a plugins directory for commands
122
+ * @param {string} pluginsDir - Path to plugins directory
123
+ * @param {Function} discoverCommandsFromDir - Function to discover commands from a directory
124
+ */
125
+ export async function scanPluginsDirForCommands(pluginsDir, discoverCommandsFromDir) {
126
+ const commands = [];
127
+ try {
128
+ await access(pluginsDir, constants.R_OK);
129
+ const pluginDirs = await readdir(pluginsDir, { withFileTypes: true });
130
+ for (const pluginEntry of pluginDirs) {
131
+ if (!pluginEntry.isDirectory()) continue;
132
+ const namespace = pluginEntry.name;
133
+ const pluginCommandsDir = join(pluginsDir, pluginEntry.name, 'commands');
134
+ const pluginCommands = await discoverCommandsFromDir(pluginCommandsDir, 'plugin', namespace);
135
+ commands.push(...pluginCommands);
136
+ }
137
+ } catch { /* plugins directory doesn't exist */ }
138
+ return commands;
139
+ }
140
+
141
+ /**
142
+ * Discover commands from installed plugins
143
+ * @param {string} workingDirectory - The project working directory
144
+ * @param {Function} discoverCommandsFromDir - Function to discover commands from a directory
145
+ */
146
+ export async function discoverPluginCommands(workingDirectory, discoverCommandsFromDir) {
147
+ const plugins = await readInstalledPlugins();
148
+ if (!plugins) return [];
149
+ const commands = [];
150
+ for (const [pluginId, installations] of Object.entries(plugins)) {
151
+ const relevantInstall = findRelevantInstall(installations, workingDirectory);
152
+ if (!relevantInstall) continue;
153
+ const namespace = pluginId.split('@')[0];
154
+ const pluginCommandsDir = join(relevantInstall.installPath, 'commands');
155
+ const pluginCommands = await discoverCommandsFromDir(pluginCommandsDir, 'plugin', namespace);
156
+ commands.push(...pluginCommands);
157
+ }
158
+ return commands;
159
+ }
160
+
161
+ /**
162
+ * Discover skills from installed plugins
163
+ */
164
+ export async function discoverPluginSkills(workingDirectory) {
165
+ const plugins = await readInstalledPlugins();
166
+ if (!plugins) return [];
167
+ const skills = [];
168
+ for (const [pluginId, installations] of Object.entries(plugins)) {
169
+ const relevantInstall = findRelevantInstall(installations, workingDirectory);
170
+ if (!relevantInstall) continue;
171
+ const namespace = pluginId.split('@')[0];
172
+ const pluginSkillsDir = join(relevantInstall.installPath, 'skills');
173
+ const pluginSkills = await scanSkillsDirectory(pluginSkillsDir, namespace);
174
+ skills.push(...pluginSkills);
175
+ }
176
+ return skills;
177
+ }
178
+
179
+ /**
180
+ * Discover skills from marketplace plugins
181
+ */
182
+ export async function discoverMarketplaceSkills() {
183
+ const marketplaces = await readKnownMarketplaces();
184
+ if (!marketplaces) return [];
185
+ const skills = [];
186
+ for (const [_marketplaceId, marketplace] of Object.entries(marketplaces)) {
187
+ const basePath = marketplace.installLocation;
188
+ if (!basePath) continue;
189
+ for (const subdir of ['plugins', 'external_plugins']) {
190
+ const pluginsDir = join(basePath, subdir);
191
+ const subdirSkills = await scanPluginsDirForSkills(pluginsDir);
192
+ skills.push(...subdirSkills);
193
+ }
194
+ }
195
+ return skills;
196
+ }
197
+
198
+ /**
199
+ * Discover commands from marketplace plugins
200
+ * @param {Function} discoverCommandsFromDir - Function to discover commands from a directory
201
+ */
202
+ export async function discoverMarketplaceCommands(discoverCommandsFromDir) {
203
+ const marketplaces = await readKnownMarketplaces();
204
+ if (!marketplaces) return [];
205
+ const commands = [];
206
+ for (const [_marketplaceId, marketplace] of Object.entries(marketplaces)) {
207
+ const basePath = marketplace.installLocation;
208
+ if (!basePath) continue;
209
+ for (const subdir of ['plugins', 'external_plugins']) {
210
+ const pluginsDir = join(basePath, subdir);
211
+ const subdirCommands = await scanPluginsDirForCommands(pluginsDir, discoverCommandsFromDir);
212
+ commands.push(...subdirCommands);
213
+ }
214
+ }
215
+ return commands;
216
+ }