Skip to content

Commit 9a79820

Browse files
authored
Merge pull request #41 from atxp-dev/naveen/agent-register-cli-added
feat: Add --registration-id flag for two-step agent registration
2 parents e3adb9a + d053f24 commit 9a79820

1 file changed

Lines changed: 46 additions & 33 deletions

File tree

packages/atxp/src/commands/agent.ts

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,16 @@ function showAgentHelp(): void {
4848
console.log(' - A connection token for SDK/CLI access');
4949
console.log();
5050
console.log(chalk.bold('Register Options:'));
51-
console.log(' ' + chalk.yellow('--server') + ' ' + 'Accounts server URL (default: https://accounts.atxp.ai)');
52-
console.log(' ' + chalk.yellow('--answer') + ' ' + 'Provide the challenge answer non-interactively');
51+
console.log(' ' + chalk.yellow('--server') + ' ' + 'Accounts server URL (default: https://accounts.atxp.ai)');
52+
console.log(' ' + chalk.yellow('--answer') + ' ' + 'Provide the challenge answer non-interactively');
53+
console.log(' ' + chalk.yellow('--registration-id') + ' ' + 'Resume a previous challenge (skip fetching a new one)');
5354
console.log();
5455
console.log(chalk.bold('Examples:'));
5556
console.log(' npx atxp agent create');
5657
console.log(' npx atxp agent list');
5758
console.log(' npx atxp agent register');
5859
console.log(' npx atxp agent register --server http://localhost:8016');
60+
console.log(' npx atxp agent register --registration-id reg_xxx --answer "535.00"');
5961
console.log(' CONNECTION_TOKEN=<agent_token> npx atxp email inbox');
6062
}
6163

@@ -150,42 +152,53 @@ function promptForInput(prompt: string): Promise<string> {
150152
async function registerAgent(): Promise<void> {
151153
const baseUrl = getArgValue('--server') || getBaseUrl();
152154
const presetAnswer = getArgValue('--answer');
155+
const presetRegistrationId = getArgValue('--registration-id');
153156

154-
// Step 1: Get challenge
155-
console.log(chalk.gray(`Requesting challenge from ${baseUrl}...`));
157+
let registrationId: string;
156158

157-
const challengeRes = await fetch(`${baseUrl}/agents/register`, {
158-
method: 'POST',
159-
headers: { 'Content-Type': 'application/json' },
160-
});
159+
if (presetRegistrationId) {
160+
// Resume a previous challenge — skip fetching a new one
161+
registrationId = presetRegistrationId;
162+
console.log(chalk.gray(`Resuming registration ${registrationId}...`));
163+
} else {
164+
// Step 1: Get challenge
165+
console.log(chalk.gray(`Requesting challenge from ${baseUrl}...`));
161166

162-
if (!challengeRes.ok) {
163-
const body = await challengeRes.json().catch(() => ({})) as Record<string, string>;
164-
console.error(chalk.red(`Error: ${body.error_description || body.error || challengeRes.statusText}`));
165-
process.exit(1);
166-
}
167+
const challengeRes = await fetch(`${baseUrl}/agents/register`, {
168+
method: 'POST',
169+
headers: { 'Content-Type': 'application/json' },
170+
});
167171

168-
const challenge = await challengeRes.json() as {
169-
registration_id: string;
170-
challenge: string;
171-
instructions: string;
172-
expires_at: string;
173-
};
172+
if (!challengeRes.ok) {
173+
const body = await challengeRes.json().catch(() => ({})) as Record<string, string>;
174+
console.error(chalk.red(`Error: ${body.error_description || body.error || challengeRes.statusText}`));
175+
process.exit(1);
176+
}
174177

175-
// Decode base64 challenge and instructions
176-
const decodedChallenge = Buffer.from(challenge.challenge, 'base64').toString('utf-8');
177-
const decodedInstructions = Buffer.from(challenge.instructions, 'base64').toString('utf-8');
178+
const challenge = await challengeRes.json() as {
179+
registration_id: string;
180+
challenge: string;
181+
instructions: string;
182+
expires_at: string;
183+
};
178184

179-
console.log();
180-
console.log(chalk.bold('Challenge:'));
181-
console.log(' ' + chalk.yellow(decodedChallenge));
182-
console.log();
183-
console.log(chalk.bold('Instructions:'));
184-
console.log(' ' + decodedInstructions);
185-
console.log();
186-
console.log(chalk.gray(`Registration ID: ${challenge.registration_id}`));
187-
console.log(chalk.gray(`Expires at: ${challenge.expires_at}`));
188-
console.log();
185+
registrationId = challenge.registration_id;
186+
187+
// Decode base64 challenge and instructions
188+
const decodedChallenge = Buffer.from(challenge.challenge, 'base64').toString('utf-8');
189+
const decodedInstructions = Buffer.from(challenge.instructions, 'base64').toString('utf-8');
190+
191+
console.log();
192+
console.log(chalk.bold('Challenge:'));
193+
console.log(' ' + chalk.yellow(decodedChallenge));
194+
console.log();
195+
console.log(chalk.bold('Instructions:'));
196+
console.log(' ' + decodedInstructions);
197+
console.log();
198+
console.log(chalk.gray(`Registration ID: ${registrationId}`));
199+
console.log(chalk.gray(`Expires at: ${challenge.expires_at}`));
200+
console.log();
201+
}
189202

190203
// Step 2: Get answer
191204
let answer: string;
@@ -208,7 +221,7 @@ async function registerAgent(): Promise<void> {
208221
method: 'POST',
209222
headers: { 'Content-Type': 'application/json' },
210223
body: JSON.stringify({
211-
registration_id: challenge.registration_id,
224+
registration_id: registrationId,
212225
answer,
213226
}),
214227
});

0 commit comments

Comments
 (0)