@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
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
PROJECTS_TABLE_SCHEMA_SQL,
|
|
8
8
|
PROVIDER_MODELS_TABLE_SCHEMA_SQL,
|
|
9
9
|
PUSH_SUBSCRIPTIONS_TABLE_SCHEMA_SQL,
|
|
10
|
+
SESSION_DRAFTS_TABLE_SCHEMA_SQL,
|
|
11
|
+
SUPERSEDED_PROVIDER_SESSIONS_TABLE_SCHEMA_SQL,
|
|
12
|
+
SCHEDULED_MESSAGES_TABLE_SCHEMA_SQL,
|
|
10
13
|
SESSIONS_TABLE_SCHEMA_SQL,
|
|
14
|
+
USER_PREFERENCES_TABLE_SCHEMA_SQL,
|
|
11
15
|
USER_NOTIFICATION_PREFERENCES_TABLE_SCHEMA_SQL,
|
|
12
16
|
VAPID_KEYS_TABLE_SCHEMA_SQL,
|
|
13
17
|
} from '@/modules/database/schema.js';
|
|
@@ -403,6 +407,29 @@ const addProviderSessionIdMapping = (db: Database): void => {
|
|
|
403
407
|
`);
|
|
404
408
|
};
|
|
405
409
|
|
|
410
|
+
/**
|
|
411
|
+
* Adds the `forked_from_session_id` column recording where a branched session
|
|
412
|
+
* came from.
|
|
413
|
+
*
|
|
414
|
+
* Nothing is backfilled: a session that predates forking was not forked.
|
|
415
|
+
*/
|
|
416
|
+
/**
|
|
417
|
+
* Adds the transcript path to the superseded-session record.
|
|
418
|
+
*
|
|
419
|
+
* Only rows written before this column existed lack it, and there is nothing
|
|
420
|
+
* to backfill from — the session stopped pointing at that file when the row
|
|
421
|
+
* was created — so they keep a NULL and the delete path skips them.
|
|
422
|
+
*/
|
|
423
|
+
const addSupersededTranscriptPathColumn = (db: Database): void => {
|
|
424
|
+
const columnNames = getTableInfo(db, 'superseded_provider_sessions').map((column) => column.name);
|
|
425
|
+
addColumnToTableIfNotExists(db, 'superseded_provider_sessions', columnNames, 'jsonl_path', 'TEXT');
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const addForkedFromSessionIdColumn = (db: Database): void => {
|
|
429
|
+
const columnNames = getTableInfo(db, 'sessions').map((column) => column.name);
|
|
430
|
+
addColumnToTableIfNotExists(db, 'sessions', columnNames, 'forked_from_session_id', 'TEXT');
|
|
431
|
+
};
|
|
432
|
+
|
|
406
433
|
/**
|
|
407
434
|
* Adds the `model` column that records which model each session runs with.
|
|
408
435
|
*
|
|
@@ -430,6 +457,19 @@ const addSessionEffortColumn = (db: Database): void => {
|
|
|
430
457
|
addColumnToTableIfNotExists(db, 'sessions', columnNames, 'effort', 'TEXT');
|
|
431
458
|
};
|
|
432
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Adds the reasoning-effort metadata columns to the custom-model library.
|
|
462
|
+
*
|
|
463
|
+
* Existing rows stay NULL on purpose: no effort levels were ever declared for
|
|
464
|
+
* them, and a guessed list could offer levels the model rejects. Those models
|
|
465
|
+
* keep hiding the composer's Reasoning section until the user declares levels.
|
|
466
|
+
*/
|
|
467
|
+
const addProviderModelEffortColumns = (db: Database): void => {
|
|
468
|
+
const columnNames = getTableInfo(db, 'provider_models').map((column) => column.name);
|
|
469
|
+
addColumnToTableIfNotExists(db, 'provider_models', columnNames, 'effort_values', 'TEXT DEFAULT NULL');
|
|
470
|
+
addColumnToTableIfNotExists(db, 'provider_models', columnNames, 'effort_default', 'TEXT DEFAULT NULL');
|
|
471
|
+
};
|
|
472
|
+
|
|
433
473
|
const ensureProjectsForSessionPaths = (db: Database): void => {
|
|
434
474
|
if (!tableExists(db, 'sessions')) {
|
|
435
475
|
return;
|
|
@@ -477,6 +517,11 @@ export const runMigrations = (db: Database) => {
|
|
|
477
517
|
CREATE INDEX IF NOT EXISTS idx_provider_models_provider_order
|
|
478
518
|
ON provider_models(provider, sort_order, id)
|
|
479
519
|
`);
|
|
520
|
+
addProviderModelEffortColumns(db);
|
|
521
|
+
db.exec(USER_PREFERENCES_TABLE_SCHEMA_SQL);
|
|
522
|
+
db.exec(SESSION_DRAFTS_TABLE_SCHEMA_SQL);
|
|
523
|
+
db.exec(SUPERSEDED_PROVIDER_SESSIONS_TABLE_SCHEMA_SQL);
|
|
524
|
+
addSupersededTranscriptPathColumn(db);
|
|
480
525
|
|
|
481
526
|
db.exec(PROJECTS_TABLE_SCHEMA_SQL);
|
|
482
527
|
rebuildProjectsTableWithPrimaryKeySchema(db);
|
|
@@ -487,11 +532,17 @@ export const runMigrations = (db: Database) => {
|
|
|
487
532
|
addProviderSessionIdMapping(db);
|
|
488
533
|
addSessionModelColumn(db);
|
|
489
534
|
addSessionEffortColumn(db);
|
|
535
|
+
addForkedFromSessionIdColumn(db);
|
|
490
536
|
ensureProjectsForSessionPaths(db);
|
|
537
|
+
db.exec(SCHEDULED_MESSAGES_TABLE_SCHEMA_SQL);
|
|
491
538
|
|
|
492
539
|
db.exec('CREATE INDEX IF NOT EXISTS idx_session_ids_lookup ON sessions(session_id)');
|
|
493
540
|
db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_provider_session_id ON sessions(provider_session_id)');
|
|
494
541
|
db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_project_path ON sessions(project_path)');
|
|
542
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_forked_from ON sessions(forked_from_session_id)');
|
|
543
|
+
// The due-message poll runs on a timer; without this it table-scans.
|
|
544
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_scheduled_messages_due ON scheduled_messages(status, scheduled_for)');
|
|
545
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_scheduled_messages_session ON scheduled_messages(session_id)');
|
|
495
546
|
db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_is_archived ON sessions(isArchived)');
|
|
496
547
|
db.exec('CREATE INDEX IF NOT EXISTS idx_projects_is_starred ON projects(isStarred)');
|
|
497
548
|
db.exec('CREATE INDEX IF NOT EXISTS idx_projects_is_archived ON projects(isArchived)');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getConnection } from '@/modules/database/connection.js';
|
|
2
2
|
import type {
|
|
3
|
+
CustomProviderModelEffort,
|
|
3
4
|
CustomProviderModelInput,
|
|
4
5
|
CustomProviderModelRecord,
|
|
5
6
|
LLMProvider,
|
|
@@ -11,6 +12,56 @@ type CustomProviderModelRow = {
|
|
|
11
12
|
model_id: string;
|
|
12
13
|
model_name: string;
|
|
13
14
|
sort_order: number;
|
|
15
|
+
effort_values: string | null;
|
|
16
|
+
effort_default: string | null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const CUSTOM_PROVIDER_MODEL_COLUMNS = `
|
|
20
|
+
id, provider, model_id, model_name, sort_order, effort_values, effort_default
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Decodes the stored effort columns. Anything that is not a non-empty JSON
|
|
25
|
+
* array of strings reads back as "no metadata" rather than failing the whole
|
|
26
|
+
* catalog, so one hand-edited row cannot break every model picker.
|
|
27
|
+
*/
|
|
28
|
+
const readStoredEffort = (row: CustomProviderModelRow): CustomProviderModelEffort | null => {
|
|
29
|
+
if (!row.effort_values) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let parsed: unknown;
|
|
34
|
+
try {
|
|
35
|
+
parsed = JSON.parse(row.effort_values);
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!Array.isArray(parsed)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const values = parsed.filter((value): value is string => typeof value === 'string' && value.length > 0);
|
|
44
|
+
if (values.length === 0) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return row.effort_default && values.includes(row.effort_default)
|
|
49
|
+
? { values, default: row.effort_default }
|
|
50
|
+
: { values };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** Encodes effort metadata into the two nullable columns; no levels means NULL for both. */
|
|
54
|
+
const toStoredEffortColumns = (
|
|
55
|
+
effort: CustomProviderModelEffort | null | undefined,
|
|
56
|
+
): { values: string | null; defaultValue: string | null } => {
|
|
57
|
+
if (!effort || effort.values.length === 0) {
|
|
58
|
+
return { values: null, defaultValue: null };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
values: JSON.stringify(effort.values),
|
|
63
|
+
defaultValue: effort.default ?? null,
|
|
64
|
+
};
|
|
14
65
|
};
|
|
15
66
|
|
|
16
67
|
const toCustomProviderModelRecord = (
|
|
@@ -21,6 +72,7 @@ const toCustomProviderModelRecord = (
|
|
|
21
72
|
modelId: row.model_id,
|
|
22
73
|
model: row.model_name,
|
|
23
74
|
sortOrder: row.sort_order,
|
|
75
|
+
effort: readStoredEffort(row),
|
|
24
76
|
});
|
|
25
77
|
|
|
26
78
|
const readCustomProviderModelRow = (
|
|
@@ -28,7 +80,7 @@ const readCustomProviderModelRow = (
|
|
|
28
80
|
recordId: number,
|
|
29
81
|
): CustomProviderModelRow | null => {
|
|
30
82
|
const row = getConnection().prepare(`
|
|
31
|
-
SELECT
|
|
83
|
+
SELECT ${CUSTOM_PROVIDER_MODEL_COLUMNS}
|
|
32
84
|
FROM provider_models
|
|
33
85
|
WHERE provider = ? AND id = ?
|
|
34
86
|
`).get(provider, recordId) as CustomProviderModelRow | undefined;
|
|
@@ -47,7 +99,7 @@ const readCustomProviderModelRow = (
|
|
|
47
99
|
export const providerModelsDb = {
|
|
48
100
|
listCustomProviderModels(provider: LLMProvider): CustomProviderModelRecord[] {
|
|
49
101
|
const rows = getConnection().prepare(`
|
|
50
|
-
SELECT
|
|
102
|
+
SELECT ${CUSTOM_PROVIDER_MODEL_COLUMNS}
|
|
51
103
|
FROM provider_models
|
|
52
104
|
WHERE provider = ?
|
|
53
105
|
ORDER BY sort_order ASC, lower(model_name) ASC, id ASC
|
|
@@ -69,7 +121,7 @@ export const providerModelsDb = {
|
|
|
69
121
|
modelId: string,
|
|
70
122
|
): CustomProviderModelRecord | null {
|
|
71
123
|
const row = getConnection().prepare(`
|
|
72
|
-
SELECT
|
|
124
|
+
SELECT ${CUSTOM_PROVIDER_MODEL_COLUMNS}
|
|
73
125
|
FROM provider_models
|
|
74
126
|
WHERE provider = ? AND model_id = ?
|
|
75
127
|
`).get(provider, modelId) as CustomProviderModelRow | undefined;
|
|
@@ -88,10 +140,20 @@ export const providerModelsDb = {
|
|
|
88
140
|
WHERE provider = ?
|
|
89
141
|
`).get(provider) as { next_order: number };
|
|
90
142
|
|
|
143
|
+
const effort = toStoredEffortColumns(input.effort);
|
|
91
144
|
const result = db.prepare(`
|
|
92
|
-
INSERT INTO provider_models (
|
|
93
|
-
|
|
94
|
-
|
|
145
|
+
INSERT INTO provider_models (
|
|
146
|
+
provider, model_id, model_name, sort_order, effort_values, effort_default
|
|
147
|
+
)
|
|
148
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
149
|
+
`).run(
|
|
150
|
+
provider,
|
|
151
|
+
input.id,
|
|
152
|
+
input.model,
|
|
153
|
+
nextOrder.next_order,
|
|
154
|
+
effort.values,
|
|
155
|
+
effort.defaultValue,
|
|
156
|
+
);
|
|
95
157
|
|
|
96
158
|
const row = readCustomProviderModelRow(provider, Number(result.lastInsertRowid));
|
|
97
159
|
if (!row) {
|
|
@@ -119,6 +181,17 @@ export const providerModelsDb = {
|
|
|
119
181
|
WHERE provider = ? AND id = ?
|
|
120
182
|
`).run(input.id, input.model, provider, recordId);
|
|
121
183
|
|
|
184
|
+
// An omitted `effort` keeps the stored levels so clients that only edit
|
|
185
|
+
// the name or id cannot wipe them; `null` explicitly clears them.
|
|
186
|
+
if (input.effort !== undefined) {
|
|
187
|
+
const effort = toStoredEffortColumns(input.effort);
|
|
188
|
+
db.prepare(`
|
|
189
|
+
UPDATE provider_models
|
|
190
|
+
SET effort_values = ?, effort_default = ?
|
|
191
|
+
WHERE provider = ? AND id = ?
|
|
192
|
+
`).run(effort.values, effort.defaultValue, provider, recordId);
|
|
193
|
+
}
|
|
194
|
+
|
|
122
195
|
if (previous.model_id !== input.id) {
|
|
123
196
|
db.prepare(`
|
|
124
197
|
UPDATE sessions
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
import { getConnection } from '@/modules/database/connection.js';
|
|
4
|
+
|
|
5
|
+
export type ScheduledMessageStatus = 'pending' | 'sent' | 'failed' | 'cancelled';
|
|
6
|
+
|
|
7
|
+
export type ScheduledMessageRow = {
|
|
8
|
+
id: string;
|
|
9
|
+
user_id: number;
|
|
10
|
+
session_id: string;
|
|
11
|
+
content: string;
|
|
12
|
+
options: string;
|
|
13
|
+
scheduled_for: string;
|
|
14
|
+
status: ScheduledMessageStatus;
|
|
15
|
+
failure_reason: string | null;
|
|
16
|
+
created_at: string;
|
|
17
|
+
updated_at: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const COLUMNS =
|
|
21
|
+
'id, user_id, session_id, content, options, scheduled_for, status, failure_reason, created_at, updated_at';
|
|
22
|
+
|
|
23
|
+
export const scheduledMessagesDb = {
|
|
24
|
+
create(input: {
|
|
25
|
+
userId: number;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
content: string;
|
|
28
|
+
options: unknown;
|
|
29
|
+
scheduledFor: Date;
|
|
30
|
+
}): ScheduledMessageRow {
|
|
31
|
+
const db = getConnection();
|
|
32
|
+
const id = randomUUID();
|
|
33
|
+
|
|
34
|
+
db.prepare(
|
|
35
|
+
`INSERT INTO scheduled_messages (id, user_id, session_id, content, options, scheduled_for, status)
|
|
36
|
+
VALUES (?, ?, ?, ?, ?, ?, 'pending')`
|
|
37
|
+
).run(
|
|
38
|
+
id,
|
|
39
|
+
input.userId,
|
|
40
|
+
input.sessionId,
|
|
41
|
+
input.content,
|
|
42
|
+
JSON.stringify(input.options ?? {}),
|
|
43
|
+
input.scheduledFor.toISOString(),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return db.prepare(`SELECT ${COLUMNS} FROM scheduled_messages WHERE id = ?`).get(id) as ScheduledMessageRow;
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/** Everything still to come or recently resolved, newest schedule first. */
|
|
50
|
+
listForSession(userId: number, sessionId: string): ScheduledMessageRow[] {
|
|
51
|
+
return getConnection()
|
|
52
|
+
.prepare(
|
|
53
|
+
`SELECT ${COLUMNS} FROM scheduled_messages
|
|
54
|
+
WHERE user_id = ? AND session_id = ?
|
|
55
|
+
ORDER BY scheduled_for ASC`
|
|
56
|
+
)
|
|
57
|
+
.all(userId, sessionId) as ScheduledMessageRow[];
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
listPendingForUser(userId: number): ScheduledMessageRow[] {
|
|
61
|
+
return getConnection()
|
|
62
|
+
.prepare(
|
|
63
|
+
`SELECT ${COLUMNS} FROM scheduled_messages
|
|
64
|
+
WHERE user_id = ? AND status = 'pending'
|
|
65
|
+
ORDER BY scheduled_for ASC`
|
|
66
|
+
)
|
|
67
|
+
.all(userId) as ScheduledMessageRow[];
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Claims every message whose time has passed, marking them in the same
|
|
72
|
+
* statement that selects them.
|
|
73
|
+
*
|
|
74
|
+
* Claiming is what makes a missed schedule work: the server can be down at
|
|
75
|
+
* the moment a message was due, and the next poll after it starts picks the
|
|
76
|
+
* message up instead of skipping it. Doing it in one transaction is what
|
|
77
|
+
* stops two overlapping polls from sending the same message twice.
|
|
78
|
+
*/
|
|
79
|
+
claimDue(now: Date): ScheduledMessageRow[] {
|
|
80
|
+
const db = getConnection();
|
|
81
|
+
const nowIso = now.toISOString();
|
|
82
|
+
|
|
83
|
+
return db.transaction(() => {
|
|
84
|
+
const due = db
|
|
85
|
+
.prepare(
|
|
86
|
+
`SELECT ${COLUMNS} FROM scheduled_messages
|
|
87
|
+
WHERE status = 'pending' AND scheduled_for <= ?
|
|
88
|
+
ORDER BY scheduled_for ASC`
|
|
89
|
+
)
|
|
90
|
+
.all(nowIso) as ScheduledMessageRow[];
|
|
91
|
+
|
|
92
|
+
for (const row of due) {
|
|
93
|
+
db.prepare(
|
|
94
|
+
`UPDATE scheduled_messages SET status = 'sent', updated_at = CURRENT_TIMESTAMP WHERE id = ?`
|
|
95
|
+
).run(row.id);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return due;
|
|
99
|
+
})();
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
markFailed(id: string, reason: string): void {
|
|
103
|
+
getConnection()
|
|
104
|
+
.prepare(
|
|
105
|
+
`UPDATE scheduled_messages
|
|
106
|
+
SET status = 'failed', failure_reason = ?, updated_at = CURRENT_TIMESTAMP
|
|
107
|
+
WHERE id = ?`
|
|
108
|
+
)
|
|
109
|
+
.run(reason.slice(0, 500), id);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Cancels a pending message, or dismisses a failed one so its banner goes
|
|
114
|
+
* away. Returns false when it had already fired successfully.
|
|
115
|
+
*/
|
|
116
|
+
cancel(userId: number, id: string): boolean {
|
|
117
|
+
const result = getConnection()
|
|
118
|
+
.prepare(
|
|
119
|
+
`UPDATE scheduled_messages
|
|
120
|
+
SET status = 'cancelled', updated_at = CURRENT_TIMESTAMP
|
|
121
|
+
WHERE id = ? AND user_id = ? AND status IN ('pending', 'failed')`
|
|
122
|
+
)
|
|
123
|
+
.run(id, userId);
|
|
124
|
+
|
|
125
|
+
return result.changes > 0;
|
|
126
|
+
},
|
|
127
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { getConnection } from '@/modules/database/connection.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One chat scope's unsent state: the text still in the composer, plus the
|
|
5
|
+
* message queued behind an in-flight turn. Both are optional — a scope can
|
|
6
|
+
* hold only a draft, only a queued message, or both.
|
|
7
|
+
*/
|
|
8
|
+
export type SessionDraftRecord = {
|
|
9
|
+
scope: string;
|
|
10
|
+
text: string;
|
|
11
|
+
queuedMessage: unknown | null;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type DraftRow = {
|
|
16
|
+
draft_scope: string;
|
|
17
|
+
draft_text: string;
|
|
18
|
+
queued_message: string | null;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** A server-owned queued turn together with the exact stored value used to claim it once. */
|
|
23
|
+
export type QueuedSessionMessageRecord = {
|
|
24
|
+
userId: number;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
queuedMessage: unknown;
|
|
27
|
+
claimToken: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type QueuedMessageRow = {
|
|
31
|
+
user_id: number;
|
|
32
|
+
draft_scope: string;
|
|
33
|
+
queued_message: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** A queued message that no longer parses is treated as absent, not fatal. */
|
|
37
|
+
function parseQueuedMessage(raw: string | null): unknown | null {
|
|
38
|
+
if (!raw) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(raw) as unknown;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function toRecord(row: DraftRow): SessionDraftRecord {
|
|
50
|
+
return {
|
|
51
|
+
scope: row.draft_scope,
|
|
52
|
+
text: row.draft_text,
|
|
53
|
+
queuedMessage: parseQueuedMessage(row.queued_message),
|
|
54
|
+
updatedAt: row.updated_at,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const sessionDraftsDb = {
|
|
59
|
+
/**
|
|
60
|
+
* Returns every draft the user has, newest first.
|
|
61
|
+
*
|
|
62
|
+
* The client pulls the whole set once per load: drafts are short strings, and
|
|
63
|
+
* having them all up front means switching sessions restores a draft written
|
|
64
|
+
* on another device without a round trip.
|
|
65
|
+
*/
|
|
66
|
+
getDrafts(userId: number): SessionDraftRecord[] {
|
|
67
|
+
const db = getConnection();
|
|
68
|
+
const rows = db
|
|
69
|
+
.prepare(
|
|
70
|
+
`SELECT draft_scope, draft_text, queued_message, updated_at
|
|
71
|
+
FROM session_drafts
|
|
72
|
+
WHERE user_id = ?
|
|
73
|
+
ORDER BY datetime(updated_at) DESC`
|
|
74
|
+
)
|
|
75
|
+
.all(userId) as DraftRow[];
|
|
76
|
+
|
|
77
|
+
return rows.map(toRecord);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/** Lists persisted queued turns whose scopes are real chat sessions. */
|
|
81
|
+
listQueuedMessages(): QueuedSessionMessageRecord[] {
|
|
82
|
+
const rows = getConnection()
|
|
83
|
+
.prepare(
|
|
84
|
+
`SELECT drafts.user_id, drafts.draft_scope, drafts.queued_message
|
|
85
|
+
FROM session_drafts AS drafts
|
|
86
|
+
INNER JOIN sessions ON sessions.session_id = drafts.draft_scope
|
|
87
|
+
WHERE drafts.queued_message IS NOT NULL`
|
|
88
|
+
)
|
|
89
|
+
.all() as QueuedMessageRow[];
|
|
90
|
+
|
|
91
|
+
return rows.map((row) => ({
|
|
92
|
+
userId: row.user_id,
|
|
93
|
+
sessionId: row.draft_scope,
|
|
94
|
+
queuedMessage: parseQueuedMessage(row.queued_message),
|
|
95
|
+
claimToken: row.queued_message,
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
/** Atomically removes a queued turn only if it has not been edited since listing. */
|
|
100
|
+
claimQueuedMessage(candidate: QueuedSessionMessageRecord): boolean {
|
|
101
|
+
const result = getConnection()
|
|
102
|
+
.prepare(
|
|
103
|
+
`UPDATE session_drafts
|
|
104
|
+
SET queued_message = NULL, updated_at = CURRENT_TIMESTAMP
|
|
105
|
+
WHERE user_id = ? AND draft_scope = ? AND queued_message = ?`
|
|
106
|
+
)
|
|
107
|
+
.run(candidate.userId, candidate.sessionId, candidate.claimToken);
|
|
108
|
+
return result.changes > 0;
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
/** Restores a claim lost to the narrow race where another run starts first. */
|
|
112
|
+
restoreQueuedMessage(candidate: QueuedSessionMessageRecord): void {
|
|
113
|
+
getConnection()
|
|
114
|
+
.prepare(
|
|
115
|
+
`UPDATE session_drafts
|
|
116
|
+
SET queued_message = ?, updated_at = CURRENT_TIMESTAMP
|
|
117
|
+
WHERE user_id = ? AND draft_scope = ? AND queued_message IS NULL`
|
|
118
|
+
)
|
|
119
|
+
.run(candidate.claimToken, candidate.userId, candidate.sessionId);
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
/** Removes the placeholder row left after its last queued turn is claimed. */
|
|
123
|
+
deleteEmptyDraft(userId: number, scope: string): void {
|
|
124
|
+
getConnection()
|
|
125
|
+
.prepare(
|
|
126
|
+
`DELETE FROM session_drafts
|
|
127
|
+
WHERE user_id = ? AND draft_scope = ? AND draft_text = '' AND queued_message IS NULL`
|
|
128
|
+
)
|
|
129
|
+
.run(userId, scope);
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Writes one scope's draft, or deletes the row when nothing is left to keep.
|
|
134
|
+
*
|
|
135
|
+
* Deleting on empty is what stops the table growing a permanent row for every
|
|
136
|
+
* session the user ever opened and typed a character into.
|
|
137
|
+
*/
|
|
138
|
+
saveDraft(
|
|
139
|
+
userId: number,
|
|
140
|
+
scope: string,
|
|
141
|
+
draft: { text: string; queuedMessage: unknown | null }
|
|
142
|
+
): void {
|
|
143
|
+
const db = getConnection();
|
|
144
|
+
|
|
145
|
+
if (!draft.text && draft.queuedMessage === null) {
|
|
146
|
+
db.prepare('DELETE FROM session_drafts WHERE user_id = ? AND draft_scope = ?')
|
|
147
|
+
.run(userId, scope);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
db.prepare(
|
|
152
|
+
`INSERT INTO session_drafts (user_id, draft_scope, draft_text, queued_message, updated_at)
|
|
153
|
+
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
154
|
+
ON CONFLICT(user_id, draft_scope) DO UPDATE SET
|
|
155
|
+
draft_text = excluded.draft_text,
|
|
156
|
+
queued_message = excluded.queued_message,
|
|
157
|
+
updated_at = CURRENT_TIMESTAMP`
|
|
158
|
+
).run(
|
|
159
|
+
userId,
|
|
160
|
+
scope,
|
|
161
|
+
draft.text,
|
|
162
|
+
draft.queuedMessage === null ? null : JSON.stringify(draft.queuedMessage)
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
deleteDraft(userId: number, scope: string): void {
|
|
167
|
+
const db = getConnection();
|
|
168
|
+
db.prepare('DELETE FROM session_drafts WHERE user_id = ? AND draft_scope = ?')
|
|
169
|
+
.run(userId, scope);
|
|
170
|
+
},
|
|
171
|
+
};
|