chainlesschain 0.162.189 → 0.162.197

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 (317) hide show
  1. package/README.md +84 -11
  2. package/bin/chainlesschain.js +7 -52
  3. package/completions/_cc +209 -0
  4. package/completions/cc.bash +18 -0
  5. package/completions/cc.fish +13 -0
  6. package/completions/cc.ps1 +226 -0
  7. package/package.json +10 -2
  8. package/src/assets/web-panel/assets/{AIOps-DbZft8w0.js → AIOps-D3Gu1a5d.js} +1 -1
  9. package/src/assets/web-panel/assets/{ActionButton-DoOZpwfN.js → ActionButton-DrwAoKaz.js} +1 -1
  10. package/src/assets/web-panel/assets/{Analytics-B0J0KLTW.js → Analytics-C7Q-gd_3.js} +3 -3
  11. package/src/assets/web-panel/assets/{AppLayout-D9eIR0qq.js → AppLayout-DgBtae-n.js} +4 -4
  12. package/src/assets/web-panel/assets/{Artifacts-BnZXEVeo.js → Artifacts-pQ6LcA-W.js} +1 -1
  13. package/src/assets/web-panel/assets/{Audit-X1ce4Bjn.js → Audit-DK61tocB.js} +1 -1
  14. package/src/assets/web-panel/assets/{BackgroundAgents-BvWR-y5v.js → BackgroundAgents-BOKgDFRh.js} +1 -1
  15. package/src/assets/web-panel/assets/{Backup-BublSGEd.js → Backup-Bo9G4vTP.js} +1 -1
  16. package/src/assets/web-panel/assets/{BaseInput-CR_77Hso.js → BaseInput-Do_dE9_v.js} +1 -1
  17. package/src/assets/web-panel/assets/{Chat-DixW52tq.js → Chat-COVvZzOL.js} +6 -6
  18. package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +1 -0
  19. package/src/assets/web-panel/assets/{Checkbox-CCv1C87K.js → Checkbox-Z9MJMolt.js} +1 -1
  20. package/src/assets/web-panel/assets/{Codegen-B03Cc3dd.js → Codegen-BVzWKVbf.js} +1 -1
  21. package/src/assets/web-panel/assets/{Col-CA06-6pU.js → Col-C8MnYcbT.js} +1 -1
  22. package/src/assets/web-panel/assets/{Community-Bj881J52.js → Community-DQxqw15l.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compact-UZLTPoaL.js → Compact-BAUmrh3y.js} +1 -1
  24. package/src/assets/web-panel/assets/{Compliance-kGwzRb_0.js → Compliance-jPAkQ3zK.js} +1 -1
  25. package/src/assets/web-panel/assets/{Cowork-KundoYM8.js → Cowork-BBQyxbh8.js} +2 -2
  26. package/src/assets/web-panel/assets/{Cron-BYZyoqDe.js → Cron-W5koq8Z5.js} +2 -2
  27. package/src/assets/web-panel/assets/{Crosschain-BhrrppBX.js → Crosschain-BQhnu5hS.js} +1 -1
  28. package/src/assets/web-panel/assets/{DID-CdC6EguZ.js → DID-DD7PlI18.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dashboard-CcQx3J4y.js → Dashboard-w_ILuwKI.js} +2 -2
  30. package/src/assets/web-panel/assets/{Dropdown-BpijtEzQ.js → Dropdown-qiDUAyAo.js} +1 -1
  31. package/src/assets/web-panel/assets/{EmailListRenderer-DfZjeZTe.js → EmailListRenderer-PDeBcI5H.js} +1 -1
  32. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BFYSf69C.js → FamilyGuardDashboard-SuArscRM.js} +1 -1
  33. package/src/assets/web-panel/assets/{Federation-Okdi3pJm.js → Federation-BCovZaUn.js} +1 -1
  34. package/src/assets/web-panel/assets/{FormItemContext-mH-HebKW.js → FormItemContext-DjlFdVFk.js} +1 -1
  35. package/src/assets/web-panel/assets/{GenericCardRenderer-xivV69x7.js → GenericCardRenderer-DoEZ7fcS.js} +1 -1
  36. package/src/assets/web-panel/assets/{Git-1rh_YBwg.js → Git-CV0-6GPI.js} +2 -2
  37. package/src/assets/web-panel/assets/{Governance-eAXkNxdY.js → Governance-B_SFN50w.js} +1 -1
  38. package/src/assets/web-panel/assets/{Inference-CS6dMVTN.js → Inference-heI0Eo6k.js} +1 -1
  39. package/src/assets/web-panel/assets/{KnowledgeGraph-Bq_TnkvD.js → KnowledgeGraph-Cz5INS5p.js} +1 -1
  40. package/src/assets/web-panel/assets/{Logs-KchHtiHt.js → Logs-BSFxiHkg.js} +2 -2
  41. package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +1 -0
  42. package/src/assets/web-panel/assets/{Marketplace-CsmGcX5X.js → Marketplace-0TWTpE7k.js} +1 -1
  43. package/src/assets/web-panel/assets/{McpTools-BaPFnnyz.js → McpTools-CV4-wBLm.js} +4 -4
  44. package/src/assets/web-panel/assets/{Memory-2m-sUUf7.js → Memory-x5bH5rw5.js} +2 -2
  45. package/src/assets/web-panel/assets/{MobileBridge-D5nVZBRu.js → MobileBridge-DaBmUu9G.js} +1 -1
  46. package/src/assets/web-panel/assets/{MobileProjects-Bo8MLZvT.js → MobileProjects-DqnoFPgR.js} +1 -1
  47. package/src/assets/web-panel/assets/{Mtc-3GDvamGa.js → Mtc-B_zKEBif.js} +4 -4
  48. package/src/assets/web-panel/assets/{MtcAudit-D2zGuZCH.js → MtcAudit-BCfKD2yg.js} +4 -4
  49. package/src/assets/web-panel/assets/{Multisig-BBVQ4t6t.js → Multisig-DgYfj6c_.js} +3 -3
  50. package/src/assets/web-panel/assets/{NLProgramming-BIOCyOGp.js → NLProgramming-Dz09lFUm.js} +1 -1
  51. package/src/assets/web-panel/assets/{Notes-DVwBGpzc.js → Notes-Cuj6ugBE.js} +3 -3
  52. package/src/assets/web-panel/assets/{NotificationSettings-BDnHfIfX.js → NotificationSettings-DK2WXjhg.js} +1 -1
  53. package/src/assets/web-panel/assets/{OrderTableRenderer-C7Ek20ag.js → OrderTableRenderer-D1IAOQoo.js} +1 -1
  54. package/src/assets/web-panel/assets/{Organization-D3SRKaa7.js → Organization-9fqnPvTw.js} +4 -4
  55. package/src/assets/web-panel/assets/{Overflow-C2B8ahyn.js → Overflow-n5xHkhow.js} +1 -1
  56. package/src/assets/web-panel/assets/{P2P-2iwQzG65.js → P2P-B5AUWwH-.js} +2 -2
  57. package/src/assets/web-panel/assets/{PdhVaultBrowser-CoPiWqMN.js → PdhVaultBrowser-CoUDV6dy.js} +4 -4
  58. package/src/assets/web-panel/assets/{Permissions-yV5XNXo5.js → Permissions-DPRmQf_H.js} +4 -4
  59. package/src/assets/web-panel/assets/{PersonalDataHub-uCDJhMUF.js → PersonalDataHub-B37bsbEN.js} +4 -4
  60. package/src/assets/web-panel/assets/{Pipeline-hN7ucMOA.js → Pipeline-CCAuPqu9.js} +1 -1
  61. package/src/assets/web-panel/assets/{Privacy-CgU0ptN4.js → Privacy-B81msZdv.js} +1 -1
  62. package/src/assets/web-panel/assets/{ProjectInit-CfYPiT6j.js → ProjectInit-B-Py2NbF.js} +2 -2
  63. package/src/assets/web-panel/assets/{ProjectSettings-B0A2C4nw.js → ProjectSettings-CYsneiRB.js} +2 -2
  64. package/src/assets/web-panel/assets/{Projects-BE5C0ajn.js → Projects-Y975Mh6R.js} +1 -1
  65. package/src/assets/web-panel/assets/{Providers-CstQPf8W.js → Providers-uO-10aP1.js} +1 -1
  66. package/src/assets/web-panel/assets/{QrScannerModal-Co3z_ynk.js → QrScannerModal-Bj_6gJ0l.js} +1 -1
  67. package/src/assets/web-panel/assets/{QuickAsk-DMTS6pQ6.js → QuickAsk-BgpBCMPE.js} +1 -1
  68. package/src/assets/web-panel/assets/{Recommend-ETw4odUa.js → Recommend-DhUW3YUA.js} +1 -1
  69. package/src/assets/web-panel/assets/RemoteSession-DdeyfbkA.js +5 -0
  70. package/src/assets/web-panel/assets/{Reputation-BTVqQgKq.js → Reputation-fxW421xd.js} +1 -1
  71. package/src/assets/web-panel/assets/{Row-CBKKwwtO.js → Row-De73w1og.js} +1 -1
  72. package/src/assets/web-panel/assets/{RssFeed-BHUQ438I.js → RssFeed-3US_Q_lj.js} +2 -2
  73. package/src/assets/web-panel/assets/{Search-B4NqeUsF.js → Search-DbZ_DU74.js} +1 -1
  74. package/src/assets/web-panel/assets/{Security-BRjoYG5_.js → Security-DoIU1vMF.js} +4 -4
  75. package/src/assets/web-panel/assets/{Services-CxQzu3p3.js → Services-DB_RGqpc.js} +2 -2
  76. package/src/assets/web-panel/assets/{Skeleton-BKzwwmWO.js → Skeleton-DnzLaayC.js} +1 -1
  77. package/src/assets/web-panel/assets/{Skills-DrsFcgth.js → Skills-VzVXHENF.js} +1 -1
  78. package/src/assets/web-panel/assets/{Sla-D21tmXCH.js → Sla-DMfvjCAI.js} +1 -1
  79. package/src/assets/web-panel/assets/{SpeechSettings-CjyjLfp8.js → SpeechSettings-DQQOYWbF.js} +1 -1
  80. package/src/assets/web-panel/assets/{SyncSettings-Cu45-tnx.js → SyncSettings-Bmx3FG1P.js} +2 -2
  81. package/src/assets/web-panel/assets/{Tasks-oMcILYOj.js → Tasks-DOQyfb-2.js} +1 -1
  82. package/src/assets/web-panel/assets/{Templates-Bh-Zcr5R.js → Templates-D6hTRT7c.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tenant-68ns63aI.js → Tenant-CTPQZAzs.js} +1 -1
  84. package/src/assets/web-panel/assets/{Terminal-BLJkFykE.js → Terminal-B7vII3oH.js} +2 -2
  85. package/src/assets/web-panel/assets/{TimelineRenderer-xcrJLq-O.js → TimelineRenderer-BkiFJeXV.js} +1 -1
  86. package/src/assets/web-panel/assets/{Tokens-C6PpFJtf.js → Tokens-BPPdQMNo.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trigger-BaKA7tdM.js → Trigger-BxG8JAEI.js} +1 -1
  88. package/src/assets/web-panel/assets/{Trust-BzhA57Jc.js → Trust-DHD7nMpM.js} +1 -1
  89. package/src/assets/web-panel/assets/{UkeySign-4_U3JkIR.js → UkeySign-B4BJpU47.js} +1 -1
  90. package/src/assets/web-panel/assets/{VideoEditing-162AANxX.js → VideoEditing-CRiGpFx2.js} +1 -1
  91. package/src/assets/web-panel/assets/{Wallet-B1viuql_.js → Wallet-BSDSNiem.js} +4 -4
  92. package/src/assets/web-panel/assets/{WebAuthn-ZVWazhCy.js → WebAuthn-DLTUh5Zv.js} +5 -5
  93. package/src/assets/web-panel/assets/WorkflowEditor-tW2MwjhD.js +1 -0
  94. package/src/assets/web-panel/assets/{chat-DmrHNuwq.js → chat-SgsLQ3FC.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-DAJ_M-PK.js → colors-BHjjLIKO.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-uIzmYwLs.js → compact-item-VceErdKq.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-D_ZmuLwb.js → createContext-BZ332MYl.js} +1 -1
  98. package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +1 -0
  99. package/src/assets/web-panel/assets/{hasIn-CDt_shTL.js → hasIn-CBTjJOjn.js} +1 -1
  100. package/src/assets/web-panel/assets/index-0O5ePnUq.js +1 -0
  101. package/src/assets/web-panel/assets/{index-rXdwUeE3.js → index-1n7xjKDU.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BAvSmJXW.js → index-29wVzi-k.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-C16fYKFD.js → index-B2u26AS3.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C5WcdJH2.js → index-B40dQn0G.js} +3 -3
  105. package/src/assets/web-panel/assets/{index-CaelyMgF.js → index-B5KAGxNo.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-OzTxFIJP.js → index-BC1xuQgX.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CzXqvMuP.js → index-BETEjuNr.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-clSX4PEc.js → index-BOtvPdHt.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-saf3VNeP.js → index-BPXFLYdW.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DdUMcwRB.js → index-BQSmZGgs.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DfSSy9uy.js → index-BRWhLbWF.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-GcKOHD_c.js → index-BTlc-Bve.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BHvlm0In.js → index-BY1wexYG.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Cvak6Oe2.js → index-BcUenmCX.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CKyd472S.js → index-BeiqkxJG.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DvFhhe6r.js → index-BhXZEUAc.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DBFmcaCQ.js → index-By5jBtkV.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DqDSF2RW.js → index-CLc19alH.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DeGBoLQA.js → index-CMVvxIS8.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-FyplHuNt.js → index-C_B9rFQE.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CeUpKjvi.js → index-CaIS_TNX.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BRa4kJ_S.js → index-CawpdGTW.js} +1 -1
  123. package/src/assets/web-panel/assets/index-ChAzPigF.js +1 -0
  124. package/src/assets/web-panel/assets/{index-QsgfSZrV.js → index-CpumS98o.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BDF6EQBs.js → index-Cr4rjlW5.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-rS3gl_68.js → index-CrUgDQkf.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-D4n1lGTB.js → index-CtjLcCNU.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-ifxmu8SY.js → index-DUkVN794.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BTCXf1t-.js → index-D_SePDWj.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Bbxjfstq.js → index-DaCCy6lq.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-D9OE8B3d.js → index-DdefYBSw.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CG0lY4h3.js → index-DePOeMDM.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Bx4d6c1k.js → index-DgPvuIn2.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Z8P4BexE.js → index-FJ3zC9LK.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-ByzGvpR9.js → index-_PHrIO4O.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-DwfvPe-j.js → index-fU7wNHDB.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-CcZ9xJI9.js → index-iYQNU9za.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CbD_WW_6.js → index-vIXOpcjD.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-pmfaD-aK.js → initDefaultProps-D1oZNz0D.js} +1 -1
  140. package/src/assets/web-panel/assets/{motion-CaQ2CpYF.js → motion-C8k6doMO.js} +1 -1
  141. package/src/assets/web-panel/assets/{move-CkKTqNbI.js → move-DJ4qSbYt.js} +1 -1
  142. package/src/assets/web-panel/assets/{mtc-parser-Dd4xsgRI.js → mtc-parser-CdpJD85j.js} +1 -1
  143. package/src/assets/web-panel/assets/{omit-BFuA5YEs.js → omit-B0V4slKA.js} +1 -1
  144. package/src/assets/web-panel/assets/{pickAttrs-DDfxOAJc.js → pickAttrs-Di5NiW1F.js} +1 -1
  145. package/src/assets/web-panel/assets/{placementArrow-Be595JCp.js → placementArrow-B5OMHgEM.js} +1 -1
  146. package/src/assets/web-panel/assets/{responsiveObserve-7byljUM3.js → responsiveObserve-C6U9IWql.js} +1 -1
  147. package/src/assets/web-panel/assets/{slide-CTWfOTaY.js → slide-BMyTH3rN.js} +1 -1
  148. package/src/assets/web-panel/assets/{statusUtils-CNZOuIxM.js → statusUtils-C7d6BG7Z.js} +1 -1
  149. package/src/assets/web-panel/assets/{styleChecker-DwOcBV78.js → styleChecker-CR50QnQy.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFlexGapSupport-B6MNwAO9.js → useFlexGapSupport-DBEeoMb8.js} +1 -1
  151. package/src/assets/web-panel/assets/{useFs-CzyQjH9r.js → useFs-3r099cjv.js} +1 -1
  152. package/src/assets/web-panel/assets/{usePersonalDataHub-Dxh3KiVA.js → usePersonalDataHub-C5IYNdTK.js} +1 -1
  153. package/src/assets/web-panel/assets/{vnode-DVfZiS5N.js → vnode-DmEOLRHf.js} +1 -1
  154. package/src/assets/web-panel/assets/{zoom-BYme7fbY.js → zoom-DnpUiVCB.js} +1 -1
  155. package/src/assets/web-panel/index.html +1 -1
  156. package/src/cli-help.js +181 -0
  157. package/src/command-help-index.json +181 -0
  158. package/src/command-manifest.json +1271 -175
  159. package/src/command-surface-policy.js +312 -0
  160. package/src/commands/agent.js +76 -33
  161. package/src/commands/artifacts.js +400 -2
  162. package/src/commands/background-session.js +41 -3
  163. package/src/commands/checkpoint-restore-recovery.js +1476 -0
  164. package/src/commands/checkpoint.js +947 -22
  165. package/src/commands/compact.js +101 -25
  166. package/src/commands/config.js +506 -20
  167. package/src/commands/doctor.js +4 -1
  168. package/src/commands/hub.js +1 -1
  169. package/src/commands/mcp.js +688 -24
  170. package/src/commands/pack.js +16 -2
  171. package/src/commands/plugin.js +20 -12
  172. package/src/commands/session-mcp-recovery.js +218 -0
  173. package/src/commands/session.js +470 -110
  174. package/src/commands/setup.js +36 -10
  175. package/src/commands/skill.js +181 -110
  176. package/src/commands/status.js +21 -5
  177. package/src/commands/update.js +68 -6
  178. package/src/constants.js +11 -0
  179. package/src/data/changelog.json +14 -1
  180. package/src/gateways/ws/action-protocol.js +10 -0
  181. package/src/gateways/ws/session-protocol.js +555 -27
  182. package/src/gateways/ws/ws-agent-handler.js +541 -14
  183. package/src/gateways/ws/ws-session-gateway.js +129 -22
  184. package/src/gateways/ws/ws-session-state.js +431 -0
  185. package/src/harness/background-task-manager.js +233 -36
  186. package/src/harness/jsonl-session-store.js +2551 -167
  187. package/src/harness/mcp-client.js +802 -61
  188. package/src/harness/prompt-compressor.js +227 -27
  189. package/src/harness/session-index.js +89 -38
  190. package/src/harness/session-list-index.js +254 -0
  191. package/src/harness/structured-handoff.js +410 -0
  192. package/src/lazy-dispatch.js +747 -84
  193. package/src/lib/__tests__/logger.test.js +50 -2
  194. package/src/lib/advisor-runtime.js +1047 -0
  195. package/src/lib/agent-core.js +1 -0
  196. package/src/lib/agent-sandbox.js +120 -26
  197. package/src/lib/agent-session-export.js +20 -0
  198. package/src/lib/agent-team/team-runner.js +230 -8
  199. package/src/lib/artifact-store.js +131 -8
  200. package/src/lib/background-agent-supervisor.js +185 -13
  201. package/src/lib/background-interaction-journal.js +37 -9
  202. package/src/lib/background-launch-profile.js +1058 -0
  203. package/src/lib/checkpoint-restore-already-completed-controller.js +902 -0
  204. package/src/lib/checkpoint-restore-orchestrator.js +987 -0
  205. package/src/lib/checkpoint-restore-partial-rollback-controller.js +1953 -0
  206. package/src/lib/checkpoint-restore-recovery-controller.js +689 -0
  207. package/src/lib/checkpoint-restore-recovery.js +884 -0
  208. package/src/lib/checkpoint-restore-retention.js +126 -0
  209. package/src/lib/checkpoint-restore-saga.js +5079 -0
  210. package/src/lib/checkpoint-restore-session-recovery.js +1178 -0
  211. package/src/lib/checkpoint-restore-workspace-target-verifier.js +270 -0
  212. package/src/lib/checkpoint-store.js +1688 -97
  213. package/src/lib/checkpoint-timeline-authority.js +522 -0
  214. package/src/lib/checkpoint-timeline.js +642 -0
  215. package/src/lib/config-keys.js +18 -119
  216. package/src/lib/config-manager.js +446 -27
  217. package/src/lib/config-redaction.js +57 -0
  218. package/src/lib/config-schema.js +853 -0
  219. package/src/lib/cowork-mcp-tools.js +5 -0
  220. package/src/lib/cowork-task-runner.js +458 -63
  221. package/src/lib/delivery-coordinator.js +1234 -0
  222. package/src/lib/delivery-evidence.js +450 -0
  223. package/src/lib/doctor-checkup.js +199 -14
  224. package/src/lib/executable-path.js +34 -0
  225. package/src/lib/fatal-handler.js +16 -0
  226. package/src/lib/file-checkpoint.js +4909 -186
  227. package/src/lib/file-lines.js +125 -0
  228. package/src/lib/headless-config-command.js +16 -5
  229. package/src/lib/hook-runner.cjs +139 -38
  230. package/src/lib/hooks-v2-workspace-context.js +10 -0
  231. package/src/lib/impacted-gate-selector.js +424 -0
  232. package/src/lib/interaction-adapter.js +62 -0
  233. package/src/lib/jsonl-session-store.js +1 -35
  234. package/src/lib/logger.js +66 -14
  235. package/src/lib/mcp-call-ledger-store.js +1069 -0
  236. package/src/lib/mcp-call-ledger.js +747 -0
  237. package/src/lib/mcp-client.js +5 -0
  238. package/src/lib/mcp-conflict-scheduler.js +468 -0
  239. package/src/lib/mcp-effect-contract.js +102 -0
  240. package/src/lib/mcp-headers-helper-trust.js +145 -0
  241. package/src/lib/mcp-headers-helper.js +616 -0
  242. package/src/lib/mcp-host-recovery-runtime.js +131 -0
  243. package/src/lib/mcp-ledger-recovery-admission.js +1065 -0
  244. package/src/lib/mcp-recovery-adjudication.js +443 -0
  245. package/src/lib/output-context.js +86 -0
  246. package/src/lib/packer/file-identity.js +170 -0
  247. package/src/lib/packer/index.js +3 -0
  248. package/src/lib/packer/native-update-state.js +277 -0
  249. package/src/lib/packer/pack-update-applier.js +1983 -136
  250. package/src/lib/packer/pack-update-checker.js +34 -0
  251. package/src/lib/packer/pack-update-downloader.js +875 -86
  252. package/src/lib/packer/pack-update-signature.js +86 -0
  253. package/src/lib/packer/pkg-config-generator.js +6 -0
  254. package/src/lib/paths.js +65 -10
  255. package/src/lib/plan-mode.js +831 -14
  256. package/src/lib/plan-persistence.js +540 -0
  257. package/src/lib/plugin-runtime/hooks.js +227 -69
  258. package/src/lib/plugin-runtime/plugin-options.js +189 -44
  259. package/src/lib/pr-automation-policy.js +146 -8
  260. package/src/lib/process-execution-broker/credential-agent.js +7 -0
  261. package/src/lib/process-execution-broker/index.js +53 -8
  262. package/src/lib/process-execution-broker/workspace-transaction.js +976 -73
  263. package/src/lib/project-instructions.js +165 -29
  264. package/src/lib/project-mcp-trust.js +67 -0
  265. package/src/lib/public-ide-capability-manifest.js +278 -0
  266. package/src/lib/public-ide-capability-validation.js +351 -0
  267. package/src/lib/secret-store.js +267 -43
  268. package/src/lib/secure-fs.js +1089 -0
  269. package/src/lib/security-audit.js +58 -0
  270. package/src/lib/service-manager.js +34 -13
  271. package/src/lib/session-budget-runtime.js +1452 -0
  272. package/src/lib/session-host-snapshot.js +388 -0
  273. package/src/lib/session-message-provenance.js +429 -0
  274. package/src/lib/session-projection.js +804 -0
  275. package/src/lib/session-resource-budget.js +1495 -0
  276. package/src/lib/settings-hooks.cjs +138 -22
  277. package/src/lib/settings-loader.cjs +25 -2
  278. package/src/lib/side-effect-ledger-store.js +45 -23
  279. package/src/lib/skill-execution-identity.js +217 -0
  280. package/src/lib/skill-loader.js +299 -18
  281. package/src/lib/sub-agent-context.js +236 -28
  282. package/src/lib/sub-agent-registry.js +5 -0
  283. package/src/lib/subagent-contract.js +94 -0
  284. package/src/lib/todo-manager.js +185 -18
  285. package/src/lib/todo-persistence.js +417 -0
  286. package/src/lib/turn-binding-store.js +41 -23
  287. package/src/lib/with-file-lock.js +25 -1
  288. package/src/lib/ws-chat-handler.js +21 -0
  289. package/src/program-base.js +18 -0
  290. package/src/repl/advisor-command.js +103 -0
  291. package/src/repl/agent-repl.js +2332 -154
  292. package/src/repl/btw-command.js +93 -10
  293. package/src/repl/clipboard-image.js +119 -0
  294. package/src/repl/config-summary.js +64 -108
  295. package/src/repl/prompt-editor.js +233 -0
  296. package/src/repl/prompt-interactions.js +404 -0
  297. package/src/repl/prompt-stash.js +354 -0
  298. package/src/repl/prompt-suggestions.js +312 -0
  299. package/src/repl/repl-keybindings.js +227 -0
  300. package/src/repl/session-recap.js +217 -0
  301. package/src/repl/slash-command-registry.js +25 -4
  302. package/src/repl/terminal-layout.js +88 -0
  303. package/src/runtime/agent-core.js +1264 -325
  304. package/src/runtime/coding-agent-contract-shared.cjs +13 -1
  305. package/src/runtime/coding-agent-managed-tool-policy.cjs +7 -2
  306. package/src/runtime/diagnostics.js +32 -13
  307. package/src/runtime/headless-runner.js +298 -118
  308. package/src/runtime/headless-stream.js +353 -95
  309. package/src/runtime/mcp-config.js +148 -14
  310. package/src/runtime/status-diagnostics-lite.js +137 -0
  311. package/src/assets/web-panel/assets/ChatBubbleRenderer-DDHDpBBA.js +0 -1
  312. package/src/assets/web-panel/assets/MarkdownRenderer-TabqHW9B.js +0 -1
  313. package/src/assets/web-panel/assets/RemoteSession-B0rkE09d.js +0 -5
  314. package/src/assets/web-panel/assets/WorkflowEditor-tzdyUk-1.js +0 -1
  315. package/src/assets/web-panel/assets/devWarning-DIrncrV1.js +0 -1
  316. package/src/assets/web-panel/assets/index-D-Swwqld.js +0 -1
  317. package/src/assets/web-panel/assets/index-FMZAMKy8.js +0 -1
@@ -52,7 +52,8 @@ export const LOCAL_FILE_NAMES = ["cc.local.md", "CLAUDE.local.md"];
52
52
  * path RELATIVE to the project root, with forward slashes:
53
53
  * - a bare name (`node_modules`, `dist`) matches that segment ANYWHERE;
54
54
  * - a slashed prefix (`packages/legacy`) matches that dir and everything under;
55
- * - a glob (`**​/generated/**`, `vendor/*`) matches via `*`/`**`/`?`.
55
+ * - a glob (`**` followed by `/generated/**`, or `vendor/*`) matches via
56
+ * `*`/`**`/`?`.
56
57
  */
57
58
  export function normalizeInstructionExcludes(list) {
58
59
  if (!Array.isArray(list)) return [];
@@ -534,15 +535,30 @@ export function resolveSubtreeInstructions(opts = {}) {
534
535
  // Subtree instructions apply only to DESCENDANTS of baseDir (ancestors were
535
536
  // loaded at startup). Reject a target that escapes baseDir or the repo.
536
537
  const relFromBase = path.relative(baseDir, target);
537
- if (
538
- !relFromBase ||
539
- relFromBase.startsWith("..") ||
540
- path.isAbsolute(relFromBase)
541
- ) {
538
+ if (pathEscapesBoundary(path, relFromBase)) {
539
+ if (opts.strictBoundary) {
540
+ throw new SubtreeInstructionBoundaryError({
541
+ repoRoot,
542
+ baseDir,
543
+ targetPath: target,
544
+ });
545
+ }
542
546
  return [];
543
547
  }
544
548
  const relFromRoot = path.relative(repoRoot, target);
545
- if (relFromRoot.startsWith("..") || path.isAbsolute(relFromRoot)) return [];
549
+ if (pathEscapesBoundary(path, relFromRoot)) {
550
+ if (opts.strictBoundary) {
551
+ throw new SubtreeInstructionBoundaryError({
552
+ repoRoot,
553
+ baseDir,
554
+ targetPath: target,
555
+ });
556
+ }
557
+ return [];
558
+ }
559
+ // A path directly in baseDir has no lazy subtree instructions. This is a
560
+ // valid no-op, not a boundary violation.
561
+ if (!relFromBase) return [];
546
562
 
547
563
  // Directories strictly between baseDir (exclusive) and target (inclusive).
548
564
  const dirs = [];
@@ -573,43 +589,163 @@ export function resolveSubtreeInstructions(opts = {}) {
573
589
  }
574
590
 
575
591
  /**
576
- * Stateful companion to `resolveSubtreeInstructions`: tracks which subtree
577
- * directories have already been injected across a session so a second access to
578
- * the same subtree is a no-op. `onAccess(path)` returns ONLY the freshly
579
- * discovered files. Fail-open (any error → []).
592
+ * Explicit error used by the strict, stateful discovery API. The legacy pure
593
+ * resolver and `onAccess()` remain fail-open for compatibility, while batching
594
+ * callers can distinguish an empty discovery from a rejected path traversal.
595
+ */
596
+ export class SubtreeInstructionBoundaryError extends Error {
597
+ constructor({ repoRoot, baseDir, targetPath }) {
598
+ super(
599
+ `subtree instruction target is outside the allowed project boundary: ${targetPath}`,
600
+ );
601
+ this.name = "SubtreeInstructionBoundaryError";
602
+ this.code = "ERR_SUBTREE_INSTRUCTION_BOUNDARY";
603
+ this.repoRoot = repoRoot;
604
+ this.baseDir = baseDir;
605
+ this.targetPath = targetPath;
606
+ }
607
+ }
608
+
609
+ function subtreeInstructionIdentity(path, filePath) {
610
+ const absolute = path.resolve(filePath);
611
+ // Windows paths are case-insensitive. Normalising case makes discoveries for
612
+ // source + target paths safe to merge by identity even if callers use
613
+ // different drive-letter/path casing.
614
+ return path.sep === "\\" ? absolute.toLowerCase() : absolute;
615
+ }
616
+
617
+ function pathEscapesBoundary(path, relativePath) {
618
+ return (
619
+ relativePath === ".." ||
620
+ relativePath.startsWith(`..${path.sep}`) ||
621
+ path.isAbsolute(relativePath)
622
+ );
623
+ }
624
+
625
+ /**
626
+ * Stateful companion to `resolveSubtreeInstructions`. `discover(path)` returns
627
+ * uncommitted candidates carrying stable identities; `commit()` / `markLoaded()`
628
+ * acknowledge only candidates that the caller successfully read and parsed.
629
+ * `onAccess()` retains the previous fail-open convenience behavior.
580
630
  */
581
631
  export class SubtreeInstructionLoader {
582
632
  constructor(opts = {}) {
583
633
  const path = opts.deps?.path || pathDefault;
584
634
  this._opts = opts;
585
- this._loadedDirs = new Set();
586
- this._loadedFiles = new Set(
587
- (opts.alreadyLoaded || []).map((p) => path.resolve(p)),
588
- );
635
+ this._path = path;
636
+ this._loadedFiles = new Map();
637
+ for (const filePath of opts.alreadyLoaded || []) {
638
+ const absolute = path.resolve(filePath);
639
+ this._loadedFiles.set(
640
+ subtreeInstructionIdentity(path, absolute),
641
+ absolute,
642
+ );
643
+ }
589
644
  }
590
645
 
591
- /** @returns {Array<{path:string, scope:"project", dir:string}>} newly injected */
646
+ /**
647
+ * Discover every applicable instruction file not yet committed. Discovery is
648
+ * intentionally repeatable and does not mutate loaded state.
649
+ *
650
+ * @returns {Array<{path:string, scope:"project", dir:string, identity:string}>}
651
+ * @throws {SubtreeInstructionBoundaryError} when targetPath escapes base/repo
652
+ */
653
+ discover(targetPath) {
654
+ const found = resolveSubtreeInstructions({
655
+ ...this._opts,
656
+ accessedPath: targetPath,
657
+ alreadyLoaded: [],
658
+ strictBoundary: true,
659
+ });
660
+ return found
661
+ .map((candidate) => ({
662
+ ...candidate,
663
+ identity: subtreeInstructionIdentity(this._path, candidate.path),
664
+ }))
665
+ .filter((candidate) => !this._loadedFiles.has(candidate.identity));
666
+ }
667
+
668
+ /**
669
+ * Mark successfully read/parsed/injected discoveries as loaded. Callers may
670
+ * pass one candidate or a source+target batch deduped by `identity`.
671
+ *
672
+ * @returns {number} number of newly committed instruction files
673
+ */
674
+ commit(discoveries) {
675
+ const batch = Array.isArray(discoveries) ? discoveries : [discoveries];
676
+ const validated = new Map();
677
+ for (const candidate of batch) {
678
+ const candidatePath =
679
+ typeof candidate === "string"
680
+ ? candidate
681
+ : candidate?.path || candidate?.identity;
682
+ if (typeof candidatePath !== "string") continue;
683
+ const absolute = this._path.resolve(candidatePath);
684
+ const identity = subtreeInstructionIdentity(this._path, absolute);
685
+ if (
686
+ typeof candidate !== "string" &&
687
+ candidate.identity &&
688
+ candidate.identity !== identity
689
+ ) {
690
+ throw new TypeError(
691
+ `subtree instruction identity does not match its path: ${candidate.identity}`,
692
+ );
693
+ }
694
+
695
+ // A caller may commit a source+target batch assembled across discover()
696
+ // calls. Recheck its lexical boundary before mutating loaded state.
697
+ const repoRoot = this._path.resolve(
698
+ this._opts.repoRoot || this._opts.baseDir || process.cwd(),
699
+ );
700
+ const baseDir = this._path.resolve(this._opts.baseDir || repoRoot);
701
+ const relativeToBase = this._path.relative(baseDir, absolute);
702
+ const relativeToRoot = this._path.relative(repoRoot, absolute);
703
+ if (
704
+ pathEscapesBoundary(this._path, relativeToBase) ||
705
+ pathEscapesBoundary(this._path, relativeToRoot)
706
+ ) {
707
+ throw new SubtreeInstructionBoundaryError({
708
+ repoRoot,
709
+ baseDir,
710
+ targetPath: absolute,
711
+ });
712
+ }
713
+ validated.set(identity, absolute);
714
+ }
715
+
716
+ // Validate the complete source+target batch before mutating loaded state.
717
+ let committed = 0;
718
+ for (const [identity, absolute] of validated) {
719
+ if (!this._loadedFiles.has(identity)) {
720
+ this._loadedFiles.set(identity, absolute);
721
+ committed++;
722
+ }
723
+ }
724
+ return committed;
725
+ }
726
+
727
+ /** Alias for callers that prefer acknowledgement terminology. */
728
+ markLoaded(discoveries) {
729
+ return this.commit(discoveries);
730
+ }
731
+
732
+ /**
733
+ * Legacy discover+commit convenience. New read/parse callers should use the
734
+ * two phases directly so a transient failure remains retryable.
735
+ */
592
736
  onAccess(accessedPath) {
593
737
  try {
594
- const found = resolveSubtreeInstructions({
595
- ...this._opts,
596
- accessedPath,
597
- alreadyLoaded: this._loadedFiles,
598
- });
599
- const fresh = found.filter((f) => !this._loadedDirs.has(f.dir));
600
- for (const f of fresh) {
601
- this._loadedDirs.add(f.dir);
602
- this._loadedFiles.add(f.path);
603
- }
604
- return fresh;
738
+ const found = this.discover(accessedPath);
739
+ this.commit(found);
740
+ return found;
605
741
  } catch {
606
742
  return [];
607
743
  }
608
744
  }
609
745
 
610
- /** Absolute paths injected so far (startup set + every onAccess discovery). */
746
+ /** Absolute paths injected so far (startup set + every committed discovery). */
611
747
  loadedFiles() {
612
- return [...this._loadedFiles];
748
+ return [...this._loadedFiles.values()];
613
749
  }
614
750
  }
615
751
 
@@ -14,6 +14,7 @@
14
14
  */
15
15
 
16
16
  import path from "node:path";
17
+ import fs from "node:fs";
17
18
  import { createHash } from "node:crypto";
18
19
  import { getHomeDir } from "./paths.js";
19
20
  import { withFileLock } from "./with-file-lock.js";
@@ -23,6 +24,7 @@ import {
23
24
  } from "./durable-security-store.js";
24
25
 
25
26
  export const _deps = { withFileLock };
27
+ const workspaceAuthorities = new WeakMap();
26
28
 
27
29
  function storePath(opts = {}) {
28
30
  return (
@@ -36,6 +38,71 @@ export function projectMcpFingerprint(content) {
36
38
  return createHash("sha256").update(String(content), "utf-8").digest("hex");
37
39
  }
38
40
 
41
+ /**
42
+ * Issue an in-process authority only after the caller has verified the exact
43
+ * project file fingerprint. Plain config fields cannot forge this token.
44
+ */
45
+ export function issueProjectMcpWorkspaceAuthority({
46
+ file,
47
+ content,
48
+ workspaceRoot,
49
+ serverName,
50
+ config = {},
51
+ }) {
52
+ const canonicalFile = fs.realpathSync.native(path.resolve(file));
53
+ const canonicalRoot = fs.realpathSync.native(path.resolve(workspaceRoot));
54
+ const token = Object.freeze({});
55
+ workspaceAuthorities.set(
56
+ token,
57
+ Object.freeze({
58
+ file: canonicalFile,
59
+ fingerprint: projectMcpFingerprint(content),
60
+ workspaceRoot: canonicalRoot,
61
+ serverName: String(serverName || ""),
62
+ url: typeof config.url === "string" ? config.url : "",
63
+ transport: typeof config.transport === "string" ? config.transport : "",
64
+ headersHelper:
65
+ typeof config.headersHelper === "string" ? config.headersHelper : "",
66
+ }),
67
+ );
68
+ return token;
69
+ }
70
+
71
+ /** Resolve a collector-issued project authority against the exact config. */
72
+ export function resolveProjectMcpWorkspaceAuthority(token, expected = {}) {
73
+ const record = workspaceAuthorities.get(token);
74
+ if (!record) return null;
75
+ let expectedFile;
76
+ try {
77
+ expectedFile = fs.realpathSync.native(
78
+ path.resolve(String(expected.configSource || "")),
79
+ );
80
+ } catch {
81
+ return null;
82
+ }
83
+ let currentFingerprint;
84
+ try {
85
+ currentFingerprint = projectMcpFingerprint(
86
+ fs.readFileSync(expectedFile, "utf8"),
87
+ );
88
+ } catch {
89
+ return null;
90
+ }
91
+ if (
92
+ record.file !== expectedFile ||
93
+ record.fingerprint !== currentFingerprint ||
94
+ record.serverName !== String(expected.serverName || "") ||
95
+ record.url !== (typeof expected.url === "string" ? expected.url : "") ||
96
+ record.transport !==
97
+ (typeof expected.transport === "string" ? expected.transport : "") ||
98
+ record.headersHelper !==
99
+ (typeof expected.headersHelper === "string" ? expected.headersHelper : "")
100
+ ) {
101
+ return null;
102
+ }
103
+ return record.workspaceRoot;
104
+ }
105
+
39
106
  function readStore(opts) {
40
107
  return readSecurityStore(storePath(opts), "project MCP trust");
41
108
  }
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Canonical, public (secret-free) IDE capability manifest.
3
+ *
4
+ * Host runtimes intentionally keep their native registration formats
5
+ * (VS Code package.json/registerCommand, JetBrains plugin.xml/actions and the
6
+ * existing Desktop keyboard-shortcut registry). This manifest is the single
7
+ * reviewable contract those public surfaces are validated against.
8
+ */
9
+
10
+ import { buildCompatFixture } from "./capability-manifest.js";
11
+
12
+ const freeze = (value) => {
13
+ if (!value || typeof value !== "object" || Object.isFrozen(value)) {
14
+ return value;
15
+ }
16
+ for (const child of Object.values(value)) freeze(child);
17
+ return Object.freeze(value);
18
+ };
19
+
20
+ const BRIDGE_TOOL_FEATURES = [
21
+ ["getSelection", "selection"],
22
+ ["getActiveFile", "active_file"],
23
+ ["getDiagnostics", "diagnostics"],
24
+ ["getOpenEditors", "open_editors"],
25
+ ["openDiff", "native_diff"],
26
+ ["openMultiDiff", "multi_file_diff"],
27
+ ["getTerminalOutput", "terminal_output"],
28
+ ["getPreviewState", "preview_state"],
29
+ ["getTestResults", "test_results"],
30
+ ["getCoverage", "coverage"],
31
+ ["getDebugState", "debug_state"],
32
+ ["executeCode", "notebook_execute"],
33
+ ["getHover", "semantic_hover"],
34
+ ["goToDefinition", "semantic_definition"],
35
+ ["findReferences", "semantic_references"],
36
+ ["renamePreview", "semantic_rename"],
37
+ ["getCallHierarchy", "semantic_call_hierarchy"],
38
+ ["getSymbolInfo", "semantic_symbols"],
39
+ ["getProjectModel", "project_model"],
40
+ ];
41
+
42
+ const VSCODE_COMMANDS = [
43
+ "chainlesschain.ide.showStatus",
44
+ "chainlesschain.ide.restart",
45
+ "chainlesschain.ide.openDashboard",
46
+ "chainlesschain.complete.trigger",
47
+ "chainlesschain.ide.doctor",
48
+ "chainlesschain.ide.exportDiagnostics",
49
+ "chainlesschain.team.monitor",
50
+ "chainlesschain.session.prStatus",
51
+ "chainlesschain.background.agents",
52
+ "chainlesschain.sessions.workbench",
53
+ "chainlesschain.remote.control",
54
+ "chainlesschain.usage.show",
55
+ "chainlesschain.plugins.manage",
56
+ "chainlesschain.worktree.tasks",
57
+ "chainlesschain.chrome.connector",
58
+ "chainlesschain.artifacts.show",
59
+ "chainlesschain.policy.show",
60
+ "chainlesschain.workspace.scanAutoExec",
61
+ "chainlesschain.remote.doctor",
62
+ "chainlesschain.lens.explain",
63
+ "chainlesschain.lens.refactor",
64
+ "chainlesschain.diff.accept",
65
+ "chainlesschain.diff.reject",
66
+ "chainlesschain.memory.init",
67
+ "chainlesschain.memory.files",
68
+ "chainlesschain.llm.configure",
69
+ "chainlesschain.llm.configureVision",
70
+ "chainlesschain.chat.insertReference",
71
+ "chainlesschain.chat.fixDiagnostics",
72
+ "chainlesschain.chat.explainSelection",
73
+ "chainlesschain.chat.refactorSelection",
74
+ "chainlesschain.chat.newConversation",
75
+ "chainlesschain.chat.reopenClosedSession",
76
+ "chainlesschain.inlineChat.open",
77
+ "chainlesschain.inlineChat.explain",
78
+ "chainlesschain.inlineChat.refactor",
79
+ "chainlesschain.inlineChat.fix",
80
+ "chainlesschain.inlineChat.generateDocs",
81
+ "chainlesschain.inlineChat.generateTests",
82
+ "chainlesschain.plan.approve",
83
+ "chainlesschain.plan.requestChanges",
84
+ "chainlesschain.plan.regenerate",
85
+ "chainlesschain.plan.reject",
86
+ "chainlesschain.preview.start",
87
+ "chainlesschain.preview.stop",
88
+ "chainlesschain.cli.upgrade",
89
+ "chainlesschain.cli.checkUpdate",
90
+ "chainlesschain.cli.whatsNew",
91
+ "chainlesschain.cli.installManaged",
92
+ "chainlesschain.cli.rollbackManaged",
93
+ ];
94
+
95
+ const JETBRAINS_ACTIONS = [
96
+ "chainlesschain.ide.ShowStatus",
97
+ "chainlesschain.ide.ShowActivity",
98
+ "chainlesschain.ide.OpenDashboard",
99
+ "chainlesschain.team.Monitor",
100
+ "chainlesschain.session.PrStatus",
101
+ "chainlesschain.bg.Agents",
102
+ "chainlesschain.remote.Control",
103
+ "chainlesschain.sessions.Workbench",
104
+ "chainlesschain.usage.Show",
105
+ "chainlesschain.artifacts.Browse",
106
+ "chainlesschain.policy.Viewer",
107
+ "chainlesschain.plugins.Manage",
108
+ "chainlesschain.worktree.Tasks",
109
+ "chainlesschain.chrome.Connector",
110
+ "chainlesschain.workspace.ScanAutoExec",
111
+ "chainlesschain.managedCli.Install",
112
+ "chainlesschain.managedCli.Rollback",
113
+ "chainlesschain.ide.DiagnoseBridge",
114
+ "chainlesschain.ide.ExportDiagnostics",
115
+ "chainlesschain.ide.RestartBridge",
116
+ "chainlesschain.cli.whatsNew",
117
+ "chainlesschain.ide.ConfigureLlm",
118
+ "chainlesschain.ide.ConfigureVisionModel",
119
+ "chainlesschain.chat.newConversation",
120
+ "chainlesschain.chat.reopenClosedConversation",
121
+ "chainlesschain.completion.trigger",
122
+ "chainlesschain.chat.explainSelection",
123
+ "chainlesschain.chat.refactorSelection",
124
+ "chainlesschain.chat.insertFileReference",
125
+ "chainlesschain.memory.init",
126
+ "chainlesschain.memory.files",
127
+ "chainlesschain.preview.start",
128
+ "chainlesschain.preview.stop",
129
+ ];
130
+
131
+ const DESKTOP_SHORTCUT_KEYS = [
132
+ "Ctrl+S",
133
+ "Ctrl+F",
134
+ "Ctrl+Shift+F",
135
+ "Ctrl+P",
136
+ "Ctrl+K",
137
+ "Ctrl+B",
138
+ "Ctrl+`",
139
+ "Ctrl+/",
140
+ "Ctrl+D",
141
+ "Ctrl+Shift+K",
142
+ "Alt+Up",
143
+ "Alt+Down",
144
+ "Ctrl+Z",
145
+ "Ctrl+Shift+Z",
146
+ "Ctrl+N",
147
+ "Ctrl+W",
148
+ "Ctrl+Shift+T",
149
+ "Ctrl+Tab",
150
+ "Ctrl+Shift+Tab",
151
+ "Esc",
152
+ "F2",
153
+ "Delete",
154
+ ];
155
+
156
+ export const PUBLIC_IDE_CAPABILITY_MANIFEST = freeze({
157
+ schema: "chainlesschain.public-ide-capabilities/v1",
158
+ schemaVersion: 1,
159
+ minimumCliVersion: "0.162.47",
160
+ protocol: buildCompatFixture(),
161
+ bridge: {
162
+ schemaVersion: 1,
163
+ toolFeatures: BRIDGE_TOOL_FEATURES,
164
+ },
165
+ surfaces: {
166
+ cli: {
167
+ commandManifest: "packages/cli/src/command-manifest.json",
168
+ commandHelpIndex: "packages/cli/src/command-help-index.json",
169
+ requiredCommands: ["doctor", "ide"],
170
+ doctorCommands: ["doctor", "ide doctor"],
171
+ },
172
+ vscode: {
173
+ commandContribution: "packages/vscode-extension/package.json",
174
+ runtimeRegistration: "packages/vscode-extension/src/extension.js",
175
+ bridgeCapabilities: "packages/vscode-extension/src/ide-capabilities.js",
176
+ minimumCliVersionSource: "packages/vscode-extension/src/version-check.js",
177
+ doctorImplementation: "packages/vscode-extension/src/ide-doctor.js",
178
+ readme: "packages/vscode-extension/README.md",
179
+ commands: VSCODE_COMMANDS,
180
+ doctorCommands: [
181
+ "chainlesschain.ide.doctor",
182
+ "chainlesschain.remote.doctor",
183
+ ],
184
+ },
185
+ jetbrains: {
186
+ actionDescriptor:
187
+ "packages/jetbrains-plugin/src/main/resources/META-INF/plugin.xml",
188
+ bridgeCapabilities:
189
+ "packages/jetbrains-plugin/src/main/java/com/chainlesschain/ide/IdeCapabilities.java",
190
+ minimumCliVersionSource:
191
+ "packages/jetbrains-plugin/src/main/java/com/chainlesschain/ide/RuntimeCompatibility.java",
192
+ doctorImplementation:
193
+ "packages/jetbrains-plugin/src/main/java/com/chainlesschain/ide/intellij/DiagnoseBridgeAction.java",
194
+ readme: "packages/jetbrains-plugin/README.md",
195
+ actions: JETBRAINS_ACTIONS,
196
+ doctorActions: ["chainlesschain.ide.DiagnoseBridge"],
197
+ },
198
+ desktop: {
199
+ commandRegistry:
200
+ "desktop-app-vue/src/renderer/utils/keyboard-shortcuts.ts",
201
+ registryConsumer:
202
+ "desktop-app-vue/src/renderer/components/common/CommandPalette.vue",
203
+ defaultShortcutKeys: DESKTOP_SHORTCUT_KEYS,
204
+ registryContract: [
205
+ "register",
206
+ "registerMultiple",
207
+ "getAllCommands",
208
+ "show-command-palette",
209
+ ],
210
+ // These are existing independent surfaces, not new registries. Recording
211
+ // them keeps this first slice honest while the later P0-0 convergence
212
+ // work replaces their placeholder handlers with canonical consumers.
213
+ unconvergedSurfaces: [
214
+ "desktop-app-vue/src/renderer/shell/CommandPalette.vue",
215
+ "desktop-app-vue/src/renderer/utils/globalSearchManager.ts",
216
+ ],
217
+ },
218
+ },
219
+ });
220
+
221
+ export const PUBLIC_IDE_MANIFEST_OUTPUT =
222
+ "docs/cli/PUBLIC_IDE_CAPABILITY_MANIFEST.generated.json";
223
+
224
+ export const README_BLOCK_START =
225
+ "<!-- chainlesschain-public-ide-capabilities:start -->";
226
+ export const README_BLOCK_END =
227
+ "<!-- chainlesschain-public-ide-capabilities:end -->";
228
+
229
+ export function renderPublicIdeCapabilityManifest(
230
+ manifest = PUBLIC_IDE_CAPABILITY_MANIFEST,
231
+ ) {
232
+ return `${JSON.stringify(
233
+ {
234
+ _generated:
235
+ "packages/cli/scripts/gen-public-ide-capability-manifest.mjs - do not edit by hand",
236
+ ...manifest,
237
+ },
238
+ null,
239
+ 2,
240
+ )}\n`;
241
+ }
242
+
243
+ export function renderPublicIdeReadmeBlock(
244
+ host,
245
+ manifest = PUBLIC_IDE_CAPABILITY_MANIFEST,
246
+ ) {
247
+ const surface = manifest.surfaces[host];
248
+ if (!surface || (host !== "vscode" && host !== "jetbrains")) {
249
+ throw new Error(`Unsupported README host: ${host}`);
250
+ }
251
+ const entries = host === "vscode" ? surface.commands : surface.actions;
252
+ const entryLabel =
253
+ host === "vscode" ? "VS Code commands" : "JetBrains actions";
254
+ const doctorEntries =
255
+ host === "vscode" ? surface.doctorCommands : surface.doctorActions;
256
+ const lines = [
257
+ README_BLOCK_START,
258
+ "",
259
+ "## Public capability contract (generated)",
260
+ "",
261
+ "This summary is pinned to the repository's versioned, secret-free",
262
+ "[`PUBLIC_IDE_CAPABILITY_MANIFEST.generated.json`](../../docs/cli/PUBLIC_IDE_CAPABILITY_MANIFEST.generated.json).",
263
+ `The base IDE/Doctor contract requires \`cc >= ${manifest.minimumCliVersion}\`; feature-specific sections below may require a newer CLI.`,
264
+ "",
265
+ `- ${entryLabel}: **${entries.length}** registered entries`,
266
+ `- Doctor entries: ${doctorEntries.map((id) => `\`${id}\``).join(", ")}`,
267
+ `- Bridge capability schema: **v${manifest.bridge.schemaVersion}** (${manifest.bridge.toolFeatures.length} mapped tools)`,
268
+ "- Drift check: `npm run ide:capabilities:check` from the repository root",
269
+ "",
270
+ `<details><summary>${entryLabel}</summary>`,
271
+ "",
272
+ ...entries.map((id) => `- \`${id}\``),
273
+ "",
274
+ "</details>",
275
+ README_BLOCK_END,
276
+ ];
277
+ return `${lines.join("\n")}\n`;
278
+ }