chainlesschain 0.162.160 → 0.162.161

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 (179) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-CkRHjW8e.js → AIOps-DMn528q-.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BP3MeNi2.js → ActionButton-D9ZcDCJL.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-CjbjQsOr.js → Analytics-A_K-8PX0.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-i0adH1M8.js → AppLayout-D4pFW3X6.js} +3 -3
  6. package/src/assets/web-panel/assets/{Artifacts-CCCG2GOU.js → Artifacts-Dz46COAd.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-DrsgvwHC.js → Audit-cbMjbyg0.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DkXNkbZM.js → BackgroundAgents-Dtf88GAj.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DarTWCex.js → Backup-C5KRxn52.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-DaDzhcto.js → BaseInput-Dd2UK3BN.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-C4EzGw6V.js → Chat-lptKTFdG.js} +6 -6
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-C2KLtwHz.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-gddNgaQi.js → Checkbox-_yspG6rG.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-BKldFWf9.js → Codegen-BGq_GAha.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-ChR-brDs.js → Col-CePor71g.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DlHtZX86.js → Community-CLOWhIT7.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BAhfcBpC.js → Compact-CivJt2vT.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-gIrKkm6m.js → Compliance-Btmo1GGE.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BYnzLBO3.js → Cowork-Ct35OlG4.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-ByUDIljI.js → Cron-CTc2GmhB.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DOdNbHFp.js → Crosschain-ZtiBETk1.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BJHaNWD2.js → DID-BNqMQQXw.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-Drm_tClz.js → Dashboard-BmzZd-9V.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CA1WLzGN.js → Dropdown-CMVgvP2M.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-Di1SKjNO.js → EmailListRenderer-CcqQFAfT.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-44Ve7ZFe.js → FamilyGuardDashboard-CTqB1_4V.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-CubPwv_N.js → Federation-CiKOOzlb.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CsUFe5bU.js → FormItemContext-Wk-OT0gr.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-D7xRjPjZ.js → GenericCardRenderer-DbEQT6ue.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-D-Qx9dhO.js → Git-0ZvCPSD9.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-_YMYaU4n.js → Governance-CmVuKkPb.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-J7Yzh-K_.js → Inference-CTWE3Jwg.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-D37iI_Mo.js → KnowledgeGraph-CBEIF00L.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-oMTSYfGY.js → Logs-DLhxDwVG.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-DxywvhTU.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-DKUqYDaF.js → Marketplace-BgsCBrnc.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BEv3Gx61.js → McpTools-ClBUGDS2.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-CtA8XD2y.js → Memory-CnG_ZnYw.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-ug7c1mMj.js → MobileBridge-BUOAbR1Z.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-Dnt_9-WB.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-WJaMs4i2.js → Mtc-CLjt4kCD.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-DXnK_-ru.js → MtcAudit-f24U9Aes.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-C4Ev7726.js → Multisig-GrmGQbSq.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-BMFb9_zk.js → NLProgramming-DADaWn-n.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Bl93nvBX.js → Notes-xtf5RX6C.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BN2W5cl6.js → NotificationSettings-Cd27Rgtx.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-Dxc9oN4o.js → OrderTableRenderer-fXRxlDjl.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-CAs48637.js → Organization-joCFlNB0.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Bhq27Zoc.js → Overflow-B1HoURq0.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-D61-2542.js → P2P-DiwsKbT7.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-C1j4iUxz.js → PdhVaultBrowser-Xe-BsW6S.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-rJ2-fScM.js → Permissions-C23qi8kl.js} +3 -3
  53. package/src/assets/web-panel/assets/{PersonalDataHub-DFIlTok6.js → PersonalDataHub-BS1syX2f.js} +2 -2
  54. package/src/assets/web-panel/assets/{Pipeline-BjIgEWoZ.js → Pipeline-DRYwwDyh.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BQoH5wcX.js → Privacy-BQKaDHPH.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-CYR_-_Ub.js → ProjectInit-BC6F9xiG.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-nkatCq-9.js → ProjectSettings-ClFPc1Nd.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-SS9uZKCl.js → Projects-Dn-f5aYe.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-BnKM9fsF.js → Providers-CLWuOUNt.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-Cfe82dbz.js → QrScannerModal-DiqULTxb.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-r1RbPufV.js → QuickAsk-9A03P-E_.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CjCbM2WE.js → Recommend-CJZAnbq_.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-BuMGPH6V.js → RemoteSession-C9A1R77h.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-Bmj3NY1F.js → Reputation-BIZc6Rky.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-BIsNcE_1.js → Row-DfIPNtuG.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-BObmojD2.js → RssFeed-C5znFcQ1.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-BRmbkQNS.js → Search-DSs2z3OX.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-_rF3DRpY.js → Security-CV6LcrLY.js} +3 -3
  69. package/src/assets/web-panel/assets/{Services-D0If9ZV4.js → Services-cmhoX0Xj.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-o7zIksUg.js → Skeleton-tCsg2po7.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-oUR7zi9u.js → Skills-BK1KUDiy.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-fqKyGi03.js → Sla-yRgyeA82.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-B1wZ_gxx.js → SpeechSettings-c1mo1mlp.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-B3qJWYXq.js → SyncSettings-koIAfuT3.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-BH5_dUfr.js → Tasks-DkkreAaB.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-CCIVpjRP.js → Templates-fy5Ctf9M.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-2GZtTGnB.js → Tenant-Bw70Jf6S.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-BlMkfs_u.js → Terminal-BKh6Rx-4.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-U6hi5OMc.js → TimelineRenderer-Dg54WP0c.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-C-_BerGJ.js → Tokens-BvvD5SxJ.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-DaKzBgN3.js → Trigger-B7Ug9x4e.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-CLvcsco3.js → Trust-BjvuMORY.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BFn_Y1zZ.js → UkeySign-CZqhkx8p.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-B0V18dLT.js → VideoEditing-ClR50lhX.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BbmP7Imu.js → Wallet-DlfppYjx.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Dewj_0kt.js → WebAuthn-BirgVr8B.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-DOxz3Lwa.js → WorkflowEditor-B8DP_bax.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-B1OIpZnh.js → chat-DA8AUZzL.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-CSGNVdri.js → colors-C38pLGp1.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-8S0vcg0u.js → compact-item-81rtr98o.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-vZyc27TN.js → createContext-D34ixq8t.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-CHDIEOeN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DWw3-UhA.js → hasIn-D4bzqTrZ.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-dxocDVD_.js → index-9qoVpPt6.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-xx5M5Rbj.js → index-B0QArPQt.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DtHWHJnj.js → index-B8mkLM4x.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DLgkAhEE.js → index-BIP62a6r.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-tr1x96W9.js → index-BP-zkXK8.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CfEvacz7.js → index-BS3M5H9V.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D1i_8oop.js → index-BXd2_LmH.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BDHyovnK.js → index-BlxEphl7.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CLPr2vC_.js → index-BqIhLAbA.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BQssf0EQ.js → index-BtGxuQrO.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BuB5P0TR.js → index-BvD7b2IK.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DeCS12Mh.js → index-BvL_3J_n.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BeBv896m.js → index-COe_cOLJ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Dc40pX3F.js → index-CP5alL4t.js} +1 -1
  108. package/src/assets/web-panel/assets/index-CY1NURWZ.js +1 -0
  109. package/src/assets/web-panel/assets/{index-B4pP2ycr.js → index-CbhE3j5j.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DKwl1AkQ.js → index-Cd3KuNK5.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BZnauCqN.js → index-CoVgZw_b.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BwKrTVV0.js → index-CuS-UPoj.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Q6oyLnKC.js → index-D0Ih7Hwn.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CB2MOS_8.js → index-D3zCCZRS.js} +3 -3
  115. package/src/assets/web-panel/assets/{index-BdyokEau.js → index-D6GfvEQG.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DPgY5GLy.js → index-DBFSo1NF.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CFQWZvak.js → index-DFHa1HIg.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BjC-TrOb.js → index-DFyWKOBD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Dg0Izipr.js → index-DMgnRwrK.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BKEmQQvR.js → index-DUQLXLQM.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DLAvUtOH.js → index-D_2VYPr1.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-D8qXVfoV.js → index-DakfFZ-k.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DcfLXAW7.js → index-Ddk0e_Pi.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BoIPHP4R.js → index-DkHqMnn3.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CJgKP2cm.js → index-Dmo3dFHb.js} +1 -1
  126. package/src/assets/web-panel/assets/index-DokUYqpq.js +1 -0
  127. package/src/assets/web-panel/assets/{index-C6r27A-o.js → index-DvfCEJG-.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CbZqw7pg.js → index-E1OJRXs4.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BkWd6YL7.js → index-F76w1NiL.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-t-q3rkVm.js → index-ZRJRItm0.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CwXBblm-.js → index-fI5sXMLg.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CI3slBKI.js → index-tKiC8T-4.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-Di5YFId0.js → initDefaultProps-ByyvflIR.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BVSN0aeL.js → motion-B3FQm2By.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-DHNiaP2l.js → move-BSfns6Ef.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-xJPf3gQD.js → mtc-parser-CTG1Ieri.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-C7qzUdkN.js → omit-DObM_2j6.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-pSpjg3Le.js → pickAttrs-DOfelQ1t.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-cs_jL_UC.js → placementArrow-CHZILds_.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-DkS_Zs4r.js → responsiveObserve-REbucKSx.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-B5O1Kpxo.js → slide-C6EZzD7o.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BX02GnZp.js → statusUtils-BxkWS-g3.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-EmBYRftd.js → styleChecker-Chklyoq6.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-ZGzN1cU8.js → useFlexGapSupport-CRVwKrrI.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CfP7M1m7.js → useFs-DV24ik_J.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CbIPHgNh.js → usePersonalDataHub-C7vIo4Pg.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-7xh0If_O.js → vnode-By-v5GlF.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DmitvTR2.js → zoom-B1w9Am3r.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agenda.js +15 -1
  151. package/src/commands/agent.js +7 -0
  152. package/src/commands/background-session.js +16 -2
  153. package/src/data/changelog.json +7 -2
  154. package/src/gateways/ws/background-agent-protocol.js +88 -14
  155. package/src/lib/agent-authority.js +251 -0
  156. package/src/lib/background-agent-phase.js +100 -0
  157. package/src/lib/background-agent-supervisor.js +288 -8
  158. package/src/lib/backpressure-policy.js +105 -0
  159. package/src/lib/capability-negotiation.js +212 -0
  160. package/src/lib/credential-guard.js +11 -0
  161. package/src/lib/credential-proxy.js +182 -0
  162. package/src/lib/event-seq-replay.js +167 -0
  163. package/src/lib/goal-condition-engine.js +369 -0
  164. package/src/lib/headless-manifest.js +13 -0
  165. package/src/lib/ide-context.js +53 -14
  166. package/src/lib/project-instructions.js +98 -1
  167. package/src/lib/remote-path-mapping.js +229 -0
  168. package/src/lib/schedule-planner.js +136 -0
  169. package/src/repl/bg-dashboard.js +13 -12
  170. package/src/runtime/agent-core.js +11 -4
  171. package/src/runtime/headless-stream.js +195 -11
  172. package/src/runtime/system-prompt.js +3 -0
  173. package/src/workers/background-agent-worker.js +37 -2
  174. package/src/assets/web-panel/assets/ChatBubbleRenderer-lkavIWMS.js +0 -1
  175. package/src/assets/web-panel/assets/MarkdownRenderer-BqaPmC0W.js +0 -1
  176. package/src/assets/web-panel/assets/MobileProjects-BpX5g9It.js +0 -1
  177. package/src/assets/web-panel/assets/devWarning-DYEZcY55.js +0 -1
  178. package/src/assets/web-panel/assets/index-DmVFfcNR.js +0 -1
  179. package/src/assets/web-panel/assets/index-x7YyhMUa.js +0 -1
@@ -1 +1 @@
1
- import{i as e}from"./index-CB2MOS_8.js";function r(a,s,t){return e({[`${a}-status-success`]:s==="success",[`${a}-status-warning`]:s==="warning",[`${a}-status-error`]:s==="error",[`${a}-status-validating`]:s==="validating",[`${a}-has-feedback`]:t})}const c=(a,s)=>s||a;export{c as a,r as g};
1
+ import{i as e}from"./index-D3zCCZRS.js";function r(a,s,t){return e({[`${a}-status-success`]:s==="success",[`${a}-status-warning`]:s==="warning",[`${a}-status-error`]:s==="error",[`${a}-status-validating`]:s==="validating",[`${a}-has-feedback`]:t})}const c=(a,s)=>s||a;export{c as a,r as g};
@@ -1 +1 @@
1
- import{B as d}from"./index-CB2MOS_8.js";const i=()=>d()&&window.document.documentElement,c=e=>{if(d()&&window.document.documentElement){const t=Array.isArray(e)?e:[e],{documentElement:n}=window.document;return t.some(r=>r in n.style)}return!1},u=(e,t)=>{if(!c(e))return!1;const n=document.createElement("div"),r=n.style[e];return n.style[e]=t,n.style[e]!==r};function s(e,t){return!Array.isArray(e)&&t!==void 0?u(e,t):c(e)}let o;const p=()=>{if(!i())return!1;if(o!==void 0)return o;const e=document.createElement("div");return e.style.display="flex",e.style.flexDirection="column",e.style.rowGap="1px",e.appendChild(document.createElement("div")),e.appendChild(document.createElement("div")),document.body.appendChild(e),o=e.scrollHeight===1,document.body.removeChild(e),o};export{i as c,p as d,s as i};
1
+ import{B as d}from"./index-D3zCCZRS.js";const i=()=>d()&&window.document.documentElement,c=e=>{if(d()&&window.document.documentElement){const t=Array.isArray(e)?e:[e],{documentElement:n}=window.document;return t.some(r=>r in n.style)}return!1},u=(e,t)=>{if(!c(e))return!1;const n=document.createElement("div"),r=n.style[e];return n.style[e]=t,n.style[e]!==r};function s(e,t){return!Array.isArray(e)&&t!==void 0?u(e,t):c(e)}let o;const p=()=>{if(!i())return!1;if(o!==void 0)return o;const e=document.createElement("div");return e.style.display="flex",e.style.flexDirection="column",e.style.rowGap="1px",e.appendChild(document.createElement("div")),e.appendChild(document.createElement("div")),document.body.appendChild(e),o=e.scrollHeight===1,document.body.removeChild(e),o};export{i as c,p as d,s as i};
@@ -1 +1 @@
1
- import{o,s as t}from"./vendor-Bn1JzzAn.js";import{d as s}from"./styleChecker-EmBYRftd.js";const r=(()=>{const e=t(!1);return o(()=>{e.value=s()}),e});export{r as u};
1
+ import{o,s as t}from"./vendor-Bn1JzzAn.js";import{d as s}from"./styleChecker-Chklyoq6.js";const r=(()=>{const e=t(!1);return o(()=>{e.value=s()}),e});export{r as u};
@@ -1 +1 @@
1
- import{u as d}from"./index-CB2MOS_8.js";import{u as c}from"./useShellMode-CgR0wCYM.js";function u({accept:l=""}={}){return new Promise(a=>{if(typeof document>"u"){a({canceled:!0,path:null,content:null});return}const n=document.createElement("input");n.type="file",l&&(n.accept=l),n.style.display="none",document.body.appendChild(n);let o=!1;const i=()=>{n.parentNode&&n.parentNode.removeChild(n)},r=()=>{if(o)return;o=!0;const e=n.files&&n.files[0];if(!e){i(),a({canceled:!0,path:null,content:null});return}const t=new FileReader;t.onload=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:typeof t.result=="string"?t.result:""})},t.onerror=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:null,reason:"read_failed"})},t.readAsText(e)};n.addEventListener("change",r),n.click()})}function f(l,{defaultPath:a="download.txt"}={}){if(typeof document>"u")return{canceled:!0,path:null};const n=new Blob([l],{type:"text/plain"}),o=URL.createObjectURL(n),i=document.createElement("a");return i.href=o,i.download=a,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(o),{canceled:!1,path:a}}function p(l){if(!Array.isArray(l))return"";const a=[];for(const n of l)if(Array.isArray(n.extensions))for(const o of n.extensions)a.push(`.${o.replace(/^\./,"")}`);return a.join(",")}function m(){const l=d();async function a(r={}){if(c().isEmbedded){const e=await l.sendRaw({type:"fs.openDialog",title:r.title,filters:r.filters},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDialog failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,content:t.content??null,size:t.size,reason:t.reason}}return u({accept:p(r.filters)})}async function n(r,e={}){if(typeof r!="string")throw new Error("content must be a string");if(c().isEmbedded){const t=await l.sendRaw({type:"fs.saveDialog",title:e.title,defaultPath:e.defaultPath,filters:e.filters,content:r},6e4);if(t&&t.ok===!1)throw new Error(t.error||"fs.saveDialog failed");const s=t?.result??t;return{canceled:!!s.canceled,path:s.path??null}}return f(r,{defaultPath:e.defaultPath})}async function o(r,e={}){const t=JSON.stringify(r,null,2),s={...e,defaultPath:e.defaultPath||"data.json",filters:e.filters||[{name:"JSON",extensions:["json"]}]};return n(t,s)}async function i(r={}){if(!c().isEmbedded)return{canceled:!0,path:null,initialized:!1,unsupported:!0};const e=await l.sendRaw({type:"fs.openDirectory",title:r.title},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDirectory failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,initialized:!!t.initialized}}return{pickFileText:a,saveText:n,saveJson:o,pickDirectory:i}}export{m as u};
1
+ import{u as d}from"./index-D3zCCZRS.js";import{u as c}from"./useShellMode-CgR0wCYM.js";function u({accept:l=""}={}){return new Promise(a=>{if(typeof document>"u"){a({canceled:!0,path:null,content:null});return}const n=document.createElement("input");n.type="file",l&&(n.accept=l),n.style.display="none",document.body.appendChild(n);let o=!1;const i=()=>{n.parentNode&&n.parentNode.removeChild(n)},r=()=>{if(o)return;o=!0;const e=n.files&&n.files[0];if(!e){i(),a({canceled:!0,path:null,content:null});return}const t=new FileReader;t.onload=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:typeof t.result=="string"?t.result:""})},t.onerror=()=>{i(),a({canceled:!1,path:e.name,size:e.size,content:null,reason:"read_failed"})},t.readAsText(e)};n.addEventListener("change",r),n.click()})}function f(l,{defaultPath:a="download.txt"}={}){if(typeof document>"u")return{canceled:!0,path:null};const n=new Blob([l],{type:"text/plain"}),o=URL.createObjectURL(n),i=document.createElement("a");return i.href=o,i.download=a,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(o),{canceled:!1,path:a}}function p(l){if(!Array.isArray(l))return"";const a=[];for(const n of l)if(Array.isArray(n.extensions))for(const o of n.extensions)a.push(`.${o.replace(/^\./,"")}`);return a.join(",")}function m(){const l=d();async function a(r={}){if(c().isEmbedded){const e=await l.sendRaw({type:"fs.openDialog",title:r.title,filters:r.filters},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDialog failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,content:t.content??null,size:t.size,reason:t.reason}}return u({accept:p(r.filters)})}async function n(r,e={}){if(typeof r!="string")throw new Error("content must be a string");if(c().isEmbedded){const t=await l.sendRaw({type:"fs.saveDialog",title:e.title,defaultPath:e.defaultPath,filters:e.filters,content:r},6e4);if(t&&t.ok===!1)throw new Error(t.error||"fs.saveDialog failed");const s=t?.result??t;return{canceled:!!s.canceled,path:s.path??null}}return f(r,{defaultPath:e.defaultPath})}async function o(r,e={}){const t=JSON.stringify(r,null,2),s={...e,defaultPath:e.defaultPath||"data.json",filters:e.filters||[{name:"JSON",extensions:["json"]}]};return n(t,s)}async function i(r={}){if(!c().isEmbedded)return{canceled:!0,path:null,initialized:!1,unsupported:!0};const e=await l.sendRaw({type:"fs.openDirectory",title:r.title},6e4);if(e&&e.ok===!1)throw new Error(e.error||"fs.openDirectory failed");const t=e?.result??e;return{canceled:!!t.canceled,path:t.path??null,initialized:!!t.initialized}}return{pickFileText:a,saveText:n,saveJson:o,pickDirectory:i}}export{m as u};
@@ -1 +1 @@
1
- import{u as f}from"./index-CB2MOS_8.js";function d(n){if(!n)return n;if(n.error)throw new Error(n.error);return n.result!==void 0?n.result:n}function p(n,t,a,e,r){return typeof n.onMessage!="function"||typeof n.sendRaw!="function"?n.sendRaw({type:t,...a},r).then(d):new Promise((u,s)=>{const l=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`,w=`${t}.event`,g=`${t}.end`;let c=!1,y=()=>{};const o=(i,b)=>{if(!c){c=!0,clearTimeout(m);try{y()}catch{}i(b)}},m=setTimeout(()=>{o(s,new Error(`stream timeout (${r}ms): ${t}`))},r),h=n.onMessage(i=>{if(!(c||!i)&&!(i.id!==l&&i.requestId!==l)){if(i.type===w){if(typeof e=="function")try{e(i.event||i)}catch{}return}if(i.type===g){o(u,d(i));return}i.type==="error"&&o(s,new Error(i.message||"stream error"))}});y=typeof h=="function"?h:()=>{},Promise.resolve(n.sendRaw({id:l,type:t,...a},r)).catch(()=>{})})}function D(){const n=f(),t=(a,e={},r=3e4)=>n.sendRaw({type:a,...e},r).then(d);return{async health(){return await t("personal-data-hub.health",{},8e3)},async stats(){return await t("personal-data-hub.stats",{},8e3)},async listAdapters(){return await t("personal-data-hub.list-adapters",{},5e3)},async pickFile(a={}){try{const e=await n.sendRaw({type:"fs.openDialog",title:a.title,filters:a.filters},6e4),r=e&&e.result!==void 0?e.result:e;return r&&r.ok&&typeof r.filePath=="string"?r.filePath:null}catch{return null}},async adapterReadiness(a){return await t("personal-data-hub.adapter-readiness",Number.isInteger(a)?{timeoutMs:a}:{},15e3)},async syncAdapter(a,e={}){return await t("personal-data-hub.sync-adapter",{name:a,options:e},12e4)},async syncAll(a={}){return await t("personal-data-hub.sync-all",{options:a},6e5)},async registerMock({name:a="mock",count:e=20,seed:r=1}={}){return await t("personal-data-hub.register-mock",{name:a,count:e,seed:r})},async unregister(a){return await t("personal-data-hub.unregister",{name:a})},async ask(a,e={}){return await t("personal-data-hub.ask",{question:a,options:e},18e4)},async queryEvents(a={}){return await t("personal-data-hub.query-events",a,1e4)},async recentAudit(a={}){return await t("personal-data-hub.recent-audit",a,1e4)},async searchEvents(a={}){return await t("personal-data-hub.search-events",a,15e3)},async facetCounts(a={}){return await t("personal-data-hub.facet-counts",a,1e4)},async testEmailAuth(a){return await t("personal-data-hub.test-email-auth",{account:a},3e4)},async registerEmail(a,e={}){return await t("personal-data-hub.register-email",{account:a,opts:e},15e3)},async unregisterEmail(a){return await t("personal-data-hub.unregister-email",{email:a},5e3)},async listEmailAccounts(){return await t("personal-data-hub.list-email-accounts",{},5e3)},async eventDetail(a){return await t("personal-data-hub.event-detail",{eventId:a},5e3)},async syncAdapterStream(a,e={},r){return await p(n,"personal-data-hub.sync-adapter-stream",{name:a,options:e},r,6e5)},async syncAllStream(a={},e){return await p(n,"personal-data-hub.sync-all-stream",{options:a},e,9e5)},async registerAlipay(a,e={}){return await t("personal-data-hub.register-alipay",{account:a,opts:e},15e3)},async unregisterAlipay(a){return await t("personal-data-hub.unregister-alipay",{email:a},5e3)},async listAlipayAccounts(){return await t("personal-data-hub.list-alipay-accounts",{},5e3)},async importAlipayBill({zipPath:a,csvPath:e,zipPassword:r}={}){return await t("personal-data-hub.import-alipay-bill",{zipPath:a,csvPath:e,zipPassword:r},3e5)},async reviewQueueList(a=50){return await t("personal-data-hub.review-queue-list",{limit:a},5e3)},async reviewDecision(a,e){return await t("personal-data-hub.review-decision",{reviewId:a,decision:e},5e3)},async manualMerge(a,e){return await t("personal-data-hub.manual-merge",{aId:a,bId:e},5e3)},async manualUnmerge(a){return await t("personal-data-hub.manual-unmerge",{personId:a},5e3)},async resolverDrain(a=50){return await t("personal-data-hub.resolver-drain",{limit:a},18e4)},async resolverStats(){return await t("personal-data-hub.resolver-stats",{},5e3)},async skillsList(){return await t("personal-data-hub.skills-list",{},5e3)},async runSkill(a,e={}){return await t("personal-data-hub.run-skill",{name:a,options:e},12e4)},async openAichatLogin(a,e={}){return await t("personal-data-hub.aichat-open-login",{vendor:a,opts:e},1e4)},async probeAichatCookies(a,e){return await t("personal-data-hub.aichat-probe-cookies",{vendor:a,cookieHeader:e},1e4)},async registerAichatVendor(a,e,r={}){return await t("personal-data-hub.aichat-register-vendor",{vendor:a,cookies:e,opts:r},3e4)},async rotateAichatLogin(a){return await t("personal-data-hub.aichat-rotate-login",{vendor:a},1e4)},async listAichatAccounts(){return await t("personal-data-hub.list-aichat-accounts",{},5e3)},async unregisterAichat(a){return await t("personal-data-hub.unregister-aichat",{vendor:a},5e3)},async aichatHealthCheckOnce(){return await t("personal-data-hub.aichat-health-check-once",{},3e4)},async probeWechatEnv(){return await t("personal-data-hub.wechat-env-probe",{},15e3)},async registerWechat({account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s}={}){return await t("personal-data-hub.register-wechat",{account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s},45e3)},async listWechatAccounts(){return await t("personal-data-hub.list-wechat-accounts",{},5e3)},async unregisterWechat(a){return await t("personal-data-hub.unregister-wechat",{uin:a},5e3)},async bilibiliAdbSync(a={}){return await t("personal-data-hub.bilibili-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bilibiliAdbDoctor(){return await t("personal-data-hub.bilibili-adb-doctor",{},15e3)},async weiboAdbSync(a={}){return await t("personal-data-hub.weibo-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async xhsAdbSync(a={}){return await t("personal-data-hub.xhs-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async toutiaoAdbSync(a={}){return await t("personal-data-hub.toutiao-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},9e4)},async kuaishouAdbSync(a={}){return await t("personal-data-hub.kuaishou-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bridgeDoctor(){return await t("personal-data-hub.bridge-doctor",{},6e4)},async douyinAdbSync(a={}){return await t("personal-data-hub.douyin-adb-sync",{uid:a.uid,limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)}}}export{D as u};
1
+ import{u as f}from"./index-D3zCCZRS.js";function d(n){if(!n)return n;if(n.error)throw new Error(n.error);return n.result!==void 0?n.result:n}function p(n,t,a,e,r){return typeof n.onMessage!="function"||typeof n.sendRaw!="function"?n.sendRaw({type:t,...a},r).then(d):new Promise((u,s)=>{const l=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`,w=`${t}.event`,g=`${t}.end`;let c=!1,y=()=>{};const o=(i,b)=>{if(!c){c=!0,clearTimeout(m);try{y()}catch{}i(b)}},m=setTimeout(()=>{o(s,new Error(`stream timeout (${r}ms): ${t}`))},r),h=n.onMessage(i=>{if(!(c||!i)&&!(i.id!==l&&i.requestId!==l)){if(i.type===w){if(typeof e=="function")try{e(i.event||i)}catch{}return}if(i.type===g){o(u,d(i));return}i.type==="error"&&o(s,new Error(i.message||"stream error"))}});y=typeof h=="function"?h:()=>{},Promise.resolve(n.sendRaw({id:l,type:t,...a},r)).catch(()=>{})})}function D(){const n=f(),t=(a,e={},r=3e4)=>n.sendRaw({type:a,...e},r).then(d);return{async health(){return await t("personal-data-hub.health",{},8e3)},async stats(){return await t("personal-data-hub.stats",{},8e3)},async listAdapters(){return await t("personal-data-hub.list-adapters",{},5e3)},async pickFile(a={}){try{const e=await n.sendRaw({type:"fs.openDialog",title:a.title,filters:a.filters},6e4),r=e&&e.result!==void 0?e.result:e;return r&&r.ok&&typeof r.filePath=="string"?r.filePath:null}catch{return null}},async adapterReadiness(a){return await t("personal-data-hub.adapter-readiness",Number.isInteger(a)?{timeoutMs:a}:{},15e3)},async syncAdapter(a,e={}){return await t("personal-data-hub.sync-adapter",{name:a,options:e},12e4)},async syncAll(a={}){return await t("personal-data-hub.sync-all",{options:a},6e5)},async registerMock({name:a="mock",count:e=20,seed:r=1}={}){return await t("personal-data-hub.register-mock",{name:a,count:e,seed:r})},async unregister(a){return await t("personal-data-hub.unregister",{name:a})},async ask(a,e={}){return await t("personal-data-hub.ask",{question:a,options:e},18e4)},async queryEvents(a={}){return await t("personal-data-hub.query-events",a,1e4)},async recentAudit(a={}){return await t("personal-data-hub.recent-audit",a,1e4)},async searchEvents(a={}){return await t("personal-data-hub.search-events",a,15e3)},async facetCounts(a={}){return await t("personal-data-hub.facet-counts",a,1e4)},async testEmailAuth(a){return await t("personal-data-hub.test-email-auth",{account:a},3e4)},async registerEmail(a,e={}){return await t("personal-data-hub.register-email",{account:a,opts:e},15e3)},async unregisterEmail(a){return await t("personal-data-hub.unregister-email",{email:a},5e3)},async listEmailAccounts(){return await t("personal-data-hub.list-email-accounts",{},5e3)},async eventDetail(a){return await t("personal-data-hub.event-detail",{eventId:a},5e3)},async syncAdapterStream(a,e={},r){return await p(n,"personal-data-hub.sync-adapter-stream",{name:a,options:e},r,6e5)},async syncAllStream(a={},e){return await p(n,"personal-data-hub.sync-all-stream",{options:a},e,9e5)},async registerAlipay(a,e={}){return await t("personal-data-hub.register-alipay",{account:a,opts:e},15e3)},async unregisterAlipay(a){return await t("personal-data-hub.unregister-alipay",{email:a},5e3)},async listAlipayAccounts(){return await t("personal-data-hub.list-alipay-accounts",{},5e3)},async importAlipayBill({zipPath:a,csvPath:e,zipPassword:r}={}){return await t("personal-data-hub.import-alipay-bill",{zipPath:a,csvPath:e,zipPassword:r},3e5)},async reviewQueueList(a=50){return await t("personal-data-hub.review-queue-list",{limit:a},5e3)},async reviewDecision(a,e){return await t("personal-data-hub.review-decision",{reviewId:a,decision:e},5e3)},async manualMerge(a,e){return await t("personal-data-hub.manual-merge",{aId:a,bId:e},5e3)},async manualUnmerge(a){return await t("personal-data-hub.manual-unmerge",{personId:a},5e3)},async resolverDrain(a=50){return await t("personal-data-hub.resolver-drain",{limit:a},18e4)},async resolverStats(){return await t("personal-data-hub.resolver-stats",{},5e3)},async skillsList(){return await t("personal-data-hub.skills-list",{},5e3)},async runSkill(a,e={}){return await t("personal-data-hub.run-skill",{name:a,options:e},12e4)},async openAichatLogin(a,e={}){return await t("personal-data-hub.aichat-open-login",{vendor:a,opts:e},1e4)},async probeAichatCookies(a,e){return await t("personal-data-hub.aichat-probe-cookies",{vendor:a,cookieHeader:e},1e4)},async registerAichatVendor(a,e,r={}){return await t("personal-data-hub.aichat-register-vendor",{vendor:a,cookies:e,opts:r},3e4)},async rotateAichatLogin(a){return await t("personal-data-hub.aichat-rotate-login",{vendor:a},1e4)},async listAichatAccounts(){return await t("personal-data-hub.list-aichat-accounts",{},5e3)},async unregisterAichat(a){return await t("personal-data-hub.unregister-aichat",{vendor:a},5e3)},async aichatHealthCheckOnce(){return await t("personal-data-hub.aichat-health-check-once",{},3e4)},async probeWechatEnv(){return await t("personal-data-hub.wechat-env-probe",{},15e3)},async registerWechat({account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s}={}){return await t("personal-data-hub.register-wechat",{account:a,dbPath:e,wechatDataPath:r,fridaOpts:u,keyProviderOverride:s},45e3)},async listWechatAccounts(){return await t("personal-data-hub.list-wechat-accounts",{},5e3)},async unregisterWechat(a){return await t("personal-data-hub.unregister-wechat",{uin:a},5e3)},async bilibiliAdbSync(a={}){return await t("personal-data-hub.bilibili-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bilibiliAdbDoctor(){return await t("personal-data-hub.bilibili-adb-doctor",{},15e3)},async weiboAdbSync(a={}){return await t("personal-data-hub.weibo-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async xhsAdbSync(a={}){return await t("personal-data-hub.xhs-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)},async toutiaoAdbSync(a={}){return await t("personal-data-hub.toutiao-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},9e4)},async kuaishouAdbSync(a={}){return await t("personal-data-hub.kuaishou-adb-sync",{limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},12e4)},async bridgeDoctor(){return await t("personal-data-hub.bridge-doctor",{},6e4)},async douyinAdbSync(a={}){return await t("personal-data-hub.douyin-adb-sync",{uid:a.uid,limits:a.limits,stagingDir:a.stagingDir,displayName:a.displayName},6e4)}}}export{D as u};
@@ -1 +1 @@
1
- import{N as i,h as a,w as l}from"./index-CB2MOS_8.js";import{a7 as o,k as g,C as d,F as f,A as p}from"./vendor-Bn1JzzAn.js";function c(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,u=e;if(Array.isArray(e)&&(u=i(e)[0]),!u)return null;const n=o(u,r,s);return n.props=t?a(a({},n.props),r):n.props,l(typeof n.props.class!="object","class must be string"),n}function V(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return e.map(s=>c(s,r,t))}function v(e,r,t){p(o(e,a({},r)),t)}const m=e=>(e||[]).some(r=>g(r)?!(r.type===d||r.type===f&&!m(r.children)):!0)?e:null;function h(e,r,t,s){var u;const n=(u=e[r])===null||u===void 0?void 0:u.call(e,t);return m(n)?n:s?.()}export{h as a,V as b,c,v as t};
1
+ import{N as i,h as a,w as l}from"./index-D3zCCZRS.js";import{a7 as o,k as g,C as d,F as f,A as p}from"./vendor-Bn1JzzAn.js";function c(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0,s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,u=e;if(Array.isArray(e)&&(u=i(e)[0]),!u)return null;const n=o(u,r,s);return n.props=t?a(a({},n.props),r):n.props,l(typeof n.props.class!="object","class must be string"),n}function V(e){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;return e.map(s=>c(s,r,t))}function v(e,r,t){p(o(e,a({},r)),t)}const m=e=>(e||[]).some(r=>g(r)?!(r.type===d||r.type===f&&!m(r.children)):!0)?e:null;function h(e,r,t,s){var u;const n=(u=e[r])===null||u===void 0?void 0:u.call(e,t);return m(n)?n:s?.()}export{h as a,V as b,c,v as t};
@@ -1,4 +1,4 @@
1
- import{K as o}from"./index-CB2MOS_8.js";import{i as f}from"./motion-BVSN0aeL.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
1
+ import{K as o}from"./index-D3zCCZRS.js";import{i as f}from"./motion-B3FQm2By.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
2
2
  ${t}-enter,
3
3
  ${t}-appear
4
4
  `]:{transform:"scale(0)",opacity:0,animationTimingFunction:n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${t}-leave`]:{animationTimingFunction:n.motionEaseInOutCirc}}]};export{h as i,c as z};
@@ -8,7 +8,7 @@
8
8
  // Injected by web-ui-server.js at serve time
9
9
  window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
10
10
  </script>
11
- <script type="module" crossorigin src="./assets/index-CB2MOS_8.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-D3zCCZRS.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="./assets/vendor-Bn1JzzAn.js">
13
13
  <link rel="modulepreload" crossorigin href="./assets/icons-DG5UD-6K.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
@@ -20,6 +20,7 @@ import { fileURLToPath } from "node:url";
20
20
  import chalk from "chalk";
21
21
  import { AgentScheduleStore } from "../lib/agent-schedule-store.js";
22
22
  import { sendAgentNotification } from "../lib/agent-notify.js";
23
+ import { nextWakeupAt } from "../lib/schedule-planner.js";
23
24
 
24
25
  const BIN_PATH = fileURLToPath(
25
26
  new URL("../../bin/chainlesschain.js", import.meta.url),
@@ -63,8 +64,13 @@ export function runAgendaList(options = {}, _deps = {}) {
63
64
  const log = _deps.log || ((m) => console.log(m));
64
65
  const store = _deps.store || new AgentScheduleStore();
65
66
  const entries = store.list(options.kind || null);
67
+ // Adaptive next-wakeup (schedule-planner): the earliest future fire time
68
+ // across all schedulable, non-expired entries — what a daemon would sleep
69
+ // until. `now` is injectable for tests.
70
+ const now = _deps.now ? _deps.now() : Date.now();
71
+ const nextAt = nextWakeupAt(entries, { now });
66
72
  if (options.json) {
67
- log(JSON.stringify({ entries }, null, 2));
73
+ log(JSON.stringify({ entries, nextWakeupAt: nextAt }, null, 2));
68
74
  return 0;
69
75
  }
70
76
  if (entries.length === 0) {
@@ -86,6 +92,14 @@ export function runAgendaList(options = {}, _deps = {}) {
86
92
  );
87
93
  log(` ${chalk.dim(when)}`);
88
94
  }
95
+ if (nextAt != null) {
96
+ const rel = Math.max(0, Math.round((nextAt - now) / 1000));
97
+ log(
98
+ chalk.gray(
99
+ `\n next wakeup: ${new Date(nextAt).toISOString()} (in ${rel}s)`,
100
+ ),
101
+ );
102
+ }
89
103
  log("");
90
104
  return 0;
91
105
  }
@@ -290,6 +290,10 @@ export function registerAgentCommand(program) {
290
290
  "Headless input: text | stream-json (NDJSON user events on stdin, multi-turn)",
291
291
  "text",
292
292
  )
293
+ .option(
294
+ "--trace-id <id>",
295
+ "Correlation id stamped as `trace_id` on every stream-json output line (also read from CC_TRACE_ID). Lets an IDE/bridge trace one run across its own logs, the CLI, transcripts and diagnostics. Auto-generated per run when omitted.",
296
+ )
293
297
  .option(
294
298
  "--fallback-model <model>",
295
299
  "Backup model(s) to try in order when the primary fails (transient error or model-not-found). Repeatable or comma-separated; up to 3. A `provider:model` entry (e.g. openai:gpt-4o) falls back cross-provider, using that provider's API key from its env var (skipped if unset — never reuses the primary key). Defaults to config llm.fallbackModels.",
@@ -828,6 +832,9 @@ export function registerAgentCommand(program) {
828
832
  baseUrl: options.baseUrl,
829
833
  apiKey: options.apiKey,
830
834
  sessionId: options.session,
835
+ // Cross-event correlation id for this run (stamped as `trace_id` on
836
+ // every output line); falls back to CC_TRACE_ID / auto-generated.
837
+ traceId: options.traceId || null,
831
838
  // Auto-checkpoint follows the same resolution as the headless/REPL
832
839
  // paths (default ON in a git repo) so panel/stream sessions snapshot
833
840
  // before mutating tools and can be rewound via `cc checkpoint`.
@@ -103,10 +103,24 @@ async function loadSupervisor() {
103
103
  return import("../lib/background-agent-supervisor.js");
104
104
  }
105
105
 
106
- function readLogFromOffset(file, offset) {
106
+ export const LOG_TRUNCATION_NOTICE =
107
+ "--- log truncated/rotated, resuming from tail ---";
108
+ const TRUNCATION_RESUME_TAIL_BYTES = 4096;
109
+
110
+ export function readLogFromOffset(file, offset) {
107
111
  if (!existsSync(file)) return { text: "", offset };
108
112
  const text = readFileSync(file, "utf8");
109
- if (offset > text.length) offset = 0;
113
+ if (offset > text.length) {
114
+ // Gap 3: the log shrank under us (rotation/truncation). Resetting the
115
+ // offset to 0 used to REPLAY the entire new file into the follow stream;
116
+ // resume from the current tail instead, with an explicit marker.
117
+ const from = Math.max(0, text.length - TRUNCATION_RESUME_TAIL_BYTES);
118
+ return {
119
+ text: `\n${LOG_TRUNCATION_NOTICE}\n${text.slice(from)}`,
120
+ offset: text.length,
121
+ truncated: true,
122
+ };
123
+ }
110
124
  return { text: text.slice(offset), offset: text.length };
111
125
  }
112
126
 
@@ -3,7 +3,7 @@
3
3
  "releases": [
4
4
  {
5
5
  "productVersion": "Unreleased",
6
- "cliVersion": "0.162.160",
6
+ "cliVersion": "0.162.161",
7
7
  "cliVersions": [
8
8
  "0.4.46",
9
9
  "0.4.51",
@@ -18,11 +18,16 @@
18
18
  "0.162.157",
19
19
  "0.162.158",
20
20
  "0.162.159",
21
- "0.162.160"
21
+ "0.162.160",
22
+ "0.162.161"
22
23
  ],
23
24
  "date": null,
24
25
  "title": "",
25
26
  "sections": [
27
+ {
28
+ "heading": "Added — cc CLI 0.162.161:增量 gap-analysis(P0 后台状态机/跨 Agent 授权/凭据代理 + P1 完成条件/Monorepo 排除/持久 Scheduler)+ bg-* WS relay 协议硬化(CLI-only npm 发版)",
29
+ "body": "> `chainlesschain` 0.162.160 → **0.162.161** 发 npm `latest`(经 `npm-publish.yml`,`--provenance --access public`)。纯 `packages/cli/src` + `packages/agent-sdk` 协议增量;未触 `pdh/lib` → 无 Android cc bundle rollover / 无 USR_VERSION 改动。命令面无新顶层命令(`cc agenda list` 增 `nextWakeupAt` 字段),**顶层命令数 175 不变**。对照 `docs/CLAUDE_CODE_CLI_INCREMENTAL_GAP_ANALYSIS_2026-07-12.md`(vs Claude Code v2.1.207)逐节落地 P0/P1 Windows-可做、自包含、全测试的最有价值切片,每节文档记录「已落地」与「仍欠」。\n>\n> 全部为纯核 + 时钟注入(无 timer/RNG,确定性可测)+ 最小真实接线的低风险增量;已落地增量的 9 个测试文件 148 测全绿。\n\n- **跨事件 `trace_id`(协议 §1.2.1)**:stream-json 每行标注 run-scoped `trace_id`(`--trace-id` / `CC_TRACE_ID` / 自动生成),`sanitizeTraceId` 限字符集 `[A-Za-z0-9._:-]`≤128,供跨进程/跨 Agent 事件关联。\n- **后台 Agent 状态机(P0)**:拆分 Idle 与 Needs-input——`background-agent-phase.js` 归一化 phase(starting/working/idle/needs_input/waiting_permission,legacy `turn`→working),`phaseGroupKey` 让 `cc` 后台仪表板把「空闲」与「待输入/待批准」分组显示,不再混为一谈。\n- **跨 Agent 授权边界(P0 安全)**:`agent-authority.js` 授权信封——`origin`(user/model/subagent/teammate/channel/hook/remote/system/permission_tool)→ `authority`(none/steer/approve/manage),仅 user=manage、permission_tool=approve、已认证且 approve-scoped 的 remote=approve 可批准;`approvalBindingDigest({toolCallId,args,policyDigest})` 常数时间校验、fail-closed,防止一个 Agent 冒用另一个的批准。`origin` 恒由可信 dispatch 赋值,绝不从消息内容读取。\n- **跨平台沙箱与凭据代理(P0)**:`credential-proxy.js`——子进程环境默认屏蔽长效凭据(`maskCredentialEnv` 把 secret 值换成哨兵 `cc-cred-redacted:<NAME>`,`mask`/`deny` 双模式),审计日志绝不记录还原后的明文(`redactEnvForAudit`),`resolveApprovedInjection` 按 approved-host fail-closed 注入;`CC_CREDENTIAL_PROXY` 开关,关闭时同对象引用零开销。接线到 agent-core 前后台两处 spawn。\n- **会话级完成条件引擎(P1)**:`goal-condition-engine.js`——确定性完成条件(`exit-zero:`/`file-exists:`/`contains:`/`regex:`/`model:`/裸),预算(maxOuterTurns 默认 10、硬顶 100)+ 纯 reducer `evaluateGoalStep`,`GoalConditionEngine` 支持 snapshot/fromSnapshot 恢复;确定性检查经注入 spawnSync/existsSync 可测。\n- **大型 Monorepo 上下文排除(P1)**:`instructionExcludes`——`project-instructions.js` 支持按 glob 排除 legacy/vendor/generated 子树(裸名=任意段匹配、带斜杠前缀=目录+后代、`*`/`**`/`?` 通配、祖先匹配语义),@import 目标落在排除子树内也跳过(避免把凭据文件拉进 prompt);`composeSystemPrompt` 透传 `instructionExcludes`。\n- **统一持久 Scheduler 规划器(P1)**:`schedule-planner.js`——确定性 jitter(FNV-1a 稳定 per-task 偏移,跨重启不漂移,避免共享 cron 分钟的惊群)、自适应唤醒(`nextWakeupAt`/`msUntilNextWakeup` 让 daemon 睡到最早 fire 而非轮询)、过期(`isEntryExpired`/`partitionSchedule` 先退休过期再触发);接线到 `cc agenda list`(JSON `nextWakeupAt` + \"next wakeup\" 行)。\n- **bg-* WS relay 协议硬化**:事件序号缺口检测 + replay(慢/断线消费者补投)、出站背压(slow-consumer 保护)、跨语言 fixture 契约 + `tool_use_id` + event seq,IDE 上报文件路径的 remote URI/path 映射,MCP tool-path 边界守卫 + Windows lockfile ACL,diff-apply 并发/二进制守卫 + 读取实时编辑器缓冲的 stale-rejection,后台 Agent supervisor 3 个 pinned gap 收口 + 有界 prompt 队列。"
30
+ },
26
31
  {
27
32
  "heading": "Added — cc CLI 0.162.160:运行时安全与确定性 8 批(沙箱严格模式 + 依赖/凭据安全 + 确定性 Headless + Subagent 契约 + MCP 生命周期 + Hooks 硬化)(CLI-only npm 发版)",
28
33
  "body": "> `chainlesschain` 0.162.159 → **0.162.160** 发 npm `latest`(经 `npm-publish.yml`,`--provenance --access public`)。纯 `packages/cli/src` 增量;未触 `pdh/lib` → 无 Android cc bundle rollover / 无 USR_VERSION 改动。命令面**只加子命令**(`cc session rename/prune`、`cc daemon rm`、`cc mcp trust-project`),**顶层命令数 175 不变**(manifest 无需重生)。对照 `docs/CLAUDE_CODE_CLI_GAP_ANALYSIS.md`(docs 根)审计确认仍缺的 8 项全落地(commit 链 `c4533ad848..4c2e297754`)。\n>\n> ⚠️ **行为变更(升级前须知)**:① `run_code` 的 pip 依赖**默认不再自动安装**(改 opt-in,见下);② agent 脚本默认写 OS 临时目录、不再落项目根(`persist:true` 才进项目);③ headless/agent **退出码细化**——最大轮次→3、预算超限→4、模型错误→5、配置错误→6(成功仍 0、通用失败仍 1、hook block 仍 2、SIGINT/SIGTERM 仍 130/143)。依赖固定 exit≠0 判失败的脚本不受影响;依赖\"失败必为 1\"的脚本需放宽。\n\n- **确定性 Headless(A)**:新增 `--ephemeral`(resume 只读回放、零落盘);init 事件补 `protocol_version`/`session_persistence`/`loaded_sources`/`policy_digest`/`tools_hash`/`isolation_level`(消费者可判定回放确定性与工具/策略指纹);退出码分类(`lib/exit-codes.cjs`);`cc agent --capabilities` 打印机读能力清单(协议版本、agent 工具集、权限模式、退出码、特性开关)后退出。\n- **依赖安装安全(B)**:`run_code` 的 pip 自动安装**默认关闭**——经 settings `runCode.autoInstall` 或 `CC_RUN_CODE_AUTO_INSTALL` 显式开启,且受 `runCode.installAllowlist`(PEP 503 归一化包名)约束,每次安装写审计 JSONL(`~/.chainlesschain/audit/`,`CC_AUDIT_DIR` 可覆盖);agent 脚本默认写 OS 临时目录(`persist:true` 才进项目根)。系统提示词/工具契约文案已同步。\n- **凭据卫生(C)**:config `llm.apiKeyHelper`——从外部命令(→ OS 凭据库)解析 API Key,5 分钟缓存,helper 失败 **fail-closed 并告警一次**(返回 null,绝不静默替换成别的凭据);argv `--api-key` 明文传参现给出告警(进程表/shell 历史泄露面)。\n- **沙箱严格模式(D)**:`failIfUnavailable` 此前只是声明、从不执行——现在启动期探测沙箱引擎(docker `version` / bwrap `--version`),不可用即拒绝启动(退出码 6),headless 与交互双路均生效;`isolation_level`(os-sandbox / container / policy-only)透出到 init 事件与 `sandboxSummary`,不再静默降级为\"只有工具规则\"。\n- **Subagent 契约(E)**:`spawn_sub_agent` 与 `.claude/agents/*.md` frontmatter 双入口新增 `disallowedTools`(从 allowedTools 减去)、`maxTurns`、`isolation:worktree`。**顺手修出一个真 bug**:`SubAgentContext._runCore` 早已算出工具白名单却从未传给 agentLoop——子代理在 LLM 面一直看到全量工具,白名单形同虚设(修=`enabledToolNames` 透传)。\n- **会话运营(F)**:`cc session rename <id> <title>`(append `session_rename` 事件,哈希链不破)+ `cc session prune --older-than <days> [--keep N] [--dry-run]`(按最后活动保留期清理,默认保最新 10)+ `cc daemon rm <id> [--force] [--keep-log]`(终态直接移除、运行中需 `--force`)。\n- **MCP 生命周期(G)**:mcp-client 处理 `notifications/tools/list_changed` + `notifications/resources/list_changed`——合并式重拉服务器工具/资源清单(刻意**不动 in-flight LLM 工具数组**,保 tool-search 缓存稳定性,追加式更新);项目 `.mcp.json` 首用记 sha256 指纹,文件变更后 **fail-closed 拒绝加载**,需 `CC_PROJECT_MCP_TRUST=1` 或 `cc mcp trust-project` 显式重信任(防被换过的项目配置静默拉起新 MCP server)。\n- **Hooks 硬化(H)**:每个 hook 的 stdin payload 打 `schema_version`(=1,additive 变更保号、破坏性 reshape 才 bump);连续失败熔断——同一 hook 命令连续 3 次非阻塞失败(spawn error / 超时 / 非 2 非零退出)开闸,60s 冷却后半开试跑一次,成功或真 block/ask 决策关闸(`CC_HOOK_BREAKER_THRESHOLD=0` 关闭、`CC_HOOK_BREAKER_COOLDOWN_MS` 可调);坏 hook 不再每轮拖慢 agent。"
@@ -8,17 +8,37 @@
8
8
  * Routes (request → reply):
9
9
  * bg-list {all?} → {type:"bg-list", sessions}
10
10
  * bg-view {bgId, lines?} → {type:"bg-view", session, log}
11
- * bg-attach {bgId, lines?} → {type:"bg-attach", bgId, hello, log}
11
+ * bg-attach {bgId, lines?, sinceSeq?} → {type:"bg-attach", bgId, hello,
12
+ * log, latestSeq, [reattached, replayed,
13
+ * replayTruncated]}
12
14
  * bg-prompt {bgId, text} → {type:"bg-prompt", bgId, sent}
13
15
  * bg-stop-turn {bgId} → {type:"bg-stop-turn", bgId, sent}
14
16
  * bg-detach {bgId} → {type:"bg-detach", bgId}
15
17
  * bg-stop {bgId} → {type:"bg-stop", session} (kill whole session)
16
18
  *
17
- * While attached, the server pushes unsolicited frames to that client:
18
- * {type:"bg-event", bgId, event} worker lifecycle events (turn-started /
19
+ * While attached, the server pushes unsolicited frames to that client, each
20
+ * stamped with a per-attachment monotonic `seq` (additive; older clients
21
+ * ignore it) so the client can detect gaps and request a replay:
22
+ * {type:"bg-event", bgId, seq, event} worker lifecycle events (turn-started /
19
23
  * turn-ended / idle / accepted / error /
20
24
  * transport-closed)
21
- * {type:"bg-log", bgId, chunk} log-file delta (500ms poll)
25
+ * {type:"bg-log", bgId, seq, chunk} log-file delta (500ms poll)
26
+ *
27
+ * Reconnect resilience: a panel whose WS blipped re-sends bg-attach with the
28
+ * last `seq` it saw (`sinceSeq`); the still-live relay re-pushes the frames it
29
+ * missed (bounded buffer) and reports `latestSeq`. If the missed range was
30
+ * already evicted, `replayTruncated:true` tells the client to full-resync from
31
+ * the log. If the relay was fully torn down (WS closed → cleanup), the fresh
32
+ * attach returns hello + log tail as before and the client resets its tracker.
33
+ *
34
+ * Backpressure: if the WS client drains too slowly (ws.bufferedAmount over the
35
+ * high water), DROPPABLE frames (bg-log) are shed while CRITICAL ones (bg-event
36
+ * lifecycle) are always delivered. Dropped frames are still recorded (seq
37
+ * advances), so the gap on the next delivered frame trips the client's
38
+ * replaySince recovery. A one-shot {type:"bg-lag", bgId, lagging:true} marks
39
+ * the start and {type:"bg-lag", bgId, lagging:false, dropped, latestSeq} the
40
+ * recovery — the UI shows "catching up" instead of freezing. bg-lag frames
41
+ * carry no seq (out-of-band control; the gap tracker ignores them).
22
42
  *
23
43
  * The state file's `transport.token` is the local takeover capability — it is
24
44
  * NEVER sent over WS. Sessions are serialized with `interactive: true/false`
@@ -26,6 +46,12 @@
26
46
  */
27
47
 
28
48
  import { existsSync, readFileSync } from "node:fs";
49
+ import { EventReplayBuffer } from "../../lib/event-seq-replay.js";
50
+ import {
51
+ BackpressurePolicy,
52
+ CRITICAL,
53
+ DROPPABLE,
54
+ } from "../../lib/backpressure-policy.js";
29
55
 
30
56
  const LOG_POLL_MS = 500;
31
57
 
@@ -139,6 +165,20 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
139
165
  if (existing) {
140
166
  // Idempotent re-attach: reply with the live handshake instead of
141
167
  // stacking a second relay (a reconnecting panel re-sends bg-attach).
168
+ // If the panel reports the last seq it saw (`sinceSeq`), replay the
169
+ // push frames it missed while the WS was blipped — re-sent as normal
170
+ // bg-event/bg-log frames (their original seq), so the client's gap
171
+ // tracker sees a contiguous run. `replayTruncated` tells the client the
172
+ // hole predates our buffer and it must full-resync (re-read the log).
173
+ const sinceSeq = Number(message.sinceSeq);
174
+ let replayTruncated = false;
175
+ let replayed = 0;
176
+ if (Number.isFinite(sinceSeq)) {
177
+ const { frames, truncated } = existing.buffer.replaySince(sinceSeq);
178
+ replayTruncated = truncated;
179
+ replayed = frames.length;
180
+ for (const frame of frames) server._send(ws, frame);
181
+ }
142
182
  server._send(ws, {
143
183
  id,
144
184
  type: "bg-attach",
@@ -146,6 +186,9 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
146
186
  hello: existing.hello,
147
187
  log: "",
148
188
  reattached: true,
189
+ latestSeq: existing.buffer.latestSeq,
190
+ replayed,
191
+ replayTruncated,
149
192
  });
150
193
  return;
151
194
  }
@@ -172,6 +215,42 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
172
215
  );
173
216
  }
174
217
 
218
+ // Per-attachment replay buffer: stamps a monotonic seq on every push frame
219
+ // and retains a bounded tail so a reconnecting client can fill gaps
220
+ // (bg-attach { sinceSeq }). One buffer per relay instance — seq restarts
221
+ // at 1 on a fresh attach, so the client resets its tracker then.
222
+ const buffer = new EventReplayBuffer();
223
+ // Backpressure: if the WS client drains too slowly (ws.bufferedAmount grows
224
+ // past the high water), shed DROPPABLE frames (bg-log — recoverable) while
225
+ // still delivering CRITICAL ones (bg-event lifecycle). Dropped frames are
226
+ // still RECORDED (seq advances), so the seq gap on the next delivered frame
227
+ // trips the client's replaySince recovery; a one-shot bg-lag notice lets
228
+ // the UI show "catching up" instead of freezing. Buffer stays 0 in the
229
+ // normal case → byte-identical legacy behavior.
230
+ const backpressure = new BackpressurePolicy();
231
+ const bufferedBytes = () =>
232
+ ws && Number.isFinite(ws.bufferedAmount) ? ws.bufferedAmount : 0;
233
+ const pushFrame = (base, frameClass) => {
234
+ const frame = buffer.record(base); // record always → seq advances, replay recovers drops
235
+ const d = backpressure.evaluate(bufferedBytes(), frameClass);
236
+ if (d.lagStarted)
237
+ server._send(ws, { type: "bg-lag", bgId, lagging: true });
238
+ if (d.send) server._send(ws, frame);
239
+ if (d.lagEnded) {
240
+ server._send(ws, {
241
+ type: "bg-lag",
242
+ bgId,
243
+ lagging: false,
244
+ dropped: d.dropped,
245
+ latestSeq: buffer.latestSeq,
246
+ });
247
+ }
248
+ };
249
+ const pushEvent = (event) =>
250
+ pushFrame({ type: "bg-event", bgId, event }, CRITICAL);
251
+ const pushLog = (chunk) =>
252
+ pushFrame({ type: "bg-log", bgId, chunk }, DROPPABLE);
253
+
175
254
  const { connectBackgroundSession } =
176
255
  await import("../../lib/background-session-transport.js");
177
256
  let conn;
@@ -179,16 +258,10 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
179
258
  conn = await connectBackgroundSession({
180
259
  pipePath: session.transport.pipe,
181
260
  token: session.transport.token,
182
- onEvent: (event) => {
183
- server._send(ws, { type: "bg-event", bgId, event });
184
- },
261
+ onEvent: (event) => pushEvent(event),
185
262
  onClose: () => {
186
263
  if (dropAttachment(client, bgId)) {
187
- server._send(ws, {
188
- type: "bg-event",
189
- bgId,
190
- event: { type: "transport-closed" },
191
- });
264
+ pushEvent({ type: "transport-closed" });
192
265
  }
193
266
  },
194
267
  });
@@ -212,7 +285,7 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
212
285
  if (text.length > offset) {
213
286
  const chunk = text.slice(offset);
214
287
  offset = text.length;
215
- server._send(ws, { type: "bg-log", bgId, chunk });
288
+ pushLog(chunk);
216
289
  }
217
290
  } catch {
218
291
  /* transient read failures skip one tick */
@@ -220,7 +293,7 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
220
293
  }, LOG_POLL_MS);
221
294
  poll.unref?.();
222
295
 
223
- attachments(client).set(bgId, { conn, poll, hello: conn.hello });
296
+ attachments(client).set(bgId, { conn, poll, hello: conn.hello, buffer });
224
297
  server._send(ws, {
225
298
  id,
226
299
  type: "bg-attach",
@@ -229,6 +302,7 @@ export async function handleBgAttach(server, clientId, id, ws, message) {
229
302
  log: readBackgroundAgentLog(bgId, {
230
303
  lines: Number(message.lines) || 100,
231
304
  }),
305
+ latestSeq: buffer.latestSeq,
232
306
  });
233
307
  } catch (err) {
234
308
  sendError(server, id, ws, "BG_ATTACH_FAILED", err.message);