@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
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Per-run Codex SDK provider injection (AC-464).
3
+ *
4
+ * The runtime used to always construct `new Codex()` with no options, so a
5
+ * model bound to a project upstream provider still dialled Codex's global
6
+ * default. This criterion pins the three readings that make the binding real:
7
+ *
8
+ * - POSITIVE: a model whose public config carries `codexProviderId` compiles
9
+ * `config.model_provider` + `config.model_providers.<id>` (base_url,
10
+ * env_key, wire_api) and passes the token-file secret in the child env
11
+ * under `env_key`. The REAL Codex SDK spawns the REAL bundled CLI, which
12
+ * POSTs to a local mock `/v1/responses`; the mock asserts the request's
13
+ * `Authorization` header is `Bearer <token-file secret>`.
14
+ * - ISOLATION: a host sentinel variable present in `process.env` is absent
15
+ * from the child env, while plumbing (PATH/HOME) survives.
16
+ * - NEGATIVE: a model with no `codexProviderId` still constructs `new Codex()`
17
+ * with neither `config` nor `env`; a model bound to an unknown provider is
18
+ * refused with a readable line and never falls back to the default endpoint.
19
+ */
20
+ import assert from 'node:assert/strict';
21
+ import http from 'node:http';
22
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
23
+ import type { AddressInfo } from 'node:net';
24
+ import os from 'node:os';
25
+ import path from 'node:path';
26
+ import test, { type TestContext } from 'node:test';
27
+
28
+ import { Codex } from '@openai/codex-sdk';
29
+ import type { CodexOptions, Thread, ThreadOptions } from '@openai/codex-sdk';
30
+
31
+ import { codexRuntime } from '@/modules/providers/list/codex/codex-runtime.provider.js';
32
+ import {
33
+ createCodexModelProvidersSource,
34
+ } from '@/modules/settings/index.js';
35
+ import {
36
+ installCodexProviderRegistryPort,
37
+ } from '@/shared/ports/codex-provider-registry.port.js';
38
+ import type { ProviderRuntimeContext } from '@/shared/index.js';
39
+
40
+ const HOST_SENTINEL_KEY = 'CC_CODEX_HOST_SENTINEL';
41
+ const HOST_SENTINEL_VALUE = 'host-secret-that-must-not-reach-the-child';
42
+ const PROVIDER_ID = 'bob';
43
+ const ENV_KEY = 'BOB_API_KEY';
44
+ const TOKEN_SECRET = 'token-file-secret-4242';
45
+
46
+ /** One request the bundled CLI made to the mock endpoint. */
47
+ type SeenRequest = { url: string; authorization: string | undefined };
48
+
49
+ /**
50
+ * A local Responses-API mock. A 400 is deliberate: Codex 0.166 treats it as a
51
+ * terminal client error (no 5xx retry/backoff), so the criterion settles in
52
+ * well under a second while still exercising the real HTTP path — including the
53
+ * `Authorization` header the provider's `env_key` produces.
54
+ */
55
+ async function startMockResponsesApi(): Promise<{
56
+ requests: SeenRequest[];
57
+ baseUrl: string;
58
+ close(): Promise<void>;
59
+ }> {
60
+ const requests: SeenRequest[] = [];
61
+ const server = http.createServer((request, response) => {
62
+ requests.push({
63
+ url: request.url ?? '',
64
+ authorization: typeof request.headers.authorization === 'string'
65
+ ? request.headers.authorization
66
+ : undefined,
67
+ });
68
+ request.resume();
69
+ response.writeHead(400, { 'content-type': 'application/json' });
70
+ response.end(JSON.stringify({ error: { message: 'mock: provider injection criterion' } }));
71
+ });
72
+
73
+ await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
74
+ const { port } = server.address() as AddressInfo;
75
+ return {
76
+ requests,
77
+ baseUrl: `http://127.0.0.1:${port}/v1`,
78
+ close: () => new Promise<void>((resolve, reject) => {
79
+ server.close((error) => (error ? reject(error) : resolve()));
80
+ }),
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Writes the production settings document + token file, then installs the real
86
+ * settings source in the shared registry port. Nothing about the resolution is
87
+ * stubbed: the runtime reads the JSON and the 0600 token file through the same
88
+ * `resolve()` the production composition root installs.
89
+ */
90
+ async function withProviderRegistry(
91
+ baseUrl: string,
92
+ run: (home: string) => Promise<void>,
93
+ ): Promise<void> {
94
+ const directory = await mkdtemp(path.join(os.tmpdir(), 'codex-perrun-injection-'));
95
+ const settingsPath = path.join(directory, 'codex.settings.json');
96
+ const tokenFile = path.join(directory, 'bob.token');
97
+ await writeFile(tokenFile, TOKEN_SECRET, { encoding: 'utf8', mode: 0o600 });
98
+ await writeFile(
99
+ settingsPath,
100
+ JSON.stringify({
101
+ modelProviders: {
102
+ [PROVIDER_ID]: {
103
+ name: 'Bob Upstream',
104
+ baseUrl,
105
+ envKey: ENV_KEY,
106
+ tokenFile,
107
+ },
108
+ },
109
+ }),
110
+ 'utf8',
111
+ );
112
+
113
+ const source = createCodexModelProvidersSource({ settingsPath, env: {}, homeDir: directory });
114
+ installCodexProviderRegistryPort({
115
+ read: () => ({
116
+ providers: source.read().providers.map((provider) => ({ id: provider.id })),
117
+ reservedIds: [],
118
+ }),
119
+ resolve: (id) => source.resolve(id),
120
+ });
121
+
122
+ try {
123
+ await run(directory);
124
+ } finally {
125
+ await rm(directory, { recursive: true, force: true });
126
+ }
127
+ }
128
+
129
+ /** A context whose single model option carries (or omits) a provider binding. */
130
+ function contextForModel(
131
+ modelId: string,
132
+ codexProviderId?: string,
133
+ ): ProviderRuntimeContext {
134
+ return {
135
+ resolveProviderSessionId: () => null,
136
+ resolveResumeModel: async () => modelId,
137
+ getProviderModels: async () => ({
138
+ OPTIONS: [{
139
+ value: modelId,
140
+ label: modelId,
141
+ isCustom: true,
142
+ config: codexProviderId === undefined
143
+ ? { env: [] }
144
+ : { codexProviderId, env: [] },
145
+ }],
146
+ DEFAULT: modelId,
147
+ }),
148
+ normalizeMessage: () => [],
149
+ isProviderInstalled: async () => true,
150
+ };
151
+ }
152
+
153
+ /**
154
+ * Captures the options the runtime handed the REAL SDK constructor while
155
+ * letting the original `startThread` run, so the CLI still starts for real.
156
+ */
157
+ function captureCodexOptions(t: TestContext): { options: () => CodexOptions } {
158
+ let captured: CodexOptions | undefined;
159
+ const originalStartThread = Codex.prototype.startThread;
160
+ t.mock.method(Codex.prototype, 'startThread', function startThread(
161
+ this: Codex,
162
+ options?: ThreadOptions,
163
+ ): Thread {
164
+ captured = (this as unknown as { options: CodexOptions }).options;
165
+ return originalStartThread.call(this, options);
166
+ });
167
+ return {
168
+ options: () => {
169
+ assert.ok(captured, 'the runtime must construct the SDK through startThread');
170
+ return captured;
171
+ },
172
+ };
173
+ }
174
+
175
+ test('AC-464: a bound model launches the real SDK under its provider and the token file supplies Authorization', async (t) => {
176
+ const mock = await startMockResponsesApi();
177
+ const previousHome = process.env.HOME;
178
+ process.env[HOST_SENTINEL_KEY] = HOST_SENTINEL_VALUE;
179
+
180
+ try {
181
+ await withProviderRegistry(mock.baseUrl, async (home) => {
182
+ // Keep the real CLI's session/config writes inside the criterion's temp
183
+ // directory instead of the operator's ~/.codex.
184
+ process.env.HOME = home;
185
+ const capture = captureCodexOptions(t);
186
+
187
+ const messages: any[] = [];
188
+ await codexRuntime.run('hello provider', {
189
+ sessionId: 'codex-perrun-injection',
190
+ model: 'bound-model',
191
+ cwd: home,
192
+ permissionMode: 'bypassPermissions',
193
+ }, { isWebSocketWriter: true, send: (message) => messages.push(message) }, contextForModel('bound-model', PROVIDER_ID));
194
+
195
+ const options = capture.options();
196
+ assert.deepEqual(options.config, {
197
+ model_provider: PROVIDER_ID,
198
+ model_providers: {
199
+ [PROVIDER_ID]: {
200
+ name: 'Bob Upstream',
201
+ base_url: mock.baseUrl,
202
+ env_key: ENV_KEY,
203
+ wire_api: 'responses',
204
+ },
205
+ },
206
+ });
207
+ assert.equal(options.env?.[ENV_KEY], TOKEN_SECRET);
208
+ assert.equal(options.env?.[HOST_SENTINEL_KEY], undefined, 'a host sentinel must not reach the child');
209
+
210
+ // The real bundled CLI actually spoke to the mock: the secret arrived as
211
+ // the bearer token, which is the end-to-end reading the config alone
212
+ // cannot prove.
213
+ assert.ok(mock.requests.length >= 1, `the real CLI must call the mock; messages=${JSON.stringify(messages)}`);
214
+ assert.equal(mock.requests[0].url, '/v1/responses');
215
+ assert.equal(mock.requests[0].authorization, `Bearer ${TOKEN_SECRET}`);
216
+ });
217
+ } finally {
218
+ if (previousHome === undefined) delete process.env.HOME;
219
+ else process.env.HOME = previousHome;
220
+ delete process.env[HOST_SENTINEL_KEY];
221
+ await mock.close();
222
+ }
223
+ });
224
+
225
+ test('AC-464: an unbound model keeps the previous no-options construction', async (t) => {
226
+ let captured: CodexOptions | undefined;
227
+ const fakeThread = {
228
+ id: 'native-thread',
229
+ async runStreamed() {
230
+ return { events: (async function* () {})() };
231
+ },
232
+ } as unknown as Thread;
233
+ // No CLI is needed for the negative reading: the question is what the runtime
234
+ // handed the constructor, and the SDK stores it on the instance.
235
+ t.mock.method(Codex.prototype, 'startThread', function startThread(this: Codex) {
236
+ captured = (this as unknown as { options: CodexOptions }).options;
237
+ return fakeThread;
238
+ });
239
+
240
+ await codexRuntime.run('hello default', {
241
+ model: 'unbound-model',
242
+ cwd: os.tmpdir(),
243
+ }, { isWebSocketWriter: true, send: () => {} }, contextForModel('unbound-model'));
244
+
245
+ assert.ok(captured, 'the runtime must construct the SDK through startThread');
246
+ assert.equal(captured.config, undefined);
247
+ assert.equal(captured.env, undefined);
248
+ });
249
+
250
+ test('AC-464: a model bound to an unknown provider fails readably and never dials the default', async (t) => {
251
+ const mock = await startMockResponsesApi();
252
+ try {
253
+ await withProviderRegistry(mock.baseUrl, async (home) => {
254
+ const messages: any[] = [];
255
+ await codexRuntime.run('hello nobody', {
256
+ model: 'dangling-model',
257
+ cwd: home,
258
+ }, { isWebSocketWriter: true, send: (message) => messages.push(message) }, contextForModel('dangling-model', 'nobody'));
259
+
260
+ const error = messages.find((message) => message.kind === 'error');
261
+ assert.ok(error, `an unresolvable provider must surface an error; messages=${JSON.stringify(messages)}`);
262
+ assert.match(String(error.content), /nobody/);
263
+ assert.match(String(error.content), /not configured/);
264
+ assert.equal(mock.requests.length, 0, 'a refusal must not spawn the CLI against any endpoint');
265
+ });
266
+ } finally {
267
+ await mock.close();
268
+ }
269
+ });
@@ -0,0 +1,386 @@
1
+ import assert from 'node:assert/strict';
2
+ import { once } from 'node:events';
3
+ import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
4
+ import type { AddressInfo } from 'node:net';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+ import test from 'node:test';
8
+
9
+ import express, { type NextFunction, type Request, type Response } from 'express';
10
+
11
+ import {
12
+ closeConnection,
13
+ getConnection,
14
+ initializeDatabase,
15
+ providerModelsDb,
16
+ sessionsDb,
17
+ } from '@/modules/database/index.js';
18
+ import providerRouter from '@/modules/providers/provider.routes.js';
19
+ import { providerModelsService } from '@/modules/providers/index.js';
20
+ import { sessionsService } from '@/modules/providers/services/sessions.service.js';
21
+ import { providerRegistry } from '@/modules/providers/provider.registry.js';
22
+ import {
23
+ installCodexProviderRegistryPort,
24
+ type CodexProviderRegistryReading,
25
+ } from '@/shared/ports/codex-provider-registry.port.js';
26
+ import type { IProviderFork } from '@/shared/interfaces.js';
27
+ import { AppError } from '@/shared/utils.js';
28
+
29
+ /**
30
+ * A session records the upstream provider its model is bound to (AC-462).
31
+ *
32
+ * Legs:
33
+ * 1. the sessions row gains `model_provider_id`, and the first send records the
34
+ * provider the selected model entry declares (`codexProviderId`);
35
+ * 2. a model that declares no provider leaves the session unbound;
36
+ * 3. moving a bound session to a selection that runs under a DIFFERENT provider
37
+ * is refused with the fork/new-session action, and nothing is written; the
38
+ * same provider with another model is an ordinary switch;
39
+ * 4. a provider that was deleted or renamed is MARKED — the recorded model is
40
+ * still the one the conversation ran with, never the catalog default — and a
41
+ * fresh binding to it is refused;
42
+ * 5. a row that recorded no binding (a session from before the column, or one
43
+ * that only ever ran unbound) can still establish one;
44
+ * 6. the HTTP route answers the refusal with the same code and message;
45
+ * 7. a fork inherits the binding, because its source thread started under it;
46
+ * 8. the pre-admission send guard refuses the same switch before a run exists.
47
+ *
48
+ * WHY THESE READ THE SERVICE, NOT A COPY OF ITS LOGIC. `setSessionModel` is the
49
+ * funnel every send passes through (`chat.send`, `chat.edit-send`, the
50
+ * active-model route and the MCP reconfigure tool), so a green run over it is a
51
+ * reading of the guard every entry point shares. The registry is a shared port
52
+ * installed by the settings module in production; these legs install a fake
53
+ * reading and mutate its ids to model a deleted or renamed provider.
54
+ */
55
+
56
+ const BOUND_BOB = 'bound-bob-model';
57
+ const BOUND_BOB_SECOND = 'bound-bob-second-model';
58
+ const BOUND_ALICE = 'bound-alice-model';
59
+ const UNBOUND = 'plain-unbound-model';
60
+
61
+ type BindingWorkspace = {
62
+ baseUrl: string;
63
+ workspacePath: string;
64
+ /** The project provider ids the fake registry currently defines. */
65
+ providerIds: Set<string>;
66
+ };
67
+
68
+ const createRegistry = (): { providerIds: Set<string>; read: () => CodexProviderRegistryReading } => {
69
+ const providerIds = new Set(['bob', 'alice']);
70
+ const read = (): CodexProviderRegistryReading => ({
71
+ providers: [...providerIds].map((id) => ({ id })),
72
+ reservedIds: ['openai', 'ollama', 'lmstudio'],
73
+ });
74
+ return { providerIds, read };
75
+ };
76
+
77
+ async function withBindingWorkspace(run: (context: BindingWorkspace) => Promise<void>): Promise<void> {
78
+ const previousDatabasePath = process.env.DATABASE_PATH;
79
+ const directory = await mkdtemp(path.join(os.tmpdir(), 'codex-session-provider-binding-'));
80
+ const workspacePath = path.join(directory, 'workspace');
81
+ await mkdir(workspacePath, { recursive: true });
82
+ const { providerIds, read } = createRegistry();
83
+
84
+ closeConnection();
85
+ process.env.DATABASE_PATH = path.join(directory, 'auth.db');
86
+ await writeFile(process.env.DATABASE_PATH, '');
87
+ await initializeDatabase();
88
+ // Installed before the first write: the service reads this port lazily, so
89
+ // every leg below is judged against the registry this test states.
90
+ installCodexProviderRegistryPort({ read });
91
+
92
+ const app = express().use(express.json()).use('/api/providers', providerRouter);
93
+ app.use((error: unknown, _req: Request, res: Response, _next: NextFunction) => {
94
+ if (error instanceof AppError) {
95
+ res.status(error.statusCode).json({
96
+ success: false,
97
+ error: { code: error.code, message: error.message },
98
+ });
99
+ return;
100
+ }
101
+ res.status(500).json({ success: false, error: { code: 'INTERNAL_ERROR' } });
102
+ });
103
+ const server = app.listen(0, '127.0.0.1');
104
+ await once(server, 'listening');
105
+
106
+ try {
107
+ const address = server.address() as AddressInfo;
108
+ await run({ baseUrl: `http://127.0.0.1:${address.port}`, workspacePath, providerIds });
109
+ } finally {
110
+ await new Promise<void>((resolve, reject) => {
111
+ server.close((error) => error ? reject(error) : resolve());
112
+ });
113
+ closeConnection();
114
+ if (previousDatabasePath === undefined) {
115
+ delete process.env.DATABASE_PATH;
116
+ } else {
117
+ process.env.DATABASE_PATH = previousDatabasePath;
118
+ }
119
+ await rm(directory, { recursive: true, force: true });
120
+ }
121
+ }
122
+
123
+ /** Seeds one custom Codex model entry; `providerId` is its `codexProviderId`. */
124
+ function seedModel(modelId: string, providerId?: string): void {
125
+ providerModelsDb.createCustomProviderModel('codex', {
126
+ id: modelId,
127
+ model: modelId,
128
+ config: providerId === undefined ? { env: [] } : { env: [], codexProviderId: providerId },
129
+ });
130
+ }
131
+
132
+ /** Seeds the app row a send would write to. */
133
+ function seedSession(sessionId: string, workspacePath: string, provider = 'codex'): void {
134
+ sessionsDb.createAppSession(sessionId, provider, workspacePath, 'Binding session');
135
+ }
136
+
137
+ function sessionColumns(): string[] {
138
+ return (getConnection().prepare('PRAGMA table_info(sessions)').all() as Array<{ name: string }>)
139
+ .map((column) => column.name);
140
+ }
141
+
142
+ /**
143
+ * The refusal a provider switch must produce: 409, the recorded id, what the
144
+ * requested selection would run under, and the way out.
145
+ */
146
+ function providerSwitchRefusal(expectedTarget: RegExp): (error: unknown) => boolean {
147
+ return (error: unknown): boolean => {
148
+ assert.ok(error instanceof AppError, `expected an AppError, got ${String(error)}`);
149
+ assert.equal(error.statusCode, 409);
150
+ assert.equal(error.code, 'SESSION_PROVIDER_MISMATCH');
151
+ assert.match(error.message, /"bob"/);
152
+ assert.match(error.message, expectedTarget);
153
+ assert.match(error.message, /fork this session/i);
154
+ assert.match(error.message, /start a new one/i);
155
+ return true;
156
+ };
157
+ }
158
+
159
+ test('the first send records the upstream provider its model is bound to, and readers carry it', async () => {
160
+ await withBindingWorkspace(async ({ workspacePath }) => {
161
+ assert.ok(
162
+ sessionColumns().includes('model_provider_id'),
163
+ 'the sessions table must carry the column this feature records into',
164
+ );
165
+
166
+ seedModel(BOUND_BOB, 'bob');
167
+ seedSession('first-send', workspacePath);
168
+
169
+ const stored = providerModelsService.setSessionModel('codex', 'first-send', BOUND_BOB);
170
+
171
+ assert.equal(sessionsDb.getSessionById('first-send')?.model_provider_id, 'bob');
172
+ assert.equal(stored?.modelProviderId, 'bob');
173
+ assert.equal(stored?.modelProviderProblem, null);
174
+
175
+ const resolved = await providerModelsService.resolveSessionModel('codex', { sessionId: 'first-send' });
176
+ assert.equal(resolved.model, BOUND_BOB);
177
+ assert.equal(resolved.modelProviderId, 'bob');
178
+ assert.equal(resolved.modelProviderProblem, null);
179
+ assert.equal(resolved.source, 'session');
180
+
181
+ // Write-once: a later write cannot move the conversation behind the guard.
182
+ assert.equal(sessionsDb.setSessionModelProviderId('first-send', 'alice'), false);
183
+ assert.equal(sessionsDb.getSessionById('first-send')?.model_provider_id, 'bob');
184
+ });
185
+ });
186
+
187
+ test('a model that declares no provider leaves the session unbound', async () => {
188
+ await withBindingWorkspace(async ({ workspacePath }) => {
189
+ seedModel(UNBOUND);
190
+ seedSession('unbound-session', workspacePath);
191
+
192
+ const stored = providerModelsService.setSessionModel('codex', 'unbound-session', UNBOUND);
193
+
194
+ assert.equal(sessionsDb.getSessionById('unbound-session')?.model_provider_id, null);
195
+ assert.equal(stored?.modelProviderId, null);
196
+ assert.equal(stored?.modelProviderProblem, null);
197
+
198
+ const resolved = await providerModelsService.resolveSessionModel('codex', { sessionId: 'unbound-session' });
199
+ assert.equal(resolved.model, UNBOUND);
200
+ assert.equal(resolved.modelProviderId, null);
201
+ assert.equal(resolved.modelProviderProblem, null);
202
+ });
203
+ });
204
+
205
+ test('moving a bound session to another provider is refused with the fork action; the same provider is not', async () => {
206
+ await withBindingWorkspace(async ({ workspacePath }) => {
207
+ seedModel(BOUND_BOB, 'bob');
208
+ seedModel(BOUND_BOB_SECOND, 'bob');
209
+ seedModel(BOUND_ALICE, 'alice');
210
+ seedModel(UNBOUND);
211
+ seedSession('bound-session', workspacePath);
212
+ providerModelsService.setSessionModel('codex', 'bound-session', BOUND_BOB);
213
+
214
+ // Another provider's model — including a model that would inherit the
215
+ // process-global provider (NULL) — is a provider switch, not a model switch.
216
+ assert.throws(
217
+ () => providerModelsService.setSessionModel('codex', 'bound-session', BOUND_ALICE),
218
+ providerSwitchRefusal(/"alice"/),
219
+ );
220
+ assert.throws(
221
+ () => providerModelsService.setSessionModel('codex', 'bound-session', UNBOUND),
222
+ providerSwitchRefusal(/inherits the provider default/),
223
+ );
224
+
225
+ // Nothing was written by either refusal.
226
+ const unchanged = sessionsDb.getSessionById('bound-session');
227
+ assert.equal(unchanged?.model, BOUND_BOB);
228
+ assert.equal(unchanged?.model_provider_id, 'bob');
229
+
230
+ // Another model on the SAME provider is an ordinary switch.
231
+ providerModelsService.setSessionModel('codex', 'bound-session', BOUND_BOB_SECOND);
232
+ const switched = sessionsDb.getSessionById('bound-session');
233
+ assert.equal(switched?.model, BOUND_BOB_SECOND);
234
+ assert.equal(switched?.model_provider_id, 'bob');
235
+ });
236
+ });
237
+
238
+ test('a deleted or renamed provider is marked, and the session keeps the model it ran with', async () => {
239
+ await withBindingWorkspace(async ({ workspacePath, providerIds }) => {
240
+ seedModel(BOUND_BOB, 'bob');
241
+ seedSession('orphaned-session', workspacePath);
242
+ providerModelsService.setSessionModel('codex', 'orphaned-session', BOUND_BOB);
243
+
244
+ const before = await providerModelsService.resolveSessionModel('codex', { sessionId: 'orphaned-session' });
245
+ assert.equal(before.modelProviderProblem, null, 'a provider that still exists is not marked');
246
+
247
+ // Renaming the provider is a full-file replacement of the registry: the old
248
+ // id disappears, exactly as a delete would.
249
+ providerIds.delete('bob');
250
+ providerIds.add('robert');
251
+
252
+ const after = await providerModelsService.resolveSessionModel('codex', { sessionId: 'orphaned-session' });
253
+ // The model is the recorded one, NOT the catalog default: a provider that
254
+ // disappeared must not make the session look like it never picked a model.
255
+ assert.equal(after.model, BOUND_BOB);
256
+ assert.equal(after.modelProviderId, 'bob');
257
+ assert.ok(after.modelProviderProblem);
258
+ assert.match(after.modelProviderProblem, /"bob"/);
259
+ assert.match(after.modelProviderProblem, /no longer defined/);
260
+ assert.match(after.modelProviderProblem, /fork this session/i);
261
+
262
+ // The row itself is untouched by the read.
263
+ const row = sessionsDb.getSessionById('orphaned-session');
264
+ assert.equal(row?.model, BOUND_BOB);
265
+ assert.equal(row?.model_provider_id, 'bob');
266
+
267
+ // A fresh binding to the retired provider is refused, and writes nothing.
268
+ seedSession('fresh-session', workspacePath);
269
+ assert.throws(
270
+ () => providerModelsService.setSessionModel('codex', 'fresh-session', BOUND_BOB),
271
+ (error: unknown) => error instanceof AppError
272
+ && error.statusCode === 409
273
+ && error.code === 'SESSION_PROVIDER_UNKNOWN'
274
+ && /"bob"/.test(error.message)
275
+ && /no longer exists/.test(error.message),
276
+ );
277
+ const fresh = sessionsDb.getSessionById('fresh-session');
278
+ assert.equal(fresh?.model_provider_id, null);
279
+ });
280
+ });
281
+
282
+ test('a row that recorded no binding can still establish one', async () => {
283
+ await withBindingWorkspace(async ({ workspacePath }) => {
284
+ seedModel(UNBOUND);
285
+ seedModel(BOUND_BOB, 'bob');
286
+ seedSession('legacy-session', workspacePath);
287
+
288
+ // A session from before the column: it has a model, but no provider id.
289
+ sessionsDb.setSessionModel('legacy-session', UNBOUND);
290
+ assert.equal(sessionsDb.getSessionById('legacy-session')?.model_provider_id, null);
291
+
292
+ const stored = providerModelsService.setSessionModel('codex', 'legacy-session', BOUND_BOB);
293
+
294
+ assert.equal(stored?.modelProviderId, 'bob');
295
+ assert.equal(sessionsDb.getSessionById('legacy-session')?.model_provider_id, 'bob');
296
+ });
297
+ });
298
+
299
+ test('the active-model route answers the refusal with the same readable code', async () => {
300
+ await withBindingWorkspace(async ({ baseUrl, workspacePath }) => {
301
+ seedModel(BOUND_BOB, 'bob');
302
+ seedModel(BOUND_ALICE, 'alice');
303
+ seedSession('route-session', workspacePath);
304
+ providerModelsService.setSessionModel('codex', 'route-session', BOUND_BOB);
305
+
306
+ const refused = await fetch(`${baseUrl}/api/providers/codex/sessions/route-session/active-model`, {
307
+ method: 'POST',
308
+ headers: { 'content-type': 'application/json' },
309
+ body: JSON.stringify({ model: BOUND_ALICE }),
310
+ });
311
+ const refusedBody = await refused.json() as { error?: { code?: string; message?: string } };
312
+
313
+ assert.equal(refused.status, 409);
314
+ assert.equal(refusedBody.error?.code, 'SESSION_PROVIDER_MISMATCH');
315
+ assert.match(String(refusedBody.error?.message), /fork this session/i);
316
+ assert.equal(sessionsDb.getSessionById('route-session')?.model, BOUND_BOB);
317
+
318
+ const reading = await fetch(`${baseUrl}/api/providers/codex/sessions/route-session/active-model`);
319
+ const readingBody = await reading.json() as {
320
+ data: { model: string; modelProviderId: string | null; modelProviderProblem: string | null };
321
+ };
322
+ assert.equal(readingBody.data.model, BOUND_BOB);
323
+ assert.equal(readingBody.data.modelProviderId, 'bob');
324
+ assert.equal(readingBody.data.modelProviderProblem, null);
325
+ });
326
+ });
327
+
328
+ test('a fork inherits the upstream provider binding of the conversation it branched from', async () => {
329
+ await withBindingWorkspace(async ({ workspacePath }) => {
330
+ const sourcePath = path.join(workspacePath, 'native-source.jsonl');
331
+ const forkedPath = path.join(workspacePath, 'native-fork.jsonl');
332
+ await writeFile(sourcePath, '{}\n', 'utf8');
333
+ await writeFile(forkedPath, '{}\n', 'utf8');
334
+
335
+ seedSession('fork-source', workspacePath, 'claude');
336
+ sessionsDb.assignProviderSessionId('fork-source', 'native-source');
337
+ getConnection()
338
+ .prepare('UPDATE sessions SET jsonl_path = ? WHERE session_id = ?')
339
+ .run(sourcePath, 'fork-source');
340
+ sessionsDb.setSessionModelProviderId('fork-source', 'bob');
341
+
342
+ const claude = providerRegistry.resolveProvider('claude') as { fork?: IProviderFork };
343
+ const realFork = claude.fork;
344
+ Object.defineProperty(claude, 'fork', {
345
+ configurable: true,
346
+ writable: true,
347
+ value: {
348
+ forkSession: async () => ({ providerSessionId: 'native-fork', jsonlPath: forkedPath }),
349
+ } as IProviderFork,
350
+ });
351
+
352
+ try {
353
+ const result = await sessionsService.forkSessionById('fork-source');
354
+ // The branch resumes a thread the provider started under `bob`; dropping
355
+ // the binding would make that resume the mismatch this column prevents.
356
+ assert.equal(sessionsDb.getSessionById(result.sessionId)?.model_provider_id, 'bob');
357
+ } finally {
358
+ Object.defineProperty(claude, 'fork', { configurable: true, writable: true, value: realFork });
359
+ }
360
+ });
361
+ });
362
+
363
+ test('the pre-admission send guard refuses the switch and passes the first send', async () => {
364
+ await withBindingWorkspace(async ({ workspacePath }) => {
365
+ seedModel(BOUND_BOB, 'bob');
366
+ seedModel(BOUND_ALICE, 'alice');
367
+ seedSession('guard-session', workspacePath);
368
+
369
+ // A session with no recorded binding: the first send is exactly where one
370
+ // is allowed to be established, so the guard passes.
371
+ assert.doesNotThrow(() => {
372
+ providerModelsService.assertSessionProviderSwitch('codex', 'guard-session', BOUND_BOB);
373
+ });
374
+
375
+ providerModelsService.setSessionModel('codex', 'guard-session', BOUND_BOB);
376
+
377
+ assert.throws(
378
+ () => providerModelsService.assertSessionProviderSwitch('codex', 'guard-session', BOUND_ALICE),
379
+ providerSwitchRefusal(/"alice"/),
380
+ );
381
+ // Same provider, another model: nothing for the guard to refuse.
382
+ assert.doesNotThrow(() => {
383
+ providerModelsService.assertSessionProviderSwitch('codex', 'guard-session', BOUND_BOB);
384
+ });
385
+ });
386
+ });
@@ -78,7 +78,7 @@ const writeCodexTranscript = async (
78
78
  return filePath;
79
79
  };
80
80
 
81
- test('Codex synchronizer preserves the title assigned when CloudCLI creates a session', { concurrency: false }, async () => {
81
+ test('Codex synchronizer preserves the title assigned when Cloudpit creates a session', { concurrency: false }, async () => {
82
82
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'codex-session-sync-app-'));
83
83
  const workspacePath = path.join(tempRoot, 'workspace');
84
84
  await mkdir(workspacePath, { recursive: true });
@@ -509,14 +509,14 @@ const seedOpenCodeSession = async (
509
509
  }
510
510
  };
511
511
 
512
- test('OpenCode synchronizer preserves the title assigned when CloudCLI creates a session', { concurrency: false }, async () => {
512
+ test('OpenCode synchronizer preserves the title assigned when Cloudpit creates a session', { concurrency: false }, async () => {
513
513
  const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'opencode-session-sync-app-'));
514
514
  const workspacePath = path.join(tempRoot, 'workspace');
515
515
  await mkdir(workspacePath, { recursive: true });
516
516
  const restoreHomeDir = patchHomeDir(tempRoot);
517
517
 
518
518
  try {
519
- // Both provider-owned values differ from the CloudCLI title so either one
519
+ // Both provider-owned values differ from the Cloudpit title so either one
520
520
  // leaking through would change the assertion below.
521
521
  await seedOpenCodeSession(tempRoot, workspacePath, {
522
522
  sessionId: 'oc-app-1',