chainlesschain 0.165.5 → 0.165.6

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 (193) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-CEeYTeDB.js → AIOps-vfoDb6HZ.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BeRUQ3V2.js → ActionButton-Cm5f7p93.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DrV718XF.js → Analytics-yRuvgWxa.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-Cd2Frt7Q.js → AppLayout-BROsC4h1.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-CUJMlORU.js → Artifacts-CimHApb1.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CXJcfT6p.js → Audit-DI8kr8zI.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DOv6Z7H9.js → BackgroundAgents-DSLzKy-n.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BwdDyBI0.js → Backup-DkH_n2r1.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BmLn4kYH.js → BaseInput-CKSrUoRA.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-COg8pAW2.js → Chat-ClwfMXUS.js} +4 -4
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-CjMaqfL7.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-BCP4uoU8.js → Checkbox-BYTehcQG.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-pRt6Y9JI.js → Codegen-B8AMcp6J.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DLaprKhS.js → Col-BNSogPo3.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DyATsz5f.js → Community-JxPvGb8O.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BXAaupZK.js → Compact-DF7bFAgE.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-DpcJBELr.js → Compliance-Bvhqnwrq.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-DG4EFWyd.js → Cowork-BDS0CJvM.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-F6Oy5n2P.js → Cron-DqvRfxoQ.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BOdgtalX.js → Crosschain-CDcIvnqS.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-DT1dSkjH.js → DID-D7jaUxU3.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-NBUIqWzC.js → Dashboard-B5A18wEV.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CSpHeMYB.js → Dropdown-_6IVkGag.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-CEG0xISr.js → EmailListRenderer-C9PeiKCG.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BTZ0BZna.js → FamilyGuardDashboard-DXjuEHrX.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BuuCTn2V.js → Federation-B4IAR9zv.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-KAVceevk.js → FormItemContext-CxQeSNx1.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-DnHpcQvW.js → GenericCardRenderer-B8GS-Y3N.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-C_B_0HwB.js → Git-BS8SouUX.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-DPSZuzuu.js → Governance-Dq9aYb5Q.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BV-06V7q.js → Inference-BrCEe9AJ.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-wpDuupn6.js → KnowledgeGraph-DybOpiY2.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Bseca1_I.js → Logs-DBpzbRfx.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-d3kM4DDL.js → Marketplace-Cc7CCSCu.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-DQ_xZ23i.js → McpTools-DFaIhOfu.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-CRIeYO4L.js → Memory-KCqlp9ol.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BsllIa9l.js → MobileBridge-Bys84ySN.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BUuQy30X.js → MobileProjects-B-6qU-je.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-BOFDIzrC.js → Mtc-BgY-fvCq.js} +4 -4
  42. package/src/assets/web-panel/assets/{MtcAudit-BQg-vyvG.js → MtcAudit-B8pCmqQJ.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-Bo1jrPdN.js → Multisig-BbOmYutA.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-Bmod8alw.js → NLProgramming-BocLQz_M.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CGGFL8w-.js → Notes-CSwbxEop.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BsZvCJxC.js → NotificationSettings-CqFNSYG3.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C1-Quo_h.js → OrderTableRenderer-C6gMfAk7.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-BjOeDYOi.js → Organization-QrDXVdMJ.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-DwVV3l5A.js → Overflow-Cxntotjt.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-Cu3DQT9W.js → P2P-CIdBOwNq.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Cg0gR7dH.js → PdhVaultBrowser-CT5aP8rD.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-CsAXxRN5.js → Permissions-DH7OM8XU.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-C-nNmnYp.js → PersonalDataHub-CnJqbWce.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-BOnW7nNc.js → Pipeline-5C3HG1kH.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-ClLSyGKt.js → Privacy-B4yIp7xK.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-DuLvjjq7.js → ProjectInit-BMvt-2M0.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DQYYbDD9.js → ProjectSettings-CvSTEMRG.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Drw8MBGK.js → Projects-BKBJxEek.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-ckqHQe6K.js → Providers-BdwUqFWN.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-DW5BXk-G.js → QrScannerModal-DtnCKlTm.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-DDLnhNTp.js → QuickAsk-sTbgwyNr.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-PJQ2C91U.js → Recommend-Bzr14gSb.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-s6wmda34.js → RemoteSession-C_TF5IaJ.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-DC2sb-I3.js → Reputation-GCAM4H2K.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-hPGk1eGj.js → Row-Dir0r6OQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-RIvfZql0.js → RssFeed-CpGnlecX.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DFg1G1eR.js → Search-DMMamC6u.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-D6H5p8Dp.js → Security-yqay5yG-.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-nxYiFV_w.js → Services-C5i2wh9G.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-BmgFNAdB.js → Skeleton-vUqk35yj.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CsaaD2av.js → Skills-DzcSkhot.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-yM5y9yvK.js → Sla-CB6qbYNr.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DPy1XMYh.js → SpeechSettings-BHUI7cox.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-CFVhEyyr.js → SyncSettings-D-RrsxTJ.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-DdO02Inn.js → Tasks-DFxdOJiq.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Eo2d8Llu.js → Templates-SKAob_Aq.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-ChESOXgy.js → Tenant-BPfsfHQ-.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-BJ7oDxTI.js → Terminal-8iw7FpUf.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-hWX0fUvz.js → TimelineRenderer-C4Gjj5Su.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DVBZQnd-.js → Tokens-COYhN18e.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-D89cQfVq.js → Trigger-B-JzXcf6.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BIVSb4-V.js → Trust-BJ5bg0nI.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B58gWopl.js → UkeySign-BG_ByRMf.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DhHI7bmG.js → VideoEditing-B3kOnSiU.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-C4FheWS_.js → Wallet-CcoGFnK7.js} +3 -3
  86. package/src/assets/web-panel/assets/{WebAuthn-DnPRq-Bx.js → WebAuthn-DdT8vRC_.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-BerRPjpJ.js → WorkflowEditor-CZu3M9N8.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BzZ52iKr.js → chat-DxJt3Qba.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BI_E4BAn.js → colors-DdYfwJaB.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-d50mr3yk.js → compact-item-BG3SUzwj.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-C6FsQ1IH.js → createContext-By51z2-1.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLZEMgLP.js → hasIn-B0apZ3KJ.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BoNZlzhQ.js → index-3jWkIu5j.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-AHr7ryWf.js → index-B3rWuPMW.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-KNGgO4Wm.js → index-B5rLiEo0.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-IPkwSAW_.js → index-BBPf3TpM.js} +1 -1
  98. package/src/assets/web-panel/assets/index-BETiL0a3.js +1 -0
  99. package/src/assets/web-panel/assets/{index-Dec0Kf_Z.js → index-BIrJfqO4.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BTpIOTfR.js → index-BLIbGOLX.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BcSUl9fA.js → index-BP94CrBV.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-B81mo1Et.js → index-BWF8_mkx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DoFtCVZ7.js → index-BYINoRLK.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DY4j5zkF.js → index-BZ_0qm4g.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CVzuawCX.js → index-BewKYrX9.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DE0V6cp-.js → index-BfWYsB9t.js} +1 -1
  107. package/src/assets/web-panel/assets/index-BhAVHuW8.js +1 -0
  108. package/src/assets/web-panel/assets/{index-BRGx3w6T.js → index-Bissefox.js} +3 -3
  109. package/src/assets/web-panel/assets/{index-CjuKZBqJ.js → index-BkvcEo4p.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-9H_M2jju.js → index-Bos5_aMV.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DqkbHHg8.js → index-C1C9i79A.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Y2-q7QLm.js → index-CAhHirVH.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Q5Tn735s.js → index-CNIxXMmN.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CO8DAF7U.js → index-CW93tZDv.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BZjjdQ62.js → index-CWEuZWCK.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C3k8kevG.js → index-Cp6e-hGw.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CUaEHfQ0.js → index-CpjZhgNd.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-GXE0D8Nx.js → index-CzmQElZy.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bmr_vxXD.js → index-DCn8IcxV.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D-aBumtY.js → index-DE76D-kA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BeM4hfht.js → index-DaIz0NAW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Pvf30m8Q.js → index-Da_WBdLX.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BAE3hwev.js → index-Dz49VOyQ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CdKt9fOd.js → index-Q2SCX-MI.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CRN5TRTQ.js → index-RD6O-0C6.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DsscwxPE.js → index-SQqOlR3d.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-TWG-_D1M.js → index-ZFbps9po.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CLoTQr0W.js → index-ZxtP8jG7.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BB9SqVSt.js → index-bP_VlDb4.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-A5CDWP7y.js → index-kf57LJ93.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CgkoH3_g.js → index-oxRrmFO9.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Co7s9LsB.js → index-p1_8SbI1.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-D-4Hzgej.js → initDefaultProps-BWJktcg8.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-D4Wl4xU7.js → motion-BEXBzUFV.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-Cd5eQvL0.js → move-BUKwn2sx.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-B4ilslCW.js → mtc-parser-FTI7btqQ.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-Ckarx-tf.js → omit-CsLtSPH3.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-QJ0bpCmc.js → pickAttrs-DWZxsT_S.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-CKHm-tq8.js → placementArrow-Bcfs43CX.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-CV6a_w_Y.js → responsiveObserve-a9bcC1p-.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-mHpeQFgk.js → slide-BDTzgOXN.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-DIaQNQWA.js → statusUtils-Iq1j_HUg.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-PJpzavV8.js → styleChecker-DAZEYxeh.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-BH7zTw8S.js → useFlexGapSupport-DVkjyDrh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-BDNG3JDd.js → useFs-wXTpNTHt.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CY2VWdUg.js → usePersonalDataHub-CtQM_aZr.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D0kw9jhz.js → vnode-hjEoG85v.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-B5g7TN7r.js → zoom-BHVpyKg_.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +14 -2
  152. package/src/commands/background-session.js +100 -10
  153. package/src/commands/mcp.js +5 -0
  154. package/src/commands/plugin.js +145 -29
  155. package/src/commands/remote-control.js +295 -110
  156. package/src/commands/session-message.js +171 -0
  157. package/src/commands/session.js +11 -0
  158. package/src/data/changelog.json +15 -2
  159. package/src/harness/mcp-client.js +141 -10
  160. package/src/lib/background-session-transport.js +153 -27
  161. package/src/lib/mcp-client.js +2 -0
  162. package/src/lib/mcp-headers-helper.js +47 -5
  163. package/src/lib/mcp-oauth.js +55 -6
  164. package/src/lib/mcp-tls.js +230 -0
  165. package/src/lib/output-styles.js +12 -0
  166. package/src/lib/plugin-runtime/install.js +614 -71
  167. package/src/lib/plugin-runtime/marketplace-archive-source.js +331 -0
  168. package/src/lib/plugin-runtime/marketplace-catalog.js +52 -6
  169. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
  170. package/src/lib/plugin-runtime/marketplace-source-adapter.js +163 -0
  171. package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
  172. package/src/lib/plugin-runtime/remote-source.js +435 -55
  173. package/src/lib/plugin-security.js +393 -41
  174. package/src/lib/plugin-source-identity.js +850 -0
  175. package/src/lib/remote-approval-bridge.js +136 -46
  176. package/src/lib/remote-control.js +217 -31
  177. package/src/lib/session-message-fabric.js +1105 -0
  178. package/src/lib/session-projection.js +45 -2
  179. package/src/lib/session-runtime-retention.js +155 -0
  180. package/src/lib/settings-loader.cjs +29 -0
  181. package/src/repl/agent-repl.js +51 -14
  182. package/src/repl/permission-prompt.js +31 -8
  183. package/src/repl/repl-keybindings.js +55 -0
  184. package/src/runtime/agent-core.js +51 -2
  185. package/src/runtime/headless-runner.js +47 -66
  186. package/src/runtime/headless-stream.js +18 -24
  187. package/src/runtime/mcp-config.js +2 -0
  188. package/src/runtime/policies/agent-policy.js +2 -0
  189. package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +0 -1
  190. package/src/assets/web-panel/assets/MarkdownRenderer-B4RLp2zs.js +0 -1
  191. package/src/assets/web-panel/assets/devWarning-CagEcIex.js +0 -1
  192. package/src/assets/web-panel/assets/index-pzT9PpOU.js +0 -1
  193. package/src/assets/web-panel/assets/index-z1kFadaX.js +0 -1
@@ -615,6 +615,37 @@ function approvalSummary(source, state) {
615
615
  };
616
616
  }
617
617
 
618
+ function messagingSummary(sessionIds, fabric) {
619
+ const linked = new Set(
620
+ (Array.isArray(sessionIds) ? sessionIds : [sessionIds]).filter(Boolean),
621
+ );
622
+ const endpoints = Array.isArray(fabric?.endpoints)
623
+ ? fabric.endpoints
624
+ .filter((endpoint) => linked.has(endpoint?.sessionId))
625
+ .map((endpoint) => ({
626
+ name: asText(endpoint?.name),
627
+ address: asText(endpoint?.address),
628
+ policy: ["accept", "hold", "refuse"].includes(endpoint?.policy)
629
+ ? endpoint.policy
630
+ : "refuse",
631
+ online: endpoint?.online === true,
632
+ idle: endpoint?.idle === true,
633
+ unread: asCount(endpoint?.unread),
634
+ held: asCount(endpoint?.held),
635
+ }))
636
+ .filter((endpoint) => endpoint.name && endpoint.address)
637
+ .sort((left, right) => left.name.localeCompare(right.name))
638
+ : [];
639
+ return {
640
+ authority: "cli",
641
+ registered: endpoints.length > 0,
642
+ revision: Number.isSafeInteger(fabric?.revision) ? fabric.revision : 0,
643
+ unread: endpoints.reduce((total, endpoint) => total + endpoint.unread, 0),
644
+ held: endpoints.reduce((total, endpoint) => total + endpoint.held, 0),
645
+ endpoints,
646
+ };
647
+ }
648
+
618
649
  function lastEventFor(source, state) {
619
650
  const at =
620
651
  toIso(source?.lastEvent?.at) ||
@@ -629,7 +660,11 @@ function lastEventFor(source, state) {
629
660
  };
630
661
  }
631
662
 
632
- function projectOne(kind, source, { artifacts, prLinks }) {
663
+ function projectOne(
664
+ kind,
665
+ source,
666
+ { artifacts, prLinks, sessionMessageFabric },
667
+ ) {
633
668
  let sourceId;
634
669
  if (kind === "remote") {
635
670
  const stateFile = asText(source?.stateFile);
@@ -701,6 +736,7 @@ function projectOne(kind, source, { artifacts, prLinks }) {
701
736
  ? { count: asCount(source?.artifacts?.count), latest: null }
702
737
  : artifactSummary(linkedSessionIds, artifacts),
703
738
  approval: approvalSummary(source, state),
739
+ messaging: messagingSummary(linkedSessionIds, sessionMessageFabric),
704
740
  pr: prSummary(linkedSessionIds, prLinks),
705
741
  workflow: dynamicWorkflowSummary(source),
706
742
  lastEvent: lastEventFor(source, state),
@@ -726,10 +762,11 @@ export function buildSessionProjection({
726
762
  dynamicWorkflow = [],
727
763
  artifacts = [],
728
764
  prLinks = {},
765
+ sessionMessageFabric = null,
729
766
  sourceErrors = {},
730
767
  generatedAt = new Date().toISOString(),
731
768
  } = {}) {
732
- const context = { artifacts, prLinks };
769
+ const context = { artifacts, prLinks, sessionMessageFabric };
733
770
  const sessions = [
734
771
  ...(Array.isArray(local) ? local : []).map((source) =>
735
772
  projectOne("local", source, context),
@@ -785,6 +822,12 @@ export function buildSessionProjection({
785
822
  Array.isArray(dynamicWorkflow) ? dynamicWorkflow.length : 0,
786
823
  sourceErrors.dynamicWorkflow,
787
824
  ),
825
+ sessionMessageFabric: sourceStatus(
826
+ Array.isArray(sessionMessageFabric?.endpoints)
827
+ ? sessionMessageFabric.endpoints.length
828
+ : 0,
829
+ sourceErrors.sessionMessageFabric,
830
+ ),
788
831
  };
789
832
  const revision = projectionRevision({
790
833
  schema: SESSION_PROJECTION_SCHEMA,
@@ -0,0 +1,155 @@
1
+ /** Bounded live-state retention for long-running agent conversations. */
2
+
3
+ import { createHash } from "node:crypto";
4
+
5
+ export const SESSION_RUNTIME_RETENTION_LIMITS = Object.freeze({
6
+ recentResults: 32,
7
+ retainedResultChars: 512,
8
+ markerHeadChars: 128,
9
+ markerTailChars: 128,
10
+ });
11
+
12
+ export const SESSION_RUNTIME_RELEASE_MARKER = "…[live result released:";
13
+ const BACKGROUND_RESULT_PREFIX = '[Background sub-agent "';
14
+
15
+ function normalizedLimit(value, fallback, minimum = 0) {
16
+ return Number.isFinite(value)
17
+ ? Math.max(minimum, Math.floor(value))
18
+ : fallback;
19
+ }
20
+
21
+ function resultContent(message) {
22
+ if (!message || typeof message.content !== "string") return null;
23
+ if (message.role === "tool") return message.content;
24
+ if (
25
+ message.role === "user" &&
26
+ message.content.startsWith(BACKGROUND_RESULT_PREFIX)
27
+ ) {
28
+ return message.content;
29
+ }
30
+ return null;
31
+ }
32
+
33
+ // V8 may represent `slice()` as a view that keeps the entire source string's
34
+ // backing store alive. Joining individual UTF-16 code units forces a small,
35
+ // independent flat string while preserving even unpaired surrogate units.
36
+ function detachedSlice(content, start, end) {
37
+ const length = Math.max(0, end - start);
38
+ const units = new Array(length);
39
+ for (let index = 0; index < length; index += 1) {
40
+ units[index] = content.charAt(start + index);
41
+ }
42
+ return units.join("");
43
+ }
44
+
45
+ function releaseProjection(content, options) {
46
+ const digest = createHash("sha256").update(content, "utf8").digest("hex");
47
+ const marker =
48
+ `${SESSION_RUNTIME_RELEASE_MARKER} ${content.length} chars; sha256:${digest}; ` +
49
+ "full evidence remains in the durable transcript]";
50
+ const maxChars = options.retainedResultChars;
51
+ if (marker.length >= maxChars) {
52
+ return { content: marker.slice(0, maxChars), digest };
53
+ }
54
+ const remaining = maxChars - marker.length - 2;
55
+ const headChars = Math.min(
56
+ options.markerHeadChars,
57
+ Math.max(0, Math.floor(remaining / 2)),
58
+ );
59
+ const tailChars = Math.min(
60
+ options.markerTailChars,
61
+ Math.max(0, remaining - headChars),
62
+ );
63
+ const head = detachedSlice(content, 0, headChars);
64
+ const tail =
65
+ tailChars > 0
66
+ ? detachedSlice(content, content.length - tailChars, content.length)
67
+ : "";
68
+ return {
69
+ content: `${head}\n${marker}\n${tail}`.slice(0, maxChars),
70
+ digest,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Replace old live tool/subagent result bodies with a bounded head/tail,
76
+ * digest, and durable-transcript locator. The message and pairing structure is
77
+ * retained; only old result content is released. The returned array is new and
78
+ * the input is never mutated.
79
+ */
80
+ export function releaseOldLiveSessionResults(messages, configured = {}) {
81
+ if (!Array.isArray(messages)) {
82
+ return {
83
+ messages,
84
+ stats: {
85
+ strategy: "session-runtime-retention",
86
+ released: 0,
87
+ savedChars: 0,
88
+ recentResults: 0,
89
+ durableReferences: [],
90
+ },
91
+ };
92
+ }
93
+ const options = {
94
+ recentResults: normalizedLimit(
95
+ configured.recentResults,
96
+ SESSION_RUNTIME_RETENTION_LIMITS.recentResults,
97
+ ),
98
+ retainedResultChars: normalizedLimit(
99
+ configured.retainedResultChars,
100
+ SESSION_RUNTIME_RETENTION_LIMITS.retainedResultChars,
101
+ 256,
102
+ ),
103
+ markerHeadChars: normalizedLimit(
104
+ configured.markerHeadChars,
105
+ SESSION_RUNTIME_RETENTION_LIMITS.markerHeadChars,
106
+ ),
107
+ markerTailChars: normalizedLimit(
108
+ configured.markerTailChars,
109
+ SESSION_RUNTIME_RETENTION_LIMITS.markerTailChars,
110
+ ),
111
+ };
112
+ const resultIndexes = [];
113
+ for (let index = 0; index < messages.length; index += 1) {
114
+ if (resultContent(messages[index]) != null) resultIndexes.push(index);
115
+ }
116
+ const releaseCount = Math.max(
117
+ 0,
118
+ resultIndexes.length - options.recentResults,
119
+ );
120
+ const releaseIndexes = new Set(resultIndexes.slice(0, releaseCount));
121
+ let released = 0;
122
+ let savedChars = 0;
123
+ const durableReferences = [];
124
+ const output = messages.map((message, index) => {
125
+ if (!releaseIndexes.has(index)) return message;
126
+ const content = resultContent(message);
127
+ if (content.length <= options.retainedResultChars) {
128
+ return message;
129
+ }
130
+ const projection = releaseProjection(content, options);
131
+ released += 1;
132
+ savedChars += content.length - projection.content.length;
133
+ durableReferences.push({
134
+ messageIndex: index,
135
+ digest: `sha256:${projection.digest}`,
136
+ originalChars: content.length,
137
+ retainedChars: projection.content.length,
138
+ });
139
+ return { ...message, content: projection.content };
140
+ });
141
+ return {
142
+ messages: output,
143
+ stats: {
144
+ strategy: "session-runtime-retention",
145
+ released,
146
+ savedChars,
147
+ saved: savedChars,
148
+ recentResults: Math.min(options.recentResults, resultIndexes.length),
149
+ retainedResultChars: options.retainedResultChars,
150
+ originalMessages: messages.length,
151
+ compressedMessages: output.length,
152
+ durableReferences,
153
+ },
154
+ };
155
+ }
@@ -438,6 +438,34 @@ function readBooleanSetting(key, opts = {}) {
438
438
  return value;
439
439
  }
440
440
 
441
+ /**
442
+ * Read a string setting across the layered `.claude/settings.json` files.
443
+ * The closest layer wins and managed settings remain authoritative. Blank and
444
+ * non-string values are ignored so they cannot erase a valid lower layer.
445
+ *
446
+ * @param {string} key settings key or dotted path
447
+ * @param {object} [opts]
448
+ * @returns {string|undefined}
449
+ */
450
+ function readStringSetting(key, opts = {}) {
451
+ const cwd = opts.cwd || process.cwd();
452
+ const parts = String(key).split(".");
453
+ let value;
454
+ const absorb = (data) => {
455
+ let node = data;
456
+ for (const part of parts) {
457
+ node = node && typeof node === "object" ? node[part] : undefined;
458
+ }
459
+ if (typeof node === "string" && node.trim()) value = node.trim();
460
+ };
461
+ for (const file of settingsPaths(cwd, opts.settingsFile)) {
462
+ absorb(readSettingsFile(file, { onWarn: opts.onWarn }));
463
+ }
464
+ const managed = loadManagedSettings(opts);
465
+ if (managed.settings) absorb(managed.settings);
466
+ return value;
467
+ }
468
+
441
469
  /**
442
470
  * Read a string-array setting across the layered `.claude/settings.json` files
443
471
  * plus managed settings. Unlike {@link readBooleanSetting} (last-layer wins),
@@ -484,6 +512,7 @@ module.exports = {
484
512
  loadSettingsConfig,
485
513
  readSettingsFile,
486
514
  readBooleanSetting,
515
+ readStringSetting,
487
516
  readStringArraySetting,
488
517
  settingsPaths,
489
518
  managedSettingsPath,
@@ -185,6 +185,11 @@ import {
185
185
  createPromptInteractionSurface,
186
186
  mergeClipboardImageChips,
187
187
  } from "./prompt-interactions.js";
188
+ import {
189
+ isReadlineWordRuboutKey,
190
+ readlineWordRubout,
191
+ resolveReplKeybindingFlavor,
192
+ } from "./repl-keybindings.js";
188
193
  import { createSystemClipboardImageBinding } from "./clipboard-image.js";
189
194
  import {
190
195
  buildPermissionPrompt,
@@ -2760,15 +2765,11 @@ export async function runReplStartupBoundary(options, startupDependencies) {
2760
2765
  "CC_REPL_STARTUP_DEPENDENCY_INVALID",
2761
2766
  );
2762
2767
  }
2763
- const root = openBudgetRoot(
2764
- leaseSessionId,
2765
- options.sessionBudgetRoot,
2766
- {
2767
- persist: true,
2768
- signal: combineReplSignals(options.signal, leaseScope.lease.signal),
2769
- table: options.sessionBudgetRoot.table,
2770
- },
2771
- );
2768
+ const root = openBudgetRoot(leaseSessionId, options.sessionBudgetRoot, {
2769
+ persist: true,
2770
+ signal: combineReplSignals(options.signal, leaseScope.lease.signal),
2771
+ table: options.sessionBudgetRoot.table,
2772
+ });
2772
2773
  if (
2773
2774
  root?.enabled !== true ||
2774
2775
  !root.budget ||
@@ -2824,10 +2825,7 @@ export function startReplJsonlSession(
2824
2825
  ...meta,
2825
2826
  ...(observabilityScope != null ? { observabilityScope } : {}),
2826
2827
  });
2827
- if (
2828
- requireDurable &&
2829
- (typeof sessionId !== "string" || !sessionId)
2830
- ) {
2828
+ if (requireDurable && (typeof sessionId !== "string" || !sessionId)) {
2831
2829
  throw new Error("JSONL session creation returned no durable session id");
2832
2830
  }
2833
2831
  return sessionId || null;
@@ -3187,6 +3185,7 @@ async function startAgentReplInWorkspaceOwned(
3187
3185
  let _visionModel;
3188
3186
  let _promptInteractionConfig = {};
3189
3187
  let _persistPromptSuggestionsEnabled = null;
3188
+ let _keybindingFlavor = "classic";
3190
3189
  // Hard stream inactivity timeout override (config.llm.streamStallTimeoutMs,
3191
3190
  // ms): a stream silent that long is aborted + retried instead of hanging.
3192
3191
  // Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
@@ -3218,6 +3217,23 @@ async function startAgentReplInWorkspaceOwned(
3218
3217
  } catch {
3219
3218
  /* optional — resolveVisionLlm falls back to DEFAULT_VISION_MODEL */
3220
3219
  }
3220
+ try {
3221
+ const { readStringSetting } = await import("../lib/settings-loader.cjs");
3222
+ const configuredFlavor = readStringSetting("keybindingFlavor", {
3223
+ cwd: process.cwd(),
3224
+ settingsFile: options.settingsFile || null,
3225
+ managedSettingsFile: options.managedSettingsFile || null,
3226
+ onWarn: (message) => logger.warn(message),
3227
+ });
3228
+ const resolvedFlavor = resolveReplKeybindingFlavor(configuredFlavor);
3229
+ _keybindingFlavor = resolvedFlavor.flavor;
3230
+ if (resolvedFlavor.error) {
3231
+ logger.warn(`settings: ${resolvedFlavor.error}; using classic`);
3232
+ }
3233
+ } catch (error) {
3234
+ if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
3235
+ logger.warn(`settings: could not load keybindingFlavor (${error.message})`);
3236
+ }
3221
3237
  // Extra workspace roots (--add-dir): advertised in the system prompt and
3222
3238
  // spanned by search_files.
3223
3239
  const additionalDirectories = Array.isArray(options.additionalDirectories)
@@ -3815,6 +3831,8 @@ async function startAgentReplInWorkspaceOwned(
3815
3831
  agentSessionId:
3816
3832
  sessionId || `repl-${process.pid}-${Date.now().toString(36)}`,
3817
3833
  isText: false, // the REPL prints its own pairing lines below
3834
+ allowLan: options.remoteControlAllowLan === true,
3835
+ env: process.env,
3818
3836
  });
3819
3837
  _remoteApproval = {
3820
3838
  bridge: started.bridge,
@@ -5201,6 +5219,25 @@ async function startAgentReplInWorkspaceOwned(
5201
5219
  return;
5202
5220
  }
5203
5221
 
5222
+ // 1.875) The opt-in readline flavor makes Ctrl+W a whitespace-delimited
5223
+ // unix-word-rubout. Classic stays byte-identical and lets Node readline
5224
+ // own the chord; Vim NORMAL mode continues to use the existing engine.
5225
+ if (
5226
+ !_turnAbort &&
5227
+ (!_vimEnabled || !_vim) &&
5228
+ _keybindingFlavor === "readline" &&
5229
+ isReadlineWordRuboutKey(_str, k)
5230
+ ) {
5231
+ _consumeReadlineKeypress(key);
5232
+ const next = readlineWordRubout(rl.line, rl.cursor);
5233
+ if (next.changed) {
5234
+ rl.line = next.line;
5235
+ rl.cursor = next.cursor;
5236
+ rl._refreshLine?.();
5237
+ }
5238
+ return;
5239
+ }
5240
+
5204
5241
  // 2) Vim mode: modal editing on the current input line.
5205
5242
  if (_vimEnabled && !_turnAbort) {
5206
5243
  if (!_vim) {
@@ -5625,7 +5662,7 @@ async function startAgentReplInWorkspaceOwned(
5625
5662
  ` ${chalk.cyan("/voice")} Speech dictation — local-first STT (/voice hold|tap|off)`,
5626
5663
  );
5627
5664
  logger.log(
5628
- ` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; explanatory/learning built-in)`,
5665
+ ` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; concise/explanatory/learning built-in)`,
5629
5666
  );
5630
5667
  logger.log(
5631
5668
  ` ${chalk.cyan("/editor")} Edit a draft prompt in an external editor`,
@@ -14,15 +14,38 @@
14
14
  *
15
15
  * @returns {string} the prompt header (no styling, no trailing "Proceed?")
16
16
  */
17
+ export function visualizePermissionText(value) {
18
+ return String(value ?? "").replace(
19
+ /[\u0000-\u001f\u007f-\u009f\u00ad\u034f\u061c\u115f\u1160\u17b4\u17b5\u180b-\u180f\u200b-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufeff\uffa0]/gu,
20
+ (character) => {
21
+ if (character === "\t") return "<TAB>";
22
+ if (character === "\n") return "<LF>";
23
+ if (character === "\r") return "<CR>";
24
+ return `<U+${character.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}>`;
25
+ },
26
+ );
27
+ }
28
+
17
29
  export function buildPermissionPrompt({ tool, args, rule, reason } = {}) {
18
- const detail = args?.command
19
- ? ` ${args.command}`
20
- : args?.path
21
- ? ` ${args.path}`
22
- : "";
23
- if (rule) return `[Permission] rule "${rule}" asks before ${tool}:${detail}`;
24
- if (reason) return `[Permission] ${reason}`;
25
- return `[Permission] confirm ${tool}:${detail}`;
30
+ const visibleTool = visualizePermissionText(tool);
31
+ const command = typeof args?.command === "string" ? args.command : "";
32
+ const source = args?.path ?? args?.file_path ?? args?.source ?? "";
33
+ const destination = args?.destination ?? args?.new_path ?? args?.to ?? "";
34
+ const rawDetail = command
35
+ ? command
36
+ : source && destination
37
+ ? `${source} -> ${destination}`
38
+ : source || destination;
39
+ const detail = rawDetail ? ` ${visualizePermissionText(rawDetail)}` : "";
40
+ if (rule) {
41
+ return `[Permission] rule "${visualizePermissionText(rule)}" asks before ${visibleTool}:${detail}`;
42
+ }
43
+ if (reason) {
44
+ const reasonText = String(reason);
45
+ const missingTarget = rawDetail && !reasonText.includes(String(rawDetail));
46
+ return `[Permission] ${visualizePermissionText(reasonText)}${missingTarget ? `:${detail}` : ""}`;
47
+ }
48
+ return `[Permission] confirm ${visibleTool}:${detail}`;
26
49
  }
27
50
 
28
51
  /**
@@ -1,5 +1,60 @@
1
1
  /** Declarative, validated keybindings for interactive prompt actions. */
2
2
 
3
+ export const DEFAULT_REPL_KEYBINDING_FLAVOR = "classic";
4
+ export const REPL_KEYBINDING_FLAVORS = Object.freeze([
5
+ DEFAULT_REPL_KEYBINDING_FLAVOR,
6
+ "readline",
7
+ ]);
8
+
9
+ /**
10
+ * Resolve the prompt editing flavor. Unknown values stay on the compatible
11
+ * classic behavior and include a diagnostic for the caller to surface.
12
+ */
13
+ export function resolveReplKeybindingFlavor(value) {
14
+ if (value == null || String(value).trim() === "") {
15
+ return { flavor: DEFAULT_REPL_KEYBINDING_FLAVOR, error: null };
16
+ }
17
+ const flavor = String(value).trim().toLowerCase();
18
+ if (REPL_KEYBINDING_FLAVORS.includes(flavor)) {
19
+ return { flavor, error: null };
20
+ }
21
+ return {
22
+ flavor: DEFAULT_REPL_KEYBINDING_FLAVOR,
23
+ error: `keybindingFlavor must be classic or readline (got "${String(value)}")`,
24
+ };
25
+ }
26
+
27
+ /** True for the terminal Ctrl+W chord used by readline's unix-word-rubout. */
28
+ export function isReadlineWordRuboutKey(input, key = {}) {
29
+ if (key.meta || key.alt || key.shift) return false;
30
+ const name = String(key.name || "").toLowerCase();
31
+ return (
32
+ key.ctrl === true &&
33
+ (name === "w" || input === "\u0017" || key.sequence === "\u0017")
34
+ );
35
+ }
36
+
37
+ /**
38
+ * Delete the token immediately left of the cursor using whitespace-only word
39
+ * boundaries. This intentionally treats a full path as one token, unlike the
40
+ * classic path-segment behavior. Text right of the cursor is preserved.
41
+ */
42
+ export function readlineWordRubout(line, cursor) {
43
+ const text = String(line || "");
44
+ const point = Math.max(
45
+ 0,
46
+ Math.min(Number.isInteger(cursor) ? cursor : text.length, text.length),
47
+ );
48
+ let start = point;
49
+ while (start > 0 && /\s/u.test(text[start - 1])) start -= 1;
50
+ while (start > 0 && !/\s/u.test(text[start - 1])) start -= 1;
51
+ return {
52
+ line: text.slice(0, start) + text.slice(point),
53
+ cursor: start,
54
+ changed: start !== point,
55
+ };
56
+ }
57
+
3
58
  export const REPL_KEYBINDING_ACTIONS = Object.freeze([
4
59
  "prompt.edit",
5
60
  "prompt.stash",
@@ -136,6 +136,7 @@ import {
136
136
  } from "../harness/structured-handoff.js";
137
137
  import { isMcpRpcError } from "../harness/mcp-client.js";
138
138
  import { projectCanonicalResumeMessages } from "../lib/session-message-provenance.js";
139
+ import { releaseOldLiveSessionResults } from "../lib/session-runtime-retention.js";
139
140
  import {
140
141
  pathMatchesOpenedFileIdentitySync,
141
142
  sameOpenedFileIdentity,
@@ -12571,6 +12572,7 @@ async function _settleAutomaticCompaction({
12571
12572
  compacted,
12572
12573
  stats,
12573
12574
  options,
12575
+ trigger = "auto",
12574
12576
  }) {
12575
12577
  if (!_sameMessageSnapshot(messages, liveExpectedMessages)) {
12576
12578
  throw _compactionSettlementError(
@@ -12590,7 +12592,7 @@ async function _settleAutomaticCompaction({
12590
12592
  settlement = options.onCompaction(stats, compacted, {
12591
12593
  expectedMessages: authorityExpectedMessages,
12592
12594
  liveExpectedMessages,
12593
- trigger: "auto",
12595
+ trigger,
12594
12596
  });
12595
12597
  } else if (options.sessionId && options.persistCompaction !== false) {
12596
12598
  const store = await import("../harness/jsonl-session-store.js");
@@ -12605,7 +12607,7 @@ async function _settleAutomaticCompaction({
12605
12607
  options.sessionId,
12606
12608
  {
12607
12609
  ...stats,
12608
- trigger: "auto",
12610
+ trigger,
12609
12611
  messages: projectCanonicalResumeMessages(compacted, { strict: true }),
12610
12612
  },
12611
12613
  authorityExpectedMessages,
@@ -13180,6 +13182,53 @@ export async function* agentLoop(messages, options) {
13180
13182
  };
13181
13183
  }
13182
13184
 
13185
+ // Release result bodies that have left the recent display window before
13186
+ // every provider admission, independent of the semantic-compaction token
13187
+ // threshold. Settlement persists a bounded resume checkpoint before the
13188
+ // live array changes; the earlier hash-chained result events remain the
13189
+ // durable evidence for audit/recovery.
13190
+ if (options.runtimeResultRetention !== false && messages.length > 32) {
13191
+ const retentionConfig =
13192
+ options.runtimeResultRetention &&
13193
+ typeof options.runtimeResultRetention === "object"
13194
+ ? options.runtimeResultRetention
13195
+ : options.runtimeResultRetentionOptions;
13196
+ const retained = releaseOldLiveSessionResults(messages, retentionConfig);
13197
+ if (
13198
+ retained.stats.released > 0 &&
13199
+ !_sameMessageSnapshot(retained.messages, messages)
13200
+ ) {
13201
+ const authorityExpectedMessages = [...messages];
13202
+ const liveExpectedMessages = [...messages];
13203
+ try {
13204
+ await _settleAutomaticCompaction({
13205
+ messages,
13206
+ liveExpectedMessages,
13207
+ authorityExpectedMessages,
13208
+ compacted: retained.messages,
13209
+ stats: retained.stats,
13210
+ options,
13211
+ trigger: "runtime-retention",
13212
+ });
13213
+ yield {
13214
+ type: "session-runtime-retention",
13215
+ runId,
13216
+ stats: retained.stats,
13217
+ };
13218
+ } catch (error) {
13219
+ yield {
13220
+ type: "session-runtime-retention-degraded",
13221
+ runId,
13222
+ reason:
13223
+ error?.code === "SESSION_REVISION_STALE"
13224
+ ? "session_messages_changed_during_retention"
13225
+ : "canonical_retention_settlement_failed",
13226
+ code: error?.code || "CC_SESSION_RETENTION_SETTLEMENT_FAILED",
13227
+ };
13228
+ }
13229
+ }
13230
+ }
13231
+
13183
13232
  // Headless auto-compaction (Claude-Code `--print` parity). Keeps long
13184
13233
  // `-p` / `--resume` runs under the model's context window instead of
13185
13234
  // growing until the provider rejects the request. Opt-out with