chainlesschain 0.162.33 → 0.162.35
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-3TazCYWE.js → AIOps-CJn02U42.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DUPN0PST.js → ActionButton-ewURAAoy.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CemvhkzD.js → Analytics-BiSadESb.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-BL_tAU3M.js → AppLayout-BR0WOEug.js} +4 -4
- package/src/assets/web-panel/assets/{Audit-Dl9l-cxF.js → Audit-CrqcYx0e.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BKDDX75m.js → Backup-DtbSBn4e.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CDYePvMI.js → BaseInput-BjSc9j0o.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CGtR0sg3.js → Chat-ixzrlCJE.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-B78nEq05.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CwYIHOOo.js → Checkbox-UGYeSsgr.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CIF5tbtd.js → Codegen-B97OOAg4.js} +1 -1
- package/src/assets/web-panel/assets/{Col-z7d4kxeP.js → Col-D9aGkaZ6.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DUlDrqF7.js → Community-Dc2v2RGS.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CJ1o8QQR.js → Compact-B_FYlUQR.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D3i9d_uO.js → Compliance-C4FiTHyC.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Wm7JTkfB.js → Cowork-CQ8j3LIg.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-B0QnHhZx.js → Cron-Dzjs9Z9Z.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-3yPrnNgd.js → Crosschain-BXI24uzI.js} +1 -1
- package/src/assets/web-panel/assets/{DID-cfdkiDWF.js → DID-C-I4_d07.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DFkgM4gT.js → Dashboard-BzzGh5mo.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-YYWE81DL.js → Dropdown-Bh8H70De.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BXfHK1Bn.js → EmailListRenderer-DI_qybJP.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DInUxJ2G.js → FamilyGuardDashboard-DkKTsfc4.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DNUYeFsv.js → Federation-DS7CmvVG.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Cr7eVEBB.js → FormItemContext-CI97WsB5.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-_gF4cmDa.js → GenericCardRenderer-Da27EdR4.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BqldmUbO.js → Git-CEh0gR2W.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BF59ZiQ8.js → Governance-kIr3tls2.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Cy7y1eb9.js → Inference-CC1GzyC1.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B3fVocTO.js → KnowledgeGraph-BNgTiWOB.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BDirsUVk.js → Logs-B2P10gB1.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-GhXpZgp2.js → Marketplace-HPfBvbFZ.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-0VvfIhKx.js → McpTools-ByYotSKb.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CJLBgAUT.js → Memory-BGIAzFVS.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BMedY9Yg.js → MobileBridge-CroNYTAH.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-CH-qnGEV.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CgEuUg0g.js → Mtc-BqhyIwo9.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-1pWNe_xi.js → MtcAudit-BpEKOvx9.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DPIQ7oZL.js → Multisig-DST1d_Qo.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-W__P_P4Z.js → NLProgramming-DlMsZcK_.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C_MCDhFk.js → Notes-C734UJvD.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CDFotapL.js → NotificationSettings-C0-pPxvk.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dtht0cEs.js → OrderTableRenderer-C7zT9eFc.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-D6lMumhD.js → Organization-C5iHC_yW.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-BMOvUMW6.js → Overflow-CovuHHVR.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DsQTEw1t.js → P2P-Dx9QL-Gy.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CncRtN1Z.js → PdhVaultBrowser-IP1dEt6-.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DDC-DkUl.js → Permissions-BrR1XZG5.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-DVKY_NnT.js → PersonalDataHub-BgqxVE5m.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-C7oDVTl-.js → Pipeline-DzMk5HAz.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DReGvTEJ.js → Privacy-CDoLa6tk.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C-j2dzxJ.js → ProjectInit-Dy5gc6ve.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DcUsvFnc.js → ProjectSettings-DXy-k4hG.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-jSjWnmr6.js → Projects-DvsaEbZR.js} +1 -1
- package/src/assets/web-panel/assets/Providers-Demck9PO.js +1 -0
- package/src/assets/web-panel/assets/{QuickAsk-DdvLtpEU.js → QuickAsk-B8KEHCnd.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DPAi2zo3.js → Recommend-DNVHGYYZ.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-DJD7qXSI.js → Reputation-CaDhWP03.js} +1 -1
- package/src/assets/web-panel/assets/{Row-XERdPDHk.js → Row-CrGLI02x.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Cl_VlCLg.js → RssFeed-BX7P8I6i.js} +3 -3
- package/src/assets/web-panel/assets/Search-laS6rz8M.js +1 -0
- package/src/assets/web-panel/assets/{Security-DjjCrw8v.js → Security-B6J7IFc1.js} +2 -2
- package/src/assets/web-panel/assets/{Services-BuWeB4YJ.js → Services-vvdcO3mM.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-VZXOKwC_.js → Skeleton-BoAoPTzZ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-B76ONTfP.js → Skills-CyIQV5b3.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DIj1KREq.js → Sla-BAQVgdZV.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BrAp3Yk3.js → SpeechSettings-Bxcn1Jkj.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings--mJcpccF.js → SyncSettings-Dpaj3hDM.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-Bwqo89En.js +1 -0
- package/src/assets/web-panel/assets/{Templates-kOBK6m1Z.js → Templates-Bowcqifn.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BjSzYPzn.js → Tenant-DOkf85uG.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DwpY-Ay7.js → Terminal-v4MM9dCj.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-aoI0DazM.js → TimelineRenderer-B9A3zDXA.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-YwE0LqSZ.js → Tokens-jtVVqKFr.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CwSKzvlX.js → Trigger-26Iw-iIl.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B__Jqdzn.js → Trust-DqY5ORrH.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-mty0jwmx.js → UkeySign-BFsbr3y7.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Ddsx_OQ6.js → VideoEditing-BtDbj3oa.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D4Q8yXZm.js → Wallet-BAwmwHbk.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CLUaKUr5.js → WebAuthn-DINJTsfq.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Di5pOaeC.js → WorkflowEditor-BEorm8SK.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CELatHkT.js → chat-CE39-Dxg.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CawDLjXV.js → colors-C_cLZ93a.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DeMp-K0j.js → compact-item-BSioWA2c.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-zY9kXivd.js → createContext-CGTk4mhN.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-PObcVnJR.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-VEBMW8E4.js → hasIn-Dl1fRwS_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHqvj9uz.js → index--SWvw6yW.js} +1 -1
- package/src/assets/web-panel/assets/{index-S9JZDSaa.js → index-9_mmaR42.js} +1 -1
- package/src/assets/web-panel/assets/{index-XFyv3Sg_.js → index-B016Fsqr.js} +3 -3
- package/src/assets/web-panel/assets/{index-BqJ2r12F.js → index-B2QiUEgK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtLZammH.js → index-BAhinBPR.js} +1 -1
- package/src/assets/web-panel/assets/index-BNwIzLyX.js +1 -0
- package/src/assets/web-panel/assets/{index-Cr7lnIeI.js → index-BWpfxzVm.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXNe_zIP.js → index-BhqOTuMW.js} +1 -1
- package/src/assets/web-panel/assets/{index-GRNVdvoA.js → index-BmbVyhk1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFc0vBN9.js → index-BnEPB1Mz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSiL_W2n.js → index-Bvi14vJ7.js} +1 -1
- package/src/assets/web-panel/assets/{index-KcOEkUCM.js → index-C-VVk1Jg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfGGKoo8.js → index-C2ly7sCw.js} +1 -1
- package/src/assets/web-panel/assets/{index-fBNVDEf2.js → index-C4JXchTG.js} +1 -1
- package/src/assets/web-panel/assets/{index-vaD1iHg5.js → index-C9tq8Da8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyeYs7SG.js → index-CA6K7lZB.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVkrfyuk.js → index-CAwVwBOL.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0GhuYLk.js → index-CST381Qf.js} +1 -1
- package/src/assets/web-panel/assets/{index-SrQIPYq8.js → index-CbXnyoSO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHxHLv2b.js → index-Ceo9P9tQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtoauqWt.js → index-ChwpS1f0.js} +1 -1
- package/src/assets/web-panel/assets/{index-V3K9gvKR.js → index-CisXVbSt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DALuVdhu.js → index-Cxw3p73X.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhsfyHcg.js → index-D9D4q-qI.js} +1 -1
- package/src/assets/web-panel/assets/{index-b3ZuAreb.js → index-DDQx2YFc.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8AZpx7d.js → index-DJyeeygd.js} +1 -1
- package/src/assets/web-panel/assets/{index-u_1aiNTA.js → index-DKEipmR8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DClGYjBM.js → index-DTKEXyaW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbJZzK9B.js → index-DTpCUi0m.js} +1 -1
- package/src/assets/web-panel/assets/index-Dh6FxR9B.js +1 -0
- package/src/assets/web-panel/assets/{index-DPHe9NYG.js → index-Di6nvW1N.js} +1 -1
- package/src/assets/web-panel/assets/{index-8kqE_cVD.js → index-DrWERr8C.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWbbB1MI.js → index-Ds2RzRG0.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dna2psGz.js → index-II3JhQu2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjctklSd.js → index-OCxo0X6J.js} +1 -1
- package/src/assets/web-panel/assets/{index-TfXODan7.js → index-Qj2x55mz.js} +1 -1
- package/src/assets/web-panel/assets/{index-JseP3-5X.js → index-hv4jUdG3.js} +1 -1
- package/src/assets/web-panel/assets/{index-VJnHvkv2.js → index-iiZfONfx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfZV3FXN.js → index-pngH1and.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Sd7Eayz4.js → initDefaultProps-GOhLA2-f.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DlToY72q.js → motion-jqxFzHTx.js} +1 -1
- package/src/assets/web-panel/assets/{move-DvS7EmAP.js → move-CSLsp6TA.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CzLq4QKW.js → omit-Cnlrb25c.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BcM75Jx_.js → pickAttrs-CLqlxWWD.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B7xXXiwd.js → placementArrow-BAWIWtul.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CrYPRB-g.js → responsiveObserve-CSR1DayS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CSYTtsRt.js → slide-CNhoPJOp.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CeSuOVT_.js → statusUtils-BZiYHRHW.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-KiQethca.js → styleChecker-BMoY-Fm5.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CSQnQdiv.js → useFlexGapSupport-DhtNdlaS.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Br8Kr1pr.js → useFs-DNPtDOZ4.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DGJtDcMm.js → usePersonalDataHub-DTdjNvAI.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C-jVtGka.js → vnode-C9zW9IJ2.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CeWySTPF.js → zoom-D-6RYJJr.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +19 -0
- package/src/commands/agents.js +193 -0
- package/src/commands/command.js +187 -0
- package/src/commands/context.js +189 -0
- package/src/index.js +6 -0
- package/src/lib/agents.js +142 -0
- package/src/lib/slash-commands.js +201 -0
- package/src/repl/agent-repl.js +42 -1
- package/src/runtime/agent-core.js +253 -0
- package/src/runtime/headless-runner.js +30 -1
- package/src/runtime/headless-stream.js +65 -0
- package/src/runtime/mcp-config.js +100 -0
- package/src/runtime/policies/agent-policy.js +1 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DZjc9uKn.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-mdohgRlL.js +0 -1
- package/src/assets/web-panel/assets/Providers-DIpohWG5.js +0 -1
- package/src/assets/web-panel/assets/Search-C-poG9P5.js +0 -1
- package/src/assets/web-panel/assets/Tasks-DM8cMr83.js +0 -1
- package/src/assets/web-panel/assets/devWarning-zLjV7g6r.js +0 -1
- package/src/assets/web-panel/assets/index-CDtUWCtX.js +0 -1
- package/src/assets/web-panel/assets/index-d_RPqH7u.js +0 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc agents — user-defined subagents (Claude-Code parity, `.claude/agents/*.md`).
|
|
3
|
+
*
|
|
4
|
+
* cc agents list [--json] list discovered agents
|
|
5
|
+
* cc agents show <name> show metadata + system prompt
|
|
6
|
+
* cc agents run <name> <task...> [opts] run the task as this agent (headless)
|
|
7
|
+
* cc agents new <name> [--description <d>] scaffold an agent file
|
|
8
|
+
*
|
|
9
|
+
* Each `.claude/agents/<name>.md` (project, recursive) or `~/.claude/agents/`
|
|
10
|
+
* (personal) defines a subagent: the body is its system prompt; frontmatter
|
|
11
|
+
* declares `description`, `tools` (allow-list), `model`. `run` maps the agent
|
|
12
|
+
* onto a one-shot headless run (system prompt + tool scope + model), so a
|
|
13
|
+
* portable Claude-Code agent definition is runnable as-is. Distinct from `cc
|
|
14
|
+
* command` (prompt macros) and `cc skill` (AI-invoked capabilities).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import chalk from "chalk";
|
|
18
|
+
import { logger } from "../lib/logger.js";
|
|
19
|
+
|
|
20
|
+
export function registerAgentsCommand(program) {
|
|
21
|
+
const cmd = program
|
|
22
|
+
.command("agents")
|
|
23
|
+
.description("User-defined subagents (.claude/agents/*.md)");
|
|
24
|
+
|
|
25
|
+
// ── list ──────────────────────────────────────────────────────────────
|
|
26
|
+
cmd
|
|
27
|
+
.command("list")
|
|
28
|
+
.alias("ls")
|
|
29
|
+
.description("List discovered subagents (project + personal)")
|
|
30
|
+
.option("--json", "Output as JSON")
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
try {
|
|
33
|
+
const { discoverAgents } = await import("../lib/agents.js");
|
|
34
|
+
const all = discoverAgents(process.cwd());
|
|
35
|
+
if (options.json) {
|
|
36
|
+
console.log(JSON.stringify(all, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (all.length === 0) {
|
|
40
|
+
logger.log(
|
|
41
|
+
chalk.gray(
|
|
42
|
+
"No subagents found. Create one with: cc agents new <name>",
|
|
43
|
+
),
|
|
44
|
+
);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
logger.log(chalk.bold(`Subagents (${all.length})`));
|
|
48
|
+
for (const a of all) {
|
|
49
|
+
const tools = a.tools ? a.tools.join(",") : "(all)";
|
|
50
|
+
logger.log(
|
|
51
|
+
` ${chalk.cyan(a.name.padEnd(22))} ${chalk.gray(`[${a.scope}]`)} ` +
|
|
52
|
+
`${a.description || ""}`,
|
|
53
|
+
);
|
|
54
|
+
logger.log(
|
|
55
|
+
chalk.gray(
|
|
56
|
+
` tools: ${tools}${a.model ? ` · model: ${a.model}` : ""}`,
|
|
57
|
+
),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
} catch (err) {
|
|
61
|
+
logger.error(chalk.red(`agents list failed: ${err.message}`));
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ── show ──────────────────────────────────────────────────────────────
|
|
67
|
+
cmd
|
|
68
|
+
.command("show <name>")
|
|
69
|
+
.description("Show an agent's metadata + system prompt")
|
|
70
|
+
.option("--json", "Output as JSON")
|
|
71
|
+
.action(async (name, options) => {
|
|
72
|
+
try {
|
|
73
|
+
const { getAgent } = await import("../lib/agents.js");
|
|
74
|
+
const a = getAgent(name, process.cwd());
|
|
75
|
+
if (!a) {
|
|
76
|
+
logger.error(chalk.red(`no such agent: ${name}`));
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (options.json) {
|
|
81
|
+
console.log(JSON.stringify(a, null, 2));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
logger.log(chalk.bold(a.name) + chalk.gray(` [${a.scope}]`));
|
|
85
|
+
if (a.description) logger.log(chalk.gray(` ${a.description}`));
|
|
86
|
+
logger.log(
|
|
87
|
+
chalk.gray(
|
|
88
|
+
` tools: ${a.tools ? a.tools.join(",") : "(all)"}` +
|
|
89
|
+
`${a.model ? ` · model: ${a.model}` : ""}`,
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
logger.log(chalk.gray(` file: ${a.file}`));
|
|
93
|
+
logger.log("");
|
|
94
|
+
logger.log(a.systemPrompt || chalk.gray("(empty system prompt)"));
|
|
95
|
+
} catch (err) {
|
|
96
|
+
logger.error(chalk.red(`agents show failed: ${err.message}`));
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// ── run ───────────────────────────────────────────────────────────────
|
|
102
|
+
cmd
|
|
103
|
+
.command("run <name> [task...]")
|
|
104
|
+
.description("Run a task headlessly as the named subagent")
|
|
105
|
+
.option("--output-format <fmt>", "text | json | stream-json", "text")
|
|
106
|
+
.option("--model <model>", "Override the agent's model")
|
|
107
|
+
.option("--permission-mode <mode>", "ApprovalGate tier (see cc agent)")
|
|
108
|
+
.option("--add-dir <dir...>", "Extra workspace roots")
|
|
109
|
+
.action(async (name, task, options) => {
|
|
110
|
+
try {
|
|
111
|
+
const { getAgent } = await import("../lib/agents.js");
|
|
112
|
+
const a = getAgent(name, process.cwd());
|
|
113
|
+
if (!a) {
|
|
114
|
+
logger.error(chalk.red(`no such agent: ${name}`));
|
|
115
|
+
process.exitCode = 1;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const prompt = Array.isArray(task) ? task.join(" ").trim() : "";
|
|
119
|
+
if (!prompt) {
|
|
120
|
+
logger.error(
|
|
121
|
+
chalk.red(`agents run requires a task, e.g. cc agents run ${name} "review @src/x.js"`),
|
|
122
|
+
);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const { runAgentHeadless } = await import("../runtime/headless-runner.js");
|
|
127
|
+
const outcome = await runAgentHeadless({
|
|
128
|
+
prompt,
|
|
129
|
+
// The agent file's body becomes the system prompt (its persona).
|
|
130
|
+
systemPrompt: a.systemPrompt || undefined,
|
|
131
|
+
// Frontmatter `tools` scopes the run; null = inherit all.
|
|
132
|
+
allowedTools: a.tools || undefined,
|
|
133
|
+
model: options.model || a.model || undefined,
|
|
134
|
+
outputFormat: options.outputFormat,
|
|
135
|
+
permissionMode: options.permissionMode,
|
|
136
|
+
additionalDirectories: Array.isArray(options.addDir)
|
|
137
|
+
? options.addDir
|
|
138
|
+
: [],
|
|
139
|
+
});
|
|
140
|
+
process.exit(outcome.exitCode);
|
|
141
|
+
} catch (err) {
|
|
142
|
+
logger.error(chalk.red(`agents run failed: ${err.message}`));
|
|
143
|
+
process.exitCode = 1;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ── new (scaffold) ────────────────────────────────────────────────────
|
|
148
|
+
cmd
|
|
149
|
+
.command("new <name>")
|
|
150
|
+
.description("Scaffold a new agent file under .claude/agents/")
|
|
151
|
+
.option("--description <d>", "Frontmatter description")
|
|
152
|
+
.option("--tools <list>", "Comma-separated tool allow-list")
|
|
153
|
+
.option("--personal", "Create under ~/.claude/agents instead of project")
|
|
154
|
+
.action(async (name, options) => {
|
|
155
|
+
try {
|
|
156
|
+
const fs = await import("node:fs");
|
|
157
|
+
const path = await import("node:path");
|
|
158
|
+
const { homedir } = await import("node:os");
|
|
159
|
+
const safe = String(name).replace(/^\//, "").replace(/:/g, "/");
|
|
160
|
+
const root = options.personal
|
|
161
|
+
? path.join(homedir(), ".claude", "agents")
|
|
162
|
+
: path.join(process.cwd(), ".claude", "agents");
|
|
163
|
+
const file = path.join(root, `${safe}.md`);
|
|
164
|
+
if (fs.existsSync(file)) {
|
|
165
|
+
logger.error(chalk.red(`already exists: ${file}`));
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
170
|
+
const toolsLine = options.tools
|
|
171
|
+
? `tools: ${options.tools}\n`
|
|
172
|
+
: "# tools: read_file, search_files # omit to inherit all tools\n";
|
|
173
|
+
const tpl = `---
|
|
174
|
+
name: ${safe.replace(/\//g, ":")}
|
|
175
|
+
description: ${options.description || name}
|
|
176
|
+
${toolsLine}---
|
|
177
|
+
|
|
178
|
+
You are a focused subagent. Describe its role, constraints, and output format
|
|
179
|
+
here — this whole body becomes the system prompt for \`cc agents run ${safe.replace(/\//g, ":")}\`.
|
|
180
|
+
`;
|
|
181
|
+
fs.writeFileSync(file, tpl, "utf-8");
|
|
182
|
+
logger.log(chalk.green(`✓ created ${file}`));
|
|
183
|
+
logger.log(
|
|
184
|
+
chalk.gray(
|
|
185
|
+
` run it with: cc agents run ${safe.replace(/\//g, ":")} "<task>"`,
|
|
186
|
+
),
|
|
187
|
+
);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
logger.error(chalk.red(`agents new failed: ${err.message}`));
|
|
190
|
+
process.exitCode = 1;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc command — user-defined slash-command macros (Claude-Code parity).
|
|
3
|
+
*
|
|
4
|
+
* cc command list [--json] list discovered commands
|
|
5
|
+
* cc command show <name> show metadata + template body
|
|
6
|
+
* cc command run <name> [args...] [opts] expand the template and run it
|
|
7
|
+
* headlessly (or --print-prompt)
|
|
8
|
+
* cc command new <name> [--description <d>] scaffold a command file
|
|
9
|
+
*
|
|
10
|
+
* Commands live in `.claude/commands/` (project, recursive) or
|
|
11
|
+
* `~/.claude/commands/` (personal). A file `git/commit.md` → command
|
|
12
|
+
* `git:commit`. Template body
|
|
13
|
+
* supports $ARGUMENTS / $1..$9, !`bash` bang execution, and @path file refs.
|
|
14
|
+
* Distinct from skills (AI-invoked); these are macros you run explicitly.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import chalk from "chalk";
|
|
18
|
+
import { logger } from "../lib/logger.js";
|
|
19
|
+
|
|
20
|
+
export function registerCommandCommand(program) {
|
|
21
|
+
const cmd = program
|
|
22
|
+
.command("command")
|
|
23
|
+
.alias("cmd")
|
|
24
|
+
.description("User-defined slash-command macros (.claude/commands/*.md)");
|
|
25
|
+
|
|
26
|
+
// ── list ──────────────────────────────────────────────────────────────
|
|
27
|
+
cmd
|
|
28
|
+
.command("list")
|
|
29
|
+
.alias("ls")
|
|
30
|
+
.description("List discovered command macros (project + personal)")
|
|
31
|
+
.option("--json", "Output as JSON")
|
|
32
|
+
.action(async (options) => {
|
|
33
|
+
try {
|
|
34
|
+
const { discoverCommands } = await import("../lib/slash-commands.js");
|
|
35
|
+
const all = discoverCommands(process.cwd());
|
|
36
|
+
if (options.json) {
|
|
37
|
+
console.log(JSON.stringify(all, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (all.length === 0) {
|
|
41
|
+
logger.log(
|
|
42
|
+
chalk.gray(
|
|
43
|
+
"No command macros. Create one: cc command new <name> " +
|
|
44
|
+
"(or add .claude/commands/<name>.md)",
|
|
45
|
+
),
|
|
46
|
+
);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
for (const c of all) {
|
|
50
|
+
const tag =
|
|
51
|
+
c.scope === "project" ? chalk.cyan("[proj]") : chalk.gray("[pers]");
|
|
52
|
+
logger.log(
|
|
53
|
+
`${chalk.bold("/" + c.name.padEnd(22))} ${tag} ${chalk.gray(c.description || "")}` +
|
|
54
|
+
(c.argumentHint ? chalk.dim(` ${c.argumentHint}`) : ""),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
logger.error(chalk.red(`command list failed: ${err.message}`));
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// ── show ──────────────────────────────────────────────────────────────
|
|
64
|
+
cmd
|
|
65
|
+
.command("show <name>")
|
|
66
|
+
.description("Show a command's metadata and template body")
|
|
67
|
+
.option("--json", "Output as JSON")
|
|
68
|
+
.action(async (name, options) => {
|
|
69
|
+
try {
|
|
70
|
+
const { getCommand } = await import("../lib/slash-commands.js");
|
|
71
|
+
const c = getCommand(name, process.cwd());
|
|
72
|
+
if (!c) {
|
|
73
|
+
logger.error(chalk.red(`no such command: ${name}`));
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (options.json) {
|
|
78
|
+
console.log(JSON.stringify(c, null, 2));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
logger.log(
|
|
82
|
+
chalk.bold(`/${c.name}`) + ` ${chalk.gray(`[${c.scope}]`)}`,
|
|
83
|
+
);
|
|
84
|
+
if (c.description) logger.log(chalk.gray(` ${c.description}`));
|
|
85
|
+
if (c.argumentHint) logger.log(chalk.gray(` args: ${c.argumentHint}`));
|
|
86
|
+
if (c.model) logger.log(chalk.gray(` model: ${c.model}`));
|
|
87
|
+
if (c.allowedTools)
|
|
88
|
+
logger.log(chalk.gray(` allowed-tools: ${c.allowedTools}`));
|
|
89
|
+
logger.log(chalk.gray(` file: ${c.file}`));
|
|
90
|
+
logger.log(chalk.dim(" ───"));
|
|
91
|
+
logger.log(c.body);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
logger.error(chalk.red(`command show failed: ${err.message}`));
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ── run ───────────────────────────────────────────────────────────────
|
|
99
|
+
cmd
|
|
100
|
+
.command("run <name> [args...]")
|
|
101
|
+
.description("Expand a command template and run it headlessly")
|
|
102
|
+
.option("--print-prompt", "Print the expanded prompt without running it")
|
|
103
|
+
.option("--no-bang", "Do not execute !`cmd` bang segments")
|
|
104
|
+
.option("--output-format <fmt>", "text | json | stream-json", "text")
|
|
105
|
+
.option("--model <model>", "Override the model")
|
|
106
|
+
.option("--permission-mode <mode>", "ApprovalGate tier (see cc agent)")
|
|
107
|
+
.action(async (name, args, options) => {
|
|
108
|
+
try {
|
|
109
|
+
const { getCommand, expandCommand } =
|
|
110
|
+
await import("../lib/slash-commands.js");
|
|
111
|
+
const c = getCommand(name, process.cwd());
|
|
112
|
+
if (!c) {
|
|
113
|
+
logger.error(chalk.red(`no such command: ${name}`));
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const { prompt, warnings } = expandCommand(c, args, {
|
|
118
|
+
cwd: process.cwd(),
|
|
119
|
+
allowBang: options.bang !== false, // commander maps --no-bang → bang:false
|
|
120
|
+
});
|
|
121
|
+
for (const w of warnings) process.stderr.write(` @ref: ${w}\n`);
|
|
122
|
+
|
|
123
|
+
if (options.printPrompt) {
|
|
124
|
+
console.log(prompt);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const { runAgentHeadless, parseToolList } =
|
|
129
|
+
await import("../runtime/headless-runner.js");
|
|
130
|
+
const outcome = await runAgentHeadless({
|
|
131
|
+
prompt,
|
|
132
|
+
outputFormat: options.outputFormat,
|
|
133
|
+
model: options.model || c.model || undefined,
|
|
134
|
+
permissionMode: options.permissionMode,
|
|
135
|
+
// A command's frontmatter allowed-tools scopes the run.
|
|
136
|
+
allowedTools: parseToolList(c.allowedTools),
|
|
137
|
+
});
|
|
138
|
+
process.exit(outcome.exitCode);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
logger.error(chalk.red(`command run failed: ${err.message}`));
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// ── new (scaffold) ────────────────────────────────────────────────────
|
|
146
|
+
cmd
|
|
147
|
+
.command("new <name>")
|
|
148
|
+
.description("Scaffold a new command file under .claude/commands/")
|
|
149
|
+
.option("--description <d>", "Frontmatter description")
|
|
150
|
+
.option("--personal", "Create under ~/.claude/commands instead of project")
|
|
151
|
+
.action(async (name, options) => {
|
|
152
|
+
try {
|
|
153
|
+
const fs = await import("node:fs");
|
|
154
|
+
const path = await import("node:path");
|
|
155
|
+
const { homedir } = await import("node:os");
|
|
156
|
+
const safe = String(name).replace(/^\//, "").replace(/:/g, "/");
|
|
157
|
+
const root = options.personal
|
|
158
|
+
? path.join(homedir(), ".claude", "commands")
|
|
159
|
+
: path.join(process.cwd(), ".claude", "commands");
|
|
160
|
+
const file = path.join(root, `${safe}.md`);
|
|
161
|
+
if (fs.existsSync(file)) {
|
|
162
|
+
logger.error(chalk.red(`already exists: ${file}`));
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
167
|
+
const tpl = `---
|
|
168
|
+
description: ${options.description || name}
|
|
169
|
+
argument-hint: "[args]"
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
Describe the task here. Use $ARGUMENTS for all args, $1/$2 for positional,
|
|
173
|
+
@path to inline file contents, and !\`git status\` to splice in command output.
|
|
174
|
+
`;
|
|
175
|
+
fs.writeFileSync(file, tpl, "utf-8");
|
|
176
|
+
logger.log(chalk.green(`✓ created ${file}`));
|
|
177
|
+
logger.log(
|
|
178
|
+
chalk.gray(
|
|
179
|
+
` run it with: cc command run ${safe.replace(/\//g, ":")} <args>`,
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
logger.error(chalk.red(`command new failed: ${err.message}`));
|
|
184
|
+
process.exitCode = 1;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc context [sessionId] — context-window token breakdown for a session.
|
|
3
|
+
*
|
|
4
|
+
* Shows how a session's stored conversation fills the model context window,
|
|
5
|
+
* grouped by role (system / user / assistant / tool), with the share each takes
|
|
6
|
+
* and the headroom remaining. Reuses the SAME token estimator + window table as
|
|
7
|
+
* the headless auto-compactor (prompt-compressor.js) and the JSONL session store
|
|
8
|
+
* (rebuildMessages) — no new data is collected, this is purely a reporting view.
|
|
9
|
+
*
|
|
10
|
+
* Complements `cc cost` ($ spend) and `cc session usage` (raw token counts):
|
|
11
|
+
* this is the "how full is the window right now" view (Claude-Code `/context`).
|
|
12
|
+
*
|
|
13
|
+
* cc context # most-recent headless session
|
|
14
|
+
* cc context <sessionId>
|
|
15
|
+
* cc context --model claude-sonnet-4-6 # size against a specific window
|
|
16
|
+
* cc context --json
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import chalk from "chalk";
|
|
20
|
+
import { logger } from "../lib/logger.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Bucket message tokens by role. tool_calls carried on assistant messages are
|
|
24
|
+
* counted separately so the breakdown reflects what actually fills the window.
|
|
25
|
+
*/
|
|
26
|
+
export function categorizeContext(messages, estimateTokens) {
|
|
27
|
+
const buckets = { system: 0, user: 0, assistant: 0, tool: 0, toolCalls: 0 };
|
|
28
|
+
const counts = { system: 0, user: 0, assistant: 0, tool: 0 };
|
|
29
|
+
for (const m of messages) {
|
|
30
|
+
if (!m) continue;
|
|
31
|
+
const role =
|
|
32
|
+
m.role === "system" || m.role === "user" || m.role === "tool"
|
|
33
|
+
? m.role
|
|
34
|
+
: "assistant";
|
|
35
|
+
const content =
|
|
36
|
+
typeof m.content === "string"
|
|
37
|
+
? m.content
|
|
38
|
+
: JSON.stringify(m.content || "");
|
|
39
|
+
buckets[role] += estimateTokens(content);
|
|
40
|
+
counts[role] += 1;
|
|
41
|
+
if (Array.isArray(m.tool_calls) && m.tool_calls.length) {
|
|
42
|
+
buckets.toolCalls += estimateTokens(JSON.stringify(m.tool_calls));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const total =
|
|
46
|
+
buckets.system +
|
|
47
|
+
buckets.user +
|
|
48
|
+
buckets.assistant +
|
|
49
|
+
buckets.tool +
|
|
50
|
+
buckets.toolCalls;
|
|
51
|
+
return { buckets, counts, total };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function bar(frac, width = 24) {
|
|
55
|
+
const f = Math.max(0, Math.min(1, frac || 0));
|
|
56
|
+
const filled = Math.round(f * width);
|
|
57
|
+
return "█".repeat(filled) + "░".repeat(width - filled);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function registerContextCommand(program) {
|
|
61
|
+
program
|
|
62
|
+
.command("context")
|
|
63
|
+
.description(
|
|
64
|
+
"Context-window token breakdown for a session (Claude-Code /context parity)",
|
|
65
|
+
)
|
|
66
|
+
.argument("[id]", "Session ID (omit for the most-recent headless session)")
|
|
67
|
+
.option("--model <model>", "Size against this model's context window")
|
|
68
|
+
.option("--provider <provider>", "Provider (for the window default)")
|
|
69
|
+
.option("--json", "Output as JSON")
|
|
70
|
+
.action(async (id, options) => {
|
|
71
|
+
const {
|
|
72
|
+
rebuildMessages,
|
|
73
|
+
getLastSessionId,
|
|
74
|
+
sessionExists,
|
|
75
|
+
readEvents,
|
|
76
|
+
} = await import("../harness/jsonl-session-store.js");
|
|
77
|
+
const { estimateTokens, getContextWindow } = await import(
|
|
78
|
+
"../harness/prompt-compressor.js"
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const sessionId = id || getLastSessionId();
|
|
82
|
+
if (!sessionId) {
|
|
83
|
+
logger.error(
|
|
84
|
+
'No session found. Run a headless agent with `--session <id>` first, or pass a session id.',
|
|
85
|
+
);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!sessionExists(sessionId)) {
|
|
90
|
+
logger.error(
|
|
91
|
+
`No headless transcript for session "${sessionId}" (headless sessions are JSONL-only).`,
|
|
92
|
+
);
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const messages = rebuildMessages(sessionId) || [];
|
|
98
|
+
|
|
99
|
+
// Auto-detect the session's model/provider from its session_start header,
|
|
100
|
+
// overridable by flags so you can size the same transcript against a
|
|
101
|
+
// different window.
|
|
102
|
+
let recordedModel = "";
|
|
103
|
+
let recordedProvider = "";
|
|
104
|
+
try {
|
|
105
|
+
const start = (readEvents(sessionId) || []).find(
|
|
106
|
+
(e) => e.type === "session_start",
|
|
107
|
+
);
|
|
108
|
+
recordedModel = start?.data?.model || "";
|
|
109
|
+
recordedProvider = start?.data?.provider || "";
|
|
110
|
+
} catch {
|
|
111
|
+
// header optional — fall through to flags/defaults
|
|
112
|
+
}
|
|
113
|
+
const model = options.model || recordedModel || null;
|
|
114
|
+
const provider = options.provider || recordedProvider || "ollama";
|
|
115
|
+
const window = getContextWindow(model, provider);
|
|
116
|
+
|
|
117
|
+
const { buckets, counts, total } = categorizeContext(
|
|
118
|
+
messages,
|
|
119
|
+
estimateTokens,
|
|
120
|
+
);
|
|
121
|
+
const used = window > 0 ? total / window : 0;
|
|
122
|
+
const remaining = Math.max(0, window - total);
|
|
123
|
+
|
|
124
|
+
if (options.json) {
|
|
125
|
+
console.log(
|
|
126
|
+
JSON.stringify(
|
|
127
|
+
{
|
|
128
|
+
sessionId,
|
|
129
|
+
model: model || null,
|
|
130
|
+
provider,
|
|
131
|
+
contextWindow: window,
|
|
132
|
+
totalTokens: total,
|
|
133
|
+
usedFraction: Number(used.toFixed(4)),
|
|
134
|
+
remainingTokens: remaining,
|
|
135
|
+
messageCount: messages.length,
|
|
136
|
+
breakdown: buckets,
|
|
137
|
+
counts,
|
|
138
|
+
overflows: total > window,
|
|
139
|
+
},
|
|
140
|
+
null,
|
|
141
|
+
2,
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
logger.log(chalk.bold(`Context — session ${chalk.gray(sessionId.slice(0, 28))}`));
|
|
148
|
+
logger.log(
|
|
149
|
+
chalk.gray(
|
|
150
|
+
` model ${model || "(default)"} · provider ${provider} · ` +
|
|
151
|
+
`window ${window.toLocaleString()} tokens · ${messages.length} messages`,
|
|
152
|
+
),
|
|
153
|
+
);
|
|
154
|
+
logger.log("");
|
|
155
|
+
|
|
156
|
+
const rows = [
|
|
157
|
+
["system", buckets.system, counts.system],
|
|
158
|
+
["user", buckets.user, counts.user],
|
|
159
|
+
["assistant", buckets.assistant, counts.assistant],
|
|
160
|
+
["tool results", buckets.tool, counts.tool],
|
|
161
|
+
["tool calls", buckets.toolCalls, null],
|
|
162
|
+
];
|
|
163
|
+
for (const [label, tok, cnt] of rows) {
|
|
164
|
+
if (!tok) continue;
|
|
165
|
+
const frac = total ? tok / total : 0;
|
|
166
|
+
logger.log(
|
|
167
|
+
` ${label.padEnd(13)} ${String(tok).padStart(7)} ` +
|
|
168
|
+
`${chalk.cyan(bar(frac))} ${String(Math.round(frac * 100)).padStart(3)}%` +
|
|
169
|
+
`${cnt != null ? chalk.gray(` (${cnt})`) : ""}`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
logger.log("");
|
|
174
|
+
const pct = (used * 100).toFixed(1);
|
|
175
|
+
const color = used > 0.9 ? chalk.red : used > 0.7 ? chalk.yellow : chalk.green;
|
|
176
|
+
logger.log(
|
|
177
|
+
` ${chalk.bold("total".padEnd(11))} ${String(total).padStart(7)} ` +
|
|
178
|
+
`${color(bar(used))} ${color(`${pct}% of window`)}`,
|
|
179
|
+
);
|
|
180
|
+
logger.log(
|
|
181
|
+
chalk.gray(` headroom ${String(remaining).padStart(7)} tokens remaining`),
|
|
182
|
+
);
|
|
183
|
+
if (total > window) {
|
|
184
|
+
logger.log(
|
|
185
|
+
chalk.red(" ⚠ exceeds the model context window — compaction required"),
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
package/src/index.js
CHANGED
|
@@ -57,8 +57,11 @@ import { registerPermMemCommand } from "./commands/permmem.js";
|
|
|
57
57
|
import { registerRCacheCommand } from "./commands/rcache.js";
|
|
58
58
|
import { registerSessionCommand } from "./commands/session.js";
|
|
59
59
|
import { registerCostCommand } from "./commands/cost.js";
|
|
60
|
+
import { registerContextCommand } from "./commands/context.js";
|
|
61
|
+
import { registerAgentsCommand } from "./commands/agents.js";
|
|
60
62
|
import { registerCheckpointCommand } from "./commands/checkpoint.js";
|
|
61
63
|
import { registerGoalCommand } from "./commands/goal.js";
|
|
64
|
+
import { registerCommandCommand } from "./commands/command.js";
|
|
62
65
|
import { registerCompactCommand } from "./commands/compact.js";
|
|
63
66
|
import { registerConsolCommand } from "./commands/consol.js";
|
|
64
67
|
import { registerImportCommand } from "./commands/import.js";
|
|
@@ -453,8 +456,11 @@ export function createProgram(opts = {}) {
|
|
|
453
456
|
registerRCacheCommand(program);
|
|
454
457
|
registerSessionCommand(program);
|
|
455
458
|
registerCostCommand(program);
|
|
459
|
+
registerContextCommand(program);
|
|
460
|
+
registerAgentsCommand(program);
|
|
456
461
|
registerCheckpointCommand(program);
|
|
457
462
|
registerGoalCommand(program);
|
|
463
|
+
registerCommandCommand(program);
|
|
458
464
|
registerCompactCommand(program);
|
|
459
465
|
registerConsolCommand(program);
|
|
460
466
|
|