chainlesschain 0.162.174 → 0.162.176

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 (281) hide show
  1. package/package.json +10 -10
  2. package/src/assets/web-panel/assets/{AIOps-Dcl-X1Hw.js → AIOps-BDLu5Elz.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-ClMh9HzT.js → ActionButton-DH5us-CK.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DPj0rSQ5.js → Analytics-BZ0u8IFG.js} +3 -3
  5. package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +9 -0
  6. package/src/assets/web-panel/assets/{Artifacts-L8781rE8.js → Artifacts-Br2YBbh_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CffB6WIP.js → Audit-C3C6a482.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-BkLhayyY.js → BackgroundAgents-CzHvebcj.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BQnwFI78.js → Backup-DZNHYDFd.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-xuUGHQch.js → BaseInput-VRiC4fIx.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-feQXwWrg.js → Chat-Cm08WWAD.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-CGHYrugQ.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-DVaIiUGW.js → Checkbox-DtByk7d7.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-D2kEnzeU.js → Codegen-CphXXOfD.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-azDoyusS.js → Col-Hz86TnLR.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-OZdnPWM5.js → Community-HP03ltpD.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-VDMvBN-C.js → Compact-B_N1mqQz.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CPJ_zgQ1.js → Compliance-CVztRpi8.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-iRBwcsOA.js → Cowork-wUVOyZih.js} +4 -4
  20. package/src/assets/web-panel/assets/{Cron-DrxrspUz.js → Cron-DW5TLJKw.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-D-rkAZXF.js → Crosschain-CrAFGhWH.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-5Pp1Xnmr.js → DID-pA-oD8ke.js} +2 -2
  23. package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +3 -0
  24. package/src/assets/web-panel/assets/{Dropdown-BWj_E0Ie.js → Dropdown-EweJcsek.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-BT-wgSEh.js → EmailListRenderer-C9xVLPG4.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-1PzH23pa.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BxMIXGC6.js → Federation-DtZda9A_.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CyJobBln.js → FormItemContext-CiYdcVz3.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-YkjFuQTN.js → GenericCardRenderer-DA13uwA0.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-C2a98Wp_.js → Git-DzRhZD1O.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-DKL3Fl84.js → Governance-D5RMgOSb.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BJ2cQC_3.js → Inference-BgrPfSNk.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DBAsOngt.js → KnowledgeGraph-DzjnD571.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-COt8g9LO.js → Logs-BhWzVDtN.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-3Lfht1Fd.js → MarkdownRenderer-BDape9cx.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-C9Zk9Pb2.js → Marketplace-DJtL5GV7.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-DDWDFWPO.js → McpTools-CZcQygI7.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-BRmVye_o.js → Memory-DUWSDUUu.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-CppBbWpD.js → MobileBridge-BTwq2WKY.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-CcWpeGa6.js → Mtc-BiGugEQm.js} +6 -6
  42. package/src/assets/web-panel/assets/{MtcAudit-BcllEq0K.js → MtcAudit-DY7a6gUe.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-BFD1CarL.js → Multisig-BQbDu_w7.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-QNXXYvjz.js → NLProgramming-CM2wXTLv.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-07YwgQVy.js → Notes-DI6gGs1v.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-bOccEInE.js → NotificationSettings-BsZOLWAB.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DlRi29WL.js → OrderTableRenderer-C48mu09U.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-CBaezzEr.js → Organization-Cds0_tXr.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Bl5NohFO.js → Overflow-WunYMD87.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CLMal9Aw.js → P2P-Bo6j4DDv.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CGO0NITk.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-CPSw48E2.js → Permissions-EMvMMC8N.js} +3 -3
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CDM5n134.js → PersonalDataHub-AX3ypUDV.js} +2 -2
  54. package/src/assets/web-panel/assets/{Pipeline-BdsqG7WV.js → Pipeline-BOx8HOgL.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-B6L4E-M7.js → Privacy-tBeTVQVM.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-DXPyZKRs.js → ProjectInit-CVYg1W4M.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-BrCC3xYT.js → ProjectSettings-Dvt5I7y1.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BYmuHC2q.js → Projects-Cc7FC9-e.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-CbCe2eUl.js → Providers-Ct8xqY-E.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-DkukgCrR.js → QrScannerModal-Cni8Ooja.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-D-htOrV8.js → QuickAsk-BJVLKdxr.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Bm7SIfzu.js → Recommend-DPG8Rbbm.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C9rP-iMc.js → RemoteSession-DsdR7dCt.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-kGlUgbsl.js → Reputation-Csg1YM-b.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-PBupbbUA.js → Row-D9DoFoEf.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-njlwKUGK.js → RssFeed-BsvKrXMS.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-DLdEmgBw.js → Search-DFUStfgQ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-SXGPSHdu.js → Security-ILg1zxdK.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-CuFGnNsb.js → Services-Dd41PCaY.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-CtUC0mDa.js → Skeleton-Bzo1cN80.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-P1qgOVFn.js → Skills-BDHh17P0.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-CsppE8YV.js → Sla-jl7UTiRY.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-Cq1oG56m.js → SpeechSettings-BePa-RF6.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DdKW6V-C.js → SyncSettings-DiqqDKGZ.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-BCc9san5.js → Tasks-DYQ_6lxj.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-CcHC1dMA.js → Templates-JiDeI06L.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-CA4PqU22.js → Tenant-hhgI6zwS.js} +1 -1
  78. package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DHWTSvOy.js → TimelineRenderer-B8uB5Llk.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-Ddz-P_yh.js → Tokens-C3b_6r2z.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-ePmrmLZ1.js → Trigger-tIP7HKVe.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DmuK1CCE.js → Trust-vjoc11vJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CqqBuRrT.js → UkeySign-DUPBnGuH.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-BGlR3uWM.js → VideoEditing-CBvhUY5T.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-Ba_Qx6Ga.js → Wallet-DUaQ0uA5.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-29neXKt2.js → WebAuthn-DllSivjE.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-lD0lR0UQ.js → WorkflowEditor-xc8D3uO6.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-B3stH01u.js → chat-BVicU7oA.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-Czly56MN.js → colors-DJzLmhLm.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-C0TkbkAJ.js → compact-item-BvYRfThE.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BJmpSlf1.js → createContext-DGXxCBKR.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-D1q-zw7u.js → hasIn-SBDJB1y4.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DV-twjNO.js → index-1SdDS6lR.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-B-kTvMq7.js → index-9gdI7uUW.js} +1 -1
  96. package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
  97. package/src/assets/web-panel/assets/{index-Bm_-RKal.js → index-BJZf9DhV.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CQftlZn-.js → index-BO1itZaY.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-Dw3L_smW.js → index-BTrBGBJs.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-C7sFKQ53.js → index-BYqz4Wrr.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DlvsSuBC.js → index-Bf-ctERC.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-ChESIe5r.js → index-CKyEivf8.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DaqEHaCg.js → index-CdGY9P8a.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DZeoKL6t.js → index-Cf-O_g_8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-XWV8JWMc.js → index-CloCgBUR.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CpMIdPJ0.js → index-CoJAO1Lm.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CgS8XUBU.js → index-Crk5NTb0.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DmUta2lw.js → index-Cs2rmLFt.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Dpz_7sf-.js → index-CtwqO5qo.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DRcQsPez.js → index-D7HimK0M.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BEt2-3x5.js → index-DCdRAgjy.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CHvPlzWJ.js → index-DCqRS6da.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BDHXx65P.js → index-DHVLJ8q0.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-K4YaPDOn.js → index-DKrvvWm4.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C1pOqU7D.js → index-DMarmfrv.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DAhrn9EJ.js → index-DRfiXB_p.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-cPjWjvmW.js → index-Dm_77jgR.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-C27TnOoT.js → index-DnjPdvR6.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-upY9rkGZ.js → index-DonCnfMr.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CbvNJUwu.js → index-DvUTDYXX.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BVwJ3jht.js → index-FxZzRyE1.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DIF6XHIi.js → index-MjC4G09d.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-B8KqsomG.js → index-VMfwIH5G.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-8GKykbS4.js → index-YJkzy8ZF.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DpGs96FC.js → index-d5BVd-cL.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DO8xOwxi.js → index-e4fXH_WO.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Cu_4HaUS.js → index-hxTODbM1.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Cf7Gr3NG.js → index-lpaGoTH3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DBqAm8es.js → index-wcCL-miV.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-ZDUhX41Z.js → index-xfluRkCT.js} +1 -1
  131. package/src/assets/web-panel/assets/index-ycwAfC-i.js +1 -0
  132. package/src/assets/web-panel/assets/{index-z8ATo2aQ.js → index-z1ZylsLq.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-QWEXi6-t.js → initDefaultProps-C1zO1KnY.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BfrQwvV1.js → motion-CWLtEGmC.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-Dn7x0H9t.js → move-DzD_C3Vm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-F61D_TgE.js → mtc-parser-D880PYJl.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-4SQZ39PF.js → omit-CFR_z2ov.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-C7DTe126.js → pickAttrs-srIhgrSC.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-40NeyzDK.js → placementArrow-C1rXpibP.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BiUJ6qWs.js → responsiveObserve-C30gRcSS.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-CacJTM3f.js → slide-CvtKiMfV.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-K812HB-k.js → statusUtils-DNHO7ITG.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-CKeHA2eM.js → styleChecker-Dt_Sl-g4.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-CKl4FqXF.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DPoiJjSZ.js → useFs-Baxglj2V.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-aHwBspmt.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DrA-GuCT.js → vnode-mIRkdT7o.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-G3LMswgy.js → zoom-HzI5DlH_.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/auth/npm-auth.js +30 -5
  151. package/src/commands/agenda.js +64 -2
  152. package/src/commands/agent.js +45 -3
  153. package/src/commands/background-session.js +103 -0
  154. package/src/commands/config.js +70 -5
  155. package/src/commands/context.js +36 -2
  156. package/src/commands/hub.js +19 -1
  157. package/src/commands/memory.js +21 -6
  158. package/src/commands/permissions.js +57 -1
  159. package/src/commands/plugin.js +2 -0
  160. package/src/commands/review.js +23 -11
  161. package/src/commands/routine.js +31 -8
  162. package/src/commands/session.js +11 -3
  163. package/src/commands/team.js +20 -7
  164. package/src/commands/update.js +65 -10
  165. package/src/esm-bridge.js +3 -0
  166. package/src/gateways/terminal/PtyManager.js +8 -1
  167. package/src/gateways/ws/message-dispatcher.js +3 -0
  168. package/src/gateways/ws/session-protocol.js +26 -0
  169. package/src/gateways/ws/ws-agent-handler.js +107 -69
  170. package/src/gateways/ws/ws-server.js +92 -4
  171. package/src/harness/jsonl-session-store.js +13 -6
  172. package/src/harness/mcp-client.js +200 -1
  173. package/src/index.js +123 -55
  174. package/src/lazy-dispatch.js +86 -85
  175. package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
  176. package/src/lib/agent-coordinator.js +4 -0
  177. package/src/lib/agent-ipc-bus.js +32 -2
  178. package/src/lib/agent-sandbox.js +16 -2
  179. package/src/lib/agent-schedule-store.js +55 -0
  180. package/src/lib/agent-tool-admission.js +104 -0
  181. package/src/lib/api-key-helper.js +10 -2
  182. package/src/lib/async-hook-supervisor.cjs +26 -4
  183. package/src/lib/background-interaction-resolver.js +71 -0
  184. package/src/lib/background-session-transport.js +59 -1
  185. package/src/lib/changelog.js +19 -11
  186. package/src/lib/channels/channel-manager.js +6 -0
  187. package/src/lib/channels/telegram-channel.js +11 -1
  188. package/src/lib/channels/webhook-channel.js +15 -3
  189. package/src/lib/checkpoint-store.js +10 -2
  190. package/src/lib/cloud/bundle.js +12 -2
  191. package/src/lib/code-review.js +32 -8
  192. package/src/lib/computer-use/control-backend.js +18 -3
  193. package/src/lib/context-breakdown.js +46 -0
  194. package/src/lib/context-source-ledger.js +43 -0
  195. package/src/lib/crash-reporter.js +6 -0
  196. package/src/lib/diff-review-follow-up.js +154 -0
  197. package/src/lib/downloader.js +17 -3
  198. package/src/lib/ensure-utf8.js +11 -3
  199. package/src/lib/event-runtime-producer.js +58 -0
  200. package/src/lib/event-runtime-store.js +354 -0
  201. package/src/lib/event-runtime-worker.js +109 -0
  202. package/src/lib/execution-backend.js +72 -21
  203. package/src/lib/git-integration.js +19 -4
  204. package/src/lib/hook-manager.js +34 -15
  205. package/src/lib/hook-runner.cjs +48 -3
  206. package/src/lib/hooks-v2-producers.js +15 -0
  207. package/src/lib/hooks-v2-runtime.js +70 -21
  208. package/src/lib/host-adb-bridge.js +111 -21
  209. package/src/lib/ide-context.js +128 -1
  210. package/src/lib/interaction-adapter.js +39 -0
  211. package/src/lib/ipc-attach-protocol.js +98 -0
  212. package/src/lib/json-schema-validate.js +190 -36
  213. package/src/lib/lan-pairing-preflight.js +13 -2
  214. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
  215. package/src/lib/lsp/lsp-client.js +18 -1
  216. package/src/lib/lsp/lsp-manager.js +4 -0
  217. package/src/lib/lsp/lsp-server-registry.js +11 -0
  218. package/src/lib/mcp-oauth.js +8 -2
  219. package/src/lib/npm-invocation.js +29 -0
  220. package/src/lib/packer/pkg-runner.js +13 -2
  221. package/src/lib/packer/precheck.js +33 -16
  222. package/src/lib/packer/web-panel-builder.js +16 -2
  223. package/src/lib/permission-rules.cjs +5 -1
  224. package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
  225. package/src/lib/personal-data-hub-wiring.js +27 -3
  226. package/src/lib/plan-mode.js +204 -11
  227. package/src/lib/plugin-monitor-supervisor.js +39 -4
  228. package/src/lib/plugin-runtime/bin.js +45 -0
  229. package/src/lib/plugin-runtime/hooks.js +14 -1
  230. package/src/lib/plugin-runtime/install.js +2 -1
  231. package/src/lib/plugin-runtime/lsp.js +3 -0
  232. package/src/lib/plugin-runtime/mcp.js +8 -1
  233. package/src/lib/plugin-runtime/monitors.js +4 -0
  234. package/src/lib/plugin-runtime/plugin-options.js +74 -7
  235. package/src/lib/plugin-runtime/signature.js +45 -0
  236. package/src/lib/pr-create.js +21 -8
  237. package/src/lib/pr-link-ledger.js +15 -3
  238. package/src/lib/process-execution-broker/credential-agent.js +295 -0
  239. package/src/lib/process-execution-broker/index.js +440 -14
  240. package/src/lib/process-execution-broker/patch-child-process.js +2 -3
  241. package/src/lib/process-execution-broker/platform-sandbox.js +351 -0
  242. package/src/lib/process-manager.js +18 -3
  243. package/src/lib/provenance-api.js +6 -0
  244. package/src/lib/proxy-bootstrap.js +19 -0
  245. package/src/lib/publish-workspace.js +14 -6
  246. package/src/lib/repl-rewind.js +9 -4
  247. package/src/lib/secret-store.js +159 -0
  248. package/src/lib/service-manager.js +64 -29
  249. package/src/lib/session-hooks.js +328 -473
  250. package/src/lib/session-telemetry-middleware.js +6 -0
  251. package/src/lib/settings-hook-events.cjs +61 -1
  252. package/src/lib/settings-hooks.cjs +4 -0
  253. package/src/lib/side-effect-ledger.js +22 -0
  254. package/src/lib/sub-agent-context.js +5 -0
  255. package/src/lib/sub-agent-profiles.js +4 -0
  256. package/src/lib/trace-api.js +6 -0
  257. package/src/lib/turn-context.js +14 -8
  258. package/src/lib/unattended-action-policy.js +83 -0
  259. package/src/lib/update-notice.js +9 -45
  260. package/src/lib/with-file-lock.js +7 -0
  261. package/src/lib/ws-server.js +1 -0
  262. package/src/repl/agent-repl.js +71 -13
  263. package/src/repl/clipboard-copy.js +8 -2
  264. package/src/repl/pr-comments.js +30 -7
  265. package/src/runtime/agent-core.js +439 -87
  266. package/src/runtime/agent-runtime.js +1 -0
  267. package/src/runtime/coding-agent-contract-shared.cjs +52 -0
  268. package/src/runtime/coding-agent-policy.cjs +20 -0
  269. package/src/runtime/diagnostics.js +73 -8
  270. package/src/runtime/headless-runner.js +63 -0
  271. package/src/runtime/headless-stream.js +269 -17
  272. package/src/runtime/mcp-config.js +16 -1
  273. package/src/workers/background-agent-worker.js +80 -1
  274. package/src/assets/web-panel/assets/AppLayout-7iSKDmlI.js +0 -9
  275. package/src/assets/web-panel/assets/ChatBubbleRenderer-DcbUHeGW.js +0 -1
  276. package/src/assets/web-panel/assets/Dashboard-BAKYNavw.js +0 -3
  277. package/src/assets/web-panel/assets/MobileProjects-C4GKn1dH.js +0 -1
  278. package/src/assets/web-panel/assets/Terminal-Fj7ea0In.js +0 -3
  279. package/src/assets/web-panel/assets/devWarning-CDI8Sbaj.js +0 -1
  280. package/src/assets/web-panel/assets/index-96LBR96V.js +0 -1
  281. package/src/assets/web-panel/assets/index-DyQkiW24.js +0 -1
@@ -14,6 +14,7 @@ import {
14
14
  LEGACY_TO_UNIFIED_TYPE,
15
15
  } from "../runtime/runtime-events.js";
16
16
  import { createAbortError } from "./abort-utils.js";
17
+ import { emitHooksV2Event } from "./hooks-v2-producers.js";
17
18
  import { verifyApprovalBinding } from "./agent-authority.js";
18
19
  import { createEnvelope } from "@chainlesschain/session-core";
19
20
 
@@ -245,6 +246,44 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
245
246
  this._resolvePending(requestId, answer, "question", binding);
246
247
  }
247
248
 
249
+ /**
250
+ * Ask an MCP server elicitation over the same question/answer channel.
251
+ * The schema is carried as metadata so capable IDE clients can render a
252
+ * native form; older clients still receive a bounded, ordinary question.
253
+ */
254
+ async askElicitation({
255
+ server,
256
+ requestId: mcpRequestId,
257
+ message = "MCP server requests input",
258
+ requestedSchema = null,
259
+ timeoutMs,
260
+ } = {}) {
261
+ emitHooksV2Event("MCPElicitation", {
262
+ server: server || null,
263
+ request_id: mcpRequestId ?? null,
264
+ message: String(message),
265
+ requested_schema: requestedSchema || null,
266
+ });
267
+ return this._request(
268
+ {
269
+ type: "question",
270
+ questionType: "elicitation",
271
+ question: String(message),
272
+ ...(requestedSchema ? { requestedSchema } : {}),
273
+ metadata: {
274
+ kind: "mcp_elicitation",
275
+ server: server || null,
276
+ requestId: mcpRequestId ?? null,
277
+ requestedSchema: requestedSchema || null,
278
+ },
279
+ },
280
+ {
281
+ kind: "question",
282
+ ...(Number(timeoutMs) > 0 ? { timeoutMs: Number(timeoutMs) } : {}),
283
+ },
284
+ );
285
+ }
286
+
248
287
  async requestHostTool(toolName, args = {}, extra = {}) {
249
288
  return this._request(
250
289
  {
@@ -0,0 +1,98 @@
1
+ /**
2
+ * IPC Attach Protocol — stdio 双向消息协议
3
+ *
4
+ * 用于 `cc cowork background attach <id>` 与 Background Agent Worker 子进程之间
5
+ * 传递结构化消息(提问/回答/取消/恢复),与普通 stdout/stderr 输出互不干扰。
6
+ *
7
+ * 协议格式:每一行以 `__IPC__:` 开头,后接 JSON 编码的消息体
8
+ * 换行安全:JSON 内的换行符被转义为 \x1f,回车符被转义为 \x1e
9
+ */
10
+
11
+ const IPC_PREFIX = "__IPC__:";
12
+ const NL = "\n";
13
+ const CR = "\r";
14
+ const NL_SUBST = "\x1f";
15
+ const CR_SUBST = "\x1e";
16
+
17
+ /**
18
+ * 编码一条 IPC 消息
19
+ * @param {string} type - 消息类型 (HELLO/QUESTION/ANSWER/RESUME/CANCEL/...)
20
+ * @param {object} [payload={}] - 消息负载
21
+ * @returns {string} 可直接写入 stdin/stdout 的带前缀字符串(含末尾换行)
22
+ */
23
+ function encodeIpcMessage(type, payload = {}) {
24
+ const json = JSON.stringify({ type, ...payload });
25
+ const safe = json.split(CR).join(CR_SUBST).split(NL).join(NL_SUBST);
26
+ return IPC_PREFIX + safe + NL;
27
+ }
28
+
29
+ /**
30
+ * 尝试从一行文本解析 IPC 消息
31
+ * @param {string} line - 单行文本(不含末尾换行)
32
+ * @returns {object|null} 解析出的消息对象,非 IPC 消息返回 null
33
+ */
34
+ function decodeIpcLine(line) {
35
+ if (!line || !line.startsWith(IPC_PREFIX)) return null;
36
+ const raw = line
37
+ .slice(IPC_PREFIX.length)
38
+ .split(CR_SUBST)
39
+ .join(CR)
40
+ .split(NL_SUBST)
41
+ .join(NL);
42
+ try {
43
+ return JSON.parse(raw);
44
+ } catch (_err) {
45
+ return { type: "PARSE_ERROR", raw };
46
+ }
47
+ }
48
+
49
+ /**
50
+ * 从文本流中提取所有完整 IPC 消息,并返回剩余的未完成片段
51
+ * @param {string} buffer - 累积的文本缓冲区
52
+ * @returns {{ messages: Array<object>, rest: string }}
53
+ */
54
+ function parseIpcBuffer(buffer) {
55
+ const messages = [];
56
+ const lines = buffer.split(NL);
57
+ const rest = lines.pop() || "";
58
+ for (const line of lines) {
59
+ const msg = decodeIpcLine(line);
60
+ if (msg) messages.push(msg);
61
+ }
62
+ return { messages, rest };
63
+ }
64
+
65
+ /**
66
+ * 将答案值标准化为字符串(兼容文本/对象/选项序号)
67
+ * @param {*} value - 用户输入的原始答案
68
+ * @param {object} [question] - 原问题对象(用于解析选项序号)
69
+ * @returns {string}
70
+ */
71
+ function normalizeAnswer(value, question = null) {
72
+ if (value === null || value === undefined) return "";
73
+ if (typeof value === "string") {
74
+ const s = value.trim();
75
+ if (
76
+ question &&
77
+ Array.isArray(question.options) &&
78
+ question.options.length > 0
79
+ ) {
80
+ const num = Number(s);
81
+ if (Number.isInteger(num) && num >= 1 && num <= question.options.length) {
82
+ return String(
83
+ question.options[num - 1].value ?? question.options[num - 1],
84
+ );
85
+ }
86
+ }
87
+ return s;
88
+ }
89
+ return JSON.stringify(value);
90
+ }
91
+
92
+ export {
93
+ IPC_PREFIX,
94
+ encodeIpcMessage,
95
+ decodeIpcLine,
96
+ parseIpcBuffer,
97
+ normalizeAnswer,
98
+ };
@@ -173,9 +173,7 @@ export function computeSchemaDigest(schema) {
173
173
  }
174
174
 
175
175
  /** Resolve a local `#/...` JSON Pointer $ref within `root`; null if unresolved. */
176
- function resolveRef(root, ref) {
177
- if (typeof ref !== "string" || !ref.startsWith("#")) return null;
178
- const frag = ref.slice(1);
176
+ function resolvePointer(root, frag) {
179
177
  if (frag === "" || frag === "/") return root;
180
178
  const parts = frag
181
179
  .replace(/^\//, "")
@@ -189,15 +187,56 @@ function resolveRef(root, ref) {
189
187
  return cur === undefined ? null : cur;
190
188
  }
191
189
 
190
+ function findAnchor(root, anchor, seen = new Set()) {
191
+ if (!root || typeof root !== "object" || seen.has(root)) return null;
192
+ seen.add(root);
193
+ if (root.$anchor === anchor || root.$dynamicAnchor === anchor) return root;
194
+ for (const value of Object.values(root)) {
195
+ const found = findAnchor(value, anchor, seen);
196
+ if (found) return found;
197
+ }
198
+ return null;
199
+ }
200
+
201
+ /** Resolve local refs or a caller-provided external document registry. */
202
+ function resolveRef(root, ref, externalSchemas = {}) {
203
+ if (typeof ref !== "string") return null;
204
+ if (ref.startsWith("#")) {
205
+ const fragment = ref.slice(1);
206
+ if (fragment === "" || fragment.startsWith("/")) {
207
+ return resolvePointer(root, fragment);
208
+ }
209
+ try {
210
+ return findAnchor(root, decodeURIComponent(fragment), new Set());
211
+ } catch {
212
+ return findAnchor(root, fragment, new Set());
213
+ }
214
+ }
215
+ const hash = ref.indexOf("#");
216
+ const uri = hash >= 0 ? ref.slice(0, hash) : ref;
217
+ const document = externalSchemas?.[ref] ?? externalSchemas?.[uri];
218
+ if (document === undefined) return null;
219
+ if (hash < 0) return document;
220
+ const fragment = ref.slice(hash + 1);
221
+ if (fragment === "" || fragment.startsWith("/")) {
222
+ return resolvePointer(document, fragment);
223
+ }
224
+ try {
225
+ return findAnchor(document, decodeURIComponent(fragment), new Set());
226
+ } catch {
227
+ return findAnchor(document, fragment, new Set());
228
+ }
229
+ }
230
+
192
231
  // ─── instance validation ─────────────────────────────────────────────────────
193
232
 
194
233
  /**
195
234
  * Validate `value` against `schema`.
196
235
  * @returns {{valid:boolean, errors:Array<{code,keyword,instancePath,schemaPath,message}>}}
197
236
  */
198
- export function validate(value, schema) {
237
+ export function validate(value, schema, { externalSchemas = {} } = {}) {
199
238
  const errors = [];
200
- _validate(value, schema, [], [], schema, errors, 0);
239
+ _validate(value, schema, [], [], schema, errors, 0, externalSchemas);
201
240
  return { valid: errors.length === 0, errors };
202
241
  }
203
242
 
@@ -211,7 +250,7 @@ function _err(errors, keyword, instSegs, schemaSegs, message) {
211
250
  });
212
251
  }
213
252
 
214
- function _validate(value, schema, inst, sch, root, errors, depth) {
253
+ function _validate(value, schema, inst, sch, root, errors, depth, externalSchemas) {
215
254
  if (schema === true || schema === undefined) return;
216
255
  if (schema === false) {
217
256
  _err(errors, "false", inst, sch, "schema is `false` — no value is valid");
@@ -220,19 +259,25 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
220
259
  if (!schema || typeof schema !== "object") return;
221
260
  if (depth > MAX_REF_DEPTH) return; // cyclic $ref guard
222
261
 
223
- // $ref — validate against the referenced schema (local only).
224
- if (typeof schema.$ref === "string") {
225
- const target = resolveRef(root, schema.$ref);
262
+ // $ref/$dynamicRef — local pointer/anchor or explicit external registry.
263
+ const refKeyword =
264
+ typeof schema.$ref === "string"
265
+ ? "$ref"
266
+ : typeof schema.$dynamicRef === "string"
267
+ ? "$dynamicRef"
268
+ : null;
269
+ if (refKeyword) {
270
+ const target = resolveRef(root, schema[refKeyword], externalSchemas);
226
271
  if (target == null) {
227
272
  _err(
228
273
  errors,
229
- "$ref",
274
+ refKeyword,
230
275
  inst,
231
- [...sch, "$ref"],
232
- `cannot resolve $ref "${schema.$ref}"`,
276
+ [...sch, refKeyword],
277
+ `cannot resolve ${refKeyword} "${schema[refKeyword]}"`,
233
278
  );
234
279
  } else {
235
- _validate(value, target, inst, [...sch, "$ref"], root, errors, depth + 1);
280
+ _validate(value, target, inst, [...sch, refKeyword], root, errors, depth + 1, externalSchemas);
236
281
  }
237
282
  // sibling keywords still apply in 2020-12; fall through.
238
283
  }
@@ -282,12 +327,12 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
282
327
  if (t === "number" || t === "integer")
283
328
  _validateNumber(value, schema, inst, sch, errors);
284
329
  if (t === "array")
285
- _validateArray(value, schema, inst, sch, root, errors, depth);
330
+ _validateArray(value, schema, inst, sch, root, errors, depth, externalSchemas);
286
331
  if (t === "object")
287
- _validateObject(value, schema, inst, sch, root, errors, depth);
332
+ _validateObject(value, schema, inst, sch, root, errors, depth, externalSchemas);
288
333
 
289
- _validateCombinators(value, schema, inst, sch, root, errors, depth);
290
- _validateConditional(value, schema, inst, sch, root, errors, depth);
334
+ _validateCombinators(value, schema, inst, sch, root, errors, depth, externalSchemas);
335
+ _validateConditional(value, schema, inst, sch, root, errors, depth, externalSchemas);
291
336
  }
292
337
 
293
338
  /**
@@ -295,9 +340,9 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
295
340
  * own errors are never reported; if the value matches `if`, `then` applies,
296
341
  * otherwise `else` applies. No `if` keyword ⇒ then/else are inert.
297
342
  */
298
- function _validateConditional(value, schema, inst, sch, root, errors, depth) {
343
+ function _validateConditional(value, schema, inst, sch, root, errors, depth, externalSchemas) {
299
344
  if (schema.if === undefined) return;
300
- const matched = _branchValid(value, schema.if, root, depth);
345
+ const matched = _branchValid(value, schema.if, root, depth, externalSchemas);
301
346
  if (matched) {
302
347
  if (schema.then !== undefined) {
303
348
  _validate(
@@ -308,10 +353,11 @@ function _validateConditional(value, schema, inst, sch, root, errors, depth) {
308
353
  root,
309
354
  errors,
310
355
  depth,
356
+ externalSchemas,
311
357
  );
312
358
  }
313
359
  } else if (schema.else !== undefined) {
314
- _validate(value, schema.else, inst, [...sch, "else"], root, errors, depth);
360
+ _validate(value, schema.else, inst, [...sch, "else"], root, errors, depth, externalSchemas);
315
361
  }
316
362
  }
317
363
 
@@ -423,7 +469,7 @@ function _validateNumber(value, schema, inst, sch, errors) {
423
469
  }
424
470
  }
425
471
 
426
- function _validateArray(value, schema, inst, sch, root, errors, depth) {
472
+ function _validateArray(value, schema, inst, sch, root, errors, depth, externalSchemas) {
427
473
  if (Number.isFinite(schema.minItems) && value.length < schema.minItems) {
428
474
  _err(
429
475
  errors,
@@ -460,6 +506,24 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
460
506
  }
461
507
  }
462
508
  const prefix = Array.isArray(schema.prefixItems) ? schema.prefixItems : [];
509
+ if (schema.contains !== undefined) {
510
+ const matches = value.reduce(
511
+ (count, item, i) =>
512
+ count + (_branchValid(item, schema.contains, root, depth, externalSchemas) ? 1 : 0),
513
+ 0,
514
+ );
515
+ const min = Number.isFinite(schema.minContains) ? schema.minContains : 1;
516
+ const max = Number.isFinite(schema.maxContains) ? schema.maxContains : Infinity;
517
+ if (matches < min || matches > max) {
518
+ _err(
519
+ errors,
520
+ "contains",
521
+ inst,
522
+ [...sch, "contains"],
523
+ `array contains ${matches} matching item(s), expected ${min}${max === Infinity ? "+" : `..${max}`}`,
524
+ );
525
+ }
526
+ }
463
527
  value.forEach((item, i) => {
464
528
  if (i < prefix.length) {
465
529
  _validate(
@@ -470,6 +534,7 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
470
534
  root,
471
535
  errors,
472
536
  depth,
537
+ externalSchemas,
473
538
  );
474
539
  } else if (schema.items !== undefined) {
475
540
  _validate(
@@ -480,12 +545,13 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
480
545
  root,
481
546
  errors,
482
547
  depth,
548
+ externalSchemas,
483
549
  );
484
550
  }
485
551
  });
486
552
  }
487
553
 
488
- function _validateObject(value, schema, inst, sch, root, errors, depth) {
554
+ function _validateObject(value, schema, inst, sch, root, errors, depth, externalSchemas) {
489
555
  const keys = Object.keys(value);
490
556
  if (
491
557
  Number.isFinite(schema.minProperties) &&
@@ -523,6 +589,10 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
523
589
  }
524
590
  }
525
591
  const props = schema.properties || {};
592
+ const patterns = schema.patternProperties || {};
593
+ const patternEntries = Object.entries(patterns).map(([pattern, sub]) => {
594
+ try { return [new RegExp(pattern), pattern, sub]; } catch { return [null, pattern, sub]; }
595
+ });
526
596
  for (const [k, v] of Object.entries(value)) {
527
597
  if (Object.prototype.hasOwnProperty.call(props, k)) {
528
598
  _validate(
@@ -533,19 +603,25 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
533
603
  root,
534
604
  errors,
535
605
  depth,
606
+ externalSchemas,
536
607
  );
537
- } else if (schema.additionalProperties === false) {
608
+ } else {
609
+ const matches = patternEntries.filter(([re]) => re && re.test(k));
610
+ if (matches.length > 0) {
611
+ for (const [, pattern, sub] of matches) {
612
+ _validate(v, sub, [...inst, k], [...sch, "patternProperties", pattern], root, errors, depth, externalSchemas);
613
+ }
614
+ continue;
615
+ }
616
+ if (schema.additionalProperties === false || schema.unevaluatedProperties === false) {
538
617
  _err(
539
618
  errors,
540
- "additionalProperties",
619
+ schema.additionalProperties === false ? "additionalProperties" : "unevaluatedProperties",
541
620
  [...inst, k],
542
- [...sch, "additionalProperties"],
621
+ [...sch, schema.additionalProperties === false ? "additionalProperties" : "unevaluatedProperties"],
543
622
  `unexpected property "${k}"`,
544
623
  );
545
- } else if (
546
- schema.additionalProperties &&
547
- typeof schema.additionalProperties === "object"
548
- ) {
624
+ } else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
549
625
  _validate(
550
626
  v,
551
627
  schema.additionalProperties,
@@ -554,25 +630,49 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
554
630
  root,
555
631
  errors,
556
632
  depth,
633
+ externalSchemas,
557
634
  );
635
+ }
636
+ }
637
+ }
638
+ if (schema.propertyNames !== undefined) {
639
+ for (const key of keys) {
640
+ _validate(key, schema.propertyNames, [...inst, key], [...sch, "propertyNames"], root, errors, depth, externalSchemas);
641
+ }
642
+ }
643
+ if (schema.dependentRequired && typeof schema.dependentRequired === "object") {
644
+ for (const [key, required] of Object.entries(schema.dependentRequired)) {
645
+ if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
646
+ for (const dep of Array.isArray(required) ? required : []) {
647
+ if (!Object.prototype.hasOwnProperty.call(value, dep)) {
648
+ _err(errors, "dependentRequired", inst, [...sch, "dependentRequired", key], `property "${key}" requires property "${dep}"`);
649
+ }
650
+ }
651
+ }
652
+ }
653
+ if (schema.dependentSchemas && typeof schema.dependentSchemas === "object") {
654
+ for (const [key, sub] of Object.entries(schema.dependentSchemas)) {
655
+ if (Object.prototype.hasOwnProperty.call(value, key)) {
656
+ _validate(value, sub, inst, [...sch, "dependentSchemas", key], root, errors, depth, externalSchemas);
657
+ }
558
658
  }
559
659
  }
560
660
  }
561
661
 
562
- function _branchValid(value, subschema, root, depth) {
662
+ function _branchValid(value, subschema, root, depth, externalSchemas) {
563
663
  const errs = [];
564
- _validate(value, subschema, [], [], root, errs, depth + 1);
664
+ _validate(value, subschema, [], [], root, errs, depth + 1, externalSchemas);
565
665
  return errs.length === 0;
566
666
  }
567
667
 
568
- function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
668
+ function _validateCombinators(value, schema, inst, sch, root, errors, depth, externalSchemas) {
569
669
  if (Array.isArray(schema.allOf)) {
570
670
  schema.allOf.forEach((s, i) => {
571
- _validate(value, s, inst, [...sch, "allOf", i], root, errors, depth);
671
+ _validate(value, s, inst, [...sch, "allOf", i], root, errors, depth, externalSchemas);
572
672
  });
573
673
  }
574
674
  if (Array.isArray(schema.anyOf)) {
575
- const ok = schema.anyOf.some((s) => _branchValid(value, s, root, depth));
675
+ const ok = schema.anyOf.some((s) => _branchValid(value, s, root, depth, externalSchemas));
576
676
  if (!ok)
577
677
  _err(
578
678
  errors,
@@ -584,7 +684,7 @@ function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
584
684
  }
585
685
  if (Array.isArray(schema.oneOf)) {
586
686
  const matches = schema.oneOf.filter((s) =>
587
- _branchValid(value, s, root, depth),
687
+ _branchValid(value, s, root, depth, externalSchemas),
588
688
  ).length;
589
689
  if (matches !== 1) {
590
690
  _err(
@@ -598,7 +698,7 @@ function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
598
698
  }
599
699
  if (
600
700
  schema.not !== undefined &&
601
- _branchValid(value, schema.not, root, depth)
701
+ _branchValid(value, schema.not, root, depth, externalSchemas)
602
702
  ) {
603
703
  _err(
604
704
  errors,
@@ -692,6 +792,8 @@ function _metaValidate(schema, segs, errors, depth) {
692
792
  "maxItems",
693
793
  "minProperties",
694
794
  "maxProperties",
795
+ "minContains",
796
+ "maxContains",
695
797
  ]) {
696
798
  if (
697
799
  schema[k] !== undefined &&
@@ -724,6 +826,28 @@ function _metaValidate(schema, segs, errors, depth) {
724
826
  if (schema.$ref !== undefined && typeof schema.$ref !== "string") {
725
827
  _metaErr(errors, "$ref", [...segs, "$ref"], "$ref must be a string");
726
828
  }
829
+ for (const k of ["$id", "$schema", "$anchor", "$dynamicAnchor", "$dynamicRef", "$comment"]) {
830
+ if (schema[k] !== undefined && typeof schema[k] !== "string") {
831
+ _metaErr(errors, k, [...segs, k], `${k} must be a string`);
832
+ }
833
+ }
834
+ if (schema.$anchor !== undefined && typeof schema.$anchor === "string" && !/^[A-Za-z][A-Za-z0-9:_-]*$/.test(schema.$anchor)) {
835
+ _metaErr(errors, "$anchor", [...segs, "$anchor"], "$anchor must match the anchor-name syntax");
836
+ }
837
+ if (schema.$dynamicAnchor !== undefined && typeof schema.$dynamicAnchor === "string" && !/^[A-Za-z][A-Za-z0-9:_-]*$/.test(schema.$dynamicAnchor)) {
838
+ _metaErr(errors, "$dynamicAnchor", [...segs, "$dynamicAnchor"], "$dynamicAnchor must match the anchor-name syntax");
839
+ }
840
+ if (schema.$vocabulary !== undefined) {
841
+ if (!schema.$vocabulary || typeof schema.$vocabulary !== "object" || Array.isArray(schema.$vocabulary)) {
842
+ _metaErr(errors, "$vocabulary", [...segs, "$vocabulary"], "$vocabulary must be an object");
843
+ } else {
844
+ for (const [uri, required] of Object.entries(schema.$vocabulary)) {
845
+ if (typeof required !== "boolean") {
846
+ _metaErr(errors, "$vocabulary", [...segs, "$vocabulary", uri], "vocabulary values must be boolean");
847
+ }
848
+ }
849
+ }
850
+ }
727
851
  if (schema.properties !== undefined) {
728
852
  if (
729
853
  typeof schema.properties !== "object" ||
@@ -741,6 +865,36 @@ function _metaValidate(schema, segs, errors, depth) {
741
865
  }
742
866
  }
743
867
  }
868
+ for (const k of ["patternProperties", "dependentSchemas"]) {
869
+ if (schema[k] === undefined) continue;
870
+ if (typeof schema[k] !== "object" || Array.isArray(schema[k])) {
871
+ _metaErr(errors, k, [...segs, k], `${k} must be an object`);
872
+ } else {
873
+ for (const [name, sub] of Object.entries(schema[k])) {
874
+ if (k === "patternProperties") {
875
+ try { new RegExp(name); } catch (e) { _metaErr(errors, k, [...segs, k, name], `invalid regex: ${e.message}`); }
876
+ }
877
+ _metaValidate(sub, [...segs, k, name], errors, depth + 1);
878
+ }
879
+ }
880
+ }
881
+ if (schema.propertyNames !== undefined) {
882
+ _metaValidate(schema.propertyNames, [...segs, "propertyNames"], errors, depth + 1);
883
+ }
884
+ if (schema.dependentRequired !== undefined) {
885
+ if (typeof schema.dependentRequired !== "object" || Array.isArray(schema.dependentRequired)) {
886
+ _metaErr(errors, "dependentRequired", [...segs, "dependentRequired"], "dependentRequired must be an object");
887
+ } else {
888
+ for (const [key, required] of Object.entries(schema.dependentRequired)) {
889
+ if (!Array.isArray(required) || required.some((v) => typeof v !== "string")) {
890
+ _metaErr(errors, "dependentRequired", [...segs, "dependentRequired", key], "dependentRequired values must be arrays of strings");
891
+ }
892
+ }
893
+ }
894
+ }
895
+ if (schema.contains !== undefined) {
896
+ _metaValidate(schema.contains, [...segs, "contains"], errors, depth + 1);
897
+ }
744
898
  if (
745
899
  schema.additionalProperties !== undefined &&
746
900
  typeof schema.additionalProperties === "object"
@@ -21,8 +21,12 @@
21
21
 
22
22
  import os from "node:os";
23
23
  import fs from "node:fs";
24
- import { execSync } from "node:child_process";
25
24
  import dgram from "node:dgram";
25
+ import executionBroker from "./process-execution-broker/index.js";
26
+
27
+ export const _deps = {
28
+ execFileSync: (...args) => executionBroker.execFileSync(...args),
29
+ };
26
30
 
27
31
  const MDNS_PORT = 5353;
28
32
  const MDNS_GROUP = "224.0.0.251";
@@ -313,7 +317,14 @@ function which(cmd) {
313
317
  try {
314
318
  const platform = os.platform();
315
319
  const probe = platform === "win32" ? "where" : "which";
316
- execSync(`${probe} ${cmd}`, { stdio: "pipe", windowsHide: true });
320
+ _deps.execFileSync(probe, [cmd], {
321
+ origin: "lan-pairing:firewall-probe",
322
+ scope: "network-diagnostics",
323
+ policy: "allow",
324
+ shell: false,
325
+ stdio: "pipe",
326
+ windowsHide: true,
327
+ });
317
328
  return true;
318
329
  } catch (_err) {
319
330
  return false;
@@ -109,6 +109,24 @@ describe("plugin server registration", () => {
109
109
  expect(s).toMatchObject({ id: "zls" });
110
110
  });
111
111
 
112
+ it("returns plugin provenance for Broker-enforced servers", () => {
113
+ registerLanguageServer({
114
+ languageId: "kotlin",
115
+ command: "kotlin-lsp",
116
+ pluginId: "p-kotlin",
117
+ pluginVersion: "1.2.3",
118
+ pluginSource: "/plugins/kotlin/.lsp.json",
119
+ });
120
+ const isWin = process.platform === "win32";
121
+ existsFor([path.join("/proj", "node_modules", ".bin", isWin ? "kotlin-lsp.cmd" : "kotlin-lsp")]);
122
+ expect(resolveServer("kotlin", "/proj")).toMatchObject({
123
+ origin: "plugin:lsp",
124
+ pluginId: "p-kotlin",
125
+ pluginVersion: "1.2.3",
126
+ pluginSource: "/plugins/kotlin/.lsp.json",
127
+ });
128
+ });
129
+
112
130
  it("rejects an incomplete registration", () => {
113
131
  expect(() => registerLanguageServer({ languageId: "x" })).toThrow(
114
132
  /requires/,
@@ -16,6 +16,7 @@
16
16
  import { spawn as nodeSpawn } from "child_process";
17
17
  import { EventEmitter } from "events";
18
18
  import { encodeMessage, MessageBuffer } from "./jsonrpc-stream.js";
19
+ import { executionBroker } from "../process-execution-broker/index.js";
19
20
 
20
21
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
21
22
  const DEFAULT_INIT_TIMEOUT_MS = 30_000;
@@ -41,6 +42,10 @@ export class LSPClient extends EventEmitter {
41
42
  this.env = opts.env || {};
42
43
  this.requestTimeoutMs = opts.requestTimeoutMs || DEFAULT_REQUEST_TIMEOUT_MS;
43
44
  this.capabilitiesOverride = opts.capabilities || null;
45
+ this.origin = opts.origin || null;
46
+ this.pluginId = opts.pluginId || null;
47
+ this.pluginVersion = opts.pluginVersion || null;
48
+ this.pluginSource = opts.pluginSource || null;
44
49
 
45
50
  this._child = null;
46
51
  this._buffer = new MessageBuffer();
@@ -73,13 +78,25 @@ export class LSPClient extends EventEmitter {
73
78
  // fix, so buildSpawnCommand rewrites them to an explicit `cmd.exe /d /s /c`
74
79
  // invocation with verbatim args — still no shell, still injection-safe.
75
80
  const spawnSpec = buildSpawnCommand(this.command, this.args);
76
- this._child = _deps.spawn(spawnSpec.file, spawnSpec.args, {
81
+ const spawnFn = String(this.origin || "").startsWith("plugin:")
82
+ ? executionBroker.spawn.bind(executionBroker)
83
+ : _deps.spawn;
84
+ this._child = spawnFn(spawnSpec.file, spawnSpec.args, {
77
85
  cwd: this.rootPath,
78
86
  env: { ...process.env, ...this.env },
79
87
  stdio: ["pipe", "pipe", "pipe"],
80
88
  shell: false,
81
89
  windowsHide: true,
82
90
  windowsVerbatimArguments: spawnSpec.windowsVerbatimArguments,
91
+ ...(this.origin
92
+ ? {
93
+ origin: this.origin,
94
+ policy: "allow",
95
+ pluginId: this.pluginId,
96
+ pluginVersion: this.pluginVersion,
97
+ pluginSource: this.pluginSource,
98
+ }
99
+ : {}),
83
100
  });
84
101
 
85
102
  this._child.on("error", (err) => {
@@ -239,6 +239,10 @@ export class LSPManager {
239
239
  command: resolved.command,
240
240
  args: resolved.args,
241
241
  rootPath: projectRoot,
242
+ origin: resolved.origin,
243
+ pluginId: resolved.pluginId,
244
+ pluginVersion: resolved.pluginVersion,
245
+ pluginSource: resolved.pluginSource,
242
246
  });
243
247
  // Collect pushed diagnostics keyed by document, tracking publish count/time
244
248
  // so callers can wait for the project to load (first publish) and settle
@@ -95,6 +95,9 @@ export function registerLanguageServer(def) {
95
95
  bins: [def.command],
96
96
  argsFor: () => (Array.isArray(def.args) ? def.args : []),
97
97
  fromPlugin: true,
98
+ pluginId: def.pluginId || null,
99
+ pluginVersion: def.pluginVersion || null,
100
+ pluginSource: def.pluginSource || null,
98
101
  };
99
102
  const existing = pluginServers.get(def.languageId) || [];
100
103
  // De-dupe by server id so re-registering the same server (e.g. a reload)
@@ -147,6 +150,14 @@ export function resolveServer(languageId, projectRoot) {
147
150
  id: def.id,
148
151
  command,
149
152
  args: def.argsFor(bin),
153
+ ...(def.fromPlugin
154
+ ? {
155
+ origin: "plugin:lsp",
156
+ pluginId: def.pluginId,
157
+ pluginVersion: def.pluginVersion,
158
+ pluginSource: def.pluginSource,
159
+ }
160
+ : {}),
150
161
  };
151
162
  }
152
163
  }