diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..709b18b --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,110 @@ +#!/usr/bin/env bun +/** + * CLI entry point for auth-runtime. + * + * Commands: + * token → {"token":"st_xxx"} + * session → {"accessToken":"...","expiresIn":900} + * client-config → {"clientId":"...","metadata":{...}} + * request [options] → {"status":200,"body":"..."} + * + * Options for `request`: + * --body '{"key":"value"}' Request body (JSON string) + * --api-base URL Override API base URL + * + * JSON output to stdout, errors to stderr, exit code 0/1. + */ + +import { createSkillClient } from './index.js'; + +function fatal(msg: string): never { + console.error(msg); + process.exit(1); +} + +function usage(): never { + fatal( + 'Usage:\n' + + ' auth-rt token\n' + + ' auth-rt session\n' + + ' auth-rt client-config\n' + + ' auth-rt request [--body JSON] [--api-base URL]', + ); +} + +async function main() { + const args = process.argv.slice(2); + if (args.length === 0) usage(); + + const command = args[0]; + + if (command === 'token') { + const client = createSkillClient(); + const session = await client.session(); + console.log(JSON.stringify({ token: session.accessToken })); + return; + } + + if (command === 'session') { + const client = createSkillClient(); + const session = await client.session(); + console.log(JSON.stringify(session)); + return; + } + + if (command === 'client-config') { + const client = createSkillClient(); + const config = await client.clientConfig(); + console.log(JSON.stringify(config)); + return; + } + + if (command === 'request') { + if (args.length < 3) { + fatal('request requires '); + } + + const method = args[1].toUpperCase(); + const path = args[2]; + + let body: string | undefined; + let apiBase: string | undefined; + + for (let i = 3; i < args.length; i++) { + if (args[i] === '--body' && i + 1 < args.length) { + body = args[++i]; + } else if (args[i] === '--api-base' && i + 1 < args.length) { + apiBase = args[++i]; + } + } + + const client = createSkillClient(apiBase ? { apiBase } : undefined); + + const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'] as const; + if (!validMethods.includes(method as any)) { + fatal(`Invalid method: ${method}`); + } + + const parsedBody = body ? JSON.parse(body) : undefined; + + let result; + switch (method) { + case 'GET': result = await client.get(path); break; + case 'POST': result = await client.post(path, parsedBody); break; + case 'PUT': result = await client.put(path, parsedBody); break; + case 'PATCH': result = await client.patch(path, parsedBody); break; + case 'DELETE': result = await client.delete(path, parsedBody); break; + default: fatal(`Unsupported method: ${method}`); + } + + console.log(JSON.stringify(result)); + return; + } + + fatal(`Unknown command: ${command}`); +} + +main().catch((err) => { + console.error(String(err?.message || err)); + process.exit(1); +});