@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,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resident Codex provider injection (AC-463).
|
|
3
|
+
*
|
|
4
|
+
* The resident path spawned `codex app-server` with the driver-wide launch, so a
|
|
5
|
+
* session whose model was bound to a project upstream provider still ran under
|
|
6
|
+
* Codex's process-global `openai` provider. Codex 0.166 does not accept the
|
|
7
|
+
* binding at `thread/start` — it starts the thread and then refuses the first
|
|
8
|
+
* `turn/start` with `modelProviderMismatch` — so the provider has to be compiled
|
|
9
|
+
* into the app-server's spawn arguments.
|
|
10
|
+
*
|
|
11
|
+
* WHAT THIS FILE PINS, all against the REAL bundled `@openai/codex` 0.166.0
|
|
12
|
+
* app-server and a local mock Responses API (no injected transport):
|
|
13
|
+
*
|
|
14
|
+
* - POSITIVE: a session whose launch bag names `modelProviderId` spawns the
|
|
15
|
+
* app-server with `-c model_provider` + `-c model_providers.<id>={...}`; the
|
|
16
|
+
* turn reaches the mock's `/v1/responses` with `Authorization: Bearer
|
|
17
|
+
* <token-file secret>`.
|
|
18
|
+
* - ISOLATION: a host sentinel in `process.env` is absent from the child
|
|
19
|
+
* environment, and the secret appears in neither the child's argv nor any
|
|
20
|
+
* process table — it travels only under the provider's `env_key`.
|
|
21
|
+
* - NEGATIVE CONTROL: the same custom provider named ONLY on `thread/start`
|
|
22
|
+
* (the shape the old code could have been tempted into) makes the turn fail
|
|
23
|
+
* with the server's own "uses bob, but your current provider is openai"
|
|
24
|
+
* refusal and never reaches the mock.
|
|
25
|
+
* - RESUME: a restarted host re-injects the same provider id and resumes the
|
|
26
|
+
* SAME thread id under it. Without the recorded id the resume surfaces the
|
|
27
|
+
* server's `modelProviderNotConfigured` sentence instead of falling back.
|
|
28
|
+
* - RESTORE WIRING: the production `defaultResidentLaunchOptions` reads the
|
|
29
|
+
* session row's `model_provider_id` into the launch bag the restore pass
|
|
30
|
+
* hands `startResidentSession`.
|
|
31
|
+
*/
|
|
32
|
+
import assert from 'node:assert/strict';
|
|
33
|
+
import { readFile, readdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
34
|
+
import http from 'node:http';
|
|
35
|
+
import type { AddressInfo } from 'node:net';
|
|
36
|
+
import os from 'node:os';
|
|
37
|
+
import path from 'node:path';
|
|
38
|
+
import test, { after, before } from 'node:test';
|
|
39
|
+
|
|
40
|
+
import { closeConnection, initializeDatabase, sessionsDb } from '@/modules/database/index.js';
|
|
41
|
+
import { CodexAppServerConnection } from '@/modules/providers/list/codex/codex-app-server.connection.js';
|
|
42
|
+
import {
|
|
43
|
+
CodexHostDriver,
|
|
44
|
+
type CodexResidentHostPort,
|
|
45
|
+
} from '@/modules/providers/list/codex/codex-host-driver.provider.js';
|
|
46
|
+
import { providerRuntimeService } from '@/modules/providers/services/provider-runtime.service.js';
|
|
47
|
+
import { createCodexModelProvidersSource } from '@/modules/settings/index.js';
|
|
48
|
+
import type { IProvider, IProviderHostDriver, IProviderHostDriverSink } from '@/shared/interfaces.js';
|
|
49
|
+
import { installCodexProviderRegistryPort } from '@/shared/ports/codex-provider-registry.port.js';
|
|
50
|
+
import { installProviderRegistryPort } from '@/shared/ports/provider-registry.port.js';
|
|
51
|
+
import type {
|
|
52
|
+
HostResidentLaunch,
|
|
53
|
+
HostTurnInput,
|
|
54
|
+
LLMProvider,
|
|
55
|
+
ProcessHost,
|
|
56
|
+
ProviderRuntimeContext,
|
|
57
|
+
ProviderRuntimeWriter,
|
|
58
|
+
SessionBinding,
|
|
59
|
+
} from '@/shared/types.js';
|
|
60
|
+
|
|
61
|
+
const HOST_SENTINEL_KEY = 'CC_CODEX_HOST_SENTINEL';
|
|
62
|
+
const HOST_SENTINEL_VALUE = 'host-secret-that-must-not-reach-the-child';
|
|
63
|
+
const PROVIDER_ID = 'bob';
|
|
64
|
+
const ENV_KEY = 'BOB_API_KEY';
|
|
65
|
+
const TOKEN_SECRET = 'token-file-secret-4242';
|
|
66
|
+
const APP_SESSION = 'codex-resident-injection';
|
|
67
|
+
const MODEL = 'custom-model';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* An isolated database for the whole file.
|
|
71
|
+
*
|
|
72
|
+
* The resident turn relay links streamed frames to a session row, so a real
|
|
73
|
+
* app-server run reads `sessionsDb` even though these criteria never ask it to.
|
|
74
|
+
* Pointing the process at a private database keeps that read off the operator's
|
|
75
|
+
* `~/.cloudcli/auth.db` (and off a sibling criterion's fixture).
|
|
76
|
+
*/
|
|
77
|
+
const DATABASE_DIRECTORY = path.join(
|
|
78
|
+
os.tmpdir(),
|
|
79
|
+
`codex-resident-injection-db-${process.pid}-${Date.now()}`,
|
|
80
|
+
);
|
|
81
|
+
before(async () => {
|
|
82
|
+
process.env.DATABASE_PATH = path.join(DATABASE_DIRECTORY, 'auth.db');
|
|
83
|
+
await initializeDatabase();
|
|
84
|
+
});
|
|
85
|
+
after(async () => {
|
|
86
|
+
closeConnection();
|
|
87
|
+
await rm(DATABASE_DIRECTORY, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/** One request the bundled CLI made to the mock endpoint. */
|
|
91
|
+
type SeenRequest = { url: string; authorization: string | undefined };
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A local Responses-API mock. The 400 is deliberate: Codex 0.166 treats it as a
|
|
95
|
+
* terminal client error (no 5xx backoff), so a turn settles in well under a
|
|
96
|
+
* second while still exercising the real HTTP path — including the
|
|
97
|
+
* `Authorization` header the provider's `env_key` produces.
|
|
98
|
+
*/
|
|
99
|
+
async function startMockResponsesApi(): Promise<{
|
|
100
|
+
requests: SeenRequest[];
|
|
101
|
+
baseUrl: string;
|
|
102
|
+
close(): Promise<void>;
|
|
103
|
+
}> {
|
|
104
|
+
const requests: SeenRequest[] = [];
|
|
105
|
+
const server = http.createServer((request, response) => {
|
|
106
|
+
requests.push({
|
|
107
|
+
url: request.url ?? '',
|
|
108
|
+
authorization: typeof request.headers.authorization === 'string'
|
|
109
|
+
? request.headers.authorization
|
|
110
|
+
: undefined,
|
|
111
|
+
});
|
|
112
|
+
request.resume();
|
|
113
|
+
response.writeHead(400, { 'content-type': 'application/json' });
|
|
114
|
+
response.end(JSON.stringify({ error: { message: 'mock: resident provider injection criterion' } }));
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
118
|
+
const { port } = server.address() as AddressInfo;
|
|
119
|
+
return {
|
|
120
|
+
requests,
|
|
121
|
+
baseUrl: `http://127.0.0.1:${port}/v1`,
|
|
122
|
+
close: () => new Promise<void>((resolve, reject) => {
|
|
123
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
124
|
+
}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Writes the production settings document + its 0600 token file and installs the
|
|
130
|
+
* real settings source in the shared registry port. Nothing about resolution is
|
|
131
|
+
* stubbed: the driver reads the JSON and the token file through the same
|
|
132
|
+
* `resolve()` the production composition root installs.
|
|
133
|
+
*/
|
|
134
|
+
async function withProviderRegistry(
|
|
135
|
+
baseUrl: string,
|
|
136
|
+
run: (home: string) => Promise<void>,
|
|
137
|
+
): Promise<void> {
|
|
138
|
+
const directory = await mkdtemp(path.join(os.tmpdir(), 'codex-resident-injection-'));
|
|
139
|
+
const settingsPath = path.join(directory, 'codex.settings.json');
|
|
140
|
+
const tokenFile = path.join(directory, 'bob.token');
|
|
141
|
+
await writeFile(tokenFile, TOKEN_SECRET, { encoding: 'utf8', mode: 0o600 });
|
|
142
|
+
await writeFile(
|
|
143
|
+
settingsPath,
|
|
144
|
+
JSON.stringify({
|
|
145
|
+
modelProviders: {
|
|
146
|
+
[PROVIDER_ID]: {
|
|
147
|
+
name: 'Bob Upstream',
|
|
148
|
+
baseUrl,
|
|
149
|
+
envKey: ENV_KEY,
|
|
150
|
+
tokenFile,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
'utf8',
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const source = createCodexModelProvidersSource({ settingsPath, env: {}, homeDir: directory });
|
|
158
|
+
installCodexProviderRegistryPort({
|
|
159
|
+
read: () => ({
|
|
160
|
+
providers: source.read().providers.map((provider) => ({ id: provider.id })),
|
|
161
|
+
reservedIds: [],
|
|
162
|
+
}),
|
|
163
|
+
resolve: (id) => source.resolve(id),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
await run(directory);
|
|
168
|
+
} finally {
|
|
169
|
+
// The app-server writes its rollout lazily; let the killed child finish
|
|
170
|
+
// before the directory walk, and retry the race-prone removal.
|
|
171
|
+
await pause(150);
|
|
172
|
+
await rm(directory, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const SINK: IProviderHostDriverSink = {
|
|
177
|
+
leaseAdded: () => {},
|
|
178
|
+
leaseRemoved: () => {},
|
|
179
|
+
activity: () => {},
|
|
180
|
+
identity: () => {},
|
|
181
|
+
exited: () => {},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/** The binding the manager writes before asking a driver to start a host. */
|
|
185
|
+
function bindingFor(appSessionId: string): SessionBinding {
|
|
186
|
+
return {
|
|
187
|
+
appSessionId,
|
|
188
|
+
providerSessionId: null,
|
|
189
|
+
state: 'idle',
|
|
190
|
+
leases: [],
|
|
191
|
+
lastActivityAt: Date.now(),
|
|
192
|
+
peerName: null,
|
|
193
|
+
detachReason: null,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A stand-in for the process-wide session-host manager, narrowed to the two
|
|
199
|
+
* verbs `CodexResidentHostPort` declares.
|
|
200
|
+
*
|
|
201
|
+
* It reproduces the ORDER the real `openHost` uses — register the record, call
|
|
202
|
+
* `startHost`, then `bind` — because that order is load-bearing here: the
|
|
203
|
+
* connection (and therefore the spawn args) is created in `startHost`, before
|
|
204
|
+
* `bind` could hand the per-session launch over.
|
|
205
|
+
*/
|
|
206
|
+
function createHostPort(): CodexResidentHostPort & { hosts: ProcessHost[]; openCalls: string[] } {
|
|
207
|
+
const hosts: ProcessHost[] = [];
|
|
208
|
+
const openCalls: string[] = [];
|
|
209
|
+
return {
|
|
210
|
+
hosts,
|
|
211
|
+
openCalls,
|
|
212
|
+
async openHost(input): Promise<ProcessHost> {
|
|
213
|
+
openCalls.push(input.appSessionId);
|
|
214
|
+
const binding = bindingFor(input.appSessionId);
|
|
215
|
+
const host: ProcessHost = {
|
|
216
|
+
hostId: `host-${hosts.length + 1}`,
|
|
217
|
+
provider: input.provider,
|
|
218
|
+
mode: input.mode,
|
|
219
|
+
state: 'idle',
|
|
220
|
+
pid: null,
|
|
221
|
+
startedAt: Date.now(),
|
|
222
|
+
bindings: new Map([[input.appSessionId, binding]]),
|
|
223
|
+
closeReason: null,
|
|
224
|
+
closeDetail: null,
|
|
225
|
+
quietDeadlineAt: null,
|
|
226
|
+
quietWindowStartAt: null,
|
|
227
|
+
};
|
|
228
|
+
hosts.push(host);
|
|
229
|
+
await input.driver.startHost(host, SINK);
|
|
230
|
+
await input.driver.bind(host, binding);
|
|
231
|
+
return host;
|
|
232
|
+
},
|
|
233
|
+
snapshot: () => hosts,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function contextFor(providerSessionId: string | null): ProviderRuntimeContext {
|
|
238
|
+
return {
|
|
239
|
+
resolveProviderSessionId: () => providerSessionId,
|
|
240
|
+
resolveResumeModel: async () => MODEL,
|
|
241
|
+
getProviderModels: async () => ({ OPTIONS: [], DEFAULT: MODEL }),
|
|
242
|
+
normalizeMessage: () => [],
|
|
243
|
+
isProviderInstalled: async () => true,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function writerInto(messages: unknown[]): ProviderRuntimeWriter {
|
|
248
|
+
return { isWebSocketWriter: true, send: (message) => messages.push(message) };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const TURN: HostTurnInput = { command: 'hello provider', options: {} };
|
|
252
|
+
|
|
253
|
+
/** The launch bag the restore pass assembles for a provider-bound session. */
|
|
254
|
+
function launchOptionsFor(cwd: string, modelProviderId?: string): Record<string, unknown> {
|
|
255
|
+
return {
|
|
256
|
+
model: MODEL,
|
|
257
|
+
cwd,
|
|
258
|
+
permissionMode: 'bypassPermissions',
|
|
259
|
+
...(modelProviderId === undefined ? {} : { modelProviderId }),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** The child's argv, NUL-separated, as `/proc` reports it. */
|
|
264
|
+
async function childArgv(pid: number): Promise<string> {
|
|
265
|
+
return readFile(`/proc/${pid}/cmdline`, 'utf8');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** The child's initial environment, NUL-separated. */
|
|
269
|
+
async function childEnviron(pid: number): Promise<string> {
|
|
270
|
+
return readFile(`/proc/${pid}/environ`, 'utf8');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Whether the secret is visible in ANY process table entry on this host.
|
|
275
|
+
*
|
|
276
|
+
* This is the "not on a command line" reading at the strength the AC asks for:
|
|
277
|
+
* the child's own argv is checked separately, and this sweep catches a leak into
|
|
278
|
+
* a wrapper process. Unreadable entries (another user's process) are skipped —
|
|
279
|
+
* they cannot be the child this criterion spawned.
|
|
280
|
+
*/
|
|
281
|
+
async function secretInAnyProcessTable(secret: string): Promise<string | null> {
|
|
282
|
+
for (const entry of await readdir('/proc')) {
|
|
283
|
+
if (!/^\d+$/.test(entry)) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const cmdline = await childArgv(Number(entry));
|
|
288
|
+
if (cmdline.includes(secret)) {
|
|
289
|
+
return entry;
|
|
290
|
+
}
|
|
291
|
+
} catch {
|
|
292
|
+
// Gone between readdir and read, or not ours to read.
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** Lets the killed app-server flush its rollout before the restart resumes it. */
|
|
299
|
+
function pause(ms: number): Promise<void> {
|
|
300
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
test('AC-463: a provider-bound resident session spawns under its provider and the token file supplies Authorization', async () => {
|
|
304
|
+
const mock = await startMockResponsesApi();
|
|
305
|
+
const previousHome = process.env.HOME;
|
|
306
|
+
const previousCodexHome = process.env.CODEX_HOME;
|
|
307
|
+
process.env[HOST_SENTINEL_KEY] = HOST_SENTINEL_VALUE;
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
await withProviderRegistry(mock.baseUrl, async (home) => {
|
|
311
|
+
// Keep the real CLI's session/config writes inside the criterion's temp
|
|
312
|
+
// directory instead of the operator's ~/.codex.
|
|
313
|
+
process.env.HOME = home;
|
|
314
|
+
process.env.CODEX_HOME = home;
|
|
315
|
+
|
|
316
|
+
const launched: Array<{ args?: string[]; env?: NodeJS.ProcessEnv }> = [];
|
|
317
|
+
const port = createHostPort();
|
|
318
|
+
const driver = new CodexHostDriver({
|
|
319
|
+
host: port,
|
|
320
|
+
createConnection: (launch) => {
|
|
321
|
+
launched.push(launch);
|
|
322
|
+
return new CodexAppServerConnection({ launch });
|
|
323
|
+
},
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
const started = await driver.startResidentSession(APP_SESSION, {
|
|
327
|
+
options: launchOptionsFor(home, PROVIDER_ID),
|
|
328
|
+
context: contextFor(null),
|
|
329
|
+
});
|
|
330
|
+
assert.ok(started.pid !== null, 'the real app-server process must report a pid');
|
|
331
|
+
|
|
332
|
+
// ── the compiled launch: args carry the provider, env carries the secret ──
|
|
333
|
+
assert.equal(launched.length, 1, 'one app-server was spawned for the session');
|
|
334
|
+
const launch = launched[0];
|
|
335
|
+
const args = launch.args ?? [];
|
|
336
|
+
assert.ok(args.includes(`model_provider="${PROVIDER_ID}"`), `spawn args must select the provider: ${JSON.stringify(args)}`);
|
|
337
|
+
assert.ok(
|
|
338
|
+
args.some((arg) => arg.startsWith(`model_providers.${PROVIDER_ID}={`) && arg.includes(`env_key = "${ENV_KEY}"`)),
|
|
339
|
+
`spawn args must define the provider endpoint: ${JSON.stringify(args)}`,
|
|
340
|
+
);
|
|
341
|
+
assert.equal(launch.env?.[ENV_KEY], TOKEN_SECRET, 'the token-file secret travels under env_key');
|
|
342
|
+
assert.equal(launch.env?.[HOST_SENTINEL_KEY], undefined, 'a host sentinel must not reach the child');
|
|
343
|
+
assert.ok(!JSON.stringify(args).includes(TOKEN_SECRET), 'the secret must never be an argv value');
|
|
344
|
+
|
|
345
|
+
// ── the real process table: secret in env, never on the command line ──
|
|
346
|
+
const argv = await childArgv(started.pid);
|
|
347
|
+
assert.ok(!argv.includes(TOKEN_SECRET), 'the secret must not be visible in the child argv');
|
|
348
|
+
assert.ok(argv.includes(`model_provider="${PROVIDER_ID}"`), 'the child really was spawned with the provider override');
|
|
349
|
+
const environ = await childEnviron(started.pid);
|
|
350
|
+
assert.ok(environ.includes(`${ENV_KEY}=${TOKEN_SECRET}`), 'the secret is in the child environment under env_key');
|
|
351
|
+
assert.ok(!environ.includes(HOST_SENTINEL_KEY), 'the host sentinel is absent from the child environment');
|
|
352
|
+
assert.equal(await secretInAnyProcessTable(TOKEN_SECRET), null, 'the secret is in no process table entry');
|
|
353
|
+
|
|
354
|
+
// ── the turn reaches the mock with the env_key credential ──
|
|
355
|
+
const messages: unknown[] = [];
|
|
356
|
+
await driver.run(APP_SESSION, TURN, writerInto(messages), contextFor(null));
|
|
357
|
+
assert.ok(mock.requests.length >= 1, `the real app-server must call the mock; frames=${JSON.stringify(messages)}`);
|
|
358
|
+
assert.equal(mock.requests[0].url, '/v1/responses');
|
|
359
|
+
assert.equal(mock.requests[0].authorization, `Bearer ${TOKEN_SECRET}`);
|
|
360
|
+
|
|
361
|
+
// ── restart + resume: the SAME provider id and the SAME thread ──
|
|
362
|
+
const threadId = driver.readSession(APP_SESSION).threadId;
|
|
363
|
+
assert.ok(threadId, 'the first turn must have established a thread');
|
|
364
|
+
const firstHost = port.hosts[0];
|
|
365
|
+
await driver.closeHost(firstHost, 'user');
|
|
366
|
+
await pause(200);
|
|
367
|
+
|
|
368
|
+
const resumePort = createHostPort();
|
|
369
|
+
const resumedLaunches: Array<{ args?: string[]; env?: NodeJS.ProcessEnv }> = [];
|
|
370
|
+
const resumedDriver = new CodexHostDriver({
|
|
371
|
+
host: resumePort,
|
|
372
|
+
createConnection: (resumedLaunch) => {
|
|
373
|
+
resumedLaunches.push(resumedLaunch);
|
|
374
|
+
return new CodexAppServerConnection({ launch: resumedLaunch });
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
await resumedDriver.startResidentSession(APP_SESSION, {
|
|
378
|
+
options: launchOptionsFor(home, PROVIDER_ID),
|
|
379
|
+
context: contextFor(threadId),
|
|
380
|
+
});
|
|
381
|
+
await resumedDriver.run(APP_SESSION, { command: 'again', options: {} }, writerInto(messages), contextFor(threadId));
|
|
382
|
+
|
|
383
|
+
assert.ok(
|
|
384
|
+
(resumedLaunches[0].args ?? []).includes(`model_provider="${PROVIDER_ID}"`),
|
|
385
|
+
'the restarted host re-injects the recorded provider',
|
|
386
|
+
);
|
|
387
|
+
assert.equal(
|
|
388
|
+
resumedDriver.readSession(APP_SESSION).threadId,
|
|
389
|
+
threadId,
|
|
390
|
+
'the resumed turn re-used the original thread (a no-rollout fallback would have replaced the id)',
|
|
391
|
+
);
|
|
392
|
+
assert.equal(mock.requests.length, 2, 'the resumed turn also reached the mock');
|
|
393
|
+
assert.equal(mock.requests[1].authorization, `Bearer ${TOKEN_SECRET}`);
|
|
394
|
+
|
|
395
|
+
// ── missing provider config on resume is a readable refusal, not openai ──
|
|
396
|
+
await resumedDriver.closeHost(resumePort.hosts[0], 'user');
|
|
397
|
+
const requestsBefore = mock.requests.length;
|
|
398
|
+
const barePort = createHostPort();
|
|
399
|
+
const bareDriver = new CodexHostDriver({
|
|
400
|
+
host: barePort,
|
|
401
|
+
createConnection: (bareLaunch) => new CodexAppServerConnection({ launch: bareLaunch }),
|
|
402
|
+
});
|
|
403
|
+
await bareDriver.startResidentSession(APP_SESSION, {
|
|
404
|
+
options: launchOptionsFor(home),
|
|
405
|
+
context: contextFor(threadId),
|
|
406
|
+
});
|
|
407
|
+
await assert.rejects(
|
|
408
|
+
bareDriver.run(APP_SESSION, TURN, writerInto(messages), contextFor(threadId)),
|
|
409
|
+
(error: unknown) => /bob/.test(String((error as Error).message)) && /no longer configured/i.test(String((error as Error).message)),
|
|
410
|
+
'resume without the recorded provider must surface modelProviderNotConfigured',
|
|
411
|
+
);
|
|
412
|
+
assert.equal(mock.requests.length, requestsBefore, 'a refused resume must not dial any endpoint');
|
|
413
|
+
await bareDriver.closeHost(barePort.hosts[0], 'user');
|
|
414
|
+
});
|
|
415
|
+
} finally {
|
|
416
|
+
if (previousHome === undefined) delete process.env.HOME;
|
|
417
|
+
else process.env.HOME = previousHome;
|
|
418
|
+
if (previousCodexHome === undefined) delete process.env.CODEX_HOME;
|
|
419
|
+
else process.env.CODEX_HOME = previousCodexHome;
|
|
420
|
+
delete process.env[HOST_SENTINEL_KEY];
|
|
421
|
+
await mock.close();
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('AC-463: naming the provider only on thread/start is refused by the real app-server', async () => {
|
|
426
|
+
const mock = await startMockResponsesApi();
|
|
427
|
+
const previousHome = process.env.HOME;
|
|
428
|
+
const previousCodexHome = process.env.CODEX_HOME;
|
|
429
|
+
|
|
430
|
+
try {
|
|
431
|
+
await withProviderRegistry(mock.baseUrl, async (home) => {
|
|
432
|
+
process.env.HOME = home;
|
|
433
|
+
process.env.CODEX_HOME = home;
|
|
434
|
+
|
|
435
|
+
// No `-c` provider overrides: this is exactly the shape an implementation
|
|
436
|
+
// that only passed `modelProvider` to `thread/start` would produce.
|
|
437
|
+
const connection = new CodexAppServerConnection({
|
|
438
|
+
launch: {
|
|
439
|
+
cwd: home,
|
|
440
|
+
env: { ...process.env },
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
try {
|
|
444
|
+
await connection.initialize();
|
|
445
|
+
const started = await connection.request('thread/start', {
|
|
446
|
+
model: MODEL,
|
|
447
|
+
cwd: home,
|
|
448
|
+
approvalPolicy: 'never',
|
|
449
|
+
sandbox: 'danger-full-access',
|
|
450
|
+
modelProvider: PROVIDER_ID,
|
|
451
|
+
config: {
|
|
452
|
+
model_providers: {
|
|
453
|
+
[PROVIDER_ID]: {
|
|
454
|
+
name: 'Bob Upstream',
|
|
455
|
+
base_url: mock.baseUrl,
|
|
456
|
+
env_key: ENV_KEY,
|
|
457
|
+
wire_api: 'responses',
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
});
|
|
462
|
+
const thread = (started as { thread?: { id?: string } }).thread;
|
|
463
|
+
assert.ok(thread?.id, 'the thread starts; the mismatch only shows on the first turn');
|
|
464
|
+
|
|
465
|
+
await assert.rejects(
|
|
466
|
+
connection.request('turn/start', { threadId: thread.id, input: [{ type: 'text', text: 'hello' }] }),
|
|
467
|
+
(error: unknown) => /provider/i.test(String((error as Error).message)),
|
|
468
|
+
'a thread-level provider alone must be refused by the process-global check',
|
|
469
|
+
);
|
|
470
|
+
assert.equal(mock.requests.length, 0, 'the refused turn never reaches the custom endpoint');
|
|
471
|
+
} finally {
|
|
472
|
+
connection.close();
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
} finally {
|
|
476
|
+
if (previousHome === undefined) delete process.env.HOME;
|
|
477
|
+
else process.env.HOME = previousHome;
|
|
478
|
+
if (previousCodexHome === undefined) delete process.env.CODEX_HOME;
|
|
479
|
+
else process.env.CODEX_HOME = previousCodexHome;
|
|
480
|
+
await mock.close();
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
test('AC-463: an unknown recorded provider is refused readably before any process is spawned', async () => {
|
|
485
|
+
const mock = await startMockResponsesApi();
|
|
486
|
+
try {
|
|
487
|
+
await withProviderRegistry(mock.baseUrl, async () => {
|
|
488
|
+
const port = createHostPort();
|
|
489
|
+
const driver = new CodexHostDriver({ host: port });
|
|
490
|
+
|
|
491
|
+
await assert.rejects(
|
|
492
|
+
driver.startResidentSession(APP_SESSION, {
|
|
493
|
+
options: launchOptionsFor(os.tmpdir(), 'nobody'),
|
|
494
|
+
context: contextFor(null),
|
|
495
|
+
}),
|
|
496
|
+
(error: unknown) => {
|
|
497
|
+
const message = String((error as Error).message);
|
|
498
|
+
return message.includes('nobody') && /not configured/i.test(message);
|
|
499
|
+
},
|
|
500
|
+
'an unresolvable provider must be named and reported as not configured',
|
|
501
|
+
);
|
|
502
|
+
assert.deepEqual(port.openCalls, [], 'no host was opened for a provider that cannot be resolved');
|
|
503
|
+
assert.equal(mock.requests.length, 0, 'nothing dialled any endpoint');
|
|
504
|
+
});
|
|
505
|
+
} finally {
|
|
506
|
+
await mock.close();
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
test('AC-463: the restore launch options carry the session row provider id', async () => {
|
|
511
|
+
const previousDatabasePath = process.env.DATABASE_PATH;
|
|
512
|
+
const directory = await mkdtemp(path.join(os.tmpdir(), 'codex-resident-restore-db-'));
|
|
513
|
+
closeConnection();
|
|
514
|
+
process.env.DATABASE_PATH = path.join(directory, 'auth.db');
|
|
515
|
+
await initializeDatabase();
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
sessionsDb.createSession(APP_SESSION, 'codex', directory);
|
|
519
|
+
sessionsDb.setSessionModel(APP_SESSION, MODEL);
|
|
520
|
+
sessionsDb.setSessionModelProviderId(APP_SESSION, PROVIDER_ID);
|
|
521
|
+
|
|
522
|
+
let captured: HostResidentLaunch | null = null;
|
|
523
|
+
const fakeDriver = {
|
|
524
|
+
async startResidentSession(_appSessionId: string, launch: HostResidentLaunch) {
|
|
525
|
+
captured = launch;
|
|
526
|
+
return { hostId: 'host-restore', pid: null };
|
|
527
|
+
},
|
|
528
|
+
} as unknown as IProviderHostDriver;
|
|
529
|
+
const fakeProvider = {
|
|
530
|
+
id: 'codex',
|
|
531
|
+
hostDriver: fakeDriver,
|
|
532
|
+
sessions: { normalizeMessage: () => [] },
|
|
533
|
+
auth: { getStatus: async () => ({ installed: true }) },
|
|
534
|
+
} as unknown as IProvider;
|
|
535
|
+
|
|
536
|
+
installProviderRegistryPort({
|
|
537
|
+
listProviders: () => [fakeProvider],
|
|
538
|
+
resolveProvider: (id) => {
|
|
539
|
+
if (id === 'codex') {
|
|
540
|
+
return fakeProvider;
|
|
541
|
+
}
|
|
542
|
+
throw new Error(`unexpected provider ${id}`);
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
const result = await providerRuntimeService.startResidentSession('codex' as LLMProvider, APP_SESSION);
|
|
547
|
+
assert.deepEqual(result, { hostId: 'host-restore', pid: null });
|
|
548
|
+
assert.ok(captured, 'the production restore seam must reach the driver');
|
|
549
|
+
const options = (captured as HostResidentLaunch).options;
|
|
550
|
+
assert.equal(options.modelProviderId, PROVIDER_ID, 'the row provider id reaches the resident launch bag');
|
|
551
|
+
assert.equal(options.model, MODEL, 'the row model still reaches it too');
|
|
552
|
+
} finally {
|
|
553
|
+
closeConnection();
|
|
554
|
+
if (previousDatabasePath === undefined) {
|
|
555
|
+
delete process.env.DATABASE_PATH;
|
|
556
|
+
} else {
|
|
557
|
+
process.env.DATABASE_PATH = previousDatabasePath;
|
|
558
|
+
}
|
|
559
|
+
await rm(directory, { recursive: true, force: true });
|
|
560
|
+
}
|
|
561
|
+
});
|