chainlesschain 0.162.158 → 0.162.160

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 (219) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-BwpTJTN_.js → AIOps-CkRHjW8e.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-BtQOoo3l.js → ActionButton-BP3MeNi2.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Duf_rXZa.js → Analytics-CjbjQsOr.js} +2 -2
  6. package/src/assets/web-panel/assets/{AppLayout-XQK3wjvB.js → AppLayout-i0adH1M8.js} +5 -5
  7. package/src/assets/web-panel/assets/Artifacts-CCCG2GOU.js +1 -0
  8. package/src/assets/web-panel/assets/{Audit-DNjOGQLh.js → Audit-DrsgvwHC.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-FH9RAfB5.js → BackgroundAgents-DkXNkbZM.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-ZIbrR4-U.js → Backup-DarTWCex.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DSt3NaND.js → BaseInput-DaDzhcto.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-CY-wvbjv.js → Chat-C4EzGw6V.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-lkavIWMS.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-8JVadE_B.js → Checkbox-gddNgaQi.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CN83nPYI.js → Codegen-BKldFWf9.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-xPSvqdN8.js → Col-ChR-brDs.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-D78cnIjG.js → Community-DlHtZX86.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-CSw6Csbp.js → Compact-BAhfcBpC.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-E_HhjcYR.js → Compliance-gIrKkm6m.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DybeQjmm.js → Cowork-BYnzLBO3.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-DS0BJeLY.js → Cron-ByUDIljI.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BOwVgkbs.js → Crosschain-DOdNbHFp.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DRUr9YuX.js → DID-BJHaNWD2.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-Cht-yUKW.js → Dashboard-Drm_tClz.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BLr_EJ9X.js → Dropdown-CA1WLzGN.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-Drexuh5W.js → EmailListRenderer-Di1SKjNO.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-D9Q2Kq63.js → FamilyGuardDashboard-44Ve7ZFe.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-C-Z1xI-T.js → Federation-CubPwv_N.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-DLHPMkQF.js → FormItemContext-CsUFe5bU.js} +1 -1
  30. package/src/assets/web-panel/assets/GenericCardRenderer-D7xRjPjZ.js +1 -0
  31. package/src/assets/web-panel/assets/{Git-syATcaBt.js → Git-D-Qx9dhO.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CYe_r8Zf.js → Governance-_YMYaU4n.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-GWxErB7k.js → Inference-J7Yzh-K_.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-qQvVCZoi.js → KnowledgeGraph-D37iI_Mo.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-BenAU2W8.js → Logs-oMTSYfGY.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-7agE3Or1.js → MarkdownRenderer-BqaPmC0W.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-D4Jn5fpD.js → Marketplace-DKUqYDaF.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DtAwoqiQ.js → McpTools-BEv3Gx61.js} +4 -4
  39. package/src/assets/web-panel/assets/{Memory-BI_O50I8.js → Memory-CtA8XD2y.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-CQWE2lqx.js → MobileBridge-ug7c1mMj.js} +1 -1
  41. package/src/assets/web-panel/assets/MobileProjects-BpX5g9It.js +1 -0
  42. package/src/assets/web-panel/assets/{Mtc-Dnr16qsn.js → Mtc-WJaMs4i2.js} +2 -2
  43. package/src/assets/web-panel/assets/{MtcAudit-CQ5Xe4-a.js → MtcAudit-DXnK_-ru.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-Bjr8O-wy.js → Multisig-C4Ev7726.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-CEe-KirU.js → NLProgramming-BMFb9_zk.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-spKJIKF9.js → Notes-Bl93nvBX.js} +4 -4
  47. package/src/assets/web-panel/assets/{NotificationSettings-DRp83LFG.js → NotificationSettings-BN2W5cl6.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-h1A0XB2a.js → OrderTableRenderer-Dxc9oN4o.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-BlgB0IYg.js → Organization-CAs48637.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-a_35HqZI.js → Overflow-Bhq27Zoc.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CSNHCNPC.js → P2P-D61-2542.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-C8M1JH-1.js → PdhVaultBrowser-C1j4iUxz.js} +5 -5
  53. package/src/assets/web-panel/assets/{Permissions-DmjJi9Ms.js → Permissions-rJ2-fScM.js} +3 -3
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DfuwRyf4.js → PersonalDataHub-DFIlTok6.js} +2 -2
  55. package/src/assets/web-panel/assets/{Pipeline-B2-S4ekE.js → Pipeline-BjIgEWoZ.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-B1dOiBLC.js → Privacy-BQoH5wcX.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-_pNmc-DX.js → ProjectInit-CYR_-_Ub.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-DmwG2Ii1.js → ProjectSettings-nkatCq-9.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-SS9uZKCl.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-C6HSjg1d.js → Providers-BnKM9fsF.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-CrDmS7l1.js → QrScannerModal-Cfe82dbz.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-CfKvWt-x.js → QuickAsk-r1RbPufV.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-DMa6Kuzv.js → Recommend-CjCbM2WE.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DrktUo5x.js → RemoteSession-BuMGPH6V.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-BTPQ1vjL.js → Reputation-Bmj3NY1F.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-B6Q7QkMG.js → Row-BIsNcE_1.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-B1IJhAmX.js → RssFeed-BObmojD2.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-xbea1kGD.js → Search-BRmbkQNS.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-7rs0cO3F.js → Security-_rF3DRpY.js} +2 -2
  70. package/src/assets/web-panel/assets/{Services-0fjixK0S.js → Services-D0If9ZV4.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-B_rVq9Cu.js → Skeleton-o7zIksUg.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-C5uM90b9.js → Skills-oUR7zi9u.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-U4pYCIZH.js → Sla-fqKyGi03.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-Cdz4yTWx.js → SpeechSettings-B1wZ_gxx.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-Me3aetHv.js → SyncSettings-B3qJWYXq.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-Cf6aNkL_.js → Tasks-BH5_dUfr.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-CYatk4tU.js → Templates-CCIVpjRP.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-DIMKLw7o.js → Tenant-2GZtTGnB.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-C_cp-uSJ.js → Terminal-BlMkfs_u.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-cUPVNADp.js → TimelineRenderer-U6hi5OMc.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-CiaEIXVf.js → Tokens-C-_BerGJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DB1WU5lQ.js → Trigger-DaKzBgN3.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-Cfht9Ijy.js → Trust-CLvcsco3.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-K3P4Vt9S.js → UkeySign-BFn_Y1zZ.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-DWjhjXRh.js → VideoEditing-B0V18dLT.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-D9-Q1Kan.js → Wallet-BbmP7Imu.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-BDszy-oV.js → WebAuthn-Dewj_0kt.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-DIhij4rA.js → WorkflowEditor-DOxz3Lwa.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-D7VCiKbh.js → chat-B1OIpZnh.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-BvOd9pVn.js → colors-CSGNVdri.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DoqXBiAO.js → compact-item-8S0vcg0u.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-CrKRzUtp.js → createContext-vZyc27TN.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DYEZcY55.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-BWAev4WC.js → hasIn-DWw3-UhA.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DvDOpsJB.js → index-B4pP2ycr.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-oY45XrkG.js → index-BDHyovnK.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CmJ6xKBO.js → index-BKEmQQvR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BoYrS_L2.js → index-BQssf0EQ.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-ww1QtLnX.js → index-BZnauCqN.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BWWsaimP.js → index-BdyokEau.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CoD31Ndm.js → index-BeBv896m.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DlGu7As6.js → index-BjC-TrOb.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-zH-tuuGZ.js → index-BkWd6YL7.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CEXfKSiI.js → index-BoIPHP4R.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CEPHMSih.js → index-BuB5P0TR.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-PDxGjKRu.js → index-BwKrTVV0.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BkgnGX7v.js → index-C6r27A-o.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DV-Rfmfx.js → index-CB2MOS_8.js} +3 -3
  109. package/src/assets/web-panel/assets/{index-KR1-Em9C.js → index-CFQWZvak.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-8g5TJCZ3.js → index-CI3slBKI.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BCyP071m.js → index-CJgKP2cm.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CSb-tnIo.js → index-CLPr2vC_.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-1poMpMU0.js → index-CbZqw7pg.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BZGk8AbZ.js → index-CfEvacz7.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BXyl8O23.js → index-CwXBblm-.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BHOcVYrx.js → index-D1i_8oop.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Bq_ctRpz.js → index-D8qXVfoV.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-gmxqu5Kk.js → index-DKwl1AkQ.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-D23L1V76.js → index-DLAvUtOH.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CDGLdn12.js → index-DLgkAhEE.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-YGDy7nNq.js → index-DPgY5GLy.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Cx7M7PSF.js → index-Dc40pX3F.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-JzUmJMvn.js → index-DcfLXAW7.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-HwHdTusY.js → index-DeCS12Mh.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B30NvR21.js → index-Dg0Izipr.js} +1 -1
  126. package/src/assets/web-panel/assets/index-DmVFfcNR.js +1 -0
  127. package/src/assets/web-panel/assets/{index-B0vGEbJT.js → index-DtHWHJnj.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bf9YlbDn.js → index-Q6oyLnKC.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Bj7EgmOp.js → index-dxocDVD_.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-ISvPZ05r.js → index-t-q3rkVm.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C5kRmj3P.js → index-tr1x96W9.js} +1 -1
  132. package/src/assets/web-panel/assets/index-x7YyhMUa.js +1 -0
  133. package/src/assets/web-panel/assets/{index-BN9m4Ux2.js → index-xx5M5Rbj.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-XW-OR3mL.js → initDefaultProps-Di5YFId0.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-CeuEHh20.js → motion-BVSN0aeL.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-Dva79Keg.js → move-DHNiaP2l.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-C0B6bD2j.js → mtc-parser-xJPf3gQD.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-AkZvO-a2.js → omit-C7qzUdkN.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-B4r55qGc.js → pickAttrs-pSpjg3Le.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-BLH-z7YE.js → placementArrow-cs_jL_UC.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-ksEGZ2Wf.js → responsiveObserve-DkS_Zs4r.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-Cth4OD1Z.js → slide-B5O1Kpxo.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-9S83ezxw.js → statusUtils-BX02GnZp.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-7yQmQGZ4.js → styleChecker-EmBYRftd.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-DpGnMmPc.js → useFlexGapSupport-ZGzN1cU8.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-C4zDZIXH.js → useFs-CfP7M1m7.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-CoLICdUZ.js → usePersonalDataHub-CbIPHgNh.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-CKyH-35X.js → vnode-7xh0If_O.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-DRDGit17.js → zoom-DmitvTR2.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-manifest.json +17 -3
  152. package/src/commands/agent.js +72 -6
  153. package/src/commands/background-session.js +173 -3
  154. package/src/commands/browse.js +86 -0
  155. package/src/commands/cloud.js +232 -0
  156. package/src/commands/doctor.js +61 -6
  157. package/src/commands/mcp.js +107 -0
  158. package/src/commands/plugin.js +63 -1
  159. package/src/commands/routine.js +367 -0
  160. package/src/commands/session.js +396 -0
  161. package/src/data/changelog.json +12 -2
  162. package/src/harness/jsonl-session-store.js +152 -3
  163. package/src/harness/mcp-client.js +50 -0
  164. package/src/harness/session-index.js +295 -0
  165. package/src/harness/session-mirror.js +142 -0
  166. package/src/harness/transcript-integrity.js +182 -0
  167. package/src/index.js +8 -0
  168. package/src/lib/agent-sandbox.js +68 -0
  169. package/src/lib/agents.js +12 -4
  170. package/src/lib/api-key-helper.js +62 -0
  171. package/src/lib/background-agent-supervisor.js +158 -2
  172. package/src/lib/channels/channel-manager.js +126 -0
  173. package/src/lib/channels/telegram-channel.js +112 -0
  174. package/src/lib/channels/webhook-channel.js +140 -0
  175. package/src/lib/chrome-connector.js +386 -0
  176. package/src/lib/cloud/bundle.js +110 -0
  177. package/src/lib/cloud/cloud-client.js +152 -0
  178. package/src/lib/computer-use/authorization.js +173 -0
  179. package/src/lib/computer-use/computer-use-server.js +276 -0
  180. package/src/lib/computer-use/control-backend.js +150 -0
  181. package/src/lib/dependency-install-policy.js +130 -0
  182. package/src/lib/doctor-checkup.js +652 -0
  183. package/src/lib/exit-codes.cjs +77 -0
  184. package/src/lib/headless-manifest.js +175 -0
  185. package/src/lib/hook-runner.cjs +70 -4
  186. package/src/lib/ide-context-redaction.js +130 -0
  187. package/src/lib/ide-context.js +89 -13
  188. package/src/lib/jsonl-session-store.js +6 -0
  189. package/src/lib/llm-config-defaults.js +24 -8
  190. package/src/lib/lsp/lsp-server-registry.js +48 -21
  191. package/src/lib/plugin-runtime/governance.js +174 -0
  192. package/src/lib/pr-link-ledger.js +221 -0
  193. package/src/lib/project-mcp-trust.js +87 -0
  194. package/src/lib/routine-store.js +352 -0
  195. package/src/lib/sensitive-file-guard.js +51 -0
  196. package/src/lib/session-store-guard.js +40 -0
  197. package/src/lib/session-usage.js +318 -2
  198. package/src/lib/sub-agent-context.js +30 -3
  199. package/src/repl/agent-repl.js +361 -3
  200. package/src/repl/bg-dashboard.js +355 -0
  201. package/src/repl/fast-mode.js +103 -0
  202. package/src/repl/fullscreen-tui.js +197 -0
  203. package/src/repl/slash-command-registry.js +11 -3
  204. package/src/repl/voice-dictation.js +132 -0
  205. package/src/runtime/agent-core.js +344 -7
  206. package/src/runtime/coding-agent-contract-shared.cjs +107 -2
  207. package/src/runtime/coding-agent-policy.cjs +17 -0
  208. package/src/runtime/headless-runner.js +137 -14
  209. package/src/runtime/headless-stream.js +43 -9
  210. package/src/runtime/mcp-config.js +32 -1
  211. package/src/runtime/policies/agent-policy.js +3 -0
  212. package/src/assets/web-panel/assets/Artifacts-DQvJoQ6E.js +0 -1
  213. package/src/assets/web-panel/assets/ChatBubbleRenderer-BAV9V-t-.js +0 -1
  214. package/src/assets/web-panel/assets/GenericCardRenderer-DxxEdn2r.js +0 -1
  215. package/src/assets/web-panel/assets/MobileProjects-CVtTqgtg.js +0 -1
  216. package/src/assets/web-panel/assets/Projects-COATmHxF.js +0 -1
  217. package/src/assets/web-panel/assets/devWarning-nDB--2xr.js +0 -1
  218. package/src/assets/web-panel/assets/index-B1_pRTtB.js +0 -1
  219. package/src/assets/web-panel/assets/index-TMM9FuW-.js +0 -1
@@ -0,0 +1,232 @@
1
+ /**
2
+ * `cc cloud` — self-hosted cloud handoff (gap-2026-07-11 P1#7).
3
+ *
4
+ * cc cloud run "<task>" bundle branch → submit to the private runner → record job
5
+ * cc cloud status [id] poll job(s) (last job when id omitted)
6
+ * cc cloud attach <id> wait for completion, reflow patch/plan/pr/artifacts locally
7
+ * cc cloud list local job ledger
8
+ *
9
+ * Runner endpoint + token come from config (cloud.baseUrl / cloud.token) or
10
+ * env (CC_CLOUD_URL / CC_CLOUD_TOKEN). See src/lib/cloud/cloud-client.js for
11
+ * the runner protocol.
12
+ */
13
+
14
+ import { join } from "node:path";
15
+ import { existsSync, mkdirSync } from "node:fs";
16
+ import chalk from "chalk";
17
+ import { logger } from "../lib/logger.js";
18
+
19
+ async function resolveRunner() {
20
+ let cfg = {};
21
+ try {
22
+ cfg = (await import("../lib/config-manager.js")).loadConfig()?.cloud || {};
23
+ } catch {
24
+ cfg = {};
25
+ }
26
+ const baseUrl = process.env.CC_CLOUD_URL || cfg.baseUrl || "";
27
+ const token = process.env.CC_CLOUD_TOKEN || cfg.token || null;
28
+ return { baseUrl, token };
29
+ }
30
+
31
+ function statusColor(status) {
32
+ if (status === "done") return chalk.green;
33
+ if (status === "failed" || status === "timeout") return chalk.red;
34
+ if (status === "running") return chalk.cyan;
35
+ return chalk.gray;
36
+ }
37
+
38
+ export function registerCloudCommand(program) {
39
+ const cloud = program
40
+ .command("cloud")
41
+ .description(
42
+ "Self-hosted cloud handoff — offload a task to a private runner (bundle → run → reflow)",
43
+ );
44
+
45
+ cloud
46
+ .command("run <task...>")
47
+ .description(
48
+ "Bundle the current branch and submit a task to the private runner",
49
+ )
50
+ .option("--json", "Output as JSON")
51
+ .option("--attach", "Wait for completion and reflow the result")
52
+ .action(async (taskWords, options) => {
53
+ try {
54
+ const task = taskWords.join(" ");
55
+ const { baseUrl, token } = await resolveRunner();
56
+ const { CloudClient, saveJob } =
57
+ await import("../lib/cloud/cloud-client.js");
58
+ const { bundleBranch } = await import("../lib/cloud/bundle.js");
59
+ const client = new CloudClient({ baseUrl, token });
60
+
61
+ logger.log(chalk.gray("Bundling current branch…"));
62
+ const snap = bundleBranch(process.cwd());
63
+ logger.log(
64
+ chalk.gray(
65
+ ` ${snap.branch} @ ${snap.baseSha.slice(0, 8)} (${(snap.bytes / 1024).toFixed(0)} KB)`,
66
+ ),
67
+ );
68
+
69
+ const submitted = await client.submit({
70
+ task,
71
+ bundle: snap.bundle,
72
+ branch: snap.branch,
73
+ baseSha: snap.baseSha,
74
+ });
75
+ const job = saveJob({
76
+ jobId: submitted.jobId,
77
+ task,
78
+ branch: snap.branch,
79
+ baseSha: snap.baseSha,
80
+ baseUrl,
81
+ status: "queued",
82
+ submittedAt: Date.now(),
83
+ cwd: process.cwd(),
84
+ });
85
+ if (options.json && !options.attach) {
86
+ return console.log(JSON.stringify(job, null, 2));
87
+ }
88
+ logger.success(`Submitted cloud job ${job.jobId} → ${baseUrl}`);
89
+ logger.log(chalk.gray(` cc cloud attach ${job.jobId}`));
90
+ if (options.attach) await attachJob(job.jobId, options);
91
+ } catch (err) {
92
+ logger.error(err.message);
93
+ process.exitCode = 1;
94
+ }
95
+ });
96
+
97
+ cloud
98
+ .command("status [id]")
99
+ .description("Poll a cloud job's status (most recent when id omitted)")
100
+ .option("--json", "Output as JSON")
101
+ .action(async (id, options) => {
102
+ try {
103
+ const { CloudClient, readJob, listJobs, saveJob } =
104
+ await import("../lib/cloud/cloud-client.js");
105
+ const job = id ? readJob(id) : listJobs()[0];
106
+ if (!job)
107
+ throw new Error(id ? `job not found: ${id}` : "no cloud jobs");
108
+ const client = new CloudClient({
109
+ baseUrl: job.baseUrl,
110
+ token: (await resolveRunner()).token,
111
+ });
112
+ const status = await client.status(job.jobId);
113
+ saveJob({ ...job, status: status.status, lastSummary: status.summary });
114
+ if (options.json) return console.log(JSON.stringify(status, null, 2));
115
+ logger.log(
116
+ `${statusColor(status.status)(status.status)} ${job.jobId} ${chalk.gray(job.task)}`,
117
+ );
118
+ if (status.summary) logger.log(chalk.gray(` ${status.summary}`));
119
+ } catch (err) {
120
+ logger.error(err.message);
121
+ process.exitCode = 1;
122
+ }
123
+ });
124
+
125
+ cloud
126
+ .command("attach <id>")
127
+ .description("Wait for a cloud job to finish and reflow its result locally")
128
+ .option("--json", "Output as JSON")
129
+ .option("--no-apply", "Fetch the result but do not apply the patch")
130
+ .action(async (id, options) => {
131
+ try {
132
+ await attachJob(id, options);
133
+ } catch (err) {
134
+ logger.error(err.message);
135
+ process.exitCode = 1;
136
+ }
137
+ });
138
+
139
+ cloud
140
+ .command("list", { isDefault: true })
141
+ .description("List local cloud jobs")
142
+ .option("--json", "Output as JSON")
143
+ .action(async (options) => {
144
+ try {
145
+ const { listJobs } = await import("../lib/cloud/cloud-client.js");
146
+ const jobs = listJobs();
147
+ if (options.json) return console.log(JSON.stringify(jobs, null, 2));
148
+ if (jobs.length === 0) {
149
+ logger.log(
150
+ chalk.gray("No cloud jobs. Submit one with `cc cloud run`."),
151
+ );
152
+ return;
153
+ }
154
+ for (const j of jobs) {
155
+ logger.log(
156
+ `${statusColor(j.status)((j.status || "?").padEnd(8))} ${j.jobId} ${chalk.gray(j.branch)} ${j.task}`,
157
+ );
158
+ }
159
+ } catch (err) {
160
+ logger.error(err.message);
161
+ process.exitCode = 1;
162
+ }
163
+ });
164
+ }
165
+
166
+ async function attachJob(id, options = {}) {
167
+ const { CloudClient, readJob, saveJob, pollUntilDone } =
168
+ await import("../lib/cloud/cloud-client.js");
169
+ const { applyResultPatch, persistResultArtifacts } =
170
+ await import("../lib/cloud/bundle.js");
171
+ const { token } = await resolveRunner();
172
+
173
+ const job = readJob(id);
174
+ if (!job) throw new Error(`job not found: ${id}`);
175
+ const client = new CloudClient({ baseUrl: job.baseUrl, token });
176
+
177
+ logger.log(chalk.gray(`Waiting for ${id}…`));
178
+ const final = await pollUntilDone(client, id, {
179
+ onTick: (s) =>
180
+ logger.log(
181
+ chalk.gray(` ${s.status}${s.summary ? `: ${s.summary}` : ""}`),
182
+ ),
183
+ });
184
+ saveJob({ ...job, status: final.status, lastSummary: final.summary });
185
+
186
+ if (final.status !== "done") {
187
+ logger.error(`Job ${id} ended ${final.status}: ${final.summary || ""}`);
188
+ process.exitCode = 1;
189
+ return;
190
+ }
191
+
192
+ const result = await client.result(id);
193
+
194
+ // Persist plan/artifacts under the job's local dir.
195
+ const { cloudJobsDir } = await import("../lib/cloud/cloud-client.js");
196
+ const destDir = join(cloudJobsDir(), `${id}-result`);
197
+ if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });
198
+ const written = persistResultArtifacts(result, destDir);
199
+
200
+ let applied = null;
201
+ if (result.patch && options.apply !== false) {
202
+ applied = applyResultPatch(result.patch, job.cwd || process.cwd());
203
+ }
204
+
205
+ if (options.json) {
206
+ return console.log(
207
+ JSON.stringify(
208
+ { jobId: id, status: final.status, applied, written, pr: result.pr },
209
+ null,
210
+ 2,
211
+ ),
212
+ );
213
+ }
214
+ logger.success(`Job ${id} done`);
215
+ if (result.pr)
216
+ logger.log(chalk.magenta(` PR: ${result.pr.url || result.pr}`));
217
+ if (applied) {
218
+ logger.log(
219
+ applied.applied
220
+ ? chalk.green(` patch: ${applied.reason}`)
221
+ : chalk.yellow(` patch: ${applied.reason} (saved under ${destDir})`),
222
+ );
223
+ if (!applied.applied) {
224
+ // Save the unapplied patch so the user can resolve it by hand.
225
+ persistResultArtifacts(
226
+ { artifacts: [{ name: "result.patch", content: result.patch }] },
227
+ destDir,
228
+ );
229
+ }
230
+ }
231
+ for (const w of written) logger.log(chalk.gray(` wrote ${w}`));
232
+ }
@@ -1,18 +1,40 @@
1
1
  import chalk from "chalk";
2
2
  import logger from "../lib/logger.js";
3
3
  import { collectDoctorReport } from "../runtime/diagnostics.js";
4
+ import {
5
+ collectCheckupSections,
6
+ runCheckupFixes,
7
+ unsafeFixCommands,
8
+ } from "../lib/doctor-checkup.js";
9
+
10
+ const LEVEL_ICON = {
11
+ ok: () => chalk.green("✔"),
12
+ warn: () => chalk.yellow("⚠"),
13
+ err: () => chalk.red("✖"),
14
+ info: () => chalk.gray("·"),
15
+ };
4
16
 
5
17
  export function registerDoctorCommand(program) {
6
18
  program
7
19
  .command("doctor")
8
- .description("Diagnose your ChainlessChain environment")
20
+ .alias("checkup")
21
+ .description("Diagnose your ChainlessChain environment (alias: checkup)")
9
22
  .option("--json", "Output as machine-readable JSON")
23
+ .option("--fix", "Apply safe fixes (stale job files, git worktree prune)")
10
24
  .action(async (options) => {
11
25
  const report = await collectDoctorReport();
26
+ const sections = await collectCheckupSections({ cwd: process.cwd() });
27
+ const fixResults = options.fix ? await runCheckupFixes(sections) : null;
28
+
29
+ const checkupErrs = sections
30
+ .flatMap((s) => s.checks)
31
+ .filter((c) => c.level === "err").length;
12
32
 
13
33
  if (options.json) {
14
- console.log(JSON.stringify(report, null, 2));
15
- if (report.summary.criticalFailed > 0) {
34
+ console.log(
35
+ JSON.stringify({ ...report, checkup: sections, fixResults }, null, 2),
36
+ );
37
+ if (report.summary.criticalFailed > 0 || checkupErrs > 0) {
16
38
  process.exitCode = 1;
17
39
  }
18
40
  return;
@@ -41,6 +63,17 @@ export function registerDoctorCommand(program) {
41
63
  logger.log(` ${icon} ${check.name}${detail}`);
42
64
  }
43
65
 
66
+ // Layered checkup sections (config chain / provider / MCP / IDE /
67
+ // plugins / subagents / transcripts / background agents / worktrees).
68
+ for (const section of sections) {
69
+ logger.log(chalk.bold(`\n ${section.title}\n`));
70
+ for (const c of section.checks) {
71
+ const icon = (LEVEL_ICON[c.level] || LEVEL_ICON.info)();
72
+ const detail = c.detail ? chalk.gray(` — ${c.detail}`) : "";
73
+ logger.log(` ${icon} ${c.name}${detail}`);
74
+ }
75
+ }
76
+
44
77
  logger.log(chalk.bold("\n Port Status\n"));
45
78
  for (const p of report.ports) {
46
79
  const icon = p.open ? chalk.green("●") : chalk.gray("○");
@@ -54,13 +87,35 @@ export function registerDoctorCommand(program) {
54
87
  logger.log(` ${icon} Free space: ${report.disk.freeGB.toFixed(1)} GB`);
55
88
  }
56
89
 
90
+ // Applied fixes (--fix) and copyable commands for the rest.
91
+ if (fixResults && fixResults.length > 0) {
92
+ logger.log(chalk.bold("\n Fixes applied\n"));
93
+ for (const f of fixResults) {
94
+ const icon = f.applied ? chalk.green("✔") : chalk.red("✖");
95
+ logger.log(` ${icon} ${f.id}: ${f.detail}`);
96
+ }
97
+ } else if (options.fix) {
98
+ logger.log(chalk.gray("\n No safe fixes needed.\n"));
99
+ }
100
+ const manual = unsafeFixCommands(sections);
101
+ if (manual.length > 0) {
102
+ logger.log(
103
+ chalk.bold("\n Suggested commands (need your judgement)\n"),
104
+ );
105
+ for (const m of manual) {
106
+ logger.log(` ${chalk.gray("#")} ${m.description}`);
107
+ logger.log(` ${chalk.cyan(m.command)}`);
108
+ }
109
+ }
110
+
57
111
  logger.newline();
58
- if (report.summary.failed === 0) {
112
+ const totalIssues = report.summary.criticalFailed + checkupErrs;
113
+ if (report.summary.failed === 0 && checkupErrs === 0) {
59
114
  logger.log(chalk.bold.green(" All checks passed!\n"));
60
- } else if (report.summary.criticalFailed > 0) {
115
+ } else if (totalIssues > 0) {
61
116
  logger.log(
62
117
  chalk.bold.red(
63
- ` ${report.summary.criticalFailed} issue(s) found. See details above.\n`,
118
+ ` ${totalIssues} issue(s) found. See details above.\n`,
64
119
  ),
65
120
  );
66
121
  process.exitCode = 1;
@@ -342,6 +342,67 @@ export function registerMcpCommand(program) {
342
342
  }
343
343
  });
344
344
 
345
+ // mcp computer-use — expose GUI control verbs as an MCP server (opt-in)
346
+ mcp
347
+ .command("computer-use")
348
+ .description(
349
+ "Expose GUI control (screenshot/window-list/click/type/scroll/clipboard/app-launch) as a Streamable-HTTP MCP server. OFF by default; input verbs need confirm:true; high-risk apps (terminals/IDEs/settings/password managers) always confirm",
350
+ )
351
+ .option("--port <n>", "Port to listen on (default: random free port)", "0")
352
+ .option(
353
+ "--capabilities <list>",
354
+ "Comma-separated subset (default: all): screenshot,window_list,app_launch,click,type,scroll,clipboard_read,clipboard_write",
355
+ )
356
+ .option(
357
+ "--allow-apps <list>",
358
+ "Comma-separated app allowlist for input/launch verbs (default: any app)",
359
+ )
360
+ .option(
361
+ "--confirm-all",
362
+ "Require confirm:true for every verb, not just input verbs",
363
+ )
364
+ .option("--token <token>", "Fixed Bearer token (default: random)")
365
+ .option("--no-auth", "Disable Bearer auth (server binds 127.0.0.1 only)")
366
+ .action(async (options) => {
367
+ try {
368
+ const { startComputerUseServer } =
369
+ await import("../lib/computer-use/computer-use-server.js");
370
+ const handle = await startComputerUseServer({
371
+ port: Number(options.port) || 0,
372
+ token: options.auth === false ? false : options.token || null,
373
+ config: {
374
+ capabilities: options.capabilities
375
+ ? options.capabilities.split(",").map((s) => s.trim())
376
+ : undefined,
377
+ appAllowlist: options.allowApps
378
+ ? options.allowApps.split(",").map((s) => s.trim())
379
+ : undefined,
380
+ confirmAll: options.confirmAll === true,
381
+ },
382
+ });
383
+ logger.log(
384
+ chalk.bold("Computer-use MCP server ready (Streamable-HTTP)"),
385
+ );
386
+ logger.log(` URL: ${chalk.cyan(handle.url)}`);
387
+ logger.log(` Capabilities: ${handle.capabilities.join(", ")}`);
388
+ if (handle.token) {
389
+ logger.log(` Auth: Bearer ${handle.token}`);
390
+ } else {
391
+ logger.log(chalk.yellow(" Auth: disabled (--no-auth)"));
392
+ }
393
+ logger.log(
394
+ chalk.yellow(
395
+ " ⚠ GUI control can act on anything on screen. Input verbs need confirm:true; high-risk apps always confirm.",
396
+ ),
397
+ );
398
+ logger.log(chalk.gray("\nCtrl+C to stop."));
399
+ await new Promise(() => {});
400
+ } catch (err) {
401
+ logger.error(chalk.red(`mcp computer-use failed: ${err.message}`));
402
+ process.exitCode = 1;
403
+ }
404
+ });
405
+
345
406
  // mcp servers — list configured servers
346
407
  mcp
347
408
  .command("servers")
@@ -938,6 +999,52 @@ export function registerMcpCommand(program) {
938
999
  });
939
1000
 
940
1001
  // mcp scaffold — generate a boilerplate MCP server project
1002
+ mcp
1003
+ .command("trust-project")
1004
+ .description(
1005
+ "Re-trust the project .mcp.json after reviewing a content change (records its fingerprint for --project-mcp runs)",
1006
+ )
1007
+ .option("--json", "Output as JSON")
1008
+ .action(async (options) => {
1009
+ try {
1010
+ const fsMod = await import("node:fs");
1011
+ const { projectRootBase } = await import("../lib/project-root.cjs");
1012
+ const { recordProjectMcpTrust, projectMcpFingerprint } =
1013
+ await import("../lib/project-mcp-trust.js");
1014
+ const cwd = process.cwd();
1015
+ const candidates = [path.join(cwd, ".mcp.json")];
1016
+ const root = projectRootBase(cwd, { fs: fsMod.default, path });
1017
+ if (root) candidates.push(path.join(root, ".mcp.json"));
1018
+ const results = [];
1019
+ for (const file of [...new Set(candidates)]) {
1020
+ if (!fsMod.existsSync(file)) continue;
1021
+ const content = fsMod.readFileSync(file, "utf-8");
1022
+ const ok = recordProjectMcpTrust(file, content);
1023
+ results.push({
1024
+ file,
1025
+ trusted: ok,
1026
+ fingerprint: projectMcpFingerprint(content).slice(0, 16),
1027
+ });
1028
+ }
1029
+ if (options.json) {
1030
+ console.log(JSON.stringify(results, null, 2));
1031
+ return;
1032
+ }
1033
+ if (results.length === 0) {
1034
+ console.log("No .mcp.json found in this project.");
1035
+ return;
1036
+ }
1037
+ for (const r of results) {
1038
+ console.log(
1039
+ `${r.trusted ? "Trusted" : "FAILED to record"} ${r.file} (${r.fingerprint})`,
1040
+ );
1041
+ }
1042
+ } catch (err) {
1043
+ console.error(`Failed: ${err.message}`);
1044
+ process.exitCode = 1;
1045
+ }
1046
+ });
1047
+
941
1048
  mcp
942
1049
  .command("scaffold <name>")
943
1050
  .description("Scaffold a new MCP server project (stdio or http+sse)")
@@ -538,10 +538,61 @@ export function registerPluginCommand(program) {
538
538
 
539
539
  const counts = summarizeComponents(manifest);
540
540
 
541
+ // Dependency version constraints (gap P2#13): if the manifest declares
542
+ // `dependencies` (plugin name → semver range, plus reserved host/cc),
543
+ // check them against what's installed and the running cc version. Unmet
544
+ // deps are surfaced but do not by themselves fail structural validation —
545
+ // they may simply be absent in this environment.
546
+ let dependencyCheck = null;
547
+ try {
548
+ const rawManifest = manifest.manifestPath
549
+ ? JSON.parse(
550
+ (await import("node:fs")).readFileSync(
551
+ manifest.manifestPath,
552
+ "utf8",
553
+ ),
554
+ )
555
+ : {};
556
+ if (rawManifest && rawManifest.dependencies) {
557
+ const { checkPluginDependencies, formatDependencyIssues } =
558
+ await import("../lib/plugin-runtime/governance.js");
559
+ const { discoverPlugins } =
560
+ await import("../lib/plugin-runtime/scopes.js");
561
+ const { VERSION } = await import("../constants.js");
562
+ const installed = {};
563
+ try {
564
+ for (const p of discoverPlugins({ skipPolicy: true })) {
565
+ installed[p.name] = p.version;
566
+ }
567
+ } catch {
568
+ /* discovery best-effort */
569
+ }
570
+ const result = checkPluginDependencies(rawManifest, {
571
+ installed,
572
+ hostVersion: VERSION,
573
+ });
574
+ dependencyCheck = {
575
+ ok: result.ok,
576
+ issues: formatDependencyIssues(
577
+ manifest.metadata?.name || dir,
578
+ result,
579
+ ),
580
+ ...result,
581
+ };
582
+ }
583
+ } catch {
584
+ /* dependency inspection is best-effort */
585
+ }
586
+
541
587
  if (options.json) {
542
588
  console.log(
543
589
  JSON.stringify(
544
- { ...manifest, componentCounts: counts, verification },
590
+ {
591
+ ...manifest,
592
+ componentCounts: counts,
593
+ verification,
594
+ dependencyCheck,
595
+ },
545
596
  null,
546
597
  2,
547
598
  ),
@@ -570,6 +621,17 @@ export function registerPluginCommand(program) {
570
621
  (verification.ok ? chalk.green("passed") : chalk.red("FAILED")),
571
622
  );
572
623
  }
624
+ if (dependencyCheck) {
625
+ logger.log(
626
+ chalk.bold("\nDependencies: ") +
627
+ (dependencyCheck.ok
628
+ ? chalk.green("satisfied")
629
+ : chalk.yellow("unmet")),
630
+ );
631
+ for (const issue of dependencyCheck.issues) {
632
+ logger.log(chalk.yellow(` ⚠ ${issue}`));
633
+ }
634
+ }
573
635
  for (const w of manifest.warnings) logger.log(chalk.yellow(` ⚠ ${w}`));
574
636
  for (const e of manifest.errors) logger.log(chalk.red(` ✖ ${e}`));
575
637
  if (manifest.ok) {