@yalehwang/cloudpit 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api-docs.html +3 -3
- package/dist/assets/{abnfDiagram-N423BO3Z-D5yLnMt9.js → abnfDiagram-N423BO3Z-D7Xt05gV.js} +1 -1
- package/dist/assets/{abnfDiagram-N423BO3Z-bTHtQIhR.js → abnfDiagram-N423BO3Z-dmPRRPEm.js} +1 -1
- package/dist/assets/{arc-1DmrBEyG.js → arc-B7W3R5qH.js} +1 -1
- package/dist/assets/{arc-BlGK--01.js → arc-BHMlIcaQ.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G--lzbKBn9.js → architectureDiagram-T3A2C74G-CUUpAoN0.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-7lKNAbUU.js → architectureDiagram-T3A2C74G-DpXhbHxu.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-17cdO9zs.js → blockDiagram-VBNYF7ZC-Bf0yfNxj.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-BPavJfDj.js → blockDiagram-VBNYF7ZC-Cki9AOhc.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-Bm1-2w3b.js → c4Diagram-5PPSVZJV-DK2RqNDO.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-aHvFL3Wb.js → c4Diagram-5PPSVZJV-DyhTF0e5.js} +1 -1
- package/dist/assets/channel-DTLMNzbH.js +1 -0
- package/dist/assets/channel-DiqxUuPf.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-D7WqZewM.js → chunk-2GRJ4B5K-BYtByJbf.js} +1 -1
- package/dist/assets/{chunk-2GRJ4B5K-DbwzBiPF.js → chunk-2GRJ4B5K-CksFgocc.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-DdCr89uy.js → chunk-2Q5K7J3B-D2kQa5TZ.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-TFd0ECKO.js → chunk-2Q5K7J3B-NSSX86FA.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-BdhRBpEi.js → chunk-5RXB4S5H-DNNYC8_t.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-D0SQ3nIe.js → chunk-5RXB4S5H-Rx0YaqNI.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-B9Lv3cWR.js → chunk-5VM5RSS4-B1k4I4CX.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DioqTIvB.js → chunk-5VM5RSS4-CsvQj3QC.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-09bwlcIv.js → chunk-6Q2QTUOP-48-dEgAs.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-JuhPJZZL.js → chunk-6Q2QTUOP-DCMSW5_0.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-C6f2SgCw.js → chunk-GF5L2VYU-CGyvOsdN.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-DzD9aOyp.js → chunk-GF5L2VYU-YXe113hp.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BggnWNZv.js → chunk-JWPE2WC7-BT7vCW4x.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-Dte_Ax9K.js → chunk-JWPE2WC7-D2K1Oywq.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-9TCQV92m.js → chunk-KBJHAD2P-CQZWamtE.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-DDnJp7kJ.js → chunk-KBJHAD2P-gpEwZrNy.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-CE2Y4D_h.js → chunk-RYQCIY6F-BI0fMtjY.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DsgFSTNw.js → chunk-RYQCIY6F-vguRdb4F.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-B1FIfsqq.js → chunk-XXDRQBXY-B99qH1_w.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-B4YfaqTO.js → chunk-XXDRQBXY-DZLJnbBB.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-BaV-s6x8.js +1 -0
- package/dist/assets/classDiagram-JCYQIIEL-D4M03B4L.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-BaV-s6x8.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-D4M03B4L.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-C1AG5Pib.js → cose-bilkent-JH36ORCC-EsVnz-E6.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-lMwWDibI.js → cose-bilkent-JH36ORCC-VI2OjCIx.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-BlabniRL.js → cynefin-VYW2F7L2-BVYg0ixs.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-W-c-z4IW.js → cynefin-VYW2F7L2-BnHmA5I2.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-BtTep_pq.js → cynefinDiagram-MW4NZA55-B-OCRLIw.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-Due6EIPh.js → cynefinDiagram-MW4NZA55-ItLlzjDR.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-CWLaFfdt.js → dagre-VZM6K2ZE-DkVDkAWJ.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-DZldvqiQ.js → dagre-VZM6K2ZE-bYR4z8-Z.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-RnmUHYwN.js → diagram-7IWD3JNH-DjXMue67.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-Di-7-nSA.js → diagram-7IWD3JNH-FNEXlm5k.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-Wybyn8fw.js → diagram-B4RE2ZJO-73NYiO_P.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-mrK79C2E.js → diagram-B4RE2ZJO-dB4QHq0D.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-JY6FqSFu.js → diagram-LBJQPF4R-DyKT610O.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-sWhu2VLy.js → diagram-LBJQPF4R-rMgmnjvd.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-BJ4T0WGp.js → diagram-Q27KOJAE-BvsfmmQt.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-DyGT9KhB.js → diagram-Q27KOJAE-c6DEjLQX.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-oXFJAndB.js → diagram-UB23O5K3-BMo2VXVb.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-tTd8qwEM.js → diagram-UB23O5K3-DRMKefnZ.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-DV67cBe6.js → ebnfDiagram-BXEA7PRR-BrOAekWh.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-OQGm8tPs.js → ebnfDiagram-BXEA7PRR-YmQkylwV.js} +1 -1
- package/dist/assets/{elk-BRx4gEGg.js → elk-Hz3WRESK.js} +1 -1
- package/dist/assets/{elk-CdAQJ-NA.js → elk-tPSZwRVB.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-BhD2xZ2I.js → erDiagram-JOGREHBK-BlaZnoQi.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-BqP8DqqW.js → erDiagram-JOGREHBK-CRCfRUXt.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-B4AjZxPJ.js → flowDiagram-UKHOOZJN-DQ1gbjxo.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-CP_1WsW4.js → flowDiagram-UKHOOZJN-Dinlbmds.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-BMk6nngr.js → ganttDiagram-PKOTCBZU-CMGpcBZO.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-B_ce39Ld.js → ganttDiagram-PKOTCBZU-Eh94zuPI.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-CnZA42iA.js → gitGraphDiagram-DS77QQ5N-Bp8xIZbk.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-DqEz_iTn.js → gitGraphDiagram-DS77QQ5N-Cu-b4YNw.js} +1 -1
- package/dist/assets/index-51e8fagd.css +32 -0
- package/dist/assets/{index-D5nLH7qP.js → index-CQE9C6k6.js} +356 -356
- package/dist/assets/{index-CqyOGerp.js → index-S8ow0XfK.js} +356 -356
- package/dist/assets/{infoDiagram-6WML65LV-BQf7m4X4.js → infoDiagram-6WML65LV-CClEEtTq.js} +1 -1
- package/dist/assets/{infoDiagram-6WML65LV-Dntf4YFM.js → infoDiagram-6WML65LV-QmHeojgl.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-BDjsldAI.js → ishikawaDiagram-WSZJBQD7-BemSj9lN.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-BqXpJeoL.js → ishikawaDiagram-WSZJBQD7-nw48g1vr.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-CBcFzP2M.js → journeyDiagram-NVQOT4AX-DeNtO6OU.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-DoWKjgKd.js → journeyDiagram-NVQOT4AX-q1lCfOYn.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-9bspl7j-.js → kanban-definition-27J2QSJJ-Bzhu6hql.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-Cjxa-Fbb.js → kanban-definition-27J2QSJJ-VfvD33YG.js} +1 -1
- package/dist/assets/{linear-YogAXmU_.js → linear-C0Kwu3Yp.js} +1 -1
- package/dist/assets/{linear-lIhI5Y8l.js → linear-CbM_4-fP.js} +1 -1
- package/dist/assets/{mermaid.core-2Spxcrg7.js → mermaid.core-G2huIsXn.js} +5 -5
- package/dist/assets/{mermaid.core-BxxInCBm.js → mermaid.core-fvTQFUX1.js} +5 -5
- package/dist/assets/{mindmap-definition-FAOFIHXS-DblO5EG4.js → mindmap-definition-FAOFIHXS-BONvuyvz.js} +1 -1
- package/dist/assets/{mindmap-definition-FAOFIHXS-_nlvJ9VK.js → mindmap-definition-FAOFIHXS-BzYawGKQ.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-BBJFPAZG.js → pegDiagram-VL7TDLO6-Df2HAKGH.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-DhRH7YRf.js → pegDiagram-VL7TDLO6-DnMwBHn_.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-4Qy7Nk4U.js → pieDiagram-7S7Q4E2Y-Cd3-a-dM.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-BUtdeYBT.js → pieDiagram-7S7Q4E2Y-LV6TOhOD.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-BUoIDY1r.js → quadrantDiagram-CIZ2JOQS-8VOnA3FV.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-D90kdHA1.js → quadrantDiagram-CIZ2JOQS-CnwxFPxh.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-CJf9--tj.js → railroadDiagram-AXF67PYL-CXBFj3Iu.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-D3S1oliC.js → railroadDiagram-AXF67PYL-DLoAPcsb.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-C04jhjS6.js → requirementDiagram-LRYGKXZP-LrVlZXSz.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-cQaGai5h.js → requirementDiagram-LRYGKXZP-pakITowN.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-AT4cTVbY.js → sankeyDiagram-W5VNT64P-BIQQ8A1I.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-DfFUdqYO.js → sankeyDiagram-W5VNT64P-C6QWOxNM.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-DbjhG030.js → sequenceDiagram-SI44F4Z6-CpHBe2CG.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-DKjdupix.js → sequenceDiagram-SI44F4Z6-cnLxaxcV.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-CCcKLP8m.js → sizeCapture-X5ZJPWSS-3g-1onHD.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-DGxRWxeo.js → sizeCapture-X5ZJPWSS-4U6b3PSL.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-D7wGCNb7.js → stateDiagram-OKZ733FA-CFwVDdlY.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-qdMAailp.js → stateDiagram-OKZ733FA-CKVGJcM2.js} +1 -1
- package/dist/assets/{stateDiagram-v2-UEYNNEHI-BbmmtA9w.js → stateDiagram-v2-UEYNNEHI-Dnbk8ftm.js} +1 -1
- package/dist/assets/{stateDiagram-v2-UEYNNEHI-Diz_hFvh.js → stateDiagram-v2-UEYNNEHI-rlA-woxH.js} +1 -1
- package/dist/assets/{swimlanes-SLNWSIFB-CZgIPz6I.js → swimlanes-SLNWSIFB-DCwz8-mf.js} +2 -2
- package/dist/assets/{swimlanes-SLNWSIFB-B16H-6OU.js → swimlanes-SLNWSIFB-M9Oumwnl.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CTtTyW6-.js +8 -0
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-Caohx6WZ.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-7r7OVlrT.js → timeline-definition-Z64GVDOM-BVmfjoWH.js} +1 -1
- package/dist/assets/{timeline-definition-Z64GVDOM-nhnkS_wy.js → timeline-definition-Z64GVDOM-DyXvto1l.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-B1piFYrz.js → vennDiagram-T6HMQDX7-CNe6zorb.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-x8SJTFhK.js → vennDiagram-T6HMQDX7-DyzOWKx3.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-BdD4GExj.js → wardleyDiagram-T6FBY63Y-D5YvMVwa.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-C90xqNVS.js → wardleyDiagram-T6FBY63Y-DXo8BCrA.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M--Ndoz0Cq.js → xychartDiagram-ELKLHX3M-CIBffVxC.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-BAKns-7o.js → xychartDiagram-ELKLHX3M-XlsWelDb.js} +1 -1
- package/dist/build-info.json +2 -2
- package/dist/convert-icons.md +10 -46
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +1 -9
- package/dist/generate-icons.js +67 -47
- package/dist/icons/icon-128x128.png +0 -0
- package/dist/icons/icon-144x144.png +0 -0
- package/dist/icons/icon-152x152.png +0 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-384x384.png +0 -0
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-72x72.png +0 -0
- package/dist/icons/icon-96x96.png +0 -0
- package/dist/index.html +2 -2
- package/dist/logo-128.png +0 -0
- package/dist/logo-256.png +0 -0
- package/dist/logo-32.png +0 -0
- package/dist/logo-512.png +0 -0
- package/dist/logo-64.png +0 -0
- package/dist/logo-source.png +0 -0
- package/dist/logo.svg +1 -17
- package/dist/sw.js +7 -9
- package/dist-server/build-info.json +2 -2
- package/dist-server/server/load-env.js +12 -4
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/browser-use/browser-use.service.js +33 -11
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +4 -4
- package/dist-server/server/modules/browser-use/index.js.map +1 -1
- package/dist-server/server/modules/browser-use/mcp-server-names.js +6 -4
- package/dist-server/server/modules/browser-use/mcp-server-names.js.map +1 -1
- package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js +49 -1
- package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js.map +1 -1
- package/dist-server/server/modules/cli/asset-migration-files.js +74 -0
- package/dist-server/server/modules/cli/asset-migration-files.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration-report.js +80 -0
- package/dist-server/server/modules/cli/asset-migration-report.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration-store.js +153 -0
- package/dist-server/server/modules/cli/asset-migration-store.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration.service.js +161 -0
- package/dist-server/server/modules/cli/asset-migration.service.js.map +1 -0
- package/dist-server/server/modules/cli/browser-use-mcp.js +9 -4
- package/dist-server/server/modules/cli/browser-use-mcp.js.map +1 -1
- package/dist-server/server/modules/cli/cli.module.js +21 -1
- package/dist-server/server/modules/cli/cli.module.js.map +1 -1
- package/dist-server/server/modules/cli/cli.service.js +6 -1
- package/dist-server/server/modules/cli/cli.service.js.map +1 -1
- package/dist-server/server/modules/cli/tests/asset-migration.service.test.js +275 -0
- package/dist-server/server/modules/cli/tests/asset-migration.service.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js +157 -0
- package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +1 -0
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli.service.test.js +6 -1
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-brief-prompt.js +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-actions.js +19 -3
- package/dist-server/server/modules/cockpit/cockpit-card-actions.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js +94 -9
- package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-registry.js +1 -1
- package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js +3 -0
- package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js +16 -0
- package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit.module.js +1 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js +96 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js.map +1 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.js +2 -2
- package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js +169 -3
- package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js.map +1 -1
- package/dist-server/server/modules/context-events/context-event-writer.js +5 -5
- package/dist-server/server/modules/context-events/context-events.module.js +2 -2
- package/dist-server/server/modules/context-events/session-ask-stream-reader.js +1 -1
- package/dist-server/server/modules/context-events/session-blocked-events.js +3 -3
- package/dist-server/server/modules/context-events/tests/session-ask-event-writer.test.js +1 -1
- package/dist-server/server/modules/context-events/tests/session-blocked-events.test.js +3 -3
- package/dist-server/server/modules/context-events/tests/session-run-events.test.js +1 -1
- package/dist-server/server/modules/database/migrations.js +23 -1
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js +25 -4
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/repositories/voice-user-identifiers.db.js +1 -1
- package/dist-server/server/modules/database/schema.js +16 -2
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js +2 -0
- package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -2
- package/dist-server/server/modules/debug-agent/tests/debug-agent-permission-popup.test.js +2 -2
- package/dist-server/server/modules/liaison/liaison-deliver.service.js +3 -3
- package/dist-server/server/modules/liaison/liaison.module.js +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js +3 -2
- package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-self-target.js +2 -2
- package/dist-server/server/modules/mcp-gateway/mcp-session-send.js +7 -0
- package/dist-server/server/modules/mcp-gateway/mcp-session-send.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-tool-annotations.js +4 -4
- package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js +4 -2
- package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-audit-route.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-audit.test.js +4 -4
- package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js +3 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js +7 -3
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-correlation-id.test.js +8 -8
- package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-english-only.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-overview.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js +3 -3
- package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-run-get.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.js +3 -3
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
- package/dist-server/server/modules/oauth/access-tokens.service.js +8 -8
- package/dist-server/server/modules/oauth/oauth-consent.service.js +20 -15
- package/dist-server/server/modules/oauth/oauth-consent.service.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js +54 -34
- package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js +35 -14
- package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js +27 -22
- package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/oauth-consent-ratelimit.test.js +2 -2
- package/dist-server/server/modules/oauth/tests/token-info.routes.test.js +2 -2
- package/dist-server/server/modules/oauth/tests/token-info.routes.test.js.map +1 -1
- package/dist-server/server/modules/observation/blind-spots.js +1 -1
- package/dist-server/server/modules/observation/observation-store.js +50 -17
- package/dist-server/server/modules/observation/observation-store.js.map +1 -1
- package/dist-server/server/modules/observation/observation-uri.js +31 -19
- package/dist-server/server/modules/observation/observation-uri.js.map +1 -1
- package/dist-server/server/modules/observation/observation.routes.js +1 -1
- package/dist-server/server/modules/observation/project-truth.js +1 -1
- package/dist-server/server/modules/observation/session-ask-decision-answer.js +2 -1
- package/dist-server/server/modules/observation/session-ask-decision-answer.js.map +1 -1
- package/dist-server/server/modules/observation/session-digest-llm.js +7 -1
- package/dist-server/server/modules/observation/session-digest-llm.js.map +1 -1
- package/dist-server/server/modules/observation/session-digest.js +39 -5
- package/dist-server/server/modules/observation/session-digest.js.map +1 -1
- package/dist-server/server/modules/observation/tests/architecture-delta.test.js +1 -1
- package/dist-server/server/modules/observation/tests/observation-routes.test.js +9 -0
- package/dist-server/server/modules/observation/tests/observation-routes.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/observation-store.test.js +38 -0
- package/dist-server/server/modules/observation/tests/observation-store.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/project-truth.test.js +2 -2
- package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js +150 -0
- package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/session-digest.test.js +24 -1
- package/dist-server/server/modules/observation/tests/session-digest.test.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +9 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-host-driver.provider.js +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +22 -3
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.connection.js +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js +11 -9
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js +15 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +14 -3
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js +248 -0
- package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js +37 -0
- package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +19 -1
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +23 -2
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +136 -106
- 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 +3 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-model-resolver.js +106 -0
- package/dist-server/server/modules/providers/services/session-model-resolver.js.map +1 -0
- package/dist-server/server/modules/providers/services/session-provider-binding.js +89 -0
- package/dist-server/server/modules/providers/services/session-provider-binding.js.map +1 -0
- package/dist-server/server/modules/providers/services/sessions.service.js +5 -1
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-resident-addressable.test.js +2 -2
- package/dist-server/server/modules/providers/tests/claude-session-name-authority.test.js +4 -4
- package/dist-server/server/modules/providers/tests/codex-app-server-protocol.test.js +1 -1
- package/dist-server/server/modules/providers/tests/codex-host-driver-persistent.test.js +2 -2
- package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js +270 -0
- package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js +484 -0
- package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js +228 -0
- package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js +306 -0
- package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +2 -2
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +15 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +1 -1
- package/dist-server/server/modules/quay/index.js +1 -1
- package/dist-server/server/modules/quay/quay-fleet-cli.js +1 -1
- package/dist-server/server/modules/quay/quay-fleet-locator.js +2 -2
- package/dist-server/server/modules/quay/quay-fleet-project-id.js +7 -7
- package/dist-server/server/modules/quay/quay-fleet-registry.js +3 -3
- package/dist-server/server/modules/quay/quay-suite-fanin-reader.js +1 -1
- package/dist-server/server/modules/quay/quay-uri-resolve.js +6 -6
- package/dist-server/server/modules/quay/quay.module.js +3 -3
- package/dist-server/server/modules/quay/quay.routes.js +1 -1
- package/dist-server/server/modules/quay/quay.service.js +4 -4
- package/dist-server/server/modules/quay/tests/contracts/fleet-cli-contracts.test.js +3 -3
- package/dist-server/server/modules/quay/tests/contracts/shapes.js +9 -9
- package/dist-server/server/modules/quay/tests/quay-fleet-locator.test.js +1 -1
- package/dist-server/server/modules/quay/tests/quay-fleet-project-id.test.js +4 -4
- package/dist-server/server/modules/quay/tests/quay-uri-resolve.test.js +10 -10
- package/dist-server/server/modules/session-hosts/tests/resident-server-restart.test.js +1 -1
- package/dist-server/server/modules/settings/codex-mcp-gateway.settings.js +1 -1
- package/dist-server/server/modules/settings/codex-model-providers.schema.js +349 -0
- package/dist-server/server/modules/settings/codex-model-providers.schema.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.service.js +199 -0
- package/dist-server/server/modules/settings/codex-model-providers.service.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.settings.js +547 -0
- package/dist-server/server/modules/settings/codex-model-providers.settings.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.store.js +200 -0
- package/dist-server/server/modules/settings/codex-model-providers.store.js.map +1 -0
- package/dist-server/server/modules/settings/index.js +10 -0
- package/dist-server/server/modules/settings/index.js.map +1 -1
- package/dist-server/server/modules/settings/server-settings-file.js +28 -32
- package/dist-server/server/modules/settings/server-settings-file.js.map +1 -1
- package/dist-server/server/modules/settings/server-settings.js +2 -2
- package/dist-server/server/modules/settings/server-settings.js.map +1 -1
- package/dist-server/server/modules/settings/settings.module.js +35 -0
- package/dist-server/server/modules/settings/settings.module.js.map +1 -1
- package/dist-server/server/modules/settings/settings.routes.js +42 -0
- package/dist-server/server/modules/settings/settings.routes.js.map +1 -1
- package/dist-server/server/modules/settings/settings.service.js +8 -21
- package/dist-server/server/modules/settings/settings.service.js.map +1 -1
- package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js +1 -0
- package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js.map +1 -1
- package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js +336 -0
- package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js.map +1 -0
- package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js +466 -0
- package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js.map +1 -0
- package/dist-server/server/modules/settings/tests/codex-provider-import.test.js +475 -0
- package/dist-server/server/modules/settings/tests/codex-provider-import.test.js.map +1 -0
- package/dist-server/server/modules/voice/tests/voice-lexicon.test.js +9 -9
- package/dist-server/server/modules/voice/tests/voice-lexicon.test.js.map +1 -1
- package/dist-server/server/modules/voice/voice-lexicon.js +1 -1
- package/dist-server/server/modules/websocket/services/chat-control.service.js +21 -1
- package/dist-server/server/modules/websocket/services/chat-control.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +25 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-background-task.test.js +18 -1
- package/dist-server/server/modules/websocket/tests/chat-background-task.test.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js +18 -1
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js.map +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +1 -1
- package/dist-server/server/shared/brand.js +18 -20
- package/dist-server/server/shared/brand.js.map +1 -1
- package/dist-server/server/shared/data-root-migration.js +3 -2
- package/dist-server/server/shared/data-root-migration.js.map +1 -1
- package/dist-server/server/shared/data-root.js +54 -59
- package/dist-server/server/shared/data-root.js.map +1 -1
- package/dist-server/server/shared/mcp-contract/types.js +20 -15
- package/dist-server/server/shared/mcp-contract/types.js.map +1 -1
- package/dist-server/server/shared/ports/codex-provider-registry.port.js +66 -0
- package/dist-server/server/shared/ports/codex-provider-registry.port.js.map +1 -0
- package/dist-server/server/shared/settings-file.js +120 -6
- package/dist-server/server/shared/settings-file.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-brand-env.test.js +76 -34
- package/dist-server/server/shared/tests/cloudpit-brand-env.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-data-root.test.js +35 -18
- package/dist-server/server/shared/tests/cloudpit-data-root.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js +153 -17
- package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js +116 -114
- package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js.map +1 -1
- package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js +9 -1
- package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js.map +1 -1
- package/dist-server/server/shared/tests/quay-test-script.test.js +40 -6
- package/dist-server/server/shared/tests/quay-test-script.test.js.map +1 -1
- package/dist-server/server/shared/tests/settings-file.test.js +58 -2
- package/dist-server/server/shared/tests/settings-file.test.js.map +1 -1
- package/dist-server/server/shared/types.js.map +1 -1
- package/dist-server/server/shared/utils.js +1 -1
- package/electron/appIdMigration.js +467 -0
- package/electron/assets/logo-macos.icns +0 -0
- package/electron/assets/logo-macos.png +0 -0
- package/electron/assets/logo-windows.ico +0 -0
- package/electron/brandEnv.js +64 -0
- package/electron/cloud.js +3 -3
- package/electron/desktopNotifications.js +1 -1
- package/electron/launcher/index.html +1 -1
- package/electron/localServer.js +41 -7
- package/electron/main.js +33 -15
- package/electron/scripts/generate-macos-icon.js +34 -28
- package/electron/scripts/generate-windows-icon.js +66 -0
- package/electron/serverInstaller.js +20 -11
- package/electron/tests/cloudpit-appid-migration.test.mjs +514 -0
- package/electron/tests/cloudpit-brand-env-wiring.test.mjs +324 -0
- package/electron/tests/cloudpit-desktop-identity.test.mjs +42 -19
- package/electron/tests/cloudpit-runtime-identity-surfaces.test.mjs +10 -4
- package/electron/tests/cloudpit-userdata-migration.test.mjs +18 -5
- package/electron/userDataMigration.js +3 -0
- package/package.json +7 -6
- package/public/api-docs.html +3 -3
- package/scripts/brand-allowlist-check.mjs +233 -12
- package/scripts/brand-allowlist-check.test.mjs +270 -1
- package/scripts/cloudpit-distribution-check.mjs +57 -23
- package/scripts/cloudpit-distribution-check.test.mjs +42 -9
- package/scripts/codex-protocol-smoke.mjs +1 -1
- package/scripts/isolated-instance.sh +1 -1
- package/scripts/mcp-smoke.mjs +2 -2
- package/scripts/release/tests/fork-release-workflows.test.mjs +45 -0
- package/scripts/release/tests/server-installer-bundle-url.test.mjs +57 -9
- package/scripts/restart-when-idle.sh +1 -1
- package/scripts/shadow-prediction-report.mjs +1 -1
- package/scripts/suite-duration-baseline.tsv +45 -0
- package/scripts/ui-scenario.mjs +195 -0
- package/scripts/ui-scenarios/codex-provider-import.json +63 -0
- package/scripts/ui-scenarios/codex-provider-settings.json +77 -0
- package/scripts/voice-capture-process-check.false-forms.test.mjs +1 -1
- package/scripts/voice-phase0-report.test.mjs +1 -1
- package/server/load-env.ts +15 -4
- package/server/modules/browser-use/browser-use.service.ts +45 -14
- package/server/modules/browser-use/index.ts +3 -4
- package/server/modules/browser-use/mcp-server-names.ts +6 -5
- package/server/modules/browser-use/tests/browser-use.service.test.ts +63 -1
- package/server/modules/cli/asset-migration-files.ts +96 -0
- package/server/modules/cli/asset-migration-report.ts +123 -0
- package/server/modules/cli/asset-migration-store.ts +228 -0
- package/server/modules/cli/asset-migration.service.ts +236 -0
- package/server/modules/cli/browser-use-mcp.ts +9 -4
- package/server/modules/cli/cli.module.ts +21 -1
- package/server/modules/cli/cli.service.ts +14 -1
- package/server/modules/cli/tests/asset-migration.service.test.ts +349 -0
- package/server/modules/cli/tests/browser-use-mcp-entry.test.ts +202 -0
- package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +1 -0
- package/server/modules/cli/tests/cli.service.test.ts +6 -1
- package/server/modules/cockpit/cockpit-brief-prompt.ts +1 -1
- package/server/modules/cockpit/cockpit-card-actions.ts +20 -3
- package/server/modules/cockpit/cockpit-card-feedback-store.ts +104 -9
- package/server/modules/cockpit/cockpit-card-registry.ts +2 -2
- package/server/modules/cockpit/cockpit-fleet-card-projection.ts +3 -0
- package/server/modules/cockpit/cockpit-fleet-executor.ts +1 -1
- package/server/modules/cockpit/cockpit-knowledge-reading.ts +17 -0
- package/server/modules/cockpit/cockpit.module.ts +2 -2
- package/server/modules/cockpit/cockpit.reducer.ts +1 -1
- package/server/modules/cockpit/tests/cockpit-card-feedback.test.ts +116 -1
- package/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.ts +2 -2
- package/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.ts +205 -3
- package/server/modules/context-events/context-event-writer.ts +6 -6
- package/server/modules/context-events/context-events.module.ts +2 -2
- package/server/modules/context-events/session-ask-stream-reader.ts +1 -1
- package/server/modules/context-events/session-blocked-events.ts +3 -3
- package/server/modules/context-events/tests/session-ask-event-writer.test.ts +1 -1
- package/server/modules/context-events/tests/session-blocked-events.test.ts +3 -3
- package/server/modules/context-events/tests/session-run-events.test.ts +1 -1
- package/server/modules/database/migrations.ts +24 -1
- package/server/modules/database/repositories/sessions.db.ts +41 -4
- package/server/modules/database/repositories/voice-user-identifiers.db.ts +1 -1
- package/server/modules/database/schema.ts +16 -2
- package/server/modules/database/tests/migrations-ensure-columns.test.ts +2 -0
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -2
- package/server/modules/debug-agent/tests/debug-agent-permission-popup.test.ts +2 -2
- package/server/modules/liaison/liaison-deliver.service.ts +4 -4
- package/server/modules/liaison/liaison.module.ts +1 -1
- package/server/modules/mcp-gateway/mcp-gateway.auth.ts +3 -2
- package/server/modules/mcp-gateway/mcp-self-target.ts +2 -2
- package/server/modules/mcp-gateway/mcp-session-send.ts +21 -2
- package/server/modules/mcp-gateway/mcp-tool-annotations.ts +4 -4
- package/server/modules/mcp-gateway/oauth-metadata.gate.ts +4 -5
- package/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-approvals.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-audit-route.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-audit.test.ts +4 -4
- package/server/modules/mcp-gateway/tests/mcp-auth.test.ts +3 -1
- package/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.ts +7 -3
- package/server/modules/mcp-gateway/tests/mcp-correlation-id.test.ts +8 -8
- package/server/modules/mcp-gateway/tests/mcp-draft.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-english-only.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-overview.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-read-tools.test.ts +3 -3
- package/server/modules/mcp-gateway/tests/mcp-run-get.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-self-target.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-background.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-session-host-control.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-search.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-send.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-usage-stats.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-write-notification.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.ts +3 -3
- package/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
- package/server/modules/oauth/access-tokens.service.ts +8 -8
- package/server/modules/oauth/oauth-consent.service.ts +20 -15
- package/server/modules/oauth/tests/access-token-scopes.test.ts +55 -34
- package/server/modules/oauth/tests/access-tokens.service.test.ts +50 -14
- package/server/modules/oauth/tests/oauth-consent-page.test.ts +29 -21
- package/server/modules/oauth/tests/oauth-consent-ratelimit.test.ts +2 -2
- package/server/modules/oauth/tests/token-info.routes.test.ts +2 -2
- package/server/modules/observation/architecture-delta.producer.ts +1 -1
- package/server/modules/observation/blind-spots.ts +1 -1
- package/server/modules/observation/observation-store.ts +54 -16
- package/server/modules/observation/observation-uri.ts +34 -21
- package/server/modules/observation/observation.routes.ts +1 -1
- package/server/modules/observation/project-truth.ts +3 -3
- package/server/modules/observation/session-ask-decision-answer.ts +2 -1
- package/server/modules/observation/session-digest-llm.ts +7 -1
- package/server/modules/observation/session-digest.ts +39 -5
- package/server/modules/observation/tests/architecture-delta.test.ts +1 -1
- package/server/modules/observation/tests/observation-routes.test.ts +13 -0
- package/server/modules/observation/tests/observation-store.test.ts +58 -0
- package/server/modules/observation/tests/project-truth.test.ts +2 -2
- package/server/modules/observation/tests/session-ask-decision-digest.test.ts +189 -0
- package/server/modules/observation/tests/session-digest.test.ts +43 -0
- package/server/modules/providers/index.ts +13 -0
- package/server/modules/providers/list/claude/claude-host-driver.provider.ts +1 -1
- package/server/modules/providers/list/codex/codex-app-server.client.ts +37 -5
- package/server/modules/providers/list/codex/codex-app-server.connection.ts +1 -1
- package/server/modules/providers/list/codex/codex-host-driver.contract.ts +18 -9
- package/server/modules/providers/list/codex/codex-host-driver.provider.ts +15 -1
- package/server/modules/providers/list/codex/codex-models.provider.ts +16 -3
- package/server/modules/providers/list/codex/codex-provider-injection.ts +323 -0
- package/server/modules/providers/list/codex/codex-resident-provider-launch.ts +71 -0
- package/server/modules/providers/list/codex/codex-runtime.provider.ts +20 -1
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +1 -1
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +1 -1
- package/server/modules/providers/provider.routes.ts +23 -2
- package/server/modules/providers/services/provider-models.service.ts +187 -124
- package/server/modules/providers/services/provider-runtime.service.ts +3 -0
- package/server/modules/providers/services/session-model-resolver.ts +180 -0
- package/server/modules/providers/services/session-provider-binding.ts +176 -0
- package/server/modules/providers/services/sessions.service.ts +5 -1
- package/server/modules/providers/tests/claude-resident-addressable.test.ts +2 -2
- package/server/modules/providers/tests/claude-session-name-authority.test.ts +4 -4
- package/server/modules/providers/tests/codex-app-server-protocol.test.ts +1 -1
- package/server/modules/providers/tests/codex-host-driver-persistent.test.ts +2 -2
- package/server/modules/providers/tests/codex-provider-model-binding.test.ts +345 -0
- package/server/modules/providers/tests/codex-resident-provider-injection.test.ts +561 -0
- package/server/modules/providers/tests/codex-runtime-provider-injection.test.ts +269 -0
- package/server/modules/providers/tests/codex-session-provider-binding.test.ts +386 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +1 -1
- package/server/modules/providers/tests/opencode-sessions.test.ts +2 -2
- package/server/modules/providers/tests/provider-models.service.test.ts +15 -0
- package/server/modules/providers/tests/provider.routes.test.ts +1 -1
- package/server/modules/quay/index.ts +1 -1
- package/server/modules/quay/quay-dispatch-carrier.ts +1 -1
- package/server/modules/quay/quay-fleet-cli.ts +1 -1
- package/server/modules/quay/quay-fleet-locator.ts +2 -2
- package/server/modules/quay/quay-fleet-project-id.ts +14 -14
- package/server/modules/quay/quay-fleet-registry.ts +8 -8
- package/server/modules/quay/quay-suite-fanin-reader.ts +1 -1
- package/server/modules/quay/quay-uri-resolve.ts +8 -8
- package/server/modules/quay/quay.module.ts +3 -3
- package/server/modules/quay/quay.routes.ts +1 -1
- package/server/modules/quay/quay.service.ts +6 -6
- package/server/modules/quay/session-task-chain.service.ts +1 -1
- package/server/modules/quay/tests/contracts/fleet-cli-contracts.test.ts +3 -3
- package/server/modules/quay/tests/contracts/shapes.ts +10 -10
- package/server/modules/quay/tests/quay-fleet-locator.test.ts +1 -1
- package/server/modules/quay/tests/quay-fleet-project-id.test.ts +6 -6
- package/server/modules/quay/tests/quay-uri-resolve.test.ts +10 -10
- package/server/modules/session-hosts/tests/resident-server-restart.test.ts +1 -1
- package/server/modules/settings/codex-mcp-gateway.settings.ts +1 -1
- package/server/modules/settings/codex-model-providers.schema.ts +460 -0
- package/server/modules/settings/codex-model-providers.service.ts +235 -0
- package/server/modules/settings/codex-model-providers.settings.ts +713 -0
- package/server/modules/settings/codex-model-providers.store.ts +244 -0
- package/server/modules/settings/index.ts +18 -0
- package/server/modules/settings/server-settings-file.ts +29 -41
- package/server/modules/settings/server-settings.ts +2 -3
- package/server/modules/settings/settings.module.ts +41 -0
- package/server/modules/settings/settings.routes.ts +37 -0
- package/server/modules/settings/settings.service.ts +21 -26
- package/server/modules/settings/tests/cockpit-session-start-settings.routes.test.ts +1 -0
- package/server/modules/settings/tests/codex-model-providers-settings.test.ts +413 -0
- package/server/modules/settings/tests/codex-provider-advanced.test.ts +540 -0
- package/server/modules/settings/tests/codex-provider-import.test.ts +621 -0
- package/server/modules/voice/tests/voice-lexicon.test.ts +10 -10
- package/server/modules/voice/voice-lexicon.ts +1 -1
- package/server/modules/websocket/services/chat-control.service.ts +35 -2
- package/server/modules/websocket/services/chat-websocket.service.ts +25 -1
- package/server/modules/websocket/tests/chat-background-task.test.ts +17 -1
- package/server/modules/websocket/tests/chat-stop-task.test.ts +17 -1
- package/server/modules/worktrees/services/worktree-list.service.ts +1 -1
- package/server/modules/worktrees/services/worktree-open.service.ts +1 -1
- package/server/modules/worktrees/services/worktree-remove.service.ts +1 -1
- package/server/shared/brand.ts +24 -38
- package/server/shared/data-root-migration.ts +3 -2
- package/server/shared/data-root.ts +73 -79
- package/server/shared/interfaces.ts +1 -1
- package/server/shared/mcp-contract/types.ts +20 -15
- package/server/shared/ports/codex-provider-registry.port.ts +133 -0
- package/server/shared/ports/session-blocked-events.port.ts +1 -1
- package/server/shared/ports/session-run-events.port.ts +2 -2
- package/server/shared/settings-file.ts +167 -6
- package/server/shared/tests/architecture-ratchet.baseline.json +15 -15
- package/server/shared/tests/cloudpit-brand-env.test.ts +106 -36
- package/server/shared/tests/cloudpit-data-root.test.ts +42 -18
- package/server/shared/tests/cloudpit-goal-exit-gate.baseline.json +6 -2
- package/server/shared/tests/cloudpit-goal-exit-gate.test.ts +179 -17
- package/server/shared/tests/cloudpit-runtime-flip.test.ts +162 -123
- package/server/shared/tests/frontend-import-cycle-budget.baseline.json +8 -6
- package/server/shared/tests/frontend-import-cycle-budget.test.ts +9 -1
- package/server/shared/tests/quay-test-script.test.ts +40 -6
- package/server/shared/tests/settings-file.test.ts +83 -1
- package/server/shared/types.ts +121 -8
- package/server/shared/utils.ts +1 -1
- package/dist/assets/channel-D7XqNTJC.js +0 -1
- package/dist/assets/channel-sbQyI1an.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-DHudi-zH.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-DV7ybJJG.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DHudi-zH.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DV7ybJJG.js +0 -1
- package/dist/assets/index-BsACp0s2.css +0 -32
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CNMNp6YA.js +0 -8
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-DOjtDEUW.js +0 -8
- package/dist/icons/icon-128x128.svg +0 -12
- package/dist/icons/icon-144x144.svg +0 -12
- package/dist/icons/icon-152x152.svg +0 -12
- package/dist/icons/icon-192x192.svg +0 -12
- package/dist/icons/icon-384x384.svg +0 -12
- package/dist/icons/icon-512x512.svg +0 -12
- package/dist/icons/icon-72x72.svg +0 -12
- package/dist/icons/icon-96x96.svg +0 -12
- package/dist/icons/icon-template.svg +0 -12
|
@@ -217,7 +217,7 @@ async function withHarness(run: (harness: Harness) => Promise<void>): Promise<vo
|
|
|
217
217
|
|
|
218
218
|
const tokens = createAccessTokensService({ now: () => new Date(NOW_MS) });
|
|
219
219
|
const readToken = tokens.issueToken({
|
|
220
|
-
userId: USER_ONE, name: 'mcp-read', scopes: ['
|
|
220
|
+
userId: USER_ONE, name: 'mcp-read', scopes: ['cloudpit:read'], expiresInDays: 30,
|
|
221
221
|
});
|
|
222
222
|
if (!readToken.ok) {
|
|
223
223
|
throw new Error('the harness must mint the read token');
|
|
@@ -225,7 +225,7 @@ async function withStatsServer(run: (server: StatsServer) => Promise<void>): Pro
|
|
|
225
225
|
const port = (httpServer.address() as AddressInfo).port;
|
|
226
226
|
|
|
227
227
|
const issue = (userId: number, scopes: string[]): { id: number; token: string } => {
|
|
228
|
-
const issued = tokens.issueToken({ userId, name: 'self-check', scopes, expiresInDays: 30 });
|
|
228
|
+
const issued = tokens.issueToken({ userId, name: 'self-check', scopes: scopes.map((scope) => scope.replace('cloudcli:', 'cloudpit:')), expiresInDays: 30 });
|
|
229
229
|
if (!issued.ok) {
|
|
230
230
|
throw new Error('the harness issued a token with a lifetime the service rejects');
|
|
231
231
|
}
|
|
@@ -356,13 +356,13 @@ async function withHarness(options: HarnessOptions, run: (harness: Harness) => P
|
|
|
356
356
|
const fullToken = tokens.issueToken({
|
|
357
357
|
userId: USER_ONE,
|
|
358
358
|
name: FULL_TOKEN_NAME,
|
|
359
|
-
scopes:
|
|
359
|
+
scopes: ACCESS_TOKEN_SCOPES.map((scope) => scope.replace('cloudcli:', 'cloudpit:')),
|
|
360
360
|
expiresInDays: 30,
|
|
361
361
|
});
|
|
362
362
|
const readOnlyToken = tokens.issueToken({
|
|
363
363
|
userId: USER_ONE,
|
|
364
364
|
name: 'ac303-read',
|
|
365
|
-
scopes: [ACCESS_TOKEN_SCOPES[0]],
|
|
365
|
+
scopes: [ACCESS_TOKEN_SCOPES[0].replace('cloudcli:', 'cloudpit:')],
|
|
366
366
|
expiresInDays: 30,
|
|
367
367
|
});
|
|
368
368
|
if (!fullToken.ok || !readOnlyToken.ok) {
|
|
@@ -69,14 +69,14 @@ const USERNAME = 'oauth-e2e-user';
|
|
|
69
69
|
*/
|
|
70
70
|
const ACCOUNT_PASSWORD = 'oauth-e2e-password';
|
|
71
71
|
const REDIRECT_URI = 'https://app.example/cb';
|
|
72
|
-
const READ_SCOPE = '
|
|
72
|
+
const READ_SCOPE = 'cloudpit:read';
|
|
73
73
|
/**
|
|
74
74
|
* A state-changing scope. Since gap-oauth-consent-flow-ux-hardening the consent
|
|
75
75
|
* `allow` branch asks for the password ONLY when the grant reaches past
|
|
76
76
|
* `cloudcli:read`, so the wrong-password counterexample and the password-carrying
|
|
77
77
|
* mode below must submit this alongside the read scope.
|
|
78
78
|
*/
|
|
79
|
-
const WRITE_SCOPE = '
|
|
79
|
+
const WRITE_SCOPE = 'cloudpit:session:send';
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* The same native module the auth module hashes with (`bcrypt.hash(pw, 12)` in
|
|
@@ -251,7 +251,7 @@ type ServerContext = {
|
|
|
251
251
|
};
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
|
-
* Seeds a temp database with ONE
|
|
254
|
+
* Seeds a temp database with ONE Cloudpit user, boots a real `server/index.ts`
|
|
255
255
|
* process against it on a temp port, waits for the ready line, and hands the
|
|
256
256
|
* context to `run`. The user row is what `oauth_grants.user_id` references and
|
|
257
257
|
* what `authenticateToken` loads for the minted JWT; since AC-261 it is also what
|
|
@@ -165,7 +165,7 @@ function buildNotificationPayload(event) {
|
|
|
165
165
|
const message = CODE_MAP[normalizedEvent.code] || 'You have a new notification';
|
|
166
166
|
|
|
167
167
|
return {
|
|
168
|
-
title: sessionName || '
|
|
168
|
+
title: sessionName || 'Cloudpit',
|
|
169
169
|
body: `${providerLabel}: ${message}`,
|
|
170
170
|
data: {
|
|
171
171
|
sessionId: normalizedEvent.sessionId || null,
|
|
@@ -137,16 +137,16 @@ function isAllowedExpiryDays(days: number | null | undefined): days is number {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
* Validates a requested scope list against the accepted vocabulary (
|
|
141
|
-
*
|
|
142
|
-
* first-occurrence order
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
140
|
+
* Validates a requested scope list against the accepted vocabulary (3.0: the
|
|
141
|
+
* eight `cloudpit:*` spellings only) and removes duplicates, preserving
|
|
142
|
+
* first-occurrence order. This is the single vocabulary check and deduplication
|
|
143
|
+
* used by both issuance paths, so no caller can mint an unknown, reserved,
|
|
144
|
+
* retired, empty or duplicated scope. Consumers: this module's `issueToken` and
|
|
145
|
+
* the settings module's `createAccessToken`.
|
|
146
146
|
*
|
|
147
147
|
* Returns `{ ok: false }` for a non-array, an empty array, any non-string
|
|
148
|
-
* element, or any string outside the vocabulary
|
|
149
|
-
* the deduplicated list.
|
|
148
|
+
* element, or any string outside the vocabulary (including the retired
|
|
149
|
+
* `cloudcli:*` spelling); otherwise `{ ok: true }` with the deduplicated list.
|
|
150
150
|
*/
|
|
151
151
|
export function normalizeAccessTokenScopes(
|
|
152
152
|
scopes: unknown,
|
|
@@ -19,10 +19,13 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import type { OAuthClientRow } from '@/modules/database/index.js';
|
|
22
|
-
import {
|
|
23
|
-
import { canonicalScope } from '@/shared/mcp-contract/index.js';
|
|
22
|
+
import { CLOUDPIT_ACCESS_TOKEN_SCOPES, canonicalScope } from '@/shared/mcp-contract/index.js';
|
|
24
23
|
|
|
25
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The canonical scope every consent grants; the SPA lists the wire spelling
|
|
26
|
+
* `cloudpit:read` checked and not removable, and the stored grant keeps this
|
|
27
|
+
* canonical name so existing `requiredScopes` literals keep matching.
|
|
28
|
+
*/
|
|
26
29
|
export const OAUTH_CONSENT_READ_SCOPE = 'cloudcli:read';
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -106,9 +109,9 @@ export type OAuthConsentClients = { findById(clientId: string): OAuthClientRow |
|
|
|
106
109
|
|
|
107
110
|
/** The whole vocabulary, each entry flagged for the screen. */
|
|
108
111
|
export function consentScopeOptions(): ConsentScopeOption[] {
|
|
109
|
-
return
|
|
110
|
-
// The
|
|
111
|
-
//
|
|
112
|
+
return CLOUDPIT_ACCESS_TOKEN_SCOPES.map((scope) => {
|
|
113
|
+
// The screen offers the 3.0 wire spellings; the description/risk tables stay
|
|
114
|
+
// keyed by the canonical names, so the lookup goes through `canonicalScope`.
|
|
112
115
|
const canonical = canonicalScope(scope);
|
|
113
116
|
return {
|
|
114
117
|
scope,
|
|
@@ -197,21 +200,23 @@ export function readConsentRequest(
|
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
/**
|
|
200
|
-
* The scopes a decision grants:
|
|
201
|
-
* pins it), then every submitted scope
|
|
202
|
-
* value the client invented — `cloudcli:admin`, a typo,
|
|
203
|
-
* dropped rather than stored on the grant.
|
|
203
|
+
* The scopes a decision grants: the canonical read scope first (forced, as the
|
|
204
|
+
* screen pins it), then every submitted wire scope, once each, stored under its
|
|
205
|
+
* canonical name. A value the client invented — `cloudcli:admin`, a typo, the
|
|
206
|
+
* retired `cloudcli:*` spelling — is dropped rather than stored on the grant.
|
|
204
207
|
*/
|
|
205
208
|
export function grantedScopes(submitted: readonly string[]): string[] {
|
|
206
|
-
const vocabulary = new Set<string>(
|
|
209
|
+
const vocabulary = new Set<string>(CLOUDPIT_ACCESS_TOKEN_SCOPES);
|
|
207
210
|
const seen = new Set<string>([OAUTH_CONSENT_READ_SCOPE]);
|
|
208
211
|
const scopes = [OAUTH_CONSENT_READ_SCOPE];
|
|
209
212
|
for (const submittedScope of submitted) {
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
+
// 3.0 accepts one wire spelling; the stored grant uses the canonical name so
|
|
214
|
+
// existing `requiredScopes` literals and the screen's tables keep matching.
|
|
215
|
+
if (!vocabulary.has(submittedScope)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
213
218
|
const scope = canonicalScope(submittedScope);
|
|
214
|
-
if (
|
|
219
|
+
if (seen.has(scope)) {
|
|
215
220
|
continue;
|
|
216
221
|
}
|
|
217
222
|
seen.add(scope);
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* temp directory. Covers:
|
|
9
9
|
* (a) any non-empty subset of the vocabulary issues 201, the response scopes
|
|
10
10
|
* equal the requested set with no duplicates, and the stored scopes match;
|
|
11
|
-
* (b) a mistyped scope, an unprefixed `read`, `
|
|
11
|
+
* (b) a mistyped scope, an unprefixed `read`, `cloudpit:admin`, an empty list
|
|
12
12
|
* and a non-string element are all 400 with the same `INVALID_SCOPE` code
|
|
13
13
|
* and write no row;
|
|
14
|
-
* (c) an omitted scope list still defaults to `
|
|
14
|
+
* (c) an omitted scope list still defaults to `cloudpit:read`;
|
|
15
15
|
* (d) the service's own `issueToken` rejects the same illegal scopes and still
|
|
16
16
|
* issues a valid one — bypassing the route cannot mint a bad scope.
|
|
17
17
|
*/
|
|
@@ -29,6 +29,7 @@ import express from 'express';
|
|
|
29
29
|
|
|
30
30
|
import { accessTokensDb, closeConnection, getConnection, initializeDatabase } from '@/modules/database/index.js';
|
|
31
31
|
import { ACCESS_TOKEN_SCOPES, createAccessTokensService } from '@/modules/oauth/index.js';
|
|
32
|
+
import { CLOUDPIT_ACCESS_TOKEN_SCOPES } from '@/shared/mcp-contract/index.js';
|
|
32
33
|
import type { AccessTokensService } from '@/modules/oauth/index.js';
|
|
33
34
|
import { createSettingsRouter, createSettingsService } from '@/modules/settings/index.js';
|
|
34
35
|
import { AppError } from '@/shared/utils.js';
|
|
@@ -37,50 +38,50 @@ const OWNER_ID = 1;
|
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* The eight issuable scopes written out literally, so a source change that adds
|
|
40
|
-
* `
|
|
41
|
+
* `cloudpit:admin` (or drops a scope) is caught here rather than silently
|
|
41
42
|
* changing what the criterion expects.
|
|
42
43
|
*/
|
|
43
44
|
const VOCABULARY = [
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
45
|
+
'cloudpit:read',
|
|
46
|
+
'cloudpit:session:send',
|
|
47
|
+
'cloudpit:session:create',
|
|
48
|
+
'cloudpit:session:control',
|
|
49
|
+
'cloudpit:approve',
|
|
49
50
|
// gap-mcp-ui-open-session: appended last, so the five positional reads in the
|
|
50
51
|
// gateway's write-tool table keep their index.
|
|
51
|
-
'
|
|
52
|
+
'cloudpit:navigate',
|
|
52
53
|
// gap-ui-visible-context-extended-fields: appended after navigate for the same
|
|
53
54
|
// reason — every positional read in the gateway keeps its index.
|
|
54
|
-
'
|
|
55
|
+
'cloudpit:selection',
|
|
55
56
|
// gap-mcp-cockpit-card-tools: the confirm scope for cockpit cards, appended
|
|
56
|
-
// LAST for the same positional reason. There is no `
|
|
57
|
-
// the three cockpit read tools use
|
|
58
|
-
'
|
|
57
|
+
// LAST for the same positional reason. There is no `cloudpit:cockpit:read`:
|
|
58
|
+
// the three cockpit read tools use the canonical read scope.
|
|
59
|
+
'cloudpit:cockpit:act',
|
|
59
60
|
] as const;
|
|
60
61
|
|
|
61
62
|
/** A non-empty subset request and the unique scopes it must resolve to. */
|
|
62
63
|
const SUBSET_REQUESTS: { requested: string[]; expectedUnique: string[] }[] = [
|
|
63
|
-
{ requested: ['
|
|
64
|
-
{ requested: ['
|
|
65
|
-
{ requested: ['
|
|
66
|
-
{ requested: ['
|
|
67
|
-
{ requested: ['
|
|
68
|
-
{ requested: ['
|
|
64
|
+
{ requested: ['cloudpit:read'], expectedUnique: ['cloudpit:read'] },
|
|
65
|
+
{ requested: ['cloudpit:session:send'], expectedUnique: ['cloudpit:session:send'] },
|
|
66
|
+
{ requested: ['cloudpit:session:create'], expectedUnique: ['cloudpit:session:create'] },
|
|
67
|
+
{ requested: ['cloudpit:session:control'], expectedUnique: ['cloudpit:session:control'] },
|
|
68
|
+
{ requested: ['cloudpit:approve'], expectedUnique: ['cloudpit:approve'] },
|
|
69
|
+
{ requested: ['cloudpit:read', 'cloudpit:approve'], expectedUnique: ['cloudpit:read', 'cloudpit:approve'] },
|
|
69
70
|
{ requested: [...VOCABULARY], expectedUnique: [...VOCABULARY] },
|
|
70
71
|
{
|
|
71
72
|
// First-occurrence order is preserved: read then approve.
|
|
72
|
-
requested: ['
|
|
73
|
-
expectedUnique: ['
|
|
73
|
+
requested: ['cloudpit:read', 'cloudpit:read', 'cloudpit:approve'],
|
|
74
|
+
expectedUnique: ['cloudpit:read', 'cloudpit:approve'],
|
|
74
75
|
},
|
|
75
76
|
];
|
|
76
77
|
|
|
77
78
|
/** The five illegal scope payloads that must all share one 400 code. */
|
|
78
79
|
const ILLEGAL_SCOPES: unknown[] = [
|
|
79
|
-
['
|
|
80
|
+
['cloudpit:reed'],
|
|
80
81
|
['read'],
|
|
81
|
-
['
|
|
82
|
+
['cloudpit:admin'],
|
|
82
83
|
[],
|
|
83
|
-
['
|
|
84
|
+
['cloudpit:read', 42],
|
|
84
85
|
];
|
|
85
86
|
|
|
86
87
|
type HttpResponse = { status: number; body: Record<string, unknown>; text: string };
|
|
@@ -234,10 +235,13 @@ async function withSettingsServer(run: (harness: Harness) => Promise<void>): Pro
|
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
|
|
237
|
-
test('(vocabulary)
|
|
238
|
-
assert.deepEqual([...
|
|
238
|
+
test('(vocabulary) the eight issuable scopes are the cloudpit:* spellings, admin absent', () => {
|
|
239
|
+
assert.deepEqual([...CLOUDPIT_ACCESS_TOKEN_SCOPES], [...VOCABULARY]);
|
|
240
|
+
assert.equal((CLOUDPIT_ACCESS_TOKEN_SCOPES as readonly string[]).includes('cloudpit:admin'), false);
|
|
241
|
+
// The canonical table is internal, still eight names, and never the request vocabulary.
|
|
242
|
+
assert.equal(ACCESS_TOKEN_SCOPES.length, 8);
|
|
239
243
|
assert.equal((ACCESS_TOKEN_SCOPES as readonly string[]).includes('cloudcli:admin'), false);
|
|
240
|
-
console.log(`(vocabulary)
|
|
244
|
+
console.log(`(vocabulary) CLOUDPIT_ACCESS_TOKEN_SCOPES = ${JSON.stringify(CLOUDPIT_ACCESS_TOKEN_SCOPES)}`);
|
|
241
245
|
});
|
|
242
246
|
|
|
243
247
|
test('(a) any non-empty vocabulary subset issues 201 with set-equal, deduplicated, stored scopes', async () => {
|
|
@@ -300,7 +304,24 @@ test('(b) the five illegal scope payloads are all 400 INVALID_SCOPE and write no
|
|
|
300
304
|
});
|
|
301
305
|
});
|
|
302
306
|
|
|
303
|
-
test('(
|
|
307
|
+
test('(b2) the retired cloudcli:* spelling is a 400 INVALID_SCOPE and writes no row', async () => {
|
|
308
|
+
await withSettingsServer(async (harness) => {
|
|
309
|
+
for (const scopes of [['cloudcli:read'], ['cloudcli:session:send'], ['cloudcli:cockpit:act']]) {
|
|
310
|
+
const beforeCount = harness.countRows();
|
|
311
|
+
const response = await postJson(harness, '/api/settings/access-tokens', {
|
|
312
|
+
name: 'retired',
|
|
313
|
+
expiresInDays: 30,
|
|
314
|
+
scopes,
|
|
315
|
+
});
|
|
316
|
+
assert.equal(response.status, 400);
|
|
317
|
+
assert.equal(errorCode(response.body), 'INVALID_SCOPE');
|
|
318
|
+
assert.equal(harness.countRows(), beforeCount);
|
|
319
|
+
console.log(`(b2) scopes=${JSON.stringify(scopes)} status=${response.status} code=${errorCode(response.body)}`);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test('(c) an omitted scope list still defaults to cloudpit:read', async () => {
|
|
304
325
|
await withSettingsServer(async (harness) => {
|
|
305
326
|
const response = await postJson(harness, '/api/settings/access-tokens', {
|
|
306
327
|
name: 'default-scope',
|
|
@@ -308,10 +329,10 @@ test('(c) an omitted scope list still defaults to cloudcli:read', async () => {
|
|
|
308
329
|
});
|
|
309
330
|
const scopes = responseScopes(response.body);
|
|
310
331
|
assert.equal(response.status, 201);
|
|
311
|
-
assert.deepEqual(scopes, ['
|
|
332
|
+
assert.deepEqual(scopes, ['cloudpit:read']);
|
|
312
333
|
|
|
313
334
|
const stored = harness.storedScopes((response.body.token as { id: number }).id);
|
|
314
|
-
assert.deepEqual(stored, ['
|
|
335
|
+
assert.deepEqual(stored, ['cloudpit:read']);
|
|
315
336
|
|
|
316
337
|
console.log(`(c) status=${response.status} token.scopes=${JSON.stringify(scopes)} stored=${JSON.stringify(stored)}`);
|
|
317
338
|
});
|
|
@@ -322,8 +343,8 @@ test('(d) service-level issueToken rejects illegal scopes and still issues a val
|
|
|
322
343
|
const beforeCount = harness.countRows();
|
|
323
344
|
|
|
324
345
|
const illegal = [
|
|
325
|
-
{ scopes: ['
|
|
326
|
-
{ scopes: ['
|
|
346
|
+
{ scopes: ['cloudpit:reed'] },
|
|
347
|
+
{ scopes: ['cloudpit:admin'] },
|
|
327
348
|
{ scopes: [] },
|
|
328
349
|
];
|
|
329
350
|
for (const { scopes } of illegal) {
|
|
@@ -333,11 +354,11 @@ test('(d) service-level issueToken rejects illegal scopes and still issues a val
|
|
|
333
354
|
}
|
|
334
355
|
assert.equal(harness.countRows(), beforeCount);
|
|
335
356
|
|
|
336
|
-
const valid = harness.tokens.issueToken({ userId: OWNER_ID, scopes: ['
|
|
357
|
+
const valid = harness.tokens.issueToken({ userId: OWNER_ID, scopes: ['cloudpit:read'] });
|
|
337
358
|
assert.equal(valid.ok, true);
|
|
338
359
|
assert.equal(harness.countRows(), beforeCount + 1);
|
|
339
360
|
console.log(
|
|
340
|
-
`(d) issueToken(['
|
|
361
|
+
`(d) issueToken(['cloudpit:read']) = ok=${valid.ok} id=${valid.ok ? valid.token.id : '-'} `
|
|
341
362
|
+ `rows ${beforeCount}->${harness.countRows()}`,
|
|
342
363
|
);
|
|
343
364
|
});
|
|
@@ -99,7 +99,7 @@ function tokenRowCount(): number {
|
|
|
99
99
|
|
|
100
100
|
test('(a) plaintext appears once in the issue result and zero times in the database', async () => {
|
|
101
101
|
await withAccessTokenDb(async ({ service, userId, dbPath }) => {
|
|
102
|
-
const issued = service.issueToken({ userId, name: 'laptop', scopes: ['
|
|
102
|
+
const issued = service.issueToken({ userId, name: 'laptop', scopes: ['cloudpit:read'] });
|
|
103
103
|
assert.equal(issued.ok, true);
|
|
104
104
|
if (!issued.ok) return;
|
|
105
105
|
|
|
@@ -149,7 +149,7 @@ test('(b) a live token verifies and stamps last_used from the injected clock, th
|
|
|
149
149
|
const issued = service.issueToken({
|
|
150
150
|
userId,
|
|
151
151
|
name: 'laptop',
|
|
152
|
-
scopes: ['
|
|
152
|
+
scopes: ['cloudpit:read', 'cloudpit:session:send'],
|
|
153
153
|
});
|
|
154
154
|
assert.equal(issued.ok, true);
|
|
155
155
|
if (!issued.ok) return;
|
|
@@ -161,11 +161,11 @@ test('(b) a live token verifies and stamps last_used from the injected clock, th
|
|
|
161
161
|
|
|
162
162
|
assert.equal(readLastUsed(), null);
|
|
163
163
|
|
|
164
|
-
const verified = service.verifyToken(issued.token.token, '
|
|
164
|
+
const verified = service.verifyToken(issued.token.token, 'cloudpit:read');
|
|
165
165
|
assert.equal(verified.ok, true);
|
|
166
166
|
if (!verified.ok) return;
|
|
167
167
|
assert.equal(verified.userId, userId);
|
|
168
|
-
assert.deepEqual(verified.scopes, ['
|
|
168
|
+
assert.deepEqual(verified.scopes, ['cloudpit:read', 'cloudpit:session:send']);
|
|
169
169
|
|
|
170
170
|
// t0: the first use fills the NULL column with the clock's reading.
|
|
171
171
|
const firstStamp = currentTime().toISOString();
|
|
@@ -173,12 +173,12 @@ test('(b) a live token verifies and stamps last_used from the injected clock, th
|
|
|
173
173
|
|
|
174
174
|
// t0+59s: inside the window, so the stored instant is left alone.
|
|
175
175
|
advanceTo(new Date(START.getTime() + 59_000));
|
|
176
|
-
assert.equal(service.verifyToken(issued.token.token, '
|
|
176
|
+
assert.equal(service.verifyToken(issued.token.token, 'cloudpit:read').ok, true);
|
|
177
177
|
assert.equal(readLastUsed(), firstStamp);
|
|
178
178
|
|
|
179
179
|
// t0+61s: past the window, so the instant advances to the new reading.
|
|
180
180
|
advanceTo(new Date(START.getTime() + 61_000));
|
|
181
|
-
assert.equal(service.verifyToken(issued.token.token, '
|
|
181
|
+
assert.equal(service.verifyToken(issued.token.token, 'cloudpit:read').ok, true);
|
|
182
182
|
assert.equal(readLastUsed(), new Date(START.getTime() + 61_000).toISOString());
|
|
183
183
|
});
|
|
184
184
|
});
|
|
@@ -190,7 +190,7 @@ test('(c) the five rejection paths yield five pairwise-distinct reasons', async
|
|
|
190
190
|
const results: VerifyAccessTokenResult[] = [];
|
|
191
191
|
|
|
192
192
|
await t.test('expired', () => {
|
|
193
|
-
const issued = service.issueToken({ userId, scopes: ['
|
|
193
|
+
const issued = service.issueToken({ userId, scopes: ['cloudpit:read'], expiresInDays: 7 });
|
|
194
194
|
assert.equal(issued.ok, true);
|
|
195
195
|
if (!issued.ok) return;
|
|
196
196
|
advanceTo(new Date(START.getTime() + 8 * MS_PER_DAY));
|
|
@@ -201,7 +201,7 @@ test('(c) the five rejection paths yield five pairwise-distinct reasons', async
|
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
await t.test('revoked', () => {
|
|
204
|
-
const issued = service.issueToken({ userId, scopes: ['
|
|
204
|
+
const issued = service.issueToken({ userId, scopes: ['cloudpit:read'] });
|
|
205
205
|
assert.equal(issued.ok, true);
|
|
206
206
|
if (!issued.ok) return;
|
|
207
207
|
assert.equal(service.revokeToken(issued.token.id), true);
|
|
@@ -211,7 +211,7 @@ test('(c) the five rejection paths yield five pairwise-distinct reasons', async
|
|
|
211
211
|
});
|
|
212
212
|
|
|
213
213
|
await t.test('rewritten plaintext is not found', () => {
|
|
214
|
-
const issued = service.issueToken({ userId, scopes: ['
|
|
214
|
+
const issued = service.issueToken({ userId, scopes: ['cloudpit:read'] });
|
|
215
215
|
assert.equal(issued.ok, true);
|
|
216
216
|
if (!issued.ok) return;
|
|
217
217
|
const rewritten =
|
|
@@ -228,7 +228,7 @@ test('(c) the five rejection paths yield five pairwise-distinct reasons', async
|
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
await t.test('insufficient scope', () => {
|
|
231
|
-
const issued = service.issueToken({ userId, scopes: ['
|
|
231
|
+
const issued = service.issueToken({ userId, scopes: ['cloudpit:read'] });
|
|
232
232
|
assert.equal(issued.ok, true);
|
|
233
233
|
if (!issued.ok) return;
|
|
234
234
|
const result = service.verifyToken(issued.token.token, 'cloudcli:admin');
|
|
@@ -247,14 +247,14 @@ test('(c) the five rejection paths yield five pairwise-distinct reasons', async
|
|
|
247
247
|
test('(d) only 7/30/90 day lifetimes are accepted; anything else writes no row', async () => {
|
|
248
248
|
await withAccessTokenDb(async ({ service, userId }) => {
|
|
249
249
|
for (const days of [7, 30, 90]) {
|
|
250
|
-
const result = service.issueToken({ userId, scopes: ['
|
|
250
|
+
const result = service.issueToken({ userId, scopes: ['cloudpit:read'], expiresInDays: days });
|
|
251
251
|
assert.equal(result.ok, true);
|
|
252
252
|
if (!result.ok) return;
|
|
253
253
|
assert.equal(result.token.expiresAt, new Date(START.getTime() + days * MS_PER_DAY).toISOString());
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
// Omitted lifetime defaults to 30 days.
|
|
257
|
-
const defaulted = service.issueToken({ userId, scopes: ['
|
|
257
|
+
const defaulted = service.issueToken({ userId, scopes: ['cloudpit:read'] });
|
|
258
258
|
assert.equal(defaulted.ok, true);
|
|
259
259
|
if (!defaulted.ok) return;
|
|
260
260
|
assert.equal(defaulted.token.expiresAt, new Date(START.getTime() + 30 * MS_PER_DAY).toISOString());
|
|
@@ -266,7 +266,7 @@ test('(d) only 7/30/90 day lifetimes are accepted; anything else writes no row',
|
|
|
266
266
|
const rejected: (number | null)[] = [null, Infinity, 0, -1, 365];
|
|
267
267
|
for (const days of rejected) {
|
|
268
268
|
assert.deepEqual(
|
|
269
|
-
service.issueToken({ userId, scopes: ['
|
|
269
|
+
service.issueToken({ userId, scopes: ['cloudpit:read'], expiresInDays: days }),
|
|
270
270
|
{ ok: false, reason: 'invalid_expiry' }
|
|
271
271
|
);
|
|
272
272
|
}
|
|
@@ -277,7 +277,7 @@ test('(d) only 7/30/90 day lifetimes are accepted; anything else writes no row',
|
|
|
277
277
|
|
|
278
278
|
test('(e) revocation takes effect on the next verify, same process, no restart', async () => {
|
|
279
279
|
await withAccessTokenDb(async ({ service, userId }) => {
|
|
280
|
-
const issued = service.issueToken({ userId, scopes: ['
|
|
280
|
+
const issued = service.issueToken({ userId, scopes: ['cloudpit:read'] });
|
|
281
281
|
assert.equal(issued.ok, true);
|
|
282
282
|
if (!issued.ok) return;
|
|
283
283
|
|
|
@@ -286,3 +286,39 @@ test('(e) revocation takes effect on the next verify, same process, no restart',
|
|
|
286
286
|
assert.deepEqual(service.verifyToken(issued.token.token), { ok: false, reason: 'revoked' });
|
|
287
287
|
});
|
|
288
288
|
});
|
|
289
|
+
|
|
290
|
+
test('(f) v3.0 refuses a legacy cloudcli:* request and still verifies a pre-3.0 token row', async () => {
|
|
291
|
+
await withAccessTokenDb(async ({ service, userId }) => {
|
|
292
|
+
// The retired spelling cannot mint a new token.
|
|
293
|
+
for (const scope of ['cloudcli:read', 'cloudcli:session:send', 'cloudcli:cockpit:act']) {
|
|
294
|
+
assert.deepEqual(
|
|
295
|
+
service.issueToken({ userId, scopes: [scope] }),
|
|
296
|
+
{ ok: false, reason: 'invalid_scope' },
|
|
297
|
+
`${scope} must be refused at the issue boundary`,
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// An old token row carries the canonical spelling. Seed one directly (the 2.x writer) and
|
|
302
|
+
// verify it still authenticates against the canonical required scope — no forced revocation.
|
|
303
|
+
const token = `ccp_${'a'.repeat(64)}`;
|
|
304
|
+
const hash = crypto.createHash('sha256').update(token).digest('hex');
|
|
305
|
+
getConnection()
|
|
306
|
+
.prepare(
|
|
307
|
+
`INSERT INTO access_tokens (user_id, token_hash, token_prefix, name, scopes, expires_at, created_at)
|
|
308
|
+
VALUES (?, ?, ?, 'legacy', ?, ?, ?)`,
|
|
309
|
+
)
|
|
310
|
+
.run(
|
|
311
|
+
userId,
|
|
312
|
+
hash,
|
|
313
|
+
token.slice(0, 8),
|
|
314
|
+
JSON.stringify(['cloudcli:read', 'cloudcli:session:send']),
|
|
315
|
+
new Date(START.getTime() + 30 * MS_PER_DAY).toISOString(),
|
|
316
|
+
START.toISOString(),
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
const verified = service.verifyToken(token, 'cloudcli:read');
|
|
320
|
+
assert.equal(verified.ok, true, 'an old token row keeps working');
|
|
321
|
+
if (!verified.ok) return;
|
|
322
|
+
assert.deepEqual(verified.scopes, ['cloudcli:read', 'cloudcli:session:send']);
|
|
323
|
+
});
|
|
324
|
+
});
|