chainlesschain 0.162.148 → 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 (322) 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-DwpCCp64.js → AIOps-CBLvrjeG.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C9pBYocA.js → ActionButton-DYv2GtE0.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BWAkeXxK.js → Analytics-CL6PZ-Ww.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CivFGH6B.js → AppLayout-xuyHt4uA.js} +3 -3
  8. package/src/assets/web-panel/assets/{Audit-Cm8hRpZm.js → Audit-DOvSVycq.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DXdFMsE8.js → Backup-DMhfTswr.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-uAwSTeql.js → BaseInput-CQxDdm63.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-KU8eeJJE.js → Chat-BEeNhK2a.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-8nul8eTq.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-C6AMDkjd.js → Checkbox-CL04O-ER.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-t2moDxcO.js → Codegen-C50o-n7x.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DCcsRRhN.js → Col-CH-bDkzs.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DtB-8SAC.js → Community-DqAIMvSe.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-CZm8THYA.js → Compact-C43fo_my.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-LiQgC7g1.js → Compliance-BERnMrdP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CA8SAxht.js → Cowork-Baw3w1gp.js} +4 -4
  20. package/src/assets/web-panel/assets/{Cron-CtRaF1wD.js → Cron-BEqAHF1-.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-6-br6Hub.js → Crosschain-CvnmKwK4.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Do2EccrL.js → DID-iMPxgVdt.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-wrXcbzGe.js → Dashboard--4SJX3YR.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-p3FsT245.js → Dropdown-BgLV6xgz.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-D95A2L8q.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-cLuJW2zo.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-Brgq_cbN.js → Federation-BbFfJ1Xi.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-DWLCkNgh.js → FormItemContext-DeGq1B-q.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BBqUfQd6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-8F090w4I.js → Git-L1PjW-lT.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CCogEbxb.js → Governance-PK-X58to.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CfLD7v7C.js → Inference-BePWEH-d.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DDuHJewd.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CE8KSEVC.js → Logs-BKkfk9hy.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-DmwpZmhT.js → Marketplace-BNMqUDla.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-Bf7AazU8.js → McpTools-w4WPiyz2.js} +5 -5
  37. package/src/assets/web-panel/assets/{Memory-D0QU_00S.js → Memory-DUKMVGNi.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-yXS9xdhx.js → MobileBridge-BWhiEyTJ.js} +1 -1
  39. package/src/assets/web-panel/assets/{MobileProjects-BuDUoGUP.js → MobileProjects-Ocf5JEkX.js} +1 -1
  40. package/src/assets/web-panel/assets/{Mtc-BYyHy28p.js → Mtc-D2B6MMhU.js} +4 -4
  41. package/src/assets/web-panel/assets/{MtcAudit-CK0aqpiZ.js → MtcAudit-DdYjCq1O.js} +4 -4
  42. package/src/assets/web-panel/assets/{Multisig-mNimKYeb.js → Multisig-Cb1hfuUZ.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-AioAJ0YA.js → NLProgramming-CTeImGp7.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-CVVNCLHE.js → Notes-BjYNc7eQ.js} +4 -4
  45. package/src/assets/web-panel/assets/{NotificationSettings-C4ABj-TK.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
  46. package/src/assets/web-panel/assets/{OrderTableRenderer-DIp8Xcbd.js → OrderTableRenderer-DVYYIizh.js} +1 -1
  47. package/src/assets/web-panel/assets/{Organization-uozl_gWK.js → Organization-Be2Kmr5j.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-BCZOM2hK.js → Overflow-Cu_-qRlR.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-CArcaiaj.js → P2P-DD2HoGzE.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-Sgq2Srr8.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
  51. package/src/assets/web-panel/assets/{Permissions-BYrQrXnH.js → Permissions-C9Srcs2M.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-BzHStAbz.js → PersonalDataHub-CUqcMgo1.js} +3 -3
  53. package/src/assets/web-panel/assets/{Pipeline-k7KqxX1M.js → Pipeline-HBrQGLXt.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-IumTUWqx.js → Privacy-D-B0vjwh.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-BRyImYTf.js → ProjectInit-eTeLIu9e.js} +2 -2
  56. package/src/assets/web-panel/assets/{ProjectSettings-BFIqTBFk.js → ProjectSettings-DrRqCsC6.js} +2 -2
  57. package/src/assets/web-panel/assets/{Projects-Dpid9CDg.js → Projects-1G9DNOhI.js} +1 -1
  58. package/src/assets/web-panel/assets/{Providers-CyyFnUPs.js → Providers-RkTZzpxP.js} +1 -1
  59. package/src/assets/web-panel/assets/{QrScannerModal-C82cRx-X.js → QrScannerModal-BSCUgsgC.js} +1 -1
  60. package/src/assets/web-panel/assets/{QuickAsk-DGxDF521.js → QuickAsk-CHgyM3Bz.js} +1 -1
  61. package/src/assets/web-panel/assets/{Recommend-Cns-Am1y.js → Recommend-0lry4OZq.js} +1 -1
  62. package/src/assets/web-panel/assets/{RemoteSession-R7OqAIlg.js → RemoteSession-Cn45UroZ.js} +2 -2
  63. package/src/assets/web-panel/assets/{Reputation-D7mgPIYV.js → Reputation-Q-Zjb707.js} +1 -1
  64. package/src/assets/web-panel/assets/{Row-B3lEURyd.js → Row-BdM70oda.js} +1 -1
  65. package/src/assets/web-panel/assets/{RssFeed-9_UVrpBt.js → RssFeed-DmOAKKap.js} +2 -2
  66. package/src/assets/web-panel/assets/{Search-ClZeO80q.js → Search-Dwavbm07.js} +1 -1
  67. package/src/assets/web-panel/assets/{Security-BNNJczEp.js → Security-DukXFCnk.js} +3 -3
  68. package/src/assets/web-panel/assets/{Services-C5SjrWUj.js → Services-BIlRnITu.js} +2 -2
  69. package/src/assets/web-panel/assets/{Skeleton-Ci_obQ-g.js → Skeleton-YYVQdhhQ.js} +1 -1
  70. package/src/assets/web-panel/assets/{Skills-DdebN15P.js → Skills-B8_iYHz2.js} +1 -1
  71. package/src/assets/web-panel/assets/{Sla-OinZP2vi.js → Sla-BdVrhT31.js} +1 -1
  72. package/src/assets/web-panel/assets/{SpeechSettings-CxzbNF51.js → SpeechSettings-CD3ggRx7.js} +1 -1
  73. package/src/assets/web-panel/assets/{SyncSettings-D06N_66b.js → SyncSettings-Bp02VZFH.js} +2 -2
  74. package/src/assets/web-panel/assets/{Tasks-BdEdW0AZ.js → Tasks-DEVmCEsr.js} +1 -1
  75. package/src/assets/web-panel/assets/{Templates-F1ctKmPa.js → Templates-B6czWc4N.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tenant-CVz1Urot.js → Tenant-BCJLv17r.js} +1 -1
  77. package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +3 -0
  78. package/src/assets/web-panel/assets/{TimelineRenderer-Doitzjmf.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tokens-BpyVRpVA.js → Tokens-BnSY0S-s.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trigger-nWhWYTbU.js → Trigger-VZw9Oy2w.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trust-DK_G-wLx.js → Trust-pZq7Hjd2.js} +1 -1
  82. package/src/assets/web-panel/assets/{UkeySign-B5yBUojO.js → UkeySign-DnQaqk4q.js} +1 -1
  83. package/src/assets/web-panel/assets/{VideoEditing-C5D51qAe.js → VideoEditing-BEUfmvJV.js} +1 -1
  84. package/src/assets/web-panel/assets/{Wallet-CLbL9K7v.js → Wallet-CoZKMXJ2.js} +4 -4
  85. package/src/assets/web-panel/assets/{WebAuthn-DZUelI3V.js → WebAuthn-CBOGVx1I.js} +5 -5
  86. package/src/assets/web-panel/assets/{WorkflowEditor-8RPxt4KW.js → WorkflowEditor-huSKn7TT.js} +1 -1
  87. package/src/assets/web-panel/assets/{chat-4N4tOA3d.js → chat-A_3w6FBO.js} +1 -1
  88. package/src/assets/web-panel/assets/{colors-zbbGVrua.js → colors-D1Bem9Oy.js} +1 -1
  89. package/src/assets/web-panel/assets/{compact-item-D7iMkbnE.js → compact-item-CJYJj0oO.js} +1 -1
  90. package/src/assets/web-panel/assets/{createContext-CBzPJv-w.js → createContext-BkbFiKT4.js} +1 -1
  91. package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
  92. package/src/assets/web-panel/assets/{hasIn-bHdrQSqZ.js → hasIn-CKvUafVY.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DbE5D0WL.js → index-AjrSPnvv.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BCr0geV9.js → index-B8i0lViZ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CiG1IZao.js → index-B9Svn0zc.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B1s0Bz9O.js → index-BHdHSX06.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-QFObYeo1.js → index-BHdailyo.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BnBOpqv3.js → index-BJwlEnYo.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CdmMoYN1.js → index-BOoAQjJz.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DUyjUkY7.js → index-BSgWxAOG.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CqdPyWm5.js → index-BdutMsne.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DmqlJed-.js → index-BiDWxzbn.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-S74FpAIn.js → index-By5a0T_W.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-kmh1TxRa.js → index-C-WIY-FQ.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BTIjjXry.js → index-C37f6iey.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BS4_Mwk6.js → index-C9bWmTcO.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BBNr77E1.js → index-CBaosWRO.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-QNAG4JtR.js → index-CBlBVJ_m.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bqmx24kh.js → index-CD62EEGo.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CQfu1U78.js → index-CUj-l7GM.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BJ4ZGyW0.js → index-CVS8Ymuq.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Ci009ijp.js → index-ChkXUj3f.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-oDKNgCsP.js → index-Cj0OZ-37.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BZb8F8YG.js → index-Co3OFL0t.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-308gCGh7.js → index-Crp8CbRg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CPxkoKgA.js → index-D22zNXiS.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-xYCm6W2h.js → index-DTs_D1OL.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BtbbdLnf.js → index-DfgCdFrN.js} +3 -3
  119. package/src/assets/web-panel/assets/{index-BsKehmmS.js → index-DjYrecNb.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CkxK86vf.js → index-DpW9cf3e.js} +1 -1
  121. package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CvRMA9uT.js → index-F--HuPG1.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DE9j5YgT.js → index-Fuk6t_3K.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-B7b1hGry.js → index-JEAGMii9.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-D1YDh7Wr.js → index-PF-mpv8K.js} +1 -1
  126. package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
  127. package/src/assets/web-panel/assets/{index-CQ6NcfWz.js → index-b-sbVdjQ.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DyoNgbXl.js → index-pyvMVX8r.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DISWAYce.js → index-qNTtOVi_.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-D4XKpj6c.js → index-tgO8iza6.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CahryTX0.js → index-ttDQVhZy.js} +1 -1
  132. package/src/assets/web-panel/assets/{initDefaultProps-BD55yNBt.js → initDefaultProps-DtrnfsZH.js} +1 -1
  133. package/src/assets/web-panel/assets/{motion-B5Bbe77U.js → motion-D4zqSaX3.js} +1 -1
  134. package/src/assets/web-panel/assets/{move-CTvIqHEH.js → move-CGFGOUQj.js} +1 -1
  135. package/src/assets/web-panel/assets/{mtc-parser-BkNyPQKB.js → mtc-parser-DH2HvkJl.js} +1 -1
  136. package/src/assets/web-panel/assets/{omit-BaXJXgHA.js → omit-jJ2at5HX.js} +1 -1
  137. package/src/assets/web-panel/assets/{pickAttrs-Bw6-YTxH.js → pickAttrs-CRyMT1Fv.js} +1 -1
  138. package/src/assets/web-panel/assets/{placementArrow-BLdbkLqJ.js → placementArrow-DZ_CX0Pt.js} +1 -1
  139. package/src/assets/web-panel/assets/{responsiveObserve-IVYkzntU.js → responsiveObserve-wruHk-h5.js} +1 -1
  140. package/src/assets/web-panel/assets/{slide-DFMFwwtY.js → slide-BGgx8q67.js} +1 -1
  141. package/src/assets/web-panel/assets/{statusUtils-CURYRtZ1.js → statusUtils-Do5M7gKm.js} +1 -1
  142. package/src/assets/web-panel/assets/{styleChecker-Cfz63s1r.js → styleChecker-CRa-GZpX.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFlexGapSupport-COJL0KE3.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFs-YLLojQQf.js → useFs-v5O2ZcJm.js} +1 -1
  145. package/src/assets/web-panel/assets/{usePersonalDataHub-BF_21qUC.js → usePersonalDataHub--z2FU0Px.js} +1 -1
  146. package/src/assets/web-panel/assets/{vnode-9ZpkA7bb.js → vnode-1emidVKd.js} +1 -1
  147. package/src/assets/web-panel/assets/{zoom-DhtAfhl8.js → zoom-CcJaRyHs.js} +1 -1
  148. package/src/assets/web-panel/index.html +1 -1
  149. package/src/assets/web-panel/remote-session-sw.js +43 -0
  150. package/src/command-manifest.json +22 -1
  151. package/src/commands/a2a.js +19 -4
  152. package/src/commands/activitypub.js +20 -3
  153. package/src/commands/agent.js +71 -10
  154. package/src/commands/audit.js +40 -24
  155. package/src/commands/codeintel.js +320 -0
  156. package/src/commands/collab.js +15 -2
  157. package/src/commands/compliance.js +5 -0
  158. package/src/commands/config.js +4 -1
  159. package/src/commands/dao.js +86 -14
  160. package/src/commands/dev.js +2 -0
  161. package/src/commands/did.js +7 -1
  162. package/src/commands/dlp.js +23 -1
  163. package/src/commands/economy.js +29 -3
  164. package/src/commands/eval.js +255 -0
  165. package/src/commands/evomap.js +26 -0
  166. package/src/commands/governance.js +17 -3
  167. package/src/commands/hardening.js +18 -0
  168. package/src/commands/incentive.js +5 -0
  169. package/src/commands/init.js +46 -2
  170. package/src/commands/kg.js +4 -0
  171. package/src/commands/loop.js +6 -1
  172. package/src/commands/lowcode.js +15 -2
  173. package/src/commands/marketplace.js +40 -6
  174. package/src/commands/matrix.js +20 -1
  175. package/src/commands/memory.js +4 -1
  176. package/src/commands/mtc.js +7 -1
  177. package/src/commands/nostr.js +31 -4
  178. package/src/commands/note.js +7 -4
  179. package/src/commands/plugin.js +474 -0
  180. package/src/commands/pqc.js +5 -0
  181. package/src/commands/reputation.js +10 -1
  182. package/src/commands/scim.js +6 -0
  183. package/src/commands/session.js +32 -10
  184. package/src/commands/siem.js +11 -0
  185. package/src/commands/sla.js +18 -3
  186. package/src/commands/social.js +38 -5
  187. package/src/commands/sso.js +10 -2
  188. package/src/commands/stress.js +23 -4
  189. package/src/commands/team.js +463 -0
  190. package/src/commands/tech.js +2 -0
  191. package/src/commands/tenant.js +10 -1
  192. package/src/commands/terraform.js +6 -0
  193. package/src/commands/update.js +1 -1
  194. package/src/commands/zkp.js +20 -0
  195. package/src/gateways/ws/message-dispatcher.js +48 -2
  196. package/src/gateways/ws/remote-session-protocol.js +140 -42
  197. package/src/gateways/ws/ws-server.js +1 -1
  198. package/src/harness/jsonl-session-store.js +12 -5
  199. package/src/harness/plugin-manager.js +16 -4
  200. package/src/harness/prompt-compressor.js +27 -1
  201. package/src/harness/remote-command-ledger.js +189 -0
  202. package/src/harness/remote-session-push-apns.js +246 -0
  203. package/src/harness/remote-session-push-errors.js +15 -0
  204. package/src/harness/remote-session-push-fcm.js +9 -25
  205. package/src/harness/remote-session-push-huawei.js +174 -0
  206. package/src/harness/remote-session-push-oppo.js +171 -0
  207. package/src/harness/remote-session-push-senders.js +42 -0
  208. package/src/harness/remote-session-push-vivo.js +179 -0
  209. package/src/harness/remote-session-push-web.js +299 -0
  210. package/src/harness/remote-session-push-xiaomi.js +99 -0
  211. package/src/harness/worktree-isolator.js +16 -6
  212. package/src/index.js +6 -0
  213. package/src/lib/__tests__/logger.test.js +5 -2
  214. package/src/lib/a2a-protocol.js +25 -1
  215. package/src/lib/activitypub-bridge.js +61 -0
  216. package/src/lib/agent-core.js +4 -0
  217. package/src/lib/agent-economy.js +262 -29
  218. package/src/lib/agent-network.js +7 -1
  219. package/src/lib/agent-sandbox.js +161 -5
  220. package/src/lib/agent-team/task-lease.js +434 -0
  221. package/src/lib/agent-team/team-budget.js +165 -0
  222. package/src/lib/agent-team/team-mailbox.js +106 -0
  223. package/src/lib/agent-team/team-runner.js +282 -0
  224. package/src/lib/agent-team/team-worktree.js +236 -0
  225. package/src/lib/agents.js +18 -0
  226. package/src/lib/async-hook-supervisor.cjs +391 -0
  227. package/src/lib/audit-logger.js +7 -6
  228. package/src/lib/autonomous-developer.js +60 -0
  229. package/src/lib/chat-core.js +17 -4
  230. package/src/lib/collaboration-governance.js +56 -0
  231. package/src/lib/community-governance.js +68 -0
  232. package/src/lib/compliance-manager.js +63 -0
  233. package/src/lib/cross-chain.js +5 -0
  234. package/src/lib/dao-governance.js +151 -2
  235. package/src/lib/did-manager.js +23 -10
  236. package/src/lib/dlp-engine.js +70 -0
  237. package/src/lib/eval/runner.js +251 -0
  238. package/src/lib/eval/tasks.js +626 -0
  239. package/src/lib/eval/trend.js +200 -0
  240. package/src/lib/evolution-system.js +92 -0
  241. package/src/lib/evomap-federation.js +55 -0
  242. package/src/lib/evomap-governance.js +94 -0
  243. package/src/lib/fatal-handler.js +17 -1
  244. package/src/lib/hardening-manager.js +73 -0
  245. package/src/lib/hierarchical-memory.js +14 -8
  246. package/src/lib/knowledge-exporter.js +8 -2
  247. package/src/lib/knowledge-graph.js +79 -0
  248. package/src/lib/llm-providers.js +23 -14
  249. package/src/lib/logger.js +4 -1
  250. package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
  251. package/src/lib/lsp/__tests__/code-intelligence.integration.test.js +129 -0
  252. package/src/lib/lsp/__tests__/code-intelligence.test.js +228 -0
  253. package/src/lib/lsp/__tests__/jsonrpc-stream.test.js +104 -0
  254. package/src/lib/lsp/__tests__/lsp-client.test.js +269 -0
  255. package/src/lib/lsp/__tests__/lsp-manager.test.js +333 -0
  256. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +128 -0
  257. package/src/lib/lsp/benchmark.js +257 -0
  258. package/src/lib/lsp/code-intelligence.js +356 -0
  259. package/src/lib/lsp/jsonrpc-stream.js +139 -0
  260. package/src/lib/lsp/lsp-client.js +339 -0
  261. package/src/lib/lsp/lsp-manager.js +375 -0
  262. package/src/lib/lsp/lsp-server-registry.js +196 -0
  263. package/src/lib/matrix-bridge.js +84 -0
  264. package/src/lib/memory-manager.js +5 -3
  265. package/src/lib/nostr-bridge.js +53 -0
  266. package/src/lib/permission-engine.js +22 -4
  267. package/src/lib/plugin-monitor-supervisor.js +238 -0
  268. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
  269. package/src/lib/plugin-runtime/agents.js +51 -0
  270. package/src/lib/plugin-runtime/bin.js +100 -0
  271. package/src/lib/plugin-runtime/hooks.js +100 -0
  272. package/src/lib/plugin-runtime/install.js +396 -0
  273. package/src/lib/plugin-runtime/lsp.js +75 -0
  274. package/src/lib/plugin-runtime/manifest.js +458 -0
  275. package/src/lib/plugin-runtime/mcp.js +89 -0
  276. package/src/lib/plugin-runtime/monitors.js +100 -0
  277. package/src/lib/plugin-runtime/policy.js +152 -0
  278. package/src/lib/plugin-runtime/reload.js +79 -0
  279. package/src/lib/plugin-runtime/remote-source.js +240 -0
  280. package/src/lib/plugin-runtime/scopes.js +197 -0
  281. package/src/lib/plugin-runtime/settings.js +119 -0
  282. package/src/lib/plugin-runtime/signature.js +107 -0
  283. package/src/lib/plugin-runtime/skills.js +43 -0
  284. package/src/lib/plugin-runtime/trust.js +140 -0
  285. package/src/lib/pqc-manager.js +64 -0
  286. package/src/lib/reputation-optimizer.js +101 -0
  287. package/src/lib/sandbox-egress-proxy.js +262 -0
  288. package/src/lib/sandbox-fs-policy.js +112 -0
  289. package/src/lib/sandbox-network-policy.js +151 -0
  290. package/src/lib/sandbox-v2.js +24 -18
  291. package/src/lib/scim-manager.js +36 -0
  292. package/src/lib/session-manager.js +5 -2
  293. package/src/lib/settings-hook-events.cjs +78 -6
  294. package/src/lib/settings-hooks.cjs +30 -3
  295. package/src/lib/settings-loader.cjs +35 -1
  296. package/src/lib/siem-exporter.js +45 -0
  297. package/src/lib/skill-loader.js +38 -2
  298. package/src/lib/skill-marketplace.js +83 -0
  299. package/src/lib/sla-manager.js +88 -0
  300. package/src/lib/social-manager.js +74 -0
  301. package/src/lib/stress-tester.js +65 -0
  302. package/src/lib/tech-learning-engine.js +75 -0
  303. package/src/lib/telemetry/span-recorder.js +237 -0
  304. package/src/lib/tenant-saas.js +107 -0
  305. package/src/lib/terraform-manager.js +67 -0
  306. package/src/lib/token-incentive.js +180 -29
  307. package/src/lib/wallet-manager.js +81 -35
  308. package/src/lib/zkp-engine.js +87 -0
  309. package/src/repl/agent-repl.js +417 -6
  310. package/src/runtime/__tests__/auto-pin.test.js +104 -0
  311. package/src/runtime/agent-core.js +771 -104
  312. package/src/runtime/auto-pin.js +117 -0
  313. package/src/runtime/coding-agent-contract-shared.cjs +82 -8
  314. package/src/runtime/coding-agent-policy.cjs +32 -7
  315. package/src/runtime/fallback-model.js +134 -7
  316. package/src/runtime/headless-runner.js +388 -108
  317. package/src/runtime/mcp-config.js +46 -0
  318. package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +0 -1
  319. package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +0 -3
  320. package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +0 -1
  321. package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +0 -1
  322. package/src/assets/web-panel/assets/index-BXiw9dQf.js +0 -1
@@ -5,6 +5,8 @@
5
5
  * with Ebbinghaus forgetting curve and spacing effect reinforcement.
6
6
  */
7
7
 
8
+ import { escapeLike } from "./sql-like.js";
9
+
8
10
  // ─── Configuration ───────────────────────────────────────────────
9
11
  export const MEMORY_CONFIG = {
10
12
  workingCapacity: 50,
@@ -292,8 +294,10 @@ export function recallMemory(db, query, options = {}) {
292
294
  // Search long-term memory (DB)
293
295
  ensureMemoryTables(db);
294
296
  const ltRows = db
295
- .prepare(`SELECT * FROM memory_long_term WHERE content LIKE ? LIMIT ?`)
296
- .all(`%${query}%`, limit);
297
+ .prepare(
298
+ `SELECT * FROM memory_long_term WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
299
+ )
300
+ .all(`%${escapeLike(query)}%`, limit);
297
301
  for (const row of ltRows) {
298
302
  const retention = calcRetention(row.last_accessed);
299
303
  if (retention >= MEMORY_CONFIG.recallThreshold) {
@@ -316,8 +320,10 @@ export function recallMemory(db, query, options = {}) {
316
320
 
317
321
  // Search core memory (DB) — core memories don't decay
318
322
  const coreRows = db
319
- .prepare(`SELECT * FROM memory_core WHERE content LIKE ? LIMIT ?`)
320
- .all(`%${query}%`, limit);
323
+ .prepare(
324
+ `SELECT * FROM memory_core WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
325
+ )
326
+ .all(`%${escapeLike(query)}%`, limit);
321
327
  for (const row of coreRows) {
322
328
  db.prepare(
323
329
  `UPDATE memory_core SET access_count = access_count + 1, last_accessed = ? WHERE id = ?`,
@@ -444,9 +450,9 @@ function _searchByType(db, query, type, options = {}) {
444
450
  ensureMemoryTables(db);
445
451
  const ltRows = db
446
452
  .prepare(
447
- `SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? LIMIT ?`,
453
+ `SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
448
454
  )
449
- .all(type, `%${query}%`, limit);
455
+ .all(type, `%${escapeLike(query)}%`, limit);
450
456
  for (const row of ltRows) {
451
457
  results.push({
452
458
  id: row.id,
@@ -462,9 +468,9 @@ function _searchByType(db, query, type, options = {}) {
462
468
 
463
469
  const coreRows = db
464
470
  .prepare(
465
- `SELECT * FROM memory_core WHERE type = ? AND content LIKE ? LIMIT ?`,
471
+ `SELECT * FROM memory_core WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
466
472
  )
467
- .all(type, `%${query}%`, limit);
473
+ .all(type, `%${escapeLike(query)}%`, limit);
468
474
  for (const row of coreRows) {
469
475
  results.push({
470
476
  id: row.id,
@@ -78,7 +78,10 @@ export function sanitizeFilename(name) {
78
78
  * Convert a note to markdown with YAML frontmatter.
79
79
  */
80
80
  export function noteToMarkdown(note) {
81
- const tags = JSON.parse(note.tags || "[]");
81
+ // safeJsonParse (not bare JSON.parse): exportToMarkdown loops over every note,
82
+ // so one corrupt/hand-edited `tags` cell would otherwise throw and abort the
83
+ // ENTIRE export mid-way. Matches generateIndexHtml, which already guards.
84
+ const tags = safeJsonParse(note.tags, []);
82
85
  const lines = [
83
86
  "---",
84
87
  `title: "${note.title.replace(/"/g, '\\"')}"`,
@@ -136,7 +139,10 @@ export function exportToMarkdown(db, outputDir, options = {}) {
136
139
  * Generate a minimal HTML page for a note.
137
140
  */
138
141
  export function noteToHtml(note) {
139
- const tags = JSON.parse(note.tags || "[]");
142
+ // safeJsonParse (not bare JSON.parse): exportToSite loops over every note, so
143
+ // one corrupt `tags` cell would otherwise throw and abort the whole site
144
+ // export — after index.html was already written, leaving dangling links.
145
+ const tags = safeJsonParse(note.tags, []);
140
146
  const tagsHtml = tags
141
147
  .map((t) => `<span class="tag">${escapeHtml(t)}</span>`)
142
148
  .join(" ");
@@ -95,6 +95,85 @@ export function ensureKnowledgeGraphTables(db) {
95
95
  );
96
96
  }
97
97
 
98
+ /**
99
+ * Hydrate the in-memory graph from the DB. The CLI is one-shot: _entities/
100
+ * _relations/_outEdges/_inEdges start empty every process. Writes dual-write
101
+ * (Map + INSERT), but every read is Map-only and nothing ever SELECTed the
102
+ * tables back — so persisted entities/relations were invisible on the next
103
+ * invocation (list/show/stats/export empty; add-relation threw "Source entity
104
+ * not found"; remove returned false and left the row). Call after
105
+ * ensureKnowledgeGraphTables(db).
106
+ */
107
+ export function loadFromDb(db) {
108
+ if (!db) return 0;
109
+ ensureKnowledgeGraphTables(db);
110
+ _entities.clear();
111
+ _relations.clear();
112
+ _outEdges.clear();
113
+ _inEdges.clear();
114
+
115
+ const entityRows = db
116
+ .prepare(
117
+ `SELECT id, name, type, properties, tags, created_at, updated_at
118
+ FROM kg_entities ORDER BY created_at ASC`,
119
+ )
120
+ .all();
121
+ for (const r of entityRows) {
122
+ // A single corrupt properties/tags cell must not crash the whole load.
123
+ let properties = null;
124
+ let tags = null;
125
+ try {
126
+ properties = r.properties ? JSON.parse(r.properties) : null;
127
+ } catch {
128
+ properties = null;
129
+ }
130
+ try {
131
+ tags = r.tags ? JSON.parse(r.tags) : null;
132
+ } catch {
133
+ tags = null;
134
+ }
135
+ _entities.set(r.id, {
136
+ id: r.id,
137
+ name: r.name,
138
+ type: r.type,
139
+ properties,
140
+ tags,
141
+ createdAt: Number(r.created_at),
142
+ updatedAt: Number(r.updated_at),
143
+ _seq: ++_seq,
144
+ });
145
+ }
146
+
147
+ const relationRows = db
148
+ .prepare(
149
+ `SELECT id, source_id, target_id, relation_type, weight, properties, created_at
150
+ FROM kg_relationships ORDER BY created_at ASC`,
151
+ )
152
+ .all();
153
+ for (const r of relationRows) {
154
+ let properties = null;
155
+ try {
156
+ properties = r.properties ? JSON.parse(r.properties) : null;
157
+ } catch {
158
+ properties = null;
159
+ }
160
+ const relation = {
161
+ id: r.id,
162
+ sourceId: r.source_id,
163
+ targetId: r.target_id,
164
+ relationType: r.relation_type,
165
+ weight: Number(r.weight),
166
+ properties,
167
+ createdAt: Number(r.created_at),
168
+ _seq: ++_seq,
169
+ };
170
+ _relations.set(r.id, relation);
171
+ _indexRelation(relation);
172
+ }
173
+
174
+ return _entities.size + _relations.size;
175
+ }
176
+
98
177
  /* ── Catalogs ──────────────────────────────────────────────── */
99
178
 
100
179
  export function listEntityTypes() {
@@ -292,20 +292,29 @@ export class LLMProviderRegistry {
292
292
  if (!this.providers.has(name)) {
293
293
  throw new Error(`Provider "${name}" not found`);
294
294
  }
295
- // Reset all
296
- this.db.prepare("UPDATE llm_providers SET is_active = 0 WHERE 1=1").run();
297
- // Set active
298
- this.db
299
- .prepare(
300
- "INSERT OR REPLACE INTO llm_providers (name, display_name, base_url, api_key_env, models, is_active) VALUES (?, ?, ?, ?, ?, 1)",
301
- )
302
- .run(
303
- name,
304
- this.providers.get(name).displayName,
305
- this.providers.get(name).baseUrl,
306
- this.providers.get(name).apiKeyEnv,
307
- JSON.stringify(this.providers.get(name).models),
308
- );
295
+ // Clear every active flag then mark the new provider active atomically.
296
+ // Without a transaction, a failure on the second statement leaves NO
297
+ // provider active — which getActive() silently masks as the "ollama"
298
+ // fallback, so a failed switch would quietly lose the current provider.
299
+ const applyWrites = () => {
300
+ this.db.prepare("UPDATE llm_providers SET is_active = 0 WHERE 1=1").run();
301
+ this.db
302
+ .prepare(
303
+ "INSERT OR REPLACE INTO llm_providers (name, display_name, base_url, api_key_env, models, is_active) VALUES (?, ?, ?, ?, ?, 1)",
304
+ )
305
+ .run(
306
+ name,
307
+ this.providers.get(name).displayName,
308
+ this.providers.get(name).baseUrl,
309
+ this.providers.get(name).apiKeyEnv,
310
+ JSON.stringify(this.providers.get(name).models),
311
+ );
312
+ };
313
+ if (this.db && typeof this.db.transaction === "function") {
314
+ this.db.transaction(applyWrites)();
315
+ } else {
316
+ applyWrites();
317
+ }
309
318
  return this.providers.get(name);
310
319
  }
311
320
 
package/src/lib/logger.js CHANGED
@@ -24,7 +24,10 @@ export function success(message, ...args) {
24
24
  }
25
25
 
26
26
  export function warn(message, ...args) {
27
- console.log(chalk.yellow("⚠"), message, ...args);
27
+ // stderr, not stdout: a warning must never interleave with a command's
28
+ // machine-readable stdout (e.g. `--json` payloads), which `| jq` and other
29
+ // consumers parse. Like error(), warn is never gated by quiet mode.
30
+ console.error(chalk.yellow("⚠"), message, ...args);
28
31
  }
29
32
 
30
33
  export function error(message, ...args) {
@@ -0,0 +1,88 @@
1
+ /**
2
+ * benchmark stats tests — the pure percentile/summarize helpers that turn raw
3
+ * latency samples into a report. No spawning; the harness itself is exercised by
4
+ * the live `cc code-intel bench` run.
5
+ */
6
+
7
+ import { describe, it, expect } from "vitest";
8
+ import {
9
+ percentile,
10
+ summarize,
11
+ sumSubtreeRss,
12
+ sumSubtreeRssFromWmicCsv,
13
+ } from "../benchmark.js";
14
+
15
+ describe("percentile", () => {
16
+ it("returns the value for a single sample", () => {
17
+ expect(percentile([5], 50)).toBe(5);
18
+ expect(percentile([5], 95)).toBe(5);
19
+ });
20
+ it("computes median and p95 with interpolation", () => {
21
+ const s = [10, 20, 30, 40, 50];
22
+ expect(percentile(s, 50)).toBe(30);
23
+ // p95 of 5 points: rank = 0.95*4 = 3.8 → 40 + (50-40)*0.8 = 48
24
+ expect(percentile(s, 95)).toBeCloseTo(48, 5);
25
+ });
26
+ it("is order-independent (sorts internally)", () => {
27
+ expect(percentile([50, 10, 30, 40, 20], 50)).toBe(30);
28
+ });
29
+ it("returns null for an empty sample", () => {
30
+ expect(percentile([], 50)).toBeNull();
31
+ });
32
+ });
33
+
34
+ describe("summarize", () => {
35
+ it("reports n/min/median/p95/max/mean rounded to 0.1ms", () => {
36
+ const s = summarize([12.34, 5.6, 8.9, 20.1, 3.33]);
37
+ expect(s.n).toBe(5);
38
+ expect(s.min).toBe(3.3);
39
+ expect(s.max).toBe(20.1);
40
+ expect(s.median).toBe(8.9);
41
+ expect(s.mean).toBe(10.1); // (12.34+5.6+8.9+20.1+3.33)/5 = 10.054 → 10.1
42
+ });
43
+ it("handles an empty sample", () => {
44
+ expect(summarize([])).toEqual({ n: 0 });
45
+ });
46
+ });
47
+
48
+ describe("sumSubtreeRss", () => {
49
+ // launcher(100) → node server(200) → worker(300); sibling(400) unrelated
50
+ const rows = [
51
+ { pid: 100, ppid: 1, val: 5 },
52
+ { pid: 200, ppid: 100, val: 120 },
53
+ { pid: 300, ppid: 200, val: 40 },
54
+ { pid: 400, ppid: 1, val: 999 },
55
+ ];
56
+ it("sums a pid and all its transitive descendants (not the launcher alone)", () => {
57
+ expect(sumSubtreeRss(rows, 100)).toBe(165); // 5 + 120 + 40
58
+ });
59
+ it("returns just the leaf when it has no children", () => {
60
+ expect(sumSubtreeRss(rows, 300)).toBe(40);
61
+ });
62
+ it("returns null when the root pid is absent", () => {
63
+ expect(sumSubtreeRss(rows, 555)).toBeNull();
64
+ });
65
+ it("does not loop on a cyclic parent relationship", () => {
66
+ const cyclic = [
67
+ { pid: 1, ppid: 2, val: 10 },
68
+ { pid: 2, ppid: 1, val: 20 },
69
+ ];
70
+ expect(sumSubtreeRss(cyclic, 1)).toBe(30);
71
+ });
72
+ });
73
+
74
+ describe("sumSubtreeRssFromWmicCsv", () => {
75
+ it("parses wmic CSV and sums the subtree in bytes", () => {
76
+ const csv = [
77
+ "Node,ParentProcessId,ProcessId,WorkingSetSize",
78
+ "HOST,1,100,5000",
79
+ "HOST,100,200,120000",
80
+ "HOST,200,300,40000",
81
+ "HOST,1,400,999000",
82
+ ].join("\r\n");
83
+ expect(sumSubtreeRssFromWmicCsv(csv, 100)).toBe(165000);
84
+ });
85
+ it("returns null on malformed input", () => {
86
+ expect(sumSubtreeRssFromWmicCsv("garbage\r\n", 100)).toBeNull();
87
+ });
88
+ });
@@ -0,0 +1,129 @@
1
+ /**
2
+ * LSP integration test — exercises the FULL stack (spawn → handshake → didOpen →
3
+ * query) against a REAL `typescript-language-server` if one is resolvable on
4
+ * PATH. When no server is installed (e.g. CI without the toolchain) the whole
5
+ * suite SKIPS visibly rather than passing hollowly ("不假绿" — no cosmetic green).
6
+ *
7
+ * To run it locally: `npm i -g typescript-language-server typescript` (or put a
8
+ * project-local one on PATH), then `npx vitest run code-intelligence.integration`.
9
+ */
10
+
11
+ import { describe, it, expect, beforeAll, afterAll } from "vitest";
12
+ import os from "os";
13
+ import fs from "fs";
14
+ import path from "path";
15
+ import { resolveBin } from "../lsp-server-registry.js";
16
+ import { CodeIntelligence } from "../code-intelligence.js";
17
+
18
+ const serverAvailable = Boolean(resolveBin("typescript-language-server"));
19
+ const suite = serverAvailable ? describe : describe.skip;
20
+
21
+ if (!serverAvailable) {
22
+ // Make the skip reason obvious in test output.
23
+ // eslint-disable-next-line no-console
24
+ console.warn(
25
+ "[lsp.integration] SKIP — no `typescript-language-server` on PATH. " +
26
+ "Install it to run real LSP integration coverage.",
27
+ );
28
+ }
29
+
30
+ suite("CodeIntelligence against a real typescript-language-server", () => {
31
+ let tmp;
32
+ let ci;
33
+
34
+ beforeAll(() => {
35
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), "cc-lsp-it-"));
36
+ fs.mkdirSync(path.join(tmp, "src"));
37
+ fs.writeFileSync(
38
+ path.join(tmp, "package.json"),
39
+ JSON.stringify({ name: "lsp-it", version: "1.0.0", private: true }),
40
+ "utf8",
41
+ );
42
+ fs.writeFileSync(
43
+ path.join(tmp, "tsconfig.json"),
44
+ JSON.stringify({
45
+ compilerOptions: {
46
+ strict: true,
47
+ target: "ES2020",
48
+ module: "ESNext",
49
+ moduleResolution: "node",
50
+ },
51
+ include: ["src"],
52
+ }),
53
+ "utf8",
54
+ );
55
+ fs.writeFileSync(
56
+ path.join(tmp, "src", "math.ts"),
57
+ "export function add(a: number, b: number): number {\n return a + b;\n}\n",
58
+ "utf8",
59
+ );
60
+ fs.writeFileSync(
61
+ path.join(tmp, "src", "main.ts"),
62
+ 'import { add } from "./math";\n\nconst total = add(1, 2);\nconsole.log(total);\nconst bad: number = notDeclared;\n',
63
+ "utf8",
64
+ );
65
+ ci = new CodeIntelligence({ projectRoot: tmp, coldStart: true });
66
+ });
67
+
68
+ afterAll(async () => {
69
+ if (ci) await ci.dispose();
70
+ try {
71
+ fs.rmSync(tmp, { recursive: true, force: true });
72
+ } catch {
73
+ /* best effort */
74
+ }
75
+ });
76
+
77
+ it("resolves a cross-file definition", async () => {
78
+ // `add` usage in main.ts (line 3, col 15) → declaration in math.ts
79
+ const res = await ci.definition(path.join(tmp, "src", "main.ts"), 3, 15);
80
+ expect(res.available).toBe(true);
81
+ expect(res.locations.length).toBeGreaterThan(0);
82
+ expect(res.locations.some((l) => l.file.endsWith("math.ts"))).toBe(true);
83
+ }, 30000);
84
+
85
+ it("finds all references to a symbol across files", async () => {
86
+ // `add` declaration in math.ts (line 1, col 17)
87
+ const res = await ci.references(path.join(tmp, "src", "math.ts"), 1, 17);
88
+ expect(res.available).toBe(true);
89
+ // declaration + import + call site
90
+ expect(res.locations.length).toBeGreaterThanOrEqual(2);
91
+ expect(res.locations.some((l) => l.file.endsWith("main.ts"))).toBe(true);
92
+ }, 30000);
93
+
94
+ it("reports diagnostics for an undefined name", async () => {
95
+ const res = await ci.diagnostics(path.join(tmp, "src", "main.ts"), {
96
+ timeoutMs: 8000,
97
+ });
98
+ expect(res.available).toBe(true);
99
+ expect(res.diagnostics.some((d) => /notDeclared/.test(d.message))).toBe(
100
+ true,
101
+ );
102
+ const err = res.diagnostics.find((d) => d.severity === "error");
103
+ expect(err).toBeTruthy();
104
+ }, 30000);
105
+
106
+ it("lists document symbols", async () => {
107
+ const res = await ci.documentSymbols(path.join(tmp, "src", "math.ts"));
108
+ expect(res.available).toBe(true);
109
+ expect(
110
+ res.symbols.some((s) => s.name === "add" && s.kind === "function"),
111
+ ).toBe(true);
112
+ }, 30000);
113
+
114
+ it("previews a rename without mutating files", async () => {
115
+ const before = fs.readFileSync(path.join(tmp, "src", "math.ts"), "utf8");
116
+ const res = await ci.renamePreview(
117
+ path.join(tmp, "src", "math.ts"),
118
+ 1,
119
+ 17,
120
+ "sum",
121
+ );
122
+ expect(res.available).toBe(true);
123
+ expect(res.edits.length).toBeGreaterThan(0);
124
+ // preview only — the file on disk is unchanged
125
+ expect(fs.readFileSync(path.join(tmp, "src", "math.ts"), "utf8")).toBe(
126
+ before,
127
+ );
128
+ }, 30000);
129
+ });
@@ -0,0 +1,228 @@
1
+ /**
2
+ * CodeIntelligence tests — result normalization + graceful degradation. Injects
3
+ * a fake LSPManager so no server runs; asserts that raw LSP shapes (Location vs
4
+ * LocationLink, DocumentSymbol vs SymbolInformation, WorkspaceEdit variants) are
5
+ * flattened to 1-based `{file,line,col}` and that "no server" degrades cleanly.
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
9
+ import { CodeIntelligence, _deps } from "../code-intelligence.js";
10
+
11
+ /** Fake manager: canned request results, or an "unavailable" verdict. */
12
+ function fakeManager({ requestResult, unavailable, diagnostics } = {}) {
13
+ const client = {
14
+ request: async () => requestResult,
15
+ running: true,
16
+ };
17
+ return {
18
+ projectRoot: "/proj",
19
+ async ensureFor() {
20
+ if (unavailable) return { unavailable: true, reason: unavailable };
21
+ return {
22
+ client,
23
+ uri: "file:///proj/a.ts",
24
+ languageId: "typescript",
25
+ root: "/proj",
26
+ };
27
+ },
28
+ async didChangeFile() {
29
+ return this.ensureFor();
30
+ },
31
+ async waitForDiagnostics() {
32
+ return diagnostics || [];
33
+ },
34
+ async disposeAll() {},
35
+ };
36
+ }
37
+
38
+ let origRead;
39
+ beforeEach(() => {
40
+ origRead = _deps.readFileSync;
41
+ _deps.readFileSync = () => "const foo = 1;\nfoo();\n";
42
+ });
43
+ afterEach(() => {
44
+ _deps.readFileSync = origRead;
45
+ });
46
+
47
+ describe("definition/references normalization", () => {
48
+ it("normalizes a plain Location to 1-based with a snippet", async () => {
49
+ const mgr = fakeManager({
50
+ requestResult: [
51
+ {
52
+ uri: "file:///proj/a.ts",
53
+ range: {
54
+ start: { line: 0, character: 6 },
55
+ end: { line: 0, character: 9 },
56
+ },
57
+ },
58
+ ],
59
+ });
60
+ const ci = new CodeIntelligence({ manager: mgr });
61
+ const res = await ci.definition("a.ts", 2, 1);
62
+ expect(res.available).toBe(true);
63
+ expect(res.locations[0]).toMatchObject({
64
+ file: expect.stringContaining("a.ts"),
65
+ line: 1, // 0 → 1
66
+ col: 7, // 6 → 7
67
+ endLine: 1,
68
+ endCol: 10,
69
+ });
70
+ expect(res.locations[0].snippet).toBe("const foo = 1;");
71
+ });
72
+
73
+ it("normalizes a LocationLink (targetUri/targetRange)", async () => {
74
+ const mgr = fakeManager({
75
+ requestResult: [
76
+ {
77
+ targetUri: "file:///proj/b.ts",
78
+ targetSelectionRange: {
79
+ start: { line: 4, character: 2 },
80
+ end: { line: 4, character: 5 },
81
+ },
82
+ },
83
+ ],
84
+ });
85
+ const ci = new CodeIntelligence({ manager: mgr });
86
+ const res = await ci.definition("a.ts", 2, 1);
87
+ expect(res.locations[0]).toMatchObject({ line: 5, col: 3 });
88
+ expect(res.locations[0].file).toContain("b.ts");
89
+ });
90
+ });
91
+
92
+ describe("graceful degradation", () => {
93
+ it("returns available:false with a reason when no server is installed", async () => {
94
+ const mgr = fakeManager({
95
+ unavailable: "no language server installed for typescript",
96
+ });
97
+ const ci = new CodeIntelligence({ manager: mgr });
98
+ const res = await ci.definition("a.ts", 1, 1);
99
+ expect(res).toEqual({
100
+ available: false,
101
+ reason: "no language server installed for typescript",
102
+ });
103
+ });
104
+ });
105
+
106
+ describe("document symbols", () => {
107
+ it("flattens hierarchical DocumentSymbols with container names", async () => {
108
+ const mgr = fakeManager({
109
+ requestResult: [
110
+ {
111
+ name: "MyClass",
112
+ kind: 5, // class
113
+ selectionRange: {
114
+ start: { line: 0, character: 6 },
115
+ end: { line: 0, character: 13 },
116
+ },
117
+ children: [
118
+ {
119
+ name: "method1",
120
+ kind: 6,
121
+ selectionRange: {
122
+ start: { line: 1, character: 2 },
123
+ end: { line: 1, character: 9 },
124
+ },
125
+ },
126
+ ],
127
+ },
128
+ ],
129
+ });
130
+ const ci = new CodeIntelligence({ manager: mgr });
131
+ const res = await ci.documentSymbols("a.ts");
132
+ expect(res.symbols).toHaveLength(2);
133
+ expect(res.symbols[0]).toMatchObject({
134
+ name: "MyClass",
135
+ kind: "class",
136
+ line: 1,
137
+ });
138
+ expect(res.symbols[1]).toMatchObject({
139
+ name: "method1",
140
+ kind: "method",
141
+ container: "MyClass",
142
+ line: 2,
143
+ });
144
+ });
145
+ });
146
+
147
+ describe("diagnostics", () => {
148
+ it("normalizes severity and position", async () => {
149
+ const mgr = fakeManager({
150
+ diagnostics: [
151
+ {
152
+ severity: 1,
153
+ message: "Cannot find name 'x'.",
154
+ range: {
155
+ start: { line: 3, character: 4 },
156
+ end: { line: 3, character: 5 },
157
+ },
158
+ code: 2304,
159
+ source: "ts",
160
+ },
161
+ ],
162
+ });
163
+ const ci = new CodeIntelligence({ manager: mgr });
164
+ const res = await ci.diagnostics("a.ts");
165
+ expect(res.diagnostics[0]).toMatchObject({
166
+ severity: "error",
167
+ message: "Cannot find name 'x'.",
168
+ line: 4,
169
+ col: 5,
170
+ code: "2304",
171
+ source: "ts",
172
+ });
173
+ });
174
+ });
175
+
176
+ describe("rename preview", () => {
177
+ it("flattens WorkspaceEdit.changes without applying", async () => {
178
+ const mgr = fakeManager({
179
+ requestResult: {
180
+ changes: {
181
+ "file:///proj/a.ts": [
182
+ {
183
+ range: {
184
+ start: { line: 0, character: 6 },
185
+ end: { line: 0, character: 9 },
186
+ },
187
+ newText: "bar",
188
+ },
189
+ ],
190
+ },
191
+ },
192
+ });
193
+ const ci = new CodeIntelligence({ manager: mgr });
194
+ const res = await ci.renamePreview("a.ts", 1, 7, "bar");
195
+ expect(res.edits).toHaveLength(1);
196
+ expect(res.edits[0].file).toContain("a.ts");
197
+ expect(res.edits[0].edits[0]).toMatchObject({
198
+ line: 1,
199
+ col: 7,
200
+ newText: "bar",
201
+ });
202
+ });
203
+
204
+ it("flattens WorkspaceEdit.documentChanges", async () => {
205
+ const mgr = fakeManager({
206
+ requestResult: {
207
+ documentChanges: [
208
+ {
209
+ textDocument: { uri: "file:///proj/c.ts", version: 2 },
210
+ edits: [
211
+ {
212
+ range: {
213
+ start: { line: 9, character: 0 },
214
+ end: { line: 9, character: 3 },
215
+ },
216
+ newText: "baz",
217
+ },
218
+ ],
219
+ },
220
+ ],
221
+ },
222
+ });
223
+ const ci = new CodeIntelligence({ manager: mgr });
224
+ const res = await ci.renamePreview("a.ts", 1, 1, "baz");
225
+ expect(res.edits[0].file).toContain("c.ts");
226
+ expect(res.edits[0].edits[0]).toMatchObject({ line: 10, newText: "baz" });
227
+ });
228
+ });