agent-cards 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/bin/agent-cards.d.ts +3 -0
  2. package/dist/bin/agent-cards.d.ts.map +1 -0
  3. package/dist/bin/agent-cards.js +76 -0
  4. package/dist/bin/agent-cards.js.map +1 -0
  5. package/dist/src/commands/balance.d.ts +2 -0
  6. package/dist/src/commands/balance.d.ts.map +1 -0
  7. package/dist/src/commands/balance.js +12 -0
  8. package/dist/src/commands/balance.js.map +1 -0
  9. package/dist/src/commands/cards/create.d.ts +2 -0
  10. package/dist/src/commands/cards/create.d.ts.map +1 -0
  11. package/dist/src/commands/cards/create.js +37 -0
  12. package/dist/src/commands/cards/create.js.map +1 -0
  13. package/dist/src/commands/cards/details.d.ts +2 -0
  14. package/dist/src/commands/cards/details.d.ts.map +1 -0
  15. package/dist/src/commands/cards/details.js +16 -0
  16. package/dist/src/commands/cards/details.js.map +1 -0
  17. package/dist/src/commands/cards/list.d.ts +2 -0
  18. package/dist/src/commands/cards/list.d.ts.map +1 -0
  19. package/dist/src/commands/cards/list.js +29 -0
  20. package/dist/src/commands/cards/list.js.map +1 -0
  21. package/dist/src/commands/signup.d.ts +2 -0
  22. package/dist/src/commands/signup.d.ts.map +1 -0
  23. package/dist/src/commands/signup.js +36 -0
  24. package/dist/src/commands/signup.js.map +1 -0
  25. package/dist/src/lib/api.d.ts +8 -0
  26. package/dist/src/lib/api.d.ts.map +1 -0
  27. package/dist/src/lib/api.js +23 -0
  28. package/dist/src/lib/api.js.map +1 -0
  29. package/dist/src/lib/config.d.ts +11 -0
  30. package/dist/src/lib/config.d.ts.map +1 -0
  31. package/dist/src/lib/config.js +27 -0
  32. package/dist/src/lib/config.js.map +1 -0
  33. package/dist/src/lib/poll.d.ts +5 -0
  34. package/dist/src/lib/poll.d.ts.map +1 -0
  35. package/dist/src/lib/poll.js +12 -0
  36. package/dist/src/lib/poll.js.map +1 -0
  37. package/package.json +34 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=agent-cards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cards.d.ts","sourceRoot":"","sources":["../../bin/agent-cards.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { signup } from '../src/commands/signup.js';
4
+ import { createCard } from '../src/commands/cards/create.js';
5
+ import { listCards } from '../src/commands/cards/list.js';
6
+ import { cardDetails } from '../src/commands/cards/details.js';
7
+ import { balance } from '../src/commands/balance.js';
8
+ const program = new Command();
9
+ program
10
+ .name('agent-cards')
11
+ .description('Terminal-first prepaid virtual Visa card service')
12
+ .version('0.1.0');
13
+ program
14
+ .command('signup')
15
+ .description('Sign up or sign in via magic link')
16
+ .action(async () => {
17
+ try {
18
+ await signup();
19
+ }
20
+ catch (err) {
21
+ console.error(`Error: ${err.message}`);
22
+ process.exit(1);
23
+ }
24
+ });
25
+ const cardsCmd = program.command('cards').description('Manage virtual cards');
26
+ cardsCmd
27
+ .command('create')
28
+ .description('Fund and issue a new virtual card')
29
+ .requiredOption('--amount <dollars>', 'Amount in dollars (e.g. 50)', parseFloat)
30
+ .action(async (opts) => {
31
+ try {
32
+ await createCard(opts.amount);
33
+ }
34
+ catch (err) {
35
+ console.error(`Error: ${err.message}`);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ cardsCmd
40
+ .command('list')
41
+ .description('List all cards')
42
+ .action(async () => {
43
+ try {
44
+ await listCards();
45
+ }
46
+ catch (err) {
47
+ console.error(`Error: ${err.message}`);
48
+ process.exit(1);
49
+ }
50
+ });
51
+ cardsCmd
52
+ .command('details <id>')
53
+ .description('Show decrypted PAN / CVV / expiry for a card')
54
+ .action(async (id) => {
55
+ try {
56
+ await cardDetails(id);
57
+ }
58
+ catch (err) {
59
+ console.error(`Error: ${err.message}`);
60
+ process.exit(1);
61
+ }
62
+ });
63
+ program
64
+ .command('balance <id>')
65
+ .description('Quick balance check for a card')
66
+ .action(async (id) => {
67
+ try {
68
+ await balance(id);
69
+ }
70
+ catch (err) {
71
+ console.error(`Error: ${err.message}`);
72
+ process.exit(1);
73
+ }
74
+ });
75
+ program.parse();
76
+ //# sourceMappingURL=agent-cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cards.js","sourceRoot":"","sources":["../../bin/agent-cards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function balance(cardId: string): Promise<void>;
2
+ //# sourceMappingURL=balance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../../src/commands/balance.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3D"}
@@ -0,0 +1,12 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { api } from '../lib/api.js';
4
+ export async function balance(cardId) {
5
+ const spinner = ora('Fetching balance...').start();
6
+ const result = await api(`/cards/${cardId}/balance`);
7
+ spinner.stop();
8
+ const dollars = (result.balanceCents / 100).toFixed(2);
9
+ const suffix = result.cached ? chalk.dim(' (cached)') : '';
10
+ console.log(`Balance: ${chalk.green.bold('$' + dollars)}${suffix}`);
11
+ }
12
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../../src/commands/balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAc;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,GAAG,CAA6C,UAAU,MAAM,UAAU,CAAC,CAAC;IACjG,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function createCard(amountDollars: number): Promise<void>;
2
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/cards/create.ts"],"names":[],"mappings":"AAeA,wBAAsB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CrE"}
@@ -0,0 +1,37 @@
1
+ import ora from 'ora';
2
+ import chalk from 'chalk';
3
+ import open from 'open';
4
+ import { api } from '../../lib/api.js';
5
+ import { poll } from '../../lib/poll.js';
6
+ export async function createCard(amountDollars) {
7
+ if (amountDollars < 1) {
8
+ console.error(chalk.red('Amount must be at least $1'));
9
+ process.exit(1);
10
+ }
11
+ const amountCents = Math.round(amountDollars * 100);
12
+ const spinner = ora('Creating checkout session...').start();
13
+ const { sessionId, checkoutUrl } = await api('/funding/checkout', { method: 'POST', body: { amountCents } });
14
+ spinner.succeed('Checkout ready');
15
+ console.log(chalk.cyan(`\nOpening payment page for $${amountDollars.toFixed(2)}...`));
16
+ console.log(chalk.dim(`URL: ${checkoutUrl}\n`));
17
+ await open(checkoutUrl);
18
+ spinner.start('Waiting for payment confirmation...');
19
+ const result = await poll(async () => {
20
+ const res = await api(`/funding/status/${sessionId}`);
21
+ if (res.status === 'ready' && res.card)
22
+ return res.card;
23
+ if (res.status === 'failed')
24
+ throw new Error('Payment failed');
25
+ return null;
26
+ }, { timeoutMs: 600_000 });
27
+ spinner.succeed(chalk.green('Virtual card issued!'));
28
+ const balance = (result.balanceCents / 100).toFixed(2);
29
+ console.log('');
30
+ console.log(` ${chalk.bold('Card')} •••• ${chalk.cyan(result.last4)}`);
31
+ console.log(` ${chalk.bold('Expires')} ${result.expiry}`);
32
+ console.log(` ${chalk.bold('Balance')} ${chalk.green('$' + balance)}`);
33
+ console.log(` ${chalk.bold('ID')} ${chalk.dim(result.id)}`);
34
+ console.log('');
35
+ console.log(chalk.dim(`Run: agent-cards cards details ${result.id} # to see full PAN/CVV`));
36
+ }
37
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../../src/commands/cards/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function cardDetails(cardId: string): Promise<void>;
2
+ //# sourceMappingURL=details.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"details.d.ts","sourceRoot":"","sources":["../../../../src/commands/cards/details.ts"],"names":[],"mappings":"AAcA,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/D"}
@@ -0,0 +1,16 @@
1
+ import chalk from 'chalk';
2
+ import { api } from '../../lib/api.js';
3
+ export async function cardDetails(cardId) {
4
+ const card = await api(`/cards/${cardId}/details`);
5
+ console.log('');
6
+ console.log(chalk.bold('Card Details'));
7
+ console.log(chalk.dim('─'.repeat(40)));
8
+ console.log(` ${chalk.bold('PAN')} ${chalk.cyan(card.pan)}`);
9
+ console.log(` ${chalk.bold('CVV')} ${chalk.cyan(card.cvv)}`);
10
+ console.log(` ${chalk.bold('Expiry')} ${card.expiry}`);
11
+ console.log(` ${chalk.bold('Balance')} ${chalk.green('$' + (card.balanceCents / 100).toFixed(2))}`);
12
+ console.log(` ${chalk.bold('Status')} ${card.status === 'OPEN' ? chalk.green('OPEN') : chalk.red(card.status)}`);
13
+ console.log('');
14
+ console.log(chalk.red.bold('⚠ Keep this PAN/CVV confidential'));
15
+ }
16
+ //# sourceMappingURL=details.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"details.js","sourceRoot":"","sources":["../../../../src/commands/cards/details.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAavC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAc,UAAU,MAAM,UAAU,CAAC,CAAC;IAEhE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function listCards(): Promise<void>;
2
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/commands/cards/list.ts"],"names":[],"mappings":"AAcA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B/C"}
@@ -0,0 +1,29 @@
1
+ import Table from 'cli-table3';
2
+ import chalk from 'chalk';
3
+ import { api } from '../../lib/api.js';
4
+ export async function listCards() {
5
+ const { cards } = await api('/cards');
6
+ if (cards.length === 0) {
7
+ console.log(chalk.dim('No cards yet. Run: agent-cards cards create --amount <dollars>'));
8
+ return;
9
+ }
10
+ const table = new Table({
11
+ head: ['ID (short)', 'Last4', 'Expiry', 'Balance', 'Limit', 'Status'],
12
+ style: { head: ['cyan'] },
13
+ });
14
+ for (const card of cards) {
15
+ const balance = `$${(card.balanceCents / 100).toFixed(2)}`;
16
+ const limit = `$${(card.spendLimitCents / 100).toFixed(2)}`;
17
+ const statusColor = card.status === 'OPEN' ? chalk.green : chalk.red;
18
+ table.push([
19
+ card.id.slice(0, 8) + '…',
20
+ '•••• ' + card.last4,
21
+ card.expiry,
22
+ chalk.green(balance),
23
+ chalk.dim(limit),
24
+ statusColor(card.status),
25
+ ]);
26
+ }
27
+ console.log(table.toString());
28
+ }
29
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/commands/cards/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAYvC,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAoB,QAAQ,CAAC,CAAC;IAEzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC,CAAC;QACzF,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC;QACrE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE;KAC1B,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG;YACzB,OAAO,GAAG,IAAI,CAAC,KAAK;YACpB,IAAI,CAAC,MAAM;YACX,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;YACpB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;SACzB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function signup(): Promise<void>;
2
+ //# sourceMappingURL=signup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signup.d.ts","sourceRoot":"","sources":["../../../src/commands/signup.ts"],"names":[],"mappings":"AAOA,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAkC5C"}
@@ -0,0 +1,36 @@
1
+ import inquirer from 'inquirer';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import { api } from '../lib/api.js';
5
+ import { writeConfig } from '../lib/config.js';
6
+ import { poll } from '../lib/poll.js';
7
+ export async function signup() {
8
+ const { email } = await inquirer.prompt([
9
+ {
10
+ type: 'input',
11
+ name: 'email',
12
+ message: 'Enter your email address:',
13
+ validate: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v) || 'Invalid email',
14
+ },
15
+ ]);
16
+ const spinner = ora('Sending magic link...').start();
17
+ const { sessionId } = await api('/auth/signup', {
18
+ method: 'POST',
19
+ body: { email },
20
+ });
21
+ spinner.succeed(`Magic link sent to ${chalk.cyan(email)}`);
22
+ console.log(chalk.dim('Check your inbox and click the link to continue...'));
23
+ spinner.start('Waiting for verification...');
24
+ const result = await poll(async () => {
25
+ const res = await api('/auth/me', {
26
+ magicToken: sessionId,
27
+ });
28
+ if (res.status === 'verified' && res.jwt)
29
+ return res;
30
+ return null;
31
+ });
32
+ writeConfig({ email: result.email ?? email, jwt: result.jwt });
33
+ spinner.succeed(chalk.green(`Signed in as ${chalk.bold(email)}`));
34
+ console.log(chalk.dim('Credentials saved to ~/.agent-cards/config.json'));
35
+ }
36
+ //# sourceMappingURL=signup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signup.js","sourceRoot":"","sources":["../../../src/commands/signup.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACtC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,2BAA2B;YACpC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,eAAe;SACjF;KACF,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;IAErD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,CAAwB,cAAc,EAAE;QACrE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,EAAE,KAAK,EAAE;KAChB,CAAC,CAAC;IAEH,OAAO,CAAC,OAAO,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAE7E,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,IAAI,EAAE;QACnC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAmD,UAAU,EAAE;YAClF,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,GAAG,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAE/D,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,8 @@
1
+ type FetchOptions = {
2
+ method?: string;
3
+ body?: unknown;
4
+ magicToken?: string;
5
+ };
6
+ export declare function api<T>(path: string, opts?: FetchOptions): Promise<T>;
7
+ export {};
8
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lib/api.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAsB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,CAwB9E"}
@@ -0,0 +1,23 @@
1
+ import { getApiUrl, getJwt } from './config.js';
2
+ export async function api(path, opts = {}) {
3
+ const url = `${getApiUrl()}${path}`;
4
+ const jwt = getJwt();
5
+ const headers = {
6
+ 'Content-Type': 'application/json',
7
+ };
8
+ if (jwt)
9
+ headers['Authorization'] = `Bearer ${jwt}`;
10
+ if (opts.magicToken)
11
+ headers['X-Magic-Token'] = opts.magicToken;
12
+ const res = await fetch(url, {
13
+ method: opts.method ?? 'GET',
14
+ headers,
15
+ body: opts.body ? JSON.stringify(opts.body) : undefined,
16
+ });
17
+ const data = await res.json();
18
+ if (!res.ok) {
19
+ throw new Error(data.error ?? `HTTP ${res.status}`);
20
+ }
21
+ return data;
22
+ }
23
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQhD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAI,IAAY,EAAE,OAAqB,EAAE;IAChE,MAAM,GAAG,GAAG,GAAG,SAAS,EAAE,GAAG,IAAI,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IAErB,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IAEF,IAAI,GAAG;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,EAAE,CAAC;IACpD,IAAI,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IAEhE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;QAC5B,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KACxD,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAE,IAAY,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,IAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,11 @@
1
+ interface Config {
2
+ email?: string;
3
+ jwt?: string;
4
+ apiUrl?: string;
5
+ }
6
+ export declare function readConfig(): Config;
7
+ export declare function writeConfig(data: Config): void;
8
+ export declare function getApiUrl(): string;
9
+ export declare function getJwt(): string | undefined;
10
+ export {};
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAOA,UAAU,MAAM;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAOnC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,SAAS,IAAI,MAAM,CAGlC;AAED,wBAAgB,MAAM,IAAI,MAAM,GAAG,SAAS,CAE3C"}
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ const CONFIG_DIR = join(homedir(), '.agent-cards');
5
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
6
+ export function readConfig() {
7
+ if (!existsSync(CONFIG_FILE))
8
+ return {};
9
+ try {
10
+ return JSON.parse(readFileSync(CONFIG_FILE, 'utf8'));
11
+ }
12
+ catch {
13
+ return {};
14
+ }
15
+ }
16
+ export function writeConfig(data) {
17
+ mkdirSync(CONFIG_DIR, { recursive: true });
18
+ writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });
19
+ }
20
+ export function getApiUrl() {
21
+ const cfg = readConfig();
22
+ return cfg.apiUrl ?? process.env.AGENT_CARDS_API_URL ?? 'http://localhost:3001';
23
+ }
24
+ export function getJwt() {
25
+ return readConfig().jwt ?? process.env.AGENT_CARDS_JWT;
26
+ }
27
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAQpD,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,OAAO,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,uBAAuB,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,UAAU,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AACzD,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function poll<T>(fn: () => Promise<T | null>, opts?: {
2
+ intervalMs?: number;
3
+ timeoutMs?: number;
4
+ }): Promise<T>;
5
+ //# sourceMappingURL=poll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../../src/lib/poll.ts"],"names":[],"mappings":"AAAA,wBAAsB,IAAI,CAAC,CAAC,EAC1B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAC3B,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,OAAO,CAAC,CAAC,CAAC,CAWZ"}
@@ -0,0 +1,12 @@
1
+ export async function poll(fn, opts = {}) {
2
+ const { intervalMs = 2000, timeoutMs = 300_000 } = opts;
3
+ const deadline = Date.now() + timeoutMs;
4
+ while (Date.now() < deadline) {
5
+ const result = await fn();
6
+ if (result !== null)
7
+ return result;
8
+ await new Promise((r) => setTimeout(r, intervalMs));
9
+ }
10
+ throw new Error('Timed out waiting for response');
11
+ }
12
+ //# sourceMappingURL=poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../../src/lib/poll.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,EAA2B,EAC3B,OAAoD,EAAE;IAEtD,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QACnC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACpD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "agent-cards",
3
+ "version": "0.1.0",
4
+ "description": "Prepaid virtual Visa cards for AI agents and developers",
5
+ "type": "module",
6
+ "bin": {
7
+ "agent-cards": "./dist/bin/agent-cards.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18"
14
+ },
15
+ "scripts": {
16
+ "dev": "tsx bin/agent-cards.ts",
17
+ "build": "tsc && chmod +x dist/bin/agent-cards.js",
18
+ "prepublishOnly": "pnpm build"
19
+ },
20
+ "dependencies": {
21
+ "chalk": "^5.3.0",
22
+ "cli-table3": "^0.6.3",
23
+ "commander": "^12.0.0",
24
+ "inquirer": "^9.2.15",
25
+ "open": "^10.1.0",
26
+ "ora": "^8.0.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/inquirer": "^9.0.7",
30
+ "@types/node": "^22.0.0",
31
+ "tsx": "^4.7.1",
32
+ "typescript": "^5.4.2"
33
+ }
34
+ }