chainlesschain 0.162.149 → 0.162.150

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 (273) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-CBLvrjeG.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-DYv2GtE0.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-CL6PZ-Ww.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-xuyHt4uA.js} +3 -3
  6. package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-DOvSVycq.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-DMhfTswr.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-CQxDdm63.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-BEeNhK2a.js} +5 -5
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-8nul8eTq.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-CL04O-ER.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-C50o-n7x.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-CH-bDkzs.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-DqAIMvSe.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-C43fo_my.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-BERnMrdP.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-Baw3w1gp.js} +4 -4
  18. package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-BEqAHF1-.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-CvnmKwK4.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-iMPxgVdt.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard--4SJX3YR.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-BgLV6xgz.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-BbFfJ1Xi.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-DeGq1B-q.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-L1PjW-lT.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-PK-X58to.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-BePWEH-d.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-BKkfk9hy.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-BNMqUDla.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-w4WPiyz2.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-DUKMVGNi.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-BWhiEyTJ.js} +1 -1
  37. package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-Ocf5JEkX.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc-D2B6MMhU.js} +4 -4
  39. package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DdYjCq1O.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-Cb1hfuUZ.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-CTeImGp7.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-BjYNc7eQ.js} +4 -4
  43. package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-DVYYIizh.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-Be2Kmr5j.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-Cu_-qRlR.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-DD2HoGzE.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
  49. package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-C9Srcs2M.js} +3 -3
  50. package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-CUqcMgo1.js} +3 -3
  51. package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-HBrQGLXt.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-D-B0vjwh.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-eTeLIu9e.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-DrRqCsC6.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-1G9DNOhI.js +1 -0
  56. package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-RkTZzpxP.js} +1 -1
  57. package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-BSCUgsgC.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-CHgyM3Bz.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-0lry4OZq.js} +1 -1
  60. package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-Cn45UroZ.js} +2 -2
  61. package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-Q-Zjb707.js} +1 -1
  62. package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-BdM70oda.js} +1 -1
  63. package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-DmOAKKap.js} +2 -2
  64. package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-Dwavbm07.js} +1 -1
  65. package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-DukXFCnk.js} +3 -3
  66. package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-BIlRnITu.js} +2 -2
  67. package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-YYVQdhhQ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-B8_iYHz2.js} +1 -1
  69. package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-BdVrhT31.js} +1 -1
  70. package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-CD3ggRx7.js} +1 -1
  71. package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-Bp02VZFH.js} +2 -2
  72. package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-DEVmCEsr.js} +1 -1
  73. package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-B6czWc4N.js} +1 -1
  74. package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-BCJLv17r.js} +1 -1
  75. package/src/assets/web-panel/assets/{Terminal-ZzU0Io1Y.js → Terminal-CD132d2Y.js} +2 -2
  76. package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-BnSY0S-s.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-VZw9Oy2w.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-pZq7Hjd2.js} +1 -1
  80. package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DnQaqk4q.js} +1 -1
  81. package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-BEUfmvJV.js} +1 -1
  82. package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-CoZKMXJ2.js} +4 -4
  83. package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-CBOGVx1I.js} +5 -5
  84. package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-huSKn7TT.js} +1 -1
  85. package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-A_3w6FBO.js} +1 -1
  86. package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-D1Bem9Oy.js} +1 -1
  87. package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-CJYJj0oO.js} +1 -1
  88. package/src/assets/web-panel/assets/{createContext-vlR43pHn.js → createContext-BkbFiKT4.js} +1 -1
  89. package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
  90. package/src/assets/web-panel/assets/{hasIn-D04tHYFd.js → hasIn-CKvUafVY.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-AjrSPnvv.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-B8i0lViZ.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-B9Svn0zc.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-BHdHSX06.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-BHdailyo.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-BJwlEnYo.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-BOoAQjJz.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BSgWxAOG.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-BdutMsne.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-BiDWxzbn.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-By5a0T_W.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-C-WIY-FQ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-C37f6iey.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-C9bWmTcO.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-CBaosWRO.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CBlBVJ_m.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-CD62EEGo.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CUj-l7GM.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index-CVS8Ymuq.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-ChkXUj3f.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D65_XseV.js → index-Cj0OZ-37.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-Co3OFL0t.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-430S68MN.js → index-Crp8CbRg.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-D22zNXiS.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-DTs_D1OL.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-DfgCdFrN.js} +3 -3
  117. package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-DjYrecNb.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-DpW9cf3e.js} +1 -1
  119. package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
  120. package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-F--HuPG1.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-Fuk6t_3K.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-JEAGMii9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DYAtmqiv.js → index-PF-mpv8K.js} +1 -1
  124. package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
  125. package/src/assets/web-panel/assets/{index-DTWg-18U.js → index-b-sbVdjQ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-pyvMVX8r.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-qNTtOVi_.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-tgO8iza6.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-ttDQVhZy.js} +1 -1
  130. package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-DtrnfsZH.js} +1 -1
  131. package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-D4zqSaX3.js} +1 -1
  132. package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-CGFGOUQj.js} +1 -1
  133. package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-DH2HvkJl.js} +1 -1
  134. package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-jJ2at5HX.js} +1 -1
  135. package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-CRyMT1Fv.js} +1 -1
  136. package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-DZ_CX0Pt.js} +1 -1
  137. package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-wruHk-h5.js} +1 -1
  138. package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-BGgx8q67.js} +1 -1
  139. package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-Do5M7gKm.js} +1 -1
  140. package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-CRa-GZpX.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-v5O2ZcJm.js} +1 -1
  143. package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub--z2FU0Px.js} +1 -1
  144. package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-1emidVKd.js} +1 -1
  145. package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-CcJaRyHs.js} +1 -1
  146. package/src/assets/web-panel/index.html +1 -1
  147. package/src/commands/a2a.js +19 -4
  148. package/src/commands/activitypub.js +20 -3
  149. package/src/commands/agent.js +27 -5
  150. package/src/commands/audit.js +40 -24
  151. package/src/commands/codeintel.js +68 -0
  152. package/src/commands/collab.js +15 -2
  153. package/src/commands/compliance.js +5 -0
  154. package/src/commands/config.js +4 -1
  155. package/src/commands/dao.js +86 -14
  156. package/src/commands/dev.js +2 -0
  157. package/src/commands/did.js +7 -1
  158. package/src/commands/dlp.js +23 -1
  159. package/src/commands/economy.js +29 -3
  160. package/src/commands/eval.js +7 -0
  161. package/src/commands/evomap.js +26 -0
  162. package/src/commands/governance.js +17 -3
  163. package/src/commands/hardening.js +18 -0
  164. package/src/commands/incentive.js +5 -0
  165. package/src/commands/init.js +46 -2
  166. package/src/commands/kg.js +4 -0
  167. package/src/commands/loop.js +6 -1
  168. package/src/commands/lowcode.js +15 -2
  169. package/src/commands/marketplace.js +40 -6
  170. package/src/commands/matrix.js +20 -1
  171. package/src/commands/memory.js +4 -1
  172. package/src/commands/mtc.js +7 -1
  173. package/src/commands/nostr.js +31 -4
  174. package/src/commands/note.js +7 -4
  175. package/src/commands/plugin.js +125 -5
  176. package/src/commands/pqc.js +5 -0
  177. package/src/commands/reputation.js +10 -1
  178. package/src/commands/scim.js +6 -0
  179. package/src/commands/session.js +32 -10
  180. package/src/commands/siem.js +11 -0
  181. package/src/commands/sla.js +18 -3
  182. package/src/commands/social.js +38 -5
  183. package/src/commands/sso.js +10 -2
  184. package/src/commands/stress.js +23 -4
  185. package/src/commands/team.js +9 -2
  186. package/src/commands/tech.js +2 -0
  187. package/src/commands/tenant.js +10 -1
  188. package/src/commands/terraform.js +6 -0
  189. package/src/commands/update.js +1 -1
  190. package/src/commands/zkp.js +20 -0
  191. package/src/gateways/ws/message-dispatcher.js +5 -2
  192. package/src/gateways/ws/remote-session-protocol.js +103 -42
  193. package/src/harness/jsonl-session-store.js +12 -5
  194. package/src/harness/plugin-manager.js +16 -4
  195. package/src/harness/remote-command-ledger.js +46 -15
  196. package/src/harness/worktree-isolator.js +16 -6
  197. package/src/lib/__tests__/logger.test.js +5 -2
  198. package/src/lib/a2a-protocol.js +25 -1
  199. package/src/lib/activitypub-bridge.js +61 -0
  200. package/src/lib/agent-core.js +2 -0
  201. package/src/lib/agent-economy.js +262 -29
  202. package/src/lib/agent-network.js +7 -1
  203. package/src/lib/agent-team/team-runner.js +25 -9
  204. package/src/lib/agent-team/team-worktree.js +36 -4
  205. package/src/lib/async-hook-supervisor.cjs +102 -16
  206. package/src/lib/audit-logger.js +7 -6
  207. package/src/lib/autonomous-developer.js +60 -0
  208. package/src/lib/chat-core.js +17 -4
  209. package/src/lib/collaboration-governance.js +56 -0
  210. package/src/lib/community-governance.js +68 -0
  211. package/src/lib/compliance-manager.js +63 -0
  212. package/src/lib/cross-chain.js +5 -0
  213. package/src/lib/dao-governance.js +151 -2
  214. package/src/lib/did-manager.js +23 -10
  215. package/src/lib/dlp-engine.js +70 -0
  216. package/src/lib/eval/runner.js +89 -1
  217. package/src/lib/eval/tasks.js +170 -0
  218. package/src/lib/eval/trend.js +16 -1
  219. package/src/lib/evolution-system.js +92 -0
  220. package/src/lib/evomap-federation.js +55 -0
  221. package/src/lib/evomap-governance.js +94 -0
  222. package/src/lib/fatal-handler.js +17 -1
  223. package/src/lib/hardening-manager.js +73 -0
  224. package/src/lib/hierarchical-memory.js +14 -8
  225. package/src/lib/knowledge-exporter.js +8 -2
  226. package/src/lib/knowledge-graph.js +79 -0
  227. package/src/lib/llm-providers.js +23 -14
  228. package/src/lib/logger.js +4 -1
  229. package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
  230. package/src/lib/lsp/__tests__/lsp-client.test.js +11 -0
  231. package/src/lib/lsp/__tests__/lsp-manager.test.js +69 -0
  232. package/src/lib/lsp/benchmark.js +257 -0
  233. package/src/lib/lsp/lsp-client.js +30 -9
  234. package/src/lib/lsp/lsp-manager.js +54 -2
  235. package/src/lib/matrix-bridge.js +84 -0
  236. package/src/lib/memory-manager.js +5 -3
  237. package/src/lib/nostr-bridge.js +53 -0
  238. package/src/lib/permission-engine.js +22 -4
  239. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
  240. package/src/lib/plugin-runtime/install.js +9 -1
  241. package/src/lib/plugin-runtime/policy.js +9 -1
  242. package/src/lib/plugin-runtime/remote-source.js +240 -0
  243. package/src/lib/pqc-manager.js +64 -0
  244. package/src/lib/reputation-optimizer.js +101 -0
  245. package/src/lib/sandbox-egress-proxy.js +159 -59
  246. package/src/lib/sandbox-fs-policy.js +112 -0
  247. package/src/lib/sandbox-network-policy.js +18 -1
  248. package/src/lib/sandbox-v2.js +14 -14
  249. package/src/lib/scim-manager.js +36 -0
  250. package/src/lib/session-manager.js +5 -2
  251. package/src/lib/settings-hooks.cjs +1 -0
  252. package/src/lib/siem-exporter.js +45 -0
  253. package/src/lib/skill-loader.js +20 -2
  254. package/src/lib/skill-marketplace.js +83 -0
  255. package/src/lib/sla-manager.js +88 -0
  256. package/src/lib/social-manager.js +74 -0
  257. package/src/lib/stress-tester.js +65 -0
  258. package/src/lib/tech-learning-engine.js +75 -0
  259. package/src/lib/tenant-saas.js +107 -0
  260. package/src/lib/terraform-manager.js +67 -0
  261. package/src/lib/token-incentive.js +180 -29
  262. package/src/lib/wallet-manager.js +81 -35
  263. package/src/lib/zkp-engine.js +87 -0
  264. package/src/repl/agent-repl.js +17 -2
  265. package/src/runtime/__tests__/auto-pin.test.js +104 -0
  266. package/src/runtime/agent-core.js +241 -68
  267. package/src/runtime/auto-pin.js +117 -0
  268. package/src/runtime/headless-runner.js +35 -0
  269. package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +0 -1
  270. package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +0 -1
  271. package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +0 -1
  272. package/src/assets/web-panel/assets/index-Cg2ldRfU.js +0 -1
  273. package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +0 -1
@@ -651,6 +651,11 @@ const BASE_FEE = {
651
651
  export function estimateFee({ fromChain, toChain, amount }) {
652
652
  if (!_validateChain(fromChain) || !_validateChain(toChain))
653
653
  return { fee: null, reason: "unsupported_chain" };
654
+ // `cc crosschain estimate-fee` passes parseFloat(amount); a non-numeric arg
655
+ // yields NaN. Without this guard percentageFee/totalFee become NaN, the
656
+ // command's `fee === null` check misses it, and it prints "$NaN USD".
657
+ if (!Number.isFinite(amount) || amount <= 0)
658
+ return { fee: null, reason: "invalid_amount" };
654
659
 
655
660
  const baseFee = (BASE_FEE[fromChain] || 1.0) + (BASE_FEE[toChain] || 1.0);
656
661
  const percentageFee = amount * (DEFAULT_CONFIG.feePercentage / 100);
@@ -112,6 +112,153 @@ export function ensureDAOv2Tables(db) {
112
112
  `);
113
113
  }
114
114
 
115
+ /**
116
+ * Hydrate the in-memory stores from the DB. The CLI is one-shot: _proposals/
117
+ * _votes/_delegations/_treasury/_delegationsV2/_treasuryTxs all start empty each
118
+ * process. Every write dual-writes (Map/obj + INSERT) but every read/mutate is
119
+ * Map-only and nothing SELECTed the tables back — so the ENTIRE dao feature was
120
+ * broken across invocations: vote/execute/allocate threw "not found", stats
121
+ * reported 0, and the treasury deposit was invisible (allocate always
122
+ * "Insufficient"). Call after ensureDAOv2Tables(db).
123
+ *
124
+ * Faithful: proposals' votesFor/votesAgainst/status, votes, legacy delegations,
125
+ * and the treasury balance (DERIVED = Σdeposit − Σallocation, replayed in
126
+ * chronological order so each tx's balanceAfter is reconstructed too).
127
+ *
128
+ * Lossy (defaulted to stay correct/safe — these columns don't exist in the
129
+ * schema): V2 proposal abstain/quadratic-weight tallies → 0; proposal.queueEnd →
130
+ * a far-future sentinel so executeProposalV2 FAILS CLOSED (a null/undefined
131
+ * would make its timelock check `now < NaN` and BYPASS the timelock); V2
132
+ * delegation status/expiresAt → ACTIVE/none (revocation is not persisted).
133
+ */
134
+ const _REHYDRATE_QUEUE_END_SENTINEL = "9999-12-31T23:59:59.999Z";
135
+
136
+ export function loadFromDb(db) {
137
+ if (!db) return 0;
138
+ ensureDAOv2Tables(db);
139
+ _proposals.clear();
140
+ _votes.clear();
141
+ _delegations.clear();
142
+ _delegationsV2.clear();
143
+ _treasuryTxs.length = 0;
144
+ _treasury.balance = 0;
145
+ _treasury.allocations = [];
146
+
147
+ for (const r of db
148
+ .prepare(
149
+ `SELECT id, title, description, proposer, status, votes_for, votes_against, voting_type, created_at, ends_at, executed_at
150
+ FROM dao_v2_proposals`,
151
+ )
152
+ .all()) {
153
+ _proposals.set(r.id, {
154
+ id: r.id,
155
+ title: r.title,
156
+ description: r.description || "",
157
+ proposer: r.proposer,
158
+ proposerDid: r.proposer, // V2 field mirrors legacy proposer
159
+ type: "standard",
160
+ status: r.status,
161
+ votesFor: Number(r.votes_for) || 0,
162
+ votesAgainst: Number(r.votes_against) || 0,
163
+ votingType: r.voting_type,
164
+ createdAt: r.created_at,
165
+ updatedAt: r.created_at,
166
+ endsAt: r.ends_at,
167
+ executedAt: r.executed_at,
168
+ // Non-persisted V2 fields — default to stay NaN-safe (see fn doc).
169
+ votesAbstain: 0,
170
+ quadraticWeightFor: 0,
171
+ quadraticWeightAgainst: 0,
172
+ quorumReached: false,
173
+ votingStart: null,
174
+ votingEnd: null,
175
+ cancelledAt: null,
176
+ // Fail-closed: a rehydrated QUEUED proposal cannot be executed until it is
177
+ // re-queued (real queueEnd is not persisted). Never bypass the timelock.
178
+ queueEnd: _REHYDRATE_QUEUE_END_SENTINEL,
179
+ });
180
+ }
181
+
182
+ for (const r of db
183
+ .prepare(
184
+ `SELECT id, proposal_id, voter, weight, direction, delegated_from, created_at
185
+ FROM dao_v2_votes`,
186
+ )
187
+ .all()) {
188
+ _votes.set(r.id, {
189
+ id: r.id,
190
+ proposalId: r.proposal_id,
191
+ voter: r.voter,
192
+ voterDid: r.voter, // both read paths (stats uses voter, anti-sybil voterDid)
193
+ weight: Number(r.weight) || 0,
194
+ voteCount: Number(r.weight) || 0,
195
+ direction: r.direction,
196
+ voteType: r.direction,
197
+ delegatedFrom: r.delegated_from,
198
+ createdAt: r.created_at,
199
+ });
200
+ }
201
+
202
+ for (const r of db
203
+ .prepare(
204
+ `SELECT delegator, delegate, weight, created_at FROM dao_v2_delegations`,
205
+ )
206
+ .all()) {
207
+ _delegations.set(r.delegator, {
208
+ delegator: r.delegator,
209
+ delegate: r.delegate,
210
+ weight: Number(r.weight) || 0,
211
+ });
212
+ // Synthesize a V2 record (status/expiresAt are not persisted → default).
213
+ _delegationsV2.set(`deleg:${r.delegator}`, {
214
+ id: `deleg:${r.delegator}`,
215
+ fromDid: r.delegator,
216
+ toDid: r.delegate,
217
+ weight: Number(r.weight) || 0,
218
+ status: DELEGATION_STATUS.ACTIVE,
219
+ expiresAt: null,
220
+ revokedAt: null,
221
+ createdAt: r.created_at,
222
+ });
223
+ }
224
+
225
+ // Treasury: no balance column — derive it by replaying the tx log in
226
+ // chronological order (deposit +, allocation −), reconstructing balanceAfter.
227
+ const treasuryRows = db
228
+ .prepare(
229
+ `SELECT id, type, amount, description, proposal_id, created_at
230
+ FROM dao_v2_treasury ORDER BY created_at ASC`,
231
+ )
232
+ .all();
233
+ for (const r of treasuryRows) {
234
+ const amt = Number(r.amount) || 0;
235
+ if (r.type === TREASURY_TX_TYPE.DEPOSIT) _treasury.balance += amt;
236
+ else if (r.type === TREASURY_TX_TYPE.ALLOCATION) _treasury.balance -= amt;
237
+ _treasuryTxs.push({
238
+ id: r.id,
239
+ txType: r.type,
240
+ proposalId: r.proposal_id,
241
+ amount: amt,
242
+ memo: r.description || "",
243
+ balanceAfter: _treasury.balance,
244
+ createdAt: r.created_at,
245
+ });
246
+ if (r.type === TREASURY_TX_TYPE.ALLOCATION) {
247
+ _treasury.allocations.push({
248
+ id: r.id,
249
+ proposalId: r.proposal_id,
250
+ amount: amt,
251
+ description: r.description || "",
252
+ date: r.created_at,
253
+ });
254
+ }
255
+ }
256
+
257
+ return (
258
+ _proposals.size + _votes.size + _delegations.size + _treasuryTxs.length
259
+ );
260
+ }
261
+
115
262
  /* ── Proposals ─────────────────────────────────────────────── */
116
263
 
117
264
  export function propose(db, title, description, proposer, options = {}) {
@@ -259,7 +406,8 @@ export function getTreasury() {
259
406
 
260
407
  export function allocate(db, proposalId, amount, description) {
261
408
  if (!proposalId) throw new Error("Proposal ID is required");
262
- if (amount <= 0) throw new Error("Amount must be positive");
409
+ if (!Number.isFinite(amount) || amount <= 0)
410
+ throw new Error("Amount must be positive");
263
411
  if (_treasury.balance < amount) {
264
412
  throw new Error("Insufficient treasury balance");
265
413
  }
@@ -287,7 +435,8 @@ export function allocate(db, proposalId, amount, description) {
287
435
  }
288
436
 
289
437
  export function depositToTreasury(db, amount, description) {
290
- if (amount <= 0) throw new Error("Amount must be positive");
438
+ if (!Number.isFinite(amount) || amount <= 0)
439
+ throw new Error("Amount must be positive");
291
440
 
292
441
  const id = `dep-${Date.now()}-${crypto.randomBytes(4).toString("hex")}`;
293
442
  const now = new Date().toISOString();
@@ -163,16 +163,29 @@ export function setDefaultIdentity(db, did) {
163
163
  const identity = getIdentity(db, did);
164
164
  if (!identity) return false;
165
165
 
166
- // Clear the current default(s). Match on is_default rather than `did LIKE '%'`
167
- // so there's no wildcard pattern here that a reader/scanner could mistake for
168
- // LIKE-injection — the target below is set via exact `did = ?` regardless.
169
- db.prepare(
170
- "UPDATE did_identities SET is_default = 0 WHERE is_default = 1",
171
- ).run();
172
- db.prepare("UPDATE did_identities SET is_default = ? WHERE did = ?").run(
173
- 1,
174
- identity.did,
175
- );
166
+ // Clear the current default(s) then set the new one atomically. Match on
167
+ // is_default rather than `did LIKE '%'` so there's no wildcard pattern here
168
+ // that a reader/scanner could mistake for LIKE-injection — the target below
169
+ // is set via exact `did = ?` regardless.
170
+ //
171
+ // The two UPDATEs must both land: without a transaction, a failure on the
172
+ // second leaves EVERY identity non-default (the default DID silently
173
+ // disappears until manually re-set), breaking the exactly-one-default
174
+ // invariant.
175
+ const applyWrites = () => {
176
+ db.prepare(
177
+ "UPDATE did_identities SET is_default = 0 WHERE is_default = 1",
178
+ ).run();
179
+ db.prepare("UPDATE did_identities SET is_default = ? WHERE did = ?").run(
180
+ 1,
181
+ identity.did,
182
+ );
183
+ };
184
+ if (db && typeof db.transaction === "function") {
185
+ db.transaction(applyWrites)();
186
+ } else {
187
+ applyWrites();
188
+ }
176
189
  return true;
177
190
  }
178
191
 
@@ -325,6 +325,76 @@ export function _resetState() {
325
325
  _v2IncidentMeta.clear();
326
326
  }
327
327
 
328
+ /**
329
+ * Rehydrate the in-memory _policies/_incidents Maps from the persisted dlp_*
330
+ * tables. The CLI runs each `cc dlp` subcommand in a fresh node process, so both
331
+ * Maps start empty every invocation. createPolicy/scanContent dual-write (Map +
332
+ * INSERT into dlp_policies/dlp_incidents) but every read (listDLPPolicies/
333
+ * listIncidents/getDLPStats + the scanContent enforcement loop over _policies)
334
+ * is Map-only and nothing SELECTed the tables back.
335
+ *
336
+ * SECURITY IMPACT: `cc dlp scan` iterates an empty _policies → matches nothing →
337
+ * returns allowed:true, so a BLOCK policy created in a prior invocation silently
338
+ * never enforces. Persisted policies were also un-listable and un-deletable
339
+ * (`policy delete`/`resolve` threw "not found"). Call after ensureDLPTables(db).
340
+ */
341
+ export function loadFromDb(db) {
342
+ if (!db) return 0;
343
+ ensureDLPTables(db);
344
+ _policies.clear();
345
+ _incidents.clear();
346
+
347
+ const parse = (v, fallback) => {
348
+ try {
349
+ return v ? JSON.parse(v) : fallback;
350
+ } catch {
351
+ return fallback;
352
+ }
353
+ };
354
+
355
+ for (const r of db
356
+ .prepare(
357
+ `SELECT id, name, patterns, keywords, action, severity, enabled, created_at
358
+ FROM dlp_policies ORDER BY created_at ASC`,
359
+ )
360
+ .all()) {
361
+ _policies.set(r.id, {
362
+ id: r.id,
363
+ name: r.name,
364
+ patterns: parse(r.patterns, []),
365
+ keywords: parse(r.keywords, []),
366
+ action: r.action,
367
+ severity: r.severity,
368
+ enabled: !!r.enabled,
369
+ createdAt: r.created_at,
370
+ });
371
+ }
372
+
373
+ for (const r of db
374
+ .prepare(
375
+ `SELECT id, policy_id, channel, action_taken, content_hash, matched_patterns,
376
+ severity, user_id, created_at, resolved_at, resolution
377
+ FROM dlp_incidents ORDER BY created_at ASC`,
378
+ )
379
+ .all()) {
380
+ _incidents.set(r.id, {
381
+ id: r.id,
382
+ policyId: r.policy_id,
383
+ channel: r.channel,
384
+ actionTaken: r.action_taken,
385
+ contentHash: r.content_hash,
386
+ matchedPatterns: parse(r.matched_patterns, []),
387
+ severity: r.severity,
388
+ userId: r.user_id,
389
+ createdAt: r.created_at,
390
+ resolvedAt: r.resolved_at ?? null,
391
+ resolution: r.resolution ?? null,
392
+ });
393
+ }
394
+
395
+ return _policies.size + _incidents.size;
396
+ }
397
+
328
398
  // ═══════════════════════════════════════════════════════════════
329
399
  // V2 Canonical Surface (Phase 50)
330
400
  // ═══════════════════════════════════════════════════════════════
@@ -18,6 +18,7 @@
18
18
  import fs from "fs";
19
19
  import os from "os";
20
20
  import path from "path";
21
+ import crypto from "crypto";
21
22
 
22
23
  export const _deps = {
23
24
  mkdtempSync: fs.mkdtempSync,
@@ -25,6 +26,55 @@ export const _deps = {
25
26
  now: () => Date.now(),
26
27
  };
27
28
 
29
+ /**
30
+ * Content-hash every file under `dir` → Map<relPath (forward-slash), sha1>. Used
31
+ * to measure edit locality: snapshot after setup (the baseline the agent starts
32
+ * from) vs after the agent runs, so we can see EXACTLY which files it touched.
33
+ */
34
+ function snapshotWorkspace(dir) {
35
+ const out = new Map();
36
+ const walk = (cur) => {
37
+ let entries;
38
+ try {
39
+ entries = fs.readdirSync(cur, { withFileTypes: true });
40
+ } catch {
41
+ return;
42
+ }
43
+ for (const e of entries) {
44
+ const full = path.join(cur, e.name);
45
+ if (e.isDirectory()) {
46
+ walk(full);
47
+ } else if (e.isFile()) {
48
+ const rel = path.relative(dir, full).split(path.sep).join("/");
49
+ let hash;
50
+ try {
51
+ hash = crypto
52
+ .createHash("sha1")
53
+ .update(fs.readFileSync(full))
54
+ .digest("hex");
55
+ } catch {
56
+ hash = "?"; // unreadable → treat as its own value (still "changed" if it flips)
57
+ }
58
+ out.set(rel, hash);
59
+ }
60
+ }
61
+ };
62
+ walk(dir);
63
+ return out;
64
+ }
65
+
66
+ /** Relative paths that were created, modified, or deleted between two snapshots. */
67
+ function diffSnapshots(before, after) {
68
+ const changed = new Set();
69
+ for (const [p, h] of after) {
70
+ if (!before.has(p) || before.get(p) !== h) changed.add(p); // created / modified
71
+ }
72
+ for (const p of before.keys()) {
73
+ if (!after.has(p)) changed.add(p); // deleted
74
+ }
75
+ return [...changed].sort();
76
+ }
77
+
28
78
  /**
29
79
  * Run a suite of eval tasks and score them.
30
80
  *
@@ -77,6 +127,9 @@ export async function runEvalSuite(tasks, opts = {}) {
77
127
  if (typeof task.setup === "function") {
78
128
  await task.setup(dir);
79
129
  }
130
+ // Baseline AFTER setup, BEFORE the agent — so the diff is exactly the
131
+ // agent's edits (not the task's starting files).
132
+ const before = snapshotWorkspace(dir);
80
133
  let agentResult;
81
134
  try {
82
135
  agentResult = await runAgent({
@@ -90,6 +143,20 @@ export async function runEvalSuite(tasks, opts = {}) {
90
143
  rec.error = `agent error: ${agentErr.message}`;
91
144
  }
92
145
  rec.agentOk = agentResult ? agentResult.ok !== false : false;
146
+ // Edit locality — snapshot NOW, before check() (some checks write to the
147
+ // workspace themselves). `unrelatedChanges` = files touched outside the
148
+ // task's declared legitimate surface; null when the task doesn't declare
149
+ // `expectedFiles` (→ excluded from the suite's 无关改动率).
150
+ const changed = diffSnapshots(before, snapshotWorkspace(dir));
151
+ rec.changedFiles = changed;
152
+ if (Array.isArray(task.expectedFiles)) {
153
+ const expected = new Set(
154
+ task.expectedFiles.map((p) => String(p).split(path.sep).join("/")),
155
+ );
156
+ rec.unrelatedChanges = changed.filter((p) => !expected.has(p));
157
+ } else {
158
+ rec.unrelatedChanges = null; // not measured
159
+ }
93
160
  const verdict = await task.check(dir, agentResult);
94
161
  rec.pass = verdict?.pass === true;
95
162
  rec.detail = verdict?.detail || "";
@@ -136,12 +203,23 @@ export async function runEvalSuite(tasks, opts = {}) {
136
203
 
137
204
  const passed = results.filter((r) => r.pass).length;
138
205
  const total = results.length;
206
+ // 无关改动率: over tasks that declared expectedFiles, the fraction that
207
+ // touched at least one file outside their legitimate surface. An agent that
208
+ // solves a task but also scribbles on unrelated files scores lower quality.
209
+ const measured = results.filter((r) => Array.isArray(r.unrelatedChanges));
210
+ const tasksWithUnrelatedChanges = measured.filter(
211
+ (r) => r.unrelatedChanges.length > 0,
212
+ ).length;
139
213
  return {
140
214
  results,
141
215
  passed,
142
216
  failed: total - passed,
143
217
  total,
144
218
  passRate: total > 0 ? passed / total : 0,
219
+ tasksWithUnrelatedChanges,
220
+ unrelatedChangeRate: measured.length
221
+ ? tasksWithUnrelatedChanges / measured.length
222
+ : 0,
145
223
  ms: _deps.now() - suiteStart,
146
224
  ...(recorder ? { telemetry: recorder.summary() } : {}),
147
225
  };
@@ -154,10 +232,20 @@ export function formatEvalReport(summary) {
154
232
  lines.push(
155
233
  `Eval: ${summary.passed}/${summary.total} passed (${pct}%) in ${summary.ms}ms`,
156
234
  );
235
+ if (typeof summary.unrelatedChangeRate === "number") {
236
+ const upct = (summary.unrelatedChangeRate * 100).toFixed(1);
237
+ lines.push(
238
+ `Unrelated-change rate: ${upct}% (${summary.tasksWithUnrelatedChanges} task(s) edited files outside their expected surface)`,
239
+ );
240
+ }
157
241
  for (const r of summary.results) {
158
242
  const mark = r.pass ? "✔" : "✗";
159
243
  const detail = r.error ? ` — ${r.error}` : r.detail ? ` — ${r.detail}` : "";
160
- lines.push(` ${mark} ${r.id} (${r.ms}ms)${detail}`);
244
+ const stray =
245
+ Array.isArray(r.unrelatedChanges) && r.unrelatedChanges.length
246
+ ? ` [+${r.unrelatedChanges.length} unrelated: ${r.unrelatedChanges.join(", ")}]`
247
+ : "";
248
+ lines.push(` ${mark} ${r.id} (${r.ms}ms)${detail}${stray}`);
161
249
  }
162
250
  return lines.join("\n");
163
251
  }
@@ -21,9 +21,19 @@ function read(dir, rel) {
21
21
  }
22
22
  }
23
23
 
24
+ // The `stringutil` "dependency" at v2, used by BOTH the upgrade-dependency
25
+ // setup and its check so the task can verify the vendored dependency file was
26
+ // not edited (the agent must adapt the caller, not touch the dependency).
27
+ const STRINGUTIL_V2 =
28
+ "export function toTitle(s) {\n" +
29
+ " const str = String(s);\n" +
30
+ " return str.charAt(0).toUpperCase() + str.slice(1);\n" +
31
+ "}\n";
32
+
24
33
  export const BUILTIN_TASKS = [
25
34
  {
26
35
  id: "create-file",
36
+ expectedFiles: ["greeting.txt"],
27
37
  description: "Create a new file with exact content",
28
38
  prompt:
29
39
  'Create a file named greeting.txt containing exactly the text "Hello, ChainlessChain!" (no trailing newline).',
@@ -40,6 +50,7 @@ export const BUILTIN_TASKS = [
40
50
  },
41
51
  {
42
52
  id: "fix-syntax-error",
53
+ expectedFiles: ["bug.js"],
43
54
  description: "Fix a syntax error so the script runs",
44
55
  prompt:
45
56
  "The file bug.js has a syntax error. Fix it so that running `node bug.js` prints exactly OK.",
@@ -71,6 +82,7 @@ export const BUILTIN_TASKS = [
71
82
  },
72
83
  {
73
84
  id: "add-function",
85
+ expectedFiles: ["math.js"],
74
86
  description: "Add a function to an existing module",
75
87
  prompt:
76
88
  "In math.js, add a named export `add(a, b)` that returns a + b. Keep the existing `mul` export.",
@@ -105,6 +117,7 @@ export const BUILTIN_TASKS = [
105
117
  },
106
118
  {
107
119
  id: "fix-failing-test",
120
+ expectedFiles: ["calc.js"],
108
121
  description:
109
122
  "Fix a bug so an existing test suite passes (bug-fix category)",
110
123
  prompt:
@@ -170,6 +183,7 @@ export const BUILTIN_TASKS = [
170
183
  },
171
184
  {
172
185
  id: "refactor-rename",
186
+ expectedFiles: ["util.js", "main.js"],
173
187
  description:
174
188
  "Rename a symbol across two files, keeping behavior (refactor)",
175
189
  prompt:
@@ -226,6 +240,7 @@ export const BUILTIN_TASKS = [
226
240
  },
227
241
  {
228
242
  id: "write-test",
243
+ expectedFiles: ["verify.mjs"],
229
244
  description:
230
245
  "Write a meaningful verifier for a module (test-completion category)",
231
246
  prompt:
@@ -300,6 +315,7 @@ export const BUILTIN_TASKS = [
300
315
  },
301
316
  {
302
317
  id: "migrate-signature",
318
+ expectedFiles: ["greet.mjs", "app.mjs"],
303
319
  description:
304
320
  "Migrate a function's call convention and update all callers (api-upgrade category)",
305
321
  prompt:
@@ -361,6 +377,7 @@ export const BUILTIN_TASKS = [
361
377
  },
362
378
  {
363
379
  id: "secure-path",
380
+ expectedFiles: ["notes.mjs"],
364
381
  description:
365
382
  "Fix a path-traversal vulnerability, verified by an exploit probe (security-fix category)",
366
383
  prompt:
@@ -447,6 +464,159 @@ export const BUILTIN_TASKS = [
447
464
  };
448
465
  },
449
466
  },
467
+ {
468
+ id: "fix-build",
469
+ expectedFiles: ["config.mjs", "app.mjs"],
470
+ description:
471
+ "Fix a cross-module build/link failure so the build passes (build-failure category)",
472
+ prompt:
473
+ "The build is broken: `node build.mjs` fails to LINK because of an " +
474
+ "export/import name mismatch between app.mjs and config.mjs. Reconcile " +
475
+ "them so `node build.mjs` prints BUILD OK. Do not edit build.mjs.",
476
+ setup: (dir) => {
477
+ // config exports `version` (lowercase) but app imports `VERSION` — an ESM
478
+ // link error at build time, distinct from a single-file syntax typo.
479
+ fs.writeFileSync(
480
+ path.join(dir, "config.mjs"),
481
+ 'export const version = "1.0.0";\n',
482
+ "utf8",
483
+ );
484
+ fs.writeFileSync(
485
+ path.join(dir, "app.mjs"),
486
+ 'import { VERSION } from "./config.mjs";\n' +
487
+ 'export function banner() {\n return "v" + VERSION;\n}\n',
488
+ "utf8",
489
+ );
490
+ fs.writeFileSync(
491
+ path.join(dir, "build.mjs"),
492
+ 'import { banner } from "./app.mjs";\n' +
493
+ 'if (banner() !== "v1.0.0") {\n' +
494
+ ' console.error("BUILD FAIL: " + banner());\n' +
495
+ " process.exit(1);\n" +
496
+ "}\n" +
497
+ 'console.log("BUILD OK");\n',
498
+ "utf8",
499
+ );
500
+ },
501
+ check: (dir) => {
502
+ const build = read(dir, "build.mjs");
503
+ if (build == null) return { pass: false, detail: "build.mjs missing" };
504
+ // Guard: fix the modules, don't neuter the build harness.
505
+ if (!/banner\(\)\s*!==\s*"v1\.0\.0"/.test(build)) {
506
+ return { pass: false, detail: "build.mjs assertion was altered" };
507
+ }
508
+ try {
509
+ const out = execFileSync(process.execPath, ["build.mjs"], {
510
+ cwd: dir,
511
+ encoding: "utf8",
512
+ timeout: 10000,
513
+ stdio: ["ignore", "pipe", "pipe"],
514
+ });
515
+ return out.includes("BUILD OK")
516
+ ? { pass: true, detail: "build links + passes" }
517
+ : {
518
+ pass: false,
519
+ detail: `unexpected output ${JSON.stringify(out.trim())}`,
520
+ };
521
+ } catch (err) {
522
+ const first = String(err.message || "").split("\n")[0];
523
+ return { pass: false, detail: `build still failing: ${first}` };
524
+ }
525
+ },
526
+ },
527
+ {
528
+ id: "upgrade-dependency",
529
+ expectedFiles: ["package.json", "app.mjs"],
530
+ description:
531
+ "Adapt code to a dependency's breaking upgrade + bump the manifest (dependency-upgrade category)",
532
+ prompt:
533
+ "The `stringutil` dependency was upgraded to 2.0.0. Breaking change: its " +
534
+ "`capitalize` export was renamed to `toTitle` (same behavior). Do all of: " +
535
+ "(1) bump stringutil to ^2.0.0 in package.json; (2) update app.mjs to " +
536
+ "import and use `toTitle` instead of `capitalize`; (3) do NOT edit " +
537
+ "stringutil.mjs. Afterwards `node run.mjs` must print OK.",
538
+ setup: (dir) => {
539
+ fs.writeFileSync(
540
+ path.join(dir, "package.json"),
541
+ JSON.stringify(
542
+ {
543
+ name: "app",
544
+ type: "module",
545
+ dependencies: { stringutil: "1.0.0" },
546
+ },
547
+ null,
548
+ 2,
549
+ ) + "\n",
550
+ "utf8",
551
+ );
552
+ // The upgraded (v2) dependency — vendored, must not be edited.
553
+ fs.writeFileSync(path.join(dir, "stringutil.mjs"), STRINGUTIL_V2, "utf8");
554
+ // The caller still uses the removed v1 `capitalize` export (link error).
555
+ fs.writeFileSync(
556
+ path.join(dir, "app.mjs"),
557
+ 'import { capitalize } from "./stringutil.mjs";\n' +
558
+ "export function label(s) {\n return capitalize(s);\n}\n",
559
+ "utf8",
560
+ );
561
+ fs.writeFileSync(
562
+ path.join(dir, "run.mjs"),
563
+ 'import { label } from "./app.mjs";\n' +
564
+ 'if (label("hello") !== "Hello") {\n' +
565
+ ' console.error("FAIL: " + label("hello"));\n' +
566
+ " process.exit(1);\n" +
567
+ "}\n" +
568
+ 'console.log("OK");\n',
569
+ "utf8",
570
+ );
571
+ },
572
+ check: (dir) => {
573
+ // The dependency is vendored — the agent must adapt the caller, NOT edit
574
+ // the dependency to re-add the old export and dodge the upgrade.
575
+ const dep = read(dir, "stringutil.mjs");
576
+ if (dep == null) return { pass: false, detail: "stringutil.mjs missing" };
577
+ if (dep !== STRINGUTIL_V2) {
578
+ return {
579
+ pass: false,
580
+ detail: "the stringutil dependency was edited (adapt the caller)",
581
+ };
582
+ }
583
+ const pkg = read(dir, "package.json");
584
+ if (pkg == null || !/"stringutil"\s*:\s*"[\^~]?2\./.test(pkg)) {
585
+ return {
586
+ pass: false,
587
+ detail: "package.json not bumped to stringutil 2.x",
588
+ };
589
+ }
590
+ const app = read(dir, "app.mjs");
591
+ if (app == null) return { pass: false, detail: "app.mjs missing" };
592
+ if (/\bcapitalize\b/.test(app)) {
593
+ return {
594
+ pass: false,
595
+ detail: "app.mjs still references the removed capitalize export",
596
+ };
597
+ }
598
+ if (!/\btoTitle\b/.test(app)) {
599
+ return { pass: false, detail: "app.mjs does not use the new toTitle" };
600
+ }
601
+ try {
602
+ const out = execFileSync(process.execPath, ["run.mjs"], {
603
+ cwd: dir,
604
+ encoding: "utf8",
605
+ timeout: 10000,
606
+ stdio: ["ignore", "pipe", "pipe"],
607
+ });
608
+ return out.trim() === "OK"
609
+ ? { pass: true, detail: "adapted to new API + manifest bumped" }
610
+ : {
611
+ pass: false,
612
+ detail: `run.mjs printed ${JSON.stringify(out.trim())}`,
613
+ };
614
+ } catch (err) {
615
+ const first = String(err.message || "").split("\n")[0];
616
+ return { pass: false, detail: `run.mjs failed: ${first}` };
617
+ }
618
+ },
619
+ },
450
620
  ];
451
621
 
452
622
  /** Look up a suite by name (only "builtin" for now). */