@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
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem I/O for the project-owned Codex provider settings file and its per-provider
|
|
3
|
+
* secret files.
|
|
4
|
+
*
|
|
5
|
+
* WHY A FILE OF ITS OWN. `codex.settings.json` is the project's one writable surface for
|
|
6
|
+
* upstream Codex providers. The schema and validation live in
|
|
7
|
+
* `codex-model-providers.settings.ts`; this sibling owns only the bytes: resolving the
|
|
8
|
+
* path, hashing the content version a concurrent editor must send back, the atomic replace,
|
|
9
|
+
* and the `600` token files. Splitting the concern keeps both files under the module
|
|
10
|
+
* standard's line ceiling and lets a criterion drive the file layer without a route.
|
|
11
|
+
*
|
|
12
|
+
* THE PROJECT FILE IS THE ONLY WRITE TARGET. A user `~/.codex/config.toml` is never written:
|
|
13
|
+
* it is read-only compatibility, and an import binds into this project file instead.
|
|
14
|
+
*
|
|
15
|
+
* SECRETS NEVER ENTER THE JSON. `tokenFile` is a path. `readTokenSecret` is the only reader
|
|
16
|
+
* and its value is handed to a caller in memory; `writeTokenSecret` exists so the settings
|
|
17
|
+
* API can accept a secret without persisting it in the document. Every write here creates the
|
|
18
|
+
* file (or replaces it) with mode `600`.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from 'node:crypto';
|
|
21
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
22
|
+
import os from 'node:os';
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
expandHome,
|
|
27
|
+
resolveSettingsPath,
|
|
28
|
+
writeSettingsFileAtomically,
|
|
29
|
+
} from '@/shared/settings-file.js';
|
|
30
|
+
import { AppError, errorMessage, isRecord } from '@/shared/utils.js';
|
|
31
|
+
|
|
32
|
+
/** The only environment entry: it names the project Codex settings file. */
|
|
33
|
+
export const CODEX_SETTINGS_PATH_ENV = 'CODEX_SETTINGS_PATH';
|
|
34
|
+
|
|
35
|
+
/** The deployment's default location; a development checkout points the env entry at `config/`. */
|
|
36
|
+
export function defaultCodexSettingsPath(homeDir: string): string {
|
|
37
|
+
return path.join(homeDir, '.config', 'cloudpit', 'codex.settings.json');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The file this process reads and writes. `explicit` is true when an operator named it. */
|
|
41
|
+
export type CodexSettingsFileTarget = {
|
|
42
|
+
path: string;
|
|
43
|
+
explicit: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Resolves the Codex settings file: an explicit path, then `CODEX_SETTINGS_PATH`, then the
|
|
48
|
+
* shipped location. Consumers: the settings module (the production source) and the criterion.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveCodexSettingsFileTarget(
|
|
51
|
+
options: {
|
|
52
|
+
settingsPath?: string | null;
|
|
53
|
+
env?: Record<string, string | undefined>;
|
|
54
|
+
homeDir?: string | undefined;
|
|
55
|
+
} = {},
|
|
56
|
+
): CodexSettingsFileTarget {
|
|
57
|
+
const homeDir = options.homeDir ?? os.homedir();
|
|
58
|
+
const { filePath, explicit } = resolveSettingsPath({
|
|
59
|
+
settingsPath: options.settingsPath,
|
|
60
|
+
env: options.env ?? process.env,
|
|
61
|
+
envVar: CODEX_SETTINGS_PATH_ENV,
|
|
62
|
+
homeDir,
|
|
63
|
+
defaultPath: defaultCodexSettingsPath,
|
|
64
|
+
});
|
|
65
|
+
return { path: filePath ?? defaultCodexSettingsPath(homeDir), explicit };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The version reported for a file that does not exist yet (a first write creates it). */
|
|
69
|
+
export const MISSING_CODEX_SETTINGS_VERSION = 'missing';
|
|
70
|
+
|
|
71
|
+
/** One raw read: the parsed document, its content hash, and whether the file was present. */
|
|
72
|
+
export type CodexSettingsDocumentReading = {
|
|
73
|
+
document: Record<string, unknown>;
|
|
74
|
+
version: string;
|
|
75
|
+
exists: boolean;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** A content hash, so a stale editor can be told the file moved under it. */
|
|
79
|
+
function versionOf(text: string): string {
|
|
80
|
+
return createHash('sha256').update(text).digest('hex');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Reads the project file. A missing file is the ordinary "no providers yet" state; an
|
|
85
|
+
* unreadable or malformed one is a visible error, never silently treated as empty.
|
|
86
|
+
*
|
|
87
|
+
* Consumers: `codex-model-providers.settings.ts` (read, resolve and the version check).
|
|
88
|
+
*/
|
|
89
|
+
export function readCodexSettingsDocument(filePath: string): CodexSettingsDocumentReading {
|
|
90
|
+
let text: string;
|
|
91
|
+
try {
|
|
92
|
+
text = readFileSync(filePath, 'utf8');
|
|
93
|
+
} catch (failure) {
|
|
94
|
+
if ((failure as NodeJS.ErrnoException | null)?.code === 'ENOENT') {
|
|
95
|
+
return { document: {}, version: MISSING_CODEX_SETTINGS_VERSION, exists: false };
|
|
96
|
+
}
|
|
97
|
+
throw new AppError(`could not read ${filePath}: ${errorMessage(failure)}`, {
|
|
98
|
+
code: 'CODEX_SETTINGS_READ_FAILED',
|
|
99
|
+
statusCode: 500,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let parsed: unknown;
|
|
104
|
+
try {
|
|
105
|
+
parsed = JSON.parse(text);
|
|
106
|
+
} catch (failure) {
|
|
107
|
+
throw new AppError(`${filePath} is not valid JSON: ${errorMessage(failure)}`, {
|
|
108
|
+
code: 'CODEX_SETTINGS_INVALID_JSON',
|
|
109
|
+
statusCode: 500,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (!isRecord(parsed)) {
|
|
113
|
+
throw new AppError(`${filePath} must contain a JSON object`, {
|
|
114
|
+
code: 'CODEX_SETTINGS_INVALID_JSON',
|
|
115
|
+
statusCode: 500,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return { document: parsed, version: versionOf(text), exists: true };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Replaces the project file with `document` after proving the caller edited the version it
|
|
123
|
+
* read. The replace is atomic and always mode `600`, even when the previous file was wider,
|
|
124
|
+
* because this document describes credentials (paths and env names) and the task's contract
|
|
125
|
+
* is a 0600 project file.
|
|
126
|
+
*
|
|
127
|
+
* Consumers: `codex-model-providers.settings.ts`'s write path.
|
|
128
|
+
*/
|
|
129
|
+
export function writeCodexSettingsDocument(
|
|
130
|
+
filePath: string,
|
|
131
|
+
document: Record<string, unknown>,
|
|
132
|
+
options: { expectedVersion: string; versionPath?: string | undefined },
|
|
133
|
+
): { version: string } {
|
|
134
|
+
const sourcePath = options.versionPath ?? filePath;
|
|
135
|
+
const current = readCodexSettingsDocument(sourcePath);
|
|
136
|
+
if (current.version !== options.expectedVersion) {
|
|
137
|
+
throw new AppError('The Codex provider settings changed since they were read; reload and save again.', {
|
|
138
|
+
code: 'VERSION_CONFLICT',
|
|
139
|
+
statusCode: 409,
|
|
140
|
+
details: { expectedVersion: options.expectedVersion, currentVersion: current.version },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const serialized = `${JSON.stringify(document, null, 2)}\n`;
|
|
145
|
+
try {
|
|
146
|
+
writeSettingsFileAtomically(filePath, serialized, { mode: 0o600 });
|
|
147
|
+
} catch (failure) {
|
|
148
|
+
throw new AppError(`could not write ${filePath}: ${errorMessage(failure)}`, {
|
|
149
|
+
code: 'CODEX_SETTINGS_WRITE_FAILED',
|
|
150
|
+
statusCode: 500,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return { version: versionOf(serialized) };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Resolves a provider's secret path. An operator-written `tokenFile` wins (a leading `~` is
|
|
158
|
+
* expanded and a relative path is resolved against the settings file's directory); otherwise
|
|
159
|
+
* every provider gets its own file under `<settings dir>/codex.secrets/<id>.token`.
|
|
160
|
+
*
|
|
161
|
+
* Consumers: `codex-model-providers.settings.ts`'s read/resolve/write paths.
|
|
162
|
+
*/
|
|
163
|
+
export function resolveCodexTokenFilePath(
|
|
164
|
+
settingsPath: string,
|
|
165
|
+
providerId: string,
|
|
166
|
+
rawTokenFile: string,
|
|
167
|
+
homeDir: string,
|
|
168
|
+
): string {
|
|
169
|
+
const trimmed = rawTokenFile.trim();
|
|
170
|
+
if (trimmed !== '') {
|
|
171
|
+
const expanded = expandHome(trimmed, homeDir);
|
|
172
|
+
return path.isAbsolute(expanded)
|
|
173
|
+
? expanded
|
|
174
|
+
: path.resolve(path.dirname(settingsPath), expanded);
|
|
175
|
+
}
|
|
176
|
+
return path.join(path.dirname(settingsPath), 'codex.secrets', `${providerId}.token`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** What one secret-file read observed: the value, or a line naming why it is unusable. */
|
|
180
|
+
export type CodexTokenSecretReading =
|
|
181
|
+
| { ok: true; secret: string }
|
|
182
|
+
| { ok: false; problem: string };
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Reads one `600` token file. A missing or empty file is a readable "no secret" answer, not a
|
|
186
|
+
* throw: the runtime must be able to say why a provider cannot launch. The value never
|
|
187
|
+
* appears in the returned text.
|
|
188
|
+
*
|
|
189
|
+
* Consumers: `codex-model-providers.settings.ts`'s `read`/`resolve`.
|
|
190
|
+
*/
|
|
191
|
+
export function readCodexTokenSecret(tokenFile: string): CodexTokenSecretReading {
|
|
192
|
+
let secret: string;
|
|
193
|
+
try {
|
|
194
|
+
secret = readFileSync(tokenFile, 'utf8').trim();
|
|
195
|
+
} catch (failure) {
|
|
196
|
+
const code = (failure as NodeJS.ErrnoException | null)?.code;
|
|
197
|
+
return {
|
|
198
|
+
ok: false,
|
|
199
|
+
problem: code === 'ENOENT'
|
|
200
|
+
? `token file ${tokenFile} is missing`
|
|
201
|
+
: `could not read token file ${tokenFile}: ${errorMessage(failure)}`,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (secret === '') {
|
|
205
|
+
return { ok: false, problem: `token file ${tokenFile} is empty` };
|
|
206
|
+
}
|
|
207
|
+
return { ok: true, secret };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Writes a secret into its token file, atomically and mode `600`. Used only when the settings
|
|
212
|
+
* API is handed a write-only `token`; the value is never placed in the project document.
|
|
213
|
+
*
|
|
214
|
+
* Consumers: `codex-model-providers.settings.ts`'s write path.
|
|
215
|
+
*/
|
|
216
|
+
export function writeCodexTokenSecret(tokenFile: string, secret: string): void {
|
|
217
|
+
try {
|
|
218
|
+
writeSettingsFileAtomically(tokenFile, secret, { mode: 0o600 });
|
|
219
|
+
} catch (failure) {
|
|
220
|
+
throw new AppError(`could not write token file ${tokenFile}: ${errorMessage(failure)}`, {
|
|
221
|
+
code: 'CODEX_TOKEN_WRITE_FAILED',
|
|
222
|
+
statusCode: 500,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Reports (never throws) whether a token file is wider than `600`. The runtime tolerates a
|
|
229
|
+
* wide file — refusing it would turn a permissions typo into a dead provider — but the reading
|
|
230
|
+
* names the problem so an operator can fix it.
|
|
231
|
+
*
|
|
232
|
+
* Consumers: `codex-model-providers.settings.ts` (per-provider warnings).
|
|
233
|
+
*/
|
|
234
|
+
export function tokenFileModeWarning(tokenFile: string): string | null {
|
|
235
|
+
try {
|
|
236
|
+
const mode = statSync(tokenFile).mode & 0o777;
|
|
237
|
+
if ((mode & 0o077) !== 0) {
|
|
238
|
+
return `token file ${tokenFile} has mode ${mode.toString(8)}; 600 is expected because it holds a secret`;
|
|
239
|
+
}
|
|
240
|
+
} catch {
|
|
241
|
+
// The read path already reports a missing file with its own, more useful message.
|
|
242
|
+
}
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
@@ -42,6 +42,24 @@ export type {
|
|
|
42
42
|
ServerSettings,
|
|
43
43
|
} from './server-settings.js';
|
|
44
44
|
export type { CodexMcpGatewaySettings } from './codex-mcp-gateway.settings.js';
|
|
45
|
+
// createCodexModelProvidersSource / CodexModelProvidersSource: the project-owned Codex upstream
|
|
46
|
+
// provider registry (`~/.config/cloudpit/codex.settings.json`). The settings API writes through
|
|
47
|
+
// the one instance `settings.module.ts` owns; the resident/per-run Codex injection tasks create
|
|
48
|
+
// their own source over the same file and call `resolve(id)` AT SPAWN TIME (reads are uncached),
|
|
49
|
+
// so an edit reaches the next launch without a restart.
|
|
50
|
+
export {
|
|
51
|
+
createCodexModelProvidersSource,
|
|
52
|
+
type CodexModelProviderResolution,
|
|
53
|
+
type CodexModelProvidersSource,
|
|
54
|
+
type ResolvedCodexModelProvider,
|
|
55
|
+
} from './codex-model-providers.settings.js';
|
|
56
|
+
// The registry's own vocabulary, exported so a sibling task names the same reserved ids and the
|
|
57
|
+
// same one accepted wire dialect instead of restating them.
|
|
58
|
+
export {
|
|
59
|
+
CODEX_PROVIDER_WIRE_API,
|
|
60
|
+
RESERVED_CODEX_PROVIDER_IDS,
|
|
61
|
+
} from './codex-model-providers.schema.js';
|
|
62
|
+
export { CODEX_SETTINGS_PATH_ENV } from './codex-model-providers.store.js';
|
|
45
63
|
// readCockpitSessionStartBoot / resolveServerSettingsFileTarget: the dual read/write target the
|
|
46
64
|
// cockpit session-start settings use when the legacy file is the source. Exported so the
|
|
47
65
|
// Cloudpit runtime criterion can drive the legacy-read → Cloudpit-write contract over a temp home.
|
|
@@ -21,22 +21,15 @@
|
|
|
21
21
|
* top-level key and every other `cockpit`/`sessionStart` field, and committed by writing a
|
|
22
22
|
* sibling temp file and renaming it over the target, so a reader never observes a half file.
|
|
23
23
|
*/
|
|
24
|
-
import { createHash
|
|
25
|
-
import {
|
|
26
|
-
existsSync,
|
|
27
|
-
mkdirSync,
|
|
28
|
-
readFileSync,
|
|
29
|
-
renameSync,
|
|
30
|
-
rmSync,
|
|
31
|
-
statSync,
|
|
32
|
-
writeFileSync,
|
|
33
|
-
} from 'node:fs';
|
|
24
|
+
import { createHash } from 'node:crypto';
|
|
25
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
34
26
|
import { homedir } from 'node:os';
|
|
35
|
-
import path from 'node:path';
|
|
36
27
|
|
|
37
28
|
import {
|
|
38
29
|
defaultServerSettingsPath as defaultServerSettingsPathForHome,
|
|
39
30
|
legacyServerSettingsPath,
|
|
31
|
+
migrateLegacyServerSettingsFile,
|
|
32
|
+
writeSettingsFileAtomically,
|
|
40
33
|
} from '@/shared/settings-file.js';
|
|
41
34
|
import { AppError, errorMessage, isRecord } from '@/shared/utils.js';
|
|
42
35
|
|
|
@@ -67,10 +60,11 @@ export function defaultServerSettingsPath(): string {
|
|
|
67
60
|
* Resolves the file the boot reader and the settings API share. Same order as
|
|
68
61
|
* `loadServerSettings`: an explicit path > `SERVER_SETTINGS_PATH` > the shipped location.
|
|
69
62
|
*
|
|
70
|
-
* The shipped location is
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
63
|
+
* The shipped location is `<home>/.config/cloudpit/server.settings.json`. v3.0 deleted the
|
|
64
|
+
* runtime read fallback to `<home>/.config/claudecodeui/server.settings.json`: on the first
|
|
65
|
+
* resolution the legacy file is COPIED to the Cloudpit path once (never overwriting an existing
|
|
66
|
+
* Cloudpit file), and every read afterwards uses only the Cloudpit file. `path` and `writePath`
|
|
67
|
+
* are therefore always the same for the default target, and a save lands in the new tree.
|
|
74
68
|
*
|
|
75
69
|
* Consumers: `server-settings.ts` (the boot read) and `settings.module.ts` (the API's target).
|
|
76
70
|
*/
|
|
@@ -78,7 +72,6 @@ export function resolveServerSettingsFileTarget(options: {
|
|
|
78
72
|
settingsPath?: string | undefined;
|
|
79
73
|
env?: Record<string, string | undefined>;
|
|
80
74
|
defaultPath?: string | undefined;
|
|
81
|
-
legacyDefaultPath?: string | undefined;
|
|
82
75
|
homeDir?: string | undefined;
|
|
83
76
|
exists?: ((filePath: string) => boolean) | undefined;
|
|
84
77
|
} = {}): ServerSettingsFileTarget {
|
|
@@ -93,12 +86,19 @@ export function resolveServerSettingsFileTarget(options: {
|
|
|
93
86
|
}
|
|
94
87
|
|
|
95
88
|
const defaultPath = options.defaultPath ?? defaultServerSettingsPathForHome(homeDir);
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
// One-time upgrade aid: copy the pre-flip file into the Cloudpit tree when the latter is
|
|
90
|
+
// absent. The legacy file is never read again after this and is left on disk.
|
|
91
|
+
// An INJECTED defaultPath marks a hermetic caller (the criteria drive an arbitrary temp file);
|
|
92
|
+
// it must not consult the process HOME behind its back, so migration runs only for the shipped
|
|
93
|
+
// default derived from `homeDir`.
|
|
94
|
+
if (options.defaultPath === undefined) {
|
|
95
|
+
migrateLegacyServerSettingsFile({
|
|
96
|
+
legacyPath: legacyServerSettingsPath(homeDir),
|
|
97
|
+
targetPath: defaultPath,
|
|
98
|
+
exists,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return { path: defaultPath, writePath: defaultPath, explicit: false };
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
@@ -293,30 +293,18 @@ function createSerialQueue(): { run<T>(operation: () => T): Promise<T> } {
|
|
|
293
293
|
|
|
294
294
|
const cockpitSessionStartWrites = createSerialQueue();
|
|
295
295
|
|
|
296
|
-
/**
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
`.${path.basename(filePath)}.${process.pid}.${randomUUID()}.tmp`,
|
|
302
|
-
);
|
|
296
|
+
/**
|
|
297
|
+
* Writes the document through the shared atomic replace, wrapping a filesystem failure in this
|
|
298
|
+
* module's own error code. An existing file keeps its mode; a new one is created `0600`.
|
|
299
|
+
*/
|
|
300
|
+
function writeAtomically(filePath: string, contents: string): void {
|
|
303
301
|
try {
|
|
304
|
-
|
|
305
|
-
const mode = replacing ? statSync(filePath).mode & 0o777 : 0o600;
|
|
306
|
-
writeFileSync(temporary, contents, { encoding: 'utf8', mode });
|
|
307
|
-
renameSync(temporary, filePath);
|
|
302
|
+
writeSettingsFileAtomically(filePath, contents);
|
|
308
303
|
} catch (failure) {
|
|
309
304
|
throw new AppError(`could not write ${filePath}: ${errorMessage(failure)}`, {
|
|
310
305
|
code: 'SERVER_SETTINGS_WRITE_FAILED',
|
|
311
306
|
statusCode: 500,
|
|
312
307
|
});
|
|
313
|
-
} finally {
|
|
314
|
-
// The rename consumed the temp name on success; this removes it only after a failed write.
|
|
315
|
-
try {
|
|
316
|
-
rmSync(temporary, { force: true });
|
|
317
|
-
} catch {
|
|
318
|
-
// A leftover temp file is not a reason to hide the write's own error.
|
|
319
|
-
}
|
|
320
308
|
}
|
|
321
309
|
}
|
|
322
310
|
|
|
@@ -377,7 +365,7 @@ export function writeCockpitSessionStart(
|
|
|
377
365
|
document.cockpit = cockpit;
|
|
378
366
|
|
|
379
367
|
const serialized = `${JSON.stringify(document, null, 2)}\n`;
|
|
380
|
-
writeAtomically(filePath, serialized
|
|
368
|
+
writeAtomically(filePath, serialized);
|
|
381
369
|
return { path: filePath, ...savedFieldsOf(document), version: versionOf(serialized) };
|
|
382
370
|
});
|
|
383
371
|
}
|
|
@@ -303,7 +303,6 @@ type ServerSettingsFileOptions = {
|
|
|
303
303
|
settingsPath?: string | undefined;
|
|
304
304
|
env?: Record<string, string | undefined>;
|
|
305
305
|
defaultPath?: string | undefined;
|
|
306
|
-
legacyDefaultPath?: string | undefined;
|
|
307
306
|
homeDir?: string | undefined;
|
|
308
307
|
exists?: ((filePath: string) => boolean) | undefined;
|
|
309
308
|
};
|
|
@@ -312,8 +311,8 @@ export function loadServerSettings(options: ServerSettingsFileOptions = {}): Ser
|
|
|
312
311
|
const target = resolveServerSettingsFileTarget(options);
|
|
313
312
|
const reading = readServerSettings(options, target);
|
|
314
313
|
// The ONE boot read becomes the "currently in effect" reading the settings API reports, so
|
|
315
|
-
// the surface and the card `session.start` executor cannot disagree about this process
|
|
316
|
-
//
|
|
314
|
+
// the surface and the card `session.start` executor cannot disagree about this process.
|
|
315
|
+
// v3.0 removed the legacy read fallback, so `path` and `writePath` are the same default file.
|
|
317
316
|
recordCockpitSessionStartBoot(reading.path, reading.cockpit.sessionStart, target.writePath);
|
|
318
317
|
return reading;
|
|
319
318
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
accessTokensDb,
|
|
3
5
|
credentialsDb,
|
|
@@ -18,9 +20,15 @@ import {
|
|
|
18
20
|
notifyUserIfEnabled,
|
|
19
21
|
} from '@/modules/notifications/index.js';
|
|
20
22
|
import { createAccessTokensService } from '@/modules/oauth/index.js';
|
|
23
|
+
import { installCodexProviderRegistryPort } from '@/shared/ports/codex-provider-registry.port.js';
|
|
21
24
|
|
|
22
25
|
import { createSettingsRouter } from './settings.routes.js';
|
|
23
26
|
import { createSettingsService } from './settings.service.js';
|
|
27
|
+
import { RESERVED_CODEX_PROVIDER_IDS } from './codex-model-providers.schema.js';
|
|
28
|
+
import {
|
|
29
|
+
createCodexModelProvidersSource,
|
|
30
|
+
readCodexUserProviderImports,
|
|
31
|
+
} from './codex-model-providers.settings.js';
|
|
24
32
|
import { DEFAULT_COCKPIT_SESSION_START_MODEL } from './server-settings.js';
|
|
25
33
|
import {
|
|
26
34
|
readCockpitSessionStart,
|
|
@@ -31,6 +39,32 @@ import {
|
|
|
31
39
|
|
|
32
40
|
const accessTokensService = createAccessTokensService({ now: () => new Date() });
|
|
33
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The project-owned Codex provider registry. One instance owns the file path and the write
|
|
44
|
+
* queue; the settings API writes through it and the Codex injection tasks create their own
|
|
45
|
+
* source over the same file (reads are uncached, so both see the latest edit).
|
|
46
|
+
*/
|
|
47
|
+
const codexModelProvidersSource = createCodexModelProvidersSource();
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The providers module refuses a model entry's `codexProviderId` unless it names a provider this
|
|
51
|
+
* registry (or Codex's built-in list) knows. It reads that judgement through a shared port rather
|
|
52
|
+
* than importing this module: `providers -> settings` would close the `providers -> settings ->
|
|
53
|
+
* mcp-gateway -> providers` cycle AC-394 pins. Reads are uncached, so a provider saved through
|
|
54
|
+
* the settings API is visible to the very next model write.
|
|
55
|
+
*
|
|
56
|
+
* The same install carries `resolve`, the spawn-time lookup a per-run/resident Codex injection
|
|
57
|
+
* uses to read the endpoint and the token-file secret. It resolves against the live file on every
|
|
58
|
+
* call, so an edit reaches the next launch without a restart.
|
|
59
|
+
*/
|
|
60
|
+
installCodexProviderRegistryPort({
|
|
61
|
+
read: () => ({
|
|
62
|
+
providers: codexModelProvidersSource.read().providers.map((provider) => ({ id: provider.id })),
|
|
63
|
+
reservedIds: RESERVED_CODEX_PROVIDER_IDS,
|
|
64
|
+
}),
|
|
65
|
+
resolve: (id) => codexModelProvidersSource.resolve(id),
|
|
66
|
+
});
|
|
67
|
+
|
|
34
68
|
/**
|
|
35
69
|
* The two files the cockpit settings page works with: the one THIS boot read, and the one a save
|
|
36
70
|
* must write. They differ only when the boot read fell back to the legacy settings file — the
|
|
@@ -176,6 +210,13 @@ const settingsService = createSettingsService({
|
|
|
176
210
|
return boot === null ? null : { model: boot.model, effort: boot.effort };
|
|
177
211
|
},
|
|
178
212
|
},
|
|
213
|
+
codexModelProviders: {
|
|
214
|
+
read: () => codexModelProvidersSource.read(),
|
|
215
|
+
write: (input) => codexModelProvidersSource.write(input),
|
|
216
|
+
// The composition root decides WHOSE profile is imported: this process's operator. The read
|
|
217
|
+
// is one-way (the user's TOML files are never written); the bind goes to the project source.
|
|
218
|
+
readUserImports: () => readCodexUserProviderImports({ homeDir: os.homedir(), env: process.env }),
|
|
219
|
+
},
|
|
179
220
|
});
|
|
180
221
|
|
|
181
222
|
/** Settings router assembled for the authenticated server mount. */
|
|
@@ -100,5 +100,42 @@ export function createSettingsRouter(
|
|
|
100
100
|
};
|
|
101
101
|
router.put('/cockpit/session-start', writeCockpitSessionStart(false));
|
|
102
102
|
router.patch('/cockpit/session-start', writeCockpitSessionStart(true));
|
|
103
|
+
|
|
104
|
+
// The project-owned Codex upstream provider registry. GET reports each provider's fields and
|
|
105
|
+
// only whether its token file holds a secret (`tokenSet`); PUT is a full replacement guarded by
|
|
106
|
+
// the content hash it was based on (`expectedVersion` in the body, or `If-Match`), so a second
|
|
107
|
+
// editor's stale save is a 409 rather than a silent overwrite.
|
|
108
|
+
//
|
|
109
|
+
// The user-profile import lives at a sub-path: GET only READS the operator's `~/.codex` TOML
|
|
110
|
+
// blocks (never a secret value), and POST binds the named rows into the project file, carrying
|
|
111
|
+
// the same version proof as a save so a stale bind cannot overwrite a newer registry.
|
|
112
|
+
router.get('/codex/model-providers/import', respond(() => service.getCodexUserProviderImports()));
|
|
113
|
+
router.post('/codex/model-providers/import', async (req, res, next) => {
|
|
114
|
+
try {
|
|
115
|
+
const header = req.get('if-match');
|
|
116
|
+
const headerVersion = header === undefined
|
|
117
|
+
? undefined
|
|
118
|
+
: header.replace(/^W\//, '').replace(/^"|"$/g, '');
|
|
119
|
+
const reading = await service.importCodexUserProviders({
|
|
120
|
+
body: req.body,
|
|
121
|
+
headerVersion,
|
|
122
|
+
});
|
|
123
|
+
res.status(200).set('ETag', `"${reading.version}"`).json(reading);
|
|
124
|
+
} catch (error) { next(error); }
|
|
125
|
+
});
|
|
126
|
+
router.get('/codex/model-providers', respond(() => service.getCodexModelProviders()));
|
|
127
|
+
router.put('/codex/model-providers', async (req, res, next) => {
|
|
128
|
+
try {
|
|
129
|
+
const header = req.get('if-match');
|
|
130
|
+
const headerVersion = header === undefined
|
|
131
|
+
? undefined
|
|
132
|
+
: header.replace(/^W\//, '').replace(/^"|"$/g, '');
|
|
133
|
+
const reading = await service.updateCodexModelProviders({
|
|
134
|
+
body: req.body,
|
|
135
|
+
headerVersion,
|
|
136
|
+
});
|
|
137
|
+
res.status(200).set('ETag', `"${reading.version}"`).json(reading);
|
|
138
|
+
} catch (error) { next(error); }
|
|
139
|
+
});
|
|
103
140
|
return router;
|
|
104
141
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { McpAuditRouteEntry, McpGatewayGateReading } from '@/modules/mcp-gateway/index.js';
|
|
2
2
|
import { normalizeAccessTokenScopes } from '@/modules/oauth/index.js';
|
|
3
|
+
import { readExpectedVersion } from '@/shared/settings-file.js';
|
|
3
4
|
import { AppError } from '@/shared/utils.js';
|
|
4
5
|
|
|
6
|
+
import {
|
|
7
|
+
createCodexModelProvidersOperations,
|
|
8
|
+
type CodexModelProvidersPort,
|
|
9
|
+
} from './codex-model-providers.service.js';
|
|
10
|
+
|
|
5
11
|
type NotificationPreferences = Record<string, unknown> & {
|
|
6
12
|
channels?: Record<string, unknown> & { webPush?: boolean };
|
|
7
13
|
};
|
|
@@ -133,7 +139,7 @@ type SettingsDependencies = {
|
|
|
133
139
|
list(userId: number): StoredOAuthToken[];
|
|
134
140
|
};
|
|
135
141
|
/**
|
|
136
|
-
* The read-only seams the Settings → API page's
|
|
142
|
+
* The read-only seams the Settings → API page's Cloudpit MCP block needs.
|
|
137
143
|
*
|
|
138
144
|
* Optional so the existing service criteria keep constructing the dependency
|
|
139
145
|
* object they always have; the module always supplies it (see
|
|
@@ -167,6 +173,14 @@ type SettingsDependencies = {
|
|
|
167
173
|
* model with the shipped default, so this module never restates it.
|
|
168
174
|
*/
|
|
169
175
|
cockpitSessionStart?: CockpitSessionStartPort;
|
|
176
|
+
/**
|
|
177
|
+
* The project-owned Codex provider registry (Settings → Agents → Codex).
|
|
178
|
+
*
|
|
179
|
+
* Optional so the existing service criteria keep constructing the dependency object they
|
|
180
|
+
* always have; `settings.module.ts` always supplies it. The operations live in a sibling
|
|
181
|
+
* file so this assembled service does not grow the registry's file and transport rules.
|
|
182
|
+
*/
|
|
183
|
+
codexModelProviders?: CodexModelProvidersPort;
|
|
170
184
|
};
|
|
171
185
|
|
|
172
186
|
/** The only lifetimes a personal access token may request, in days. */
|
|
@@ -176,7 +190,7 @@ const ALLOWED_TOKEN_EXPIRY_DAYS: readonly number[] = [7, 30, 90];
|
|
|
176
190
|
const DEFAULT_TOKEN_EXPIRY_DAYS = 30;
|
|
177
191
|
|
|
178
192
|
/** Scopes applied when the caller omits them; the read scope is the required baseline. */
|
|
179
|
-
const DEFAULT_TOKEN_SCOPES: readonly string[] = ['
|
|
193
|
+
const DEFAULT_TOKEN_SCOPES: readonly string[] = ['cloudpit:read'];
|
|
180
194
|
|
|
181
195
|
/**
|
|
182
196
|
* Projects a stored row to the client-facing token shape. Written as an
|
|
@@ -298,31 +312,12 @@ function readCockpitSessionStartEffort(value: unknown): string {
|
|
|
298
312
|
return value.trim();
|
|
299
313
|
}
|
|
300
314
|
|
|
301
|
-
/** The version the edit was based on: the body's `expectedVersion`, else the `If-Match` header. */
|
|
302
|
-
function readCockpitSessionStartVersion(
|
|
303
|
-
body: Record<string, unknown>,
|
|
304
|
-
headerVersion: string | undefined,
|
|
305
|
-
): string {
|
|
306
|
-
if (body.expectedVersion !== undefined && typeof body.expectedVersion !== 'string') {
|
|
307
|
-
throw new AppError('expectedVersion must be a string', {
|
|
308
|
-
code: 'INVALID_VERSION',
|
|
309
|
-
statusCode: 400,
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
const fromBody = typeof body.expectedVersion === 'string' ? body.expectedVersion.trim() : '';
|
|
313
|
-
const version = fromBody || (headerVersion ?? '').trim();
|
|
314
|
-
if (!version) {
|
|
315
|
-
throw new AppError('expectedVersion is required to save', {
|
|
316
|
-
code: 'VERSION_REQUIRED',
|
|
317
|
-
statusCode: 400,
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
return version;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
315
|
/** Creates settings workflows with repositories and notification effects injected. */
|
|
324
316
|
export function createSettingsService(dependencies: SettingsDependencies) {
|
|
325
317
|
return {
|
|
318
|
+
// The Codex provider registry's two endpoints are a distinct file-backed concern; they are
|
|
319
|
+
// composed here so `settings.module.ts` still builds one service.
|
|
320
|
+
...createCodexModelProvidersOperations(dependencies.codexModelProviders),
|
|
326
321
|
listCredentials(userId: number, credentialType: string | null) {
|
|
327
322
|
return { credentials: dependencies.credentials.list(userId, credentialType) };
|
|
328
323
|
},
|
|
@@ -459,7 +454,7 @@ export function createSettingsService(dependencies: SettingsDependencies) {
|
|
|
459
454
|
return { success: true };
|
|
460
455
|
},
|
|
461
456
|
/**
|
|
462
|
-
* The Settings → API page's
|
|
457
|
+
* The Settings → API page's Cloudpit MCP block: whether the gateway is
|
|
463
458
|
* enabled, the path it answers on, and the base url an MCP client should
|
|
464
459
|
* dial. The gate is read through the mcp-gateway module (the single place
|
|
465
460
|
* `MCP_ENABLED` is parsed) rather than re-derived here.
|
|
@@ -545,7 +540,7 @@ export function createSettingsService(dependencies: SettingsDependencies) {
|
|
|
545
540
|
});
|
|
546
541
|
}
|
|
547
542
|
|
|
548
|
-
const expectedVersion =
|
|
543
|
+
const expectedVersion = readExpectedVersion(body, input.headerVersion);
|
|
549
544
|
const saved = await port.write({
|
|
550
545
|
model,
|
|
551
546
|
effort: input.partial ? effort : (effort ?? ''),
|
|
@@ -318,6 +318,7 @@ test('AC1: real auth rejects anonymous and invalid callers; the GET is an allowl
|
|
|
318
318
|
{ label: 'non-string model', reply: await harness.put({ model: 42, expectedVersion: version }), code: 'INVALID_MODEL' },
|
|
319
319
|
{ label: 'non-string effort', reply: await harness.patch({ effort: 5, expectedVersion: version }), code: 'INVALID_EFFORT' },
|
|
320
320
|
{ label: 'missing version', reply: await harness.put({ model: 'x' }), code: 'VERSION_REQUIRED' },
|
|
321
|
+
{ label: 'non-string version', reply: await harness.put({ model: 'x', expectedVersion: 42 }), code: 'INVALID_VERSION' },
|
|
321
322
|
{ label: 'PUT without a model', reply: await harness.put({ effort: 'high', expectedVersion: version }), code: 'MODEL_REQUIRED' },
|
|
322
323
|
{ label: 'empty PATCH', reply: await harness.patch({ expectedVersion: version }), code: 'NOTHING_TO_UPDATE' },
|
|
323
324
|
];
|