Merge pull request #586 from clawdbot/temp/landpr-492

fix(commands): wire /usage alias to /status
This commit is contained in:
Peter Steinberger
2026-01-09 16:14:11 +00:00
committed by GitHub
10 changed files with 34 additions and 5 deletions

View File

@@ -9,6 +9,7 @@
- Providers: add Microsoft Teams provider with polling, attachments, and CLI send support. (#404) — thanks @onutc
- Slack: honor reply tags + replyToMode while keeping threaded replies in-thread. (#574) — thanks @bolismauro
- Commands: accept /models as an alias for /model.
- Commands: add `/usage` as an alias for `/status`. (#492) — thanks @lc0rp
- Models/Auth: show per-agent auth candidates in `/model status`, and add `clawdbot models auth order {get,set,clear}` (per-agent auth rotation overrides). — thanks @steipete
- Debugging: add raw model stream logging flags and document gateway watch mode.
- Gateway: decode dns-sd escaped UTF-8 in discovery output and show scan progress immediately. — thanks @steipete

View File

@@ -377,7 +377,7 @@ Options:
Clawdbot can surface provider usage/quota when OAuth/API creds are available.
Surfaces:
- `/status` (adds a short usage line when available)
- `/status` (alias: `/usage`; adds a short usage line when available)
- `clawdbot status --usage` (prints full provider breakdown)
- macOS menu bar (Usage section under Context)

View File

@@ -35,7 +35,7 @@ Directives (`/think`, `/verbose`, `/reasoning`, `/elevated`) are parsed even whe
Text + native (when enabled):
- `/help`
- `/status`
- `/status` (alias: `/usage`)
- `/debug show|set|unset|reset` (runtime overrides, owner-only)
- `/cost on|off` (toggle per-response usage line)
- `/stop`

View File

@@ -44,6 +44,8 @@ describe("control command parsing", () => {
expect(hasControlCommand("help")).toBe(false);
expect(hasControlCommand("/status")).toBe(true);
expect(hasControlCommand("/status:")).toBe(true);
expect(hasControlCommand("/usage")).toBe(true);
expect(hasControlCommand("/usage:")).toBe(true);
expect(hasControlCommand("status")).toBe(false);
});

View File

@@ -24,6 +24,8 @@ describe("commands registry", () => {
expect(detection.exact.has("/help")).toBe(true);
expect(detection.regex.test("/status")).toBe(true);
expect(detection.regex.test("/status:")).toBe(true);
expect(detection.regex.test("/usage")).toBe(true);
expect(detection.regex.test("/usage:")).toBe(true);
expect(detection.regex.test("/stop")).toBe(true);
expect(detection.regex.test("/send:")).toBe(true);
expect(detection.regex.test("/debug set foo=bar")).toBe(true);

View File

@@ -25,7 +25,7 @@ const CHAT_COMMANDS: ChatCommandDefinition[] = [
key: "status",
nativeName: "status",
description: "Show current status.",
textAliases: ["/status"],
textAliases: ["/status", "/usage"],
},
{
key: "debug",

View File

@@ -144,6 +144,12 @@ describe("directive parsing", () => {
expect(res.cleaned).toBe("thats not /tmp/hello");
});
it("preserves spacing when stripping usage directives before paths", () => {
const res = extractStatusDirective("thats not /usage:/tmp/hello");
expect(res.hasDirective).toBe(true);
expect(res.cleaned).toBe("thats not /tmp/hello");
});
it("parses queue options and modes", () => {
const res = extractQueueDirective(
"please /queue steer+backlog debounce:2s cap:5 drop:summarize now",

View File

@@ -242,6 +242,23 @@ describe("trigger handling", () => {
});
});
it("reports status via /usage without invoking the agent", async () => {
await withTempHome(async (home) => {
const res = await getReplyFromConfig(
{
Body: "/usage",
From: "+1002",
To: "+2000",
},
{},
makeCfg(home),
);
const text = Array.isArray(res) ? res[0]?.text : res?.text;
expect(text).toContain("ClawdBot");
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
});
});
it("reports active auth profile and key snippet in status", async () => {
await withTempHome(async (home) => {
const cfg = makeCfg(home);

View File

@@ -594,7 +594,8 @@ export async function handleCommands(params: {
const statusRequested =
directives.hasStatusDirective ||
command.commandBodyNormalized === "/status";
command.commandBodyNormalized === "/status" ||
command.commandBodyNormalized === "/usage";
if (allowTextCommands && statusRequested) {
const reply = await buildStatusReply({
cfg,

View File

@@ -170,7 +170,7 @@ export function extractStatusDirective(body?: string): {
hasDirective: boolean;
} {
if (!body) return { cleaned: "", hasDirective: false };
return extractSimpleDirective(body, ["status"]);
return extractSimpleDirective(body, ["status", "usage"]);
}
export type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel };