chainlesschain 0.162.175 → 0.162.177

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 (311) hide show
  1. package/package.json +10 -10
  2. package/src/assets/web-panel/assets/{AIOps-DherW0Rh.js → AIOps-DT-VPWuN.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CDGfqt2Y.js → ActionButton-DyOreOVN.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BYhkzdgD.js → Analytics-DslNsKux.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-cEKk1cpb.js → AppLayout-BNJJAYME.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-_aXR3WWc.js → Artifacts-DoaAtEcY.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CYAf-gY7.js → Audit-DPG3WdJ9.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D4Q20phR.js → BackgroundAgents-C_JO6R5G.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Cq0Tyk58.js → Backup-Cv3BooyX.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CPj_CdAv.js → BaseInput-D2uQXWu-.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BQ-Qq0es.js → Chat-B4Vczyf3.js} +4 -4
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-DE6reP99.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-rke6l3yg.js → Checkbox-qTgk4VeP.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DiacrIPq.js → Codegen-DlLWcIzj.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-Cx3BY-Up.js → Col-DNO73qp7.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DfmWiQy8.js → Community-vRDNpc4j.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DdQnpxy5.js → Compact-CEWtIXni.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-lzliOH_r.js → Compliance-KgYC9Fxi.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CYx4Un5k.js → Cowork-zj5wvkpT.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-BGDcPFlo.js → Cron-BLDoCozU.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-0_X5g2ri.js → Crosschain-BYnff4VY.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-C0PEf3Eu.js → DID-C75VFsVm.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DULQjQ58.js → Dashboard-C4Gutni2.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DGRHRbW6.js → Dropdown-B5dbO4Kx.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-ChX8XPwB.js → EmailListRenderer-BDipZtHJ.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dyq6IBNu.js → FamilyGuardDashboard-DmIzt8jj.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DH1NfAL2.js → Federation-D9QOS-uW.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BN1I_uNi.js → FormItemContext-B47HRwAm.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-Dq_2UYpe.js → GenericCardRenderer-3R4mXmgV.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BAy1yvI2.js → Git-DrNXZf1C.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-Db6Q2iSy.js → Governance-BGd7JR98.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-0ub6yHcr.js → Inference-D-2he1ed.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DtLetM36.js → KnowledgeGraph-C0sHIbK5.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Bcoy7CUd.js → Logs-DiBQO-jL.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BfEMFAXf.js → MarkdownRenderer-DL_5eV2D.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-tt2rzwRR.js → Marketplace-VR59OdrC.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-BhOgX-MU.js → McpTools-DrPzwSd3.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-BJUxeWBL.js → Memory-CBgKALwQ.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BwUY2G9w.js → MobileBridge-pQ9Tn-Mn.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BLRfHhqi.js → MobileProjects-mASB6jyj.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-B2WMboOm.js → Mtc-DTMgE7HC.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-8pNEXO63.js → MtcAudit-CwTnCtiL.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-C1wm5a_1.js → Multisig-ngm6WU8f.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-C1QpKF7g.js → NLProgramming-4YO4Qww9.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CiQUcxFu.js → Notes-DP1k45mF.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BblDPJ_x.js → NotificationSettings-r2H8yPKb.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DRjYcPtb.js → OrderTableRenderer-CoM_Zw0J.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Dp3VKB0X.js → Organization-DrO7jRWS.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Czx161m9.js → Overflow-Cnwu4i4t.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-ClFi6wOs.js → P2P-zi-cDwA_.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CRweW0lz.js → PdhVaultBrowser-DBEryDv7.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-BzcRoqTn.js → Permissions-lqXK2C3x.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-ChGTpNMd.js → PersonalDataHub-b63T3HJM.js} +2 -2
  54. package/src/assets/web-panel/assets/{Pipeline-BMOOpKWA.js → Pipeline-Kep5KAGW.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-D0AZHObH.js → Privacy-CHdvOAh1.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-yYFlZ6Ja.js → ProjectInit-BhKfdwe9.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DJNVuMQs.js → ProjectSettings-Yavk9K8A.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Br0rBWH1.js → Projects-CN8E_5Mq.js} +1 -1
  59. package/src/assets/web-panel/assets/Providers-Bfym6SQn.js +1 -0
  60. package/src/assets/web-panel/assets/{QrScannerModal-81NZOitV.js → QrScannerModal-CLSQcrlR.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Dic2lCbJ.js → QuickAsk-VPa2WKQN.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Dh9iwViE.js → Recommend-CGXR8jVU.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-Bq9VYEFy.js → RemoteSession-C_20YfMB.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CxFZ-NbJ.js → Reputation-awZh68UV.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-BVSLcaX2.js → Row-Ctb4oiYN.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-BbC-5DOH.js → RssFeed-D3sdjvUV.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-BfjZ1GCr.js → Search-C-zfA4kT.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CVjhOV5r.js → Security-D9XlmHA3.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-D45u-Aqe.js → Services-C3UKnr41.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-WkGoK4he.js → Skeleton-BQxagZfF.js} +1 -1
  71. package/src/assets/web-panel/assets/Skills-q6eb6KPZ.js +1 -0
  72. package/src/assets/web-panel/assets/{Sla-Bf4QTF3E.js → Sla-DveENvek.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DVpZdbMN.js → SpeechSettings-BFjXLNgF.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DEEojoMS.js → SyncSettings-BpHgbaP9.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-DvepRb8-.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-Bzl-9wY5.js → Templates-DEiaoyve.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-0khxUOB8.js → Tenant-ITg774nY.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-DWGYhAYU.js → Terminal-D3ZBcvnb.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-B0Y4LONc.js → TimelineRenderer-BsLU6JjU.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DEE07SFh.js → Tokens-Cb5Pquc9.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BM7xvA5z.js → Trigger-Dwfy-m9N.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-Dv3ijvvZ.js → Trust-CnlSRGG0.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B1-enmMt.js → UkeySign-Y4TlvKVo.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DYiIPByd.js → VideoEditing-BpKLtTTO.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-D-y374BQ.js → Wallet-LLBzIq8x.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-HBDjcUhi.js → WebAuthn-BeSRiusP.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-sKn4qTID.js → WorkflowEditor-BK_l1tXO.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-TVYhaBXj.js → chat-DYd-X7Wg.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DMADxY9v.js → colors-C9uip71j.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-OftcHpO_.js → compact-item-JBrfjUP6.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DW1zVUSN.js → createContext-D03fbuiq.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-B8LQ8leS.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-CaUathNp.js → hasIn-DLQOR6l-.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Cmdv6Dev.js → index-5YN7F5bO.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-iDmgT2Dg.js → index-6GuLRpBQ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-77kgkUgY.js → index-B0X76LjX.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CM8W07sc.js → index-B46YcgsV.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C9JoaYSs.js → index-BNCdRmWf.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CpDtN0dl.js → index-BYv-LWdy.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CZXYI5LU.js → index-Ba-Ps_AJ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DWVZ3T0t.js → index-BcBZwlnG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index--5UvwqH_.js → index-BdH9l8wl.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BBNg08cD.js → index-BfOs_bmg.js} +3 -3
  104. package/src/assets/web-panel/assets/index-Bh8BPtqR.js +1 -0
  105. package/src/assets/web-panel/assets/{index-s-EnkUCn.js → index-BnQgRjsm.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Lr0MO-GU.js → index-BpYKLrUT.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B-19mFhn.js → index-BuNFCZCx.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CeCIYYG7.js → index-ByHO3SqZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-hXq7QRA_.js → index-C2zmOsyD.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-8YelceUU.js → index-CChQBM1d.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B52Ztt8Q.js → index-CChaISMb.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DKjqFpYa.js → index-CILVyK3b.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DAfT3EMd.js → index-CL0ixCxk.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-sm1sGIxW.js → index-CS63r8h3.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DHi634g9.js → index-CVZWiUE_.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BEzLLVYd.js → index-Ce0Bf1YF.js} +1 -1
  117. package/src/assets/web-panel/assets/index-CeVrHLzZ.js +1 -0
  118. package/src/assets/web-panel/assets/{index-pSVCBsG4.js → index-Ck17i0OD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-GUKz4Pv9.js → index-Cpn19c9k.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CKNdnJRo.js → index-CqWk1FLG.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Bg-7FpaL.js → index-CwoDpKzW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DYwwUKDg.js → index-D-1SqEpQ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DZdT8nio.js → index-D4UY5Z60.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BvRw4Fna.js → index-D8KvuDz0.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-kdMl_0zL.js → index-DNMAAUVk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CK-p7Hji.js → index-DYLZY4uh.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DXcqvWBp.js → index-DaokIHt3.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BFVbDpqg.js → index-Q7mmL6w4.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BJ1PjRY3.js → index-SO6lgMg0.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BSp1Ofvx.js → index-iahNhZwm.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BupSWDcl.js → index-l08afIbV.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D63QVAiJ.js → index-rIxxfdTN.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-DdcKTlQR.js → initDefaultProps-CG9z1c6w.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-CL-hTBQj.js → motion-B1Ky7Zff.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-qYSAkxNG.js → move-DME8X2P1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-ZwRSZtRP.js → mtc-parser-cuJYSWB7.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-Bld-8ftI.js → omit-UI_EE0uZ.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-DGHs-a9Z.js → pickAttrs-BIoE_Z_V.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-DRQPMyI5.js → placementArrow-B48-9HKN.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-C5MJG_Yo.js → responsiveObserve-D7x_GDgD.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-VZ-fpZCD.js → slide-DjzC5_7m.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-9ocfCyHk.js → statusUtils-C6BIymhh.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B6QAwAN5.js → styleChecker-B4dGrdD9.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Bq1twor3.js → useFlexGapSupport-Bken4aNE.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DKZq96tz.js → useFs-BMlqECqv.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-D0RmRVXf.js → usePersonalDataHub-DLdrfmMa.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D6kEj_tt.js → vnode-CKJQmxa0.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-2yfasoQf.js → zoom-CaZunuau.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 +83 -5
  152. package/src/commands/agent.js +42 -4
  153. package/src/commands/background-session.js +11 -4
  154. package/src/commands/batch.js +79 -27
  155. package/src/commands/changelog.js +15 -4
  156. package/src/commands/config.js +70 -5
  157. package/src/commands/context.js +36 -2
  158. package/src/commands/eval.js +21 -6
  159. package/src/commands/hook.js +2 -2
  160. package/src/commands/hub.js +19 -1
  161. package/src/commands/loop.js +9 -2
  162. package/src/commands/memory.js +21 -6
  163. package/src/commands/permissions.js +57 -1
  164. package/src/commands/plugin.js +2 -0
  165. package/src/commands/review.js +23 -11
  166. package/src/commands/routine.js +31 -8
  167. package/src/commands/session.js +11 -3
  168. package/src/commands/skill.js +2 -0
  169. package/src/commands/statusline.js +3 -3
  170. package/src/commands/team.js +20 -7
  171. package/src/commands/update.js +65 -10
  172. package/src/data/changelog.json +293 -51
  173. package/src/gateways/terminal/PtyManager.js +8 -1
  174. package/src/gateways/ws/message-dispatcher.js +3 -0
  175. package/src/gateways/ws/session-protocol.js +26 -0
  176. package/src/gateways/ws/ws-agent-handler.js +107 -69
  177. package/src/gateways/ws/ws-server.js +74 -2
  178. package/src/harness/background-task-manager.js +18 -6
  179. package/src/harness/background-task-worker.js +11 -18
  180. package/src/harness/jsonl-session-store.js +13 -6
  181. package/src/harness/mcp-client.js +195 -2
  182. package/src/harness/worktree-isolator.js +18 -21
  183. package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
  184. package/src/lib/agent-coordinator.js +4 -0
  185. package/src/lib/agent-core.js +5 -0
  186. package/src/lib/agent-ipc-bus.js +44 -5
  187. package/src/lib/agent-sandbox.js +16 -2
  188. package/src/lib/agent-schedule-store.js +55 -0
  189. package/src/lib/agent-team/team-worktree.js +28 -6
  190. package/src/lib/agent-tool-admission.js +104 -0
  191. package/src/lib/agent-worktree.js +20 -19
  192. package/src/lib/api-key-helper.js +10 -2
  193. package/src/lib/async-hook-supervisor.cjs +135 -15
  194. package/src/lib/async-hook-supervisor.js +47 -0
  195. package/src/lib/background-agent-supervisor.js +35 -12
  196. package/src/lib/background-task-manager.js +5 -1
  197. package/src/lib/changelog.js +76 -11
  198. package/src/lib/channels/channel-manager.js +6 -0
  199. package/src/lib/channels/telegram-channel.js +11 -1
  200. package/src/lib/channels/webhook-channel.js +15 -3
  201. package/src/lib/checkpoint-store.js +10 -2
  202. package/src/lib/chrome-connector.js +6 -2
  203. package/src/lib/claude-code-bridge.js +24 -8
  204. package/src/lib/cli-anything-bridge.js +82 -25
  205. package/src/lib/cloud/bundle.js +12 -2
  206. package/src/lib/code-review.js +32 -8
  207. package/src/lib/computer-use/control-backend.js +18 -3
  208. package/src/lib/context-breakdown.js +46 -0
  209. package/src/lib/context-source-ledger.js +43 -0
  210. package/src/lib/diff-review-follow-up.js +154 -0
  211. package/src/lib/doctor-checkup.js +18 -6
  212. package/src/lib/downloader.js +17 -3
  213. package/src/lib/ensure-utf8.js +11 -3
  214. package/src/lib/eval/tasks.js +25 -31
  215. package/src/lib/event-runtime-producer.js +58 -0
  216. package/src/lib/event-runtime-store.js +354 -0
  217. package/src/lib/event-runtime-worker.js +109 -0
  218. package/src/lib/execution-backend.js +72 -21
  219. package/src/lib/git-integration.js +19 -4
  220. package/src/lib/hook-manager.js +6 -15
  221. package/src/lib/hook-runner.cjs +88 -8
  222. package/src/lib/hook-runner.js +55 -0
  223. package/src/lib/hooks-v2-producers.js +15 -0
  224. package/src/lib/hooks-v2-runtime.js +70 -21
  225. package/src/lib/host-adb-bridge.js +129 -24
  226. package/src/lib/ide-context.js +128 -1
  227. package/src/lib/interaction-adapter.js +39 -0
  228. package/src/lib/json-schema-validate.js +190 -36
  229. package/src/lib/lan-pairing-preflight.js +13 -2
  230. package/src/lib/lsp/__tests__/benchmark.test.js +61 -0
  231. package/src/lib/lsp/__tests__/lsp-client.test.js +6 -1
  232. package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
  233. package/src/lib/lsp/benchmark.js +20 -4
  234. package/src/lib/lsp/lsp-client.js +22 -3
  235. package/src/lib/lsp/lsp-manager.js +4 -0
  236. package/src/lib/lsp/lsp-server-registry.js +11 -2
  237. package/src/lib/mcp-oauth.js +8 -2
  238. package/src/lib/npm-invocation.js +29 -0
  239. package/src/lib/orchestrator.js +8 -2
  240. package/src/lib/packer/pack-update-applier.js +14 -2
  241. package/src/lib/packer/pkg-runner.js +13 -2
  242. package/src/lib/packer/precheck.js +33 -16
  243. package/src/lib/packer/smoke-runner.js +18 -5
  244. package/src/lib/packer/web-panel-builder.js +16 -2
  245. package/src/lib/paths.js +1 -1
  246. package/src/lib/permission-rules.cjs +5 -1
  247. package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
  248. package/src/lib/personal-data-hub-wiring.js +27 -3
  249. package/src/lib/plan-mode.js +204 -11
  250. package/src/lib/plugin-monitor-supervisor.js +48 -6
  251. package/src/lib/plugin-runtime/bin.js +45 -0
  252. package/src/lib/plugin-runtime/hooks.js +14 -1
  253. package/src/lib/plugin-runtime/install.js +11 -3
  254. package/src/lib/plugin-runtime/lsp.js +3 -0
  255. package/src/lib/plugin-runtime/mcp.js +8 -1
  256. package/src/lib/plugin-runtime/monitors.js +4 -0
  257. package/src/lib/plugin-runtime/plugin-options.js +74 -7
  258. package/src/lib/plugin-runtime/signature.js +45 -0
  259. package/src/lib/pr-create.js +21 -8
  260. package/src/lib/pr-link-ledger.js +15 -3
  261. package/src/lib/process-execution-broker/credential-agent.js +23 -3
  262. package/src/lib/process-execution-broker/index.js +315 -38
  263. package/src/lib/process-execution-broker/patch-child-process.js +2 -3
  264. package/src/lib/process-manager.js +18 -3
  265. package/src/lib/publish-workspace.js +14 -6
  266. package/src/lib/repl-bang-memorize.js +10 -2
  267. package/src/lib/repl-goal.js +19 -2
  268. package/src/lib/secret-store.js +159 -0
  269. package/src/lib/service-manager.js +64 -29
  270. package/src/lib/settings-hook-events.cjs +74 -9
  271. package/src/lib/settings-hook-events.js +20 -0
  272. package/src/lib/settings-hooks.cjs +4 -0
  273. package/src/lib/side-effect-ledger.js +22 -0
  274. package/src/lib/skill-packs/generator.js +18 -9
  275. package/src/lib/skill-process-broker.js +71 -0
  276. package/src/lib/slash-commands.js +10 -2
  277. package/src/lib/status-line.cjs +28 -7
  278. package/src/lib/status-line.js +33 -0
  279. package/src/lib/sub-agent-context.js +5 -0
  280. package/src/lib/sub-agent-profiles.js +4 -0
  281. package/src/lib/turn-context.js +14 -8
  282. package/src/lib/unattended-action-policy.js +83 -0
  283. package/src/lib/update-notice.js +6 -2
  284. package/src/lib/with-file-lock.js +7 -0
  285. package/src/lib/ws-server.js +1 -0
  286. package/src/repl/agent-repl.js +60 -23
  287. package/src/repl/clipboard-copy.js +8 -2
  288. package/src/repl/pr-comments.js +30 -7
  289. package/src/runtime/agent-core.js +554 -118
  290. package/src/runtime/agent-runtime.js +1 -0
  291. package/src/runtime/coding-agent-contract-shared.cjs +52 -0
  292. package/src/runtime/coding-agent-policy.cjs +20 -0
  293. package/src/runtime/diagnostics.js +73 -8
  294. package/src/runtime/headless-runner.js +88 -10
  295. package/src/runtime/headless-stream.js +343 -21
  296. package/src/runtime/mcp-config.js +16 -1
  297. package/src/runtime/session-slash-commands.js +506 -0
  298. package/src/skills/video-editing/extractors/audio-extractor.js +13 -5
  299. package/src/skills/video-editing/extractors/video-extractor.js +13 -3
  300. package/src/skills/video-editing/media-process.js +20 -0
  301. package/src/skills/video-editing/render/audio-mix.js +13 -3
  302. package/src/skills/video-editing/render/ffmpeg-concat.js +7 -2
  303. package/src/skills/video-editing/render/ffmpeg-extract.js +7 -2
  304. package/src/workers/background-agent-worker.js +6 -2
  305. package/src/assets/web-panel/assets/ChatBubbleRenderer-Ci97vNTs.js +0 -1
  306. package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +0 -1
  307. package/src/assets/web-panel/assets/Skills-D_jvQZcj.js +0 -1
  308. package/src/assets/web-panel/assets/Tasks-DFwxpLIk.js +0 -1
  309. package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +0 -1
  310. package/src/assets/web-panel/assets/index-CSgUfMTM.js +0 -1
  311. package/src/assets/web-panel/assets/index-DliSZvAP.js +0 -1
@@ -438,6 +438,109 @@ export function hasIdeOpenDiff(mcp) {
438
438
  );
439
439
  }
440
440
 
441
+ const DIFF_REVIEW_AUDIT_SCHEMA = "cc-diff-review/v1";
442
+ const DIFF_REVIEW_OPERATIONS = new Set([
443
+ "modify",
444
+ "create",
445
+ "delete",
446
+ "rename",
447
+ ]);
448
+
449
+ function auditString(value, max) {
450
+ if (value == null) return null;
451
+ const text = String(value).slice(0, max);
452
+ return text || null;
453
+ }
454
+
455
+ function auditIndex(value) {
456
+ return Number.isInteger(value) && value >= 0 ? value : null;
457
+ }
458
+
459
+ function auditFingerprint(value) {
460
+ if (!value || typeof value !== "object") return null;
461
+ const sha256 = auditString(value.sha256, 64);
462
+ if (!/^[a-f0-9]{64}$/i.test(sha256 || "")) return null;
463
+ return {
464
+ sha256: sha256.toLowerCase(),
465
+ chars: auditIndex(value.chars),
466
+ lines: auditIndex(value.lines),
467
+ };
468
+ }
469
+
470
+ /**
471
+ * Reduce a host-provided Diff Review audit to the bounded v1 wire contract.
472
+ * Correlation ids and path are overwritten from the CLI request so a malformed
473
+ * or stale local bridge cannot spoof which session/tool the decision belongs to.
474
+ */
475
+ export function normalizeDiffReviewAudit(value, binding = {}) {
476
+ if (
477
+ !value ||
478
+ typeof value !== "object" ||
479
+ value.schema !== DIFF_REVIEW_AUDIT_SCHEMA
480
+ ) {
481
+ return null;
482
+ }
483
+ const requestedOutcome = auditString(binding.outcome ?? value.outcome, 64);
484
+ const outcome = ["accepted", "rejected", "changes-requested"].includes(
485
+ requestedOutcome,
486
+ )
487
+ ? requestedOutcome
488
+ : "rejected";
489
+ const requestedOperation = binding.operation ?? value.operation;
490
+ const operation = DIFF_REVIEW_OPERATIONS.has(requestedOperation)
491
+ ? requestedOperation
492
+ : "modify";
493
+ const comments = (Array.isArray(value.comments) ? value.comments : [])
494
+ .filter((comment) => comment && typeof comment === "object")
495
+ .map((comment) => ({
496
+ line: auditIndex(comment.line),
497
+ endLine: auditIndex(comment.endLine),
498
+ lineFingerprint: auditFingerprint(comment.lineFingerprint),
499
+ note: auditString(comment.note, 1000),
500
+ }))
501
+ .filter((comment) => comment.note)
502
+ .slice(0, 32);
503
+ const selectedHunks = [
504
+ ...new Set(
505
+ (Array.isArray(value.selectedHunks) ? value.selectedHunks : []).filter(
506
+ (index) => Number.isInteger(index) && index >= 0,
507
+ ),
508
+ ),
509
+ ]
510
+ .sort((a, b) => a - b)
511
+ .slice(0, 128);
512
+ return {
513
+ schema: DIFF_REVIEW_AUDIT_SCHEMA,
514
+ reviewId: auditString(value.reviewId, 64),
515
+ createdAt: auditString(value.createdAt, 64),
516
+ actor: auditString(value.actor, 128) || "local-user",
517
+ host: auditString(value.host, 64) || "ide",
518
+ path: auditString(binding.path ?? value.path, 2048),
519
+ operation,
520
+ targetPath:
521
+ operation === "rename"
522
+ ? auditString(binding.targetPath ?? value.targetPath, 2048)
523
+ : null,
524
+ sessionId: auditString(binding.sessionId, 256),
525
+ turnId: auditString(binding.turnId, 256),
526
+ toolUseId: auditString(binding.toolUseId, 256),
527
+ outcome,
528
+ source: auditString(value.source, 64) || "agent-proposed",
529
+ written: value.written === true,
530
+ followUpRequested:
531
+ value.followUpRequested === true || outcome === "changes-requested",
532
+ baseline: auditFingerprint(value.baseline),
533
+ proposed: auditFingerprint(value.proposed),
534
+ reviewed: auditFingerprint(value.reviewed),
535
+ final: auditFingerprint(value.final),
536
+ selectedHunks,
537
+ appliedHunks: auditIndex(value.appliedHunks),
538
+ totalHunks: auditIndex(value.totalHunks),
539
+ comments,
540
+ reason: auditString(value.reason, 512),
541
+ };
542
+ }
543
+
441
544
  /**
442
545
  * Run one blocking openDiff review in the connected IDE. Returns
443
546
  * { outcome:"accepted", finalText|null } — the IDE wrote the file itself
@@ -459,7 +562,17 @@ export function hasIdeOpenDiff(mcp) {
459
562
  export async function requestIdeDiffApproval(mcp, req = {}) {
460
563
  if (!hasIdeOpenDiff(mcp)) return null;
461
564
  if (!req.path || typeof req.modifiedText !== "string") return null;
565
+ const operation = req.operation || "modify";
566
+ if (!DIFF_REVIEW_OPERATIONS.has(operation)) return null;
567
+ if (operation === "rename" && !req.targetPath) return null;
462
568
  const exec = mcp.externalToolExecutors.mcp__ide__openDiff;
569
+ const reviewContext = Object.fromEntries(
570
+ Object.entries({
571
+ sessionId: auditString(req.sessionId, 256),
572
+ turnId: auditString(req.turnId, 256),
573
+ toolUseId: auditString(req.toolUseId, 256),
574
+ }).filter(([, value]) => value),
575
+ );
463
576
  let result;
464
577
  try {
465
578
  result = await mcp.mcpClient.callTool(exec.serverName, exec.toolName, {
@@ -469,15 +582,26 @@ export async function requestIdeDiffApproval(mcp, req = {}) {
469
582
  ? { originalText: req.originalText }
470
583
  : {}),
471
584
  ...(req.title ? { title: req.title } : {}),
585
+ ...(req.operation ? { operation } : {}),
586
+ ...(operation === "rename" ? { targetPath: req.targetPath } : {}),
587
+ ...(Object.values(reviewContext).some(Boolean) ? { reviewContext } : {}),
472
588
  });
473
589
  } catch {
474
590
  return null;
475
591
  }
476
592
  const data = parseToolResultJson(result);
593
+ const audit = normalizeDiffReviewAudit(data?.audit, {
594
+ ...reviewContext,
595
+ path: req.path,
596
+ operation,
597
+ targetPath: operation === "rename" ? req.targetPath : null,
598
+ outcome: data?.outcome,
599
+ });
477
600
  if (data?.outcome === "accepted") {
478
601
  return {
479
602
  outcome: "accepted",
480
603
  finalText: typeof data.finalText === "string" ? data.finalText : null,
604
+ ...(audit ? { audit } : {}),
481
605
  };
482
606
  }
483
607
  if (data?.outcome === "changes-requested") {
@@ -486,9 +610,12 @@ export async function requestIdeDiffApproval(mcp, req = {}) {
486
610
  comments: Array.isArray(data.comments) ? data.comments : [],
487
611
  reviewedText:
488
612
  typeof data.reviewedText === "string" ? data.reviewedText : null,
613
+ ...(audit ? { audit } : {}),
489
614
  };
490
615
  }
491
- if (data?.outcome === "rejected") return { outcome: "rejected" };
616
+ if (data?.outcome === "rejected") {
617
+ return { outcome: "rejected", ...(audit ? { audit } : {}) };
618
+ }
492
619
  return null; // anything else is not a verdict — fail safe to fallback
493
620
  }
494
621
 
@@ -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
  {
@@ -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;