chainlesschain 0.162.151 → 0.162.152

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 (177) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-DuEOzebi.js → AIOps-CVLVJS-Q.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C6GiJa5H.js → ActionButton-CJ2_GJsI.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BBIiL_pO.js → Analytics-CZsmlTF8.js} +2 -2
  7. package/src/assets/web-panel/assets/{AppLayout-CuI2gZRy.js → AppLayout-DREvMZ62.js} +5 -5
  8. package/src/assets/web-panel/assets/{Audit-CbUjfr-K.js → Audit-B4NR42w_.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-CsSW9ljf.js → Backup-CJFmf3In.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-kM3rLe7F.js → BaseInput-Bh8_iUZY.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-kfE51YN3.js → Chat-DEwKjIxV.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-BOqHkxK_.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-jYb1uj-M.js → Checkbox-DYWCqYI9.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-X9XiD5Lj.js → Codegen-BlXrfZAJ.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-BfbHu1xI.js → Col-DLPM22eX.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-c4oJMFS-.js → Community-PFyzqijs.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BFmnZpH7.js → Compact-7DIfY5Wp.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-s9shVHBS.js → Compliance-DF4CinPU.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-C5da--TC.js → Cowork-B1J80Vcj.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-9kNbyNE4.js → Cron-B7sx2OXX.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-C1k3NJD4.js → Crosschain-omLkxmu-.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-DkheEvNK.js → DID-B_7r7b5F.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-C3FuSGmJ.js → Dashboard-Cp7k3GZg.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CAV6FMFD.js → Dropdown-BCKO89Y8.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-Cc-Ulc4l.js → EmailListRenderer-CNgTSsFZ.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-8CitHEtv.js → FamilyGuardDashboard-DobM83JP.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DFSZ5KDt.js → Federation-XVAYQIeu.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CEWCtnG2.js → FormItemContext-DV5ka1KQ.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-CwRzNzmX.js → GenericCardRenderer-Dg5q-KpC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-0rgDM7cJ.js → Git-Dsn3Xhxf.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CfBKtK9F.js → Governance-D06S4Qow.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CzcUVvud.js → Inference-nAvwxUXy.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-Dwc4YL4A.js → KnowledgeGraph-CtqRP_rF.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-DgFPwR2F.js → Logs-J5aGAyfY.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-DnpPTbGU.js → Marketplace-CaeY23Kj.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-DRxxINyW.js → McpTools-C2HHnwnE.js} +4 -4
  37. package/src/assets/web-panel/assets/{Memory-OhmW_6Z3.js → Memory-CWBrdKlR.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-DkTW-RK5.js → MobileBridge-CBLQ8uCY.js} +1 -1
  39. package/src/assets/web-panel/assets/{MobileProjects-DpCGV_lI.js → MobileProjects-Q_Cy_W4_.js} +1 -1
  40. package/src/assets/web-panel/assets/{Mtc--vmkL0AS.js → Mtc-BXur-euo.js} +2 -2
  41. package/src/assets/web-panel/assets/{MtcAudit-DGoFWjD4.js → MtcAudit-CpQSlOQC.js} +5 -5
  42. package/src/assets/web-panel/assets/{Multisig-B4kWgq95.js → Multisig-DlFwdEOA.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-YQwvommE.js → NLProgramming-DSh7fevc.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-CgjtUADJ.js → Notes-Bv4NOVxg.js} +3 -3
  45. package/src/assets/web-panel/assets/{NotificationSettings-6JDrpBG5.js → NotificationSettings-CzHNnIfa.js} +1 -1
  46. package/src/assets/web-panel/assets/{OrderTableRenderer-PM6IlxjO.js → OrderTableRenderer-D7pHfKK4.js} +1 -1
  47. package/src/assets/web-panel/assets/{Organization-8McOT_OF.js → Organization-COzV01ed.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-DAZpSCGc.js → Overflow-CYRZJb2_.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-B7l2ZWLy.js → P2P-DFm49FE0.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-W1Ud-NAL.js → PdhVaultBrowser-Ctr-6k5B.js} +3 -3
  51. package/src/assets/web-panel/assets/{Permissions-Czm_w9u_.js → Permissions-DXVrhFyv.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-B4F0_ZVM.js → PersonalDataHub-BO5utpLK.js} +2 -2
  53. package/src/assets/web-panel/assets/{Pipeline-B37aFiWv.js → Pipeline-C9irYCg7.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-94KBnRrD.js → Privacy-r13hrvoF.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-B5h8_dlh.js → ProjectInit-PRKNPZZC.js} +2 -2
  56. package/src/assets/web-panel/assets/{ProjectSettings-lmeI3Lpm.js → ProjectSettings-QvxM1ZDO.js} +2 -2
  57. package/src/assets/web-panel/assets/{Projects-D5AYOasl.js → Projects-DfgmsN3j.js} +1 -1
  58. package/src/assets/web-panel/assets/{Providers-B3cNWwJg.js → Providers-DxbrccZ7.js} +1 -1
  59. package/src/assets/web-panel/assets/{QrScannerModal-CHRvOw1R.js → QrScannerModal-BMHVRxBX.js} +1 -1
  60. package/src/assets/web-panel/assets/{QuickAsk-D1JMgFEd.js → QuickAsk-Co3_ndAH.js} +1 -1
  61. package/src/assets/web-panel/assets/{Recommend-EYWGR79p.js → Recommend-Cv3UWR6s.js} +1 -1
  62. package/src/assets/web-panel/assets/{RemoteSession-BAMC2pJt.js → RemoteSession-CSDsO2zA.js} +2 -2
  63. package/src/assets/web-panel/assets/{Reputation-X2Hk1XG_.js → Reputation-Bdj59vzM.js} +1 -1
  64. package/src/assets/web-panel/assets/{Row-Eq98LRtU.js → Row-CejfUjmo.js} +1 -1
  65. package/src/assets/web-panel/assets/{RssFeed-i76s6z_o.js → RssFeed-C83yKkvU.js} +2 -2
  66. package/src/assets/web-panel/assets/{Search-D_Es7CAI.js → Search-Ck4l_VI3.js} +1 -1
  67. package/src/assets/web-panel/assets/{Security-kayD2e94.js → Security-DGIIEx6K.js} +3 -3
  68. package/src/assets/web-panel/assets/{Services-Ctsm6ul8.js → Services-Cj2aNAy3.js} +2 -2
  69. package/src/assets/web-panel/assets/{Skeleton-CRNYlfdf.js → Skeleton-Dlyy8akb.js} +1 -1
  70. package/src/assets/web-panel/assets/{Skills-DkZYpF4-.js → Skills-C4aDa9Zh.js} +1 -1
  71. package/src/assets/web-panel/assets/{Sla-DXkoBcOP.js → Sla-tHd_Bauo.js} +1 -1
  72. package/src/assets/web-panel/assets/{SpeechSettings-DXi_GI1d.js → SpeechSettings-DI7R0Qgd.js} +1 -1
  73. package/src/assets/web-panel/assets/{SyncSettings-rNKpfomn.js → SyncSettings-OOxiPdsE.js} +2 -2
  74. package/src/assets/web-panel/assets/{Tasks-XF4uPtG-.js → Tasks-Nro_Ltg5.js} +1 -1
  75. package/src/assets/web-panel/assets/{Templates-i0Hzfeyu.js → Templates-Bm7eSMWH.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tenant-sMpHAi27.js → Tenant-B8F8eFvD.js} +1 -1
  77. package/src/assets/web-panel/assets/Terminal-2oWhR7QF.js +3 -0
  78. package/src/assets/web-panel/assets/{TimelineRenderer-yuC6K7Rf.js → TimelineRenderer-GLnecmpd.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tokens-B8O8i0s6.js → Tokens-CtpFyati.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trigger-Bv6yrlCr.js → Trigger-DGkXZzbN.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trust-C4mW95Ev.js → Trust-ClYZMkXN.js} +1 -1
  82. package/src/assets/web-panel/assets/{UkeySign-DV6yKaHn.js → UkeySign-C1AuEW5-.js} +1 -1
  83. package/src/assets/web-panel/assets/{VideoEditing-UI479-sD.js → VideoEditing-DHa9ekSK.js} +1 -1
  84. package/src/assets/web-panel/assets/{Wallet-M5oV9EVP.js → Wallet-CyQv8ZAN.js} +4 -4
  85. package/src/assets/web-panel/assets/{WebAuthn-DDyDHPDR.js → WebAuthn-DPxEEb5Y.js} +4 -4
  86. package/src/assets/web-panel/assets/{WorkflowEditor-RoBv4rqk.js → WorkflowEditor-C-fCM8Si.js} +1 -1
  87. package/src/assets/web-panel/assets/{chat-Cw1mE5LS.js → chat-BMu1Pk8B.js} +1 -1
  88. package/src/assets/web-panel/assets/{colors-BFP62Gwf.js → colors-DYPOXyWQ.js} +1 -1
  89. package/src/assets/web-panel/assets/{compact-item-17HL6pyC.js → compact-item-C5r_plPk.js} +1 -1
  90. package/src/assets/web-panel/assets/{createContext-D55X4fZX.js → createContext-9fWrWmuJ.js} +1 -1
  91. package/src/assets/web-panel/assets/devWarning-DmRz5Pet.js +1 -0
  92. package/src/assets/web-panel/assets/{hasIn-D3E5mNsP.js → hasIn-CjZM2-qE.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-KtLJXn4s.js → index-0DVMoDzF.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DzG7mkgW.js → index-B1iUe3Ba.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Da27u6j0.js → index-B56CI20h.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-uSsiwgZ2.js → index-BBVCXmJV.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-tUH_6bdJ.js → index-BPucc_ES.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DD_qGBrt.js → index-BVFtY8Y4.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CjCwi7we.js → index-BW-x3mUK.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-gAVxDiTZ.js → index-B_bTdeou.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CW6LLoJO.js → index-Bglw_kmu.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DkBVYlE4.js → index-BsHmE__1.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BY_xZ2jy.js → index-Bti4lpw5.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-H9_X1Cg_.js → index-ByVDaARk.js} +1 -1
  105. package/src/assets/web-panel/assets/{index--44J50mc.js → index-C3E7xVl1.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CR9rNUvi.js → index-CDaA4A0b.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BgN5G5vF.js → index-CGqrVLWe.js} +27 -27
  108. package/src/assets/web-panel/assets/{index-D4LHSde4.js → index-CJJx0kbR.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Cdvk2_2q.js → index-CTnaRErh.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DCLu84x-.js → index-CYoS2cwK.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-paVubXzn.js → index-CcDGi9U1.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BQmZg5si.js → index-Cd9_KCPs.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-tVRPgYGr.js → index-Co9kBFxY.js} +1 -1
  114. package/src/assets/web-panel/assets/index-CrsL7YBW.js +1 -0
  115. package/src/assets/web-panel/assets/{index-DIRvdwBX.js → index-CvUR6l7C.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Bq83UBDr.js → index-CyUtBxnC.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CvCFKojj.js → index-D0rFX-xN.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Bzpp2z2S.js → index-D6zyUpD6.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BnGpft-Z.js → index-DJk9cPrs.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-ITeEHb8L.js → index-DLCoKst9.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CFYGn88j.js → index-DNxR1CHs.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DOjA8bvj.js → index-DWwI0Jjd.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-RYZgFIwo.js → index-DjTB4wPn.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CLEzsZ8A.js → index-Du-w2i6G.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DtAnPBWP.js → index-HJdfPSMz.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BEa1RW4c.js → index-I3Qdrfcf.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-ASPYTzMK.js → index-Mipa7XgU.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BC6zxOlU.js → index-jO4lIpFE.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CGyTos4p.js → index-oerotzoq.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-C_MfcrLf.js → index-phHPSXlV.js} +1 -1
  131. package/src/assets/web-panel/assets/index-zW69WSDA.js +1 -0
  132. package/src/assets/web-panel/assets/{initDefaultProps-Ckp7xVZS.js → initDefaultProps-B7tpABc_.js} +1 -1
  133. package/src/assets/web-panel/assets/{motion-DUZgCpn6.js → motion-DmvaRoVv.js} +1 -1
  134. package/src/assets/web-panel/assets/{move-B2rttglH.js → move-DF4X29Wf.js} +1 -1
  135. package/src/assets/web-panel/assets/{mtc-parser-BYWcLTuN.js → mtc-parser-C0cbg4PO.js} +1 -1
  136. package/src/assets/web-panel/assets/{omit-DhHqKeFx.js → omit-DZzcYy0l.js} +1 -1
  137. package/src/assets/web-panel/assets/{pickAttrs-ANpJaWMO.js → pickAttrs-DaZWfzuH.js} +1 -1
  138. package/src/assets/web-panel/assets/{placementArrow-CfZWe7CA.js → placementArrow-CBxOEyvn.js} +1 -1
  139. package/src/assets/web-panel/assets/{responsiveObserve-D7Xz2y-R.js → responsiveObserve-CGl8NIlO.js} +1 -1
  140. package/src/assets/web-panel/assets/{slide-DekqCBY9.js → slide-Bv330MSZ.js} +1 -1
  141. package/src/assets/web-panel/assets/{statusUtils-BET6XU7h.js → statusUtils-DJVy5oEM.js} +1 -1
  142. package/src/assets/web-panel/assets/{styleChecker-qHmJjV62.js → styleChecker-BiY1H5ST.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFlexGapSupport-BoMCTNyu.js → useFlexGapSupport-D1sN2OlQ.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFs-TdW-NgFC.js → useFs-DxxHawzW.js} +1 -1
  145. package/src/assets/web-panel/assets/{usePersonalDataHub-Dyox7wCu.js → usePersonalDataHub-C1HblLrD.js} +1 -1
  146. package/src/assets/web-panel/assets/{vnode-XUn5S8CP.js → vnode-Dex0jy4T.js} +1 -1
  147. package/src/assets/web-panel/assets/{zoom-Ls77i8hn.js → zoom-Bk1MScAD.js} +1 -1
  148. package/src/assets/web-panel/index.html +1 -1
  149. package/src/commands/agent.js +8 -1
  150. package/src/commands/eval.js +88 -23
  151. package/src/commands/plugin.js +10 -0
  152. package/src/commands/team.js +26 -3
  153. package/src/data/changelog.json +12 -2
  154. package/src/harness/remote-command-ledger.js +60 -10
  155. package/src/lib/agent-sandbox.js +11 -5
  156. package/src/lib/agent-team/task-lease.js +28 -0
  157. package/src/lib/agent-team/team-runner.js +25 -0
  158. package/src/lib/eval/tasks.js +62 -41
  159. package/src/lib/eval/trend.js +7 -1
  160. package/src/lib/lsp/__tests__/lsp-client.test.js +12 -6
  161. package/src/lib/lsp/code-intelligence.js +55 -17
  162. package/src/lib/lsp/lsp-client.js +7 -1
  163. package/src/lib/plugin-runtime/install.js +20 -1
  164. package/src/lib/plugin-runtime/policy.js +13 -0
  165. package/src/lib/plugin-runtime/remote-source.js +34 -0
  166. package/src/lib/plugin-runtime/signature.js +79 -22
  167. package/src/lib/plugin-security.js +13 -14
  168. package/src/lib/telemetry/span-recorder.js +17 -6
  169. package/src/repl/agent-repl.js +12 -8
  170. package/src/runtime/__tests__/auto-pin.test.js +27 -4
  171. package/src/runtime/auto-pin.js +19 -0
  172. package/src/runtime/headless-runner.js +23 -5
  173. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bg2FTW6A.js +0 -1
  174. package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +0 -3
  175. package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +0 -1
  176. package/src/assets/web-panel/assets/index-CKBI1U5K.js +0 -1
  177. package/src/assets/web-panel/assets/index-CkLp6DTO.js +0 -1
@@ -1 +1 @@
1
- import{u as d}from"./index-BgN5G5vF.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-CGqrVLWe.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-BgN5G5vF.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-CGqrVLWe.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-BgN5G5vF.js";import{a8 as o,k as g,C as d,F as f,A as p}from"./vendor-BMxUs6UX.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-CGqrVLWe.js";import{a8 as o,k as g,C as d,F as f,A as p}from"./vendor-BMxUs6UX.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-BgN5G5vF.js";import{i as f}from"./motion-DUZgCpn6.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-CGqrVLWe.js";import{i as f}from"./motion-DmvaRoVv.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-BgN5G5vF.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-CGqrVLWe.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="./assets/vendor-BMxUs6UX.js">
13
13
  <link rel="modulepreload" crossorigin href="./assets/icons-BsDmGpcT.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
@@ -187,7 +187,7 @@ export function registerAgentCommand(program) {
187
187
  )
188
188
  .option(
189
189
  "--auto-pin",
190
- "During auto-compaction, pin the original task (first user turn) so it always survives compaction (off by default)",
190
+ "Force-pin the original task (first user turn) through compaction (ON by default; disable with CC_AUTO_PIN=0 or config context.autoPin=false)",
191
191
  )
192
192
  .option(
193
193
  "--max-rewakes <n>",
@@ -347,6 +347,13 @@ export function registerAgentCommand(program) {
347
347
  false,
348
348
  )
349
349
  .action(async (task, options, command) => {
350
+ // CC_API_KEY env fallback for --api-key: lets callers (IDE plugins,
351
+ // scripts) pass the key via the environment instead of argv, where it
352
+ // is visible to every local process (/proc/<pid>/cmdline, Win32_Process).
353
+ // An explicit --api-key still wins.
354
+ if (!options.apiKey && process.env.CC_API_KEY) {
355
+ options.apiKey = process.env.CC_API_KEY;
356
+ }
350
357
  const bypassPermissions = !!(
351
358
  options.allowDangerousBypass ||
352
359
  options.yolo ||
@@ -11,7 +11,7 @@
11
11
  import fs from "fs";
12
12
  import path from "path";
13
13
  import { fileURLToPath } from "url";
14
- import { spawn } from "child_process";
14
+ import { spawn, spawnSync } from "child_process";
15
15
  import { runEvalSuite } from "../lib/eval/runner.js";
16
16
  import { getSuite } from "../lib/eval/tasks.js";
17
17
  import {
@@ -45,6 +45,40 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
45
45
  // This file is src/commands/eval.js → the CLI entry is bin/chainlesschain.js.
46
46
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
47
47
 
48
+ /**
49
+ * Kill an agent child AND its tool grandchildren. A bare child.kill("SIGTERM")
50
+ * only reaches the direct child (and on Windows TerminateProcess never reaches
51
+ * grandchildren), leaving tools alive and still WRITING into the workspace.
52
+ * POSIX children are spawned detached (own process group) so -pid reaps the
53
+ * whole tree; Windows uses taskkill /T /F. Same pattern as the async-hook
54
+ * supervisor's _killChildTree.
55
+ */
56
+ function killAgentTree(child) {
57
+ if (!child || !child.pid) return;
58
+ if (process.platform === "win32") {
59
+ try {
60
+ spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], {
61
+ windowsHide: true,
62
+ timeout: 10000,
63
+ });
64
+ } catch {
65
+ /* fall through to the direct kill below */
66
+ }
67
+ } else {
68
+ try {
69
+ process.kill(-child.pid, "SIGKILL"); // negative pid = process group
70
+ return;
71
+ } catch {
72
+ /* not a group leader / already gone — fall through */
73
+ }
74
+ }
75
+ try {
76
+ child.kill("SIGKILL");
77
+ } catch {
78
+ /* already gone */
79
+ }
80
+ }
81
+
48
82
  /**
49
83
  * Build a runAgent that shells out to a headless `cc agent -p` in the task's
50
84
  * workspace. acceptEdits lets it write files without an interactive prompt.
@@ -52,42 +86,59 @@ const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
52
86
  function makeHeadlessRunAgent(opts = {}) {
53
87
  return function runAgent({ prompt, cwd, timeoutMs }) {
54
88
  return new Promise((resolve) => {
55
- const args = [
56
- BIN,
57
- "agent",
58
- "-p",
59
- prompt,
60
- "--permission-mode",
61
- "acceptEdits",
62
- "--output-format",
63
- "text",
64
- ];
65
- if (opts.model) args.push("--model", opts.model);
66
- if (opts.provider) args.push("--provider", opts.provider);
89
+ let args;
90
+ if (opts._argv) {
91
+ // Test seam: run an arbitrary node argv instead of the real agent, so
92
+ // the timeout/tree-kill path is testable offline.
93
+ args = opts._argv;
94
+ } else {
95
+ args = [
96
+ BIN,
97
+ "agent",
98
+ "-p",
99
+ prompt,
100
+ "--permission-mode",
101
+ "acceptEdits",
102
+ "--output-format",
103
+ "text",
104
+ ];
105
+ if (opts.model) args.push("--model", opts.model);
106
+ if (opts.provider) args.push("--provider", opts.provider);
107
+ }
67
108
  const child = spawn(process.execPath, args, {
68
109
  cwd,
69
110
  env: { ...process.env, CLAUDECODE: "1" },
70
111
  windowsHide: true,
112
+ // Own process group on POSIX so a timeout can reap the whole tree.
113
+ detached: process.platform !== "win32",
71
114
  });
72
115
  let out = "";
73
116
  let err = "";
74
117
  let settled = false;
118
+ let timedOut = false;
119
+ let graceTimer = null;
75
120
  const done = (result) => {
76
121
  if (settled) return;
77
122
  settled = true;
123
+ clearTimeout(graceTimer);
78
124
  resolve(result);
79
125
  };
80
126
  const timer = setTimeout(() => {
81
- try {
82
- child.kill("SIGTERM");
83
- } catch {
84
- /* already gone */
85
- }
86
- done({
87
- ok: false,
88
- output: out,
89
- error: `timed out after ${timeoutMs || 120000}ms`,
90
- });
127
+ // Kill the WHOLE tree, then settle on `close` — resolving immediately
128
+ // would race a still-live agent against the runner's after-snapshot,
129
+ // check() and workspace rmSync (nondeterministic scores + EBUSY leaks).
130
+ timedOut = true;
131
+ killAgentTree(child);
132
+ // Last resort if the process is unkillable and `close` never fires —
133
+ // don't hang the whole suite on one stuck task.
134
+ graceTimer = setTimeout(() => {
135
+ done({
136
+ ok: false,
137
+ output: out,
138
+ error: `timed out after ${timeoutMs || 120000}ms (process did not exit after kill)`,
139
+ });
140
+ }, 10000);
141
+ if (typeof graceTimer.unref === "function") graceTimer.unref();
91
142
  }, timeoutMs || 120000);
92
143
  if (typeof timer.unref === "function") timer.unref();
93
144
  child.stdout?.on("data", (d) => (out += d.toString("utf8")));
@@ -98,12 +149,23 @@ function makeHeadlessRunAgent(opts = {}) {
98
149
  });
99
150
  child.on("close", (code) => {
100
151
  clearTimeout(timer);
152
+ if (timedOut) {
153
+ done({
154
+ ok: false,
155
+ output: out,
156
+ error: `timed out after ${timeoutMs || 120000}ms`,
157
+ });
158
+ return;
159
+ }
101
160
  done({ ok: code === 0, output: out, error: code === 0 ? null : err });
102
161
  });
103
162
  });
104
163
  };
105
164
  }
106
165
 
166
+ // For tests: the timeout/tree-kill path needs a real spawned process.
167
+ export { makeHeadlessRunAgent, killAgentTree };
168
+
107
169
  export function registerEvalCommand(program, { logger } = {}) {
108
170
  const log = logger || console;
109
171
  program
@@ -215,6 +277,9 @@ export function registerEvalCommand(program, { logger } = {}) {
215
277
  appendHistory(options.history, {
216
278
  ranAt: new Date().toISOString(),
217
279
  label: options.label || null,
280
+ // Tagged so --trend can exclude it: a dry-run is always 0% and
281
+ // would otherwise report every passing task as a regression.
282
+ ...(options.dryRun ? { dryRun: true } : {}),
218
283
  passed: summary.passed,
219
284
  total: summary.total,
220
285
  passRate: summary.passRate,
@@ -608,6 +608,10 @@ export function registerPluginCommand(program) {
608
608
  "Plugin name to select from a multi-plugin registry",
609
609
  )
610
610
  .option("--token <token>", "Bearer token for a private registry")
611
+ .option(
612
+ "--allow-insecure-registry",
613
+ "Allow a plain-HTTP registry URL (MITM risk — trusted networks only)",
614
+ )
611
615
  .option("--json", "Output as JSON")
612
616
  .action(async (source, options) => {
613
617
  const { installFromSource } =
@@ -636,6 +640,7 @@ export function registerPluginCommand(program) {
636
640
  name,
637
641
  token: options.token,
638
642
  config,
643
+ allowInsecure: options.allowInsecureRegistry === true,
639
644
  });
640
645
  installSource = resolved.source;
641
646
  integritySha = resolved.sha256;
@@ -694,6 +699,10 @@ export function registerPluginCommand(program) {
694
699
  )
695
700
  .requiredOption("--registry <url>", "Registry/manifest URL to browse")
696
701
  .option("--token <token>", "Bearer token for a private registry")
702
+ .option(
703
+ "--allow-insecure-registry",
704
+ "Allow a plain-HTTP registry URL (MITM risk — trusted networks only)",
705
+ )
697
706
  .option("--json", "Output as JSON")
698
707
  .action(async (query, options) => {
699
708
  const { fetchRegistry, listRegistryPlugins, resolveRegistryToken } =
@@ -712,6 +721,7 @@ export function registerPluginCommand(program) {
712
721
  });
713
722
  const { registry, fromCache } = await fetchRegistry(options.registry, {
714
723
  token,
724
+ allowInsecure: options.allowInsecureRegistry === true,
715
725
  });
716
726
  let rows = listRegistryPlugins(registry);
717
727
  if (query) {
@@ -29,7 +29,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
29
29
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
30
30
 
31
31
  /** Load + validate a task-graph file into a registry (throws on bad input). */
32
- function loadRegistry(file, { ttlMs } = {}) {
32
+ export function loadRegistry(file, { ttlMs } = {}) {
33
33
  const abs = path.resolve(process.cwd(), file);
34
34
  let doc;
35
35
  try {
@@ -41,6 +41,19 @@ function loadRegistry(file, { ttlMs } = {}) {
41
41
  if (!Array.isArray(tasks) || tasks.length === 0) {
42
42
  throw new Error("task file must have a non-empty `tasks` array");
43
43
  }
44
+ // Reject unknown dependency keys up front: a typo'd dependsOn ("biuld") makes
45
+ // a task permanently unclaimable — the run silently exits 1 and `plan` drops
46
+ // it from the waves with no diagnosis.
47
+ const keys = new Set(tasks.map((t) => t.key));
48
+ for (const t of tasks) {
49
+ for (const d of t.dependsOn || t.deps || []) {
50
+ if (!keys.has(d)) {
51
+ throw new Error(
52
+ `task "${t.key}" depends on unknown task "${d}" (typo in dependsOn?)`,
53
+ );
54
+ }
55
+ }
56
+ }
44
57
  const reg = new TaskLeaseRegistry({ defaultTtlMs: ttlMs });
45
58
  for (const t of tasks) {
46
59
  const r = reg.addTask({
@@ -266,7 +279,12 @@ export function registerTeamCommand(program, { logger } = {}) {
266
279
  for (const t of reg.list()) {
267
280
  if (t.lease && t.lease.holder) lostHolders.add(t.lease.holder);
268
281
  }
269
- const freed = reg.reclaimExpired();
282
+ // Reclaim ALL dangling leases, not just expired ones: every holder in
283
+ // the persisted snapshot is from the now-dead prior process, so a lease
284
+ // still inside its TTL (a crash seconds after acquiring) must be
285
+ // reclaimed too — reclaimExpired() would skip it and strand the task,
286
+ // yet we already reported its holder LOST above.
287
+ const freed = reg.reclaimAll();
270
288
  for (const h of lostHolders) {
271
289
  if (options.json)
272
290
  console.log(JSON.stringify({ type: "teammate:lost", holder: h }));
@@ -296,8 +314,12 @@ export function registerTeamCommand(program, { logger } = {}) {
296
314
  const persist = () => {
297
315
  if (!options.state) return;
298
316
  try {
317
+ // Atomic write (tmp + rename): a crash mid-write must not truncate
318
+ // the ONLY resume file — a torn snapshot makes --resume throw and
319
+ // loses all progress.
320
+ const tmp = `${options.state}.tmp`;
299
321
  fs.writeFileSync(
300
- options.state,
322
+ tmp,
301
323
  JSON.stringify(
302
324
  {
303
325
  version: 2,
@@ -311,6 +333,7 @@ export function registerTeamCommand(program, { logger } = {}) {
311
333
  ),
312
334
  "utf8",
313
335
  );
336
+ fs.renameSync(tmp, options.state);
314
337
  } catch (e) {
315
338
  (log.error || console.error)(` state write failed: ${e.message}`);
316
339
  }
@@ -3,11 +3,21 @@
3
3
  "releases": [
4
4
  {
5
5
  "productVersion": "Unreleased",
6
- "cliVersion": "0.162.151",
7
- "cliVersions": ["0.162.150", "0.162.151"],
6
+ "cliVersion": "0.162.152",
7
+ "cliVersions": [
8
+ "0.4.46",
9
+ "0.37.4",
10
+ "0.162.150",
11
+ "0.162.151",
12
+ "0.162.152"
13
+ ],
8
14
  "date": null,
9
15
  "title": "",
10
16
  "sections": [
17
+ {
18
+ "heading": "Fixed — cc CLI 0.162.152:全面体检 13 修复 + auto-pin 默认开 + 远控幂等激活 + 多语言 LSP/内核沙箱 CI 真机验证(CLI-only npm 发版)",
19
+ "body": "> `chainlesschain` 0.162.151 → **0.162.152** 已发 npm `latest`(经 `npm-publish.yml`,`--provenance --access public`)。纯 `packages/cli/src` + `packages/web-panel`(随 `prepublishOnly build:web-panel` 打入包)增量,未触 `pdh/lib` → 无 Android cc bundle rollover / 无 USR_VERSION 改动。发版前本机三层全绿(unit+integration+e2e 23,167 passed / 0 fail)+ 新 `env-blocked-verification.yml` CI 门(真 gopls/rust-analyzer/jdtls 三语言 LSP + 真 bubblewrap 内核隔离,ubuntu)跑通。命令数不变(164)。\n\n- **安全(HIGH)插件签名锁可伪造绕过 `requireSignedPlugins`**:`.plugin-lock.json` 原是可写目录里的自断言 JSON(布尔字段+自选哈希,load 只重哈希不验签;install 还会把源目录自带的伪造 lock 原样拷入;组织没配 `trustedPluginKeySha256` 时 key 检查整个跳过)。改为 lock v2 落真 Ed25519 签名+公钥、load 时**真验签**、trust 指纹从嵌入公钥现算(永不信 lock 字段)、install 无条件剥离源自带 lock、`requireSignedPlugins`+空 key 名单 fail-closed 全拒。3 条 ATTACK 回归测试。\n- **安全:插件远程 registry 拒纯 HTTP**(registry 同时供 source+sha256,MITM 二者全控=完整性检查空转;loopback 豁免、`--allow-insecure-registry`/`CC_PLUGIN_REGISTRY_ALLOW_HTTP=1` 显式 opt-in)+ **fetchGitRepo 拒 `-` 开头 url/ref**(git argv 注入:registry 供的 ref=\"-f\" 在 full-clone retry 路径被 `checkout` 当选项;注意 `checkout -- <ref>` 是错修——`--` 后是 pathspec)。\n- **eval 反作弊三连**:`fix-failing-test`/`fix-build`/`upgrade-dependency` 的 do-not-edit harness 文件从 presence-regex(可被「文本还在但不执行」绕过:前插 `ALL OK`+exit(0)、重写 build.mjs 自定义 banner、run.mjs 干脆零守卫)改为逐字节比对模块常量;4 条作弊回归全在 pre-fix 代码上验 RED。\n- **远控账本双修**:`_perDeviceSeq` 乱序完成回退水位(新 commandId 复用旧 seq 本应拒 stale 实际 applied,真机复现)改 advance-only `Math.max`;`_applied/_order` 随 `cc serve` 无界涨(实测 5 万条 snapshot 14.3MB)加保留窗口(默认 1 万条、分块淘汰、`_baseIndex` 保 applyIndex 全局单调、snapshot 兼容旧格式,实测封顶 4.3MB)。\n- **`cc team` 三修**:runner 层 lease 心跳(内建 shell/agent executor 从不 renew → 超 TTL 长任务被 peer steal **并发双跑**,真时钟回归测试 pre-fix 红);`dependsOn` 拼错 key 现在 load 时报错(原静默 exit 1 + plan 波次悄悄少块);`--state` 快照 tmp+rename 原子写(写中崩溃不再截断唯一 resume 文件)。\n- **eval 基建双修**:超时改整树击杀(POSIX detached 组 / Win `taskkill /T /F`)+ 等 `close` 再 settle(原 kill 后立即 resolve,agent 还活着写文件时就快照/check/删目录);`--dry-run --history` 记录打 `dryRun:true` 且 `--trend` 排除(dry-run 恒 0%,原污染 CI 回归门造成全任务假回归)。\n- **OTLP 合规双修**:`*UnixNano` 时间戳改十进制字符串(ms×1e6≈1.8e18 超 2^53,JSON number 违 proto3 mapping、严格 collector 拒收);traceId 掺进程启动时间+pid(原裸计数器每进程重置 → 连续 run 全是 `0…01` 被 collector 并成一条 trace)。\n- **LSP 双修(多语言 CI 真机验证抓获)**:`normalizeUri` 统一盘符冒号编码(gopls 把 publish URI 重写成裸 `C:/` 而客户端 didOpen 用 `C%3A/`,诊断 Map key 永不相遇 → **Go 诊断恒空**;tsserver/pyright 原样回显故此前未暴露);读查询(def/refs/hover/symbols/diag/rename-preview)对 LSP `-32801 ContentModified` 有界重试(rust-analyzer 索引未稳时高频抛出,语义即「请重试」)。\n- **bwrap 沙箱挂载顺序**:`--tmpfs /tmp` 原在工作区 bind 之后挂载,遮蔽任何位于 /tmp 下的工作区(chdir 直接失败、沙箱不可用);tmpfs 移到 bind 之前(bwrap 顺序挂载、后挂者胜)。\n- **Added:auto-pin 默认开启(产品拍板)**:compaction 现在默认 pin 原始任务(首个 user 轮,token 上限 2000)防长会话跑偏;优先级 `--auto-pin` flag > `CC_AUTO_PIN`(\"1\"/\"0\") > config `context.autoPin` > 默认开;关= `CC_AUTO_PIN=0` 或 config false。\n- **Added:远控客户端发送 commandId/seq,Phase 5 幂等保护端到端激活**:web-panel 直连 `execute` 带顶层 uuid commandId + 抗页面重载单调 seq + per-TAB deviceId,断线后**同 id 重发一次**(服务端 ledger 保至多一次,`replayed` ack 如实上报);web/Android 的 E2EE 控制事件(prompt/approval/interrupt)把 commandId+per-pairing seq 打进加密明文(relay 本身 at-least-once 补投 offline-message——无 id 时补投的 prompt 会多跑一整个 agent turn)。勘误:所谓 Terminal 远程客户端不存在(cli 包内无此进程),客户端发送侧已全覆盖。\n- **Added:`env-blocked-verification.yml` CI 门**:ubuntu 真机跑三语言 LSP live 套(gopls/rust-analyzer/jdtls 各 def/refs/diag,`CC_LSP_LIVE_REQUIRE` 使装失败=红而非静默 skip)+ 真 bubblewrap 内核隔离套(netns 断网证明「无视 proxy env 的工具」也被拦、rootfs 只读、denyRead tmpfs 掩蔽);零 `continue-on-error`。\n- **desktop(不随 npm 包,同批落 main)**:SSO IPC 四 handler 端到端修复(refresh-token 传参形状错+读错 store、logout 把 providerId 当 sessionId 致 provider 侧撤销从未发生、handle-callback 会话 id 不达 renderer、get-sessions 恒空——统一路由到权威 SSOManager store)。"
20
+ },
11
21
  {
12
22
  "heading": "Added — cc CLI `cc changelog`(别名 `cc whatsnew`)命令:npm 包每版更新说明离线可查",
13
23
  "body": "> CLI-only 发版(`chainlesschain` 0.162.150 → **0.162.151**,经 `npm-publish.yml` 发 npm `latest`,`--provenance --access public`)。纯 `packages/cli/src` 增量(新增 `commands/changelog.js` + `lib/changelog.js` 解析器 + `scripts/build-changelog.mjs` 构建器 + 生成的 `src/data/changelog.json`),未触 `pdh/lib` → 无 Android cc bundle rollover / 无 USR_VERSION 改动。命令数 163 → **164**(清单已重生)。新增解析器 + 命令共 39 项单测本机全绿。\n\n- **命令**:`cc changelog` 显示当前版本 + 最近 5 条 CLI 更新(`← installed` 标出装机版);`--all` 全部历史、`<version>` 指定版本(吃 CLI 版本 `0.162.150` 或产品版本 `v5.0.3.134` / 裸 `134`)、`-n/--limit` 控制条数、`--json` 机器可读。数据**离线随包**,无网络依赖、永远和装机版本对齐。\n- **数据源与「只显示 CLI 相关条目」**:唯一权威更新记录是根 `CHANGELOG.md`(按**产品版本** `v5.0.3.x` 组织),解析器把它蒸馏成 **CLI 专属**子集。难点是区分「真·CLI 发版」与「只捎带 bump 了 cli 版本号的 PDH/安卓采集器发版」,三道闸:① CLI npm 在 `0.x` alpha 轨、产品在 `5.x` → 版本 token 只取 `0.x`,天然滤掉 `v5.0.3.x` 误抓;② 大小写敏感的 `CLI` → 真 CLI 标题写大写「CLI/cc CLI」,捎带的 bundle note 写小写「cli 0.162.x」;③ 无 `###` 子标题的块只看 `##` 标题(每块都有 `Version surfaces: CLI 0.x` 样板行,信正文会全放行)。从 112 个产品版本块精准抽出 11 个真 CLI 发版(拼多多采集 / 浏览历史等 PDH 发版正确排除)。\n- **打包**:`build:changelog` 脚本在发版时(挂进 `prepublishOnly`)把 CHANGELOG 解析成 `src/data/changelog.json`(~30KB,CLI 子集),随 `src/` 一起发 npm;in-repo dev 无 JSON 时 `loadChangelog()` 回退直接解析根 CHANGELOG。"
@@ -22,10 +22,21 @@
22
22
  */
23
23
 
24
24
  export class RemoteCommandLedger {
25
- constructor({ now = () => Date.now(), revokedDevices = [] } = {}) {
25
+ constructor({
26
+ now = () => Date.now(),
27
+ revokedDevices = [],
28
+ maxApplied = 10000,
29
+ } = {}) {
26
30
  this._now = typeof now === "function" ? now : () => now;
27
31
  this._applied = new Map(); // commandId → { applyIndex, result, deviceId, ts }
28
- this._order = []; // applyIndex commandId (total order)
32
+ this._order = []; // retained tail; applyIndex of _order[i] = _baseIndex + i
33
+ this._baseIndex = 0; // applyIndex of _order[0] (advances as old entries evict)
34
+ // Retention window: a long-lived `cc serve` would otherwise grow the ledger
35
+ // (and its snapshot) without bound — ~14 MB per 50k commands measured. The
36
+ // window must stay large relative to the reconnect-redelivery horizon: a
37
+ // commandId evicted from the window loses idempotency protection and would
38
+ // re-execute if re-delivered afterwards.
39
+ this._maxApplied = Math.max(1, Number(maxApplied) || 10000);
29
40
  this._revoked = new Set(revokedDevices);
30
41
  this._perDeviceSeq = new Map(); // deviceId → highest accepted seq
31
42
  this._inFlight = new Map(); // commandId → Promise<record> for an in-progress apply
@@ -113,13 +124,22 @@ export class RemoteCommandLedger {
113
124
  // on success and rejects on failure (so a retry can re-run the side effect).
114
125
  const runPromise = (async () => {
115
126
  const result = await execute(command);
116
- const applyIndex = this._order.length;
127
+ const applyIndex = this._baseIndex + this._order.length;
117
128
  const rec = { applyIndex, result, deviceId, ts: this._now() };
118
129
  this._applied.set(commandId, rec);
119
130
  this._order.push(commandId);
120
131
  if (deviceId != null && Number.isFinite(command.seq)) {
121
- this._perDeviceSeq.set(deviceId, command.seq);
132
+ // Advance-only watermark. Two in-flight commands from one device can
133
+ // RECORD out of order (seq 6 settles before seq 5 — both passed the
134
+ // stale check while nothing was recorded); a plain set() would regress
135
+ // the watermark to 5 and let a NEW commandId reuse seq 6.
136
+ const cur = this._perDeviceSeq.get(deviceId);
137
+ this._perDeviceSeq.set(
138
+ deviceId,
139
+ cur == null ? command.seq : Math.max(cur, command.seq),
140
+ );
122
141
  }
142
+ this._evictBeyondWindow();
123
143
  return rec;
124
144
  })();
125
145
  this._inFlight.set(commandId, runPromise);
@@ -140,15 +160,31 @@ export class RemoteCommandLedger {
140
160
  }
141
161
  }
142
162
 
163
+ /** Chunked eviction of the oldest applied entries beyond the window. */
164
+ _evictBeyondWindow() {
165
+ // Amortized: only compact once we're 50% past the cap, then cut back to
166
+ // exactly the cap — avoids an O(n) splice on every insert at steady state.
167
+ if (this._order.length <= this._maxApplied * 1.5) return;
168
+ const excess = this._order.length - this._maxApplied;
169
+ const evicted = this._order.splice(0, excess);
170
+ for (const id of evicted) this._applied.delete(id);
171
+ this._baseIndex += excess;
172
+ }
173
+
143
174
  /**
144
175
  * The ordered tail of applied commands after `cursor` (an applyIndex), so a
145
176
  * reconnecting endpoint can replay missed state in the one agreed order.
177
+ * Entries older than the retention window are gone — a caller can detect the
178
+ * gap by comparing the first element's applyIndex against its cursor+1 (see
179
+ * `oldestRetainedIndex()`), and should then resync full state instead.
146
180
  * @returns {Array<{applyIndex, commandId, result, deviceId}>}
147
181
  */
148
182
  appliedSince(cursor = -1) {
149
183
  const out = [];
150
- for (let i = cursor + 1; i < this._order.length; i++) {
151
- const commandId = this._order[i];
184
+ const start = Math.max(cursor + 1, this._baseIndex);
185
+ const end = this._baseIndex + this._order.length;
186
+ for (let i = start; i < end; i++) {
187
+ const commandId = this._order[i - this._baseIndex];
152
188
  const rec = this._applied.get(commandId);
153
189
  out.push({
154
190
  applyIndex: i,
@@ -160,27 +196,41 @@ export class RemoteCommandLedger {
160
196
  return out;
161
197
  }
162
198
 
199
+ /** Lowest applyIndex still retained (entries below it were evicted). */
200
+ oldestRetainedIndex() {
201
+ return this._baseIndex;
202
+ }
203
+
163
204
  /** Highest assigned applyIndex (−1 when nothing applied). */
164
205
  cursor() {
165
- return this._order.length - 1;
206
+ return this._baseIndex + this._order.length - 1;
166
207
  }
167
208
 
209
+ /** Total commands ever applied (including evicted ones). */
168
210
  appliedCount() {
169
- return this._order.length;
211
+ return this._baseIndex + this._order.length;
170
212
  }
171
213
 
172
214
  snapshot() {
173
215
  return {
174
216
  order: [...this._order],
217
+ baseIndex: this._baseIndex,
218
+ maxApplied: this._maxApplied,
175
219
  applied: Array.from(this._applied.entries()),
176
220
  revoked: Array.from(this._revoked),
177
221
  perDeviceSeq: Array.from(this._perDeviceSeq.entries()),
178
222
  };
179
223
  }
180
224
 
181
- static restore(snap, { now = () => Date.now() } = {}) {
182
- const l = new RemoteCommandLedger({ now });
225
+ static restore(snap, { now = () => Date.now(), maxApplied } = {}) {
226
+ const l = new RemoteCommandLedger({
227
+ now,
228
+ // Restore keeps the snapshot's window unless the caller overrides it;
229
+ // old (pre-window) snapshots fall back to the default.
230
+ maxApplied: maxApplied ?? snap?.maxApplied,
231
+ });
183
232
  l._order = [...(snap?.order || [])];
233
+ l._baseIndex = Number.isFinite(snap?.baseIndex) ? snap.baseIndex : 0;
184
234
  l._applied = new Map(snap?.applied || []);
185
235
  l._revoked = new Set(snap?.revoked || []);
186
236
  l._perDeviceSeq = new Map(snap?.perDeviceSeq || []);
@@ -151,6 +151,12 @@ export function executeSandboxedShell(command, sandbox, options = {}) {
151
151
  }
152
152
 
153
153
  function executeBubblewrapShell(command, sandbox, options, hostCwd, policy) {
154
+ // Mount ORDER matters: bwrap applies mounts sequentially and a later mount
155
+ // shadows an earlier one. `--tmpfs /tmp` must come BEFORE the workspace
156
+ // bind — with the old order (bind first, tmpfs last) any workspace living
157
+ // UNDER /tmp was wiped by the tmpfs overlay and the --chdir failed with
158
+ // "Can't chdir …: No such file or directory" (caught by the live bwrap CI
159
+ // suite, whose temp workspace is exactly such a directory).
154
160
  const args = [
155
161
  "--die-with-parent",
156
162
  "--new-session",
@@ -158,17 +164,17 @@ function executeBubblewrapShell(command, sandbox, options, hostCwd, policy) {
158
164
  "--ro-bind",
159
165
  "/",
160
166
  "/",
161
- "--bind",
162
- hostCwd,
163
- hostCwd,
164
- "--chdir",
165
- hostCwd,
166
167
  "--proc",
167
168
  "/proc",
168
169
  "--dev",
169
170
  "/dev",
170
171
  "--tmpfs",
171
172
  "/tmp",
173
+ "--bind",
174
+ hostCwd,
175
+ hostCwd,
176
+ "--chdir",
177
+ hostCwd,
172
178
  ];
173
179
  if (sandbox.network) args.push("--share-net");
174
180
  for (const target of policy.allowWrite) args.push("--bind", target, target);
@@ -324,6 +324,34 @@ export class TaskLeaseRegistry {
324
324
  return reclaimed;
325
325
  }
326
326
 
327
+ /**
328
+ * Reclaim EVERY task that currently holds a lease back to PENDING, regardless
329
+ * of expiry. Used on RESUME: a persisted snapshot comes from a prior process,
330
+ * so every lease holder is by definition dead. `reclaimExpired` alone would
331
+ * SKIP a lease still inside its TTL window (a crash seconds after acquiring) —
332
+ * that task is then neither claimable (the "valid" lease blocks it) nor
333
+ * reclaimed, so it strands forever and the run can never reach `allDone`.
334
+ * Returns the reclaimed keys.
335
+ */
336
+ reclaimAll() {
337
+ const reclaimed = [];
338
+ for (const t of this._tasks.list()) {
339
+ const lease = t.metadata?.lease || null;
340
+ if (!lease) continue;
341
+ const fresh = this._tasks.get(t.id); // re-read for current rev
342
+ if (
343
+ this._write(fresh, {
344
+ status: TASK_STATUS.PENDING,
345
+ assignee: null,
346
+ metadata: { ...fresh.metadata, lease: null },
347
+ })
348
+ ) {
349
+ reclaimed.push(fresh.metadata?.key);
350
+ }
351
+ }
352
+ return reclaimed;
353
+ }
354
+
327
355
  stats({ now = this._now() } = {}) {
328
356
  const base = this._tasks.stats();
329
357
  let leased = 0;