chainlesschain 0.162.162 → 0.162.164

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 (237) hide show
  1. package/package.json +3 -1
  2. package/src/assets/web-panel/assets/{AIOps-ClI2ALgv.js → AIOps-BqRkaHGb.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BDjRcJaK.js → ActionButton-DWO7OZLC.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DikSRsaT.js → Analytics-C5oaVezM.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-9mLhMFmz.js → AppLayout-CsUESDoZ.js} +3 -3
  6. package/src/assets/web-panel/assets/{Artifacts-BSr88BrH.js → Artifacts-Dragqu5k.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CdvyimOF.js → Audit-CQsaHctY.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-D3_hCedh.js → BackgroundAgents-DdG1jNSM.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Cyvv9RHf.js → Backup-DN6sjK4z.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BZM14kt8.js → BaseInput-Cxm_ZTCl.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DrQSokVz.js → Chat-DVXGmA56.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-HwJR-C6B.js → ChatBubbleRenderer-BdaCL_iE.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-bFLYeWMV.js → Checkbox-DEc4vD_A.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-7mN7xJXT.js → Codegen-CKiTcv36.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DAB5ZWm7.js → Col-Br9UUNN0.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-B_1TymaK.js → Community-NeUH_70T.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-Bq1uSWLJ.js → Compact-BqR-z2Df.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CyiE1jEe.js → Compliance-DcWB_SgZ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-Cpk0D7vm.js → Cowork-BfhgcudF.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-d_Lv3rdB.js → Cron-LaU29LgD.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DMqhHjMR.js → Crosschain-B2ZB9uwW.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Br-oPuBw.js → DID-BuHl38A2.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-CfLW_RaP.js → Dashboard-m627yqvZ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DZnTOExV.js → Dropdown-C7bxF8F5.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-DHIUHDv1.js → EmailListRenderer-DPLPQzLp.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bw3t3myu.js → FamilyGuardDashboard-cOiH6ike.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-D9cpQPAY.js → Federation-Bvkzg88z.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-Jdczr9Mr.js → FormItemContext-BTsiA7h_.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BT8ZMpC5.js → GenericCardRenderer-BGnVE5qu.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DjARip2b.js → Git-DS_j6r25.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-BgWbSRcj.js → Governance-CKRG3Rsl.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CfouJciM.js → Inference-DW8INoNQ.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-50l7mrAr.js → KnowledgeGraph-BhEYeFhC.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-rq50H84B.js → Logs-wqi0uxuR.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-DUPIEdQH.js → MarkdownRenderer-DS8dE8ty.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-BYgPDmHU.js → Marketplace-CMlTuPLT.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-5DVgcFdx.js → McpTools-CSx4m5JJ.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-B70LPk7f.js → Memory-vnQCUy-_.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-De8ssA5Y.js → MobileBridge-BV2NA742.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-Bw0k8e1B.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-RJsOTsIA.js → Mtc-CzK_FPB1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-Crh-6BEK.js → MtcAudit-Cb7G9oL3.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-wuoR5l3x.js → Multisig-qJxlUyzr.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-U2Mji4fZ.js → NLProgramming-DqaBJ7Te.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CdTZAyDH.js → Notes-CwhTJkRi.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-C-FucWE7.js → NotificationSettings-YDs4Fal4.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DCYFTeaI.js → OrderTableRenderer-CvEALpq7.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-an3OF85L.js → Organization-CEmQm9n8.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-C-1vmYFe.js → Overflow-zby_P_LA.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-Cwh47xKg.js → P2P-DsmDNFNT.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Dm38GT0k.js → PdhVaultBrowser-FWwFlZGF.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DS2Y8awD.js → Permissions-DuzQ6me5.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-BQNziA0I.js → PersonalDataHub-DZbeN613.js} +3 -3
  54. package/src/assets/web-panel/assets/{Pipeline-DF85L1ue.js → Pipeline-CoNSVAUS.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BuLornF-.js → Privacy-OYJEAaMC.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-C3Y31IwX.js → ProjectInit-CWIapV--.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-BCPiI8aD.js → ProjectSettings-CX8xMxZn.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BZ6s4k6g.js → Projects-BLCN8YyY.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-D3Wp022X.js → Providers-BV_sxp75.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CUJfQkH4.js → QrScannerModal-BTnRrHRp.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-UAc0EO8l.js → QuickAsk-D1KZg018.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-BaxKupcs.js → Recommend-COm5cuNg.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C75NNnXZ.js → RemoteSession-0saWEkYI.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-BVXynZAk.js → Reputation-Dr7iKLS2.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-C5MRZ0bi.js → Row-C1vpPBcr.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-DAKkEYka.js → RssFeed-CxlWrtNj.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DvWv9YOA.js → Search-BT2V8dPN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-B5peafW1.js → Security-bm9V3c5k.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-UQmvPEaG.js → Services-CocH1yyX.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-C3bhWpuF.js → Skeleton-DHItlMdd.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-DfkKf9_H.js → Skills-C59sLc4w.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DqMSjlBM.js → Sla-Crj4BMc8.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-C-WbxWUX.js → SpeechSettings-DX4KFceY.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-CYuHZ4N2.js → SyncSettings-BD_iwQLr.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-CyeAyB9d.js → Tasks-BmCTzYsH.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-BTCeQnpq.js → Templates-BGUaxZYl.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-BifQuA9Y.js → Tenant-BS0tJx2O.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-Bx_9Bocf.js → Terminal--tHSAsld.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-BX0RFCOm.js → TimelineRenderer-D9-MFxS4.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CGHrCmUS.js → Tokens-CiCB485f.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-DlqaY4SO.js → Trigger-SmCFuW_l.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DfOmj-ay.js → Trust-DkK3Rqe0.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B72jH5fE.js → UkeySign-CDM4LGdB.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-BT-63fqv.js → VideoEditing-IDB7DJXt.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-Dsul3sHr.js → Wallet-Bikj5cmt.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Izkwwdgy.js → WebAuthn-C9abWlAw.js} +2 -2
  87. package/src/assets/web-panel/assets/{WorkflowEditor-D3FHSiH1.js → WorkflowEditor-DrbRKVky.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-CmVz5z3U.js → chat-CccCSDQf.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-CuLgyJBp.js → colors-CXObXLhb.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-Ml1YkXpw.js → compact-item-B5kfYAxC.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BvjJ48bs.js → createContext-DmiPBfip.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-CvKrADNa.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DVC0157C.js → hasIn-Q6lYteAc.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-C229ABfy.js → index-25Wlqps4.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Ck_52dz_.js → index-33U29UNV.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-QXzlT9KD.js → index-4oXBDczR.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-4SBta3d7.js → index-BGYXvMc5.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B0S8NzO6.js → index-BJCCa0s_.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DJyN28Et.js → index-BJJ5DhKI.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DC_OI9H2.js → index-BLOzViJ6.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C_XuRgGn.js → index-BRrbUMoG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-wvb_FtaV.js → index-BUFpT17Q.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-KMqhcF7l.js → index-BkRDiqGc.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-vG4XSJ1d.js → index-BsfvW6my.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DYXHFr4r.js → index-By-kfPED.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DuGszaWY.js → index-BzFTcQsc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CXkJH-lK.js → index-C2FXdboq.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Dt5KMjwJ.js → index-C5XOlTHN.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-4wcgvPoF.js → index-CLhBDS2w.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-C_H_S-DY.js → index-CMq7UeoT.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BydjdZnl.js → index-CVMTWNKl.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BjHBpRYZ.js → index-Caghi-yL.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bzr0rB5T.js → index-CdB6FuSH.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BbPtzB8M.js → index-CoK8-kWQ.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BUt8kTIB.js → index-CsO3GUAY.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C_vRgTl9.js → index-CwZBa20Z.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DukDVXCv.js → index-D-kASucw.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BbepULSc.js → index-D8eBw7vW.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BfuKP4qe.js → index-D9wgifk4.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BiC6dQZG.js → index-DAYCTc07.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CmFNvNLZ.js → index-DF6Q8l2h.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DTdFUWc_.js +1 -0
  123. package/src/assets/web-panel/assets/{index-KjgKdZe-.js → index-DgTLApS9.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BpFJHiTv.js → index-DgxVJ8pg.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Cw0Rjy87.js → index-DlJvIqoR.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CFYVQMvu.js → index-Dw4eHfsG.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CudmwNBV.js → index-Rh-ytwow.js} +3 -3
  128. package/src/assets/web-panel/assets/{index-DDGaOWBV.js → index-StAEt2pq.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-D3lD5qap.js → index-bzfw951k.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BzG-x9p4.js → index-fSUMbMvv.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B_EvG_GW.js → index-tFHy5Wol.js} +1 -1
  132. package/src/assets/web-panel/assets/index-zQ0M_kz-.js +1 -0
  133. package/src/assets/web-panel/assets/{initDefaultProps-BDgd2YZ8.js → initDefaultProps-BNq7X72N.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-ErtrXdYe.js → motion-DOf9viTc.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-_GPPNCgs.js → move-CRHTcW4x.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-DRLL-8V2.js → mtc-parser-Cyoozgm2.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-p86sl023.js → omit-6-TjFNru.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-BTu7cMLH.js → pickAttrs-DlUmO1zi.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BEKz6Isr.js → placementArrow-CFOL8mIR.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-Ck42c9MP.js → responsiveObserve-BtaFK5zd.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-1CEvuPsB.js → slide-BIbc2bur.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BDfdx1GJ.js → statusUtils-BXX9d6-w.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-B4K46m5w.js → styleChecker-BGv10Bpn.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-DoIVpJNq.js → useFlexGapSupport-bKnKT8tw.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DdAWi-ln.js → useFs-FY4IL4jn.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-iUu6k8dx.js → usePersonalDataHub-Bwl9TEgu.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DZz4R6Tw.js → vnode-BM3OHxAT.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DXlf9sA3.js → zoom-D1fbFiHB.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agenda.js +320 -32
  151. package/src/commands/agent.js +105 -11
  152. package/src/commands/context.js +125 -14
  153. package/src/commands/doctor.js +85 -1
  154. package/src/commands/hook.js +181 -7
  155. package/src/commands/plugin.js +456 -1
  156. package/src/commands/review.js +363 -2
  157. package/src/commands/session.js +191 -0
  158. package/src/commands/team.js +19 -1
  159. package/src/data/changelog.json +10 -4
  160. package/src/gateways/ws/remote-session-protocol.js +39 -0
  161. package/src/gateways/ws/session-protocol.js +55 -2
  162. package/src/gateways/ws/ws-agent-handler.js +50 -0
  163. package/src/harness/jsonl-session-store.js +60 -0
  164. package/src/harness/worktree-isolator.js +140 -5
  165. package/src/lib/agent-schedule-store.js +318 -10
  166. package/src/lib/agent-team/team-worktree.js +37 -2
  167. package/src/lib/agent-tool-admission.js +125 -0
  168. package/src/lib/app-preview.js +360 -0
  169. package/src/lib/async-hook-supervisor.cjs +54 -0
  170. package/src/lib/capability-manifest.js +319 -0
  171. package/src/lib/capability-negotiation.js +23 -12
  172. package/src/lib/channels/channel-manager.js +54 -2
  173. package/src/lib/cli-context-engineering.js +9 -2
  174. package/src/lib/context-breakdown.js +116 -0
  175. package/src/lib/diagnostic-bundle.js +230 -0
  176. package/src/lib/doctor-checkup.js +275 -4
  177. package/src/lib/execution-location.js +286 -0
  178. package/src/lib/headless-manifest.js +13 -40
  179. package/src/lib/hook-event-log.cjs +193 -0
  180. package/src/lib/hook-stats-store.cjs +197 -0
  181. package/src/lib/idempotency.js +109 -0
  182. package/src/lib/interaction-adapter.js +34 -4
  183. package/src/lib/json-schema-output.js +46 -12
  184. package/src/lib/json-schema-validate.js +143 -3
  185. package/src/lib/jsonl-session-store.js +1 -0
  186. package/src/lib/lsp/__tests__/lsp-manager.test.js +58 -0
  187. package/src/lib/lsp/lsp-manager.js +56 -0
  188. package/src/lib/monitor-event.js +290 -0
  189. package/src/lib/operation-fingerprint.js +217 -0
  190. package/src/lib/plugin-runtime/bin.js +37 -0
  191. package/src/lib/plugin-runtime/capabilities.js +19 -0
  192. package/src/lib/plugin-runtime/capability-consent.js +203 -0
  193. package/src/lib/plugin-runtime/hooks.js +37 -0
  194. package/src/lib/plugin-runtime/lsp.js +38 -0
  195. package/src/lib/plugin-runtime/mcp.js +40 -0
  196. package/src/lib/plugin-runtime/monitors.js +37 -0
  197. package/src/lib/plugin-runtime/plugin-options.js +151 -0
  198. package/src/lib/plugin-runtime/policy.js +62 -0
  199. package/src/lib/plugin-runtime/scopes.js +20 -4
  200. package/src/lib/pr-automation-policy.js +224 -0
  201. package/src/lib/project-instructions.js +128 -0
  202. package/src/lib/remote-approval-bridge.js +66 -13
  203. package/src/lib/repl-goal.js +132 -0
  204. package/src/lib/repl-rewind.js +153 -0
  205. package/src/lib/review-comment-anchor.js +241 -0
  206. package/src/lib/review-pipeline.js +46 -7
  207. package/src/lib/runtime-checkup.js +221 -0
  208. package/src/lib/schedule-planner.js +17 -1
  209. package/src/lib/secret-scan.js +409 -0
  210. package/src/lib/session-branch.js +0 -0
  211. package/src/lib/settings-hook-events.cjs +13 -0
  212. package/src/lib/settings-loader.cjs +42 -0
  213. package/src/lib/side-effect-ledger-store.js +88 -0
  214. package/src/lib/side-effect-ledger.js +401 -0
  215. package/src/lib/skill-loader.js +32 -0
  216. package/src/lib/skill-path-scope.js +63 -0
  217. package/src/lib/sub-agent-context.js +110 -9
  218. package/src/lib/sub-agent-registry.js +19 -0
  219. package/src/lib/subagent-inheritance.js +112 -0
  220. package/src/lib/telemetry/span-recorder.js +17 -4
  221. package/src/lib/terminal-context.js +195 -0
  222. package/src/lib/turn-binding-store.js +119 -0
  223. package/src/lib/unattended-action-policy.js +182 -0
  224. package/src/lib/worktree-cleanup-safety.js +138 -0
  225. package/src/lib/worktree-isolator.js +8 -0
  226. package/src/lib/worktree-sparse.js +131 -0
  227. package/src/repl/agent-repl.js +280 -30
  228. package/src/repl/permission-tier.js +28 -0
  229. package/src/runtime/agent-core.js +565 -21
  230. package/src/runtime/coding-agent-contract-shared.cjs +60 -1
  231. package/src/runtime/diagnostics.js +60 -0
  232. package/src/runtime/headless-runner.js +393 -1
  233. package/src/runtime/headless-stream.js +60 -1
  234. package/src/assets/web-panel/assets/MobileProjects-D10VISps.js +0 -1
  235. package/src/assets/web-panel/assets/devWarning-DhiGrbsh.js +0 -1
  236. package/src/assets/web-panel/assets/index-B7a1TrU6.js +0 -1
  237. package/src/assets/web-panel/assets/index-C2B1KRja.js +0 -1
@@ -0,0 +1,360 @@
1
+ /**
2
+ * App-Preview auto-validation core — the pure-logic half of P1-3
3
+ * (App Preview 自动验证) of CLAUDE_CODE_IDE_INCREMENTAL_GAP_ANALYSIS_2026-07-13.md.
4
+ *
5
+ * The gap section asks for a project-level Launch config (start command, cwd,
6
+ * port, health check, env references, shutdown policy), a per-turn RISK-based
7
+ * choice of verification tier ("不要求所有改动都启动浏览器" — not every change
8
+ * needs a browser), an evidence-Artifact contract (screenshot / DOM summary /
9
+ * action sequence / test result), and login-state persistence that is OFF by
10
+ * default and must be explicitly scoped (project / session / user).
11
+ *
12
+ * This module is that decision + descriptor layer, NOT a runner: it never spawns
13
+ * a dev server, opens a browser, or touches fs / clock / RNG / process. A caller
14
+ * feeds observed facts (a package.json, a launch config, a change descriptor) and
15
+ * reads back a normalized, safe descriptor plus fail-closed policy verdicts.
16
+ *
17
+ * Two invariants give it teeth, mirroring [[execution-location.js]]:
18
+ * 1. Launch config carries env *references* only (names), never values — a
19
+ * leaked value is a violation, so the config can be rendered/logged/shipped.
20
+ * 2. Login-state persistence fails CLOSED: OFF unless explicitly enabled AND
21
+ * given an explicit {project|session|user} scope. An unknown/unscoped
22
+ * request never silently persists a session cookie jar.
23
+ *
24
+ * Free-text evidence fields are run through [[secret-scan.js]] `redactSecrets`
25
+ * so a captured console error or DOM summary can't smuggle a token into an
26
+ * Artifact.
27
+ *
28
+ * PURE: no fs / clock / RNG / process.
29
+ */
30
+
31
+ import { redactSecrets, containsSecret } from "./secret-scan.js";
32
+
33
+ /** Verification tiers, cheapest → most expensive. Risk selects the floor. */
34
+ export const VERIFICATION_TIER = Object.freeze({
35
+ STATIC: "static-check", // lint/type/build — no server, no browser
36
+ API_PROBE: "api-probe", // hit an endpoint / health check
37
+ DOM_ASSERT: "dom-assert", // render + assert DOM state
38
+ VISUAL: "visual-screenshot", // capture a screenshot for human/vision review
39
+ });
40
+
41
+ const TIER_ORDER = [
42
+ VERIFICATION_TIER.STATIC,
43
+ VERIFICATION_TIER.API_PROBE,
44
+ VERIFICATION_TIER.DOM_ASSERT,
45
+ VERIFICATION_TIER.VISUAL,
46
+ ];
47
+
48
+ /** Evidence artifact kinds the Session persists for a verification run. */
49
+ export const EVIDENCE_KIND = Object.freeze({
50
+ SCREENSHOT: "screenshot",
51
+ DOM_SUMMARY: "dom-summary",
52
+ ACTION_SEQUENCE: "action-sequence",
53
+ TEST_RESULT: "test-result",
54
+ });
55
+
56
+ /** Login-state persistence scopes. Anything else → fail-closed (no persist). */
57
+ export const LOGIN_SCOPE = Object.freeze({
58
+ PROJECT: "project",
59
+ SESSION: "session",
60
+ USER: "user",
61
+ });
62
+
63
+ const LOGIN_SCOPES = new Set(Object.values(LOGIN_SCOPE));
64
+
65
+ /**
66
+ * Known dev-server framework signatures → {framework, defaultPort}. Detection
67
+ * looks at dependencies first (most reliable), then falls back to scripts.
68
+ */
69
+ const FRAMEWORK_SIGNATURES = Object.freeze([
70
+ { dep: "next", framework: "next", defaultPort: 3000 },
71
+ { dep: "nuxt", framework: "nuxt", defaultPort: 3000 },
72
+ { dep: "@angular/cli", framework: "angular", defaultPort: 4200 },
73
+ { dep: "@vue/cli-service", framework: "vue-cli", defaultPort: 8080 },
74
+ { dep: "astro", framework: "astro", defaultPort: 4321 },
75
+ { dep: "@sveltejs/kit", framework: "sveltekit", defaultPort: 5173 },
76
+ { dep: "gatsby", framework: "gatsby", defaultPort: 8000 },
77
+ { dep: "remix", framework: "remix", defaultPort: 3000 },
78
+ { dep: "@remix-run/dev", framework: "remix", defaultPort: 3000 },
79
+ { dep: "react-scripts", framework: "create-react-app", defaultPort: 3000 },
80
+ { dep: "vite", framework: "vite", defaultPort: 5173 },
81
+ { dep: "webpack-dev-server", framework: "webpack", defaultPort: 8080 },
82
+ ]);
83
+
84
+ /** Script names, in preference order, that typically start a dev server. */
85
+ const DEV_SCRIPT_NAMES = ["dev", "start", "serve", "develop"];
86
+
87
+ function asObject(v) {
88
+ return v && typeof v === "object" && !Array.isArray(v) ? v : {};
89
+ }
90
+
91
+ /**
92
+ * Auto-detect a dev-server launch suggestion from a package.json object. Returns
93
+ * `null` when nothing recognizable is present (caller must not guess a command).
94
+ * Never fabricates a port: only a known framework yields a defaultPort; an
95
+ * unknown-framework match from a script alone leaves `port: null`.
96
+ *
97
+ * @param {object} pkg parsed package.json
98
+ * @returns {null | {framework:string|null, script:string|null, startCommand:string|null, port:number|null, source:"dependency"|"script"}}
99
+ */
100
+ export function detectDevServer(pkg) {
101
+ const p = asObject(pkg);
102
+ const deps = { ...asObject(p.dependencies), ...asObject(p.devDependencies) };
103
+ const scripts = asObject(p.scripts);
104
+
105
+ // Prefer a dependency signature — it tells us both framework and default port.
106
+ for (const sig of FRAMEWORK_SIGNATURES) {
107
+ if (Object.prototype.hasOwnProperty.call(deps, sig.dep)) {
108
+ const script =
109
+ DEV_SCRIPT_NAMES.find((name) => typeof scripts[name] === "string") ||
110
+ null;
111
+ return {
112
+ framework: sig.framework,
113
+ script,
114
+ startCommand: script ? `npm run ${script}` : null,
115
+ port: sig.defaultPort,
116
+ source: "dependency",
117
+ };
118
+ }
119
+ }
120
+
121
+ // Fall back to a recognizable dev script with no known framework — we can
122
+ // suggest the command but must not invent a port.
123
+ const script = DEV_SCRIPT_NAMES.find(
124
+ (name) => typeof scripts[name] === "string",
125
+ );
126
+ if (script) {
127
+ return {
128
+ framework: null,
129
+ script,
130
+ startCommand: `npm run ${script}`,
131
+ port: null,
132
+ source: "script",
133
+ };
134
+ }
135
+
136
+ return null;
137
+ }
138
+
139
+ function normalizeEnvRefs(env) {
140
+ // Accept an array of names, or an object whose KEYS are the referenced names.
141
+ // Values are intentionally discarded — a launch config references env by name.
142
+ if (Array.isArray(env)) {
143
+ return env.filter((e) => typeof e === "string" && e.trim() !== "");
144
+ }
145
+ if (env && typeof env === "object") {
146
+ return Object.keys(env);
147
+ }
148
+ return [];
149
+ }
150
+
151
+ const SHUTDOWN_POLICIES = new Set(["kill", "graceful", "keep"]);
152
+
153
+ /**
154
+ * Normalize a raw launch config into a safe descriptor. Env is reduced to
155
+ * reference NAMES only; a port is coerced to a valid TCP port or null; a health
156
+ * check keeps only {path, timeoutMs}. Pure — no validation verdict here (see
157
+ * validateLaunchConfig).
158
+ */
159
+ export function normalizeLaunchConfig(input = {}) {
160
+ const cfg = asObject(input);
161
+ const rawPort = Number(cfg.port);
162
+ const port =
163
+ Number.isInteger(rawPort) && rawPort > 0 && rawPort <= 65535
164
+ ? rawPort
165
+ : null;
166
+ const health = asObject(cfg.healthCheck);
167
+ const rawTimeout = Number(health.timeoutMs);
168
+ return {
169
+ startCommand:
170
+ typeof cfg.startCommand === "string" && cfg.startCommand.trim() !== ""
171
+ ? cfg.startCommand.trim()
172
+ : null,
173
+ cwd: cfg.cwd == null ? null : String(cfg.cwd),
174
+ port,
175
+ healthCheck:
176
+ health.path || health.url
177
+ ? {
178
+ path: String(health.path || health.url),
179
+ timeoutMs:
180
+ Number.isFinite(rawTimeout) && rawTimeout > 0
181
+ ? rawTimeout
182
+ : 30000,
183
+ }
184
+ : null,
185
+ envRefs: normalizeEnvRefs(cfg.env),
186
+ shutdown: SHUTDOWN_POLICIES.has(String(cfg.shutdown))
187
+ ? String(cfg.shutdown)
188
+ : "graceful",
189
+ };
190
+ }
191
+
192
+ /** Keys on an env entry that would mean a raw value leaked into the config. */
193
+ const ENV_VALUE_LEAK_KEYS = ["value", "secret", "token", "password"];
194
+
195
+ /**
196
+ * Validate a raw launch config, fail-closed and EXHAUSTIVE (collects every
197
+ * violation). Reads:
198
+ * - no start command → nothing to launch (`missing-start-command`)
199
+ * - an env entry object carrying a value/secret/token/password → the config
200
+ * must reference env by name only (`env-value-present`)
201
+ * - a health check with no path/url → can't tell when the server is ready
202
+ * (`health-check-missing-target`) — only flagged when a healthCheck object
203
+ * was supplied at all
204
+ * - a startCommand string that itself embeds a secret (`secret-in-command`)
205
+ *
206
+ * @returns {{ok:boolean, violations:string[], config:object}}
207
+ */
208
+ export function validateLaunchConfig(input = {}) {
209
+ const violations = [];
210
+ const config = normalizeLaunchConfig(input);
211
+
212
+ if (!config.startCommand) {
213
+ violations.push("missing-start-command");
214
+ } else if (containsSecret(config.startCommand)) {
215
+ violations.push("secret-in-command");
216
+ }
217
+
218
+ // Env-as-object with a value field is a leak — the config should list names.
219
+ const rawEnv = asObject(input).env;
220
+ if (rawEnv && typeof rawEnv === "object" && !Array.isArray(rawEnv)) {
221
+ for (const v of Object.values(rawEnv)) {
222
+ if (v && typeof v === "object") {
223
+ for (const k of ENV_VALUE_LEAK_KEYS) {
224
+ if (v[k] != null) {
225
+ violations.push("env-value-present");
226
+ break;
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ if (asObject(input).healthCheck && !config.healthCheck) {
234
+ violations.push("health-check-missing-target");
235
+ }
236
+
237
+ return { ok: violations.length === 0, violations, config };
238
+ }
239
+
240
+ /**
241
+ * Pick the verification tier for a change, by risk — the "不要求所有改动都启动
242
+ * 浏览器" rule. Escalation floor:
243
+ * - touches nothing runnable / docs-only → static-check
244
+ * - touches server/API code → api-probe
245
+ * - touches UI/render code → dom-assert
246
+ * - high risk OR explicit visual concern → visual-screenshot
247
+ * The caller may pass an explicit `minTier` to raise (never lower) the floor.
248
+ * A change with no signal defaults to the cheapest tier (static-check), never a
249
+ * browser launch.
250
+ *
251
+ * @param {object} change {touchesUi?, touchesApi?, touchesServer?, risk?, visual?, filesTouched?}
252
+ * @param {object} [opts] {minTier?}
253
+ * @returns {{tier:string, reasons:string[]}}
254
+ */
255
+ export function selectVerificationTier(change = {}, opts = {}) {
256
+ const c = asObject(change);
257
+ const reasons = [];
258
+ let idx = 0; // static-check floor
259
+
260
+ const bump = (tier, reason) => {
261
+ const i = TIER_ORDER.indexOf(tier);
262
+ if (i > idx) idx = i;
263
+ reasons.push(reason);
264
+ };
265
+
266
+ if (c.touchesApi === true || c.touchesServer === true) {
267
+ bump(VERIFICATION_TIER.API_PROBE, "server-or-api-change");
268
+ }
269
+ if (c.touchesUi === true) {
270
+ bump(VERIFICATION_TIER.DOM_ASSERT, "ui-change");
271
+ }
272
+ const risk = String(c.risk || "").toLowerCase();
273
+ if (c.visual === true || risk === "high" || risk === "critical") {
274
+ bump(
275
+ VERIFICATION_TIER.VISUAL,
276
+ c.visual === true ? "visual-concern" : "high-risk",
277
+ );
278
+ }
279
+
280
+ // An explicit minimum tier can only raise the floor.
281
+ const minIdx = TIER_ORDER.indexOf(String(opts.minTier));
282
+ if (minIdx > idx) {
283
+ idx = minIdx;
284
+ reasons.push("explicit-min-tier");
285
+ }
286
+
287
+ return { tier: TIER_ORDER[idx], reasons };
288
+ }
289
+
290
+ /**
291
+ * Build a secret-safe evidence artifact record. Unknown kinds are rejected
292
+ * (returns null) rather than stored blindly. Every free-text field (summary,
293
+ * console/network errors, action labels) is passed through `redactSecrets`, so
294
+ * a captured error string can't leak a token into a persisted Artifact.
295
+ *
296
+ * @param {string} kind one of EVIDENCE_KIND
297
+ * @param {object} data kind-specific payload
298
+ * @returns {null | object} `{kind, tier?, ...redacted fields}`
299
+ */
300
+ export function buildEvidenceArtifact(kind, data = {}) {
301
+ const d = asObject(data);
302
+ const redact = (s) => (typeof s === "string" ? redactSecrets(s) : null);
303
+ const base = {
304
+ kind,
305
+ tier: TIER_ORDER.includes(d.tier) ? d.tier : null,
306
+ label: redact(d.label),
307
+ };
308
+ switch (kind) {
309
+ case EVIDENCE_KIND.SCREENSHOT:
310
+ return {
311
+ ...base,
312
+ // The image bytes/path are opaque to this layer; only metadata here.
313
+ ref: d.ref == null ? null : String(d.ref),
314
+ width: Number.isFinite(Number(d.width)) ? Number(d.width) : null,
315
+ height: Number.isFinite(Number(d.height)) ? Number(d.height) : null,
316
+ };
317
+ case EVIDENCE_KIND.DOM_SUMMARY:
318
+ return { ...base, summary: redact(d.summary) };
319
+ case EVIDENCE_KIND.ACTION_SEQUENCE:
320
+ return {
321
+ ...base,
322
+ steps: Array.isArray(d.steps)
323
+ ? d.steps.map((s) => redact(String(s)))
324
+ : [],
325
+ };
326
+ case EVIDENCE_KIND.TEST_RESULT:
327
+ return {
328
+ ...base,
329
+ passed: d.passed === true,
330
+ total: Number.isFinite(Number(d.total)) ? Number(d.total) : null,
331
+ failed: Number.isFinite(Number(d.failed)) ? Number(d.failed) : null,
332
+ output: redact(d.output),
333
+ };
334
+ default:
335
+ return null;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Resolve whether login-state (cookie jar / auth session) may be persisted for a
341
+ * preview run, and at what scope. Fail-closed:
342
+ * - persistence is OFF unless `enabled === true`
343
+ * - even when enabled, an unknown/absent scope → NOT persisted
344
+ * Returns the reason when persistence is denied so the UI can prompt for an
345
+ * explicit scope. Mirrors the credential fail-closed posture elsewhere.
346
+ *
347
+ * @param {object} req {enabled?, scope?}
348
+ * @returns {{persist:boolean, scope:string|null, reason:string|null}}
349
+ */
350
+ export function resolveLoginStateScope(req = {}) {
351
+ const r = asObject(req);
352
+ if (r.enabled !== true) {
353
+ return { persist: false, scope: null, reason: "not-enabled" };
354
+ }
355
+ const scope = String(r.scope || "").toLowerCase();
356
+ if (!LOGIN_SCOPES.has(scope)) {
357
+ return { persist: false, scope: null, reason: "scope-unspecified" };
358
+ }
359
+ return { persist: true, scope, reason: null };
360
+ }
@@ -60,6 +60,19 @@ class AsyncHookSupervisor {
60
60
  this._results = []; // completed records awaiting drainResults()
61
61
  this._rewakes = []; // failed asyncRewake records awaiting drainRewakes()
62
62
  this._stopped = false;
63
+ // Reliability aggregate for `cc doctor` (慢/熔断 Hook). Folded in-memory on
64
+ // each completion and persisted ONCE on stopAll() — never per run, so the
65
+ // hook hot path takes no extra I/O. Persistence is opt-in: production passes
66
+ // `persistStats:true` (→ default path) or an explicit `hookStatsPath`; tests
67
+ // that pass neither stay hermetic (aggregation still runs, just no write).
68
+ this._statAgg = {};
69
+ this._statsStore = opts.statsStore || require("./hook-stats-store.cjs");
70
+ this._hookStatsPath =
71
+ opts.hookStatsPath ||
72
+ (opts.persistStats === true
73
+ ? this._statsStore.defaultHookStatsPath()
74
+ : null);
75
+ this._statsFs = opts.statsFs || null; // injected fs for tests
63
76
  // The exit reaper is installed LAZILY (on first spawn), not in the ctor:
64
77
  // a supervisor that never dispatches a hook (or the many built in tests)
65
78
  // must not leave a permanent `process.once('exit')` listener behind —
@@ -327,6 +340,20 @@ class AsyncHookSupervisor {
327
340
  ms: fields.started != null ? now - fields.started : 0,
328
341
  };
329
342
  this._pushResult(rec);
343
+ // Fold this run into the reliability aggregate (in-memory, bounded by
344
+ // distinct hooks). Persisted once on stopAll(); best-effort — a stats bug
345
+ // must never affect hook execution.
346
+ try {
347
+ this._statsStore.aggregateRun(this._statAgg, {
348
+ command: rec.command,
349
+ event: rec.event,
350
+ ok: rec.ok,
351
+ ms: rec.ms,
352
+ now: rec.ts,
353
+ });
354
+ } catch {
355
+ /* stats are best-effort */
356
+ }
330
357
  // A rewake fires only for a hook that OPTED IN and finished in a failure
331
358
  // state — a passing async check should not re-engage the agent.
332
359
  if (hook.asyncRewake && !rec.ok) {
@@ -381,6 +408,33 @@ class AsyncHookSupervisor {
381
408
  /* ignore */
382
409
  }
383
410
  this._exitHookInstalled = false;
411
+ this._persistStats();
412
+ }
413
+
414
+ /**
415
+ * Best-effort persist of the session's hook reliability aggregate, merged with
416
+ * whatever is already on disk (accumulates across sessions). No-op when
417
+ * persistence wasn't enabled or nothing was recorded. Never throws — called
418
+ * from stopAll(), which also runs on process 'exit'.
419
+ */
420
+ _persistStats() {
421
+ if (!this._hookStatsPath) return;
422
+ try {
423
+ const fs = this._statsFs || undefined;
424
+ this._statsStore.persistSessionStats(
425
+ this._statAgg,
426
+ this._hookStatsPath,
427
+ fs,
428
+ );
429
+ this._statAgg = {}; // folded in — don't double-count on a later stop
430
+ } catch {
431
+ /* persistence is best-effort */
432
+ }
433
+ }
434
+
435
+ /** Current in-memory reliability aggregate (test/inspection accessor). */
436
+ getStatsAggregate() {
437
+ return this._statAgg;
384
438
  }
385
439
  }
386
440