@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
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
|
|
7
7
|
import { ClaudeProviderAuth } from '@/modules/providers/list/claude/claude-auth.provider.js';
|
|
8
|
+
import type { ProviderAuthStatus, ProviderAuthSubscriptionOverride } from '@/shared/types.js';
|
|
8
9
|
|
|
9
10
|
// checkCredentials() is private, but unlike getStatus() it never shells out to the
|
|
10
11
|
// `claude` CLI — it only reads env vars and ~/.claude files. Calling it directly
|
|
@@ -15,11 +16,29 @@ type CheckCredentialsResult = {
|
|
|
15
16
|
email: string | null;
|
|
16
17
|
method: string | null;
|
|
17
18
|
error?: string;
|
|
19
|
+
subscriptionOverride?: ProviderAuthSubscriptionOverride;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
const checkCredentials = (auth: ClaudeProviderAuth): Promise<CheckCredentialsResult> =>
|
|
21
23
|
(auth as unknown as { checkCredentials: () => Promise<CheckCredentialsResult> }).checkCredentials();
|
|
22
24
|
|
|
25
|
+
// getStatus() is the public API the route serves, but it first shells out to
|
|
26
|
+
// `claude --version`. Stubbing checkInstalled() lets the test cover the mapping
|
|
27
|
+
// from checkCredentials() to the wire shape without the CLI.
|
|
28
|
+
const getStatusWithCliInstalled = (auth: ClaudeProviderAuth): Promise<ProviderAuthStatus> => {
|
|
29
|
+
(auth as unknown as { checkInstalled: () => boolean }).checkInstalled = () => true;
|
|
30
|
+
return auth.getStatus();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const validSubscriptionCredentials = (email?: string) => ({
|
|
34
|
+
claudeAiOauth: {
|
|
35
|
+
accessToken: 'valid-token',
|
|
36
|
+
refreshToken: 'live-refresh-token',
|
|
37
|
+
expiresAt: Date.now() + 60 * 60 * 1000,
|
|
38
|
+
},
|
|
39
|
+
...(email ? { email } : {}),
|
|
40
|
+
});
|
|
41
|
+
|
|
23
42
|
const ENV_KEYS = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'] as const;
|
|
24
43
|
|
|
25
44
|
const withEnv = async (
|
|
@@ -136,6 +155,64 @@ test('checkCredentials: no CLAUDE_CODE_OAUTH_TOKEN, expired credentials file rep
|
|
|
136
155
|
});
|
|
137
156
|
});
|
|
138
157
|
|
|
158
|
+
test('checkCredentials: expired access token with a live refresh token is still authenticated', async () => {
|
|
159
|
+
await withTempHome(async (homeDir) => {
|
|
160
|
+
await writeCredentialsFile(homeDir, {
|
|
161
|
+
claudeAiOauth: {
|
|
162
|
+
accessToken: 'stale-token',
|
|
163
|
+
refreshToken: 'live-refresh-token',
|
|
164
|
+
expiresAt: 1_000_000_000_000,
|
|
165
|
+
refreshTokenExpiresAt: Date.now() + 30 * 24 * 60 * 60 * 1000,
|
|
166
|
+
},
|
|
167
|
+
email: 'someone@example.com',
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await withEnv({}, async () => {
|
|
171
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
172
|
+
assert.equal(status.authenticated, true);
|
|
173
|
+
assert.equal(status.method, 'credentials_file');
|
|
174
|
+
assert.equal(status.email, 'someone@example.com');
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('checkCredentials: expired access token with a refresh token that has no recorded expiry is authenticated', async () => {
|
|
180
|
+
await withTempHome(async (homeDir) => {
|
|
181
|
+
await writeCredentialsFile(homeDir, {
|
|
182
|
+
claudeAiOauth: {
|
|
183
|
+
accessToken: 'stale-token',
|
|
184
|
+
refreshToken: 'live-refresh-token',
|
|
185
|
+
expiresAt: 1_000_000_000_000,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
await withEnv({}, async () => {
|
|
190
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
191
|
+
assert.equal(status.authenticated, true);
|
|
192
|
+
assert.equal(status.method, 'credentials_file');
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('checkCredentials: expired access token with an expired refresh token reports not authenticated', async () => {
|
|
198
|
+
await withTempHome(async (homeDir) => {
|
|
199
|
+
await writeCredentialsFile(homeDir, {
|
|
200
|
+
claudeAiOauth: {
|
|
201
|
+
accessToken: 'stale-token',
|
|
202
|
+
refreshToken: 'stale-refresh-token',
|
|
203
|
+
expiresAt: 1_000_000_000_000,
|
|
204
|
+
refreshTokenExpiresAt: 1_000_000_000_000,
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await withEnv({}, async () => {
|
|
209
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
210
|
+
assert.equal(status.authenticated, false);
|
|
211
|
+
assert.match(status.error ?? '', /expired/i);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
139
216
|
test('checkCredentials: ANTHROPIC_API_KEY takes precedence over CLAUDE_CODE_OAUTH_TOKEN', async () => {
|
|
140
217
|
await withTempHome(async () => {
|
|
141
218
|
await withEnv(
|
|
@@ -148,3 +225,134 @@ test('checkCredentials: ANTHROPIC_API_KEY takes precedence over CLAUDE_CODE_OAUT
|
|
|
148
225
|
);
|
|
149
226
|
});
|
|
150
227
|
});
|
|
228
|
+
|
|
229
|
+
// Issue #568: Claude Code silently prefers ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN
|
|
230
|
+
// over the `claude /login` subscription, billing every request to the key. The
|
|
231
|
+
// status must say so — and only when a usable login is really being bypassed.
|
|
232
|
+
|
|
233
|
+
test('checkCredentials: ANTHROPIC_API_KEY in the process env alongside a valid subscription login reports the override', async () => {
|
|
234
|
+
await withTempHome(async (homeDir) => {
|
|
235
|
+
await writeCredentialsFile(homeDir, validSubscriptionCredentials('someone@example.com'));
|
|
236
|
+
|
|
237
|
+
await withEnv({ ANTHROPIC_API_KEY: 'test-api-key' }, async () => {
|
|
238
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
239
|
+
// The existing fields are untouched: the key still wins and keeps its label.
|
|
240
|
+
assert.equal(status.authenticated, true);
|
|
241
|
+
assert.equal(status.method, 'api_key');
|
|
242
|
+
assert.equal(status.email, 'API Key Auth');
|
|
243
|
+
assert.deepEqual(status.subscriptionOverride, {
|
|
244
|
+
variable: 'ANTHROPIC_API_KEY',
|
|
245
|
+
source: 'process_env',
|
|
246
|
+
subscriptionEmail: 'someone@example.com',
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
test('checkCredentials: ANTHROPIC_AUTH_TOKEN in the process env alongside a valid subscription login names the auth token', async () => {
|
|
253
|
+
await withTempHome(async (homeDir) => {
|
|
254
|
+
await writeCredentialsFile(homeDir, validSubscriptionCredentials());
|
|
255
|
+
|
|
256
|
+
await withEnv({ ANTHROPIC_AUTH_TOKEN: 'test-auth-token', ANTHROPIC_API_KEY: 'test-api-key' }, async () => {
|
|
257
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
258
|
+
assert.equal(status.method, 'api_key');
|
|
259
|
+
assert.equal(status.email, 'Auth Token');
|
|
260
|
+
assert.deepEqual(status.subscriptionOverride, {
|
|
261
|
+
variable: 'ANTHROPIC_AUTH_TOKEN',
|
|
262
|
+
source: 'process_env',
|
|
263
|
+
subscriptionEmail: null,
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('checkCredentials: ANTHROPIC_API_KEY in settings.json env alongside a valid subscription login points at settings.json', async () => {
|
|
270
|
+
await withTempHome(async (homeDir) => {
|
|
271
|
+
await writeSettingsFile(homeDir, { ANTHROPIC_API_KEY: 'test-api-key-from-settings' });
|
|
272
|
+
await writeCredentialsFile(homeDir, validSubscriptionCredentials('someone@example.com'));
|
|
273
|
+
|
|
274
|
+
await withEnv({}, async () => {
|
|
275
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
276
|
+
assert.equal(status.method, 'api_key');
|
|
277
|
+
assert.equal(status.email, 'API Key Auth');
|
|
278
|
+
assert.deepEqual(status.subscriptionOverride, {
|
|
279
|
+
variable: 'ANTHROPIC_API_KEY',
|
|
280
|
+
source: 'settings_file',
|
|
281
|
+
subscriptionEmail: 'someone@example.com',
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test('checkCredentials: ANTHROPIC_API_KEY with no credentials file reports no override', async () => {
|
|
288
|
+
await withTempHome(async () => {
|
|
289
|
+
await withEnv({ ANTHROPIC_API_KEY: 'test-api-key' }, async () => {
|
|
290
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
291
|
+
assert.equal(status.authenticated, true);
|
|
292
|
+
assert.equal(status.method, 'api_key');
|
|
293
|
+
assert.equal(status.subscriptionOverride, undefined);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test('checkCredentials: ANTHROPIC_API_KEY with an expired subscription login reports no override', async () => {
|
|
299
|
+
await withTempHome(async (homeDir) => {
|
|
300
|
+
// Nothing usable is being bypassed here, so warning would only confuse.
|
|
301
|
+
await writeCredentialsFile(homeDir, {
|
|
302
|
+
claudeAiOauth: {
|
|
303
|
+
accessToken: 'stale-token',
|
|
304
|
+
refreshToken: 'stale-refresh-token',
|
|
305
|
+
expiresAt: 1_000_000_000_000,
|
|
306
|
+
refreshTokenExpiresAt: 1_000_000_000_000,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
await withEnv({ ANTHROPIC_API_KEY: 'test-api-key' }, async () => {
|
|
311
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
312
|
+
assert.equal(status.authenticated, true);
|
|
313
|
+
assert.equal(status.method, 'api_key');
|
|
314
|
+
assert.equal(status.subscriptionOverride, undefined);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('checkCredentials: a valid subscription login with no API key reports credentials_file and no override', async () => {
|
|
320
|
+
await withTempHome(async (homeDir) => {
|
|
321
|
+
await writeCredentialsFile(homeDir, validSubscriptionCredentials('someone@example.com'));
|
|
322
|
+
|
|
323
|
+
await withEnv({}, async () => {
|
|
324
|
+
const status = await checkCredentials(new ClaudeProviderAuth());
|
|
325
|
+
assert.equal(status.authenticated, true);
|
|
326
|
+
assert.equal(status.method, 'credentials_file');
|
|
327
|
+
assert.equal(status.email, 'someone@example.com');
|
|
328
|
+
assert.equal(status.subscriptionOverride, undefined);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('getStatus: passes the subscription override through to the wire shape, and omits the key when there is none', async () => {
|
|
334
|
+
await withTempHome(async (homeDir) => {
|
|
335
|
+
await writeCredentialsFile(homeDir, validSubscriptionCredentials('someone@example.com'));
|
|
336
|
+
|
|
337
|
+
await withEnv({ ANTHROPIC_API_KEY: 'test-api-key' }, async () => {
|
|
338
|
+
const status = await getStatusWithCliInstalled(new ClaudeProviderAuth());
|
|
339
|
+
assert.equal(status.installed, true);
|
|
340
|
+
assert.equal(status.provider, 'claude');
|
|
341
|
+
assert.equal(status.authenticated, true);
|
|
342
|
+
assert.equal(status.method, 'api_key');
|
|
343
|
+
assert.equal(status.email, 'API Key Auth');
|
|
344
|
+
assert.deepEqual(status.subscriptionOverride, {
|
|
345
|
+
variable: 'ANTHROPIC_API_KEY',
|
|
346
|
+
source: 'process_env',
|
|
347
|
+
subscriptionEmail: 'someone@example.com',
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
await withEnv({}, async () => {
|
|
352
|
+
const status = await getStatusWithCliInstalled(new ClaudeProviderAuth());
|
|
353
|
+
assert.equal(status.method, 'credentials_file');
|
|
354
|
+
// Omitted, not null: existing JSON consumers see exactly the old payload.
|
|
355
|
+
assert.equal('subscriptionOverride' in status, false);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createBackgroundWorkTracker,
|
|
6
|
+
startsBackgroundWork,
|
|
7
|
+
} from '@/modules/providers/list/claude/claude-runtime.provider.js';
|
|
8
|
+
|
|
9
|
+
// Only turns that start work outliving the turn hold their CLI process open. A
|
|
10
|
+
// turn scored `false` here has its stdin released the moment `result` arrives,
|
|
11
|
+
// and the CLI reads that EOF as print wind-down — so anything still running dies.
|
|
12
|
+
const turn = (...blocks: Array<{ name: string; input?: Record<string, unknown> }>) => ({
|
|
13
|
+
type: 'assistant',
|
|
14
|
+
message: { content: blocks.map((block) => ({ type: 'tool_use', input: {}, ...block })) },
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('a backgrounded Bash holds the process open', () => {
|
|
18
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Bash', input: { run_in_background: true } })), true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('a foreground Bash does not', () => {
|
|
22
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Bash', input: { run_in_background: false } })), false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('a backgrounded Agent holds the process open', () => {
|
|
26
|
+
// The gap this suite exists for: a background agent used to be scored as
|
|
27
|
+
// nothing outstanding, so the CLI wound down and killed it mid-run.
|
|
28
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Agent', input: { run_in_background: true } })), true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('an Agent with no run_in_background holds the process open', () => {
|
|
32
|
+
// `run_in_background` is optional on AgentInput and agents background by
|
|
33
|
+
// default, so an omitted field means background, not foreground.
|
|
34
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Agent', input: { prompt: 'Investigate' } })), true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('a foreground Agent does not', () => {
|
|
38
|
+
// It never pushes a follow-up turn, so holding for it would pin the process
|
|
39
|
+
// for the full BG_WAIT_CEILING_MS.
|
|
40
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Agent', input: { run_in_background: false } })), false);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('a Workflow holds the process open', () => {
|
|
44
|
+
// WorkflowInput has no foreground option: every call returns a task id
|
|
45
|
+
// immediately and reports back in a later turn.
|
|
46
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Workflow', input: { script: 'export const meta = {}' } })), true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('a deferred-work tool holds the process open', () => {
|
|
50
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Monitor' })), true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('a turn that starts nothing lasting does not', () => {
|
|
54
|
+
assert.equal(startsBackgroundWork(turn({ name: 'Read' })), false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('one backgrounded agent among foreground calls is enough', () => {
|
|
58
|
+
assert.equal(
|
|
59
|
+
startsBackgroundWork(
|
|
60
|
+
turn(
|
|
61
|
+
{ name: 'Read' },
|
|
62
|
+
{ name: 'Agent', input: { run_in_background: false } },
|
|
63
|
+
{ name: 'Agent', input: { run_in_background: true } },
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
true,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('a message carrying no tool calls does not', () => {
|
|
71
|
+
assert.equal(startsBackgroundWork({ type: 'result', message: { content: 'done' } }), false);
|
|
72
|
+
assert.equal(startsBackgroundWork({ type: 'assistant', message: { content: [] } }), false);
|
|
73
|
+
assert.equal(startsBackgroundWork({}), false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Once the turn's `result` is out, the tracker below is the only record of
|
|
77
|
+
// what the held process is still running: the running-sessions list reads it
|
|
78
|
+
// and a stop request is refused unless it names one of its tasks. The event
|
|
79
|
+
// shapes are the SDK's own, as a real query emits them.
|
|
80
|
+
const started = (taskId: string, extra: Record<string, unknown> = {}) => ({
|
|
81
|
+
type: 'system',
|
|
82
|
+
subtype: 'task_started',
|
|
83
|
+
task_id: taskId,
|
|
84
|
+
tool_use_id: `toolu_${taskId}`,
|
|
85
|
+
description: `Task ${taskId}`,
|
|
86
|
+
task_type: 'local_agent',
|
|
87
|
+
...extra,
|
|
88
|
+
});
|
|
89
|
+
const notified = (taskId: string, status: string) => ({
|
|
90
|
+
type: 'system', subtype: 'task_notification', task_id: taskId, tool_use_id: `toolu_${taskId}`, status, summary: '', output_file: '',
|
|
91
|
+
});
|
|
92
|
+
const updated = (taskId: string, patch: Record<string, unknown>) => ({
|
|
93
|
+
type: 'system', subtype: 'task_updated', task_id: taskId, patch,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('a task_started with a tool_use_id adds the task under its session', () => {
|
|
97
|
+
const tracker = createBackgroundWorkTracker();
|
|
98
|
+
const before = Date.now();
|
|
99
|
+
// The session's own turn issued the call, so the task is its own work.
|
|
100
|
+
tracker.apply('s1', {
|
|
101
|
+
type: 'assistant',
|
|
102
|
+
parent_tool_use_id: null,
|
|
103
|
+
message: { role: 'assistant', content: [{ type: 'tool_use', id: 'toolu_t1', name: 'Workflow', input: {} }] },
|
|
104
|
+
});
|
|
105
|
+
tracker.apply('s1', started('t1', { task_type: 'local_workflow', workflow_name: 'spec' }));
|
|
106
|
+
|
|
107
|
+
const [entry] = tracker.list();
|
|
108
|
+
assert.equal(tracker.list().length, 1);
|
|
109
|
+
assert.equal(entry.sessionId, 's1');
|
|
110
|
+
assert.equal(entry.tasks.length, 1);
|
|
111
|
+
const { startedAt, ...task } = entry.tasks[0];
|
|
112
|
+
assert.deepEqual(task, {
|
|
113
|
+
taskId: 't1',
|
|
114
|
+
toolUseId: 'toolu_t1',
|
|
115
|
+
taskType: 'local_workflow',
|
|
116
|
+
description: 'Task t1',
|
|
117
|
+
workflowName: 'spec',
|
|
118
|
+
});
|
|
119
|
+
assert.ok(startedAt >= before && startedAt <= Date.now());
|
|
120
|
+
assert.equal(tracker.hasOutstanding('s1'), true);
|
|
121
|
+
assert.equal(tracker.has('s1', 't1'), true);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('a task started for a call the session itself made is its own; one from inside an agent is nested', () => {
|
|
125
|
+
// Verified on a real run: a workflow agent that backgrounds `sleep 60` puts
|
|
126
|
+
// a `task_started` on the parent's stream, with a tool_use_id from the
|
|
127
|
+
// agent's transcript. The parent transcript has no card for it, and the
|
|
128
|
+
// pill would otherwise read "3 tasks" for one workflow.
|
|
129
|
+
const tracker = createBackgroundWorkTracker();
|
|
130
|
+
tracker.apply('s1', {
|
|
131
|
+
type: 'assistant',
|
|
132
|
+
parent_tool_use_id: null,
|
|
133
|
+
message: { role: 'assistant', content: [{ type: 'tool_use', id: 'toolu_t1', name: 'Workflow', input: {} }] },
|
|
134
|
+
});
|
|
135
|
+
tracker.apply('s1', started('t1', { task_type: 'local_workflow', workflow_name: 'spec' }));
|
|
136
|
+
tracker.apply('s1', started('t2', { task_type: 'local_bash', description: 'Sleep for 60 seconds' }));
|
|
137
|
+
|
|
138
|
+
const [entry] = tracker.list();
|
|
139
|
+
assert.deepEqual(entry.tasks.map((task) => [task.taskId, task.nested ?? false]), [['t1', false], ['t2', true]]);
|
|
140
|
+
assert.equal(tracker.has('s1', 't2'), true, 'a nested task can still be stopped');
|
|
141
|
+
|
|
142
|
+
// The set of own calls dies with the session, like the tasks.
|
|
143
|
+
tracker.clear('s1');
|
|
144
|
+
tracker.apply('s1', started('t1', { task_type: 'local_workflow' }));
|
|
145
|
+
assert.equal(tracker.list()[0].tasks[0].nested, true);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('a task_started without a tool_use_id is not tracked', () => {
|
|
149
|
+
// Housekeeping tasks the CLI starts on its own have no launching call and
|
|
150
|
+
// nothing in the transcript to show them under.
|
|
151
|
+
const tracker = createBackgroundWorkTracker();
|
|
152
|
+
tracker.apply('s1', { type: 'system', subtype: 'task_started', task_id: 'ambient', description: 'x' });
|
|
153
|
+
|
|
154
|
+
assert.deepEqual(tracker.list(), []);
|
|
155
|
+
assert.equal(tracker.hasOutstanding('s1'), false);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('a task_notification removes the task whatever its status', () => {
|
|
159
|
+
const tracker = createBackgroundWorkTracker();
|
|
160
|
+
tracker.apply('s1', started('t1'));
|
|
161
|
+
tracker.apply('s1', started('t2'));
|
|
162
|
+
tracker.apply('s1', notified('t1', 'completed'));
|
|
163
|
+
|
|
164
|
+
assert.equal(tracker.has('s1', 't1'), false);
|
|
165
|
+
assert.equal(tracker.has('s1', 't2'), true);
|
|
166
|
+
assert.equal(tracker.hasOutstanding('s1'), true);
|
|
167
|
+
|
|
168
|
+
tracker.apply('s1', notified('t2', 'stopped'));
|
|
169
|
+
assert.equal(tracker.hasOutstanding('s1'), false);
|
|
170
|
+
assert.deepEqual(tracker.list(), []);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('a terminal task_updated removes the task', () => {
|
|
174
|
+
const tracker = createBackgroundWorkTracker();
|
|
175
|
+
for (const [taskId, status] of [['a', 'completed'], ['b', 'failed'], ['c', 'killed']]) {
|
|
176
|
+
tracker.apply('s1', started(taskId));
|
|
177
|
+
tracker.apply('s1', updated(taskId, { status, end_time: 1 }));
|
|
178
|
+
assert.equal(tracker.has('s1', taskId), false, `${status} settles the task`);
|
|
179
|
+
}
|
|
180
|
+
assert.equal(tracker.hasOutstanding('s1'), false);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('a non-terminal task_updated keeps the task', () => {
|
|
184
|
+
const tracker = createBackgroundWorkTracker();
|
|
185
|
+
tracker.apply('s1', started('t1'));
|
|
186
|
+
tracker.apply('s1', updated('t1', { status: 'running' }));
|
|
187
|
+
tracker.apply('s1', updated('t1', { is_backgrounded: true }));
|
|
188
|
+
tracker.apply('s1', updated('t1', { status: 'paused' }));
|
|
189
|
+
|
|
190
|
+
assert.equal(tracker.has('s1', 't1'), true);
|
|
191
|
+
assert.equal(tracker.hasOutstanding('s1'), true);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('clearing a session empties it and leaves the others alone', () => {
|
|
195
|
+
const tracker = createBackgroundWorkTracker();
|
|
196
|
+
tracker.apply('s1', started('t1'));
|
|
197
|
+
tracker.apply('s2', started('t2'));
|
|
198
|
+
tracker.clear('s1');
|
|
199
|
+
|
|
200
|
+
assert.equal(tracker.hasOutstanding('s1'), false);
|
|
201
|
+
assert.equal(tracker.has('s1', 't1'), false);
|
|
202
|
+
assert.deepEqual(tracker.list().map((entry) => entry.sessionId), ['s2']);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('messages that are not task events leave the set untouched', () => {
|
|
206
|
+
const tracker = createBackgroundWorkTracker();
|
|
207
|
+
tracker.apply('s1', started('t1'));
|
|
208
|
+
tracker.apply('s1', { type: 'assistant', message: { content: [] } });
|
|
209
|
+
tracker.apply('s1', { type: 'system', subtype: 'task_progress', task_id: 't1', description: 'x', usage: {} });
|
|
210
|
+
tracker.apply('s1', { type: 'result', task_id: 't1' });
|
|
211
|
+
|
|
212
|
+
assert.equal(tracker.has('s1', 't1'), true);
|
|
213
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { ClaudeSessionsProvider } from '@/modules/providers/list/claude/claude-sessions.provider.js';
|
|
5
|
+
|
|
6
|
+
const provider = new ClaudeSessionsProvider();
|
|
7
|
+
const SESSION_ID = 'claude-compaction-1';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Both records that describe a compaction are `system` events, which normalized
|
|
11
|
+
* to nothing before this: the boundary carries the numbers, the status says one
|
|
12
|
+
* is running. Each becomes one ordinary assistant row, so a client that knows
|
|
13
|
+
* nothing of `compact` still reads the sentence.
|
|
14
|
+
*/
|
|
15
|
+
test('a compact boundary becomes one row carrying its numbers', () => {
|
|
16
|
+
const [row, ...rest] = provider.normalizeMessage({
|
|
17
|
+
type: 'system',
|
|
18
|
+
subtype: 'compact_boundary',
|
|
19
|
+
uuid: 'u-1',
|
|
20
|
+
timestamp: '2026-01-01T00:00:00.000Z',
|
|
21
|
+
compactMetadata: {
|
|
22
|
+
trigger: 'manual',
|
|
23
|
+
preTokens: 335_402,
|
|
24
|
+
postTokens: 10_120,
|
|
25
|
+
durationMs: 142_000,
|
|
26
|
+
},
|
|
27
|
+
}, SESSION_ID);
|
|
28
|
+
|
|
29
|
+
assert.equal(rest.length, 0);
|
|
30
|
+
assert.equal(row.kind, 'text');
|
|
31
|
+
assert.equal(row.role, 'assistant');
|
|
32
|
+
assert.equal(row.content, 'Compacted · manual · 335k → 10k tokens · 2m 22s');
|
|
33
|
+
assert.deepEqual(row.compact, {
|
|
34
|
+
phase: 'done',
|
|
35
|
+
trigger: 'manual',
|
|
36
|
+
preTokens: 335_402,
|
|
37
|
+
postTokens: 10_120,
|
|
38
|
+
durationMs: 142_000,
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('the live spelling of the metadata reads the same', () => {
|
|
43
|
+
const [row] = provider.normalizeMessage({
|
|
44
|
+
type: 'system',
|
|
45
|
+
subtype: 'compact_boundary',
|
|
46
|
+
compact_metadata: { trigger: 'auto', pre_tokens: 1_240_000, post_tokens: 18_000, duration_ms: 45_000 },
|
|
47
|
+
}, SESSION_ID);
|
|
48
|
+
|
|
49
|
+
assert.equal(row.content, 'Compacted · auto · 1.2M → 18k tokens · 45s');
|
|
50
|
+
assert.equal(row.compact?.trigger, 'auto');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('a boundary with no metadata still says a compaction happened', () => {
|
|
54
|
+
const [row] = provider.normalizeMessage({
|
|
55
|
+
type: 'system',
|
|
56
|
+
subtype: 'compact_boundary',
|
|
57
|
+
}, SESSION_ID);
|
|
58
|
+
|
|
59
|
+
assert.equal(row.content, 'Compacted · auto');
|
|
60
|
+
assert.equal(row.compact?.phase, 'done');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('a compacting status becomes a running row, and other statuses none', () => {
|
|
64
|
+
const [running] = provider.normalizeMessage({
|
|
65
|
+
type: 'system',
|
|
66
|
+
subtype: 'status',
|
|
67
|
+
status: 'compacting',
|
|
68
|
+
}, SESSION_ID);
|
|
69
|
+
|
|
70
|
+
assert.equal(running.content, 'Compacting conversation…');
|
|
71
|
+
assert.equal(running.compact?.phase, 'running');
|
|
72
|
+
|
|
73
|
+
assert.deepEqual(
|
|
74
|
+
provider.normalizeMessage({ type: 'system', subtype: 'status', status: 'requesting' }, SESSION_ID),
|
|
75
|
+
[],
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('a failed compaction says so, with the reason when there is one', () => {
|
|
80
|
+
const [failed] = provider.normalizeMessage({
|
|
81
|
+
type: 'system',
|
|
82
|
+
subtype: 'status',
|
|
83
|
+
compact_result: 'failed',
|
|
84
|
+
compact_error: 'context still too large',
|
|
85
|
+
}, SESSION_ID);
|
|
86
|
+
|
|
87
|
+
assert.equal(failed.content, 'Compaction failed: context still too large');
|
|
88
|
+
assert.equal(failed.compact?.phase, 'failed');
|
|
89
|
+
assert.equal(failed.compact?.error, 'context still too large');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('the summary keeps its flag, so the client can fold it into the row', () => {
|
|
93
|
+
const [row] = provider.normalizeMessage({
|
|
94
|
+
type: 'user',
|
|
95
|
+
isCompactSummary: true,
|
|
96
|
+
message: { role: 'user', content: 'This session is being continued from a previous conversation.' },
|
|
97
|
+
}, SESSION_ID);
|
|
98
|
+
|
|
99
|
+
assert.equal(row.role, 'assistant');
|
|
100
|
+
assert.equal(row.isCompactSummary, true);
|
|
101
|
+
});
|