@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
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
* contains HTML — plus the correct callback host (AC4). [was the AC-260 (a)
|
|
22
22
|
* HTML-escaping leg: the server renders no HTML any more, so escaping has no
|
|
23
23
|
* subject; the honest translation is that the value is structured data.]
|
|
24
|
-
* (c) GET context returns the whole scope vocabulary, `
|
|
24
|
+
* (c) GET context returns the whole scope vocabulary, `cloudpit:read` flagged
|
|
25
25
|
* `required:true`/`writable:false`, the rest `required:false`/`writable:true`,
|
|
26
26
|
* and never `cloudcli:admin` (AC4; old (b)/(m)'s intent).
|
|
27
27
|
* (d) decision deny → `redirectTo` carries `error=access_denied` and the verbatim
|
|
28
28
|
* state, no code, no new code row (AC6; old (d)).
|
|
29
29
|
* (e) decision allow → `redirectTo` carries a non-empty code and the verbatim
|
|
30
30
|
* state, and the grant row's scopes are exactly the submitted set ∪
|
|
31
|
-
* `cloudcli:read`, once each (AC5; old (c)/(e)).
|
|
31
|
+
* the canonical `cloudcli:read`, once each (AC5; old (c)/(e)).
|
|
32
32
|
* (f) an unregistered `redirect_uri` is refused at GET /oauth/authorize (400
|
|
33
33
|
* error page, NO Location), at context (400 JSON) and at decision for BOTH
|
|
34
34
|
* allow and deny (400, no `redirectTo`, no code row) — the deny branch is
|
|
@@ -107,6 +107,9 @@ import { OAUTH_CONSENT_SPA_PATH } from '../../../../shared/oauthConsent.js';
|
|
|
107
107
|
const PUBLIC_BASE_URL = 'https://cli.example';
|
|
108
108
|
const REDIRECT_URI = 'https://app.example/cb';
|
|
109
109
|
const START_MS = Date.UTC(2026, 0, 1, 0, 0, 0);
|
|
110
|
+
// 3.0 splits the two vocabularies: the consent screen OFFERS the wire spelling
|
|
111
|
+
// (`cloudpit:*`), while a granted decision is STORED under the canonical name
|
|
112
|
+
// (`cloudcli:*`) so the existing `requiredScopes` literals keep matching.
|
|
110
113
|
const READ_SCOPE = 'cloudcli:read';
|
|
111
114
|
const WRITE_SCOPE = 'cloudcli:session:send';
|
|
112
115
|
const CREATE_SCOPE = 'cloudcli:session:create';
|
|
@@ -114,12 +117,14 @@ const CONTROL_SCOPE = 'cloudcli:session:control';
|
|
|
114
117
|
const NAVIGATE_SCOPE = 'cloudcli:navigate';
|
|
115
118
|
const APPROVE_SCOPE = 'cloudcli:approve';
|
|
116
119
|
// gap-ui-visible-context-extended-fields: the appended content scope, offered by
|
|
117
|
-
// the consent screen since it maps the whole
|
|
120
|
+
// the consent screen since it maps the whole wire vocabulary.
|
|
118
121
|
const SELECTION_SCOPE = 'cloudcli:selection';
|
|
119
122
|
// gap-mcp-cockpit-card-tools: the appended confirm scope. It is a WRITE scope —
|
|
120
123
|
// confirming a card runs the option's declared executor — so leg (c) requires it
|
|
121
124
|
// to carry a `write` group and a non-empty risk badge, which it does.
|
|
122
125
|
const COCKPIT_ACT_SCOPE = 'cloudcli:cockpit:act';
|
|
126
|
+
|
|
127
|
+
/** The wire spelling of each canonical constant: what the consent screen offers and accepts. */
|
|
123
128
|
const VOCABULARY = [
|
|
124
129
|
READ_SCOPE,
|
|
125
130
|
WRITE_SCOPE,
|
|
@@ -129,6 +134,9 @@ const VOCABULARY = [
|
|
|
129
134
|
NAVIGATE_SCOPE,
|
|
130
135
|
SELECTION_SCOPE,
|
|
131
136
|
COCKPIT_ACT_SCOPE,
|
|
137
|
+
].map((scope) => scope.replace('cloudcli:', 'cloudpit:'));
|
|
138
|
+
const [READ_WIRE, WRITE_WIRE, CREATE_WIRE, , , NAVIGATE_WIRE] = VOCABULARY as [
|
|
139
|
+
string, string, string, string, string, string, string, string,
|
|
132
140
|
];
|
|
133
141
|
const USER_ID = 1;
|
|
134
142
|
const OWNER = 'owner';
|
|
@@ -271,7 +279,7 @@ function latestGrantScopes(): string[] {
|
|
|
271
279
|
function authorizeQuery(
|
|
272
280
|
clientId: string,
|
|
273
281
|
challenge: string,
|
|
274
|
-
scopes: string[] = [
|
|
282
|
+
scopes: string[] = [READ_WIRE],
|
|
275
283
|
state = 'xyz',
|
|
276
284
|
redirectUri: string = REDIRECT_URI
|
|
277
285
|
): string {
|
|
@@ -336,7 +344,7 @@ test('(a) GET /oauth/authorize 302s to the relative SPA route, query preserved i
|
|
|
336
344
|
await withConsentServer(async (harness) => {
|
|
337
345
|
const clientId = harness.registerClient('consent-app');
|
|
338
346
|
const pair = pkcePair();
|
|
339
|
-
const query = authorizeQuery(clientId, pair.challenge, [
|
|
347
|
+
const query = authorizeQuery(clientId, pair.challenge, [READ_WIRE, WRITE_WIRE], 'state-abc');
|
|
340
348
|
const response = await fetch(`${harness.baseUrl}/oauth/authorize?${query}`, { redirect: 'manual' });
|
|
341
349
|
assert.equal(response.status, 302);
|
|
342
350
|
const location = response.headers.get('location') ?? '';
|
|
@@ -368,7 +376,7 @@ test('(b) GET context returns the client name as JSON data (verbatim) and the ri
|
|
|
368
376
|
});
|
|
369
377
|
});
|
|
370
378
|
|
|
371
|
-
test('(c) GET context returns the whole vocabulary with
|
|
379
|
+
test('(c) GET context returns the whole wire vocabulary with cloudpit:read required and non-writable', async () => {
|
|
372
380
|
await withConsentServer(async (harness) => {
|
|
373
381
|
const clientId = harness.registerClient('consent-app');
|
|
374
382
|
const reading = await getContext(harness, clientId);
|
|
@@ -377,7 +385,7 @@ test('(c) GET context returns the whole vocabulary with cloudcli:read required a
|
|
|
377
385
|
assert.deepEqual(scopes.map((entry) => entry.scope), VOCABULARY, 'the whole vocabulary, in order');
|
|
378
386
|
for (const entry of scopes) {
|
|
379
387
|
assert.ok(entry.description.length > 0, `${entry.scope} must carry an English description`);
|
|
380
|
-
if (entry.scope ===
|
|
388
|
+
if (entry.scope === READ_WIRE) {
|
|
381
389
|
assert.equal(entry.required, true, 'the read-only scope is pinned');
|
|
382
390
|
assert.equal(entry.writable, false, 'the read-only scope is not removable');
|
|
383
391
|
} else {
|
|
@@ -391,7 +399,7 @@ test('(c) GET context returns the whole vocabulary with cloudcli:read required a
|
|
|
391
399
|
// and, for a state-changing scope, a risk code the badge renders from. The
|
|
392
400
|
// existing assertions above are untouched; these are additive.
|
|
393
401
|
for (const entry of scopes) {
|
|
394
|
-
if (entry.scope ===
|
|
402
|
+
if (entry.scope === READ_WIRE) {
|
|
395
403
|
assert.equal(entry.group, 'read', 'the pinned scope is filed under the read group');
|
|
396
404
|
assert.equal(entry.risk, null, 'a read scope carries no risk badge');
|
|
397
405
|
} else {
|
|
@@ -416,7 +424,7 @@ test('(d) decision deny returns error=access_denied with the verbatim state and
|
|
|
416
424
|
state: 'state-deny-1',
|
|
417
425
|
code_challenge: pkcePair().challenge,
|
|
418
426
|
code_challenge_method: 'S256',
|
|
419
|
-
scopes: [
|
|
427
|
+
scopes: [READ_WIRE],
|
|
420
428
|
action: 'deny',
|
|
421
429
|
});
|
|
422
430
|
assert.equal(denied.status, 200);
|
|
@@ -430,7 +438,7 @@ test('(d) decision deny returns error=access_denied with the verbatim state and
|
|
|
430
438
|
});
|
|
431
439
|
});
|
|
432
440
|
|
|
433
|
-
test('(e) decision allow returns a code and stores the
|
|
441
|
+
test('(e) decision allow returns a code and stores the canonical set plus the read scope', async () => {
|
|
434
442
|
await withConsentServer(async (harness) => {
|
|
435
443
|
const clientId = harness.registerClient('consent-app');
|
|
436
444
|
const pair = pkcePair();
|
|
@@ -443,7 +451,7 @@ test('(e) decision allow returns a code and stores the submitted set plus cloudc
|
|
|
443
451
|
code_challenge_method: 'S256',
|
|
444
452
|
// The read-only box is pinned on the client, so it is not submitted; the
|
|
445
453
|
// control scope was left unchecked.
|
|
446
|
-
scopes: [
|
|
454
|
+
scopes: [WRITE_WIRE],
|
|
447
455
|
action: 'allow',
|
|
448
456
|
});
|
|
449
457
|
assert.equal(allowed.status, 200);
|
|
@@ -469,7 +477,7 @@ test('(f) an unregistered redirect_uri is refused at authorize, context and deci
|
|
|
469
477
|
|
|
470
478
|
// GET /oauth/authorize: an error page and NO Location header.
|
|
471
479
|
const getResponse = await fetch(
|
|
472
|
-
`${harness.baseUrl}/oauth/authorize?${authorizeQuery(clientId, pkcePair().challenge, [
|
|
480
|
+
`${harness.baseUrl}/oauth/authorize?${authorizeQuery(clientId, pkcePair().challenge, [READ_WIRE], 'xyz', evil)}`,
|
|
473
481
|
{ redirect: 'manual' }
|
|
474
482
|
);
|
|
475
483
|
const getBody = await getResponse.text();
|
|
@@ -492,7 +500,7 @@ test('(f) an unregistered redirect_uri is refused at authorize, context and deci
|
|
|
492
500
|
state: 'xyz',
|
|
493
501
|
code_challenge: pkcePair().challenge,
|
|
494
502
|
code_challenge_method: 'S256',
|
|
495
|
-
scopes: [
|
|
503
|
+
scopes: [READ_WIRE],
|
|
496
504
|
action,
|
|
497
505
|
});
|
|
498
506
|
assert.equal(response.status, 400, `decision ${action} to an unregistered callback must be refused`);
|
|
@@ -518,7 +526,7 @@ test('(g) the JSON API carries the anti-framing and no-store headers', async ()
|
|
|
518
526
|
state: 'xyz',
|
|
519
527
|
code_challenge: pkcePair().challenge,
|
|
520
528
|
code_challenge_method: 'S256',
|
|
521
|
-
scopes: [
|
|
529
|
+
scopes: [READ_WIRE],
|
|
522
530
|
action: 'deny',
|
|
523
531
|
});
|
|
524
532
|
assert.equal(decision.headers.get('x-frame-options'), 'DENY');
|
|
@@ -542,7 +550,7 @@ test('(g) the JSON API carries the anti-framing and no-store headers', async ()
|
|
|
542
550
|
test('(h) the SPA document at /oauth/consent carries the three headers over the static layer', async () => {
|
|
543
551
|
await withConsentServer(async (harness) => {
|
|
544
552
|
const clientId = harness.registerClient('consent-app');
|
|
545
|
-
const query = authorizeQuery(clientId, pkcePair().challenge, [
|
|
553
|
+
const query = authorizeQuery(clientId, pkcePair().challenge, [READ_WIRE], 'state-doc');
|
|
546
554
|
const response = await fetch(`${harness.baseUrl}${OAUTH_CONSENT_SPA_PATH}?${query}`);
|
|
547
555
|
assert.equal(response.status, 200, 'the SPA document is served from dist/index.html');
|
|
548
556
|
assert.match(response.headers.get('content-type') ?? '', /text\/html/);
|
|
@@ -616,7 +624,7 @@ test('(k) context and decision without a JWT are 401 and create no code row', as
|
|
|
616
624
|
state: 'xyz',
|
|
617
625
|
code_challenge: pkcePair().challenge,
|
|
618
626
|
code_challenge_method: 'S256',
|
|
619
|
-
scopes: [
|
|
627
|
+
scopes: [READ_WIRE],
|
|
620
628
|
action: 'allow',
|
|
621
629
|
},
|
|
622
630
|
null
|
|
@@ -637,7 +645,7 @@ test('(m) a forged scope outside the vocabulary never reaches the grant', async
|
|
|
637
645
|
state: 'xyz',
|
|
638
646
|
code_challenge: pkcePair().challenge,
|
|
639
647
|
code_challenge_method: 'S256',
|
|
640
|
-
scopes: ['cloudcli:admin', 'bogus',
|
|
648
|
+
scopes: ['cloudcli:admin', 'bogus', CREATE_WIRE, CREATE_WIRE, NAVIGATE_WIRE],
|
|
641
649
|
action: 'allow',
|
|
642
650
|
});
|
|
643
651
|
assert.equal(allowed.status, 200);
|
|
@@ -696,7 +704,7 @@ test('(o) a read-only allow with no password and no injected verifier mints a co
|
|
|
696
704
|
state: 'state-readonly',
|
|
697
705
|
code_challenge: pkcePair().challenge,
|
|
698
706
|
code_challenge_method: 'S256',
|
|
699
|
-
scopes: [
|
|
707
|
+
scopes: [READ_WIRE],
|
|
700
708
|
action: 'allow',
|
|
701
709
|
password: '',
|
|
702
710
|
});
|
|
@@ -720,7 +728,7 @@ test('(p) a deny carrying a write scope and no password is still access_denied',
|
|
|
720
728
|
state: 'state-deny-write',
|
|
721
729
|
code_challenge: pkcePair().challenge,
|
|
722
730
|
code_challenge_method: 'S256',
|
|
723
|
-
scopes: [
|
|
731
|
+
scopes: [WRITE_WIRE],
|
|
724
732
|
action: 'deny',
|
|
725
733
|
password: '',
|
|
726
734
|
});
|
|
@@ -773,7 +781,7 @@ test('(l) in a real browser the 302 lands on the SPA route and the window.locati
|
|
|
773
781
|
body: JSON.stringify({
|
|
774
782
|
client_id: q.get('client_id'), redirect_uri: q.get('redirect_uri'), state: q.get('state'),
|
|
775
783
|
code_challenge: q.get('code_challenge'), code_challenge_method: 'S256',
|
|
776
|
-
scopes: ['
|
|
784
|
+
scopes: ['cloudpit:read'], action: 'allow',
|
|
777
785
|
}),
|
|
778
786
|
}).then((r) => r.json());
|
|
779
787
|
window.location.href = decision.redirectTo;
|
|
@@ -802,7 +810,7 @@ test('(l) in a real browser the 302 lands on the SPA route and the window.locati
|
|
|
802
810
|
const callback = `${callbackOrigin}/cb`;
|
|
803
811
|
const clientId = harness.registerClient('browser-app', callback);
|
|
804
812
|
const pair = pkcePair();
|
|
805
|
-
const query = authorizeQuery(clientId, pair.challenge, [
|
|
813
|
+
const query = authorizeQuery(clientId, pair.challenge, [READ_WIRE], 'state-browser', callback);
|
|
806
814
|
|
|
807
815
|
const page = await browser.newPage();
|
|
808
816
|
await page.goto(`${harness.baseUrl}/oauth/authorize?${query}`);
|
|
@@ -65,13 +65,13 @@ import type { OAuthProvider } from '@/modules/oauth/index.js';
|
|
|
65
65
|
|
|
66
66
|
const CLIENT_ID = 'client-ratelimit';
|
|
67
67
|
const REDIRECT_URI = 'https://app.example/cb';
|
|
68
|
-
const READ_SCOPE = '
|
|
68
|
+
const READ_SCOPE = 'cloudpit:read';
|
|
69
69
|
/**
|
|
70
70
|
* A state-changing scope. The password branch is now reached ONLY by a grant that
|
|
71
71
|
* goes past `cloudcli:read`, so the legs that are about the password (a–h below)
|
|
72
72
|
* must submit this rather than the read scope.
|
|
73
73
|
*/
|
|
74
|
-
const WRITE_SCOPE = '
|
|
74
|
+
const WRITE_SCOPE = 'cloudpit:session:send';
|
|
75
75
|
/** Fifteen minutes, the AC's window; also the amount leg (b) advances past. */
|
|
76
76
|
const WINDOW_MS = 15 * 60 * 1000;
|
|
77
77
|
const MAX_ATTEMPTS = 10;
|
|
@@ -89,7 +89,7 @@ function issueToken(harness: Harness, expiresInDays: number): IssuedToken {
|
|
|
89
89
|
const issued = harness.tokens.issueToken({
|
|
90
90
|
userId: USER_ONE,
|
|
91
91
|
name: 'self-check',
|
|
92
|
-
scopes: ['
|
|
92
|
+
scopes: ['cloudpit:read'],
|
|
93
93
|
expiresInDays,
|
|
94
94
|
});
|
|
95
95
|
if (!issued.ok) {
|
|
@@ -111,7 +111,7 @@ test('(a) a live token answers 200 with its owner, scopes and expiry, verified p
|
|
|
111
111
|
assert.equal(response.status, 200);
|
|
112
112
|
const body = await response.json() as { userId: number; scopes: string[]; expiresAt: string };
|
|
113
113
|
assert.equal(body.userId, USER_ONE);
|
|
114
|
-
assert.deepEqual(body.scopes, ['
|
|
114
|
+
assert.deepEqual(body.scopes, ['cloudpit:read'], 'the token row keeps the issued wire spelling');
|
|
115
115
|
assert.equal(body.expiresAt, token.expiresAt);
|
|
116
116
|
|
|
117
117
|
// No cache: the row is read on every request, so a second call answers the
|
|
@@ -42,7 +42,7 @@ export const ARCHITECTURE_DELTA_REFRESH_MS = 60 * 60 * 1000;
|
|
|
42
42
|
/**
|
|
43
43
|
* The project the producer observes.
|
|
44
44
|
*
|
|
45
|
-
* `projectId` addresses the
|
|
45
|
+
* `projectId` addresses the Cloudpit project the architecture service resolves to a root;
|
|
46
46
|
* `fleetProjectId` is what the `cloudcli://architecture/<id>` URI (and therefore the wall) uses.
|
|
47
47
|
* A project without a fleet id has no addressable tile and is skipped — the same rule the
|
|
48
48
|
* project-truth producer applies to its unregistered projects.
|
|
@@ -40,7 +40,7 @@ const SESSION_LLM_BLIND_SPOTS: readonly string[] = [
|
|
|
40
40
|
/** What the layered project-truth reading cannot see. */
|
|
41
41
|
const PROJECT_BLIND_SPOTS: readonly string[] = [
|
|
42
42
|
'看不见未登记到 quay-fleet 的项目与不经 quay 的工作',
|
|
43
|
-
'部署层只对
|
|
43
|
+
'部署层只对 Cloudpit 自身有意义',
|
|
44
44
|
'验证层只反映 gate 的判据,不反映判据本身是否判别',
|
|
45
45
|
];
|
|
46
46
|
|
|
@@ -38,8 +38,10 @@ import {
|
|
|
38
38
|
withBlindSpotsInDigest,
|
|
39
39
|
} from './blind-spots.js';
|
|
40
40
|
import {
|
|
41
|
+
canonicalObservationUri,
|
|
41
42
|
parseObservationUri,
|
|
42
43
|
type ObservationKind,
|
|
44
|
+
type ObservationUri,
|
|
43
45
|
} from './observation-uri.js';
|
|
44
46
|
import { evaluateProducer, type ProducerReading } from './producer-liveness.js';
|
|
45
47
|
|
|
@@ -250,7 +252,9 @@ function toObservedObject(row: ObservedObjectRow): ObservedObject {
|
|
|
250
252
|
tier,
|
|
251
253
|
);
|
|
252
254
|
return {
|
|
253
|
-
|
|
255
|
+
// Stored rows are canonical `cloudpit://` keys (the 2.1 normalization moved the 2.0 rows);
|
|
256
|
+
// the projection normalizes once more so every reading of an object is one string.
|
|
257
|
+
uri: canonicalObservationUri(row.uri),
|
|
254
258
|
kind,
|
|
255
259
|
title: row.title,
|
|
256
260
|
status,
|
|
@@ -267,12 +271,17 @@ function toObservedObject(row: ObservedObjectRow): ObservedObject {
|
|
|
267
271
|
}
|
|
268
272
|
|
|
269
273
|
function toSeenCursor(row: ObservationSeenCursorRow): SeenCursor {
|
|
270
|
-
return {
|
|
274
|
+
return {
|
|
275
|
+
userId: row.userId,
|
|
276
|
+
uri: canonicalObservationUri(row.uri),
|
|
277
|
+
revision: row.revision,
|
|
278
|
+
at: row.at,
|
|
279
|
+
};
|
|
271
280
|
}
|
|
272
281
|
|
|
273
282
|
function toObservedRevision(row: ObservedRevisionRow): ObservedRevision {
|
|
274
283
|
return {
|
|
275
|
-
uri: row.uri,
|
|
284
|
+
uri: canonicalObservationUri(row.uri),
|
|
276
285
|
revision: row.revision,
|
|
277
286
|
at: row.at,
|
|
278
287
|
deltaItems: parseDeltaItems(row.deltaItemsJson),
|
|
@@ -311,8 +320,22 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
311
320
|
}
|
|
312
321
|
const publish = deps.publish ?? (() => {});
|
|
313
322
|
|
|
323
|
+
/**
|
|
324
|
+
* The row key a write must use. 3.0 has exactly one spelling: a new object lands on (and an
|
|
325
|
+
* existing object continues) the canonical `cloudpit://` key. The 2.1 key normalization already
|
|
326
|
+
* moved the rows a 2.0 producer wrote, so no read has to try a legacy key any more.
|
|
327
|
+
*/
|
|
328
|
+
const storageUriOf = (parsed: ObservationUri): string => parsed.uri;
|
|
329
|
+
|
|
330
|
+
/** Revisions for the one canonical spelling, oldest first. */
|
|
331
|
+
const revisionsAfter = (uri: string, afterRevision: number): ObservedRevisionRow[] => {
|
|
332
|
+
return observationDb.listRevisionsAfter(uri, afterRevision);
|
|
333
|
+
};
|
|
334
|
+
|
|
314
335
|
const publishRevision = (uri: string, revision: number, status: ObservedStatus, deltaItems: string[]): void => {
|
|
315
|
-
const recipients = new Set(
|
|
336
|
+
const recipients = new Set<string>();
|
|
337
|
+
for (const userId of observationDb.listWatchUserIds(uri)) recipients.add(userId);
|
|
338
|
+
for (const userId of observationDb.listSeenUserIds(uri)) recipients.add(userId);
|
|
316
339
|
for (const userId of recipients) {
|
|
317
340
|
publish(userId, { kind: 'observation.update', uri, revision, seenRevision: null, deltaItems });
|
|
318
341
|
}
|
|
@@ -321,7 +344,7 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
321
344
|
const requireUri = (value: unknown) => {
|
|
322
345
|
const parsed = parseObservationUri(value);
|
|
323
346
|
if (parsed === null) {
|
|
324
|
-
throw invalid('`uri` must be one of
|
|
347
|
+
throw invalid('`uri` must be one of cloudpit://session/<id>, cloudpit://architecture/<id>, quay://<id>/board', 'INVALID_URI');
|
|
325
348
|
}
|
|
326
349
|
return parsed;
|
|
327
350
|
};
|
|
@@ -367,7 +390,7 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
367
390
|
const items = deltaItems.map((item) => item.trim()).filter((item) => item !== '');
|
|
368
391
|
|
|
369
392
|
const appended = observationDb.appendRevision({
|
|
370
|
-
uri: parsed
|
|
393
|
+
uri: storageUriOf(parsed),
|
|
371
394
|
kind,
|
|
372
395
|
title,
|
|
373
396
|
statusState: status.state,
|
|
@@ -405,7 +428,7 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
405
428
|
if (!Number.isInteger(afterRevision) || afterRevision < 0) {
|
|
406
429
|
throw invalid('`revision` must be a non-negative integer');
|
|
407
430
|
}
|
|
408
|
-
return
|
|
431
|
+
return revisionsAfter(parsed.uri, afterRevision).map(toObservedRevision);
|
|
409
432
|
},
|
|
410
433
|
|
|
411
434
|
markSeen(userId, uri, revision) {
|
|
@@ -421,6 +444,7 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
421
444
|
return { cursor: toSeenCursor(current), advanced: false };
|
|
422
445
|
}
|
|
423
446
|
const at = now();
|
|
447
|
+
// One spelling, one row: the cursor always lives under the canonical address.
|
|
424
448
|
observationDb.writeSeenCursor(key, parsed.uri, revision, at);
|
|
425
449
|
const cursor: SeenCursor = { userId: key, uri: parsed.uri, revision, at };
|
|
426
450
|
const object = readObject(parsed.uri);
|
|
@@ -446,8 +470,8 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
446
470
|
const key = userKey(userId);
|
|
447
471
|
const parsed = requireUri(uri);
|
|
448
472
|
const at = now();
|
|
449
|
-
const row = observationDb.writeWatchEntry(key, parsed
|
|
450
|
-
const entry: WatchEntry = { userId: row.userId, uri:
|
|
473
|
+
const row = observationDb.writeWatchEntry(key, storageUriOf(parsed), at);
|
|
474
|
+
const entry: WatchEntry = { userId: row.userId, uri: parsed.uri, pinnedAt: row.pinnedAt };
|
|
451
475
|
publish(key, {
|
|
452
476
|
kind: 'observation.update',
|
|
453
477
|
uri: parsed.uri,
|
|
@@ -474,16 +498,30 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
474
498
|
|
|
475
499
|
getWall(userId) {
|
|
476
500
|
const key = userKey(userId);
|
|
477
|
-
|
|
478
|
-
const pinnedUris = new Set(
|
|
501
|
+
// Pins and cursors are already canonical; normalization keeps the join key one string.
|
|
502
|
+
const pinnedUris = new Set(
|
|
503
|
+
observationDb.listWatchEntries(key).map((pin) => canonicalObservationUri(pin.uri)),
|
|
504
|
+
);
|
|
479
505
|
const cursors = new Map<string, number>();
|
|
480
506
|
for (const cursor of observationDb.listSeenCursors(key)) {
|
|
481
|
-
|
|
507
|
+
const uri = canonicalObservationUri(cursor.uri);
|
|
508
|
+
cursors.set(uri, Math.max(cursors.get(uri) ?? 0, cursor.revision));
|
|
482
509
|
}
|
|
483
510
|
|
|
484
|
-
|
|
511
|
+
// One wall entry per canonical address even if both spellings have a row: the higher
|
|
512
|
+
// revision is the object's current state (a 2.0 row plus a post-flip row never doubles it).
|
|
513
|
+
const objects = new Map<string, ObservedObject>();
|
|
485
514
|
for (const row of observationDb.listObjects()) {
|
|
515
|
+
// 3.0 reads one spelling: a pre-normalization row still keyed `cloudcli://` is not an
|
|
516
|
+
// address this release can show (the 2.1 migration moved the rows it could reach).
|
|
517
|
+
if (parseObservationUri(row.uri) === null) continue;
|
|
486
518
|
const object = toObservedObject(row);
|
|
519
|
+
const known = objects.get(object.uri);
|
|
520
|
+
if (known === undefined || object.revision > known.revision) objects.set(object.uri, object);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const candidates: ObservationWallEntry[] = [];
|
|
524
|
+
for (const object of objects.values()) {
|
|
487
525
|
const pinned = pinnedUris.has(object.uri);
|
|
488
526
|
// An unpinned object is on the wall only while it needs attention; recovering to `ok`
|
|
489
527
|
// (or to any other non-attention reading) is what makes it leave again.
|
|
@@ -491,9 +529,9 @@ export function createObservationStore(deps: ObservationStoreDeps = {}): Observa
|
|
|
491
529
|
continue;
|
|
492
530
|
}
|
|
493
531
|
const seenRevision = cursors.get(object.uri) ?? 0;
|
|
494
|
-
const deltaItems =
|
|
495
|
-
|
|
496
|
-
|
|
532
|
+
const deltaItems = revisionsAfter(object.uri, seenRevision).flatMap((revision) =>
|
|
533
|
+
parseDeltaItems(revision.deltaItemsJson),
|
|
534
|
+
);
|
|
497
535
|
candidates.push({ object, pinned, seenRevision, deltaItems });
|
|
498
536
|
}
|
|
499
537
|
|
|
@@ -7,22 +7,27 @@
|
|
|
7
7
|
* let a typo create a second object for the same conversation, which is exactly the
|
|
8
8
|
* "unobservable-because-misaddressed" failure this layer exists to prevent.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* cloudpit://session/<id> — one Cloudpi session (canonical since 2.1)
|
|
11
|
+
* cloudpit://architecture/<projectId> — one project's architecture graph
|
|
12
12
|
* quay://<fleetProjectId>/board — one fleet project's board (the fleet's own grammar)
|
|
13
13
|
* quay://fleet/initiative/<slug> — one cross-project initiative (the fleet's reserved segment)
|
|
14
14
|
*
|
|
15
|
+
* 3.0 OWNS ONE SPELLING. 2.1 switched the write and kept the legacy `cloudcli://session/<id>` /
|
|
16
|
+
* `cloudcli://architecture/<id>` read spellings; this release retires those reads, so the parser
|
|
17
|
+
* accepts only the canonical `cloudpit://` forms. The 2.1 key normalization already moved stored
|
|
18
|
+
* object rows onto that spelling. See `docs/proposals/cloudpit-compat-retirement.md` (R6/R7).
|
|
19
|
+
*
|
|
15
20
|
* The initiative address is the fleet's (`ADR-013` reserves `fleet` for exactly this object).
|
|
16
21
|
* The cockpit's initiative view pins it to the wall, so the watch routes must accept it even
|
|
17
22
|
* though no observation producer writes an object ROW for it: a pin is a user's bookmark, and
|
|
18
23
|
* refusing the fleet's own address would make 「钉到观察墙」 impossible for the object the
|
|
19
24
|
* initiative view is about.
|
|
20
25
|
*
|
|
21
|
-
* The
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
+
* The cloud scheme is Cloudpi's; quay's board URI is kept verbatim because the fleet owns that
|
|
27
|
+
* address space and will own its "seen" write-back later (see the task's Notes). An id segment
|
|
28
|
+
* may not be empty, may not contain `/`, `?`, `#` or whitespace, and is not percent-decoded
|
|
29
|
+
* here: the routes decode the path parameter once, and every other caller builds the URI with
|
|
30
|
+
* the formatters below.
|
|
26
31
|
*
|
|
27
32
|
* Consumers: `server/modules/observation/observation-store.ts` (write validation and the wall)
|
|
28
33
|
* and `server/modules/observation/observation.routes.ts` (transport validation).
|
|
@@ -38,27 +43,27 @@ export type ObservationKind = 'session' | 'project' | 'architecture';
|
|
|
38
43
|
* caller can use the parsed value as a map key without re-formatting it.
|
|
39
44
|
*/
|
|
40
45
|
export type ObservationUri =
|
|
41
|
-
| { scheme: '
|
|
42
|
-
| { scheme: '
|
|
46
|
+
| { scheme: 'cloudpit'; kind: 'session'; id: string; uri: string }
|
|
47
|
+
| { scheme: 'cloudpit'; kind: 'architecture'; id: string; uri: string }
|
|
43
48
|
| { scheme: 'quay'; kind: 'project'; id: string; uri: string }
|
|
44
49
|
| { scheme: 'quay'; kind: 'initiative'; id: string; uri: string };
|
|
45
50
|
|
|
46
51
|
/** One path segment: at least one character, none of the URI's structural characters. */
|
|
47
52
|
const SEGMENT = '[^/?#\\s]+';
|
|
48
53
|
|
|
49
|
-
const
|
|
54
|
+
const CLOUDPIT_URI = new RegExp(`^cloudpit://(session|architecture)/(${SEGMENT})$`);
|
|
50
55
|
const QUAY_BOARD_URI = new RegExp(`^quay://(${SEGMENT})/board$`);
|
|
51
56
|
/** The fleet's one reserved address: `fleet` is not a project, and only `initiative` lives there. */
|
|
52
57
|
const QUAY_INITIATIVE_URI = new RegExp(`^quay://fleet/initiative/(${SEGMENT})$`);
|
|
53
58
|
|
|
54
|
-
/** The canonical `
|
|
59
|
+
/** The canonical `cloudpit://session/<id>` spelling 2.1 writes. */
|
|
55
60
|
export function formatSessionUri(id: string): string {
|
|
56
|
-
return `
|
|
61
|
+
return `cloudpit://session/${id}`;
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
/** The canonical `
|
|
64
|
+
/** The canonical `cloudpit://architecture/<id>` spelling 2.1 writes. */
|
|
60
65
|
export function formatArchitectureUri(projectId: string): string {
|
|
61
|
-
return `
|
|
66
|
+
return `cloudpit://architecture/${projectId}`;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
/** The canonical `quay://<fleetProjectId>/board` spelling. */
|
|
@@ -94,13 +99,11 @@ export function formatObservationUri(parsed: ObservationUri): string {
|
|
|
94
99
|
*/
|
|
95
100
|
export function parseObservationUri(value: unknown): ObservationUri | null {
|
|
96
101
|
if (typeof value !== 'string') return null;
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
const kind =
|
|
100
|
-
const id =
|
|
101
|
-
|
|
102
|
-
// legacy `cloudcli://` one; 2.0 is a read widening, not a rename.
|
|
103
|
-
return { scheme: 'cloudcli', kind, id, uri: kind === 'session' ? formatSessionUri(id) : formatArchitectureUri(id) };
|
|
102
|
+
const cloud = CLOUDPIT_URI.exec(value);
|
|
103
|
+
if (cloud !== null) {
|
|
104
|
+
const kind = cloud[1] === 'session' ? 'session' : 'architecture';
|
|
105
|
+
const id = cloud[2]!;
|
|
106
|
+
return { scheme: 'cloudpit', kind, id, uri: kind === 'session' ? formatSessionUri(id) : formatArchitectureUri(id) };
|
|
104
107
|
}
|
|
105
108
|
const initiative = QUAY_INITIATIVE_URI.exec(value);
|
|
106
109
|
if (initiative !== null) {
|
|
@@ -112,3 +115,13 @@ export function parseObservationUri(value: unknown): ObservationUri | null {
|
|
|
112
115
|
}
|
|
113
116
|
return null;
|
|
114
117
|
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Maps an accepted object address onto its canonical `cloudpit://` form; a `quay://` address (or
|
|
121
|
+
* an unparseable value) is returned verbatim. Consumers: the observation store's row mapping and
|
|
122
|
+
* the wall's join keys.
|
|
123
|
+
*/
|
|
124
|
+
export function canonicalObservationUri(value: string): string {
|
|
125
|
+
const parsed = parseObservationUri(value);
|
|
126
|
+
return parsed === null ? value : parsed.uri;
|
|
127
|
+
}
|
|
@@ -53,7 +53,7 @@ function invalidRequest(message: string): AppError {
|
|
|
53
53
|
function requireBodyUri(body: unknown): string {
|
|
54
54
|
const uri = body !== null && typeof body === 'object' ? (body as Record<string, unknown>).uri : undefined;
|
|
55
55
|
if (parseObservationUri(uri) === null) {
|
|
56
|
-
throw invalidRequest('`uri` must be one of
|
|
56
|
+
throw invalidRequest('`uri` must be one of cloudpit://session/<id>, cloudpit://architecture/<id>, quay://<id>/board');
|
|
57
57
|
}
|
|
58
58
|
return uri as string;
|
|
59
59
|
}
|
|
@@ -35,7 +35,7 @@ import type { ObservedStatus } from './observation-store.js';
|
|
|
35
35
|
|
|
36
36
|
/** One project as the producer addresses it. `fleetProjectId` is the `quay://` project segment. */
|
|
37
37
|
export type ProjectTruthProjectRef = {
|
|
38
|
-
/**
|
|
38
|
+
/** Cloudpit's own project id, used only to ask the quay service for a snapshot. */
|
|
39
39
|
projectId: string;
|
|
40
40
|
/** Absolute project root; the deploy reader resolves its own script relative to it. */
|
|
41
41
|
projectPath: string;
|
|
@@ -48,7 +48,7 @@ export type ProjectTruthProjectRef = {
|
|
|
48
48
|
fleetProjectId: string | null;
|
|
49
49
|
/**
|
|
50
50
|
* The deployment target, or `null` when the project has no deployment concept. Today only
|
|
51
|
-
*
|
|
51
|
+
* Cloudpit itself does; every other project's deploy layer is `not-applicable`.
|
|
52
52
|
*/
|
|
53
53
|
deploy: ProjectTruthDeployTarget | null;
|
|
54
54
|
};
|
|
@@ -221,7 +221,7 @@ const PROJECT_TRUTH_LAYER_LABELS = {
|
|
|
221
221
|
} as const satisfies Record<keyof ProjectTruthLayers, string>;
|
|
222
222
|
|
|
223
223
|
/** The deploy layer's "no deployment concept" state, excluded from aggregation. */
|
|
224
|
-
export const PROJECT_TRUTH_NOT_APPLICABLE_REASON = '该项目没有部署概念(目前只有
|
|
224
|
+
export const PROJECT_TRUTH_NOT_APPLICABLE_REASON = '该项目没有部署概念(目前只有 Cloudpit 自身有部署)';
|
|
225
225
|
|
|
226
226
|
/** One criterion row counts as a gate only while it is a live, runnable criterion. */
|
|
227
227
|
const GATE_EXCLUDED_GOAL_STATUSES = new Set(['draft', 'superseded', 'retired']);
|
|
@@ -274,7 +274,8 @@ export const SYSTEM_PROMPT = [
|
|
|
274
274
|
'是提问时输出:{"isAsking":true,"ask":"…","situation":"…","incomplete":false,"recommendedOptionId":null,"judgeOptionId":null,"judgeReason":null,"options":[{"id":"…","label":"…","does":"…","tags":[{"kind":"consequence","text":"…"}],"source":"assistant"}]}',
|
|
275
275
|
'- ask:把助手消息里真正的待决问题重述成一个问句,保留原文的限定条件;不要整段照抄。问题可能来自中段的「值得优先/下一步/是否…」清单,最后一段只是附注时也要从前面取出它。',
|
|
276
276
|
'- situation:回答这个问题需要知道的情境(在做什么、卡在哪、已试过什么),只写原文有的事实。',
|
|
277
|
-
'- options
|
|
277
|
+
'- options:当问题只有一个选择维度(从若干互斥项里选一个)时,助手原文用编号或项目符号列出多少项就给出多少条 option(label 用原文的选项名);原文没有列出选择才用空数组 []。does 是选它会发生什么,tags 是后果标签(kind 用 consequence / risk / cost / benefit)。',
|
|
278
|
+
'- 多个相互独立的子决定(例如「三个设计点,每个都要选 A 还是 B」)不要拆成 2N 条半方向、更不要穷举 2^N 种组合:打包成 3–5 个自洽的组合选项,每个 option 覆盖全部子决定(label 用「①…+②…+③…」这种合取写法,does 写清每个子决定的取值);优先保留助手自己讨论过或最可能被选的组合,并含「全部保持现状」「全部按助手建议推进」这类自然端点。',
|
|
278
279
|
'- 是/否提问:当助手消息是「是否要…」「要不要…」「要我…吗」「Should I…?」这类只能答是或否的问题、且原文没有列出选项时,给出两个 option:id 分别为 "yes"(label 「是」)和 "no"(label 「否」),各写一句 does 与一个 consequence 标签。',
|
|
279
280
|
'- recommendedOptionId:仅当助手原文明确推荐了某个选项时填它的 id;原文没有推荐就填 null。',
|
|
280
281
|
'- judgeOptionId:当原文没有明确推荐时,从 options 里挑出最可能被选的一项填它的 id(是/否题填 "yes" 或 "no");原文已有明确推荐时必须填 null,不得覆盖助手的推荐。',
|
|
@@ -43,6 +43,7 @@ import { readSessionAskEventWriterPort } from '@/shared/ports/session-ask-events
|
|
|
43
43
|
|
|
44
44
|
import type { ObservedObject, ObservationStore } from './observation-store.js';
|
|
45
45
|
import { createObservationStore } from './observation-store.js';
|
|
46
|
+
import { parseObservationUri } from './observation-uri.js';
|
|
46
47
|
import { createSessionAskDecisionDigest } from './session-ask-decision-digest.js';
|
|
47
48
|
import { createSessionDigestProducer } from './session-digest.producer.js';
|
|
48
49
|
import type { SessionDigestProducer, SessionTurnEndEvent } from './session-digest.producer.js';
|
|
@@ -348,11 +349,16 @@ export function createSessionDigestLlmTier(deps: SessionDigestLlmTierDeps): Sess
|
|
|
348
349
|
durationMs: number;
|
|
349
350
|
}): void {
|
|
350
351
|
try {
|
|
352
|
+
// The ledger names the session by its id, not by the address spelling: since 2.1 the
|
|
353
|
+
// formatter writes `cloudpit://session/<id>`, while a 2.0 row may still be the legacy
|
|
354
|
+
// `cloudcli://` one. The parser normalizes both onto the canonical address, so the id is
|
|
355
|
+
// read the same way whichever spelling 2.0/2.1 stored.
|
|
356
|
+
const parsedUri = parseObservationUri(record.object.uri);
|
|
351
357
|
usageLog.write({
|
|
352
358
|
type: 'observation.session-digest-llm',
|
|
353
359
|
at: record.at,
|
|
354
360
|
uri: record.object.uri,
|
|
355
|
-
sessionId: record.object.uri
|
|
361
|
+
sessionId: parsedUri?.id ?? record.object.uri,
|
|
356
362
|
model: record.model,
|
|
357
363
|
state: record.state,
|
|
358
364
|
...(record.reason === undefined ? {} : { reason: record.reason }),
|