mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
fix(test): guard claude usage debug args
This commit is contained in:
parent
50b5238b38
commit
a971641a54
2 changed files with 126 additions and 10 deletions
|
|
@ -16,6 +16,7 @@ import {
|
|||
|
||||
type Args = {
|
||||
agentId: string;
|
||||
help: boolean;
|
||||
reveal: boolean;
|
||||
sessionKey?: string;
|
||||
};
|
||||
|
|
@ -36,31 +37,86 @@ const mask = (value: string) => {
|
|||
);
|
||||
};
|
||||
|
||||
const parseArgs = (): Args => {
|
||||
const args = process.argv.slice(2);
|
||||
const parseArgs = (args = process.argv.slice(2)): Args => {
|
||||
let agentId = "main";
|
||||
let help = false;
|
||||
let reveal = false;
|
||||
let sessionKey: string | undefined;
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg === "--agent" && args[i + 1]) {
|
||||
agentId = args[++i].trim() || "main";
|
||||
if (arg === "--agent") {
|
||||
agentId = parseNonBlankArgValue(parseRequiredArgValue(args, i, "--agent"), "--agent");
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith("--agent=")) {
|
||||
agentId = parseNonBlankArgValue(parseInlineArgValue(arg, "--agent"), "--agent");
|
||||
continue;
|
||||
}
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
help = true;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--reveal") {
|
||||
reveal = true;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--session-key" && args[i + 1]) {
|
||||
sessionKey = normalizeOptionalString(args[++i]);
|
||||
if (arg === "--session-key") {
|
||||
sessionKey = parseNonBlankArgValue(
|
||||
parseRequiredArgValue(args, i, "--session-key"),
|
||||
"--session-key",
|
||||
);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith("--session-key=")) {
|
||||
sessionKey = parseNonBlankArgValue(
|
||||
parseInlineArgValue(arg, "--session-key"),
|
||||
"--session-key",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
throw new Error(`Unknown argument: ${arg}`);
|
||||
}
|
||||
|
||||
return { agentId, reveal, sessionKey };
|
||||
return { agentId, help, reveal, sessionKey };
|
||||
};
|
||||
|
||||
function parseRequiredArgValue(args: string[], index: number, label: string): string {
|
||||
const value = args[index + 1];
|
||||
if (!value || value.startsWith("-")) {
|
||||
throw new Error(`${label} requires a value`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function parseInlineArgValue(arg: string, label: string): string {
|
||||
const value = arg.slice(`${label}=`.length);
|
||||
if (!value) {
|
||||
throw new Error(`${label} requires a value`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function parseNonBlankArgValue(value: string, label: string): string {
|
||||
const normalized = normalizeOptionalString(value);
|
||||
if (!normalized) {
|
||||
throw new Error(`${label} requires a value`);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function printUsage(): void {
|
||||
console.log(`Usage: node --import tsx scripts/debug-claude-usage.ts [options]
|
||||
|
||||
Options:
|
||||
--agent <id> OpenClaw agent id to inspect (default: main)
|
||||
--session-key <key> Claude web session key override
|
||||
--reveal Print token/session values instead of masked identifiers
|
||||
--help, -h Show this help message`);
|
||||
}
|
||||
|
||||
const loadAuthProfiles = (agentId: string) => {
|
||||
const stateRoot = process.env.OPENCLAW_STATE_DIR?.trim() || path.join(os.homedir(), ".openclaw");
|
||||
const authPath = path.join(stateRoot, "agents", agentId, "agent", "auth-profiles.json");
|
||||
|
|
@ -413,8 +469,13 @@ const fetchClaudeWebUsage = async (sessionKey: string, options: FetchOptions = {
|
|||
: { ok: false as const, step: "usage", status: usageRes.status, body: usageText };
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const opts = parseArgs();
|
||||
const main = async (argv = process.argv.slice(2)) => {
|
||||
const opts = parseArgs(argv);
|
||||
if (opts.help) {
|
||||
printUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
const { authPath, store } = loadAuthProfiles(opts.agentId);
|
||||
console.log(`Auth file: ${redactHomePath(authPath)}`);
|
||||
|
||||
|
|
@ -485,11 +546,12 @@ export const testing = {
|
|||
browserRootLabel,
|
||||
fetchAnthropicOAuthUsage,
|
||||
mask,
|
||||
parseArgs,
|
||||
readBoundedResponseText,
|
||||
resolveFetchTimeoutMs,
|
||||
};
|
||||
|
||||
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
|
||||
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1] ?? "")).href) {
|
||||
await main().catch((error: unknown) => {
|
||||
console.error(
|
||||
previewForDevToolLog(error instanceof Error ? error.message : String(error), 800),
|
||||
|
|
|
|||
|
|
@ -716,6 +716,60 @@ describe("script-specific dev tooling hardening", () => {
|
|||
expect(claudeUsageTesting.CLAUDE_COOKIE_HOST_SQL).not.toContain("%claude.ai%");
|
||||
});
|
||||
|
||||
it("rejects malformed Claude usage args before reading auth or browser state", () => {
|
||||
expect(claudeUsageTesting.parseArgs(["--agent", "work", "--session-key=abc"])).toEqual({
|
||||
agentId: "work",
|
||||
help: false,
|
||||
reveal: false,
|
||||
sessionKey: "abc",
|
||||
});
|
||||
expect(claudeUsageTesting.parseArgs(["--help"])).toEqual({
|
||||
agentId: "main",
|
||||
help: true,
|
||||
reveal: false,
|
||||
sessionKey: undefined,
|
||||
});
|
||||
expect(() => claudeUsageTesting.parseArgs(["--wat"])).toThrow("Unknown argument: --wat");
|
||||
expect(() => claudeUsageTesting.parseArgs(["--agent"])).toThrow("--agent requires a value");
|
||||
expect(() => claudeUsageTesting.parseArgs(["--agent="])).toThrow("--agent requires a value");
|
||||
expect(() => claudeUsageTesting.parseArgs(["--session-key", "--reveal"])).toThrow(
|
||||
"--session-key requires a value",
|
||||
);
|
||||
expect(() => claudeUsageTesting.parseArgs(["--session-key= "])).toThrow(
|
||||
"--session-key requires a value",
|
||||
);
|
||||
});
|
||||
|
||||
it("prints Claude usage help without opening auth stores", () => {
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
["--import", "tsx", "scripts/debug-claude-usage.ts", "--help"],
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain("Usage: node --import tsx scripts/debug-claude-usage.ts");
|
||||
expect(result.stderr).toBe("");
|
||||
});
|
||||
|
||||
it("fails missing Claude usage option values before defaulting to main auth", () => {
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
["--import", "tsx", "scripts/debug-claude-usage.ts", "--agent"],
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.stdout).toBe("");
|
||||
expect(result.stderr).toContain("--agent requires a value");
|
||||
});
|
||||
|
||||
it("aborts stalled Claude usage fetches at the request timeout", async () => {
|
||||
let signal: AbortSignal | undefined;
|
||||
const request = claudeUsageTesting.fetchAnthropicOAuthUsage("test-token", {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue