Files
sentryagent-idp/cli/src/commands/configure.ts
SentryAgent.ai Developer d1e6af25aa feat(phase-4): WS2 + WS3 — Developer Portal (Next.js 14) and CLI tool (sentryagent)
WS2: Developer Portal (portal/)
- Standalone Next.js 14 + Tailwind CSS app — independent deployment
- Home page: hero, feature grid, CTA to /get-started
- /pricing: free tier limits table (10 agents, 1k calls/day) + paid tier CTA
- /sdks: all 4 SDKs (Node.js, Python, Go, Java) with install + code examples
- /api-explorer: Swagger UI from NEXT_PUBLIC_API_URL/openapi.json, persistAuthorization
- /get-started: 4-step wizard (setup → register agent → credentials → SDK snippet)
- Shared Nav component with active-link highlighting
- Build: 8/8 static pages, zero TypeScript errors

WS3: CLI Tool (cli/ — npm package: sentryagent)
- configure, register-agent, list-agents, issue-token, rotate-credentials, tail-audit-log
- Auto OAuth2 token fetch + 30s-buffer cache via client_credentials flow
- chalk-formatted table output, confirmation prompts, bounded audit log dedup
- bash + zsh shell completion scripts
- README with installation, all commands, and completion setup
- Build: tsc clean, node dist/index.js --help verified

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 04:29:50 +00:00

64 lines
1.7 KiB
TypeScript

import * as readline from 'readline';
import { Command } from 'commander';
import chalk from 'chalk';
import { writeConfig } from '../config';
function prompt(rl: readline.Interface, question: string): Promise<string> {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer.trim());
});
});
}
export function registerConfigure(program: Command): void {
program
.command('configure')
.description('Configure the CLI with API URL and credentials')
.action(async () => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
try {
console.log(chalk.bold('SentryAgent CLI Configuration'));
console.log(chalk.dim('─'.repeat(40)));
const apiUrl = await prompt(
rl,
chalk.cyan('API URL') + ' (e.g. https://api.sentryagent.ai): ',
);
if (apiUrl === '') {
console.error(chalk.red('API URL cannot be empty.'));
process.exit(1);
}
const clientId = await prompt(rl, chalk.cyan('Client ID') + ': ');
if (clientId === '') {
console.error(chalk.red('Client ID cannot be empty.'));
process.exit(1);
}
const clientSecret = await prompt(
rl,
chalk.cyan('Client Secret') + ': ',
);
if (clientSecret === '') {
console.error(chalk.red('Client Secret cannot be empty.'));
process.exit(1);
}
writeConfig({ apiUrl, clientId, clientSecret });
console.log();
console.log(
chalk.green('✓') +
' Configuration saved to ~/.sentryagent/config.json',
);
} finally {
rl.close();
}
});
}