chainlesschain 0.162.35 → 0.162.37

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 (193) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-CJn02U42.js → AIOps-_oxz4VHy.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-ewURAAoy.js → ActionButton-uaeqFuDj.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BiSadESb.js → Analytics-BPVV0OUf.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BR0WOEug.js → AppLayout-ppCYKm3I.js} +4 -4
  6. package/src/assets/web-panel/assets/{Audit-CrqcYx0e.js → Audit-DFAY6umk.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-DtbSBn4e.js → Backup-pAPBFDyP.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-BjSc9j0o.js → BaseInput-BbBl0uT2.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-ixzrlCJE.js → Chat-Ct22JUnT.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-B78nEq05.js → ChatBubbleRenderer-DPlsLl22.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-UGYeSsgr.js → Checkbox-DEkCollc.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-B97OOAg4.js → Codegen-Tor-de39.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-D9aGkaZ6.js → Col-ojNrLQU7.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-Dc2v2RGS.js → Community-CLOGhqMF.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-B_FYlUQR.js → Compact-CYKNlSZ4.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-C4FiTHyC.js → Compliance-C5E6ABuA.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-CQ8j3LIg.js → Cowork-CHeEsZ3W.js} +2 -2
  18. package/src/assets/web-panel/assets/{Cron-Dzjs9Z9Z.js → Cron-B4e1n2e7.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-BXI24uzI.js → Crosschain-DbNV8P9R.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-C-I4_d07.js → DID-C5_Tk3nC.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-BzzGh5mo.js → Dashboard-BhdV_c4N.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-Bh8H70De.js → Dropdown-CEi5AMtM.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-DI_qybJP.js → EmailListRenderer-DOhPiYng.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DkKTsfc4.js → FamilyGuardDashboard-fu4NRP3X.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-DS7CmvVG.js → Federation-B7BtIWKL.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-CI97WsB5.js → FormItemContext-BmPWZVLP.js} +1 -1
  27. package/src/assets/web-panel/assets/GenericCardRenderer-hsOPNJq8.js +1 -0
  28. package/src/assets/web-panel/assets/{Git-CEh0gR2W.js → Git-Bi_EFBUH.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-kIr3tls2.js → Governance-emf2ubDK.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-CC1GzyC1.js → Inference-B7KjKzkI.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-BNgTiWOB.js → KnowledgeGraph-uAaBK0F3.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-B2P10gB1.js → Logs-utK7hNpj.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-HPfBvbFZ.js → Marketplace-CzQe6n3z.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-ByYotSKb.js → McpTools-CuAaJr51.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-BGIAzFVS.js → Memory-CRuZZJ75.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-CroNYTAH.js → MobileBridge-Cp06wunh.js} +2 -2
  37. package/src/assets/web-panel/assets/MobileProjects-DJEdUwhr.js +1 -0
  38. package/src/assets/web-panel/assets/{Mtc-BqhyIwo9.js → Mtc-8YY4dR7g.js} +2 -2
  39. package/src/assets/web-panel/assets/{MtcAudit-BpEKOvx9.js → MtcAudit-BmPJYHar.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-DST1d_Qo.js → Multisig-d-ydyVdq.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-DlMsZcK_.js → NLProgramming-DA_ikw_n.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-C734UJvD.js → Notes-DIyF-fRe.js} +3 -3
  43. package/src/assets/web-panel/assets/{NotificationSettings-C0-pPxvk.js → NotificationSettings-CzPZXEtK.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-BiLtg-LY.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-C5iHC_yW.js → Organization-DdDZ_Ap6.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-CovuHHVR.js → Overflow-BnMBkttv.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-Dx9QL-Gy.js → P2P-Es1050f-.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-IP1dEt6-.js → PdhVaultBrowser-CKkRmyn9.js} +4 -4
  49. package/src/assets/web-panel/assets/{Permissions-BrR1XZG5.js → Permissions-zU9n9cAD.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-BgqxVE5m.js → PersonalDataHub-BZi5Xwas.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-DzMk5HAz.js → Pipeline-CRfeGiFc.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-CDoLa6tk.js → Privacy-CQA_IgLA.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-Dy5gc6ve.js → ProjectInit-C9hmEvoT.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-DXy-k4hG.js → ProjectSettings-yXA72ws4.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-BpWS-qam.js +1 -0
  56. package/src/assets/web-panel/assets/Providers-Cxe55dRD.js +1 -0
  57. package/src/assets/web-panel/assets/{QuickAsk-B8KEHCnd.js → QuickAsk-Do0aUTQr.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-DNVHGYYZ.js → Recommend--ysZHjyA.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-CaDhWP03.js → Reputation-BOBU8JrH.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-CrGLI02x.js → Row-C6X7bRKE.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-BX7P8I6i.js → RssFeed-D8AwqlkQ.js} +3 -3
  62. package/src/assets/web-panel/assets/Search-Bi3rCZD4.js +1 -0
  63. package/src/assets/web-panel/assets/{Security-B6J7IFc1.js → Security-DxUDVrtY.js} +4 -4
  64. package/src/assets/web-panel/assets/{Services-vvdcO3mM.js → Services-BXXN7yC1.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-BoAoPTzZ.js → Skeleton-B3BR34tZ.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-CyIQV5b3.js → Skills-BjYu8OQ1.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-BAQVgdZV.js → Sla-DDkCtD8w.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-Bxcn1Jkj.js → SpeechSettings-CGhYzP7V.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-Dpaj3hDM.js → SyncSettings-CYNKVAHA.js} +2 -2
  70. package/src/assets/web-panel/assets/{Tasks-Bwqo89En.js → Tasks-DavmlJpd.js} +1 -1
  71. package/src/assets/web-panel/assets/{Templates-Bowcqifn.js → Templates-CQuYFf2C.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-DOkf85uG.js → Tenant-DdzZh8vE.js} +1 -1
  73. package/src/assets/web-panel/assets/Terminal-D75WeG9d.js +3 -0
  74. package/src/assets/web-panel/assets/{TimelineRenderer-B9A3zDXA.js → TimelineRenderer-DKOARnc_.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-jtVVqKFr.js → Tokens-D7QRNG8y.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-26Iw-iIl.js → Trigger-BCsqLZl4.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-DqY5ORrH.js → Trust-BarGUa6p.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-BFsbr3y7.js → UkeySign-pHrg5a8E.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-BtDbj3oa.js → VideoEditing-Dug3m1py.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-BAwmwHbk.js → Wallet-BfK3Z_Ez.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-DINJTsfq.js → WebAuthn-CYRdl9td.js} +5 -5
  82. package/src/assets/web-panel/assets/{WorkflowEditor-BEorm8SK.js → WorkflowEditor-DTW5AcqM.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-CE39-Dxg.js → chat-CCXz4j38.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-C_cLZ93a.js → colors-BJBOhAqa.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-BSioWA2c.js → compact-item-E9M6BQcM.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-CGTk4mhN.js → createContext-Cg9CAws4.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-BrsbTJUv.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-Dl1fRwS_.js → hasIn-DhVtqv5L.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-pngH1and.js → index--7o5YdL6.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-BmbVyhk1.js → index-4N5lNXGP.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-BnEPB1Mz.js → index-6-04M2Nx.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-Cxw3p73X.js → index-B111fZ21.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-CST381Qf.js → index-B4NBF4Sa.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-ChwpS1f0.js → index-B8bjEHrQ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index--SWvw6yW.js → index-BAB0nGP7.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CAwVwBOL.js → index-BFZPRd0T.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-hv4jUdG3.js → index-B_SMPD4L.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Qj2x55mz.js → index-BxSzyly9.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BWpfxzVm.js → index-ByazO4Q9.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Di6nvW1N.js → index-C-2dUIli.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BhqOTuMW.js → index-CFarAlXj.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CA6K7lZB.js → index-CFp-wdrQ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DTKEXyaW.js → index-CJ8nNT8h.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-iiZfONfx.js → index-CSiyjCYi.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DTpCUi0m.js → index-CUp_c8Le.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Bvi14vJ7.js → index-CVR_s-pT.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DKEipmR8.js → index-Ca8BYV1g.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DJyeeygd.js → index-CeRlLp3F.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C9tq8Da8.js → index-ChsSljaN.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B2QiUEgK.js → index-CkTeBHI9.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-OCxo0X6J.js → index-Cm1m7BJh.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DrWERr8C.js → index-ComyTKz-.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B016Fsqr.js → index-CznfPnOx.js} +3 -3
  114. package/src/assets/web-panel/assets/{index-CisXVbSt.js → index-D5yC2Ps8.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C-VVk1Jg.js → index-D7DXdf7x.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DDQx2YFc.js → index-DDcJO27F.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Ds2RzRG0.js → index-DSQazU6J.js} +1 -1
  118. package/src/assets/web-panel/assets/index-DSTQDO-Y.js +1 -0
  119. package/src/assets/web-panel/assets/{index-C4JXchTG.js → index-DaFe1aqY.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BAhinBPR.js → index-DdhnGez0.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-9_mmaR42.js → index-Di5LBXcE.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-D9D4q-qI.js → index-Dwvewrul.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CbXnyoSO.js → index-MdXEhfdJ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-II3JhQu2.js → index-_PNqQ5mE.js} +1 -1
  125. package/src/assets/web-panel/assets/index-c2U6LV3Q.js +1 -0
  126. package/src/assets/web-panel/assets/{index-C2ly7sCw.js → index-kz1oXl1a.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Ceo9P9tQ.js → index-wkt-o5q5.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-GOhLA2-f.js → initDefaultProps-iyBaePF-.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-jqxFzHTx.js → motion-RWtj4rgu.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-CSLsp6TA.js → move-CqPRVzpH.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-Cnlrb25c.js → omit-DsvJze25.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-CLqlxWWD.js → pickAttrs-B4tfZBhc.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-BAWIWtul.js → placementArrow-KvHUwXMA.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-CSR1DayS.js → responsiveObserve-DGdJ-b7W.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-CNhoPJOp.js → slide-Cd6ebRmw.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-BZiYHRHW.js → statusUtils-Bg9GcIAn.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-BMoY-Fm5.js → styleChecker-MQjKsG84.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-DhtNdlaS.js → useFlexGapSupport-C241WujP.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-DNPtDOZ4.js → useFs-CMpy7RS4.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-DTdjNvAI.js → usePersonalDataHub-BLHtapKb.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-C9zW9IJ2.js → vnode-DmcTV67c.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-D-6RYJJr.js → zoom-DHL8_0Y8.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/agent.js +161 -6
  145. package/src/commands/agents.js +8 -2
  146. package/src/commands/cli-anything.js +14 -6
  147. package/src/commands/command.js +7 -2
  148. package/src/commands/hook.js +136 -28
  149. package/src/commands/ide.js +168 -0
  150. package/src/commands/loop.js +450 -0
  151. package/src/commands/mcp.js +92 -0
  152. package/src/commands/output-style.js +127 -0
  153. package/src/commands/permissions.js +211 -0
  154. package/src/commands/statusline.js +93 -0
  155. package/src/index.js +10 -2
  156. package/src/lib/agent-core.js +7 -0
  157. package/src/lib/agents.js +5 -0
  158. package/src/lib/hook-manager.js +1 -0
  159. package/src/lib/hook-runner.cjs +183 -0
  160. package/src/lib/ide-bridge.js +310 -0
  161. package/src/lib/image-input.js +156 -0
  162. package/src/lib/loop.js +198 -0
  163. package/src/lib/mcp-oauth.js +415 -0
  164. package/src/lib/output-styles.js +179 -0
  165. package/src/lib/permission-rules.cjs +325 -0
  166. package/src/lib/provider-options.js +11 -7
  167. package/src/lib/settings-hook-events.cjs +102 -0
  168. package/src/lib/settings-hooks.cjs +163 -0
  169. package/src/lib/settings-loader.cjs +244 -0
  170. package/src/lib/slash-commands.js +4 -0
  171. package/src/lib/status-line.cjs +204 -0
  172. package/src/lib/sub-agent-profiles.js +3 -0
  173. package/src/lib/web-search.js +487 -0
  174. package/src/repl/agent-repl.js +450 -35
  175. package/src/repl/slash-macro.js +45 -0
  176. package/src/runtime/agent-core.js +799 -21
  177. package/src/runtime/coding-agent-contract-shared.cjs +94 -4
  178. package/src/runtime/coding-agent-policy.cjs +24 -0
  179. package/src/runtime/headless-runner.js +162 -6
  180. package/src/runtime/headless-stream.js +133 -7
  181. package/src/runtime/mcp-config.js +161 -15
  182. package/src/runtime/policies/agent-policy.js +4 -0
  183. package/src/runtime/system-prompt.js +6 -1
  184. package/src/assets/web-panel/assets/GenericCardRenderer-Da27EdR4.js +0 -1
  185. package/src/assets/web-panel/assets/MobileProjects-CH-qnGEV.js +0 -1
  186. package/src/assets/web-panel/assets/OrderTableRenderer-C7zT9eFc.js +0 -1
  187. package/src/assets/web-panel/assets/Projects-DvsaEbZR.js +0 -1
  188. package/src/assets/web-panel/assets/Providers-Demck9PO.js +0 -1
  189. package/src/assets/web-panel/assets/Search-laS6rz8M.js +0 -1
  190. package/src/assets/web-panel/assets/Terminal-v4MM9dCj.js +0 -3
  191. package/src/assets/web-panel/assets/devWarning-PObcVnJR.js +0 -1
  192. package/src/assets/web-panel/assets/index-BNwIzLyX.js +0 -1
  193. package/src/assets/web-panel/assets/index-Dh6FxR9B.js +0 -1
@@ -6,6 +6,7 @@
6
6
  import chalk from "chalk";
7
7
  import { logger } from "../lib/logger.js";
8
8
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
9
+ import { withQuietStdout } from "../runtime/quiet-stdout.js";
9
10
  import {
10
11
  ensureCliAnythingTables,
11
12
  detectPython,
@@ -17,6 +18,13 @@ import {
17
18
  listTools,
18
19
  } from "../lib/cli-anything-bridge.js";
19
20
 
21
+ // bootstrap()/shutdown() log "[AppConfig] …" and "[DatabaseManager] …" via
22
+ // console.info, which Node writes to stdout. That chatter corrupts the JSON
23
+ // emitted by `--json` subcommands. Divert it to stderr (the diagnostic
24
+ // channel) so stdout stays a pristine machine-readable payload.
25
+ const quietBootstrap = (opts) => withQuietStdout(() => bootstrap(opts));
26
+ const quietShutdown = () => withQuietStdout(() => shutdown());
27
+
20
28
  export function registerCliAnythingCommand(program) {
21
29
  const cliAny = program
22
30
  .command("cli-anything")
@@ -135,7 +143,7 @@ export function registerCliAnythingCommand(program) {
135
143
  .option("--json", "Output as JSON")
136
144
  .action(async (name, opts) => {
137
145
  try {
138
- const ctx = await bootstrap({ verbose: program.opts().verbose });
146
+ const ctx = await quietBootstrap({ verbose: program.opts().verbose });
139
147
  if (!ctx.db) {
140
148
  logger.error(
141
149
  "Database not available. Run `chainlesschain setup` first.",
@@ -154,7 +162,7 @@ export function registerCliAnythingCommand(program) {
154
162
  force: opts.force,
155
163
  });
156
164
 
157
- await shutdown();
165
+ await quietShutdown();
158
166
 
159
167
  if (opts.json) {
160
168
  console.log(JSON.stringify(result, null, 2));
@@ -188,7 +196,7 @@ export function registerCliAnythingCommand(program) {
188
196
  .option("--json", "Output as JSON")
189
197
  .action(async (opts) => {
190
198
  try {
191
- const ctx = await bootstrap({ verbose: program.opts().verbose });
199
+ const ctx = await quietBootstrap({ verbose: program.opts().verbose });
192
200
  if (!ctx.db) {
193
201
  logger.error("Database not available.");
194
202
  process.exit(1);
@@ -197,7 +205,7 @@ export function registerCliAnythingCommand(program) {
197
205
  ensureCliAnythingTables(db);
198
206
 
199
207
  const tools = listTools(db);
200
- await shutdown();
208
+ await quietShutdown();
201
209
 
202
210
  if (opts.json) {
203
211
  console.log(JSON.stringify(tools, null, 2));
@@ -241,7 +249,7 @@ export function registerCliAnythingCommand(program) {
241
249
  .option("--json", "Output as JSON")
242
250
  .action(async (name, opts) => {
243
251
  try {
244
- const ctx = await bootstrap({ verbose: program.opts().verbose });
252
+ const ctx = await quietBootstrap({ verbose: program.opts().verbose });
245
253
  if (!ctx.db) {
246
254
  logger.error("Database not available.");
247
255
  process.exit(1);
@@ -250,7 +258,7 @@ export function registerCliAnythingCommand(program) {
250
258
  ensureCliAnythingTables(db);
251
259
 
252
260
  const result = removeTool(db, name);
253
- await shutdown();
261
+ await quietShutdown();
254
262
 
255
263
  if (opts.json) {
256
264
  console.log(JSON.stringify(result, null, 2));
@@ -145,8 +145,9 @@ export function registerCommandCommand(program) {
145
145
  // ── new (scaffold) ────────────────────────────────────────────────────
146
146
  cmd
147
147
  .command("new <name>")
148
- .description("Scaffold a new command file under .claude/commands/")
148
+ .description("Scaffold a new command file (project-native .chainlesschain/commands/)")
149
149
  .option("--description <d>", "Frontmatter description")
150
+ .option("--claude", "Create under .claude/commands (Claude-Code-portable)")
150
151
  .option("--personal", "Create under ~/.claude/commands instead of project")
151
152
  .action(async (name, options) => {
152
153
  try {
@@ -154,9 +155,13 @@ export function registerCommandCommand(program) {
154
155
  const path = await import("node:path");
155
156
  const { homedir } = await import("node:os");
156
157
  const safe = String(name).replace(/^\//, "").replace(/:/g, "/");
158
+ // Project commands go to the native `.chainlesschain/commands/`; use
159
+ // --claude for the portable `.claude/commands/`, --personal for home.
157
160
  const root = options.personal
158
161
  ? path.join(homedir(), ".claude", "commands")
159
- : path.join(process.cwd(), ".claude", "commands");
162
+ : options.claude
163
+ ? path.join(process.cwd(), ".claude", "commands")
164
+ : path.join(process.cwd(), ".chainlesschain", "commands");
160
165
  const file = path.join(root, `${safe}.md`);
161
166
  if (fs.existsSync(file)) {
162
167
  logger.error(chalk.red(`already exists: ${file}`));
@@ -29,9 +29,10 @@ export function registerHookCommand(program) {
29
29
  // hook list
30
30
  hook
31
31
  .command("list", { isDefault: true })
32
- .description("List all registered hooks")
32
+ .description("List registered hooks (DB) + .claude/settings.json hooks")
33
33
  .option("--event <name>", "Filter by event name")
34
34
  .option("--enabled", "Show only enabled hooks")
35
+ .option("--settings <file>", "Also merge an explicit settings file")
35
36
  .option("--json", "Output as JSON")
36
37
  .action(async (options) => {
37
38
  try {
@@ -46,43 +47,76 @@ export function registerHookCommand(program) {
46
47
  enabledOnly: options.enabled,
47
48
  });
48
49
 
50
+ // .claude/settings.json `hooks` block (Claude-Code parity, decision-
51
+ // capable; distinct from the DB registry above which is observe-only).
52
+ const { loadHooks } = await import("../lib/settings-hooks.cjs");
53
+ const { hooks: settingsHooks, files: settingsFiles } = loadHooks({
54
+ cwd: process.cwd(),
55
+ settingsFile: options.settings,
56
+ });
57
+
49
58
  if (options.json) {
50
59
  console.log(
51
60
  JSON.stringify(
52
- hooks.map((h) => ({
53
- id: h.id,
54
- event: h.event,
55
- name: h.name,
56
- type: h.type,
57
- priority: h.priority,
58
- enabled: h.enabled === 1,
59
- matcher: h.matcher,
60
- description: h.description,
61
- })),
61
+ {
62
+ hooks: hooks.map((h) => ({
63
+ id: h.id,
64
+ event: h.event,
65
+ name: h.name,
66
+ type: h.type,
67
+ priority: h.priority,
68
+ enabled: h.enabled === 1,
69
+ matcher: h.matcher,
70
+ description: h.description,
71
+ })),
72
+ settingsHooks,
73
+ settingsFiles,
74
+ },
62
75
  null,
63
76
  2,
64
77
  ),
65
78
  );
66
- } else if (hooks.length === 0) {
67
- logger.info(
68
- 'No hooks registered. Add one with "chainlesschain hook add <event> <name>"',
69
- );
70
79
  } else {
71
- logger.log(chalk.bold(`Hooks (${hooks.length}):\n`));
72
- for (const h of hooks) {
73
- const status = h.enabled
74
- ? chalk.green("enabled")
75
- : chalk.gray("disabled");
76
- const pLabel = Object.entries(HookPriority).find(
77
- ([, v]) => v === h.priority,
80
+ if (hooks.length === 0) {
81
+ logger.info(
82
+ 'No DB hooks. Add one with "chainlesschain hook add <event> <name>"',
78
83
  );
79
- const priorityStr = pLabel ? pLabel[0] : String(h.priority);
80
- logger.log(
81
- ` ${chalk.cyan(h.name)} [${h.event}] priority=${priorityStr} type=${h.type} [${status}]`,
84
+ } else {
85
+ logger.log(chalk.bold(`DB hooks (${hooks.length}):\n`));
86
+ for (const h of hooks) {
87
+ const status = h.enabled
88
+ ? chalk.green("enabled")
89
+ : chalk.gray("disabled");
90
+ const pLabel = Object.entries(HookPriority).find(
91
+ ([, v]) => v === h.priority,
92
+ );
93
+ const priorityStr = pLabel ? pLabel[0] : String(h.priority);
94
+ logger.log(
95
+ ` ${chalk.cyan(h.name)} [${h.event}] priority=${priorityStr} type=${h.type} [${status}]`,
96
+ );
97
+ if (h.description) logger.log(` ${chalk.gray(h.description)}`);
98
+ if (h.matcher)
99
+ logger.log(` matcher: ${chalk.yellow(h.matcher)}`);
100
+ }
101
+ }
102
+ const events = Object.keys(settingsHooks);
103
+ if (events.length > 0) {
104
+ const n = events.reduce(
105
+ (a, e) => a + settingsHooks[e].length,
106
+ 0,
82
107
  );
83
- if (h.description) logger.log(` ${chalk.gray(h.description)}`);
84
- if (h.matcher)
85
- logger.log(` matcher: ${chalk.yellow(h.matcher)}`);
108
+ logger.log(chalk.bold(`\n.claude/settings.json hooks (${n}):`));
109
+ for (const ev of events) {
110
+ if (options.event && ev !== options.event) continue;
111
+ for (const g of settingsHooks[ev]) {
112
+ for (const h of g.hooks) {
113
+ logger.log(
114
+ ` ${chalk.cyan(ev)} matcher=${chalk.yellow(g.matcher || "*")} ${chalk.gray(h.command)}`,
115
+ );
116
+ }
117
+ }
118
+ }
119
+ logger.log(chalk.dim(` sources: ${settingsFiles.join(", ")}`));
86
120
  }
87
121
  }
88
122
 
@@ -93,6 +127,80 @@ export function registerHookCommand(program) {
93
127
  }
94
128
  });
95
129
 
130
+ // hook test — dry-run .claude/settings.json hooks for an event + tool
131
+ hook
132
+ .command("test <event> <tool> [args...]")
133
+ .description(
134
+ 'Show which settings.json hooks fire for an event+tool (e.g. hook test PreToolUse run_shell "git push"); --run executes them',
135
+ )
136
+ .option("--settings <file>", "Also merge an explicit settings file")
137
+ .option("--run", "Actually execute the matched hooks and show decisions")
138
+ .option("--json", "Output as JSON")
139
+ .action(async (event, tool, args, options) => {
140
+ try {
141
+ const { loadHooks, collectHooks } =
142
+ await import("../lib/settings-hooks.cjs");
143
+ const { hooks } = loadHooks({
144
+ cwd: process.cwd(),
145
+ settingsFile: options.settings,
146
+ });
147
+ const matched = collectHooks(hooks, event, tool);
148
+ const toolInput = args && args.length ? { command: args.join(" "), args } : {};
149
+ const payload = {
150
+ hook_event_name: event,
151
+ tool_name: tool,
152
+ tool_input: toolInput,
153
+ cwd: process.cwd(),
154
+ session_id: "test",
155
+ };
156
+
157
+ if (!options.run) {
158
+ if (options.json) {
159
+ console.log(JSON.stringify({ event, tool, matched, payload }, null, 2));
160
+ } else if (matched.length === 0) {
161
+ logger.log(
162
+ chalk.gray(`no settings.json hooks match ${event} / ${tool}`),
163
+ );
164
+ } else {
165
+ logger.log(
166
+ chalk.bold(`${matched.length} hook(s) would fire for ${event} / ${tool}:`),
167
+ );
168
+ for (const h of matched) logger.log(` ${chalk.gray(h.command)}`);
169
+ logger.log(chalk.dim(" (use --run to execute and see decisions)"));
170
+ }
171
+ return;
172
+ }
173
+
174
+ const { runHooks } = await import("../lib/hook-runner.cjs");
175
+ const outcome = runHooks(matched, payload, {
176
+ cwd: process.cwd(),
177
+ event,
178
+ });
179
+ if (options.json) {
180
+ console.log(JSON.stringify(outcome, null, 2));
181
+ return;
182
+ }
183
+ const color =
184
+ outcome.decision === "block"
185
+ ? chalk.red
186
+ : outcome.decision === "ask"
187
+ ? chalk.yellow
188
+ : chalk.green;
189
+ logger.log(`decision: ${color.bold(outcome.decision)}`);
190
+ if (outcome.reason) logger.log(`reason: ${outcome.reason}`);
191
+ if (outcome.hook) logger.log(`from: ${chalk.gray(outcome.hook)}`);
192
+ for (const r of outcome.results) {
193
+ logger.log(
194
+ ` ${chalk.gray(r.command)} → ${r.decision}` +
195
+ (r.exitCode != null ? ` (exit ${r.exitCode})` : ""),
196
+ );
197
+ }
198
+ } catch (err) {
199
+ logger.error(`hook test failed: ${err.message}`);
200
+ process.exitCode = 1;
201
+ }
202
+ });
203
+
96
204
  // hook add
97
205
  hook
98
206
  .command("add")
@@ -0,0 +1,168 @@
1
+ /**
2
+ * `cc ide` — inspect IDE bridge discovery (Phase 0).
3
+ *
4
+ * The agent auto-connects a running editor's MCP server when inside an IDE
5
+ * integrated terminal (or with `cc agent --ide`). These subcommands make that
6
+ * discovery visible and debuggable WITHOUT running an agent:
7
+ *
8
+ * cc ide list list live IDE lockfiles found
9
+ * cc ide status which server `cc agent` would connect to (+ its MCP config)
10
+ * cc ide doctor explain WHY discovery did / didn't pick a server
11
+ *
12
+ * Pure read-only over ~/.chainlesschain/ide/*.json — see
13
+ * docs/design/modules/98_IDE桥接对标方案.md.
14
+ */
15
+ import chalk from "chalk";
16
+ import {
17
+ readIdeLocks,
18
+ discoverIdeServer,
19
+ ideServerToMcpConfig,
20
+ isInIdeTerminal,
21
+ ideLockDir,
22
+ diagnoseIde,
23
+ } from "../lib/ide-bridge.js";
24
+
25
+ function emit(obj) {
26
+ console.log(JSON.stringify(obj, null, 2));
27
+ }
28
+
29
+ export function registerIdeCommand(program) {
30
+ const ide = program
31
+ .command("ide")
32
+ .description("Inspect IDE bridge discovery (editor MCP server auto-connect)");
33
+
34
+ ide
35
+ .command("list")
36
+ .description("List live IDE lockfiles (editor MCP servers advertised)")
37
+ .option("--json", "Machine-readable output")
38
+ .action((options) => {
39
+ const locks = readIdeLocks();
40
+ if (options.json) {
41
+ // Never surface the raw bearer token or internal _file path.
42
+ const safe = locks.map(({ token, _file, ...rest }) => ({
43
+ ...rest,
44
+ hasToken: !!token,
45
+ }));
46
+ emit({ lockDir: ideLockDir(), count: safe.length, locks: safe });
47
+ return;
48
+ }
49
+ if (!locks.length) {
50
+ console.log(
51
+ chalk.gray(`No live IDE lockfiles in ${ideLockDir()}`),
52
+ );
53
+ console.log(
54
+ chalk.gray(
55
+ "Start an IDE extension that advertises one, or run `cc ide doctor`.",
56
+ ),
57
+ );
58
+ return;
59
+ }
60
+ console.log(chalk.bold(`IDE servers (${locks.length}) in ${ideLockDir()}:`));
61
+ for (const l of locks) {
62
+ console.log(
63
+ ` ${chalk.cyan(l.ide)} port ${l.port} ${l.transport} ` +
64
+ `${l.token ? chalk.green("token") : chalk.yellow("no-token")}`,
65
+ );
66
+ console.log(chalk.gray(` url ${l.url}`));
67
+ if (l.workspaceFolders.length) {
68
+ console.log(chalk.gray(` ws ${l.workspaceFolders.join(", ")}`));
69
+ }
70
+ }
71
+ });
72
+
73
+ ide
74
+ .command("status")
75
+ .description("Show the IDE server `cc agent` would connect to right now")
76
+ .option("--ide", "Force selection even outside an IDE terminal")
77
+ .option("--json", "Machine-readable output")
78
+ .action((options) => {
79
+ const env = process.env;
80
+ const cwd = process.cwd();
81
+ const inIde = isInIdeTerminal(env);
82
+ const lock = discoverIdeServer({ cwd, env, force: options.ide === true });
83
+ const cfg = lock ? ideServerToMcpConfig(lock) : null;
84
+ // Redact the bearer token in the previewed config.
85
+ const safeCfg = cfg
86
+ ? {
87
+ ...cfg,
88
+ headers: cfg.headers?.Authorization
89
+ ? { ...cfg.headers, Authorization: "Bearer ***" }
90
+ : cfg.headers,
91
+ }
92
+ : null;
93
+ if (options.json) {
94
+ // Strip the raw token + internal _file from the chosen lock.
95
+ const safeChosen = lock
96
+ ? (({ token, _file, ...rest }) => ({ ...rest, hasToken: !!token }))(
97
+ lock,
98
+ )
99
+ : null;
100
+ emit({
101
+ inIdeTerminal: inIde,
102
+ chosen: safeChosen,
103
+ mcpConfig: safeCfg,
104
+ });
105
+ return;
106
+ }
107
+ console.log(
108
+ `In IDE terminal: ${inIde ? chalk.green("yes") : chalk.gray("no")}`,
109
+ );
110
+ if (!lock) {
111
+ console.log(
112
+ chalk.gray(
113
+ "No IDE server would be connected. Try `cc ide doctor` for why.",
114
+ ),
115
+ );
116
+ return;
117
+ }
118
+ console.log(
119
+ `Would connect: ${chalk.cyan(lock.ide)} on port ${lock.port} ` +
120
+ `(${lock.transport}) as MCP server ${chalk.bold("ide")}`,
121
+ );
122
+ console.log(chalk.gray("MCP config:"));
123
+ console.log(chalk.gray(" " + JSON.stringify(safeCfg)));
124
+ });
125
+
126
+ ide
127
+ .command("doctor")
128
+ .description("Explain why IDE discovery did / didn't pick a server")
129
+ .option("--ide", "Diagnose as if --ide (force) were passed")
130
+ .option("--json", "Machine-readable output")
131
+ .action((options) => {
132
+ const diag = diagnoseIde({
133
+ cwd: process.cwd(),
134
+ env: process.env,
135
+ force: options.ide === true,
136
+ });
137
+ if (options.json) {
138
+ emit(diag);
139
+ return;
140
+ }
141
+ console.log(chalk.bold("IDE bridge discovery"));
142
+ console.log(` lock dir : ${diag.lockDir}`);
143
+ console.log(
144
+ ` in IDE terminal: ${diag.inIdeTerminal ? chalk.green("yes") : chalk.gray("no")}`,
145
+ );
146
+ console.log(` live locks : ${diag.locks.length}`);
147
+ for (const l of diag.locks) {
148
+ const m =
149
+ l.matchScore >= 0
150
+ ? chalk.green(`workspace-match(${l.matchScore})`)
151
+ : chalk.yellow("no-workspace-match");
152
+ console.log(
153
+ ` - ${chalk.cyan(l.ide)} port ${l.port} ${l.transport} ` +
154
+ `${l.hasToken ? "token" : chalk.yellow("no-token")} ${m}`,
155
+ );
156
+ }
157
+ console.log(
158
+ ` result : ${
159
+ diag.chosen
160
+ ? chalk.green(`connect ${diag.chosen.ide}:${diag.chosen.port}`)
161
+ : chalk.yellow("nothing to connect")
162
+ }`,
163
+ );
164
+ console.log(` reason : ${diag.reason}`);
165
+ });
166
+
167
+ return ide;
168
+ }