chainlesschain 0.162.35 → 0.162.36
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-vAVAFNJ4.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ewURAAoy.js → ActionButton-BnRHFCKM.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BiSadESb.js → Analytics-BOjwqWqG.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BR0WOEug.js → AppLayout-Dc0D1Txn.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-CrqcYx0e.js → Audit-dd_2efaZ.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DtbSBn4e.js → Backup-HF1jgm8G.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BjSc9j0o.js → BaseInput-CCtzmoKe.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-ixzrlCJE.js → Chat-BNfH1c3p.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-B78nEq05.js → ChatBubbleRenderer-DCWFqmI4.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-UGYeSsgr.js → Checkbox-BOr-NscK.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B97OOAg4.js → Codegen-DE058N7-.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D9aGkaZ6.js → Col-SOREo1XE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Dc2v2RGS.js → Community-sOvNZo9f.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B_FYlUQR.js → Compact-DnBe558D.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-C4FiTHyC.js → Compliance-o-r6CUbg.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CQ8j3LIg.js → Cowork-D6_k9mHP.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Dzjs9Z9Z.js → Cron-CEV3Xkrm.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BXI24uzI.js → Crosschain-eJ1lQWKU.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C-I4_d07.js → DID-B-WqM9Hp.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BzzGh5mo.js → Dashboard-ZnKPcsHN.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Bh8H70De.js → Dropdown-B8uLWDIP.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DI_qybJP.js → EmailListRenderer-Jmj2Y7aH.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DkKTsfc4.js → FamilyGuardDashboard-Cb2xetG-.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DS7CmvVG.js → Federation-C_07GXoq.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CI97WsB5.js → FormItemContext-D3kbYrMU.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Da27EdR4.js → GenericCardRenderer-9xgqvGPg.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CEh0gR2W.js → Git-BlwWlMMB.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-kIr3tls2.js → Governance-DxN3wQZ_.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CC1GzyC1.js → Inference-ls7pSw_D.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BNgTiWOB.js → KnowledgeGraph-_n9hYuPI.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B2P10gB1.js → Logs-CvEVY5TK.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-HPfBvbFZ.js → Marketplace-C3qvQJT7.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-ByYotSKb.js → McpTools-DiwKpnKx.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BGIAzFVS.js → Memory-CIBPi_da.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CroNYTAH.js → MobileBridge-D-v0Se8y.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-cP1apTQD.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BqhyIwo9.js → Mtc-BMFWrI65.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BpEKOvx9.js → MtcAudit-2s8LaHtR.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DST1d_Qo.js → Multisig-dL_nvj7d.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DlMsZcK_.js → NLProgramming-BbrJp06R.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C734UJvD.js → Notes-jR9irwy3.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0-pPxvk.js → NotificationSettings-Dk-STCIX.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C7zT9eFc.js → OrderTableRenderer-CqqfY6zq.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-C5iHC_yW.js → Organization-BCK5jylo.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CovuHHVR.js → Overflow-BRAY7Smt.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Dx9QL-Gy.js → P2P-BltVRGjb.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-IP1dEt6-.js → PdhVaultBrowser-CV8UbXHe.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-BrR1XZG5.js → Permissions-_tNl47Qh.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BgqxVE5m.js → PersonalDataHub-Cgc4HjpX.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-DzMk5HAz.js → Pipeline-Bn_QU4mu.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CDoLa6tk.js → Privacy-jzJowp5P.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Dy5gc6ve.js → ProjectInit-B_1pJ8qd.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DXy-k4hG.js → ProjectSettings-CPVZpXzs.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CQsHOWnT.js +1 -0
- package/src/assets/web-panel/assets/Providers-CzzMiLC0.js +1 -0
- package/src/assets/web-panel/assets/{QuickAsk-B8KEHCnd.js → QuickAsk-MxBKIn9o.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DNVHGYYZ.js → Recommend-D8lN6Lis.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-CaDhWP03.js → Reputation-CfYK-IrV.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CrGLI02x.js → Row-Bg7NZDP9.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BX7P8I6i.js → RssFeed-BOVNJhj0.js} +3 -3
- package/src/assets/web-panel/assets/Search-B38qzmhY.js +1 -0
- package/src/assets/web-panel/assets/{Security-B6J7IFc1.js → Security-CjqleZpe.js} +4 -4
- package/src/assets/web-panel/assets/{Services-vvdcO3mM.js → Services-Bu9JSJap.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BoAoPTzZ.js → Skeleton-B2RvRkaX.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CyIQV5b3.js → Skills-_h42mxMN.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BAQVgdZV.js → Sla-BssLs56D.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bxcn1Jkj.js → SpeechSettings-DCxFYHsd.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dpaj3hDM.js → SyncSettings-D2xQuNLE.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Bwqo89En.js → Tasks-DhpOGOlo.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bowcqifn.js → Templates-CYG-R-aS.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DOkf85uG.js → Tenant-BQRYLsvP.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-v4MM9dCj.js → Terminal-imKU7N5j.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B9A3zDXA.js → TimelineRenderer-BIZzBftk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-jtVVqKFr.js → Tokens-uMLH5p_a.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-26Iw-iIl.js → Trigger-BzS6XPqx.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DqY5ORrH.js → Trust-R4zhHufZ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BFsbr3y7.js → UkeySign-DATQCoGe.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BtDbj3oa.js → VideoEditing-ClUmKOtS.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BAwmwHbk.js → Wallet-DzJTbQzD.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DINJTsfq.js → WebAuthn-CrXrLmzQ.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BEorm8SK.js → WorkflowEditor-CpvZ0Tma.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CE39-Dxg.js → chat-a6wpYmVL.js} +1 -1
- package/src/assets/web-panel/assets/{colors-C_cLZ93a.js → colors-CXJADb1t.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BSioWA2c.js → compact-item-CL2pohS_.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CGTk4mhN.js → createContext-xFi_1G5_.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BtmELbtB.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Dl1fRwS_.js → hasIn-Bchh1rAi.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAhinBPR.js → index-B3Tpv7-d.js} +1 -1
- package/src/assets/web-panel/assets/index-B4l4vLTB.js +1 -0
- package/src/assets/web-panel/assets/{index-BWpfxzVm.js → index-B4zNisy9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CA6K7lZB.js → index-B6NehWty.js} +1 -1
- package/src/assets/web-panel/assets/index-B7Ek5iiY.js +1 -0
- package/src/assets/web-panel/assets/{index-DJyeeygd.js → index-B7knYOpm.js} +1 -1
- package/src/assets/web-panel/assets/{index-hv4jUdG3.js → index-B7wT5VRi.js} +1 -1
- package/src/assets/web-panel/assets/{index-9_mmaR42.js → index-BF4xx1_b.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cxw3p73X.js → index-BH9t10pe.js} +1 -1
- package/src/assets/web-panel/assets/{index-B016Fsqr.js → index-BPH5ESqs.js} +3 -3
- package/src/assets/web-panel/assets/{index-BmbVyhk1.js → index-BmsIKzyu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CST381Qf.js → index-BoaRB-4a.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9D4q-qI.js → index-BrbJBnT-.js} +1 -1
- package/src/assets/web-panel/assets/{index-pngH1and.js → index-C2eMYASq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKEipmR8.js → index-C4yBRKT4.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2QiUEgK.js → index-CGq4HQno.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4JXchTG.js → index-CMybtJY6.js} +1 -1
- package/src/assets/web-panel/assets/{index-iiZfONfx.js → index-CR3kFPuC.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTKEXyaW.js → index-CTRd7vkq.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2ly7sCw.js → index-CdU8BwRW.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di6nvW1N.js → index-Cua_P8St.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnEPB1Mz.js → index-CuehgDOp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DrWERr8C.js → index-D-TT9Swq.js} +1 -1
- package/src/assets/web-panel/assets/{index-II3JhQu2.js → index-DEYcLAl7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbXnyoSO.js → index-DQ_hw_5P.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ceo9P9tQ.js → index-DTEu7TSF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDQx2YFc.js → index-DVo1GJoj.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-VVk1Jg.js → index-DjdOL159.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAwVwBOL.js → index-DsbMVBj1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bvi14vJ7.js → index-DxahxRP7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhqOTuMW.js → index-EPERz4Pu.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ds2RzRG0.js → index-IkvkNxbc.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChwpS1f0.js → index-KCib1PTw.js} +1 -1
- package/src/assets/web-panel/assets/{index-OCxo0X6J.js → index-M8SZI11a.js} +1 -1
- package/src/assets/web-panel/assets/{index-Qj2x55mz.js → index-TxbHusq2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CisXVbSt.js → index-dsLc7t6W.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9tq8Da8.js → index-jMcv1u5o.js} +1 -1
- package/src/assets/web-panel/assets/{index--SWvw6yW.js → index-majCS3s2.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTpCUi0m.js → index-u8K1y_lh.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-GOhLA2-f.js → initDefaultProps-DYn3Gc09.js} +1 -1
- package/src/assets/web-panel/assets/{motion-jqxFzHTx.js → motion-ZS3eolb9.js} +1 -1
- package/src/assets/web-panel/assets/{move-CSLsp6TA.js → move-CEw4uqr3.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Cnlrb25c.js → omit-DlHFZnPp.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CLqlxWWD.js → pickAttrs-eZQvV5fA.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BAWIWtul.js → placementArrow-B31jQwa-.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CSR1DayS.js → responsiveObserve-DAsNmVto.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CNhoPJOp.js → slide-gPQPrYZC.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BZiYHRHW.js → statusUtils-DwWKX5co.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BMoY-Fm5.js → styleChecker-B3VOtXuH.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DhtNdlaS.js → useFlexGapSupport-6ADctM2r.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DNPtDOZ4.js → useFs-6Zx1SSKs.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DTdjNvAI.js → usePersonalDataHub-BzReowln.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C9zW9IJ2.js → vnode-C8IpEQbD.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D-6RYJJr.js → zoom-ruc9vHr0.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/command.js +7 -2
- package/src/commands/hook.js +136 -28
- package/src/commands/ide.js +168 -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 +8 -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/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 +445 -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 +1 -0
- package/src/runtime/system-prompt.js +6 -1
- package/src/assets/web-panel/assets/MobileProjects-CH-qnGEV.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/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
package/src/commands/mcp.js
CHANGED
|
@@ -65,6 +65,98 @@ export function registerMcpCommand(program) {
|
|
|
65
65
|
.command("mcp")
|
|
66
66
|
.description("MCP server management and tool execution");
|
|
67
67
|
|
|
68
|
+
// mcp login — OAuth 2.0 (Auth Code + PKCE) for a remote MCP server.
|
|
69
|
+
mcp
|
|
70
|
+
.command("login <url>")
|
|
71
|
+
.description("Authorize a remote MCP server via OAuth (opens a browser); stores the token")
|
|
72
|
+
.option("--scope <scope>", "OAuth scope(s) to request")
|
|
73
|
+
.option("--client-id <id>", "Use a pre-registered client_id instead of dynamic registration")
|
|
74
|
+
.option("--port <n>", "Localhost callback port", (v) => parseInt(v, 10), 53682)
|
|
75
|
+
.option("--no-open", "Print the authorize URL instead of opening a browser")
|
|
76
|
+
.action(async (url, options) => {
|
|
77
|
+
try {
|
|
78
|
+
const oauth = await import("../lib/mcp-oauth.js");
|
|
79
|
+
if (options.open === false) {
|
|
80
|
+
oauth._deps.openBrowser = () => false; // commander maps --no-open → open:false
|
|
81
|
+
}
|
|
82
|
+
logger.log(chalk.gray(`Authorizing ${url} …`));
|
|
83
|
+
const rec = await oauth.authorizeInteractive(url, {
|
|
84
|
+
scope: options.scope,
|
|
85
|
+
clientId: options.clientId,
|
|
86
|
+
port: options.port,
|
|
87
|
+
writeOut: (s) => process.stdout.write(s),
|
|
88
|
+
});
|
|
89
|
+
logger.log(
|
|
90
|
+
chalk.green(`✓ authorized ${rec.server}`) +
|
|
91
|
+
chalk.gray(
|
|
92
|
+
rec.expires_at
|
|
93
|
+
? ` (expires ${new Date(rec.expires_at).toISOString()})`
|
|
94
|
+
: "",
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
logger.log(
|
|
98
|
+
chalk.gray("The token is injected as a Bearer header on connect."),
|
|
99
|
+
);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
logger.error(chalk.red(`mcp login failed: ${err.message}`));
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// mcp logout — forget a stored OAuth token.
|
|
107
|
+
mcp
|
|
108
|
+
.command("logout <url>")
|
|
109
|
+
.description("Delete the stored OAuth token for a remote MCP server")
|
|
110
|
+
.action(async (url) => {
|
|
111
|
+
try {
|
|
112
|
+
const { deleteStoredToken, serverKey } = await import("../lib/mcp-oauth.js");
|
|
113
|
+
const ok = deleteStoredToken(url);
|
|
114
|
+
logger.log(
|
|
115
|
+
ok
|
|
116
|
+
? chalk.green(`✓ removed token for ${serverKey(url)}`)
|
|
117
|
+
: chalk.gray(`no stored token for ${serverKey(url)}`),
|
|
118
|
+
);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
logger.error(chalk.red(`mcp logout failed: ${err.message}`));
|
|
121
|
+
process.exitCode = 1;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// mcp auth — list stored OAuth tokens.
|
|
126
|
+
mcp
|
|
127
|
+
.command("auth")
|
|
128
|
+
.description("List stored MCP OAuth tokens")
|
|
129
|
+
.option("--json", "Output as JSON")
|
|
130
|
+
.action(async (options) => {
|
|
131
|
+
try {
|
|
132
|
+
const { loadTokenStore, isTokenExpired } = await import("../lib/mcp-oauth.js");
|
|
133
|
+
const store = loadTokenStore();
|
|
134
|
+
const rows = Object.values(store).map((r) => ({
|
|
135
|
+
server: r.server,
|
|
136
|
+
expired: isTokenExpired(r),
|
|
137
|
+
expires_at: r.expires_at || null,
|
|
138
|
+
refresh: Boolean(r.refresh_token),
|
|
139
|
+
}));
|
|
140
|
+
if (options.json) {
|
|
141
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (rows.length === 0) {
|
|
145
|
+
logger.log(chalk.gray("No MCP OAuth tokens. Run: cc mcp login <url>"));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
for (const r of rows) {
|
|
149
|
+
const state = r.expired ? chalk.red("expired") : chalk.green("valid");
|
|
150
|
+
logger.log(
|
|
151
|
+
` ${chalk.cyan(r.server)} [${state}]${r.refresh ? chalk.gray(" +refresh") : ""}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
} catch (err) {
|
|
155
|
+
logger.error(chalk.red(`mcp auth failed: ${err.message}`));
|
|
156
|
+
process.exitCode = 1;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
68
160
|
// mcp servers — list configured servers
|
|
69
161
|
mcp
|
|
70
162
|
.command("servers")
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc output-style — list / show output-style personas (Claude-Code parity).
|
|
3
|
+
*
|
|
4
|
+
* cc output-style list [--json] list built-ins + .claude/output-styles/*.md
|
|
5
|
+
* cc output-style show <name> show a style's metadata + body
|
|
6
|
+
* cc output-style new <name> scaffold a new style file
|
|
7
|
+
*
|
|
8
|
+
* Apply one with `cc agent --output-style <name>` or the REPL `/output-style`,
|
|
9
|
+
* or set a default via `outputStyle` in .claude/settings.json.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import { logger } from "../lib/logger.js";
|
|
14
|
+
|
|
15
|
+
export function registerOutputStyleCommand(program) {
|
|
16
|
+
const cmd = program
|
|
17
|
+
.command("output-style")
|
|
18
|
+
.alias("output-styles")
|
|
19
|
+
.description("List / show agent output-style personas");
|
|
20
|
+
|
|
21
|
+
cmd
|
|
22
|
+
.command("list", { isDefault: true })
|
|
23
|
+
.alias("ls")
|
|
24
|
+
.description("List built-in + .claude/output-styles/*.md personas")
|
|
25
|
+
.option("--json", "Output as JSON")
|
|
26
|
+
.action(async (options) => {
|
|
27
|
+
try {
|
|
28
|
+
const { discoverOutputStyles, settingsDefaultOutputStyle } =
|
|
29
|
+
await import("../lib/output-styles.js");
|
|
30
|
+
const all = discoverOutputStyles(process.cwd());
|
|
31
|
+
const dflt = settingsDefaultOutputStyle(process.cwd());
|
|
32
|
+
if (options.json) {
|
|
33
|
+
console.log(JSON.stringify({ default: dflt, styles: all }, null, 2));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (const s of all) {
|
|
37
|
+
const tag = s.builtin
|
|
38
|
+
? chalk.gray("[builtin]")
|
|
39
|
+
: s.scope === "project"
|
|
40
|
+
? chalk.cyan("[proj]")
|
|
41
|
+
: chalk.gray("[pers]");
|
|
42
|
+
const star = s.name === dflt ? chalk.green(" *") : "";
|
|
43
|
+
logger.log(
|
|
44
|
+
`${chalk.bold(s.name.padEnd(16))} ${tag}${star} ${chalk.gray(s.description || "")}`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
if (dflt) logger.log(chalk.dim(`\ndefault (settings.json): ${dflt}`));
|
|
48
|
+
} catch (err) {
|
|
49
|
+
logger.error(chalk.red(`output-style list failed: ${err.message}`));
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
cmd
|
|
55
|
+
.command("show <name>")
|
|
56
|
+
.description("Show a style's metadata and body")
|
|
57
|
+
.option("--json", "Output as JSON")
|
|
58
|
+
.action(async (name, options) => {
|
|
59
|
+
try {
|
|
60
|
+
const { getOutputStyle } = await import("../lib/output-styles.js");
|
|
61
|
+
const s = getOutputStyle(name, process.cwd());
|
|
62
|
+
if (!s) {
|
|
63
|
+
logger.error(chalk.red(`no such output style: ${name}`));
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (options.json) {
|
|
68
|
+
console.log(JSON.stringify(s, null, 2));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
logger.log(
|
|
72
|
+
chalk.bold(s.name) +
|
|
73
|
+
(s.builtin ? chalk.gray(" [builtin]") : chalk.gray(` [${s.scope}]`)),
|
|
74
|
+
);
|
|
75
|
+
if (s.description) logger.log(chalk.gray(` ${s.description}`));
|
|
76
|
+
if (s.file) logger.log(chalk.gray(` file: ${s.file}`));
|
|
77
|
+
logger.log(chalk.dim(" ───"));
|
|
78
|
+
logger.log(s.body || chalk.gray("(empty — no persona overlay)"));
|
|
79
|
+
} catch (err) {
|
|
80
|
+
logger.error(chalk.red(`output-style show failed: ${err.message}`));
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
cmd
|
|
86
|
+
.command("new <name>")
|
|
87
|
+
.description("Scaffold a new style under .claude/output-styles/")
|
|
88
|
+
.option("--description <d>", "Frontmatter description")
|
|
89
|
+
.option("--personal", "Create under ~/.claude/output-styles instead of project")
|
|
90
|
+
.action(async (name, options) => {
|
|
91
|
+
try {
|
|
92
|
+
const fs = await import("node:fs");
|
|
93
|
+
const path = await import("node:path");
|
|
94
|
+
const { homedir } = await import("node:os");
|
|
95
|
+
const safe = String(name).replace(/[^\w.-]/g, "-");
|
|
96
|
+
const root = options.personal
|
|
97
|
+
? path.join(homedir(), ".claude", "output-styles")
|
|
98
|
+
: path.join(process.cwd(), ".claude", "output-styles");
|
|
99
|
+
const file = path.join(root, `${safe}.md`);
|
|
100
|
+
if (fs.existsSync(file)) {
|
|
101
|
+
logger.error(chalk.red(`already exists: ${file}`));
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
106
|
+
const tpl = `---
|
|
107
|
+
name: ${safe}
|
|
108
|
+
description: ${options.description || name}
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Output style: ${safe}
|
|
112
|
+
|
|
113
|
+
Describe how the agent should behave in this style. This text is appended to
|
|
114
|
+
the system prompt (after the base coding instructions), so keep it focused on
|
|
115
|
+
*behaviour / tone*, not tool mechanics.
|
|
116
|
+
`;
|
|
117
|
+
fs.writeFileSync(file, tpl, "utf-8");
|
|
118
|
+
logger.log(chalk.green(`✓ created ${file}`));
|
|
119
|
+
logger.log(
|
|
120
|
+
chalk.gray(` use it: cc agent --output-style ${safe} -p "..."`),
|
|
121
|
+
);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
logger.error(chalk.red(`output-style new failed: ${err.message}`));
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc permissions — inspect, dry-run, and edit the `.claude/settings.json`
|
|
3
|
+
* permission ruleset (Claude-Code `permissions.{allow,ask,deny}` parity).
|
|
4
|
+
*
|
|
5
|
+
* cc permissions list [--json] merged ruleset + source file
|
|
6
|
+
* cc permissions test <tool> <args...> dry-run: which rule decides?
|
|
7
|
+
* cc permissions add <allow|ask|deny> <rule> append a rule to a settings file
|
|
8
|
+
* [--local | --user] (default target: project)
|
|
9
|
+
*
|
|
10
|
+
* The ruleset is loaded by settings-loader (user < project < local < env) and
|
|
11
|
+
* evaluated by permission-rules (deny > ask > allow). This command only reads
|
|
12
|
+
* and edits the files / runs the engine — it does not yet gate the agent tool
|
|
13
|
+
* loop (that wiring is a separate, riskier step).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import chalk from "chalk";
|
|
17
|
+
import { logger } from "../lib/logger.js";
|
|
18
|
+
|
|
19
|
+
const KIND_COLOR = {
|
|
20
|
+
allow: chalk.green,
|
|
21
|
+
ask: chalk.yellow,
|
|
22
|
+
deny: chalk.red,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** Resolve an umbrella token (Bash) to a concrete tool name for dry-run. */
|
|
26
|
+
function resolveConcreteTool(token, groups) {
|
|
27
|
+
const t = String(token || "");
|
|
28
|
+
const lower = t.toLowerCase();
|
|
29
|
+
if (Object.prototype.hasOwnProperty.call(groups, lower)) {
|
|
30
|
+
return groups[lower][0];
|
|
31
|
+
}
|
|
32
|
+
return t;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Build the tool args object a dry-run target needs from positional args. */
|
|
36
|
+
function buildArgs(tool, positional, rulesMod) {
|
|
37
|
+
const joined = positional.join(" ").trim();
|
|
38
|
+
if (rulesMod.COMMAND_TOOLS.has(tool)) return { command: joined };
|
|
39
|
+
if (rulesMod.PATH_TOOLS.has(tool)) return { path: positional[0] || "" };
|
|
40
|
+
if (rulesMod.URL_TOOLS.has(tool)) return { url: positional[0] || "" };
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function registerPermissionsCommand(program) {
|
|
45
|
+
const cmd = program
|
|
46
|
+
.command("permissions")
|
|
47
|
+
.alias("perms")
|
|
48
|
+
.description(
|
|
49
|
+
"Inspect / dry-run / edit .claude/settings.json permission rules",
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// ── list ──────────────────────────────────────────────────────────────
|
|
53
|
+
cmd
|
|
54
|
+
.command("list")
|
|
55
|
+
.alias("ls")
|
|
56
|
+
.description("Show the merged permission ruleset and where each rule came from")
|
|
57
|
+
.option("--json", "Output as JSON")
|
|
58
|
+
.option("--settings <file>", "Also merge an explicit settings file")
|
|
59
|
+
.action(async (options) => {
|
|
60
|
+
try {
|
|
61
|
+
const { loadSettings } = await import("../lib/settings-loader.cjs");
|
|
62
|
+
const { rules, sources, files } = loadSettings({
|
|
63
|
+
cwd: process.cwd(),
|
|
64
|
+
settingsFile: options.settings,
|
|
65
|
+
});
|
|
66
|
+
if (options.json) {
|
|
67
|
+
console.log(JSON.stringify({ rules, sources, files }, null, 2));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const total =
|
|
71
|
+
rules.allow.length + rules.ask.length + rules.deny.length;
|
|
72
|
+
if (total === 0) {
|
|
73
|
+
logger.log(
|
|
74
|
+
chalk.gray(
|
|
75
|
+
"No permission rules. Add one: cc permissions add deny \"Bash(rm:*)\"\n" +
|
|
76
|
+
"(or create .claude/settings.json with a permissions block)",
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
for (const kind of ["deny", "ask", "allow"]) {
|
|
82
|
+
if (rules[kind].length === 0) continue;
|
|
83
|
+
logger.log(KIND_COLOR[kind].bold(`${kind} (${rules[kind].length})`));
|
|
84
|
+
for (const rule of rules[kind]) {
|
|
85
|
+
const src = sources[`${kind}:${rule}`] || "?";
|
|
86
|
+
logger.log(` ${rule.padEnd(34)} ${chalk.gray(src)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (files.length) {
|
|
90
|
+
logger.log(chalk.dim(`\nsources: ${files.join(", ")}`));
|
|
91
|
+
}
|
|
92
|
+
} catch (err) {
|
|
93
|
+
logger.error(chalk.red(`permissions list failed: ${err.message}`));
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ── test (dry-run) ─────────────────────────────────────────────────────
|
|
99
|
+
cmd
|
|
100
|
+
.command("test <tool> [args...]")
|
|
101
|
+
.description(
|
|
102
|
+
'Dry-run a tool call against the ruleset, e.g. permissions test run_shell "git push"',
|
|
103
|
+
)
|
|
104
|
+
.option("--json", "Output as JSON")
|
|
105
|
+
.option("--settings <file>", "Also merge an explicit settings file")
|
|
106
|
+
.action(async (tool, args, options) => {
|
|
107
|
+
try {
|
|
108
|
+
const { loadSettings, ruleSource } =
|
|
109
|
+
await import("../lib/settings-loader.cjs");
|
|
110
|
+
// .cjs default-export interop: module.exports surfaces as `.default`.
|
|
111
|
+
const rulesMod = await import("../lib/permission-rules.cjs");
|
|
112
|
+
const mod = rulesMod.default || rulesMod;
|
|
113
|
+
|
|
114
|
+
const { rules, sources } = loadSettings({
|
|
115
|
+
cwd: process.cwd(),
|
|
116
|
+
settingsFile: options.settings,
|
|
117
|
+
});
|
|
118
|
+
const concrete = resolveConcreteTool(tool, mod.TOOL_GROUPS);
|
|
119
|
+
const toolArgs = buildArgs(concrete, args || [], mod);
|
|
120
|
+
const result = mod.evaluatePermissionRules({
|
|
121
|
+
tool: concrete,
|
|
122
|
+
args: toolArgs,
|
|
123
|
+
cwd: process.cwd(),
|
|
124
|
+
rules,
|
|
125
|
+
});
|
|
126
|
+
const decision = result.decision || "fallthrough";
|
|
127
|
+
const source = result.rule
|
|
128
|
+
? ruleSource(sources, result.decision, result.rule)
|
|
129
|
+
: null;
|
|
130
|
+
|
|
131
|
+
if (options.json) {
|
|
132
|
+
console.log(
|
|
133
|
+
JSON.stringify(
|
|
134
|
+
{ tool: concrete, args: toolArgs, decision, rule: result.rule, source },
|
|
135
|
+
null,
|
|
136
|
+
2,
|
|
137
|
+
),
|
|
138
|
+
);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const color = KIND_COLOR[result.decision] || chalk.gray;
|
|
143
|
+
logger.log(
|
|
144
|
+
`${chalk.bold(concrete)} ${chalk.gray(JSON.stringify(toolArgs))}`,
|
|
145
|
+
);
|
|
146
|
+
logger.log(` decision: ${color.bold(decision)}`);
|
|
147
|
+
if (result.rule) {
|
|
148
|
+
logger.log(` rule: ${result.rule}`);
|
|
149
|
+
if (source) logger.log(` source: ${chalk.gray(source)}`);
|
|
150
|
+
} else {
|
|
151
|
+
logger.log(
|
|
152
|
+
chalk.gray(
|
|
153
|
+
" no rule matched → falls back to risk-tier / --permission-mode logic",
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
} catch (err) {
|
|
158
|
+
logger.error(chalk.red(`permissions test failed: ${err.message}`));
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// ── add ────────────────────────────────────────────────────────────────
|
|
164
|
+
cmd
|
|
165
|
+
.command("add <decision> <rule>")
|
|
166
|
+
.description("Append a rule (allow|ask|deny) to a settings file")
|
|
167
|
+
.option("--local", "Write to .claude/settings.local.json (personal, gitignored)")
|
|
168
|
+
.option("--user", "Write to ~/.claude/settings.json (all projects)")
|
|
169
|
+
.action(async (decision, rule, options) => {
|
|
170
|
+
try {
|
|
171
|
+
const kind = String(decision || "").toLowerCase();
|
|
172
|
+
if (!["allow", "ask", "deny"].includes(kind)) {
|
|
173
|
+
logger.error(
|
|
174
|
+
chalk.red(`decision must be allow | ask | deny (got "${decision}")`),
|
|
175
|
+
);
|
|
176
|
+
process.exitCode = 1;
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const rulesMod = await import("../lib/permission-rules.cjs");
|
|
180
|
+
const mod = rulesMod.default || rulesMod;
|
|
181
|
+
if (!mod.parseRule(rule)) {
|
|
182
|
+
logger.error(
|
|
183
|
+
chalk.red(
|
|
184
|
+
`not a valid rule: "${rule}" (expected Tool or Tool(pattern), e.g. Bash(rm:*))`,
|
|
185
|
+
),
|
|
186
|
+
);
|
|
187
|
+
process.exitCode = 1;
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const scope = options.user ? "user" : options.local ? "local" : "project";
|
|
192
|
+
const { addRule } = await import("../lib/settings-loader.cjs");
|
|
193
|
+
const { file, added } = addRule({
|
|
194
|
+
cwd: process.cwd(),
|
|
195
|
+
kind,
|
|
196
|
+
rule,
|
|
197
|
+
scope,
|
|
198
|
+
});
|
|
199
|
+
if (!added) {
|
|
200
|
+
logger.log(chalk.gray(`already present in ${file}: ${kind} ${rule}`));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
logger.log(
|
|
204
|
+
`${KIND_COLOR[kind].bold("✓ " + kind)} ${rule} ${chalk.gray("→ " + file)}`,
|
|
205
|
+
);
|
|
206
|
+
} catch (err) {
|
|
207
|
+
logger.error(chalk.red(`permissions add failed: ${err.message}`));
|
|
208
|
+
process.exitCode = 1;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc statusline — preview the configured `statusLine` (Claude-Code parity).
|
|
3
|
+
*
|
|
4
|
+
* cc statusline preview the rendered status line
|
|
5
|
+
* cc statusline show show the resolved config (+ source)
|
|
6
|
+
*
|
|
7
|
+
* Configure in .claude/settings.json:
|
|
8
|
+
* { "statusLine": { "type": "command", "command": "~/.claude/status.sh" } }
|
|
9
|
+
* The command receives a JSON context on stdin and its first stdout line is the
|
|
10
|
+
* status line (shown above the REPL prompt each turn).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import chalk from "chalk";
|
|
14
|
+
import { logger } from "../lib/logger.js";
|
|
15
|
+
|
|
16
|
+
export function registerStatuslineCommand(program) {
|
|
17
|
+
const cmd = program
|
|
18
|
+
.command("statusline")
|
|
19
|
+
.alias("status-line")
|
|
20
|
+
.description("Preview / show the .claude/settings.json statusLine");
|
|
21
|
+
|
|
22
|
+
cmd
|
|
23
|
+
.command("preview", { isDefault: true })
|
|
24
|
+
.description("Render the configured status line once")
|
|
25
|
+
.option("--model <m>", "Model to pass in the context", "opus")
|
|
26
|
+
.option("--json", "Output as JSON")
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
try {
|
|
29
|
+
const { loadStatusLineConfig, buildContext, renderStatusLine } =
|
|
30
|
+
await import("../lib/status-line.cjs");
|
|
31
|
+
const cfg = loadStatusLineConfig({ cwd: process.cwd() });
|
|
32
|
+
if (!cfg) {
|
|
33
|
+
logger.log(
|
|
34
|
+
chalk.gray(
|
|
35
|
+
'No statusLine configured. Add to .claude/settings.json:\n' +
|
|
36
|
+
' { "statusLine": { "type": "command", "command": "./status.sh" } }',
|
|
37
|
+
),
|
|
38
|
+
);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const line = renderStatusLine(
|
|
42
|
+
cfg,
|
|
43
|
+
buildContext({
|
|
44
|
+
sessionId: "preview",
|
|
45
|
+
model: options.model,
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
}),
|
|
48
|
+
{ cwd: process.cwd() },
|
|
49
|
+
);
|
|
50
|
+
if (options.json) {
|
|
51
|
+
console.log(JSON.stringify({ config: cfg, line }, null, 2));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (line == null) {
|
|
55
|
+
logger.error(
|
|
56
|
+
chalk.red(
|
|
57
|
+
`statusLine command produced no output (or failed): ${cfg.command}`,
|
|
58
|
+
),
|
|
59
|
+
);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
process.stdout.write(line + "\n");
|
|
64
|
+
} catch (err) {
|
|
65
|
+
logger.error(chalk.red(`statusline preview failed: ${err.message}`));
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
cmd
|
|
71
|
+
.command("show")
|
|
72
|
+
.description("Show the resolved statusLine config")
|
|
73
|
+
.option("--json", "Output as JSON")
|
|
74
|
+
.action(async (options) => {
|
|
75
|
+
try {
|
|
76
|
+
const { loadStatusLineConfig } = await import("../lib/status-line.cjs");
|
|
77
|
+
const cfg = loadStatusLineConfig({ cwd: process.cwd() });
|
|
78
|
+
if (options.json) {
|
|
79
|
+
console.log(JSON.stringify(cfg, null, 2));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!cfg) {
|
|
83
|
+
logger.log(chalk.gray("No statusLine configured."));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
logger.log(`command: ${chalk.cyan(cfg.command)}`);
|
|
87
|
+
logger.log(chalk.gray(`type: ${cfg.type} padding: ${cfg.padding}`));
|
|
88
|
+
} catch (err) {
|
|
89
|
+
logger.error(chalk.red(`statusline show failed: ${err.message}`));
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
package/src/index.js
CHANGED
|
@@ -58,11 +58,14 @@ import { registerRCacheCommand } from "./commands/rcache.js";
|
|
|
58
58
|
import { registerSessionCommand } from "./commands/session.js";
|
|
59
59
|
import { registerCostCommand } from "./commands/cost.js";
|
|
60
60
|
import { registerContextCommand } from "./commands/context.js";
|
|
61
|
-
import { registerAgentsCommand } from "./commands/agents.js";
|
|
62
61
|
import { registerCheckpointCommand } from "./commands/checkpoint.js";
|
|
63
62
|
import { registerGoalCommand } from "./commands/goal.js";
|
|
64
63
|
import { registerCommandCommand } from "./commands/command.js";
|
|
65
64
|
import { registerCompactCommand } from "./commands/compact.js";
|
|
65
|
+
import { registerPermissionsCommand } from "./commands/permissions.js";
|
|
66
|
+
import { registerOutputStyleCommand } from "./commands/output-style.js";
|
|
67
|
+
import { registerStatuslineCommand } from "./commands/statusline.js";
|
|
68
|
+
import { registerIdeCommand } from "./commands/ide.js";
|
|
66
69
|
import { registerConsolCommand } from "./commands/consol.js";
|
|
67
70
|
import { registerImportCommand } from "./commands/import.js";
|
|
68
71
|
import { registerExportCommand } from "./commands/export.js";
|
|
@@ -457,11 +460,14 @@ export function createProgram(opts = {}) {
|
|
|
457
460
|
registerSessionCommand(program);
|
|
458
461
|
registerCostCommand(program);
|
|
459
462
|
registerContextCommand(program);
|
|
460
|
-
registerAgentsCommand(program);
|
|
461
463
|
registerCheckpointCommand(program);
|
|
462
464
|
registerGoalCommand(program);
|
|
463
465
|
registerCommandCommand(program);
|
|
464
466
|
registerCompactCommand(program);
|
|
467
|
+
registerPermissionsCommand(program);
|
|
468
|
+
registerOutputStyleCommand(program);
|
|
469
|
+
registerStatuslineCommand(program);
|
|
470
|
+
registerIdeCommand(program);
|
|
465
471
|
registerConsolCommand(program);
|
|
466
472
|
|
|
467
473
|
// Phase 2: Knowledge & content management
|
package/src/lib/agent-core.js
CHANGED
|
@@ -24,5 +24,12 @@ export {
|
|
|
24
24
|
agentLoop,
|
|
25
25
|
formatToolArgs,
|
|
26
26
|
getActiveMcpServers,
|
|
27
|
+
listBackgroundShellTasks,
|
|
28
|
+
killAllBackgroundShellTasks,
|
|
27
29
|
_accumulateOllamaStream,
|
|
30
|
+
_accumulateOpenAIStream,
|
|
31
|
+
_accumulateAnthropicStream,
|
|
32
|
+
_toAnthropicMessages,
|
|
33
|
+
_anthropicThinkingParams,
|
|
34
|
+
_normalizeAnthropicResponse,
|
|
28
35
|
} from "../runtime/agent-core.js";
|
package/src/lib/agents.js
CHANGED
|
@@ -57,7 +57,12 @@ export function normalizeTools(tools) {
|
|
|
57
57
|
export function agentDirs(cwd = process.cwd(), opts = {}) {
|
|
58
58
|
const path = opts.deps?.path || _deps.path;
|
|
59
59
|
const home = opts.home || homedir();
|
|
60
|
+
// Project-native first (highest precedence), then the Claude-Code-portable
|
|
61
|
+
// location (so existing `.claude/agents/*.md` work unchanged), then personal.
|
|
62
|
+
// discoverAgents reverses + last-write-wins, so `.chainlesschain/agents/`
|
|
63
|
+
// shadows `.claude/agents/` shadows `~/.claude/agents/` on a name clash.
|
|
60
64
|
return [
|
|
65
|
+
{ dir: path.join(cwd, ".chainlesschain", "agents"), scope: "project" },
|
|
61
66
|
{ dir: path.join(cwd, ".claude", "agents"), scope: "project" },
|
|
62
67
|
{ dir: path.join(home, ".claude", "agents"), scope: "personal" },
|
|
63
68
|
];
|
package/src/lib/hook-manager.js
CHANGED
|
@@ -40,6 +40,7 @@ export const HookEvents = {
|
|
|
40
40
|
SessionEnd: "SessionEnd",
|
|
41
41
|
PreCompact: "PreCompact",
|
|
42
42
|
PostCompact: "PostCompact",
|
|
43
|
+
Notification: "Notification",
|
|
43
44
|
UserPromptSubmit: "UserPromptSubmit",
|
|
44
45
|
AssistantResponse: "AssistantResponse",
|
|
45
46
|
AgentStart: "AgentStart",
|