@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.
Files changed (690) hide show
  1. package/README.md +1 -1
  2. package/dist/api-docs.html +3 -3
  3. package/dist/assets/{abnfDiagram-N423BO3Z-D5yLnMt9.js → abnfDiagram-N423BO3Z-D7Xt05gV.js} +1 -1
  4. package/dist/assets/{abnfDiagram-N423BO3Z-bTHtQIhR.js → abnfDiagram-N423BO3Z-dmPRRPEm.js} +1 -1
  5. package/dist/assets/{arc-1DmrBEyG.js → arc-B7W3R5qH.js} +1 -1
  6. package/dist/assets/{arc-BlGK--01.js → arc-BHMlIcaQ.js} +1 -1
  7. package/dist/assets/{architectureDiagram-T3A2C74G--lzbKBn9.js → architectureDiagram-T3A2C74G-CUUpAoN0.js} +1 -1
  8. package/dist/assets/{architectureDiagram-T3A2C74G-7lKNAbUU.js → architectureDiagram-T3A2C74G-DpXhbHxu.js} +1 -1
  9. package/dist/assets/{blockDiagram-VBNYF7ZC-17cdO9zs.js → blockDiagram-VBNYF7ZC-Bf0yfNxj.js} +1 -1
  10. package/dist/assets/{blockDiagram-VBNYF7ZC-BPavJfDj.js → blockDiagram-VBNYF7ZC-Cki9AOhc.js} +1 -1
  11. package/dist/assets/{c4Diagram-5PPSVZJV-Bm1-2w3b.js → c4Diagram-5PPSVZJV-DK2RqNDO.js} +1 -1
  12. package/dist/assets/{c4Diagram-5PPSVZJV-aHvFL3Wb.js → c4Diagram-5PPSVZJV-DyhTF0e5.js} +1 -1
  13. package/dist/assets/channel-DTLMNzbH.js +1 -0
  14. package/dist/assets/channel-DiqxUuPf.js +1 -0
  15. package/dist/assets/{chunk-2GRJ4B5K-D7WqZewM.js → chunk-2GRJ4B5K-BYtByJbf.js} +1 -1
  16. package/dist/assets/{chunk-2GRJ4B5K-DbwzBiPF.js → chunk-2GRJ4B5K-CksFgocc.js} +1 -1
  17. package/dist/assets/{chunk-2Q5K7J3B-DdCr89uy.js → chunk-2Q5K7J3B-D2kQa5TZ.js} +1 -1
  18. package/dist/assets/{chunk-2Q5K7J3B-TFd0ECKO.js → chunk-2Q5K7J3B-NSSX86FA.js} +1 -1
  19. package/dist/assets/{chunk-5RXB4S5H-BdhRBpEi.js → chunk-5RXB4S5H-DNNYC8_t.js} +1 -1
  20. package/dist/assets/{chunk-5RXB4S5H-D0SQ3nIe.js → chunk-5RXB4S5H-Rx0YaqNI.js} +1 -1
  21. package/dist/assets/{chunk-5VM5RSS4-B9Lv3cWR.js → chunk-5VM5RSS4-B1k4I4CX.js} +1 -1
  22. package/dist/assets/{chunk-5VM5RSS4-DioqTIvB.js → chunk-5VM5RSS4-CsvQj3QC.js} +1 -1
  23. package/dist/assets/{chunk-6Q2QTUOP-09bwlcIv.js → chunk-6Q2QTUOP-48-dEgAs.js} +1 -1
  24. package/dist/assets/{chunk-6Q2QTUOP-JuhPJZZL.js → chunk-6Q2QTUOP-DCMSW5_0.js} +1 -1
  25. package/dist/assets/{chunk-GF5L2VYU-C6f2SgCw.js → chunk-GF5L2VYU-CGyvOsdN.js} +1 -1
  26. package/dist/assets/{chunk-GF5L2VYU-DzD9aOyp.js → chunk-GF5L2VYU-YXe113hp.js} +1 -1
  27. package/dist/assets/{chunk-JWPE2WC7-BggnWNZv.js → chunk-JWPE2WC7-BT7vCW4x.js} +1 -1
  28. package/dist/assets/{chunk-JWPE2WC7-Dte_Ax9K.js → chunk-JWPE2WC7-D2K1Oywq.js} +1 -1
  29. package/dist/assets/{chunk-KBJHAD2P-9TCQV92m.js → chunk-KBJHAD2P-CQZWamtE.js} +1 -1
  30. package/dist/assets/{chunk-KBJHAD2P-DDnJp7kJ.js → chunk-KBJHAD2P-gpEwZrNy.js} +1 -1
  31. package/dist/assets/{chunk-RYQCIY6F-CE2Y4D_h.js → chunk-RYQCIY6F-BI0fMtjY.js} +1 -1
  32. package/dist/assets/{chunk-RYQCIY6F-DsgFSTNw.js → chunk-RYQCIY6F-vguRdb4F.js} +1 -1
  33. package/dist/assets/{chunk-XXDRQBXY-B1FIfsqq.js → chunk-XXDRQBXY-B99qH1_w.js} +1 -1
  34. package/dist/assets/{chunk-XXDRQBXY-B4YfaqTO.js → chunk-XXDRQBXY-DZLJnbBB.js} +1 -1
  35. package/dist/assets/classDiagram-JCYQIIEL-BaV-s6x8.js +1 -0
  36. package/dist/assets/classDiagram-JCYQIIEL-D4M03B4L.js +1 -0
  37. package/dist/assets/classDiagram-v2-OCEON4UE-BaV-s6x8.js +1 -0
  38. package/dist/assets/classDiagram-v2-OCEON4UE-D4M03B4L.js +1 -0
  39. package/dist/assets/{cose-bilkent-JH36ORCC-C1AG5Pib.js → cose-bilkent-JH36ORCC-EsVnz-E6.js} +1 -1
  40. package/dist/assets/{cose-bilkent-JH36ORCC-lMwWDibI.js → cose-bilkent-JH36ORCC-VI2OjCIx.js} +1 -1
  41. package/dist/assets/{cynefin-VYW2F7L2-BlabniRL.js → cynefin-VYW2F7L2-BVYg0ixs.js} +1 -1
  42. package/dist/assets/{cynefin-VYW2F7L2-W-c-z4IW.js → cynefin-VYW2F7L2-BnHmA5I2.js} +1 -1
  43. package/dist/assets/{cynefinDiagram-MW4NZA55-BtTep_pq.js → cynefinDiagram-MW4NZA55-B-OCRLIw.js} +1 -1
  44. package/dist/assets/{cynefinDiagram-MW4NZA55-Due6EIPh.js → cynefinDiagram-MW4NZA55-ItLlzjDR.js} +1 -1
  45. package/dist/assets/{dagre-VZM6K2ZE-CWLaFfdt.js → dagre-VZM6K2ZE-DkVDkAWJ.js} +1 -1
  46. package/dist/assets/{dagre-VZM6K2ZE-DZldvqiQ.js → dagre-VZM6K2ZE-bYR4z8-Z.js} +1 -1
  47. package/dist/assets/{diagram-7IWD3JNH-RnmUHYwN.js → diagram-7IWD3JNH-DjXMue67.js} +1 -1
  48. package/dist/assets/{diagram-7IWD3JNH-Di-7-nSA.js → diagram-7IWD3JNH-FNEXlm5k.js} +1 -1
  49. package/dist/assets/{diagram-B4RE2ZJO-Wybyn8fw.js → diagram-B4RE2ZJO-73NYiO_P.js} +1 -1
  50. package/dist/assets/{diagram-B4RE2ZJO-mrK79C2E.js → diagram-B4RE2ZJO-dB4QHq0D.js} +1 -1
  51. package/dist/assets/{diagram-LBJQPF4R-JY6FqSFu.js → diagram-LBJQPF4R-DyKT610O.js} +1 -1
  52. package/dist/assets/{diagram-LBJQPF4R-sWhu2VLy.js → diagram-LBJQPF4R-rMgmnjvd.js} +1 -1
  53. package/dist/assets/{diagram-Q27KOJAE-BJ4T0WGp.js → diagram-Q27KOJAE-BvsfmmQt.js} +1 -1
  54. package/dist/assets/{diagram-Q27KOJAE-DyGT9KhB.js → diagram-Q27KOJAE-c6DEjLQX.js} +1 -1
  55. package/dist/assets/{diagram-UB23O5K3-oXFJAndB.js → diagram-UB23O5K3-BMo2VXVb.js} +1 -1
  56. package/dist/assets/{diagram-UB23O5K3-tTd8qwEM.js → diagram-UB23O5K3-DRMKefnZ.js} +1 -1
  57. package/dist/assets/{ebnfDiagram-BXEA7PRR-DV67cBe6.js → ebnfDiagram-BXEA7PRR-BrOAekWh.js} +1 -1
  58. package/dist/assets/{ebnfDiagram-BXEA7PRR-OQGm8tPs.js → ebnfDiagram-BXEA7PRR-YmQkylwV.js} +1 -1
  59. package/dist/assets/{elk-BRx4gEGg.js → elk-Hz3WRESK.js} +1 -1
  60. package/dist/assets/{elk-CdAQJ-NA.js → elk-tPSZwRVB.js} +1 -1
  61. package/dist/assets/{erDiagram-JOGREHBK-BhD2xZ2I.js → erDiagram-JOGREHBK-BlaZnoQi.js} +1 -1
  62. package/dist/assets/{erDiagram-JOGREHBK-BqP8DqqW.js → erDiagram-JOGREHBK-CRCfRUXt.js} +1 -1
  63. package/dist/assets/{flowDiagram-UKHOOZJN-B4AjZxPJ.js → flowDiagram-UKHOOZJN-DQ1gbjxo.js} +1 -1
  64. package/dist/assets/{flowDiagram-UKHOOZJN-CP_1WsW4.js → flowDiagram-UKHOOZJN-Dinlbmds.js} +1 -1
  65. package/dist/assets/{ganttDiagram-PKOTCBZU-BMk6nngr.js → ganttDiagram-PKOTCBZU-CMGpcBZO.js} +1 -1
  66. package/dist/assets/{ganttDiagram-PKOTCBZU-B_ce39Ld.js → ganttDiagram-PKOTCBZU-Eh94zuPI.js} +1 -1
  67. package/dist/assets/{gitGraphDiagram-DS77QQ5N-CnZA42iA.js → gitGraphDiagram-DS77QQ5N-Bp8xIZbk.js} +1 -1
  68. package/dist/assets/{gitGraphDiagram-DS77QQ5N-DqEz_iTn.js → gitGraphDiagram-DS77QQ5N-Cu-b4YNw.js} +1 -1
  69. package/dist/assets/index-51e8fagd.css +32 -0
  70. package/dist/assets/{index-D5nLH7qP.js → index-CQE9C6k6.js} +356 -356
  71. package/dist/assets/{index-CqyOGerp.js → index-S8ow0XfK.js} +356 -356
  72. package/dist/assets/{infoDiagram-6WML65LV-BQf7m4X4.js → infoDiagram-6WML65LV-CClEEtTq.js} +1 -1
  73. package/dist/assets/{infoDiagram-6WML65LV-Dntf4YFM.js → infoDiagram-6WML65LV-QmHeojgl.js} +1 -1
  74. package/dist/assets/{ishikawaDiagram-WSZJBQD7-BDjsldAI.js → ishikawaDiagram-WSZJBQD7-BemSj9lN.js} +1 -1
  75. package/dist/assets/{ishikawaDiagram-WSZJBQD7-BqXpJeoL.js → ishikawaDiagram-WSZJBQD7-nw48g1vr.js} +1 -1
  76. package/dist/assets/{journeyDiagram-NVQOT4AX-CBcFzP2M.js → journeyDiagram-NVQOT4AX-DeNtO6OU.js} +1 -1
  77. package/dist/assets/{journeyDiagram-NVQOT4AX-DoWKjgKd.js → journeyDiagram-NVQOT4AX-q1lCfOYn.js} +1 -1
  78. package/dist/assets/{kanban-definition-27J2QSJJ-9bspl7j-.js → kanban-definition-27J2QSJJ-Bzhu6hql.js} +1 -1
  79. package/dist/assets/{kanban-definition-27J2QSJJ-Cjxa-Fbb.js → kanban-definition-27J2QSJJ-VfvD33YG.js} +1 -1
  80. package/dist/assets/{linear-YogAXmU_.js → linear-C0Kwu3Yp.js} +1 -1
  81. package/dist/assets/{linear-lIhI5Y8l.js → linear-CbM_4-fP.js} +1 -1
  82. package/dist/assets/{mermaid.core-2Spxcrg7.js → mermaid.core-G2huIsXn.js} +5 -5
  83. package/dist/assets/{mermaid.core-BxxInCBm.js → mermaid.core-fvTQFUX1.js} +5 -5
  84. package/dist/assets/{mindmap-definition-FAOFIHXS-DblO5EG4.js → mindmap-definition-FAOFIHXS-BONvuyvz.js} +1 -1
  85. package/dist/assets/{mindmap-definition-FAOFIHXS-_nlvJ9VK.js → mindmap-definition-FAOFIHXS-BzYawGKQ.js} +1 -1
  86. package/dist/assets/{pegDiagram-VL7TDLO6-BBJFPAZG.js → pegDiagram-VL7TDLO6-Df2HAKGH.js} +1 -1
  87. package/dist/assets/{pegDiagram-VL7TDLO6-DhRH7YRf.js → pegDiagram-VL7TDLO6-DnMwBHn_.js} +1 -1
  88. package/dist/assets/{pieDiagram-7S7Q4E2Y-4Qy7Nk4U.js → pieDiagram-7S7Q4E2Y-Cd3-a-dM.js} +1 -1
  89. package/dist/assets/{pieDiagram-7S7Q4E2Y-BUtdeYBT.js → pieDiagram-7S7Q4E2Y-LV6TOhOD.js} +1 -1
  90. package/dist/assets/{quadrantDiagram-CIZ2JOQS-BUoIDY1r.js → quadrantDiagram-CIZ2JOQS-8VOnA3FV.js} +1 -1
  91. package/dist/assets/{quadrantDiagram-CIZ2JOQS-D90kdHA1.js → quadrantDiagram-CIZ2JOQS-CnwxFPxh.js} +1 -1
  92. package/dist/assets/{railroadDiagram-AXF67PYL-CJf9--tj.js → railroadDiagram-AXF67PYL-CXBFj3Iu.js} +1 -1
  93. package/dist/assets/{railroadDiagram-AXF67PYL-D3S1oliC.js → railroadDiagram-AXF67PYL-DLoAPcsb.js} +1 -1
  94. package/dist/assets/{requirementDiagram-LRYGKXZP-C04jhjS6.js → requirementDiagram-LRYGKXZP-LrVlZXSz.js} +1 -1
  95. package/dist/assets/{requirementDiagram-LRYGKXZP-cQaGai5h.js → requirementDiagram-LRYGKXZP-pakITowN.js} +1 -1
  96. package/dist/assets/{sankeyDiagram-W5VNT64P-AT4cTVbY.js → sankeyDiagram-W5VNT64P-BIQQ8A1I.js} +1 -1
  97. package/dist/assets/{sankeyDiagram-W5VNT64P-DfFUdqYO.js → sankeyDiagram-W5VNT64P-C6QWOxNM.js} +1 -1
  98. package/dist/assets/{sequenceDiagram-SI44F4Z6-DbjhG030.js → sequenceDiagram-SI44F4Z6-CpHBe2CG.js} +1 -1
  99. package/dist/assets/{sequenceDiagram-SI44F4Z6-DKjdupix.js → sequenceDiagram-SI44F4Z6-cnLxaxcV.js} +1 -1
  100. package/dist/assets/{sizeCapture-X5ZJPWSS-CCcKLP8m.js → sizeCapture-X5ZJPWSS-3g-1onHD.js} +1 -1
  101. package/dist/assets/{sizeCapture-X5ZJPWSS-DGxRWxeo.js → sizeCapture-X5ZJPWSS-4U6b3PSL.js} +1 -1
  102. package/dist/assets/{stateDiagram-OKZ733FA-D7wGCNb7.js → stateDiagram-OKZ733FA-CFwVDdlY.js} +1 -1
  103. package/dist/assets/{stateDiagram-OKZ733FA-qdMAailp.js → stateDiagram-OKZ733FA-CKVGJcM2.js} +1 -1
  104. package/dist/assets/{stateDiagram-v2-UEYNNEHI-BbmmtA9w.js → stateDiagram-v2-UEYNNEHI-Dnbk8ftm.js} +1 -1
  105. package/dist/assets/{stateDiagram-v2-UEYNNEHI-Diz_hFvh.js → stateDiagram-v2-UEYNNEHI-rlA-woxH.js} +1 -1
  106. package/dist/assets/{swimlanes-SLNWSIFB-CZgIPz6I.js → swimlanes-SLNWSIFB-DCwz8-mf.js} +2 -2
  107. package/dist/assets/{swimlanes-SLNWSIFB-B16H-6OU.js → swimlanes-SLNWSIFB-M9Oumwnl.js} +2 -2
  108. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CTtTyW6-.js +8 -0
  109. package/dist/assets/swimlanesDiagram-ULZ7WXOC-Caohx6WZ.js +8 -0
  110. package/dist/assets/{timeline-definition-Z64GVDOM-7r7OVlrT.js → timeline-definition-Z64GVDOM-BVmfjoWH.js} +1 -1
  111. package/dist/assets/{timeline-definition-Z64GVDOM-nhnkS_wy.js → timeline-definition-Z64GVDOM-DyXvto1l.js} +1 -1
  112. package/dist/assets/{vennDiagram-T6HMQDX7-B1piFYrz.js → vennDiagram-T6HMQDX7-CNe6zorb.js} +1 -1
  113. package/dist/assets/{vennDiagram-T6HMQDX7-x8SJTFhK.js → vennDiagram-T6HMQDX7-DyzOWKx3.js} +1 -1
  114. package/dist/assets/{wardleyDiagram-T6FBY63Y-BdD4GExj.js → wardleyDiagram-T6FBY63Y-D5YvMVwa.js} +1 -1
  115. package/dist/assets/{wardleyDiagram-T6FBY63Y-C90xqNVS.js → wardleyDiagram-T6FBY63Y-DXo8BCrA.js} +1 -1
  116. package/dist/assets/{xychartDiagram-ELKLHX3M--Ndoz0Cq.js → xychartDiagram-ELKLHX3M-CIBffVxC.js} +1 -1
  117. package/dist/assets/{xychartDiagram-ELKLHX3M-BAKns-7o.js → xychartDiagram-ELKLHX3M-XlsWelDb.js} +1 -1
  118. package/dist/build-info.json +2 -2
  119. package/dist/convert-icons.md +10 -46
  120. package/dist/favicon.png +0 -0
  121. package/dist/favicon.svg +1 -9
  122. package/dist/generate-icons.js +67 -47
  123. package/dist/icons/icon-128x128.png +0 -0
  124. package/dist/icons/icon-144x144.png +0 -0
  125. package/dist/icons/icon-152x152.png +0 -0
  126. package/dist/icons/icon-192x192.png +0 -0
  127. package/dist/icons/icon-384x384.png +0 -0
  128. package/dist/icons/icon-512x512.png +0 -0
  129. package/dist/icons/icon-72x72.png +0 -0
  130. package/dist/icons/icon-96x96.png +0 -0
  131. package/dist/index.html +2 -2
  132. package/dist/logo-128.png +0 -0
  133. package/dist/logo-256.png +0 -0
  134. package/dist/logo-32.png +0 -0
  135. package/dist/logo-512.png +0 -0
  136. package/dist/logo-64.png +0 -0
  137. package/dist/logo-source.png +0 -0
  138. package/dist/logo.svg +1 -17
  139. package/dist/sw.js +7 -9
  140. package/dist-server/build-info.json +2 -2
  141. package/dist-server/server/load-env.js +12 -4
  142. package/dist-server/server/load-env.js.map +1 -1
  143. package/dist-server/server/modules/browser-use/browser-use.service.js +33 -11
  144. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
  145. package/dist-server/server/modules/browser-use/index.js +4 -4
  146. package/dist-server/server/modules/browser-use/index.js.map +1 -1
  147. package/dist-server/server/modules/browser-use/mcp-server-names.js +6 -4
  148. package/dist-server/server/modules/browser-use/mcp-server-names.js.map +1 -1
  149. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js +49 -1
  150. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js.map +1 -1
  151. package/dist-server/server/modules/cli/asset-migration-files.js +74 -0
  152. package/dist-server/server/modules/cli/asset-migration-files.js.map +1 -0
  153. package/dist-server/server/modules/cli/asset-migration-report.js +80 -0
  154. package/dist-server/server/modules/cli/asset-migration-report.js.map +1 -0
  155. package/dist-server/server/modules/cli/asset-migration-store.js +153 -0
  156. package/dist-server/server/modules/cli/asset-migration-store.js.map +1 -0
  157. package/dist-server/server/modules/cli/asset-migration.service.js +161 -0
  158. package/dist-server/server/modules/cli/asset-migration.service.js.map +1 -0
  159. package/dist-server/server/modules/cli/browser-use-mcp.js +9 -4
  160. package/dist-server/server/modules/cli/browser-use-mcp.js.map +1 -1
  161. package/dist-server/server/modules/cli/cli.module.js +21 -1
  162. package/dist-server/server/modules/cli/cli.module.js.map +1 -1
  163. package/dist-server/server/modules/cli/cli.service.js +6 -1
  164. package/dist-server/server/modules/cli/cli.service.js.map +1 -1
  165. package/dist-server/server/modules/cli/tests/asset-migration.service.test.js +275 -0
  166. package/dist-server/server/modules/cli/tests/asset-migration.service.test.js.map +1 -0
  167. package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js +157 -0
  168. package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js.map +1 -1
  169. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +1 -0
  170. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -1
  171. package/dist-server/server/modules/cli/tests/cli.service.test.js +6 -1
  172. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -1
  173. package/dist-server/server/modules/cockpit/cockpit-brief-prompt.js +1 -1
  174. package/dist-server/server/modules/cockpit/cockpit-card-actions.js +19 -3
  175. package/dist-server/server/modules/cockpit/cockpit-card-actions.js.map +1 -1
  176. package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js +94 -9
  177. package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js.map +1 -1
  178. package/dist-server/server/modules/cockpit/cockpit-card-registry.js +1 -1
  179. package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js +3 -0
  180. package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js.map +1 -1
  181. package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js +16 -0
  182. package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js.map +1 -1
  183. package/dist-server/server/modules/cockpit/cockpit.module.js +1 -1
  184. package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js +96 -1
  185. package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js.map +1 -1
  186. package/dist-server/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.js +2 -2
  187. package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js +169 -3
  188. package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js.map +1 -1
  189. package/dist-server/server/modules/context-events/context-event-writer.js +5 -5
  190. package/dist-server/server/modules/context-events/context-events.module.js +2 -2
  191. package/dist-server/server/modules/context-events/session-ask-stream-reader.js +1 -1
  192. package/dist-server/server/modules/context-events/session-blocked-events.js +3 -3
  193. package/dist-server/server/modules/context-events/tests/session-ask-event-writer.test.js +1 -1
  194. package/dist-server/server/modules/context-events/tests/session-blocked-events.test.js +3 -3
  195. package/dist-server/server/modules/context-events/tests/session-run-events.test.js +1 -1
  196. package/dist-server/server/modules/database/migrations.js +23 -1
  197. package/dist-server/server/modules/database/migrations.js.map +1 -1
  198. package/dist-server/server/modules/database/repositories/sessions.db.js +25 -4
  199. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
  200. package/dist-server/server/modules/database/repositories/voice-user-identifiers.db.js +1 -1
  201. package/dist-server/server/modules/database/schema.js +16 -2
  202. package/dist-server/server/modules/database/schema.js.map +1 -1
  203. package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js +2 -0
  204. package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js.map +1 -1
  205. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -2
  206. package/dist-server/server/modules/debug-agent/tests/debug-agent-permission-popup.test.js +2 -2
  207. package/dist-server/server/modules/liaison/liaison-deliver.service.js +3 -3
  208. package/dist-server/server/modules/liaison/liaison.module.js +1 -1
  209. package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js +3 -2
  210. package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js.map +1 -1
  211. package/dist-server/server/modules/mcp-gateway/mcp-self-target.js +2 -2
  212. package/dist-server/server/modules/mcp-gateway/mcp-session-send.js +7 -0
  213. package/dist-server/server/modules/mcp-gateway/mcp-session-send.js.map +1 -1
  214. package/dist-server/server/modules/mcp-gateway/mcp-tool-annotations.js +4 -4
  215. package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js +4 -2
  216. package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js.map +1 -1
  217. package/dist-server/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.js +1 -1
  218. package/dist-server/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.js +2 -2
  219. package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js +3 -2
  220. package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js.map +1 -1
  221. package/dist-server/server/modules/mcp-gateway/tests/mcp-audit-route.test.js +1 -1
  222. package/dist-server/server/modules/mcp-gateway/tests/mcp-audit.test.js +4 -4
  223. package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js +3 -1
  224. package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js.map +1 -1
  225. package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js +3 -2
  226. package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js.map +1 -1
  227. package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js +7 -3
  228. package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js.map +1 -1
  229. package/dist-server/server/modules/mcp-gateway/tests/mcp-correlation-id.test.js +8 -8
  230. package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js +3 -2
  231. package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js.map +1 -1
  232. package/dist-server/server/modules/mcp-gateway/tests/mcp-english-only.test.js +1 -1
  233. package/dist-server/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.js +2 -2
  234. package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js +1 -1
  235. package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js.map +1 -1
  236. package/dist-server/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.js +1 -1
  237. package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js +1 -1
  238. package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js.map +1 -1
  239. package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js +3 -2
  240. package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js.map +1 -1
  241. package/dist-server/server/modules/mcp-gateway/tests/mcp-overview.test.js +2 -2
  242. package/dist-server/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.js +2 -2
  243. package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js +3 -3
  244. package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js.map +1 -1
  245. package/dist-server/server/modules/mcp-gateway/tests/mcp-run-get.test.js +1 -1
  246. package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js +1 -1
  247. package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js.map +1 -1
  248. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js +2 -2
  249. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js.map +1 -1
  250. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js +1 -1
  251. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js.map +1 -1
  252. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js +1 -1
  253. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js.map +1 -1
  254. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js +2 -2
  255. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js.map +1 -1
  256. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.js +1 -1
  257. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search.test.js +1 -1
  258. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js +2 -2
  259. package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js.map +1 -1
  260. package/dist-server/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.js +1 -1
  261. package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js +1 -1
  262. package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js.map +1 -1
  263. package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js +2 -2
  264. package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js.map +1 -1
  265. package/dist-server/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.js +3 -3
  266. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
  267. package/dist-server/server/modules/oauth/access-tokens.service.js +8 -8
  268. package/dist-server/server/modules/oauth/oauth-consent.service.js +20 -15
  269. package/dist-server/server/modules/oauth/oauth-consent.service.js.map +1 -1
  270. package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js +54 -34
  271. package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js.map +1 -1
  272. package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js +35 -14
  273. package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js.map +1 -1
  274. package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js +27 -22
  275. package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js.map +1 -1
  276. package/dist-server/server/modules/oauth/tests/oauth-consent-ratelimit.test.js +2 -2
  277. package/dist-server/server/modules/oauth/tests/token-info.routes.test.js +2 -2
  278. package/dist-server/server/modules/oauth/tests/token-info.routes.test.js.map +1 -1
  279. package/dist-server/server/modules/observation/blind-spots.js +1 -1
  280. package/dist-server/server/modules/observation/observation-store.js +50 -17
  281. package/dist-server/server/modules/observation/observation-store.js.map +1 -1
  282. package/dist-server/server/modules/observation/observation-uri.js +31 -19
  283. package/dist-server/server/modules/observation/observation-uri.js.map +1 -1
  284. package/dist-server/server/modules/observation/observation.routes.js +1 -1
  285. package/dist-server/server/modules/observation/project-truth.js +1 -1
  286. package/dist-server/server/modules/observation/session-ask-decision-answer.js +2 -1
  287. package/dist-server/server/modules/observation/session-ask-decision-answer.js.map +1 -1
  288. package/dist-server/server/modules/observation/session-digest-llm.js +7 -1
  289. package/dist-server/server/modules/observation/session-digest-llm.js.map +1 -1
  290. package/dist-server/server/modules/observation/session-digest.js +39 -5
  291. package/dist-server/server/modules/observation/session-digest.js.map +1 -1
  292. package/dist-server/server/modules/observation/tests/architecture-delta.test.js +1 -1
  293. package/dist-server/server/modules/observation/tests/observation-routes.test.js +9 -0
  294. package/dist-server/server/modules/observation/tests/observation-routes.test.js.map +1 -1
  295. package/dist-server/server/modules/observation/tests/observation-store.test.js +38 -0
  296. package/dist-server/server/modules/observation/tests/observation-store.test.js.map +1 -1
  297. package/dist-server/server/modules/observation/tests/project-truth.test.js +2 -2
  298. package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js +150 -0
  299. package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js.map +1 -1
  300. package/dist-server/server/modules/observation/tests/session-digest.test.js +24 -1
  301. package/dist-server/server/modules/observation/tests/session-digest.test.js.map +1 -1
  302. package/dist-server/server/modules/providers/index.js +9 -0
  303. package/dist-server/server/modules/providers/index.js.map +1 -1
  304. package/dist-server/server/modules/providers/list/claude/claude-host-driver.provider.js +1 -1
  305. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +22 -3
  306. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -1
  307. package/dist-server/server/modules/providers/list/codex/codex-app-server.connection.js +1 -1
  308. package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js +11 -9
  309. package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js.map +1 -1
  310. package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js +15 -1
  311. package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js.map +1 -1
  312. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +14 -3
  313. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
  314. package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js +248 -0
  315. package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js.map +1 -0
  316. package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js +37 -0
  317. package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js.map +1 -0
  318. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +19 -1
  319. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
  320. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -1
  321. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +1 -1
  322. package/dist-server/server/modules/providers/provider.routes.js +23 -2
  323. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  324. package/dist-server/server/modules/providers/services/provider-models.service.js +136 -106
  325. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
  326. package/dist-server/server/modules/providers/services/provider-runtime.service.js +3 -0
  327. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -1
  328. package/dist-server/server/modules/providers/services/session-model-resolver.js +106 -0
  329. package/dist-server/server/modules/providers/services/session-model-resolver.js.map +1 -0
  330. package/dist-server/server/modules/providers/services/session-provider-binding.js +89 -0
  331. package/dist-server/server/modules/providers/services/session-provider-binding.js.map +1 -0
  332. package/dist-server/server/modules/providers/services/sessions.service.js +5 -1
  333. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
  334. package/dist-server/server/modules/providers/tests/claude-resident-addressable.test.js +2 -2
  335. package/dist-server/server/modules/providers/tests/claude-session-name-authority.test.js +4 -4
  336. package/dist-server/server/modules/providers/tests/codex-app-server-protocol.test.js +1 -1
  337. package/dist-server/server/modules/providers/tests/codex-host-driver-persistent.test.js +2 -2
  338. package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js +270 -0
  339. package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js.map +1 -0
  340. package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js +484 -0
  341. package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js.map +1 -0
  342. package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js +228 -0
  343. package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js.map +1 -0
  344. package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js +306 -0
  345. package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js.map +1 -0
  346. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +1 -1
  347. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +2 -2
  348. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +15 -0
  349. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
  350. package/dist-server/server/modules/providers/tests/provider.routes.test.js +1 -1
  351. package/dist-server/server/modules/quay/index.js +1 -1
  352. package/dist-server/server/modules/quay/quay-fleet-cli.js +1 -1
  353. package/dist-server/server/modules/quay/quay-fleet-locator.js +2 -2
  354. package/dist-server/server/modules/quay/quay-fleet-project-id.js +7 -7
  355. package/dist-server/server/modules/quay/quay-fleet-registry.js +3 -3
  356. package/dist-server/server/modules/quay/quay-suite-fanin-reader.js +1 -1
  357. package/dist-server/server/modules/quay/quay-uri-resolve.js +6 -6
  358. package/dist-server/server/modules/quay/quay.module.js +3 -3
  359. package/dist-server/server/modules/quay/quay.routes.js +1 -1
  360. package/dist-server/server/modules/quay/quay.service.js +4 -4
  361. package/dist-server/server/modules/quay/tests/contracts/fleet-cli-contracts.test.js +3 -3
  362. package/dist-server/server/modules/quay/tests/contracts/shapes.js +9 -9
  363. package/dist-server/server/modules/quay/tests/quay-fleet-locator.test.js +1 -1
  364. package/dist-server/server/modules/quay/tests/quay-fleet-project-id.test.js +4 -4
  365. package/dist-server/server/modules/quay/tests/quay-uri-resolve.test.js +10 -10
  366. package/dist-server/server/modules/session-hosts/tests/resident-server-restart.test.js +1 -1
  367. package/dist-server/server/modules/settings/codex-mcp-gateway.settings.js +1 -1
  368. package/dist-server/server/modules/settings/codex-model-providers.schema.js +349 -0
  369. package/dist-server/server/modules/settings/codex-model-providers.schema.js.map +1 -0
  370. package/dist-server/server/modules/settings/codex-model-providers.service.js +199 -0
  371. package/dist-server/server/modules/settings/codex-model-providers.service.js.map +1 -0
  372. package/dist-server/server/modules/settings/codex-model-providers.settings.js +547 -0
  373. package/dist-server/server/modules/settings/codex-model-providers.settings.js.map +1 -0
  374. package/dist-server/server/modules/settings/codex-model-providers.store.js +200 -0
  375. package/dist-server/server/modules/settings/codex-model-providers.store.js.map +1 -0
  376. package/dist-server/server/modules/settings/index.js +10 -0
  377. package/dist-server/server/modules/settings/index.js.map +1 -1
  378. package/dist-server/server/modules/settings/server-settings-file.js +28 -32
  379. package/dist-server/server/modules/settings/server-settings-file.js.map +1 -1
  380. package/dist-server/server/modules/settings/server-settings.js +2 -2
  381. package/dist-server/server/modules/settings/server-settings.js.map +1 -1
  382. package/dist-server/server/modules/settings/settings.module.js +35 -0
  383. package/dist-server/server/modules/settings/settings.module.js.map +1 -1
  384. package/dist-server/server/modules/settings/settings.routes.js +42 -0
  385. package/dist-server/server/modules/settings/settings.routes.js.map +1 -1
  386. package/dist-server/server/modules/settings/settings.service.js +8 -21
  387. package/dist-server/server/modules/settings/settings.service.js.map +1 -1
  388. package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js +1 -0
  389. package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js.map +1 -1
  390. package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js +336 -0
  391. package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js.map +1 -0
  392. package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js +466 -0
  393. package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js.map +1 -0
  394. package/dist-server/server/modules/settings/tests/codex-provider-import.test.js +475 -0
  395. package/dist-server/server/modules/settings/tests/codex-provider-import.test.js.map +1 -0
  396. package/dist-server/server/modules/voice/tests/voice-lexicon.test.js +9 -9
  397. package/dist-server/server/modules/voice/tests/voice-lexicon.test.js.map +1 -1
  398. package/dist-server/server/modules/voice/voice-lexicon.js +1 -1
  399. package/dist-server/server/modules/websocket/services/chat-control.service.js +21 -1
  400. package/dist-server/server/modules/websocket/services/chat-control.service.js.map +1 -1
  401. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +25 -1
  402. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  403. package/dist-server/server/modules/websocket/tests/chat-background-task.test.js +18 -1
  404. package/dist-server/server/modules/websocket/tests/chat-background-task.test.js.map +1 -1
  405. package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js +18 -1
  406. package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js.map +1 -1
  407. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +1 -1
  408. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +1 -1
  409. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +1 -1
  410. package/dist-server/server/shared/brand.js +18 -20
  411. package/dist-server/server/shared/brand.js.map +1 -1
  412. package/dist-server/server/shared/data-root-migration.js +3 -2
  413. package/dist-server/server/shared/data-root-migration.js.map +1 -1
  414. package/dist-server/server/shared/data-root.js +54 -59
  415. package/dist-server/server/shared/data-root.js.map +1 -1
  416. package/dist-server/server/shared/mcp-contract/types.js +20 -15
  417. package/dist-server/server/shared/mcp-contract/types.js.map +1 -1
  418. package/dist-server/server/shared/ports/codex-provider-registry.port.js +66 -0
  419. package/dist-server/server/shared/ports/codex-provider-registry.port.js.map +1 -0
  420. package/dist-server/server/shared/settings-file.js +120 -6
  421. package/dist-server/server/shared/settings-file.js.map +1 -1
  422. package/dist-server/server/shared/tests/cloudpit-brand-env.test.js +76 -34
  423. package/dist-server/server/shared/tests/cloudpit-brand-env.test.js.map +1 -1
  424. package/dist-server/server/shared/tests/cloudpit-data-root.test.js +35 -18
  425. package/dist-server/server/shared/tests/cloudpit-data-root.test.js.map +1 -1
  426. package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js +153 -17
  427. package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js.map +1 -1
  428. package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js +116 -114
  429. package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js.map +1 -1
  430. package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js +9 -1
  431. package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js.map +1 -1
  432. package/dist-server/server/shared/tests/quay-test-script.test.js +40 -6
  433. package/dist-server/server/shared/tests/quay-test-script.test.js.map +1 -1
  434. package/dist-server/server/shared/tests/settings-file.test.js +58 -2
  435. package/dist-server/server/shared/tests/settings-file.test.js.map +1 -1
  436. package/dist-server/server/shared/types.js.map +1 -1
  437. package/dist-server/server/shared/utils.js +1 -1
  438. package/electron/appIdMigration.js +467 -0
  439. package/electron/assets/logo-macos.icns +0 -0
  440. package/electron/assets/logo-macos.png +0 -0
  441. package/electron/assets/logo-windows.ico +0 -0
  442. package/electron/brandEnv.js +64 -0
  443. package/electron/cloud.js +3 -3
  444. package/electron/desktopNotifications.js +1 -1
  445. package/electron/launcher/index.html +1 -1
  446. package/electron/localServer.js +41 -7
  447. package/electron/main.js +33 -15
  448. package/electron/scripts/generate-macos-icon.js +34 -28
  449. package/electron/scripts/generate-windows-icon.js +66 -0
  450. package/electron/serverInstaller.js +20 -11
  451. package/electron/tests/cloudpit-appid-migration.test.mjs +514 -0
  452. package/electron/tests/cloudpit-brand-env-wiring.test.mjs +324 -0
  453. package/electron/tests/cloudpit-desktop-identity.test.mjs +42 -19
  454. package/electron/tests/cloudpit-runtime-identity-surfaces.test.mjs +10 -4
  455. package/electron/tests/cloudpit-userdata-migration.test.mjs +18 -5
  456. package/electron/userDataMigration.js +3 -0
  457. package/package.json +7 -6
  458. package/public/api-docs.html +3 -3
  459. package/scripts/brand-allowlist-check.mjs +233 -12
  460. package/scripts/brand-allowlist-check.test.mjs +270 -1
  461. package/scripts/cloudpit-distribution-check.mjs +57 -23
  462. package/scripts/cloudpit-distribution-check.test.mjs +42 -9
  463. package/scripts/codex-protocol-smoke.mjs +1 -1
  464. package/scripts/isolated-instance.sh +1 -1
  465. package/scripts/mcp-smoke.mjs +2 -2
  466. package/scripts/release/tests/fork-release-workflows.test.mjs +45 -0
  467. package/scripts/release/tests/server-installer-bundle-url.test.mjs +57 -9
  468. package/scripts/restart-when-idle.sh +1 -1
  469. package/scripts/shadow-prediction-report.mjs +1 -1
  470. package/scripts/suite-duration-baseline.tsv +45 -0
  471. package/scripts/ui-scenario.mjs +195 -0
  472. package/scripts/ui-scenarios/codex-provider-import.json +63 -0
  473. package/scripts/ui-scenarios/codex-provider-settings.json +77 -0
  474. package/scripts/voice-capture-process-check.false-forms.test.mjs +1 -1
  475. package/scripts/voice-phase0-report.test.mjs +1 -1
  476. package/server/load-env.ts +15 -4
  477. package/server/modules/browser-use/browser-use.service.ts +45 -14
  478. package/server/modules/browser-use/index.ts +3 -4
  479. package/server/modules/browser-use/mcp-server-names.ts +6 -5
  480. package/server/modules/browser-use/tests/browser-use.service.test.ts +63 -1
  481. package/server/modules/cli/asset-migration-files.ts +96 -0
  482. package/server/modules/cli/asset-migration-report.ts +123 -0
  483. package/server/modules/cli/asset-migration-store.ts +228 -0
  484. package/server/modules/cli/asset-migration.service.ts +236 -0
  485. package/server/modules/cli/browser-use-mcp.ts +9 -4
  486. package/server/modules/cli/cli.module.ts +21 -1
  487. package/server/modules/cli/cli.service.ts +14 -1
  488. package/server/modules/cli/tests/asset-migration.service.test.ts +349 -0
  489. package/server/modules/cli/tests/browser-use-mcp-entry.test.ts +202 -0
  490. package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +1 -0
  491. package/server/modules/cli/tests/cli.service.test.ts +6 -1
  492. package/server/modules/cockpit/cockpit-brief-prompt.ts +1 -1
  493. package/server/modules/cockpit/cockpit-card-actions.ts +20 -3
  494. package/server/modules/cockpit/cockpit-card-feedback-store.ts +104 -9
  495. package/server/modules/cockpit/cockpit-card-registry.ts +2 -2
  496. package/server/modules/cockpit/cockpit-fleet-card-projection.ts +3 -0
  497. package/server/modules/cockpit/cockpit-fleet-executor.ts +1 -1
  498. package/server/modules/cockpit/cockpit-knowledge-reading.ts +17 -0
  499. package/server/modules/cockpit/cockpit.module.ts +2 -2
  500. package/server/modules/cockpit/cockpit.reducer.ts +1 -1
  501. package/server/modules/cockpit/tests/cockpit-card-feedback.test.ts +116 -1
  502. package/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.ts +2 -2
  503. package/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.ts +205 -3
  504. package/server/modules/context-events/context-event-writer.ts +6 -6
  505. package/server/modules/context-events/context-events.module.ts +2 -2
  506. package/server/modules/context-events/session-ask-stream-reader.ts +1 -1
  507. package/server/modules/context-events/session-blocked-events.ts +3 -3
  508. package/server/modules/context-events/tests/session-ask-event-writer.test.ts +1 -1
  509. package/server/modules/context-events/tests/session-blocked-events.test.ts +3 -3
  510. package/server/modules/context-events/tests/session-run-events.test.ts +1 -1
  511. package/server/modules/database/migrations.ts +24 -1
  512. package/server/modules/database/repositories/sessions.db.ts +41 -4
  513. package/server/modules/database/repositories/voice-user-identifiers.db.ts +1 -1
  514. package/server/modules/database/schema.ts +16 -2
  515. package/server/modules/database/tests/migrations-ensure-columns.test.ts +2 -0
  516. package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -2
  517. package/server/modules/debug-agent/tests/debug-agent-permission-popup.test.ts +2 -2
  518. package/server/modules/liaison/liaison-deliver.service.ts +4 -4
  519. package/server/modules/liaison/liaison.module.ts +1 -1
  520. package/server/modules/mcp-gateway/mcp-gateway.auth.ts +3 -2
  521. package/server/modules/mcp-gateway/mcp-self-target.ts +2 -2
  522. package/server/modules/mcp-gateway/mcp-session-send.ts +21 -2
  523. package/server/modules/mcp-gateway/mcp-tool-annotations.ts +4 -4
  524. package/server/modules/mcp-gateway/oauth-metadata.gate.ts +4 -5
  525. package/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.ts +1 -1
  526. package/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.ts +2 -2
  527. package/server/modules/mcp-gateway/tests/mcp-approvals.test.ts +3 -2
  528. package/server/modules/mcp-gateway/tests/mcp-audit-route.test.ts +1 -1
  529. package/server/modules/mcp-gateway/tests/mcp-audit.test.ts +4 -4
  530. package/server/modules/mcp-gateway/tests/mcp-auth.test.ts +3 -1
  531. package/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.ts +3 -2
  532. package/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.ts +7 -3
  533. package/server/modules/mcp-gateway/tests/mcp-correlation-id.test.ts +8 -8
  534. package/server/modules/mcp-gateway/tests/mcp-draft.test.ts +3 -2
  535. package/server/modules/mcp-gateway/tests/mcp-english-only.test.ts +1 -1
  536. package/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.ts +2 -2
  537. package/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.ts +1 -1
  538. package/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.ts +1 -1
  539. package/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.ts +1 -1
  540. package/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.ts +3 -2
  541. package/server/modules/mcp-gateway/tests/mcp-overview.test.ts +2 -2
  542. package/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.ts +2 -2
  543. package/server/modules/mcp-gateway/tests/mcp-read-tools.test.ts +3 -3
  544. package/server/modules/mcp-gateway/tests/mcp-run-get.test.ts +1 -1
  545. package/server/modules/mcp-gateway/tests/mcp-self-target.test.ts +1 -1
  546. package/server/modules/mcp-gateway/tests/mcp-session-background.test.ts +2 -2
  547. package/server/modules/mcp-gateway/tests/mcp-session-host-control.test.ts +1 -1
  548. package/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.ts +1 -1
  549. package/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.ts +2 -2
  550. package/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.ts +1 -1
  551. package/server/modules/mcp-gateway/tests/mcp-session-search.test.ts +1 -1
  552. package/server/modules/mcp-gateway/tests/mcp-session-send.test.ts +2 -2
  553. package/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.ts +1 -1
  554. package/server/modules/mcp-gateway/tests/mcp-usage-stats.test.ts +1 -1
  555. package/server/modules/mcp-gateway/tests/mcp-write-notification.test.ts +2 -2
  556. package/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.ts +3 -3
  557. package/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
  558. package/server/modules/oauth/access-tokens.service.ts +8 -8
  559. package/server/modules/oauth/oauth-consent.service.ts +20 -15
  560. package/server/modules/oauth/tests/access-token-scopes.test.ts +55 -34
  561. package/server/modules/oauth/tests/access-tokens.service.test.ts +50 -14
  562. package/server/modules/oauth/tests/oauth-consent-page.test.ts +29 -21
  563. package/server/modules/oauth/tests/oauth-consent-ratelimit.test.ts +2 -2
  564. package/server/modules/oauth/tests/token-info.routes.test.ts +2 -2
  565. package/server/modules/observation/architecture-delta.producer.ts +1 -1
  566. package/server/modules/observation/blind-spots.ts +1 -1
  567. package/server/modules/observation/observation-store.ts +54 -16
  568. package/server/modules/observation/observation-uri.ts +34 -21
  569. package/server/modules/observation/observation.routes.ts +1 -1
  570. package/server/modules/observation/project-truth.ts +3 -3
  571. package/server/modules/observation/session-ask-decision-answer.ts +2 -1
  572. package/server/modules/observation/session-digest-llm.ts +7 -1
  573. package/server/modules/observation/session-digest.ts +39 -5
  574. package/server/modules/observation/tests/architecture-delta.test.ts +1 -1
  575. package/server/modules/observation/tests/observation-routes.test.ts +13 -0
  576. package/server/modules/observation/tests/observation-store.test.ts +58 -0
  577. package/server/modules/observation/tests/project-truth.test.ts +2 -2
  578. package/server/modules/observation/tests/session-ask-decision-digest.test.ts +189 -0
  579. package/server/modules/observation/tests/session-digest.test.ts +43 -0
  580. package/server/modules/providers/index.ts +13 -0
  581. package/server/modules/providers/list/claude/claude-host-driver.provider.ts +1 -1
  582. package/server/modules/providers/list/codex/codex-app-server.client.ts +37 -5
  583. package/server/modules/providers/list/codex/codex-app-server.connection.ts +1 -1
  584. package/server/modules/providers/list/codex/codex-host-driver.contract.ts +18 -9
  585. package/server/modules/providers/list/codex/codex-host-driver.provider.ts +15 -1
  586. package/server/modules/providers/list/codex/codex-models.provider.ts +16 -3
  587. package/server/modules/providers/list/codex/codex-provider-injection.ts +323 -0
  588. package/server/modules/providers/list/codex/codex-resident-provider-launch.ts +71 -0
  589. package/server/modules/providers/list/codex/codex-runtime.provider.ts +20 -1
  590. package/server/modules/providers/list/cursor/cursor-models.provider.ts +1 -1
  591. package/server/modules/providers/list/opencode/opencode-models.provider.ts +1 -1
  592. package/server/modules/providers/provider.routes.ts +23 -2
  593. package/server/modules/providers/services/provider-models.service.ts +187 -124
  594. package/server/modules/providers/services/provider-runtime.service.ts +3 -0
  595. package/server/modules/providers/services/session-model-resolver.ts +180 -0
  596. package/server/modules/providers/services/session-provider-binding.ts +176 -0
  597. package/server/modules/providers/services/sessions.service.ts +5 -1
  598. package/server/modules/providers/tests/claude-resident-addressable.test.ts +2 -2
  599. package/server/modules/providers/tests/claude-session-name-authority.test.ts +4 -4
  600. package/server/modules/providers/tests/codex-app-server-protocol.test.ts +1 -1
  601. package/server/modules/providers/tests/codex-host-driver-persistent.test.ts +2 -2
  602. package/server/modules/providers/tests/codex-provider-model-binding.test.ts +345 -0
  603. package/server/modules/providers/tests/codex-resident-provider-injection.test.ts +561 -0
  604. package/server/modules/providers/tests/codex-runtime-provider-injection.test.ts +269 -0
  605. package/server/modules/providers/tests/codex-session-provider-binding.test.ts +386 -0
  606. package/server/modules/providers/tests/codex-sessions.test.ts +1 -1
  607. package/server/modules/providers/tests/opencode-sessions.test.ts +2 -2
  608. package/server/modules/providers/tests/provider-models.service.test.ts +15 -0
  609. package/server/modules/providers/tests/provider.routes.test.ts +1 -1
  610. package/server/modules/quay/index.ts +1 -1
  611. package/server/modules/quay/quay-dispatch-carrier.ts +1 -1
  612. package/server/modules/quay/quay-fleet-cli.ts +1 -1
  613. package/server/modules/quay/quay-fleet-locator.ts +2 -2
  614. package/server/modules/quay/quay-fleet-project-id.ts +14 -14
  615. package/server/modules/quay/quay-fleet-registry.ts +8 -8
  616. package/server/modules/quay/quay-suite-fanin-reader.ts +1 -1
  617. package/server/modules/quay/quay-uri-resolve.ts +8 -8
  618. package/server/modules/quay/quay.module.ts +3 -3
  619. package/server/modules/quay/quay.routes.ts +1 -1
  620. package/server/modules/quay/quay.service.ts +6 -6
  621. package/server/modules/quay/session-task-chain.service.ts +1 -1
  622. package/server/modules/quay/tests/contracts/fleet-cli-contracts.test.ts +3 -3
  623. package/server/modules/quay/tests/contracts/shapes.ts +10 -10
  624. package/server/modules/quay/tests/quay-fleet-locator.test.ts +1 -1
  625. package/server/modules/quay/tests/quay-fleet-project-id.test.ts +6 -6
  626. package/server/modules/quay/tests/quay-uri-resolve.test.ts +10 -10
  627. package/server/modules/session-hosts/tests/resident-server-restart.test.ts +1 -1
  628. package/server/modules/settings/codex-mcp-gateway.settings.ts +1 -1
  629. package/server/modules/settings/codex-model-providers.schema.ts +460 -0
  630. package/server/modules/settings/codex-model-providers.service.ts +235 -0
  631. package/server/modules/settings/codex-model-providers.settings.ts +713 -0
  632. package/server/modules/settings/codex-model-providers.store.ts +244 -0
  633. package/server/modules/settings/index.ts +18 -0
  634. package/server/modules/settings/server-settings-file.ts +29 -41
  635. package/server/modules/settings/server-settings.ts +2 -3
  636. package/server/modules/settings/settings.module.ts +41 -0
  637. package/server/modules/settings/settings.routes.ts +37 -0
  638. package/server/modules/settings/settings.service.ts +21 -26
  639. package/server/modules/settings/tests/cockpit-session-start-settings.routes.test.ts +1 -0
  640. package/server/modules/settings/tests/codex-model-providers-settings.test.ts +413 -0
  641. package/server/modules/settings/tests/codex-provider-advanced.test.ts +540 -0
  642. package/server/modules/settings/tests/codex-provider-import.test.ts +621 -0
  643. package/server/modules/voice/tests/voice-lexicon.test.ts +10 -10
  644. package/server/modules/voice/voice-lexicon.ts +1 -1
  645. package/server/modules/websocket/services/chat-control.service.ts +35 -2
  646. package/server/modules/websocket/services/chat-websocket.service.ts +25 -1
  647. package/server/modules/websocket/tests/chat-background-task.test.ts +17 -1
  648. package/server/modules/websocket/tests/chat-stop-task.test.ts +17 -1
  649. package/server/modules/worktrees/services/worktree-list.service.ts +1 -1
  650. package/server/modules/worktrees/services/worktree-open.service.ts +1 -1
  651. package/server/modules/worktrees/services/worktree-remove.service.ts +1 -1
  652. package/server/shared/brand.ts +24 -38
  653. package/server/shared/data-root-migration.ts +3 -2
  654. package/server/shared/data-root.ts +73 -79
  655. package/server/shared/interfaces.ts +1 -1
  656. package/server/shared/mcp-contract/types.ts +20 -15
  657. package/server/shared/ports/codex-provider-registry.port.ts +133 -0
  658. package/server/shared/ports/session-blocked-events.port.ts +1 -1
  659. package/server/shared/ports/session-run-events.port.ts +2 -2
  660. package/server/shared/settings-file.ts +167 -6
  661. package/server/shared/tests/architecture-ratchet.baseline.json +15 -15
  662. package/server/shared/tests/cloudpit-brand-env.test.ts +106 -36
  663. package/server/shared/tests/cloudpit-data-root.test.ts +42 -18
  664. package/server/shared/tests/cloudpit-goal-exit-gate.baseline.json +6 -2
  665. package/server/shared/tests/cloudpit-goal-exit-gate.test.ts +179 -17
  666. package/server/shared/tests/cloudpit-runtime-flip.test.ts +162 -123
  667. package/server/shared/tests/frontend-import-cycle-budget.baseline.json +8 -6
  668. package/server/shared/tests/frontend-import-cycle-budget.test.ts +9 -1
  669. package/server/shared/tests/quay-test-script.test.ts +40 -6
  670. package/server/shared/tests/settings-file.test.ts +83 -1
  671. package/server/shared/types.ts +121 -8
  672. package/server/shared/utils.ts +1 -1
  673. package/dist/assets/channel-D7XqNTJC.js +0 -1
  674. package/dist/assets/channel-sbQyI1an.js +0 -1
  675. package/dist/assets/classDiagram-JCYQIIEL-DHudi-zH.js +0 -1
  676. package/dist/assets/classDiagram-JCYQIIEL-DV7ybJJG.js +0 -1
  677. package/dist/assets/classDiagram-v2-OCEON4UE-DHudi-zH.js +0 -1
  678. package/dist/assets/classDiagram-v2-OCEON4UE-DV7ybJJG.js +0 -1
  679. package/dist/assets/index-BsACp0s2.css +0 -32
  680. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CNMNp6YA.js +0 -8
  681. package/dist/assets/swimlanesDiagram-ULZ7WXOC-DOjtDEUW.js +0 -8
  682. package/dist/icons/icon-128x128.svg +0 -12
  683. package/dist/icons/icon-144x144.svg +0 -12
  684. package/dist/icons/icon-152x152.svg +0 -12
  685. package/dist/icons/icon-192x192.svg +0 -12
  686. package/dist/icons/icon-384x384.svg +0 -12
  687. package/dist/icons/icon-512x512.svg +0 -12
  688. package/dist/icons/icon-72x72.svg +0 -12
  689. package/dist/icons/icon-96x96.svg +0 -12
  690. 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, `cloudcli:read` flagged
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 ACCESS_TOKEN_SCOPES vocabulary.
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[] = [READ_SCOPE],
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, [READ_SCOPE, WRITE_SCOPE], 'state-abc');
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 cloudcli:read required and non-writable', async () => {
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 === READ_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 === READ_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: [READ_SCOPE],
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 submitted set plus cloudcli:read', async () => {
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: [WRITE_SCOPE],
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, [READ_SCOPE], 'xyz', evil)}`,
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: [READ_SCOPE],
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: [READ_SCOPE],
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, [READ_SCOPE], 'state-doc');
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: [READ_SCOPE],
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', CREATE_SCOPE, CREATE_SCOPE, NAVIGATE_SCOPE],
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: [READ_SCOPE],
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: [WRITE_SCOPE],
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: ['cloudcli:read'], action: 'allow',
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, [READ_SCOPE], 'state-browser', callback);
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 = 'cloudcli:read';
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 = 'cloudcli:session:send';
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: ['cloudcli:read'],
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, ['cloudcli:read']);
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 CloudCLI project the architecture service resolves to a root;
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
- '部署层只对 CloudCLI 自身有意义',
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
- uri: row.uri,
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 { userId: row.userId, uri: row.uri, revision: row.revision, at: row.at };
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([...observationDb.listWatchUserIds(uri), ...observationDb.listSeenUserIds(uri)]);
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 cloudcli://session/<id> (or cloudpit://session/<id>), cloudcli://architecture/<id> (or cloudpit://architecture/<id>), quay://<id>/board', 'INVALID_URI');
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.uri,
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 observationDb.listRevisionsAfter(parsed.uri, afterRevision).map(toObservedRevision);
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.uri, at);
450
- const entry: WatchEntry = { userId: row.userId, uri: row.uri, pinnedAt: row.pinnedAt };
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
- const pins = observationDb.listWatchEntries(key);
478
- const pinnedUris = new Set(pins.map((pin) => pin.uri));
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
- cursors.set(cursor.uri, cursor.revision);
507
+ const uri = canonicalObservationUri(cursor.uri);
508
+ cursors.set(uri, Math.max(cursors.get(uri) ?? 0, cursor.revision));
482
509
  }
483
510
 
484
- const candidates: ObservationWallEntry[] = [];
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 = observationDb
495
- .listRevisionsAfter(object.uri, seenRevision)
496
- .flatMap((revision) => parseDeltaItems(revision.deltaItemsJson));
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
- * cloudcli://session/<id> — one CloudCLI session
11
- * cloudcli://architecture/<projectId> — one project's architecture graph
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 cloudcli scheme is CloudCLI's; quay's board URI is kept verbatim because the fleet owns
22
- * that address space and will own its "seen" write-back later (see the task's Notes). An id
23
- * segment may not be empty, may not contain `/`, `?`, `#` or whitespace, and is not
24
- * percent-decoded here: the routes decode the path parameter once, and every other caller
25
- * builds the URI with the formatters below.
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: 'cloudcli'; kind: 'session'; id: string; uri: string }
42
- | { scheme: 'cloudcli'; kind: 'architecture'; id: string; uri: string }
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 CLOUDCLI_URI = new RegExp(`^(?:cloudcli|cloudpit)://(session|architecture)/(${SEGMENT})$`);
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 `cloudcli://session/<id>` spelling. */
59
+ /** The canonical `cloudpit://session/<id>` spelling 2.1 writes. */
55
60
  export function formatSessionUri(id: string): string {
56
- return `cloudcli://session/${id}`;
61
+ return `cloudpit://session/${id}`;
57
62
  }
58
63
 
59
- /** The canonical `cloudcli://architecture/<id>` spelling. */
64
+ /** The canonical `cloudpit://architecture/<id>` spelling 2.1 writes. */
60
65
  export function formatArchitectureUri(projectId: string): string {
61
- return `cloudcli://architecture/${projectId}`;
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 cloudcli = CLOUDCLI_URI.exec(value);
98
- if (cloudcli !== null) {
99
- const kind = cloudcli[1] === 'session' ? 'session' : 'architecture';
100
- const id = cloudcli[2]!;
101
- // Both spellings parse, but the canonical string (and the DB key) stays the
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 cloudcli://session/<id>, cloudcli://architecture/<id>, quay://<id>/board');
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
- /** CloudCLI's own project id, used only to ask the quay service for a snapshot. */
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
- * CloudCLI itself does; every other project's deploy layer is `not-applicable`.
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 = '该项目没有部署概念(目前只有 CloudCLI 自身有部署)';
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:助手原文用编号或项目符号列出若干选择时,必须为每一项给出一条 option(label 用原文的选项名);原文没有列出选择才用空数组 []。does 是选它会发生什么,tags 是后果标签(kind 用 consequence / risk / cost / benefit)。',
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.replace(/^cloudcli:\/\/session\//, ''),
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 }),