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.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CJn02U42.js → AIOps-_oxz4VHy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ewURAAoy.js → ActionButton-uaeqFuDj.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BiSadESb.js → Analytics-BPVV0OUf.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BR0WOEug.js → AppLayout-ppCYKm3I.js} +4 -4
- package/src/assets/web-panel/assets/{Audit-CrqcYx0e.js → Audit-DFAY6umk.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DtbSBn4e.js → Backup-pAPBFDyP.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BjSc9j0o.js → BaseInput-BbBl0uT2.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-ixzrlCJE.js → Chat-Ct22JUnT.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-B78nEq05.js → ChatBubbleRenderer-DPlsLl22.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-UGYeSsgr.js → Checkbox-DEkCollc.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B97OOAg4.js → Codegen-Tor-de39.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D9aGkaZ6.js → Col-ojNrLQU7.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Dc2v2RGS.js → Community-CLOGhqMF.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B_FYlUQR.js → Compact-CYKNlSZ4.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-C4FiTHyC.js → Compliance-C5E6ABuA.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CQ8j3LIg.js → Cowork-CHeEsZ3W.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-Dzjs9Z9Z.js → Cron-B4e1n2e7.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BXI24uzI.js → Crosschain-DbNV8P9R.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C-I4_d07.js → DID-C5_Tk3nC.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BzzGh5mo.js → Dashboard-BhdV_c4N.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Bh8H70De.js → Dropdown-CEi5AMtM.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DI_qybJP.js → EmailListRenderer-DOhPiYng.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DkKTsfc4.js → FamilyGuardDashboard-fu4NRP3X.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DS7CmvVG.js → Federation-B7BtIWKL.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CI97WsB5.js → FormItemContext-BmPWZVLP.js} +1 -1
- package/src/assets/web-panel/assets/GenericCardRenderer-hsOPNJq8.js +1 -0
- package/src/assets/web-panel/assets/{Git-CEh0gR2W.js → Git-Bi_EFBUH.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-kIr3tls2.js → Governance-emf2ubDK.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CC1GzyC1.js → Inference-B7KjKzkI.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BNgTiWOB.js → KnowledgeGraph-uAaBK0F3.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B2P10gB1.js → Logs-utK7hNpj.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-HPfBvbFZ.js → Marketplace-CzQe6n3z.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-ByYotSKb.js → McpTools-CuAaJr51.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BGIAzFVS.js → Memory-CRuZZJ75.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CroNYTAH.js → MobileBridge-Cp06wunh.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-DJEdUwhr.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BqhyIwo9.js → Mtc-8YY4dR7g.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BpEKOvx9.js → MtcAudit-BmPJYHar.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DST1d_Qo.js → Multisig-d-ydyVdq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DlMsZcK_.js → NLProgramming-DA_ikw_n.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C734UJvD.js → Notes-DIyF-fRe.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0-pPxvk.js → NotificationSettings-CzPZXEtK.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BiLtg-LY.js +1 -0
- package/src/assets/web-panel/assets/{Organization-C5iHC_yW.js → Organization-DdDZ_Ap6.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CovuHHVR.js → Overflow-BnMBkttv.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Dx9QL-Gy.js → P2P-Es1050f-.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-IP1dEt6-.js → PdhVaultBrowser-CKkRmyn9.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-BrR1XZG5.js → Permissions-zU9n9cAD.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BgqxVE5m.js → PersonalDataHub-BZi5Xwas.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-DzMk5HAz.js → Pipeline-CRfeGiFc.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CDoLa6tk.js → Privacy-CQA_IgLA.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Dy5gc6ve.js → ProjectInit-C9hmEvoT.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DXy-k4hG.js → ProjectSettings-yXA72ws4.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BpWS-qam.js +1 -0
- package/src/assets/web-panel/assets/Providers-Cxe55dRD.js +1 -0
- package/src/assets/web-panel/assets/{QuickAsk-B8KEHCnd.js → QuickAsk-Do0aUTQr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DNVHGYYZ.js → Recommend--ysZHjyA.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-CaDhWP03.js → Reputation-BOBU8JrH.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CrGLI02x.js → Row-C6X7bRKE.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BX7P8I6i.js → RssFeed-D8AwqlkQ.js} +3 -3
- package/src/assets/web-panel/assets/Search-Bi3rCZD4.js +1 -0
- package/src/assets/web-panel/assets/{Security-B6J7IFc1.js → Security-DxUDVrtY.js} +4 -4
- package/src/assets/web-panel/assets/{Services-vvdcO3mM.js → Services-BXXN7yC1.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BoAoPTzZ.js → Skeleton-B3BR34tZ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CyIQV5b3.js → Skills-BjYu8OQ1.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BAQVgdZV.js → Sla-DDkCtD8w.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bxcn1Jkj.js → SpeechSettings-CGhYzP7V.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dpaj3hDM.js → SyncSettings-CYNKVAHA.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Bwqo89En.js → Tasks-DavmlJpd.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bowcqifn.js → Templates-CQuYFf2C.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DOkf85uG.js → Tenant-DdzZh8vE.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-D75WeG9d.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-B9A3zDXA.js → TimelineRenderer-DKOARnc_.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-jtVVqKFr.js → Tokens-D7QRNG8y.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-26Iw-iIl.js → Trigger-BCsqLZl4.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DqY5ORrH.js → Trust-BarGUa6p.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BFsbr3y7.js → UkeySign-pHrg5a8E.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BtDbj3oa.js → VideoEditing-Dug3m1py.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BAwmwHbk.js → Wallet-BfK3Z_Ez.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DINJTsfq.js → WebAuthn-CYRdl9td.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BEorm8SK.js → WorkflowEditor-DTW5AcqM.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CE39-Dxg.js → chat-CCXz4j38.js} +1 -1
- package/src/assets/web-panel/assets/{colors-C_cLZ93a.js → colors-BJBOhAqa.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BSioWA2c.js → compact-item-E9M6BQcM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CGTk4mhN.js → createContext-Cg9CAws4.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BrsbTJUv.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Dl1fRwS_.js → hasIn-DhVtqv5L.js} +1 -1
- package/src/assets/web-panel/assets/{index-pngH1and.js → index--7o5YdL6.js} +1 -1
- package/src/assets/web-panel/assets/{index-BmbVyhk1.js → index-4N5lNXGP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnEPB1Mz.js → index-6-04M2Nx.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cxw3p73X.js → index-B111fZ21.js} +1 -1
- package/src/assets/web-panel/assets/{index-CST381Qf.js → index-B4NBF4Sa.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChwpS1f0.js → index-B8bjEHrQ.js} +1 -1
- package/src/assets/web-panel/assets/{index--SWvw6yW.js → index-BAB0nGP7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAwVwBOL.js → index-BFZPRd0T.js} +1 -1
- package/src/assets/web-panel/assets/{index-hv4jUdG3.js → index-B_SMPD4L.js} +1 -1
- package/src/assets/web-panel/assets/{index-Qj2x55mz.js → index-BxSzyly9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BWpfxzVm.js → index-ByazO4Q9.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di6nvW1N.js → index-C-2dUIli.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhqOTuMW.js → index-CFarAlXj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CA6K7lZB.js → index-CFp-wdrQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTKEXyaW.js → index-CJ8nNT8h.js} +1 -1
- package/src/assets/web-panel/assets/{index-iiZfONfx.js → index-CSiyjCYi.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTpCUi0m.js → index-CUp_c8Le.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bvi14vJ7.js → index-CVR_s-pT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKEipmR8.js → index-Ca8BYV1g.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJyeeygd.js → index-CeRlLp3F.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9tq8Da8.js → index-ChsSljaN.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2QiUEgK.js → index-CkTeBHI9.js} +1 -1
- package/src/assets/web-panel/assets/{index-OCxo0X6J.js → index-Cm1m7BJh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DrWERr8C.js → index-ComyTKz-.js} +1 -1
- package/src/assets/web-panel/assets/{index-B016Fsqr.js → index-CznfPnOx.js} +3 -3
- package/src/assets/web-panel/assets/{index-CisXVbSt.js → index-D5yC2Ps8.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-VVk1Jg.js → index-D7DXdf7x.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDQx2YFc.js → index-DDcJO27F.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ds2RzRG0.js → index-DSQazU6J.js} +1 -1
- package/src/assets/web-panel/assets/index-DSTQDO-Y.js +1 -0
- package/src/assets/web-panel/assets/{index-C4JXchTG.js → index-DaFe1aqY.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAhinBPR.js → index-DdhnGez0.js} +1 -1
- package/src/assets/web-panel/assets/{index-9_mmaR42.js → index-Di5LBXcE.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9D4q-qI.js → index-Dwvewrul.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbXnyoSO.js → index-MdXEhfdJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-II3JhQu2.js → index-_PNqQ5mE.js} +1 -1
- package/src/assets/web-panel/assets/index-c2U6LV3Q.js +1 -0
- package/src/assets/web-panel/assets/{index-C2ly7sCw.js → index-kz1oXl1a.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ceo9P9tQ.js → index-wkt-o5q5.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-GOhLA2-f.js → initDefaultProps-iyBaePF-.js} +1 -1
- package/src/assets/web-panel/assets/{motion-jqxFzHTx.js → motion-RWtj4rgu.js} +1 -1
- package/src/assets/web-panel/assets/{move-CSLsp6TA.js → move-CqPRVzpH.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Cnlrb25c.js → omit-DsvJze25.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CLqlxWWD.js → pickAttrs-B4tfZBhc.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BAWIWtul.js → placementArrow-KvHUwXMA.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CSR1DayS.js → responsiveObserve-DGdJ-b7W.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CNhoPJOp.js → slide-Cd6ebRmw.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BZiYHRHW.js → statusUtils-Bg9GcIAn.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BMoY-Fm5.js → styleChecker-MQjKsG84.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DhtNdlaS.js → useFlexGapSupport-C241WujP.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DNPtDOZ4.js → useFs-CMpy7RS4.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DTdjNvAI.js → usePersonalDataHub-BLHtapKb.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C9zW9IJ2.js → vnode-DmcTV67c.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D-6RYJJr.js → zoom-DHL8_0Y8.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +161 -6
- package/src/commands/agents.js +8 -2
- package/src/commands/cli-anything.js +14 -6
- package/src/commands/command.js +7 -2
- package/src/commands/hook.js +136 -28
- package/src/commands/ide.js +168 -0
- package/src/commands/loop.js +450 -0
- package/src/commands/mcp.js +92 -0
- package/src/commands/output-style.js +127 -0
- package/src/commands/permissions.js +211 -0
- package/src/commands/statusline.js +93 -0
- package/src/index.js +10 -2
- package/src/lib/agent-core.js +7 -0
- package/src/lib/agents.js +5 -0
- package/src/lib/hook-manager.js +1 -0
- package/src/lib/hook-runner.cjs +183 -0
- package/src/lib/ide-bridge.js +310 -0
- package/src/lib/image-input.js +156 -0
- package/src/lib/loop.js +198 -0
- package/src/lib/mcp-oauth.js +415 -0
- package/src/lib/output-styles.js +179 -0
- package/src/lib/permission-rules.cjs +325 -0
- package/src/lib/provider-options.js +11 -7
- package/src/lib/settings-hook-events.cjs +102 -0
- package/src/lib/settings-hooks.cjs +163 -0
- package/src/lib/settings-loader.cjs +244 -0
- package/src/lib/slash-commands.js +4 -0
- package/src/lib/status-line.cjs +204 -0
- package/src/lib/sub-agent-profiles.js +3 -0
- package/src/lib/web-search.js +487 -0
- package/src/repl/agent-repl.js +450 -35
- package/src/repl/slash-macro.js +45 -0
- package/src/runtime/agent-core.js +799 -21
- package/src/runtime/coding-agent-contract-shared.cjs +94 -4
- package/src/runtime/coding-agent-policy.cjs +24 -0
- package/src/runtime/headless-runner.js +162 -6
- package/src/runtime/headless-stream.js +133 -7
- package/src/runtime/mcp-config.js +161 -15
- package/src/runtime/policies/agent-policy.js +4 -0
- package/src/runtime/system-prompt.js +6 -1
- package/src/assets/web-panel/assets/GenericCardRenderer-Da27EdR4.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-CH-qnGEV.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-C7zT9eFc.js +0 -1
- package/src/assets/web-panel/assets/Projects-DvsaEbZR.js +0 -1
- package/src/assets/web-panel/assets/Providers-Demck9PO.js +0 -1
- package/src/assets/web-panel/assets/Search-laS6rz8M.js +0 -1
- package/src/assets/web-panel/assets/Terminal-v4MM9dCj.js +0 -3
- package/src/assets/web-panel/assets/devWarning-PObcVnJR.js +0 -1
- package/src/assets/web-panel/assets/index-BNwIzLyX.js +0 -1
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
261
|
+
await quietShutdown();
|
|
254
262
|
|
|
255
263
|
if (opts.json) {
|
|
256
264
|
console.log(JSON.stringify(result, null, 2));
|
package/src/commands/command.js
CHANGED
|
@@ -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
|
|
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
|
-
:
|
|
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}`));
|
package/src/commands/hook.js
CHANGED
|
@@ -29,9 +29,10 @@ export function registerHookCommand(program) {
|
|
|
29
29
|
// hook list
|
|
30
30
|
hook
|
|
31
31
|
.command("list", { isDefault: true })
|
|
32
|
-
.description("List
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
80
|
-
logger.log(
|
|
81
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
+
}
|