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.
- package/package.json +33 -0
- package/packages/server/bin/cli.js +4 -0
- package/packages/server/src/agents/AgentGateway.js +64 -0
- package/packages/server/src/agents/BaseAgent.js +41 -0
- package/packages/server/src/agents/LoggingAgentWrapper.js +73 -0
- package/packages/server/src/agents/adapters/ClaudeCodeAdapter.js +33 -0
- package/packages/server/src/agents/adapters/CodexAdapter.js +26 -0
- package/packages/server/src/agents/types.js +43 -0
- package/packages/server/src/agents/vcr/CassetteStore.js +111 -0
- package/packages/server/src/agents/vcr/VCRAgentAdapter.js +126 -0
- package/packages/server/src/agents/vcr/VCRSummaryWrapper.js +71 -0
- package/packages/server/src/api/canvas-helpers.js +249 -0
- package/packages/server/src/api/canvas-trash-routes.js +205 -0
- package/packages/server/src/api/canvas.js +331 -0
- package/packages/server/src/api/commandButtons.js +312 -0
- package/packages/server/src/api/commands.js +169 -0
- package/packages/server/src/api/filesystem.js +62 -0
- package/packages/server/src/api/git.js +85 -0
- package/packages/server/src/api/index.js +44 -0
- package/packages/server/src/api/kanban.js +342 -0
- package/packages/server/src/api/metrics.js +194 -0
- package/packages/server/src/api/projects-helpers.js +43 -0
- package/packages/server/src/api/projects-session-helpers.js +295 -0
- package/packages/server/src/api/projects.js +384 -0
- package/packages/server/src/api/providers.js +249 -0
- package/packages/server/src/api/quickResponses.js +129 -0
- package/packages/server/src/api/sessions-archive.js +69 -0
- package/packages/server/src/api/sessions-commands.js +220 -0
- package/packages/server/src/api/sessions-conversations.js +168 -0
- package/packages/server/src/api/sessions-draft.js +72 -0
- package/packages/server/src/api/sessions-lifecycle.js +190 -0
- package/packages/server/src/api/sessions-messages.js +141 -0
- package/packages/server/src/api/sessions-notes.js +51 -0
- package/packages/server/src/api/sessions-patch.js +252 -0
- package/packages/server/src/api/sessions-streaming.js +86 -0
- package/packages/server/src/api/sessions.js +269 -0
- package/packages/server/src/api/settings.js +194 -0
- package/packages/server/src/api/templates.js +63 -0
- package/packages/server/src/app.js +51 -0
- package/packages/server/src/database.js +58 -0
- package/packages/server/src/db/AgentCallLogRepository.js +322 -0
- package/packages/server/src/db/AttachmentRepository.js +191 -0
- package/packages/server/src/db/BaseRepository.js +39 -0
- package/packages/server/src/db/CanvasItemRepository.js +315 -0
- package/packages/server/src/db/CommandButtonRepository.js +75 -0
- package/packages/server/src/db/CommandRunRepository.js +219 -0
- package/packages/server/src/db/ConversationRepository.js +379 -0
- package/packages/server/src/db/DatabaseManager.js +91 -0
- package/packages/server/src/db/KanbanBoardRepository.js +92 -0
- package/packages/server/src/db/KanbanCardRepository.js +286 -0
- package/packages/server/src/db/KanbanLaneRepository.js +279 -0
- package/packages/server/src/db/MessageRepository.js +156 -0
- package/packages/server/src/db/ProjectDefaultsRepository.js +173 -0
- package/packages/server/src/db/ProjectRepository.js +110 -0
- package/packages/server/src/db/ProviderRepository.js +307 -0
- package/packages/server/src/db/QuickResponseRepository.js +186 -0
- package/packages/server/src/db/SessionNoteRepository.js +60 -0
- package/packages/server/src/db/SessionRepository.js +314 -0
- package/packages/server/src/db/SessionSummaryRepository.js +200 -0
- package/packages/server/src/db/SessionTemplateRepository.js +171 -0
- package/packages/server/src/db/SettingsRepository.js +211 -0
- package/packages/server/src/db/TodoRepository.js +132 -0
- package/packages/server/src/db/WorkLogRepository.js +122 -0
- package/packages/server/src/db/conversation-helpers.js +119 -0
- package/packages/server/src/db/index.js +100 -0
- package/packages/server/src/db/migrations/canvasItemsMigrations.js +109 -0
- package/packages/server/src/db/migrations/conversationsMigrations.js +183 -0
- package/packages/server/src/db/migrations/index.js +199 -0
- package/packages/server/src/db/migrations/kanbanMigrations.js +99 -0
- package/packages/server/src/db/migrations/migrationUtils.js +55 -0
- package/packages/server/src/db/migrations/miscMigrations.js +242 -0
- package/packages/server/src/db/migrations/projectsMigrations.js +95 -0
- package/packages/server/src/db/migrations/sessionsMigrations.js +282 -0
- package/packages/server/src/db/session-helpers.js +150 -0
- package/packages/server/src/index.js +106 -0
- package/packages/server/src/logger.js +22 -0
- package/packages/server/src/middleware/sessionLookup.js +57 -0
- package/packages/server/src/middleware/upload.js +94 -0
- package/packages/server/src/schema.sql +363 -0
- package/packages/server/src/services/agentCallLogger.js +116 -0
- package/packages/server/src/services/canvasStore.js +56 -0
- package/packages/server/src/services/childSessionContext.js +61 -0
- package/packages/server/src/services/commandRunner.js +422 -0
- package/packages/server/src/services/conversationContext.js +72 -0
- package/packages/server/src/services/diffService.js +172 -0
- package/packages/server/src/services/draftSessionService.js +181 -0
- package/packages/server/src/services/encryption.js +134 -0
- package/packages/server/src/services/ghService.js +169 -0
- package/packages/server/src/services/gitService.js +520 -0
- package/packages/server/src/services/gitSessionSetup.js +48 -0
- package/packages/server/src/services/hookService.js +60 -0
- package/packages/server/src/services/kanbanService.js +262 -0
- package/packages/server/src/services/kanbanTriggers.js +273 -0
- package/packages/server/src/services/nodeSpawnHelper.js +63 -0
- package/packages/server/src/services/prStatusService.js +204 -0
- package/packages/server/src/services/prUrlService.js +224 -0
- package/packages/server/src/services/providerTestService.js +81 -0
- package/packages/server/src/services/scheduleService.js +110 -0
- package/packages/server/src/services/schedulerService.js +281 -0
- package/packages/server/src/services/sessionDuplicator.js +63 -0
- package/packages/server/src/services/sessionErrors.js +173 -0
- package/packages/server/src/services/sessionExecution.js +378 -0
- package/packages/server/src/services/sessionManager.js +356 -0
- package/packages/server/src/services/sessionPrompts.js +427 -0
- package/packages/server/src/services/sessionProvider.js +107 -0
- package/packages/server/src/services/slashCommandDiscovery.js +258 -0
- package/packages/server/src/services/slashCommandPluginDiscovery.js +216 -0
- package/packages/server/src/services/slashCommandService.js +306 -0
- package/packages/server/src/services/streamEventCallbacks.js +170 -0
- package/packages/server/src/services/streamEventHandler.js +488 -0
- package/packages/server/src/services/streamUsageHandler.js +228 -0
- package/packages/server/src/services/summaryBroadcast.js +61 -0
- package/packages/server/src/services/summaryClaudeClient.js +180 -0
- package/packages/server/src/services/summaryPrompts.js +169 -0
- package/packages/server/src/services/summaryService.js +552 -0
- package/packages/server/src/services/summaryStaleCheck.js +35 -0
- package/packages/server/src/services/systemMonitor.js +281 -0
- package/packages/server/src/services/templateTriggerService.js +197 -0
- package/packages/server/src/services/terminalOutput.js +160 -0
- package/packages/server/src/services/todoStore.js +58 -0
- package/packages/server/src/services/usageTracker.js +69 -0
- package/packages/server/src/services/withConcurrencyGuard.js +110 -0
- package/packages/server/src/websocket.js +10 -0
- package/packages/server/src/ws/WebSocketManager.js +240 -0
- package/packages/server/src/ws/index.js +50 -0
- package/packages/shared/package.json +27 -0
- package/packages/shared/src/constants.js +44 -0
- package/packages/shared/src/contracts/canvas.js +25 -0
- package/packages/shared/src/contracts/commandButtons.js +36 -0
- package/packages/shared/src/contracts/kanban.js +142 -0
- package/packages/shared/src/contracts/projects.js +63 -0
- package/packages/shared/src/contracts/providers.js +81 -0
- package/packages/shared/src/contracts/quickResponses.js +44 -0
- package/packages/shared/src/contracts/sessions.js +112 -0
- package/packages/shared/src/contracts/templates.js +51 -0
- package/packages/shared/src/index.js +5 -0
- package/packages/shared/src/protocol.js +76 -0
- package/packages/shared/src/routeParams.js +36 -0
- package/packages/shared/src/types.js +167 -0
- package/packages/shared/src/utils.js +101 -0
- package/packages/web/dist/assets/ActiveSessionsView-BQc76Jc8.js +1 -0
- package/packages/web/dist/assets/ActiveSessionsView-ofSvx-K1.css +1 -0
- package/packages/web/dist/assets/AgentLogsView-CTCjHjsu.js +2 -0
- package/packages/web/dist/assets/AgentLogsView-D90PnQVk.css +1 -0
- package/packages/web/dist/assets/ApiClient-Dbs1H78V.js +1 -0
- package/packages/web/dist/assets/ArchiveConfirmModal-CCxSZ52u.js +1 -0
- package/packages/web/dist/assets/ArchiveConfirmModal-CQZeuYBz.css +1 -0
- package/packages/web/dist/assets/CommandButtonDetailView-CF_-LXpU.js +1 -0
- package/packages/web/dist/assets/CommandButtonDetailView-DBm3rzhw.css +1 -0
- package/packages/web/dist/assets/EffortLevelSelector-BQaQmU2d.css +1 -0
- package/packages/web/dist/assets/EffortLevelSelector-DPofLvm-.js +1 -0
- package/packages/web/dist/assets/GeneralSettingsView-BCf53fpC.css +1 -0
- package/packages/web/dist/assets/GeneralSettingsView-BY1G-Kv8.js +1 -0
- package/packages/web/dist/assets/InterpolationHelp-CgdbNcJB.js +1 -0
- package/packages/web/dist/assets/InterpolationHelp-iNxTxmhs.css +1 -0
- package/packages/web/dist/assets/MarkdownEditor-CqT1U8lo.js +2 -0
- package/packages/web/dist/assets/MarkdownEditor-enuH2yvP.css +1 -0
- package/packages/web/dist/assets/ModelSelector-BBn_Ve0D.js +1 -0
- package/packages/web/dist/assets/ModelSelector-DPPD-92R.css +1 -0
- package/packages/web/dist/assets/NewSessionView-Bo5l49nu.js +3 -0
- package/packages/web/dist/assets/NewSessionView-Byoi1XdQ.css +1 -0
- package/packages/web/dist/assets/PathChooser-BoMGzeg2.css +1 -0
- package/packages/web/dist/assets/PathChooser-Cx9gQ-Qt.js +1 -0
- package/packages/web/dist/assets/ProjectEditView-BFuscj-V.js +1 -0
- package/packages/web/dist/assets/ProjectEditView-DNwBUNRk.css +1 -0
- package/packages/web/dist/assets/ProjectListView-C55H1JHQ.css +1 -0
- package/packages/web/dist/assets/ProjectListView-Dj0jBZ46.js +1 -0
- package/packages/web/dist/assets/ProjectNewView-Brdp-xUu.js +1 -0
- package/packages/web/dist/assets/ProjectNewView-CpgE4R-l.css +1 -0
- package/packages/web/dist/assets/ProvidersView-B_QQF3RM.css +1 -0
- package/packages/web/dist/assets/ProvidersView-Cxc-1skq.js +1 -0
- package/packages/web/dist/assets/QuickResponseSettings-B2eVAtHW.js +1 -0
- package/packages/web/dist/assets/QuickResponseSettings-B8188A1D.css +1 -0
- package/packages/web/dist/assets/QuickResponsesPanel-DIBQFj0W.css +1 -0
- package/packages/web/dist/assets/QuickResponsesPanel-lU8pW2B0.js +1 -0
- package/packages/web/dist/assets/ResizableTextarea-B5nAA0RV.css +1 -0
- package/packages/web/dist/assets/ResizableTextarea-DSy1mWGY.js +1 -0
- package/packages/web/dist/assets/SessionCard-BvjLwVYg.js +1 -0
- package/packages/web/dist/assets/SessionCard-D20G3bX8.css +1 -0
- package/packages/web/dist/assets/SessionDetailView-BQbPg-RJ.js +36 -0
- package/packages/web/dist/assets/SessionDetailView-BrMG4p2-.css +1 -0
- package/packages/web/dist/assets/SessionFormOptions-BgqFR-5f.js +1 -0
- package/packages/web/dist/assets/SessionFormOptions-BuLlDF-7.css +1 -0
- package/packages/web/dist/assets/SessionListView-BAIBtJF7.css +1 -0
- package/packages/web/dist/assets/SessionListView-CYIHI8qF.js +1 -0
- package/packages/web/dist/assets/SessionLogStream-B-FwUMJQ.js +18 -0
- package/packages/web/dist/assets/SessionLogStream-zPUTiGbe.css +1 -0
- package/packages/web/dist/assets/SettingsView-DC8-hTQ-.css +1 -0
- package/packages/web/dist/assets/SettingsView-fZxpiGp7.js +1 -0
- package/packages/web/dist/assets/SlashCommandWizard-BB30cSvo.css +1 -0
- package/packages/web/dist/assets/SlashCommandWizard-BgaOw9W3.js +1 -0
- package/packages/web/dist/assets/SummarySettingsView-DcsmSVJI.css +1 -0
- package/packages/web/dist/assets/SummarySettingsView-eeu1Xq86.js +1 -0
- package/packages/web/dist/assets/TemplateDetailView-DEPKSwDo.js +1 -0
- package/packages/web/dist/assets/TemplateDetailView-DT2m06W7.css +1 -0
- package/packages/web/dist/assets/apl-B4CMkyY2.js +1 -0
- package/packages/web/dist/assets/asciiarmor-Df11BRmG.js +1 -0
- package/packages/web/dist/assets/asn1-EdZsLKOL.js +1 -0
- package/packages/web/dist/assets/asterisk-B-8jnY81.js +1 -0
- package/packages/web/dist/assets/brainfuck-C4LP7Hcl.js +1 -0
- package/packages/web/dist/assets/clike-B9uivgTg.js +1 -0
- package/packages/web/dist/assets/clojure-BMjYHr_A.js +1 -0
- package/packages/web/dist/assets/cmake-BQqOBYOt.js +1 -0
- package/packages/web/dist/assets/cobol-CWcv1MsR.js +1 -0
- package/packages/web/dist/assets/coffeescript-S37ZYGWr.js +1 -0
- package/packages/web/dist/assets/commandButtons-DNSHH8IA.js +4 -0
- package/packages/web/dist/assets/commonlisp-DBKNyK5s.js +1 -0
- package/packages/web/dist/assets/crystal-SjHAIU92.js +1 -0
- package/packages/web/dist/assets/css-BnMrqG3P.js +1 -0
- package/packages/web/dist/assets/cypher-C_CwsFkJ.js +1 -0
- package/packages/web/dist/assets/d-pRatUO7H.js +1 -0
- package/packages/web/dist/assets/diff-DbItnlRl.js +1 -0
- package/packages/web/dist/assets/dockerfile-BKs6k2Af.js +1 -0
- package/packages/web/dist/assets/dtd-DF_7sFjM.js +1 -0
- package/packages/web/dist/assets/dylan-DwRh75JA.js +1 -0
- package/packages/web/dist/assets/ebnf-CDyGwa7X.js +1 -0
- package/packages/web/dist/assets/ecl-Cabwm37j.js +1 -0
- package/packages/web/dist/assets/eiffel-CnydiIhH.js +1 -0
- package/packages/web/dist/assets/elm-vLlmbW-K.js +1 -0
- package/packages/web/dist/assets/erlang-BNw1qcRV.js +1 -0
- package/packages/web/dist/assets/factor-kuTfRLto.js +1 -0
- package/packages/web/dist/assets/fcl-Kvtd6kyn.js +1 -0
- package/packages/web/dist/assets/forth-Ffai-XNe.js +1 -0
- package/packages/web/dist/assets/fortran-DYz_wnZ1.js +1 -0
- package/packages/web/dist/assets/gas-Bneqetm1.js +1 -0
- package/packages/web/dist/assets/gherkin-heZmZLOM.js +1 -0
- package/packages/web/dist/assets/groovy-D9Dt4D0W.js +1 -0
- package/packages/web/dist/assets/haskell-BWDZoCOh.js +1 -0
- package/packages/web/dist/assets/haxe-H-WmDvRZ.js +1 -0
- package/packages/web/dist/assets/http-DBlCnlav.js +1 -0
- package/packages/web/dist/assets/idl-BEugSyMb.js +1 -0
- package/packages/web/dist/assets/index-BZlHgDSz.js +1 -0
- package/packages/web/dist/assets/index-BhWX8AfE.js +2 -0
- package/packages/web/dist/assets/index-Bi3XvF_f.js +1 -0
- package/packages/web/dist/assets/index-BqXoPf_D.js +1 -0
- package/packages/web/dist/assets/index-CAuTOZSD.js +1 -0
- package/packages/web/dist/assets/index-CKYk-fkb.js +1 -0
- package/packages/web/dist/assets/index-CTumW_tV.js +318 -0
- package/packages/web/dist/assets/index-CVOJVSsC.js +82 -0
- package/packages/web/dist/assets/index-CXK2Z3_z.js +1 -0
- package/packages/web/dist/assets/index-CYllQ3Vd.js +1 -0
- package/packages/web/dist/assets/index-CpsfI08O.js +1 -0
- package/packages/web/dist/assets/index-DQkhDeTA.js +3 -0
- package/packages/web/dist/assets/index-DWP8iCBp.js +1 -0
- package/packages/web/dist/assets/index-DkVb9W_J.js +1 -0
- package/packages/web/dist/assets/index-DmKHPbIa.js +1 -0
- package/packages/web/dist/assets/index-DrlQi03X.js +1 -0
- package/packages/web/dist/assets/index-gmCCsCQ1.css +1 -0
- package/packages/web/dist/assets/index-prTEzzgO.js +1 -0
- package/packages/web/dist/assets/index-wqgejMCM.js +1 -0
- package/packages/web/dist/assets/index-yh0ZHIWw.js +7 -0
- package/packages/web/dist/assets/javascript-qCveANmP.js +1 -0
- package/packages/web/dist/assets/julia-DuME0IfC.js +1 -0
- package/packages/web/dist/assets/livescript-BwQOo05w.js +1 -0
- package/packages/web/dist/assets/lua-BgMRiT3U.js +1 -0
- package/packages/web/dist/assets/mathematica-DTrFuWx2.js +1 -0
- package/packages/web/dist/assets/mbox-CNhZ1qSd.js +1 -0
- package/packages/web/dist/assets/mirc-CjQqDB4T.js +1 -0
- package/packages/web/dist/assets/mllike-CXdrOF99.js +1 -0
- package/packages/web/dist/assets/modelica-Dc1JOy9r.js +1 -0
- package/packages/web/dist/assets/mscgen-BA5vi2Kp.js +1 -0
- package/packages/web/dist/assets/mumps-BT43cFF4.js +1 -0
- package/packages/web/dist/assets/nginx-DdIZxoE0.js +1 -0
- package/packages/web/dist/assets/nsis-LdVXkNf5.js +1 -0
- package/packages/web/dist/assets/ntriples-BfvgReVJ.js +1 -0
- package/packages/web/dist/assets/octave-Ck1zUtKM.js +1 -0
- package/packages/web/dist/assets/oz-BzwKVEFT.js +1 -0
- package/packages/web/dist/assets/pascal--L3eBynH.js +1 -0
- package/packages/web/dist/assets/perl-CdXCOZ3F.js +1 -0
- package/packages/web/dist/assets/pig-CevX1Tat.js +1 -0
- package/packages/web/dist/assets/powershell-CFHJl5sT.js +1 -0
- package/packages/web/dist/assets/projects-DbBQQH-V.js +1 -0
- package/packages/web/dist/assets/properties-C78fOPTZ.js +1 -0
- package/packages/web/dist/assets/protobuf-ChK-085T.js +1 -0
- package/packages/web/dist/assets/providers-ceCc4xRU.js +1 -0
- package/packages/web/dist/assets/pug-DukmZTjD.js +1 -0
- package/packages/web/dist/assets/puppet-DMA9R1ak.js +1 -0
- package/packages/web/dist/assets/python-BuPzkPfP.js +1 -0
- package/packages/web/dist/assets/q-pXgVlZs6.js +1 -0
- package/packages/web/dist/assets/r-DUYO_cvP.js +1 -0
- package/packages/web/dist/assets/rpm-CTu-6PCP.js +1 -0
- package/packages/web/dist/assets/ruby-B2Rjki9n.js +1 -0
- package/packages/web/dist/assets/sas-B4kiWyti.js +1 -0
- package/packages/web/dist/assets/scheme-C41bIUwD.js +1 -0
- package/packages/web/dist/assets/sessions-D681M81k.js +1 -0
- package/packages/web/dist/assets/settings-D0evez2V.js +1 -0
- package/packages/web/dist/assets/shell-CjFT_Tl9.js +1 -0
- package/packages/web/dist/assets/sieve-C3Gn_uJK.js +1 -0
- package/packages/web/dist/assets/simple-mode-GW_nhZxv.js +1 -0
- package/packages/web/dist/assets/smalltalk-CnHTOXQT.js +1 -0
- package/packages/web/dist/assets/solr-DehyRSwq.js +1 -0
- package/packages/web/dist/assets/sparql-DkYu6x3z.js +1 -0
- package/packages/web/dist/assets/spreadsheet-BCZA_wO0.js +1 -0
- package/packages/web/dist/assets/sql-D0XecflT.js +1 -0
- package/packages/web/dist/assets/stex-C3f8Ysf7.js +1 -0
- package/packages/web/dist/assets/style-BTin-zR_.css +1 -0
- package/packages/web/dist/assets/stylus-B533Al4x.js +1 -0
- package/packages/web/dist/assets/swift-BzpIVaGY.js +1 -0
- package/packages/web/dist/assets/tcl-DVfN8rqt.js +1 -0
- package/packages/web/dist/assets/textile-CnDTJFAw.js +1 -0
- package/packages/web/dist/assets/tiddlywiki-DO-Gjzrf.js +1 -0
- package/packages/web/dist/assets/tiki-DGYXhP31.js +1 -0
- package/packages/web/dist/assets/toml-Bm5Em-hy.js +1 -0
- package/packages/web/dist/assets/troff-wAsdV37c.js +1 -0
- package/packages/web/dist/assets/ttcn-CfJYG6tj.js +1 -0
- package/packages/web/dist/assets/ttcn-cfg-B9xdYoR4.js +1 -0
- package/packages/web/dist/assets/turtle-B1tBg_DP.js +1 -0
- package/packages/web/dist/assets/vb-CmGdzxic.js +1 -0
- package/packages/web/dist/assets/vbscript-BuJXcnF6.js +1 -0
- package/packages/web/dist/assets/velocity-D8B20fx6.js +1 -0
- package/packages/web/dist/assets/verilog-C6RDOZhf.js +1 -0
- package/packages/web/dist/assets/vhdl-lSbBsy5d.js +1 -0
- package/packages/web/dist/assets/webidl-ZXfAyPTL.js +1 -0
- package/packages/web/dist/assets/xquery-CQfU5ijd.js +1 -0
- package/packages/web/dist/assets/yacas-BJ4BC0dw.js +1 -0
- package/packages/web/dist/assets/z80-Hz9HOZM7.js +1 -0
- package/packages/web/dist/favicon.png +0 -0
- package/packages/web/dist/index.html +17 -0
- package/packages/web/dist/logo.png +0 -0
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { sessions, messages, workLogs, conversations } from '../database.js';
|
|
2
|
+
import { broadcastToSession, broadcastToProject } from '../websocket.js';
|
|
3
|
+
import { WS_MESSAGE_TYPES } from '../../../shared/src/index.js';
|
|
4
|
+
import { updateTodos } from './todoStore.js';
|
|
5
|
+
import * as summaryService from './summaryService.js';
|
|
6
|
+
import * as diffService from './diffService.js';
|
|
7
|
+
import {
|
|
8
|
+
handleMessageStart,
|
|
9
|
+
handleMessageDelta,
|
|
10
|
+
handleTextDelta as _handleTextDelta,
|
|
11
|
+
handleResultUsage,
|
|
12
|
+
} from './streamUsageHandler.js';
|
|
13
|
+
|
|
14
|
+
// ── Shared module-level state ──────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
/** @type {Map<string, string|null>} Track last message ID for end-of-turn work log association */
|
|
17
|
+
export const lastMessageIds = new Map();
|
|
18
|
+
|
|
19
|
+
/** @type {Map<string, string>} Accumulate thinking content per session */
|
|
20
|
+
export const thinkingAccumulators = new Map();
|
|
21
|
+
|
|
22
|
+
/** @type {Map<string, string>} Accumulate text content per session */
|
|
23
|
+
export const textAccumulators = new Map();
|
|
24
|
+
|
|
25
|
+
/** @type {Map<string, { controller: AbortController }>} */
|
|
26
|
+
export const activeSessions = new Map();
|
|
27
|
+
|
|
28
|
+
/** @type {Map<string, string>} Map sessionId -> conversationId for current turn */
|
|
29
|
+
export const activeConversationIds = new Map();
|
|
30
|
+
|
|
31
|
+
/** @type {Map<string, string>} Track current model per session (updated on system.init) */
|
|
32
|
+
export const currentModels = new Map();
|
|
33
|
+
|
|
34
|
+
/** @type {Map<string, Set<string>>} Track tool_use IDs that have already been logged per session */
|
|
35
|
+
export const loggedToolUseIds = new Map();
|
|
36
|
+
|
|
37
|
+
// ── Helper functions ───────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create and broadcast a work log entry
|
|
41
|
+
* Work logs are always created as unassociated during the turn,
|
|
42
|
+
* then associated with the message when the turn completes.
|
|
43
|
+
* @param {string} sessionId
|
|
44
|
+
* @param {string} type - 'thinking', 'tool_input', or 'tool_output'
|
|
45
|
+
* @param {string} content
|
|
46
|
+
* @param {string|null} toolName
|
|
47
|
+
*/
|
|
48
|
+
export function createWorkLog(sessionId, type, content, toolName = null) {
|
|
49
|
+
// Always create as unassociated - will be associated at end of turn
|
|
50
|
+
const log = workLogs.create(sessionId, type, content, { messageId: null, toolName });
|
|
51
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_WORK_LOG, {
|
|
52
|
+
sessionId,
|
|
53
|
+
log
|
|
54
|
+
});
|
|
55
|
+
return log;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Associate pending work logs with a message and broadcast the event
|
|
60
|
+
* @param {string} sessionId
|
|
61
|
+
* @param {string} messageId
|
|
62
|
+
*/
|
|
63
|
+
export function associateAndBroadcastWorkLogs(sessionId, messageId) {
|
|
64
|
+
const associatedCount = workLogs.associatePendingLogs(sessionId, messageId);
|
|
65
|
+
if (associatedCount > 0) {
|
|
66
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_WORK_LOGS_ASSOCIATED, {
|
|
67
|
+
sessionId,
|
|
68
|
+
messageId,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return associatedCount;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Broadcast session status update
|
|
76
|
+
* @param {string} sessionId
|
|
77
|
+
* @param {string} status
|
|
78
|
+
*/
|
|
79
|
+
export function broadcastSessionStatus(sessionId, status) {
|
|
80
|
+
// Broadcast to session subscribers (for session detail view)
|
|
81
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_STATUS, { sessionId, status });
|
|
82
|
+
|
|
83
|
+
// Also broadcast SESSION_UPDATED to project subscribers (for session list updates)
|
|
84
|
+
const session = sessions.getById(sessionId);
|
|
85
|
+
if (session) {
|
|
86
|
+
broadcastToProject(session.projectId, WS_MESSAGE_TYPES.SESSION_UPDATED, {
|
|
87
|
+
projectId: session.projectId,
|
|
88
|
+
sessionId,
|
|
89
|
+
session: { ...session, status },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Compute and broadcast changes state when turn completes
|
|
96
|
+
* Called after status is set to "waiting" to provide real-time changes update
|
|
97
|
+
* @param {string} sessionId
|
|
98
|
+
* @param {string} projectId
|
|
99
|
+
* @param {string} workingDirectory
|
|
100
|
+
*/
|
|
101
|
+
export async function broadcastChangesUpdate(sessionId, projectId, workingDirectory) {
|
|
102
|
+
try {
|
|
103
|
+
const changes = await diffService.getChanges(workingDirectory);
|
|
104
|
+
const hasChanges = Boolean(changes.staged || changes.unstaged || changes.untracked);
|
|
105
|
+
|
|
106
|
+
// Count total files with changes
|
|
107
|
+
// Parse diff output to count unique files
|
|
108
|
+
const parseFilesFromDiff = (diff) => {
|
|
109
|
+
if (!diff) return 0;
|
|
110
|
+
const matches = diff.match(/^diff --git a\/(.+) b\//gm) || [];
|
|
111
|
+
return matches.length;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const stagedCount = parseFilesFromDiff(changes.staged);
|
|
115
|
+
const unstagedCount = parseFilesFromDiff(changes.unstaged);
|
|
116
|
+
const untrackedCount = parseFilesFromDiff(changes.untracked);
|
|
117
|
+
const changeCount = stagedCount + unstagedCount + untrackedCount;
|
|
118
|
+
|
|
119
|
+
// Broadcast to session subscribers
|
|
120
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.CHANGES_UPDATE, {
|
|
121
|
+
sessionId,
|
|
122
|
+
hasChanges,
|
|
123
|
+
changeCount,
|
|
124
|
+
});
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// Silently fail - changes indicator is not critical
|
|
127
|
+
// This handles cases like non-git directories or permission errors
|
|
128
|
+
console.error(`Failed to compute changes for session ${sessionId}:`, error.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ── Event-type-specific handlers ────────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Handle 'system' events (e.g. system.init)
|
|
136
|
+
* @param {string} sessionId
|
|
137
|
+
* @param {Object} event
|
|
138
|
+
*/
|
|
139
|
+
function handleSystemEvent(sessionId, event) {
|
|
140
|
+
// Store Claude's session info
|
|
141
|
+
if (event.subtype !== 'init') return;
|
|
142
|
+
|
|
143
|
+
// Save Claude session ID to the active conversation for context isolation
|
|
144
|
+
const activeConversation = conversations.getActiveBySessionId(sessionId);
|
|
145
|
+
if (activeConversation) {
|
|
146
|
+
conversations.update(activeConversation.id, {
|
|
147
|
+
claudeSessionId: event.session_id,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// Track current model for this session (used when creating messages)
|
|
151
|
+
currentModels.set(sessionId, event.model);
|
|
152
|
+
// Capture available slash commands (do NOT update model here — session.model
|
|
153
|
+
// tracks the user-requested short format; this SDK model is stored in currentModels)
|
|
154
|
+
sessions.update(sessionId, {
|
|
155
|
+
slashCommands: JSON.stringify(event.slash_commands || []),
|
|
156
|
+
});
|
|
157
|
+
// Reset message tracking for new session
|
|
158
|
+
lastMessageIds.delete(sessionId);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Handle 'assistant' events — save messages, update todos, log tool use
|
|
163
|
+
* @param {string} sessionId
|
|
164
|
+
* @param {Object} event
|
|
165
|
+
*/
|
|
166
|
+
function handleAssistantEvent(sessionId, event) {
|
|
167
|
+
// Extract text content from assistant message
|
|
168
|
+
const textContent = event.message?.content
|
|
169
|
+
?.filter((c) => c.type === 'text')
|
|
170
|
+
?.map((c) => c.text)
|
|
171
|
+
?.join('\n');
|
|
172
|
+
|
|
173
|
+
// Extract tool use for logging
|
|
174
|
+
const toolUseBlocks = event.message?.content?.filter((c) => c.type === 'tool_use') || [];
|
|
175
|
+
|
|
176
|
+
// NOTE: Do NOT use assistant event usage for broadcasting
|
|
177
|
+
// The stream events already provide real-time usage updates via message_start and message_delta
|
|
178
|
+
// Using assistant event would double-count the usage
|
|
179
|
+
|
|
180
|
+
if (textContent) {
|
|
181
|
+
handleAssistantTextContent(sessionId, textContent, toolUseBlocks);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Check for TodoWrite tool and update todos
|
|
185
|
+
// NOTE: This must be OUTSIDE the if (textContent) block because Claude can call
|
|
186
|
+
// TodoWrite without any accompanying text content (tool-only messages)
|
|
187
|
+
handleTodoWriteIfPresent(sessionId, toolUseBlocks);
|
|
188
|
+
|
|
189
|
+
// Note: Thinking content is logged via stream_event -> content_block_stop
|
|
190
|
+
// to avoid duplicates (since includePartialMessages is always enabled)
|
|
191
|
+
|
|
192
|
+
// Log tool use inputs (dedup by tool_use ID to prevent duplicates from partial assistant events)
|
|
193
|
+
logToolUseInputs(sessionId, toolUseBlocks);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Save assistant text content as a message and broadcast it
|
|
198
|
+
* @param {string} sessionId
|
|
199
|
+
* @param {string} textContent
|
|
200
|
+
* @param {Array} toolUseBlocks
|
|
201
|
+
*/
|
|
202
|
+
function handleAssistantTextContent(sessionId, textContent, toolUseBlocks) {
|
|
203
|
+
const toolUse = toolUseBlocks.length > 0 ? toolUseBlocks : null;
|
|
204
|
+
const activeConversation = conversations.getActiveBySessionId(sessionId);
|
|
205
|
+
const conversationId = activeConversation?.id || null;
|
|
206
|
+
const currentModel = currentModels.get(sessionId) || null;
|
|
207
|
+
const message = messages.create(sessionId, 'assistant', textContent, { toolUse, conversationId, model: currentModel });
|
|
208
|
+
|
|
209
|
+
// Associate pending work logs with this message immediately
|
|
210
|
+
// This ensures work logs are attached to the correct message, not just the last one
|
|
211
|
+
associateAndBroadcastWorkLogs(sessionId, message.id);
|
|
212
|
+
|
|
213
|
+
// Track the message ID in case there are trailing work logs after the last message
|
|
214
|
+
lastMessageIds.set(sessionId, message.id);
|
|
215
|
+
|
|
216
|
+
// Broadcast message with conversationId for proper routing
|
|
217
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_MESSAGE, {
|
|
218
|
+
message,
|
|
219
|
+
conversationId, // Include conversation context to prevent ambiguity
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Clear partial text on client now that complete message has been sent
|
|
223
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_PARTIAL, {
|
|
224
|
+
sessionId,
|
|
225
|
+
text: '',
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Note: Per-message onSessionActivity removed to reduce redundant summary generation.
|
|
229
|
+
// Summary generation is triggered only on turn completion (waiting state) and session complete.
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Check for TodoWrite tool in toolUseBlocks and update todos if present
|
|
234
|
+
* @param {string} sessionId
|
|
235
|
+
* @param {Array} toolUseBlocks
|
|
236
|
+
*/
|
|
237
|
+
function handleTodoWriteIfPresent(sessionId, toolUseBlocks) {
|
|
238
|
+
if (toolUseBlocks.length === 0) return;
|
|
239
|
+
const todoWrite = toolUseBlocks.find((t) => t.name === 'TodoWrite');
|
|
240
|
+
if (!todoWrite?.input?.todos) return;
|
|
241
|
+
// Get active conversation to scope todos to it
|
|
242
|
+
const activeConv = conversations.getActiveBySessionId(sessionId);
|
|
243
|
+
if (activeConv) {
|
|
244
|
+
updateTodos(sessionId, activeConv.id, todoWrite.input.todos);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Log tool use inputs, deduplicating by tool_use ID
|
|
250
|
+
* @param {string} sessionId
|
|
251
|
+
* @param {Array} toolUseBlocks
|
|
252
|
+
*/
|
|
253
|
+
function logToolUseInputs(sessionId, toolUseBlocks) {
|
|
254
|
+
if (!loggedToolUseIds.has(sessionId)) {
|
|
255
|
+
loggedToolUseIds.set(sessionId, new Set());
|
|
256
|
+
}
|
|
257
|
+
const loggedIds = loggedToolUseIds.get(sessionId);
|
|
258
|
+
for (const toolUse of toolUseBlocks) {
|
|
259
|
+
if (toolUse.id && loggedIds.has(toolUse.id)) continue;
|
|
260
|
+
if (toolUse.id) loggedIds.add(toolUse.id);
|
|
261
|
+
const toolInput = JSON.stringify(toolUse.input, null, 2);
|
|
262
|
+
createWorkLog(sessionId, 'tool_input', toolInput, toolUse.name);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Handle 'tool_result' events — log tool outputs
|
|
268
|
+
* @param {string} sessionId
|
|
269
|
+
* @param {Object} event
|
|
270
|
+
*/
|
|
271
|
+
function handleToolResultEvent(sessionId, event) {
|
|
272
|
+
// Log tool results/outputs
|
|
273
|
+
const content = event.content || event.result || '';
|
|
274
|
+
const toolName = event.tool_name || event.name || 'unknown';
|
|
275
|
+
|
|
276
|
+
// Handle different content formats
|
|
277
|
+
const logContent = formatToolResultContent(content);
|
|
278
|
+
|
|
279
|
+
if (logContent) {
|
|
280
|
+
createWorkLog(sessionId, 'tool_output', logContent, toolName);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Format tool result content for logging
|
|
286
|
+
* @param {*} content
|
|
287
|
+
* @returns {string}
|
|
288
|
+
*/
|
|
289
|
+
function formatToolResultContent(content) {
|
|
290
|
+
if (typeof content === 'string') return content;
|
|
291
|
+
if (Array.isArray(content)) {
|
|
292
|
+
return content
|
|
293
|
+
.map((c) => (c.type === 'text' ? c.text : JSON.stringify(c)))
|
|
294
|
+
.join('\n');
|
|
295
|
+
}
|
|
296
|
+
return JSON.stringify(content, null, 2);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Handle 'stream_event' wrapper — dispatches to sub-handlers based on event.event.type
|
|
301
|
+
* @param {string} sessionId
|
|
302
|
+
* @param {Object} event
|
|
303
|
+
*/
|
|
304
|
+
function handleStreamEventType(sessionId, event) {
|
|
305
|
+
const innerType = event.event?.type;
|
|
306
|
+
const handler = streamSubHandlers[innerType];
|
|
307
|
+
if (handler) {
|
|
308
|
+
handler(sessionId, event);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Handle stream_event > message_start — clear text accumulator, then delegate to streamUsageHandler
|
|
314
|
+
* @param {string} sessionId
|
|
315
|
+
* @param {Object} event
|
|
316
|
+
*/
|
|
317
|
+
function handleMessageStartWrapper(sessionId, event) {
|
|
318
|
+
// Clear text accumulator for fresh message
|
|
319
|
+
textAccumulators.delete(sessionId);
|
|
320
|
+
handleMessageStart(sessionId, event);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Handle stream_event > content_block_delta — text and thinking deltas
|
|
325
|
+
* @param {string} sessionId
|
|
326
|
+
* @param {Object} event
|
|
327
|
+
*/
|
|
328
|
+
function handleContentBlockDelta(sessionId, event) {
|
|
329
|
+
const delta = event.event.delta;
|
|
330
|
+
|
|
331
|
+
if (delta?.type === 'text_delta' && delta.text) {
|
|
332
|
+
_handleTextDelta(sessionId, delta, textAccumulators);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Handle thinking delta - accumulate and broadcast partial (don't create work log yet)
|
|
336
|
+
if (delta?.type === 'thinking_delta' && delta.thinking) {
|
|
337
|
+
handleThinkingDelta(sessionId, delta);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Handle thinking_delta within content_block_delta — accumulate thinking
|
|
343
|
+
* @param {string} sessionId
|
|
344
|
+
* @param {Object} delta
|
|
345
|
+
*/
|
|
346
|
+
function handleThinkingDelta(sessionId, delta) {
|
|
347
|
+
const current = thinkingAccumulators.get(sessionId) || '';
|
|
348
|
+
const accumulated = current + delta.thinking;
|
|
349
|
+
thinkingAccumulators.set(sessionId, accumulated);
|
|
350
|
+
|
|
351
|
+
// Broadcast partial thinking for real-time display
|
|
352
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_THINKING_PARTIAL, {
|
|
353
|
+
sessionId,
|
|
354
|
+
thinking: accumulated,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Handle stream_event > content_block_stop — finalize accumulated thinking and text
|
|
360
|
+
* @param {string} sessionId
|
|
361
|
+
* @param {Object} _event
|
|
362
|
+
*/
|
|
363
|
+
function handleContentBlockStop(sessionId, _event) {
|
|
364
|
+
const accumulated = thinkingAccumulators.get(sessionId);
|
|
365
|
+
if (accumulated) {
|
|
366
|
+
// Create a single work log entry with the complete thinking content
|
|
367
|
+
createWorkLog(sessionId, 'thinking', accumulated);
|
|
368
|
+
thinkingAccumulators.delete(sessionId);
|
|
369
|
+
|
|
370
|
+
// Clear partial thinking on client
|
|
371
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_THINKING_PARTIAL, {
|
|
372
|
+
sessionId,
|
|
373
|
+
thinking: null,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Clear text accumulator when content block finishes
|
|
378
|
+
// The text has been finalized into a message
|
|
379
|
+
textAccumulators.delete(sessionId);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Handle 'result' events — errors and final usage
|
|
384
|
+
* @param {string} sessionId
|
|
385
|
+
* @param {Object} event
|
|
386
|
+
*/
|
|
387
|
+
function handleResultEvent(sessionId, event) {
|
|
388
|
+
if (event.subtype === 'error') {
|
|
389
|
+
handleResultError(sessionId, event);
|
|
390
|
+
} else {
|
|
391
|
+
handleResultSuccess(sessionId, event);
|
|
392
|
+
}
|
|
393
|
+
// Note: Don't clear lastMessageIds here - let the post-loop association code handle it.
|
|
394
|
+
// Clearing here was causing work logs to never be associated because the 'result' event
|
|
395
|
+
// arrives before the loop ends, deleting the messageId before association can happen.
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Handle result error subtype
|
|
400
|
+
* @param {string} sessionId
|
|
401
|
+
* @param {Object} event
|
|
402
|
+
*/
|
|
403
|
+
function handleResultError(sessionId, event) {
|
|
404
|
+
sessions.update(sessionId, { status: 'error', error: event.error });
|
|
405
|
+
broadcastToSession(sessionId, WS_MESSAGE_TYPES.SESSION_ERROR, { sessionId, error: event.error });
|
|
406
|
+
// Broadcast error status to project subscribers for session list updates
|
|
407
|
+
broadcastSessionStatus(sessionId, 'error');
|
|
408
|
+
// Extract PR URL before generating summary (PR may have been created before error)
|
|
409
|
+
summaryService.extractPrUrlIfNeeded(sessionId);
|
|
410
|
+
// Generate summary on error
|
|
411
|
+
summaryService.onSessionComplete(sessionId);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Handle result success subtype — store cost and usage
|
|
416
|
+
* @param {string} sessionId
|
|
417
|
+
* @param {Object} event
|
|
418
|
+
*/
|
|
419
|
+
function handleResultSuccess(sessionId, event) {
|
|
420
|
+
// Store cost info and broadcast to project subscribers
|
|
421
|
+
if (event.total_cost_usd !== undefined) {
|
|
422
|
+
sessions.update(sessionId, { costUsd: event.total_cost_usd });
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Store final usage stats to conversation (Issue #175)
|
|
426
|
+
if (event.usage || event.modelUsage) {
|
|
427
|
+
handleResultUsage(sessionId, event);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
// ── Dispatch maps ───────────────────────────────────────────────────────────
|
|
433
|
+
|
|
434
|
+
/** @type {Record<string, (sessionId: string, event: Object) => void>} */
|
|
435
|
+
const streamSubHandlers = {
|
|
436
|
+
message_start: handleMessageStartWrapper,
|
|
437
|
+
message_delta: handleMessageDelta,
|
|
438
|
+
content_block_delta: handleContentBlockDelta,
|
|
439
|
+
content_block_stop: handleContentBlockStop,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/** @type {Record<string, (sessionId: string, event: Object) => void>} */
|
|
443
|
+
const eventHandlers = {
|
|
444
|
+
system: handleSystemEvent,
|
|
445
|
+
assistant: handleAssistantEvent,
|
|
446
|
+
tool_result: handleToolResultEvent,
|
|
447
|
+
stream_event: handleStreamEventType,
|
|
448
|
+
result: handleResultEvent,
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
// ── Main stream event handler ──────────────────────────────────────────────
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Handle a stream event from Claude SDK
|
|
455
|
+
* @param {string} sessionId
|
|
456
|
+
* @param {Object} event
|
|
457
|
+
*/
|
|
458
|
+
export async function handleStreamEvent(sessionId, event) {
|
|
459
|
+
// Check if session has been cleaned up (aborted/deleted) - don't process events for deleted sessions
|
|
460
|
+
if (!activeSessions.has(sessionId)) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const handler = eventHandlers[event.type];
|
|
465
|
+
if (handler) {
|
|
466
|
+
handler(sessionId, event);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Clean up all session state from the Maps
|
|
472
|
+
* Called in the finally block of session execution
|
|
473
|
+
* @param {string} sessionId
|
|
474
|
+
* @param {boolean} includeConversationId - Whether to also clean up activeConversationIds
|
|
475
|
+
*/
|
|
476
|
+
export function cleanupSessionState(sessionId, includeConversationId = false) {
|
|
477
|
+
textAccumulators.delete(sessionId);
|
|
478
|
+
thinkingAccumulators.delete(sessionId);
|
|
479
|
+
currentModels.delete(sessionId);
|
|
480
|
+
loggedToolUseIds.delete(sessionId);
|
|
481
|
+
activeSessions.delete(sessionId);
|
|
482
|
+
if (includeConversationId) {
|
|
483
|
+
activeConversationIds.delete(sessionId);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Re-export callback functions from streamEventCallbacks.js
|
|
488
|
+
export { handleTurnCompletion, handleSessionError } from './streamEventCallbacks.js';
|