@cloudcli-ai/cloudcli 1.37.2 → 1.37.4
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/README.md +269 -0
- package/dist/assets/{abnfDiagram-N423BO3Z-C4UAoHJb.js → abnfDiagram-N423BO3Z-Dmkwx38H.js} +1 -1
- package/dist/assets/{arc-B8jF-ja9.js → arc-DLe9AYuO.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-C_Wur_CU.js → architectureDiagram-T3A2C74G-CBbbbNUW.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-Cq4P1i8t.js → blockDiagram-VBNYF7ZC-CaMEaWu4.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-C1wG4eUj.js → c4Diagram-5PPSVZJV-DhjMgNnR.js} +1 -1
- package/dist/assets/channel-CWrmwsir.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-B8fnBG6E.js → chunk-2GRJ4B5K-yjl3-F-i.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-WdfPooPJ.js → chunk-2Q5K7J3B-DsAYaWEP.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-DhZJuG2E.js → chunk-5RXB4S5H-Bt5qmqOX.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-B0rjslal.js → chunk-5VM5RSS4-yWrWVvUt.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-CG2Oj4jL.js → chunk-6Q2QTUOP-Dt66K5xb.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-rrl2lRxY.js → chunk-GF5L2VYU-DA0vzaj4.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-CjVbrVMA.js → chunk-JWPE2WC7-CUkbx96V.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-CRzKgU8S.js → chunk-KBJHAD2P-DWKxx1WH.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DBz4GTZF.js → chunk-RYQCIY6F-BqluplN0.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-wHxalsXk.js → chunk-XXDRQBXY-DelKg3Xf.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-COAGCC6w.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-COAGCC6w.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-s1hygY8e.js → cose-bilkent-JH36ORCC-DHV93-Em.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-C4LGV15i.js → cynefin-VYW2F7L2-B9HZgoGX.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-C5uhu7B3.js → cynefinDiagram-MW4NZA55-hFjjEQg8.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-B-OBTewm.js → dagre-VZM6K2ZE-CpeVOC7V.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-BjGKQxih.js → diagram-7IWD3JNH-D0H1UoRA.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-BMKz1X2L.js → diagram-B4RE2ZJO-6Y7BQUup.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-DNh-GhKC.js → diagram-LBJQPF4R-C0nNOwht.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-BaTG9jPT.js → diagram-Q27KOJAE-En6QlOVX.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-BUwo2OvJ.js → diagram-UB23O5K3-CmPiNeGD.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-DAZgfzX2.js → ebnfDiagram-BXEA7PRR-Bygzp1Qt.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-1w1CcGEb.js → erDiagram-JOGREHBK-CwScRfzl.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-D4EII8Jj.js → flowDiagram-UKHOOZJN-bKX-0xP6.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-ChvJZAgB.js → ganttDiagram-PKOTCBZU-DtZPKXGd.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-DtOn41S8.js → gitGraphDiagram-DS77QQ5N-CUOtdL1o.js} +1 -1
- package/dist/assets/index-CdjIFxM2.js +5004 -0
- package/dist/assets/index-DgafhGTF.css +32 -0
- package/dist/assets/{infoDiagram-6WML65LV-DN_PVEJZ.js → infoDiagram-6WML65LV-ciRQTS0h.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-DbkF1kXb.js → ishikawaDiagram-WSZJBQD7-CgjhQZ84.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-pJwmhddE.js → journeyDiagram-NVQOT4AX-BsbQSeIW.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-PPAPgNp5.js → kanban-definition-27J2QSJJ-CrwzY9Jw.js} +1 -1
- package/dist/assets/{linear-iPR-J9f7.js → linear-BUaCDr6l.js} +1 -1
- package/dist/assets/{mermaid.core-BEUL86Z6.js → mermaid.core-ClgdUU0j.js} +5 -5
- package/dist/assets/{mindmap-definition-FAOFIHXS-BvZoBib7.js → mindmap-definition-FAOFIHXS-BictljY1.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-DhYreaUd.js → pegDiagram-VL7TDLO6-BXdByy_U.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-CrOHlyD0.js → pieDiagram-7S7Q4E2Y-uZsMfkRX.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-D4g5yH3t.js → quadrantDiagram-CIZ2JOQS-7lCv4QIj.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-Dj39lHlf.js → railroadDiagram-AXF67PYL-07dxIWbi.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-1AS4Zgm_.js → requirementDiagram-LRYGKXZP-Cb31Yv1_.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-CKlMn19P.js → sankeyDiagram-W5VNT64P-X0YPSyF9.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-B_j3qyvo.js → sequenceDiagram-SI44F4Z6-BdBxSIlP.js} +1 -1
- package/dist/assets/server.browser-CtX3Hdl5.js +27 -0
- package/dist/assets/{sizeCapture-X5ZJPWSS-Bp2Op16v.js → sizeCapture-X5ZJPWSS-DQM5xAyD.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-C0cN6DoY.js → stateDiagram-OKZ733FA-DJ3xkLUF.js} +1 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-vAaE4zNo.js +1 -0
- package/dist/assets/{swimlanes-SLNWSIFB-BEvXOV9b.js → swimlanes-SLNWSIFB-rjfYdW0w.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-TV2IF4Nq.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-zdJQinvZ.js → timeline-definition-Z64GVDOM-DZMra5do.js} +1 -1
- package/dist/assets/{vendor-codemirror-OwyKSvPE.js → vendor-codemirror-CYrSt7-U.js} +18 -18
- package/dist/assets/{vennDiagram-T6HMQDX7-DuF1uZMY.js → vennDiagram-T6HMQDX7-BevD8uu0.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-B9AlLQup.js → wardleyDiagram-T6FBY63Y-DsIyXB7z.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-DTJX48Qg.js → xychartDiagram-ELKLHX3M-G3PlF3ko.js} +1 -1
- package/dist/index.html +3 -3
- package/dist-server/server/index.js +11 -4
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/agent/agent.module.js +9 -2
- package/dist-server/server/modules/agent/agent.module.js.map +1 -1
- package/dist-server/server/modules/agent/agent.routes.js +177 -130
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
- package/dist-server/server/modules/agent/tests/agent-run-registration.test.js +306 -0
- package/dist-server/server/modules/agent/tests/agent-run-registration.test.js.map +1 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js +48 -2
- package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -1
- package/dist-server/server/modules/browser-use/browser-use.routes.js +39 -33
- package/dist-server/server/modules/browser-use/browser-use.routes.js.map +1 -1
- package/dist-server/server/modules/database/connection.js +1 -1
- package/dist-server/server/modules/database/connection.js.map +1 -1
- package/dist-server/server/modules/database/index.js +5 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +45 -1
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/provider-models.js +60 -6
- package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -1
- package/dist-server/server/modules/database/repositories/scheduled-messages.db.js +71 -0
- package/dist-server/server/modules/database/repositories/scheduled-messages.db.js.map +1 -0
- package/dist-server/server/modules/database/repositories/session-drafts.db.js +105 -0
- package/dist-server/server/modules/database/repositories/session-drafts.db.js.map +1 -0
- package/dist-server/server/modules/database/repositories/sessions.db.js +144 -5
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/repositories/user-preferences.db.js +65 -0
- package/dist-server/server/modules/database/repositories/user-preferences.db.js.map +1 -0
- package/dist-server/server/modules/database/schema.js +99 -0
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +99 -0
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +39 -0
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js +105 -0
- package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.module.js +2 -1
- package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.service.js +44 -7
- package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -1
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +126 -1
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -1
- package/dist-server/server/modules/git/git-branch-diff.service.js +142 -0
- package/dist-server/server/modules/git/git-branch-diff.service.js.map +1 -0
- package/dist-server/server/modules/git/git-branch.service.js.map +1 -1
- package/dist-server/server/modules/git/git.routes.js +92 -5
- package/dist-server/server/modules/git/git.routes.js.map +1 -1
- package/dist-server/server/modules/git/tests/git-branch-diff.service.test.js +160 -0
- package/dist-server/server/modules/git/tests/git-branch-diff.service.test.js.map +1 -0
- package/dist-server/server/modules/projects/project-clone.routes.js +108 -0
- package/dist-server/server/modules/projects/project-clone.routes.js.map +1 -0
- package/dist-server/server/modules/projects/projects.routes.js +13 -66
- package/dist-server/server/modules/projects/projects.routes.js.map +1 -1
- package/dist-server/server/modules/projects/services/project-clone-request.service.js +36 -0
- package/dist-server/server/modules/projects/services/project-clone-request.service.js.map +1 -0
- package/dist-server/server/modules/projects/services/project-clone.service.js +86 -32
- package/dist-server/server/modules/projects/services/project-clone.service.js.map +1 -1
- package/dist-server/server/modules/projects/services/project-delete.service.js +12 -1
- package/dist-server/server/modules/projects/services/project-delete.service.js.map +1 -1
- package/dist-server/server/modules/projects/services/project-star.service.js +2 -2
- package/dist-server/server/modules/projects/services/project-star.service.js.map +1 -1
- package/dist-server/server/modules/projects/tests/project-clone.routes.test.js +191 -0
- package/dist-server/server/modules/projects/tests/project-clone.routes.test.js.map +1 -0
- package/dist-server/server/modules/projects/tests/project-clone.service.test.js +275 -0
- package/dist-server/server/modules/projects/tests/project-clone.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +3 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +62 -9
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js +46 -0
- package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +31 -12
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js +472 -53
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +38 -11
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +1007 -60
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js +4 -1
- package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +204 -0
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js +32 -0
- package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +47 -0
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +71 -53
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +8 -0
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +1621 -431
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
- package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js +9 -2
- package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js +16 -8
- package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +274 -9
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js +5 -2
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +19 -2
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +134 -2
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/claude-cli-liveness.service.js +100 -0
- package/dist-server/server/modules/providers/services/claude-cli-liveness.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/claude-settings-permissions.service.js +97 -0
- package/dist-server/server/modules/providers/services/claude-settings-permissions.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +23 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +59 -5
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-runtime.service.js +8 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js +139 -35
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js +2 -4
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-history-cache.service.js +91 -0
- package/dist-server/server/modules/providers/services/session-history-cache.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js +105 -32
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +3 -60
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions.service.js +252 -12
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-auth.test.js +183 -0
- package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-background-work.test.js +172 -0
- package/dist-server/server/modules/providers/tests/claude-background-work.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-compaction.test.js +84 -0
- package/dist-server/server/modules/providers/tests/claude-compaction.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-message-model.test.js +123 -0
- package/dist-server/server/modules/providers/tests/claude-message-model.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-models.test.js +39 -0
- package/dist-server/server/modules/providers/tests/claude-models.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-runtime-hold.test.js +265 -0
- package/dist-server/server/modules/providers/tests/claude-runtime-hold.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js +1815 -33
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-settings-permissions.test.js +228 -0
- package/dist-server/server/modules/providers/tests/claude-settings-permissions.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js +16 -0
- package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-token-budget.test.js +85 -0
- package/dist-server/server/modules/providers/tests/claude-token-budget.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-message-editing.test.js +338 -0
- package/dist-server/server/modules/providers/tests/codex-message-editing.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-models.test.js +25 -0
- package/dist-server/server/modules/providers/tests/codex-models.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-runtime.test.js +83 -0
- package/dist-server/server/modules/providers/tests/codex-runtime.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-session-fork.test.js +54 -0
- package/dist-server/server/modules/providers/tests/codex-session-fork.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +354 -15
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/cursor-auth.test.js +167 -0
- package/dist-server/server/modules/providers/tests/cursor-auth.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/opencode-models.test.js +196 -4
- package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +19 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-capabilities.service.test.js +30 -0
- package/dist-server/server/modules/providers/tests/provider-capabilities.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +79 -1
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +164 -1
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +190 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/session-fork.test.js +113 -0
- package/dist-server/server/modules/providers/tests/session-fork.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js +139 -0
- package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js +90 -0
- package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js +122 -0
- package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/sessions.service.test.js +219 -1
- package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/skills.test.js +15 -3
- package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
- package/dist-server/server/modules/scheduled-messages/index.js +5 -0
- package/dist-server/server/modules/scheduled-messages/index.js.map +1 -0
- package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js +47 -0
- package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js.map +1 -0
- package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js +175 -0
- package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js.map +1 -0
- package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js +95 -0
- package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js.map +1 -0
- package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js +290 -0
- package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +23 -23
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -1
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +48 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -1
- package/dist-server/server/modules/user/tests/user.service.test.js +70 -0
- package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -1
- package/dist-server/server/modules/user/user.module.js +10 -1
- package/dist-server/server/modules/user/user.module.js.map +1 -1
- package/dist-server/server/modules/user/user.routes.js +44 -0
- package/dist-server/server/modules/user/user.routes.js.map +1 -1
- package/dist-server/server/modules/user/user.service.js +75 -0
- package/dist-server/server/modules/user/user.service.js.map +1 -1
- package/dist-server/server/modules/voice/tests/voice.service.test.js +3 -2
- package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -1
- package/dist-server/server/modules/websocket/index.js +7 -0
- package/dist-server/server/modules/websocket/index.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-run-registry.service.js +37 -49
- package/dist-server/server/modules/websocket/services/chat-run-registry.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +35 -5
- package/dist-server/server/modules/websocket/services/chat-session-writer.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +204 -10
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js +94 -0
- package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js.map +1 -0
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +236 -20
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-background-subscribe.test.js +137 -0
- package/dist-server/server/modules/websocket/tests/chat-background-subscribe.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js +263 -0
- package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js +29 -3
- package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js +96 -0
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js +106 -0
- package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +500 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -1
- package/dist-server/server/shared/claude-cli-path.js +22 -5
- package/dist-server/server/shared/claude-cli-path.js.map +1 -1
- package/dist-server/server/shared/index.js +3 -0
- package/dist-server/server/shared/index.js.map +1 -0
- package/dist-server/server/shared/message-unification.js +376 -0
- package/dist-server/server/shared/message-unification.js.map +1 -0
- package/dist-server/server/shared/tests/claude-cli-path.test.js +45 -1
- package/dist-server/server/shared/tests/claude-cli-path.test.js.map +1 -1
- package/dist-server/server/shared/tests/message-unification.test.js +174 -0
- package/dist-server/server/shared/tests/message-unification.test.js.map +1 -0
- package/dist-server/server/shared/tests/read-only-roots.test.js +124 -0
- package/dist-server/server/shared/tests/read-only-roots.test.js.map +1 -0
- package/dist-server/server/shared/tests/strip-ansi-sequences.test.js +31 -0
- package/dist-server/server/shared/tests/strip-ansi-sequences.test.js.map +1 -0
- package/dist-server/server/shared/utils.js +160 -0
- package/dist-server/server/shared/utils.js.map +1 -1
- package/electron/desktopWindow.js +6 -0
- package/electron/viewHost.js +25 -2
- package/package.json +20 -17
- package/server/index.ts +16 -5
- package/server/modules/agent/agent.module.ts +11 -1
- package/server/modules/agent/agent.routes.ts +200 -142
- package/server/modules/agent/tests/agent-run-registration.test.ts +348 -0
- package/server/modules/agent/tests/agent.routes.test.ts +51 -2
- package/server/modules/browser-use/browser-use.routes.ts +96 -33
- package/server/modules/database/connection.ts +2 -1
- package/server/modules/database/index.ts +10 -0
- package/server/modules/database/migrations.ts +51 -0
- package/server/modules/database/repositories/provider-models.ts +79 -6
- package/server/modules/database/repositories/scheduled-messages.db.ts +127 -0
- package/server/modules/database/repositories/session-drafts.db.ts +171 -0
- package/server/modules/database/repositories/sessions.db.ts +204 -3
- package/server/modules/database/repositories/user-preferences.db.ts +80 -0
- package/server/modules/database/schema.ts +103 -0
- package/server/modules/database/tests/provider-models.db.integration.test.ts +113 -0
- package/server/modules/database/tests/sessions.db.integration.test.ts +52 -0
- package/server/modules/database/tests/user-preferences.db.integration.test.ts +135 -0
- package/server/modules/file-tree/file-tree.module.ts +2 -1
- package/server/modules/file-tree/file-tree.service.ts +49 -7
- package/server/modules/file-tree/tests/file-tree.service.test.ts +163 -1
- package/server/modules/git/git-branch-diff.service.ts +204 -0
- package/server/modules/git/git-branch.service.ts +2 -12
- package/server/modules/git/git.routes.ts +100 -6
- package/server/modules/git/tests/git-branch-diff.service.test.ts +210 -0
- package/server/modules/projects/project-clone.routes.ts +142 -0
- package/server/modules/projects/projects.routes.ts +16 -81
- package/server/modules/projects/services/project-clone-request.service.ts +56 -0
- package/server/modules/projects/services/project-clone.service.ts +102 -34
- package/server/modules/projects/services/project-delete.service.ts +13 -1
- package/server/modules/projects/services/project-star.service.ts +2 -2
- package/server/modules/projects/tests/project-clone.routes.test.ts +246 -0
- package/server/modules/projects/tests/project-clone.service.test.ts +376 -0
- package/server/modules/providers/index.ts +4 -0
- package/server/modules/providers/list/claude/claude-auth.provider.ts +81 -11
- package/server/modules/providers/list/claude/claude-fork.provider.ts +57 -0
- package/server/modules/providers/list/claude/claude-models.provider.ts +37 -17
- package/server/modules/providers/list/claude/claude-runtime.provider.js +510 -54
- package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +40 -14
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +1195 -63
- package/server/modules/providers/list/claude/claude-skills.provider.ts +4 -1
- package/server/modules/providers/list/claude/claude.provider.ts +3 -0
- package/server/modules/providers/list/codex/codex-app-server.client.ts +243 -0
- package/server/modules/providers/list/codex/codex-fork.provider.ts +40 -0
- package/server/modules/providers/list/codex/codex-models.provider.ts +47 -0
- package/server/modules/providers/list/codex/{codex-runtime.provider.js → codex-runtime.provider.ts} +105 -70
- package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +9 -0
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +1847 -455
- package/server/modules/providers/list/codex/codex.provider.ts +3 -0
- package/server/modules/providers/list/cursor/cursor-auth.provider.ts +10 -2
- package/server/modules/providers/list/cursor/cursor-runtime.provider.js +17 -8
- package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +0 -1
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +297 -9
- package/server/modules/providers/list/opencode/opencode-runtime.provider.js +5 -2
- package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +30 -2
- package/server/modules/providers/provider.routes.ts +162 -2
- package/server/modules/providers/services/claude-cli-liveness.service.ts +121 -0
- package/server/modules/providers/services/claude-settings-permissions.service.ts +127 -0
- package/server/modules/providers/services/provider-capabilities.service.ts +40 -1
- package/server/modules/providers/services/provider-models.service.ts +71 -4
- package/server/modules/providers/services/provider-runtime.service.ts +11 -0
- package/server/modules/providers/services/provider-token-usage.service.ts +166 -39
- package/server/modules/providers/services/session-conversations-search.service.ts +2 -5
- package/server/modules/providers/services/session-history-cache.service.ts +150 -0
- package/server/modules/providers/services/session-synchronizer.service.ts +125 -38
- package/server/modules/providers/services/sessions-watcher.service.ts +3 -64
- package/server/modules/providers/services/sessions.service.ts +309 -17
- package/server/modules/providers/tests/claude-auth.test.ts +208 -0
- package/server/modules/providers/tests/claude-background-work.test.ts +213 -0
- package/server/modules/providers/tests/claude-compaction.test.ts +101 -0
- package/server/modules/providers/tests/claude-message-model.test.ts +160 -0
- package/server/modules/providers/tests/claude-models.test.ts +87 -0
- package/server/modules/providers/tests/claude-runtime-hold.test.ts +309 -0
- package/server/modules/providers/tests/claude-sessions.test.ts +2167 -37
- package/server/modules/providers/tests/claude-settings-permissions.test.ts +271 -0
- package/server/modules/providers/tests/claude-subagent-echo.test.ts +25 -0
- package/server/modules/providers/tests/claude-token-budget.test.ts +104 -0
- package/server/modules/providers/tests/codex-message-editing.test.ts +419 -0
- package/server/modules/providers/tests/codex-models.test.ts +37 -0
- package/server/modules/providers/tests/codex-runtime.test.ts +94 -0
- package/server/modules/providers/tests/codex-session-fork.test.ts +59 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +396 -15
- package/server/modules/providers/tests/cursor-auth.test.ts +187 -0
- package/server/modules/providers/tests/opencode-models.test.ts +266 -8
- package/server/modules/providers/tests/opencode-sessions.test.ts +40 -1
- package/server/modules/providers/tests/provider-capabilities.service.test.ts +37 -0
- package/server/modules/providers/tests/provider-models.service.test.ts +99 -1
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +188 -1
- package/server/modules/providers/tests/provider.routes.test.ts +230 -1
- package/server/modules/providers/tests/session-fork.test.ts +173 -0
- package/server/modules/providers/tests/session-history-cache.service.test.ts +165 -0
- package/server/modules/providers/tests/session-orphan-prune.test.ts +107 -0
- package/server/modules/providers/tests/session-synchronizer-coalescing.test.ts +136 -0
- package/server/modules/providers/tests/sessions.service.test.ts +303 -1
- package/server/modules/providers/tests/skills.test.ts +21 -5
- package/server/modules/scheduled-messages/index.ts +8 -0
- package/server/modules/scheduled-messages/scheduled-messages.routes.ts +68 -0
- package/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.ts +216 -0
- package/server/modules/scheduled-messages/services/scheduled-messages.service.ts +121 -0
- package/server/modules/scheduled-messages/tests/scheduled-messages.test.ts +354 -0
- package/server/modules/taskmaster/taskmaster.routes.ts +23 -33
- package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +57 -0
- package/server/modules/user/tests/user.service.test.ts +90 -0
- package/server/modules/user/user.module.ts +10 -1
- package/server/modules/user/user.routes.ts +44 -0
- package/server/modules/user/user.service.ts +105 -0
- package/server/modules/voice/tests/voice.service.test.ts +3 -2
- package/server/modules/websocket/README.md +4 -2
- package/server/modules/websocket/index.ts +8 -0
- package/server/modules/websocket/services/chat-run-registry.service.ts +45 -54
- package/server/modules/websocket/services/chat-session-writer.service.ts +36 -6
- package/server/modules/websocket/services/chat-websocket.service.ts +302 -16
- package/server/modules/websocket/services/session-upsert-broadcast.service.ts +108 -0
- package/server/modules/websocket/services/shell-websocket.service.ts +276 -22
- package/server/modules/websocket/tests/chat-background-subscribe.test.ts +167 -0
- package/server/modules/websocket/tests/chat-edit-send.test.ts +309 -0
- package/server/modules/websocket/tests/chat-run-registry.test.ts +34 -3
- package/server/modules/websocket/tests/chat-stop-task.test.ts +127 -0
- package/server/modules/websocket/tests/session-upsert-broadcast.test.ts +138 -0
- package/server/modules/websocket/tests/shell-websocket.service.test.ts +629 -0
- package/server/shared/claude-cli-path.ts +24 -6
- package/server/shared/index.ts +3 -0
- package/server/shared/interfaces.ts +91 -0
- package/server/shared/message-unification.ts +449 -0
- package/server/shared/tests/claude-cli-path.test.ts +58 -1
- package/server/shared/tests/message-unification.test.ts +218 -0
- package/server/shared/tests/read-only-roots.test.ts +139 -0
- package/server/shared/tests/strip-ansi-sequences.test.ts +42 -0
- package/server/shared/types.ts +382 -7
- package/server/shared/utils.ts +176 -0
- package/dist/assets/channel-_falYbU1.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-Dn-3CfpR.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-Dn-3CfpR.js +0 -1
- package/dist/assets/index-CzPLBvXT.css +0 -32
- package/dist/assets/index-DFkBBuSA.js +0 -1549
- package/dist/assets/stateDiagram-v2-UEYNNEHI-BvBxUUrZ.js +0 -1
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CsE-x4YK.js +0 -8
|
@@ -17,6 +17,8 @@ export function createAgentRouter(dependencies) {
|
|
|
17
17
|
const githubTokensDb = dependencies.githubTokens;
|
|
18
18
|
const projectsDb = dependencies.projects;
|
|
19
19
|
const providerModelsService = dependencies.models;
|
|
20
|
+
const sessionGateway = dependencies.sessions;
|
|
21
|
+
const runRegistry = dependencies.runs;
|
|
20
22
|
const queryClaudeSDK = dependencies.queryClaude;
|
|
21
23
|
const spawnCursor = dependencies.queryCursor;
|
|
22
24
|
const queryCodex = dependencies.queryCodex;
|
|
@@ -321,13 +323,15 @@ export function createAgentRouter(dependencies) {
|
|
|
321
323
|
await fs.mkdir(path.dirname(cloneDir), { recursive: true });
|
|
322
324
|
console.log('🔄 Cloning repository:', githubUrl);
|
|
323
325
|
console.log('📁 Destination:', cloneDir);
|
|
324
|
-
// Execute git clone
|
|
326
|
+
// Execute git clone. The host was validated above; the helper is
|
|
327
|
+
// still scoped to github.com over https so the token can answer no
|
|
328
|
+
// other challenge (a redirect, say).
|
|
325
329
|
const gitEnvironment = githubToken ? {
|
|
326
330
|
...process.env,
|
|
327
331
|
GIT_CONFIG_COUNT: '2',
|
|
328
332
|
GIT_CONFIG_KEY_0: 'credential.helper',
|
|
329
333
|
GIT_CONFIG_VALUE_0: '',
|
|
330
|
-
GIT_CONFIG_KEY_1: 'credential.helper',
|
|
334
|
+
GIT_CONFIG_KEY_1: 'credential.https://github.com.helper',
|
|
331
335
|
GIT_CONFIG_VALUE_1: '!f() { echo username=x-access-token; echo "password=$CLOUDCLI_GITHUB_TOKEN"; }; f',
|
|
332
336
|
CLOUDCLI_GITHUB_TOKEN: githubToken,
|
|
333
337
|
GIT_TERMINAL_PROMPT: '0'
|
|
@@ -403,21 +407,27 @@ export function createAgentRouter(dependencies) {
|
|
|
403
407
|
}
|
|
404
408
|
}
|
|
405
409
|
/**
|
|
406
|
-
* SSE Stream Writer -
|
|
410
|
+
* SSE Stream Writer - the HTTP response as one audience of a registered run.
|
|
411
|
+
*
|
|
412
|
+
* The provider runtime no longer writes here directly: it writes to the
|
|
413
|
+
* run's gateway writer, which remaps, sequences and buffers every event
|
|
414
|
+
* and forwards it — as a JSON string, the way it reaches a websocket — to
|
|
415
|
+
* each connection watching the run, this one included. The route's own
|
|
416
|
+
* events (status, session-id, GitHub results, done) are objects.
|
|
407
417
|
*/
|
|
408
418
|
class SSEStreamWriter {
|
|
409
|
-
constructor(res
|
|
419
|
+
constructor(res) {
|
|
410
420
|
this.res = res;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
421
|
+
}
|
|
422
|
+
/** What the gateway writer checks before forwarding: open until the response has ended. */
|
|
423
|
+
get readyState() {
|
|
424
|
+
return this.res.writableEnded ? 3 : 1;
|
|
414
425
|
}
|
|
415
426
|
send(data) {
|
|
416
427
|
if (this.res.writableEnded) {
|
|
417
428
|
return;
|
|
418
429
|
}
|
|
419
|
-
|
|
420
|
-
this.res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
430
|
+
this.res.write(`data: ${typeof data === 'string' ? data : JSON.stringify(data)}\n\n`);
|
|
421
431
|
}
|
|
422
432
|
end() {
|
|
423
433
|
if (!this.res.writableEnded) {
|
|
@@ -425,118 +435,66 @@ export function createAgentRouter(dependencies) {
|
|
|
425
435
|
this.res.end();
|
|
426
436
|
}
|
|
427
437
|
}
|
|
428
|
-
setSessionId(sessionId) {
|
|
429
|
-
this.sessionId = sessionId;
|
|
430
|
-
this.send({ type: 'session-id', sessionId });
|
|
431
|
-
}
|
|
432
|
-
getSessionId() {
|
|
433
|
-
return this.sessionId;
|
|
434
|
-
}
|
|
435
438
|
}
|
|
436
439
|
/**
|
|
437
|
-
* Non-streaming response collector
|
|
440
|
+
* Non-streaming response collector - the same audience role, kept in
|
|
441
|
+
* memory until the run ends.
|
|
438
442
|
*/
|
|
439
443
|
class ResponseCollector {
|
|
440
|
-
constructor(
|
|
444
|
+
constructor() {
|
|
441
445
|
this.messages = [];
|
|
442
|
-
this.sessionId = null;
|
|
443
|
-
this.userId = userId;
|
|
444
446
|
}
|
|
447
|
+
readyState = 1;
|
|
445
448
|
send(data) {
|
|
446
|
-
//
|
|
447
|
-
|
|
448
|
-
|
|
449
|
+
// The run's events arrive as JSON strings; the route's own as objects.
|
|
450
|
+
// Stored as objects either way so the filters below read one shape.
|
|
451
|
+
let record = data;
|
|
449
452
|
if (typeof data === 'string') {
|
|
450
453
|
try {
|
|
451
|
-
|
|
452
|
-
if (parsed.sessionId) {
|
|
453
|
-
this.sessionId = parsed.sessionId;
|
|
454
|
-
}
|
|
454
|
+
record = JSON.parse(data);
|
|
455
455
|
}
|
|
456
456
|
catch (e) {
|
|
457
|
-
// Not JSON,
|
|
457
|
+
// Not JSON, keep as is
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
|
-
|
|
461
|
-
this.sessionId = data.sessionId;
|
|
462
|
-
}
|
|
460
|
+
this.messages.push(record);
|
|
463
461
|
}
|
|
464
462
|
end() {
|
|
465
463
|
// Do nothing - we'll collect all messages
|
|
466
464
|
}
|
|
467
|
-
setSessionId(sessionId) {
|
|
468
|
-
this.sessionId = sessionId;
|
|
469
|
-
}
|
|
470
|
-
getSessionId() {
|
|
471
|
-
return this.sessionId;
|
|
472
|
-
}
|
|
473
465
|
getMessages() {
|
|
474
466
|
return this.messages;
|
|
475
467
|
}
|
|
476
468
|
/**
|
|
477
|
-
*
|
|
469
|
+
* The assistant's replies, as the normalized `text` events the run
|
|
470
|
+
* produced. (Earlier versions filtered a `claude-response` shape no
|
|
471
|
+
* runtime has emitted since the providers were unified, so this was
|
|
472
|
+
* always empty.)
|
|
478
473
|
*/
|
|
479
474
|
getAssistantMessages() {
|
|
480
|
-
|
|
481
|
-
for (const msg of this.messages) {
|
|
482
|
-
// Skip initial status message
|
|
483
|
-
if (msg && msg.type === 'status') {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
// Handle JSON strings
|
|
487
|
-
if (typeof msg === 'string') {
|
|
488
|
-
try {
|
|
489
|
-
const parsed = JSON.parse(msg);
|
|
490
|
-
// Only include claude-response messages with assistant type
|
|
491
|
-
if (parsed.type === 'claude-response' && parsed.data && parsed.data.type === 'assistant') {
|
|
492
|
-
assistantMessages.push(parsed.data);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
catch (e) {
|
|
496
|
-
// Not JSON, skip
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
return assistantMessages;
|
|
475
|
+
return this.messages.filter((msg) => msg && msg.kind === 'text' && msg.role === 'assistant');
|
|
501
476
|
}
|
|
502
477
|
/**
|
|
503
|
-
*
|
|
478
|
+
* The run's token usage, from the last context-window report the
|
|
479
|
+
* runtime streamed (`status` / `token_budget`, which the Claude and Codex
|
|
480
|
+
* runtimes emit per assistant message); zeros for a runtime that
|
|
481
|
+
* reports none.
|
|
504
482
|
*/
|
|
505
483
|
getTotalTokens() {
|
|
506
|
-
let
|
|
507
|
-
let totalOutput = 0;
|
|
508
|
-
let totalCacheRead = 0;
|
|
509
|
-
let totalCacheCreation = 0;
|
|
484
|
+
let budget = null;
|
|
510
485
|
for (const msg of this.messages) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (typeof msg === 'string') {
|
|
514
|
-
try {
|
|
515
|
-
data = JSON.parse(msg);
|
|
516
|
-
}
|
|
517
|
-
catch (e) {
|
|
518
|
-
continue;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
// Extract usage from claude-response messages
|
|
522
|
-
if (data && data.type === 'claude-response' && data.data) {
|
|
523
|
-
const msgData = data.data;
|
|
524
|
-
if (msgData.message && msgData.message.usage) {
|
|
525
|
-
const usage = msgData.message.usage;
|
|
526
|
-
totalInput += usage.input_tokens || 0;
|
|
527
|
-
totalOutput += usage.output_tokens || 0;
|
|
528
|
-
totalCacheRead += usage.cache_read_input_tokens || 0;
|
|
529
|
-
totalCacheCreation += usage.cache_creation_input_tokens || 0;
|
|
530
|
-
}
|
|
486
|
+
if (msg && msg.kind === 'status' && msg.text === 'token_budget' && msg.tokenBudget) {
|
|
487
|
+
budget = msg.tokenBudget;
|
|
531
488
|
}
|
|
532
489
|
}
|
|
533
|
-
const inputTokens =
|
|
490
|
+
const inputTokens = budget?.inputTokens ?? 0;
|
|
491
|
+
const outputTokens = budget?.outputTokens ?? 0;
|
|
534
492
|
return {
|
|
535
493
|
inputTokens,
|
|
536
|
-
outputTokens
|
|
537
|
-
cacheReadTokens:
|
|
538
|
-
cacheCreationTokens:
|
|
539
|
-
totalTokens: inputTokens +
|
|
494
|
+
outputTokens,
|
|
495
|
+
cacheReadTokens: budget?.cacheReadTokens ?? 0,
|
|
496
|
+
cacheCreationTokens: budget?.cacheCreationTokens ?? 0,
|
|
497
|
+
totalTokens: inputTokens + outputTokens
|
|
540
498
|
};
|
|
541
499
|
}
|
|
542
500
|
}
|
|
@@ -579,6 +537,11 @@ export function createAgentRouter(dependencies) {
|
|
|
579
537
|
* - true: Returns text/event-stream with incremental updates
|
|
580
538
|
* - false: Returns complete JSON response after completion
|
|
581
539
|
*
|
|
540
|
+
* @param {string} sessionId - (Optional) Continue an existing session: the id an earlier
|
|
541
|
+
* response reported as `sessionId` / in its `session-id` event.
|
|
542
|
+
* A session already mid-run is refused (409); an unknown id, 404.
|
|
543
|
+
* Omitted: a new session is created for the run.
|
|
544
|
+
*
|
|
582
545
|
* @param {string} model - (Optional) Model identifier for providers.
|
|
583
546
|
*
|
|
584
547
|
* Claude models: 'default', 'sonnet', 'opus', 'haiku', 'sonnet[1m]', 'opus[1m]', 'fable'
|
|
@@ -716,11 +679,21 @@ export function createAgentRouter(dependencies) {
|
|
|
716
679
|
* RESPONSE FORMATS
|
|
717
680
|
* ================================================================================================
|
|
718
681
|
*
|
|
682
|
+
* Every run is registered with the chat run registry like a message sent
|
|
683
|
+
* from the UI: it is on GET /api/providers/sessions/running while it goes,
|
|
684
|
+
* a tab that opens the session subscribes to it live, and its events
|
|
685
|
+
* reach this response the way they reach a tab — `sessionId` is the app
|
|
686
|
+
* session id, each event carries a `seq`, and the provider's own
|
|
687
|
+
* `session_created` is folded into the session row instead of forwarded.
|
|
688
|
+
*
|
|
719
689
|
* Streaming Response (stream=true):
|
|
720
690
|
* Content-Type: text/event-stream
|
|
721
691
|
* Events:
|
|
722
692
|
* - { type: "status", message: "...", projectPath: "..." }
|
|
723
|
-
* - { type: "
|
|
693
|
+
* - { type: "session-id", sessionId: "..." } // the app session id, usable as `sessionId` later
|
|
694
|
+
* - { kind: "text" | "tool_use" | ... , sessionId, seq, ... } // the provider's normalized events
|
|
695
|
+
* - { kind: "complete", ... }
|
|
696
|
+
* - { type: "status", message: "Run aborted", aborted: true } // only when a tab aborted the run; no branch/PR follows
|
|
724
697
|
* - { type: "github-branch", branch: { name: "...", url: "..." } }
|
|
725
698
|
* - { type: "github-pr", pullRequest: { number: 42, url: "..." } }
|
|
726
699
|
* - { type: "github-error", error: "..." }
|
|
@@ -729,9 +702,10 @@ export function createAgentRouter(dependencies) {
|
|
|
729
702
|
* Non-Streaming Response (stream=false):
|
|
730
703
|
* Content-Type: application/json
|
|
731
704
|
* {
|
|
732
|
-
* success: true,
|
|
733
|
-
* sessionId: "session-123",
|
|
734
|
-
*
|
|
705
|
+
* success: true, // false, with aborted: true, when a tab aborted the run
|
|
706
|
+
* sessionId: "session-123", // the app session id; pass it back as `sessionId` to continue
|
|
707
|
+
* providerSessionId: "native-id", // the provider's own id, for tooling that drives the CLI directly
|
|
708
|
+
* messages: [...], // The assistant's replies: the run's normalized `text` events
|
|
735
709
|
* tokens: {
|
|
736
710
|
* inputTokens: 150,
|
|
737
711
|
* outputTokens: 50,
|
|
@@ -751,7 +725,7 @@ export function createAgentRouter(dependencies) {
|
|
|
751
725
|
* }
|
|
752
726
|
*
|
|
753
727
|
* Error Response:
|
|
754
|
-
* HTTP Status: 400, 401, 500
|
|
728
|
+
* HTTP Status: 400, 401, 404 (unknown sessionId), 409 (session already mid-run), 500
|
|
755
729
|
* Content-Type: application/json
|
|
756
730
|
* { success: false, error: "Error description" }
|
|
757
731
|
*
|
|
@@ -783,7 +757,15 @@ export function createAgentRouter(dependencies) {
|
|
|
783
757
|
* }
|
|
784
758
|
*/
|
|
785
759
|
router.post('/', validateExternalApiKey, async (req, res) => {
|
|
786
|
-
const { githubUrl, projectPath, message,
|
|
760
|
+
const { githubUrl, projectPath, message, model, githubToken, branchName } = req.body;
|
|
761
|
+
// Transport input is typed here, before anything binds it to a query:
|
|
762
|
+
// the lookup below runs outside the try, where a throw would be an
|
|
763
|
+
// unhandled rejection.
|
|
764
|
+
if (req.body.sessionId !== undefined && req.body.sessionId !== null && typeof req.body.sessionId !== 'string') {
|
|
765
|
+
return res.status(400).json({ error: 'sessionId must be a string' });
|
|
766
|
+
}
|
|
767
|
+
const sessionId = typeof req.body.sessionId === 'string' && req.body.sessionId.trim() ? req.body.sessionId.trim() : null;
|
|
768
|
+
const requestedProvider = req.body.provider === undefined || req.body.provider === null ? null : req.body.provider;
|
|
787
769
|
const effort = typeof req.body.effort === 'string' && req.body.effort.trim()
|
|
788
770
|
? req.body.effort.trim()
|
|
789
771
|
: undefined;
|
|
@@ -800,7 +782,7 @@ export function createAgentRouter(dependencies) {
|
|
|
800
782
|
if (!message || !message.trim()) {
|
|
801
783
|
return res.status(400).json({ error: 'message is required' });
|
|
802
784
|
}
|
|
803
|
-
if (!['claude', 'cursor', 'codex', 'opencode'].includes(
|
|
785
|
+
if (requestedProvider !== null && !['claude', 'cursor', 'codex', 'opencode'].includes(requestedProvider)) {
|
|
804
786
|
return res.status(400).json({ error: 'provider must be "claude", "cursor", "codex", or "opencode"' });
|
|
805
787
|
}
|
|
806
788
|
// Validate GitHub branch/PR creation requirements
|
|
@@ -808,9 +790,33 @@ export function createAgentRouter(dependencies) {
|
|
|
808
790
|
if ((createBranch || createPR) && !githubUrl && !projectPath) {
|
|
809
791
|
return res.status(400).json({ error: 'createBranch and createPR require either githubUrl or projectPath with a GitHub remote' });
|
|
810
792
|
}
|
|
793
|
+
// A run continues a session the caller names, by its app id or — for a
|
|
794
|
+
// caller that stored what an earlier response called `sessionId` — the
|
|
795
|
+
// provider-native one, which the row is also keyed by once indexed. The
|
|
796
|
+
// row, not the request, says which provider the session belongs to, as
|
|
797
|
+
// it does for a chat send; a request that names another is refused.
|
|
798
|
+
let sessionRow = null;
|
|
799
|
+
if (sessionId) {
|
|
800
|
+
sessionRow = sessionGateway.getSessionById(sessionId) ?? sessionGateway.getSessionByProviderSessionId(sessionId);
|
|
801
|
+
if (!sessionRow) {
|
|
802
|
+
return res.status(404).json({ error: `Session "${sessionId}" was not found` });
|
|
803
|
+
}
|
|
804
|
+
if (requestedProvider !== null && requestedProvider !== sessionRow.provider) {
|
|
805
|
+
return res.status(400).json({ error: `Session "${sessionRow.session_id}" belongs to provider "${sessionRow.provider}"` });
|
|
806
|
+
}
|
|
807
|
+
// Refused before any side effect — a clone per retry would pile up
|
|
808
|
+
// under external-projects. startRun below still has the last word.
|
|
809
|
+
if (runRegistry.isProcessing(sessionRow.session_id)) {
|
|
810
|
+
return res.status(409).json({ error: `Session "${sessionRow.session_id}" already has a run in progress` });
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
const provider = sessionRow?.provider ?? requestedProvider ?? 'claude';
|
|
811
814
|
let finalProjectPath = null;
|
|
812
815
|
let clonedProjectCreated = false;
|
|
813
816
|
let writer = null;
|
|
817
|
+
// The run as the chat socket registers one: on the running-sessions
|
|
818
|
+
// list, subscribable from any tab, and completed on every exit path.
|
|
819
|
+
let run = null;
|
|
814
820
|
try {
|
|
815
821
|
// Determine the final project path
|
|
816
822
|
if (githubUrl) {
|
|
@@ -841,6 +847,11 @@ export function createAgentRouter(dependencies) {
|
|
|
841
847
|
}
|
|
842
848
|
}
|
|
843
849
|
finalProjectPath = normalizeProjectPath(finalProjectPath);
|
|
850
|
+
// A continued session runs where it lives, as a chat send does; a
|
|
851
|
+
// request that resolved to another directory is not that session.
|
|
852
|
+
if (sessionRow && sessionRow.project_path && normalizeProjectPath(sessionRow.project_path) !== finalProjectPath) {
|
|
853
|
+
throw new Error(`Session "${sessionRow.session_id}" belongs to project ${sessionRow.project_path}, not ${finalProjectPath}`);
|
|
854
|
+
}
|
|
844
855
|
// Register project path in DB (or reuse existing active registration)
|
|
845
856
|
const registrationResult = projectsDb.createProjectPath(finalProjectPath, null);
|
|
846
857
|
if (registrationResult.outcome === 'active_conflict') {
|
|
@@ -849,81 +860,104 @@ export function createAgentRouter(dependencies) {
|
|
|
849
860
|
else {
|
|
850
861
|
console.log('Project registered:', registrationResult.project);
|
|
851
862
|
}
|
|
852
|
-
//
|
|
863
|
+
// A brand-new run gets its app session row first, as a chat send does:
|
|
864
|
+
// the id is stable for the conversation, the sidebar can list it, and
|
|
865
|
+
// the provider-native id is mapped onto it when the runtime announces it.
|
|
866
|
+
const appSessionId = sessionRow
|
|
867
|
+
? sessionRow.session_id
|
|
868
|
+
: sessionGateway.createAppSession(provider, finalProjectPath, message.trim()).sessionId;
|
|
869
|
+
// Registered before any header goes out, so a session already mid-run
|
|
870
|
+
// is refused with a plain 409 rather than an empty stream. The HTTP
|
|
871
|
+
// response is the run's first audience; a tab that opens the session
|
|
872
|
+
// subscribes as another, and replays what it missed.
|
|
873
|
+
const audience = stream ? new SSEStreamWriter(res) : new ResponseCollector();
|
|
874
|
+
run = runRegistry.startRun({
|
|
875
|
+
appSessionId,
|
|
876
|
+
provider,
|
|
877
|
+
providerSessionId: sessionRow?.provider_session_id ?? null,
|
|
878
|
+
connection: audience,
|
|
879
|
+
userId: req.user.id,
|
|
880
|
+
});
|
|
881
|
+
if (!run) {
|
|
882
|
+
if (cleanup && githubUrl && clonedProjectCreated) {
|
|
883
|
+
cleanupProject(finalProjectPath, null);
|
|
884
|
+
}
|
|
885
|
+
return res.status(409).json({ error: `Session "${appSessionId}" already has a run in progress` });
|
|
886
|
+
}
|
|
887
|
+
writer = audience;
|
|
853
888
|
if (stream) {
|
|
854
889
|
// Set up SSE headers for streaming
|
|
855
890
|
res.setHeader('Content-Type', 'text/event-stream');
|
|
856
891
|
res.setHeader('Cache-Control', 'no-cache');
|
|
857
892
|
res.setHeader('Connection', 'keep-alive');
|
|
858
893
|
res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering
|
|
859
|
-
writer = new SSEStreamWriter(res, req.user.id);
|
|
860
|
-
// Send initial status
|
|
861
|
-
writer.send({
|
|
862
|
-
type: 'status',
|
|
863
|
-
message: githubUrl ? 'Repository cloned and session started' : 'Session started',
|
|
864
|
-
projectPath: finalProjectPath
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
else {
|
|
868
|
-
// Non-streaming mode: collect messages
|
|
869
|
-
writer = new ResponseCollector(req.user.id);
|
|
870
|
-
// Collect initial status message
|
|
871
|
-
writer.send({
|
|
872
|
-
type: 'status',
|
|
873
|
-
message: githubUrl ? 'Repository cloned and session started' : 'Session started',
|
|
874
|
-
projectPath: finalProjectPath
|
|
875
|
-
});
|
|
876
894
|
}
|
|
877
|
-
|
|
878
|
-
|
|
895
|
+
// The route's own opening events. `session-id` is the app session id:
|
|
896
|
+
// what the UI opens the conversation under, and what a later request
|
|
897
|
+
// passes back as `sessionId` to continue it.
|
|
898
|
+
writer.send({
|
|
899
|
+
type: 'status',
|
|
900
|
+
message: githubUrl ? 'Repository cloned and session started' : 'Session started',
|
|
901
|
+
projectPath: finalProjectPath
|
|
902
|
+
});
|
|
903
|
+
writer.send({ type: 'session-id', sessionId: appSessionId });
|
|
904
|
+
const codexModels = await providerModelsService.getProviderModels('codex');
|
|
905
|
+
const opencodeModels = await providerModelsService.getProviderModels('opencode');
|
|
879
906
|
// Start the appropriate session
|
|
880
907
|
if (provider === 'claude') {
|
|
881
908
|
console.log('🤖 Starting Claude SDK session');
|
|
882
909
|
await queryClaudeSDK(message.trim(), {
|
|
883
910
|
projectPath: finalProjectPath,
|
|
884
911
|
cwd: finalProjectPath,
|
|
885
|
-
sessionId:
|
|
912
|
+
sessionId: appSessionId,
|
|
886
913
|
model: model,
|
|
887
914
|
effort,
|
|
888
915
|
permissionMode: 'bypassPermissions' // Bypass all permissions for API calls
|
|
889
|
-
}, writer);
|
|
916
|
+
}, run.writer);
|
|
890
917
|
}
|
|
891
918
|
else if (provider === 'cursor') {
|
|
892
919
|
console.log('🖱️ Starting Cursor CLI session');
|
|
893
920
|
await spawnCursor(message.trim(), {
|
|
894
921
|
projectPath: finalProjectPath,
|
|
895
922
|
cwd: finalProjectPath,
|
|
896
|
-
sessionId:
|
|
923
|
+
sessionId: appSessionId,
|
|
897
924
|
model: model || undefined,
|
|
898
925
|
skipPermissions: true // Bypass permissions for Cursor
|
|
899
|
-
}, writer);
|
|
926
|
+
}, run.writer);
|
|
900
927
|
}
|
|
901
928
|
else if (provider === 'codex') {
|
|
902
929
|
console.log('🤖 Starting Codex SDK session');
|
|
903
930
|
await queryCodex(message.trim(), {
|
|
904
931
|
projectPath: finalProjectPath,
|
|
905
932
|
cwd: finalProjectPath,
|
|
906
|
-
sessionId:
|
|
933
|
+
sessionId: appSessionId,
|
|
907
934
|
model: model || codexModels.DEFAULT,
|
|
908
935
|
effort,
|
|
909
936
|
permissionMode: 'bypassPermissions'
|
|
910
|
-
}, writer);
|
|
937
|
+
}, run.writer);
|
|
911
938
|
}
|
|
912
939
|
else if (provider === 'opencode') {
|
|
913
940
|
console.log('Starting OpenCode CLI session');
|
|
914
941
|
await spawnOpenCode(message.trim(), {
|
|
915
942
|
projectPath: finalProjectPath,
|
|
916
943
|
cwd: finalProjectPath,
|
|
917
|
-
sessionId:
|
|
944
|
+
sessionId: appSessionId,
|
|
918
945
|
model: model || opencodeModels.DEFAULT,
|
|
919
946
|
effort,
|
|
920
947
|
permissionMode: 'bypassPermissions' // Agent runs are non-interactive, like the other providers above
|
|
921
|
-
}, writer);
|
|
948
|
+
}, run.writer);
|
|
949
|
+
}
|
|
950
|
+
// A tab can now abort the run (`chat.abort`), on which the runtime
|
|
951
|
+
// returns as it does on completion. What the interrupted agent left
|
|
952
|
+
// behind is not a result to branch or open a PR from.
|
|
953
|
+
const aborted = run.events.some((event) => event.kind === 'complete' && event.aborted === true);
|
|
954
|
+
if (aborted) {
|
|
955
|
+
writer.send({ type: 'status', message: 'Run aborted', aborted: true });
|
|
922
956
|
}
|
|
923
957
|
// Handle GitHub branch and PR creation after successful agent completion
|
|
924
958
|
let branchInfo = null;
|
|
925
959
|
let prInfo = null;
|
|
926
|
-
if (createBranch || createPR) {
|
|
960
|
+
if (!aborted && (createBranch || createPR)) {
|
|
927
961
|
try {
|
|
928
962
|
console.log('🔄 Starting GitHub branch/PR creation workflow...');
|
|
929
963
|
// Get GitHub token
|
|
@@ -1098,8 +1132,12 @@ export function createAgentRouter(dependencies) {
|
|
|
1098
1132
|
const assistantMessages = writer.getAssistantMessages();
|
|
1099
1133
|
const tokenSummary = writer.getTotalTokens();
|
|
1100
1134
|
const response = {
|
|
1101
|
-
success:
|
|
1102
|
-
|
|
1135
|
+
success: !aborted,
|
|
1136
|
+
...(aborted ? { aborted: true } : {}),
|
|
1137
|
+
sessionId: appSessionId,
|
|
1138
|
+
// The provider-native id, for a caller that drives the CLI itself
|
|
1139
|
+
// (`claude --resume`); `sessionId` is what this API and the UI use.
|
|
1140
|
+
providerSessionId: run.writer.getSessionId(),
|
|
1103
1141
|
messages: assistantMessages,
|
|
1104
1142
|
tokens: tokenSummary,
|
|
1105
1143
|
projectPath: finalProjectPath
|
|
@@ -1116,7 +1154,7 @@ export function createAgentRouter(dependencies) {
|
|
|
1116
1154
|
// Clean up if requested
|
|
1117
1155
|
if (cleanup && githubUrl && clonedProjectCreated) {
|
|
1118
1156
|
// Only cleanup if we cloned a repo (not for existing project paths)
|
|
1119
|
-
const sessionIdForCleanup = writer.getSessionId();
|
|
1157
|
+
const sessionIdForCleanup = run.writer.getSessionId();
|
|
1120
1158
|
setTimeout(() => {
|
|
1121
1159
|
cleanupProject(finalProjectPath, sessionIdForCleanup);
|
|
1122
1160
|
}, 5000);
|
|
@@ -1126,7 +1164,7 @@ export function createAgentRouter(dependencies) {
|
|
|
1126
1164
|
console.error('❌ External session error:', error);
|
|
1127
1165
|
// Clean up on error
|
|
1128
1166
|
if (finalProjectPath && cleanup && githubUrl && clonedProjectCreated) {
|
|
1129
|
-
const sessionIdForCleanup =
|
|
1167
|
+
const sessionIdForCleanup = run ? run.writer.getSessionId() : null;
|
|
1130
1168
|
cleanupProject(finalProjectPath, sessionIdForCleanup);
|
|
1131
1169
|
}
|
|
1132
1170
|
if (stream) {
|
|
@@ -1137,7 +1175,7 @@ export function createAgentRouter(dependencies) {
|
|
|
1137
1175
|
res.setHeader('Cache-Control', 'no-cache');
|
|
1138
1176
|
res.setHeader('Connection', 'keep-alive');
|
|
1139
1177
|
res.setHeader('X-Accel-Buffering', 'no');
|
|
1140
|
-
writer = new SSEStreamWriter(res
|
|
1178
|
+
writer = new SSEStreamWriter(res);
|
|
1141
1179
|
}
|
|
1142
1180
|
if (!res.writableEnded) {
|
|
1143
1181
|
writer.send({
|
|
@@ -1155,6 +1193,15 @@ export function createAgentRouter(dependencies) {
|
|
|
1155
1193
|
});
|
|
1156
1194
|
}
|
|
1157
1195
|
}
|
|
1196
|
+
finally {
|
|
1197
|
+
// Safety net, as for a chat send: a runtime that threw or resolved
|
|
1198
|
+
// without its terminal `complete` would leave the session listed as
|
|
1199
|
+
// running in every tab. Scoped to this run, so a run the session
|
|
1200
|
+
// started meanwhile is left alone.
|
|
1201
|
+
if (run) {
|
|
1202
|
+
runRegistry.completeRunIfCurrent(run, { exitCode: 1 });
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1158
1205
|
});
|
|
1159
1206
|
return router;
|
|
1160
1207
|
}
|