beam-protocol-cli 0.2.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.
@@ -0,0 +1,9 @@
1
+ interface InitOptions {
2
+ agent: string;
3
+ org: string;
4
+ force?: boolean;
5
+ directory?: string;
6
+ }
7
+ export declare function cmdInit(options: InitOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CjE"}
@@ -0,0 +1,45 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { BeamIdentity } from 'beam-protocol-sdk';
4
+ import { configExists, saveConfig, DEFAULT_DIRECTORY_URL } from '../config.js';
5
+ export async function cmdInit(options) {
6
+ const { agent, org, force, directory = DEFAULT_DIRECTORY_URL } = options;
7
+ // Validate inputs
8
+ if (!/^[a-z0-9_-]+$/.test(agent)) {
9
+ console.error(chalk.red('✖ Agent name must match [a-z0-9_-]'));
10
+ process.exit(1);
11
+ }
12
+ if (!/^[a-z0-9_-]+$/.test(org)) {
13
+ console.error(chalk.red('✖ Org name must match [a-z0-9_-]'));
14
+ process.exit(1);
15
+ }
16
+ if (configExists() && !force) {
17
+ console.error(chalk.yellow('⚠ Identity already exists at .beam/identity.json'));
18
+ console.error(chalk.dim(' Use --force to overwrite'));
19
+ process.exit(1);
20
+ }
21
+ const spinner = ora('Generating Ed25519 keypair...').start();
22
+ const identity = BeamIdentity.generate({ agentName: agent, orgName: org });
23
+ const identityData = identity.export();
24
+ saveConfig({
25
+ identity: identityData,
26
+ directoryUrl: directory,
27
+ createdAt: new Date().toISOString()
28
+ });
29
+ spinner.succeed('Identity generated');
30
+ console.log('');
31
+ console.log(chalk.bold('🔑 Beam Identity Created'));
32
+ console.log(chalk.dim('─'.repeat(40)));
33
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(identityData.beamId)}`);
34
+ console.log(`${chalk.cyan('Directory:')} ${directory}`);
35
+ console.log(`${chalk.cyan('Config:')} ${process.cwd()}/.beam/identity.json`);
36
+ console.log('');
37
+ console.log(chalk.dim('Public key (SPKI/DER/base64):'));
38
+ console.log(chalk.dim(identityData.publicKeyBase64.substring(0, 64) + '...'));
39
+ console.log('');
40
+ console.log(chalk.yellow('⚠ Keep .beam/identity.json secret — it contains your private key!'));
41
+ console.log(chalk.dim(' Add .beam/ to your .gitignore'));
42
+ console.log('');
43
+ console.log(chalk.green('Next step:'), `beam register --display-name "My Agent" --capabilities "query,answer"`);
44
+ }
45
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface LookupOptions {
2
+ directory?: string;
3
+ json?: boolean;
4
+ }
5
+ export declare function cmdLookup(beamId: string, options: LookupOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=lookup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/commands/lookup.ts"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDrF"}
@@ -0,0 +1,58 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { BeamDirectory } from 'beam-protocol-sdk';
4
+ import { loadConfig } from '../config.js';
5
+ export async function cmdLookup(beamId, options) {
6
+ const config = loadConfig();
7
+ const directoryUrl = options.directory ?? config.directoryUrl;
8
+ // Validate beam ID format
9
+ if (!beamId.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
10
+ console.error(chalk.red(`✖ Invalid Beam ID format: ${beamId}`));
11
+ console.error(chalk.dim(' Expected: agent@org.beam.directory'));
12
+ process.exit(1);
13
+ }
14
+ const spinner = ora(`Looking up ${chalk.bold(beamId)}...`).start();
15
+ try {
16
+ const directory = new BeamDirectory({ baseUrl: directoryUrl });
17
+ const record = await directory.lookup(beamId);
18
+ if (!record) {
19
+ spinner.fail(`Agent not found: ${beamId}`);
20
+ process.exit(1);
21
+ }
22
+ spinner.stop();
23
+ if (options.json) {
24
+ console.log(JSON.stringify(record, null, 2));
25
+ return;
26
+ }
27
+ const trustBar = getTrustBar(record.trustScore);
28
+ console.log('');
29
+ console.log(chalk.bold(`🤖 ${record.displayName}`));
30
+ console.log(chalk.dim('─'.repeat(40)));
31
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`);
32
+ console.log(`${chalk.cyan('Org:')} ${record.org}`);
33
+ console.log(`${chalk.cyan('Trust Score:')} ${trustBar} ${(record.trustScore * 100).toFixed(0)}%`);
34
+ console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('✓ Verified') : chalk.yellow('Unverified')}`);
35
+ if (record.capabilities.length > 0) {
36
+ console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.map(c => chalk.blue(c)).join(', ')}`);
37
+ }
38
+ console.log(`${chalk.cyan('Last Seen:')} ${new Date(record.lastSeen).toLocaleString()}`);
39
+ console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`);
40
+ console.log('');
41
+ }
42
+ catch (err) {
43
+ spinner.fail('Lookup failed');
44
+ console.error(chalk.red(`✖ ${err.message}`));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ function getTrustBar(score) {
49
+ const filled = Math.round(score * 10);
50
+ const empty = 10 - filled;
51
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
52
+ if (score >= 0.8)
53
+ return chalk.green(bar);
54
+ if (score >= 0.5)
55
+ return chalk.yellow(bar);
56
+ return chalk.red(bar);
57
+ }
58
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/commands/lookup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ interface RegisterOptions {
2
+ displayName?: string;
3
+ capabilities?: string;
4
+ directory?: string;
5
+ }
6
+ export declare function cmdRegister(options: RegisterOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAKA,UAAU,eAAe;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CzE"}
@@ -0,0 +1,46 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { BeamClient, BeamIdentity } from 'beam-protocol-sdk';
4
+ import { loadConfig } from '../config.js';
5
+ export async function cmdRegister(options) {
6
+ const config = loadConfig();
7
+ const directoryUrl = options.directory ?? config.directoryUrl;
8
+ const parsed = BeamIdentity.parseBeamId(config.identity.beamId);
9
+ if (!parsed) {
10
+ console.error(chalk.red('✖ Invalid Beam ID in config'));
11
+ process.exit(1);
12
+ }
13
+ const displayName = options.displayName ?? parsed.agent;
14
+ const capabilities = options.capabilities
15
+ ? options.capabilities.split(',').map(c => c.trim()).filter(Boolean)
16
+ : [];
17
+ const spinner = ora(`Registering ${chalk.bold(config.identity.beamId)}...`).start();
18
+ try {
19
+ const client = new BeamClient({
20
+ identity: config.identity,
21
+ directoryUrl
22
+ });
23
+ const record = await client.register(displayName, capabilities);
24
+ spinner.succeed('Agent registered successfully');
25
+ console.log('');
26
+ console.log(chalk.bold('✅ Registration Complete'));
27
+ console.log(chalk.dim('─'.repeat(40)));
28
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`);
29
+ console.log(`${chalk.cyan('Display:')} ${record.displayName}`);
30
+ console.log(`${chalk.cyan('Org:')} ${record.org}`);
31
+ console.log(`${chalk.cyan('Trust Score:')} ${(record.trustScore * 100).toFixed(0)}%`);
32
+ console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('Yes ✓') : chalk.yellow('No')}`);
33
+ if (record.capabilities.length > 0) {
34
+ console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.join(', ')}`);
35
+ }
36
+ console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`);
37
+ console.log('');
38
+ console.log(chalk.green('Next step:'), `beam lookup ${record.beamId}`);
39
+ }
40
+ catch (err) {
41
+ spinner.fail('Registration failed');
42
+ console.error(chalk.red(`✖ ${err.message}`));
43
+ process.exit(1);
44
+ }
45
+ }
46
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ interface SearchOptions {
2
+ org?: string;
3
+ capability?: string;
4
+ minTrust?: string;
5
+ limit?: string;
6
+ directory?: string;
7
+ json?: boolean;
8
+ }
9
+ export declare function cmdSearch(options: SearchOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DrE"}
@@ -0,0 +1,73 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { BeamDirectory } from 'beam-protocol-sdk';
4
+ import { loadConfig } from '../config.js';
5
+ export async function cmdSearch(options) {
6
+ const config = loadConfig();
7
+ const directoryUrl = options.directory ?? config.directoryUrl;
8
+ const query = {
9
+ org: options.org,
10
+ capabilities: options.capability ? [options.capability] : undefined,
11
+ minTrustScore: options.minTrust ? parseFloat(options.minTrust) : undefined,
12
+ limit: options.limit ? parseInt(options.limit, 10) : 20
13
+ };
14
+ const parts = [];
15
+ if (query.org)
16
+ parts.push(`org=${query.org}`);
17
+ if (query.capabilities)
18
+ parts.push(`capability=${query.capabilities[0]}`);
19
+ const label = parts.length ? parts.join(', ') : 'all agents';
20
+ const spinner = ora(`Searching ${label}...`).start();
21
+ try {
22
+ const directory = new BeamDirectory({ baseUrl: directoryUrl });
23
+ const agents = await directory.search(query);
24
+ spinner.stop();
25
+ if (options.json) {
26
+ console.log(JSON.stringify(agents, null, 2));
27
+ return;
28
+ }
29
+ if (agents.length === 0) {
30
+ console.log(chalk.yellow(`\n No agents found matching your query.\n`));
31
+ return;
32
+ }
33
+ console.log('');
34
+ console.log(chalk.bold(`🔍 Found ${agents.length} agent${agents.length !== 1 ? 's' : ''}`));
35
+ console.log(chalk.dim('─'.repeat(60)));
36
+ for (const agent of agents) {
37
+ const trustPct = (agent.trustScore * 100).toFixed(0);
38
+ const verified = agent.verified ? chalk.green('✓') : chalk.dim('○');
39
+ const caps = agent.capabilities.length > 0
40
+ ? chalk.dim(` [${agent.capabilities.join(', ')}]`)
41
+ : '';
42
+ console.log(` ${verified} ${chalk.bold(agent.beamId)}${caps}`);
43
+ console.log(` ${chalk.dim(agent.displayName)} · Trust: ${getTrustColored(agent.trustScore, trustPct + '%')} · Last seen: ${formatRelative(agent.lastSeen)}`);
44
+ console.log('');
45
+ }
46
+ }
47
+ catch (err) {
48
+ spinner.fail('Search failed');
49
+ console.error(chalk.red(`✖ ${err.message}`));
50
+ process.exit(1);
51
+ }
52
+ }
53
+ function getTrustColored(score, label) {
54
+ if (score >= 0.8)
55
+ return chalk.green(label);
56
+ if (score >= 0.5)
57
+ return chalk.yellow(label);
58
+ return chalk.red(label);
59
+ }
60
+ function formatRelative(iso) {
61
+ const ms = Date.now() - new Date(iso).getTime();
62
+ const minutes = Math.floor(ms / 60000);
63
+ if (minutes < 1)
64
+ return chalk.dim('just now');
65
+ if (minutes < 60)
66
+ return chalk.dim(`${minutes}m ago`);
67
+ const hours = Math.floor(minutes / 60);
68
+ if (hours < 24)
69
+ return chalk.dim(`${hours}h ago`);
70
+ const days = Math.floor(hours / 24);
71
+ return chalk.dim(`${days}d ago`);
72
+ }
73
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAWzC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAsB;IACpD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAA;IAE7D,MAAM,KAAK,GAAG;QACZ,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,YAAY,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;QACnE,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;QAC1E,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;KACxD,CAAA;IAED,MAAM,KAAK,GAAG,EAAE,CAAA;IAChB,IAAI,KAAK,CAAC,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,CAAA;IAC7C,IAAI,KAAK,CAAC,YAAY;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IACzE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAA;IAE5D,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAEpD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;QAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAE5C,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAA;YACvE,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC3F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAEtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YACpD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACnE,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;gBACxC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClD,CAAC,CAAC,EAAE,CAAA;YAEN,OAAO,CAAC,GAAG,CACT,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CACnD,CAAA;YACD,OAAO,CAAC,GAAG,CACT,QAAQ,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,eAAe,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,GAAG,CAAC,iBAAiB,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CACpJ,CAAA;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAC7B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,KAAa;IACnD,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3C,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAA;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAA;IACtC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,OAAO,CAAC,CAAA;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAA;IACtC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC,CAAA;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;IACnC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,CAAA;AAClC,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface SendOptions {
2
+ directory?: string;
3
+ timeout?: string;
4
+ json?: boolean;
5
+ }
6
+ export declare function cmdSend(to: string, intent: string, paramsJson: string | undefined, options: SendOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAMA,UAAU,WAAW;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,OAAO,CAC3B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Ef"}
@@ -0,0 +1,78 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { BeamClient } from 'beam-protocol-sdk';
4
+ import { loadConfig } from '../config.js';
5
+ export async function cmdSend(to, intent, paramsJson, options) {
6
+ const config = loadConfig();
7
+ const directoryUrl = options.directory ?? config.directoryUrl;
8
+ const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1000 : 10000;
9
+ // Validate beam ID format
10
+ if (!to.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
11
+ console.error(chalk.red(`✖ Invalid Beam ID: ${to}`));
12
+ console.error(chalk.dim(' Expected: agent@org.beam.directory'));
13
+ process.exit(1);
14
+ }
15
+ // Parse params
16
+ let params = {};
17
+ if (paramsJson) {
18
+ try {
19
+ const parsed = JSON.parse(paramsJson);
20
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
21
+ params = parsed;
22
+ }
23
+ else {
24
+ throw new Error('Params must be a JSON object');
25
+ }
26
+ }
27
+ catch (err) {
28
+ console.error(chalk.red(`✖ Invalid params JSON: ${err.message}`));
29
+ process.exit(1);
30
+ }
31
+ }
32
+ const spinner = ora(`Sending ${chalk.bold(intent)} to ${chalk.bold(to)}...`).start();
33
+ const startTime = Date.now();
34
+ try {
35
+ const client = new BeamClient({
36
+ identity: config.identity,
37
+ directoryUrl
38
+ });
39
+ const result = await client.send(to, intent, params, timeoutMs);
40
+ const elapsed = Date.now() - startTime;
41
+ spinner.stop();
42
+ if (options.json) {
43
+ console.log(JSON.stringify(result, null, 2));
44
+ return;
45
+ }
46
+ if (result.success) {
47
+ console.log('');
48
+ console.log(chalk.bold.green('✅ Intent delivered successfully'));
49
+ console.log(chalk.dim('─'.repeat(40)));
50
+ console.log(`${chalk.cyan('From:')} ${config.identity.beamId}`);
51
+ console.log(`${chalk.cyan('To:')} ${to}`);
52
+ console.log(`${chalk.cyan('Intent:')} ${intent}`);
53
+ console.log(`${chalk.cyan('Latency:')} ${elapsed}ms`);
54
+ if (result.payload && Object.keys(result.payload).length > 0) {
55
+ console.log('');
56
+ console.log(chalk.bold('📦 Result Payload:'));
57
+ console.log(JSON.stringify(result.payload, null, 2));
58
+ }
59
+ }
60
+ else {
61
+ console.log('');
62
+ console.log(chalk.bold.red('✖ Intent failed'));
63
+ console.log(chalk.dim('─'.repeat(40)));
64
+ console.log(`${chalk.cyan('Error:')} ${result.error ?? 'Unknown error'}`);
65
+ if (result.errorCode) {
66
+ console.log(`${chalk.cyan('Code:')} ${result.errorCode}`);
67
+ }
68
+ console.log(`${chalk.cyan('Latency:')} ${elapsed}ms`);
69
+ }
70
+ console.log('');
71
+ }
72
+ catch (err) {
73
+ spinner.fail('Send failed');
74
+ console.error(chalk.red(`✖ ${err.message}`));
75
+ process.exit(1);
76
+ }
77
+ }
78
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { BeamIdentityData } from 'beam-protocol-sdk';
2
+ export interface BeamConfig {
3
+ identity: BeamIdentityData;
4
+ directoryUrl: string;
5
+ createdAt: string;
6
+ }
7
+ export declare function getConfigDir(cwd?: string): string;
8
+ export declare function getConfigPath(cwd?: string): string;
9
+ export declare function configExists(cwd?: string): boolean;
10
+ export declare function loadConfig(cwd?: string): BeamConfig;
11
+ export declare function saveConfig(config: BeamConfig, cwd?: string): void;
12
+ export declare const DEFAULT_DIRECTORY_URL: string;
13
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,YAAY,CAAC,GAAG,SAAgB,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,GAAG,SAAgB,GAAG,MAAM,CAEzD;AAED,wBAAgB,YAAY,CAAC,GAAG,SAAgB,GAAG,OAAO,CAEzD;AAED,wBAAgB,UAAU,CAAC,GAAG,SAAgB,GAAG,UAAU,CAS1D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,SAAgB,GAAG,IAAI,CAIxE;AAED,eAAO,MAAM,qBAAqB,QAAoE,CAAA"}
package/dist/config.js ADDED
@@ -0,0 +1,26 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export function getConfigDir(cwd = process.cwd()) {
4
+ return join(cwd, '.beam');
5
+ }
6
+ export function getConfigPath(cwd = process.cwd()) {
7
+ return join(getConfigDir(cwd), 'identity.json');
8
+ }
9
+ export function configExists(cwd = process.cwd()) {
10
+ return existsSync(getConfigPath(cwd));
11
+ }
12
+ export function loadConfig(cwd = process.cwd()) {
13
+ const path = getConfigPath(cwd);
14
+ if (!existsSync(path)) {
15
+ throw new Error(`No Beam identity found. Run 'beam init' first.`);
16
+ }
17
+ const raw = readFileSync(path, 'utf8');
18
+ return JSON.parse(raw);
19
+ }
20
+ export function saveConfig(config, cwd = process.cwd()) {
21
+ const dir = getConfigDir(cwd);
22
+ mkdirSync(dir, { recursive: true });
23
+ writeFileSync(getConfigPath(cwd), JSON.stringify(config, null, 2), 'utf8');
24
+ }
25
+ export const DEFAULT_DIRECTORY_URL = process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory';
26
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAShC,MAAM,UAAU,YAAY,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC9C,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC/C,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC9C,OAAO,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,gDAAgD,CACjD,CAAA;IACH,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAkB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAChE,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC7B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnC,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,4BAA4B,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { cmdInit } from './commands/init.js';
5
+ import { cmdRegister } from './commands/register.js';
6
+ import { cmdLookup } from './commands/lookup.js';
7
+ import { cmdSearch } from './commands/search.js';
8
+ import { cmdSend } from './commands/send.js';
9
+ const program = new Command();
10
+ program
11
+ .name('beam')
12
+ .description(chalk.bold('Beam Protocol CLI') + '\n' +
13
+ chalk.dim('SMTP for AI Agents — agent identity, registration & intent routing'))
14
+ .version('0.1.0');
15
+ // ─── beam init ────────────────────────────────────────────────────────────────
16
+ program
17
+ .command('init')
18
+ .description('Generate a new Beam identity (writes .beam/identity.json)')
19
+ .requiredOption('-a, --agent <name>', 'Agent name (e.g. jarvis)')
20
+ .requiredOption('-o, --org <name>', 'Organisation name (e.g. coppen)')
21
+ .option('-d, --directory <url>', 'Directory server URL', process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory')
22
+ .option('-f, --force', 'Overwrite existing identity')
23
+ .action(async (opts) => {
24
+ await cmdInit(opts);
25
+ });
26
+ // ─── beam register ────────────────────────────────────────────────────────────
27
+ program
28
+ .command('register')
29
+ .description('Register this agent with a Beam directory')
30
+ .option('-n, --display-name <name>', 'Human-readable display name')
31
+ .option('-c, --capabilities <list>', 'Comma-separated capabilities (e.g. query,answer,write)')
32
+ .option('-d, --directory <url>', 'Override directory URL')
33
+ .action(async (opts) => {
34
+ await cmdRegister(opts);
35
+ });
36
+ // ─── beam lookup ──────────────────────────────────────────────────────────────
37
+ program
38
+ .command('lookup <beamId>')
39
+ .description('Look up an agent by Beam ID')
40
+ .option('-d, --directory <url>', 'Override directory URL')
41
+ .option('--json', 'Output raw JSON')
42
+ .action(async (beamId, opts) => {
43
+ await cmdLookup(beamId, opts);
44
+ });
45
+ // ─── beam search ──────────────────────────────────────────────────────────────
46
+ program
47
+ .command('search')
48
+ .description('Search for agents in the directory')
49
+ .option('--org <org>', 'Filter by organisation')
50
+ .option('--capability <cap>', 'Filter by capability')
51
+ .option('--min-trust <score>', 'Minimum trust score (0.0-1.0)')
52
+ .option('--limit <n>', 'Max results', '20')
53
+ .option('-d, --directory <url>', 'Override directory URL')
54
+ .option('--json', 'Output raw JSON')
55
+ .action(async (opts) => {
56
+ await cmdSearch(opts);
57
+ });
58
+ // ─── beam send ────────────────────────────────────────────────────────────────
59
+ program
60
+ .command('send <to> <intent> [params]')
61
+ .description('Send an intent to an agent and print the result')
62
+ .option('-d, --directory <url>', 'Override directory URL')
63
+ .option('-t, --timeout <seconds>', 'Timeout in seconds', '10')
64
+ .option('--json', 'Output raw JSON')
65
+ .action(async (to, intent, params, opts) => {
66
+ await cmdSend(to, intent, params, opts);
67
+ });
68
+ // ─── Error handling ───────────────────────────────────────────────────────────
69
+ program.configureOutput({
70
+ writeErr: str => process.stderr.write(chalk.red(str))
71
+ });
72
+ program.parse();
73
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "beam-protocol-cli",
3
+ "version": "0.2.0",
4
+ "description": "Beam Protocol CLI \u2014 manage Beam identities, register agents, send intents",
5
+ "type": "module",
6
+ "bin": {
7
+ "beam": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "node --watch dist/index.js",
13
+ "typecheck": "tsc --noEmit",
14
+ "start": "node dist/index.js"
15
+ },
16
+ "dependencies": {
17
+ "@beam-protocol/sdk": "*",
18
+ "beam-protocol-sdk": "^0.2.2",
19
+ "chalk": "^5.3.0",
20
+ "commander": "^12.0.0",
21
+ "inquirer": "^9.2.15",
22
+ "ora": "^8.0.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^20.11.0",
26
+ "typescript": "^5.3.3"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "license": "Apache-2.0",
32
+ "keywords": [
33
+ "beam-protocol",
34
+ "a2a",
35
+ "ai-agents",
36
+ "cli"
37
+ ]
38
+ }
@@ -0,0 +1,59 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { BeamIdentity } from 'beam-protocol-sdk'
4
+ import { configExists, saveConfig, DEFAULT_DIRECTORY_URL } from '../config.js'
5
+
6
+ interface InitOptions {
7
+ agent: string
8
+ org: string
9
+ force?: boolean
10
+ directory?: string
11
+ }
12
+
13
+ export async function cmdInit(options: InitOptions): Promise<void> {
14
+ const { agent, org, force, directory = DEFAULT_DIRECTORY_URL } = options
15
+
16
+ // Validate inputs
17
+ if (!/^[a-z0-9_-]+$/.test(agent)) {
18
+ console.error(chalk.red('✖ Agent name must match [a-z0-9_-]'))
19
+ process.exit(1)
20
+ }
21
+ if (!/^[a-z0-9_-]+$/.test(org)) {
22
+ console.error(chalk.red('✖ Org name must match [a-z0-9_-]'))
23
+ process.exit(1)
24
+ }
25
+
26
+ if (configExists() && !force) {
27
+ console.error(chalk.yellow('⚠ Identity already exists at .beam/identity.json'))
28
+ console.error(chalk.dim(' Use --force to overwrite'))
29
+ process.exit(1)
30
+ }
31
+
32
+ const spinner = ora('Generating Ed25519 keypair...').start()
33
+
34
+ const identity = BeamIdentity.generate({ agentName: agent, orgName: org })
35
+ const identityData = identity.export()
36
+
37
+ saveConfig({
38
+ identity: identityData,
39
+ directoryUrl: directory,
40
+ createdAt: new Date().toISOString()
41
+ })
42
+
43
+ spinner.succeed('Identity generated')
44
+
45
+ console.log('')
46
+ console.log(chalk.bold('🔑 Beam Identity Created'))
47
+ console.log(chalk.dim('─'.repeat(40)))
48
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(identityData.beamId)}`)
49
+ console.log(`${chalk.cyan('Directory:')} ${directory}`)
50
+ console.log(`${chalk.cyan('Config:')} ${process.cwd()}/.beam/identity.json`)
51
+ console.log('')
52
+ console.log(chalk.dim('Public key (SPKI/DER/base64):'))
53
+ console.log(chalk.dim(identityData.publicKeyBase64.substring(0, 64) + '...'))
54
+ console.log('')
55
+ console.log(chalk.yellow('⚠ Keep .beam/identity.json secret — it contains your private key!'))
56
+ console.log(chalk.dim(' Add .beam/ to your .gitignore'))
57
+ console.log('')
58
+ console.log(chalk.green('Next step:'), `beam register --display-name "My Agent" --capabilities "query,answer"`)
59
+ }
@@ -0,0 +1,70 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { BeamDirectory } from 'beam-protocol-sdk'
4
+ import type { BeamIdString } from 'beam-protocol-sdk'
5
+ import { loadConfig } from '../config.js'
6
+
7
+ interface LookupOptions {
8
+ directory?: string
9
+ json?: boolean
10
+ }
11
+
12
+ export async function cmdLookup(beamId: string, options: LookupOptions): Promise<void> {
13
+ const config = loadConfig()
14
+ const directoryUrl = options.directory ?? config.directoryUrl
15
+
16
+ // Validate beam ID format
17
+ if (!beamId.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
18
+ console.error(chalk.red(`✖ Invalid Beam ID format: ${beamId}`))
19
+ console.error(chalk.dim(' Expected: agent@org.beam.directory'))
20
+ process.exit(1)
21
+ }
22
+
23
+ const spinner = ora(`Looking up ${chalk.bold(beamId)}...`).start()
24
+
25
+ try {
26
+ const directory = new BeamDirectory({ baseUrl: directoryUrl })
27
+ const record = await directory.lookup(beamId as BeamIdString)
28
+
29
+ if (!record) {
30
+ spinner.fail(`Agent not found: ${beamId}`)
31
+ process.exit(1)
32
+ }
33
+
34
+ spinner.stop()
35
+
36
+ if (options.json) {
37
+ console.log(JSON.stringify(record, null, 2))
38
+ return
39
+ }
40
+
41
+ const trustBar = getTrustBar(record.trustScore)
42
+
43
+ console.log('')
44
+ console.log(chalk.bold(`🤖 ${record.displayName}`))
45
+ console.log(chalk.dim('─'.repeat(40)))
46
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`)
47
+ console.log(`${chalk.cyan('Org:')} ${record.org}`)
48
+ console.log(`${chalk.cyan('Trust Score:')} ${trustBar} ${(record.trustScore * 100).toFixed(0)}%`)
49
+ console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('✓ Verified') : chalk.yellow('Unverified')}`)
50
+ if (record.capabilities.length > 0) {
51
+ console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.map(c => chalk.blue(c)).join(', ')}`)
52
+ }
53
+ console.log(`${chalk.cyan('Last Seen:')} ${new Date(record.lastSeen).toLocaleString()}`)
54
+ console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`)
55
+ console.log('')
56
+ } catch (err) {
57
+ spinner.fail('Lookup failed')
58
+ console.error(chalk.red(`✖ ${(err as Error).message}`))
59
+ process.exit(1)
60
+ }
61
+ }
62
+
63
+ function getTrustBar(score: number): string {
64
+ const filled = Math.round(score * 10)
65
+ const empty = 10 - filled
66
+ const bar = '█'.repeat(filled) + '░'.repeat(empty)
67
+ if (score >= 0.8) return chalk.green(bar)
68
+ if (score >= 0.5) return chalk.yellow(bar)
69
+ return chalk.red(bar)
70
+ }
@@ -0,0 +1,58 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { BeamClient, BeamIdentity } from 'beam-protocol-sdk'
4
+ import { loadConfig } from '../config.js'
5
+
6
+ interface RegisterOptions {
7
+ displayName?: string
8
+ capabilities?: string
9
+ directory?: string
10
+ }
11
+
12
+ export async function cmdRegister(options: RegisterOptions): Promise<void> {
13
+ const config = loadConfig()
14
+ const directoryUrl = options.directory ?? config.directoryUrl
15
+
16
+ const parsed = BeamIdentity.parseBeamId(config.identity.beamId)
17
+ if (!parsed) {
18
+ console.error(chalk.red('✖ Invalid Beam ID in config'))
19
+ process.exit(1)
20
+ }
21
+
22
+ const displayName = options.displayName ?? parsed.agent
23
+ const capabilities = options.capabilities
24
+ ? options.capabilities.split(',').map(c => c.trim()).filter(Boolean)
25
+ : []
26
+
27
+ const spinner = ora(`Registering ${chalk.bold(config.identity.beamId)}...`).start()
28
+
29
+ try {
30
+ const client = new BeamClient({
31
+ identity: config.identity,
32
+ directoryUrl
33
+ })
34
+
35
+ const record = await client.register(displayName, capabilities)
36
+
37
+ spinner.succeed('Agent registered successfully')
38
+
39
+ console.log('')
40
+ console.log(chalk.bold('✅ Registration Complete'))
41
+ console.log(chalk.dim('─'.repeat(40)))
42
+ console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`)
43
+ console.log(`${chalk.cyan('Display:')} ${record.displayName}`)
44
+ console.log(`${chalk.cyan('Org:')} ${record.org}`)
45
+ console.log(`${chalk.cyan('Trust Score:')} ${(record.trustScore * 100).toFixed(0)}%`)
46
+ console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('Yes ✓') : chalk.yellow('No')}`)
47
+ if (record.capabilities.length > 0) {
48
+ console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.join(', ')}`)
49
+ }
50
+ console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`)
51
+ console.log('')
52
+ console.log(chalk.green('Next step:'), `beam lookup ${record.beamId}`)
53
+ } catch (err) {
54
+ spinner.fail('Registration failed')
55
+ console.error(chalk.red(`✖ ${(err as Error).message}`))
56
+ process.exit(1)
57
+ }
58
+ }
@@ -0,0 +1,90 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { BeamDirectory } from 'beam-protocol-sdk'
4
+ import { loadConfig } from '../config.js'
5
+
6
+ interface SearchOptions {
7
+ org?: string
8
+ capability?: string
9
+ minTrust?: string
10
+ limit?: string
11
+ directory?: string
12
+ json?: boolean
13
+ }
14
+
15
+ export async function cmdSearch(options: SearchOptions): Promise<void> {
16
+ const config = loadConfig()
17
+ const directoryUrl = options.directory ?? config.directoryUrl
18
+
19
+ const query = {
20
+ org: options.org,
21
+ capabilities: options.capability ? [options.capability] : undefined,
22
+ minTrustScore: options.minTrust ? parseFloat(options.minTrust) : undefined,
23
+ limit: options.limit ? parseInt(options.limit, 10) : 20
24
+ }
25
+
26
+ const parts = []
27
+ if (query.org) parts.push(`org=${query.org}`)
28
+ if (query.capabilities) parts.push(`capability=${query.capabilities[0]}`)
29
+ const label = parts.length ? parts.join(', ') : 'all agents'
30
+
31
+ const spinner = ora(`Searching ${label}...`).start()
32
+
33
+ try {
34
+ const directory = new BeamDirectory({ baseUrl: directoryUrl })
35
+ const agents = await directory.search(query)
36
+
37
+ spinner.stop()
38
+
39
+ if (options.json) {
40
+ console.log(JSON.stringify(agents, null, 2))
41
+ return
42
+ }
43
+
44
+ if (agents.length === 0) {
45
+ console.log(chalk.yellow(`\n No agents found matching your query.\n`))
46
+ return
47
+ }
48
+
49
+ console.log('')
50
+ console.log(chalk.bold(`🔍 Found ${agents.length} agent${agents.length !== 1 ? 's' : ''}`))
51
+ console.log(chalk.dim('─'.repeat(60)))
52
+
53
+ for (const agent of agents) {
54
+ const trustPct = (agent.trustScore * 100).toFixed(0)
55
+ const verified = agent.verified ? chalk.green('✓') : chalk.dim('○')
56
+ const caps = agent.capabilities.length > 0
57
+ ? chalk.dim(` [${agent.capabilities.join(', ')}]`)
58
+ : ''
59
+
60
+ console.log(
61
+ ` ${verified} ${chalk.bold(agent.beamId)}${caps}`
62
+ )
63
+ console.log(
64
+ ` ${chalk.dim(agent.displayName)} · Trust: ${getTrustColored(agent.trustScore, trustPct + '%')} · Last seen: ${formatRelative(agent.lastSeen)}`
65
+ )
66
+ console.log('')
67
+ }
68
+ } catch (err) {
69
+ spinner.fail('Search failed')
70
+ console.error(chalk.red(`✖ ${(err as Error).message}`))
71
+ process.exit(1)
72
+ }
73
+ }
74
+
75
+ function getTrustColored(score: number, label: string): string {
76
+ if (score >= 0.8) return chalk.green(label)
77
+ if (score >= 0.5) return chalk.yellow(label)
78
+ return chalk.red(label)
79
+ }
80
+
81
+ function formatRelative(iso: string): string {
82
+ const ms = Date.now() - new Date(iso).getTime()
83
+ const minutes = Math.floor(ms / 60000)
84
+ if (minutes < 1) return chalk.dim('just now')
85
+ if (minutes < 60) return chalk.dim(`${minutes}m ago`)
86
+ const hours = Math.floor(minutes / 60)
87
+ if (hours < 24) return chalk.dim(`${hours}h ago`)
88
+ const days = Math.floor(hours / 24)
89
+ return chalk.dim(`${days}d ago`)
90
+ }
@@ -0,0 +1,97 @@
1
+ import chalk from 'chalk'
2
+ import ora from 'ora'
3
+ import { BeamClient } from 'beam-protocol-sdk'
4
+ import type { BeamIdString } from 'beam-protocol-sdk'
5
+ import { loadConfig } from '../config.js'
6
+
7
+ interface SendOptions {
8
+ directory?: string
9
+ timeout?: string
10
+ json?: boolean
11
+ }
12
+
13
+ export async function cmdSend(
14
+ to: string,
15
+ intent: string,
16
+ paramsJson: string | undefined,
17
+ options: SendOptions
18
+ ): Promise<void> {
19
+ const config = loadConfig()
20
+ const directoryUrl = options.directory ?? config.directoryUrl
21
+ const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1000 : 10000
22
+
23
+ // Validate beam ID format
24
+ if (!to.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
25
+ console.error(chalk.red(`✖ Invalid Beam ID: ${to}`))
26
+ console.error(chalk.dim(' Expected: agent@org.beam.directory'))
27
+ process.exit(1)
28
+ }
29
+
30
+ // Parse params
31
+ let params: Record<string, unknown> = {}
32
+ if (paramsJson) {
33
+ try {
34
+ const parsed: unknown = JSON.parse(paramsJson)
35
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
36
+ params = parsed as Record<string, unknown>
37
+ } else {
38
+ throw new Error('Params must be a JSON object')
39
+ }
40
+ } catch (err) {
41
+ console.error(chalk.red(`✖ Invalid params JSON: ${(err as Error).message}`))
42
+ process.exit(1)
43
+ }
44
+ }
45
+
46
+ const spinner = ora(
47
+ `Sending ${chalk.bold(intent)} to ${chalk.bold(to)}...`
48
+ ).start()
49
+
50
+ const startTime = Date.now()
51
+
52
+ try {
53
+ const client = new BeamClient({
54
+ identity: config.identity,
55
+ directoryUrl
56
+ })
57
+
58
+ const result = await client.send(to as BeamIdString, intent, params, timeoutMs)
59
+ const elapsed = Date.now() - startTime
60
+
61
+ spinner.stop()
62
+
63
+ if (options.json) {
64
+ console.log(JSON.stringify(result, null, 2))
65
+ return
66
+ }
67
+
68
+ if (result.success) {
69
+ console.log('')
70
+ console.log(chalk.bold.green('✅ Intent delivered successfully'))
71
+ console.log(chalk.dim('─'.repeat(40)))
72
+ console.log(`${chalk.cyan('From:')} ${config.identity.beamId}`)
73
+ console.log(`${chalk.cyan('To:')} ${to}`)
74
+ console.log(`${chalk.cyan('Intent:')} ${intent}`)
75
+ console.log(`${chalk.cyan('Latency:')} ${elapsed}ms`)
76
+ if (result.payload && Object.keys(result.payload).length > 0) {
77
+ console.log('')
78
+ console.log(chalk.bold('📦 Result Payload:'))
79
+ console.log(JSON.stringify(result.payload, null, 2))
80
+ }
81
+ } else {
82
+ console.log('')
83
+ console.log(chalk.bold.red('✖ Intent failed'))
84
+ console.log(chalk.dim('─'.repeat(40)))
85
+ console.log(`${chalk.cyan('Error:')} ${result.error ?? 'Unknown error'}`)
86
+ if (result.errorCode) {
87
+ console.log(`${chalk.cyan('Code:')} ${result.errorCode}`)
88
+ }
89
+ console.log(`${chalk.cyan('Latency:')} ${elapsed}ms`)
90
+ }
91
+ console.log('')
92
+ } catch (err) {
93
+ spinner.fail('Send failed')
94
+ console.error(chalk.red(`✖ ${(err as Error).message}`))
95
+ process.exit(1)
96
+ }
97
+ }
package/src/config.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+ import type { BeamIdentityData } from 'beam-protocol-sdk'
4
+
5
+ export interface BeamConfig {
6
+ identity: BeamIdentityData
7
+ directoryUrl: string
8
+ createdAt: string
9
+ }
10
+
11
+ export function getConfigDir(cwd = process.cwd()): string {
12
+ return join(cwd, '.beam')
13
+ }
14
+
15
+ export function getConfigPath(cwd = process.cwd()): string {
16
+ return join(getConfigDir(cwd), 'identity.json')
17
+ }
18
+
19
+ export function configExists(cwd = process.cwd()): boolean {
20
+ return existsSync(getConfigPath(cwd))
21
+ }
22
+
23
+ export function loadConfig(cwd = process.cwd()): BeamConfig {
24
+ const path = getConfigPath(cwd)
25
+ if (!existsSync(path)) {
26
+ throw new Error(
27
+ `No Beam identity found. Run 'beam init' first.`
28
+ )
29
+ }
30
+ const raw = readFileSync(path, 'utf8')
31
+ return JSON.parse(raw) as BeamConfig
32
+ }
33
+
34
+ export function saveConfig(config: BeamConfig, cwd = process.cwd()): void {
35
+ const dir = getConfigDir(cwd)
36
+ mkdirSync(dir, { recursive: true })
37
+ writeFileSync(getConfigPath(cwd), JSON.stringify(config, null, 2), 'utf8')
38
+ }
39
+
40
+ export const DEFAULT_DIRECTORY_URL = process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory'
package/src/index.ts ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander'
3
+ import chalk from 'chalk'
4
+ import { cmdInit } from './commands/init.js'
5
+ import { cmdRegister } from './commands/register.js'
6
+ import { cmdLookup } from './commands/lookup.js'
7
+ import { cmdSearch } from './commands/search.js'
8
+ import { cmdSend } from './commands/send.js'
9
+
10
+ const program = new Command()
11
+
12
+ program
13
+ .name('beam')
14
+ .description(
15
+ chalk.bold('Beam Protocol CLI') + '\n' +
16
+ chalk.dim('SMTP for AI Agents — agent identity, registration & intent routing')
17
+ )
18
+ .version('0.1.0')
19
+
20
+ // ─── beam init ────────────────────────────────────────────────────────────────
21
+ program
22
+ .command('init')
23
+ .description('Generate a new Beam identity (writes .beam/identity.json)')
24
+ .requiredOption('-a, --agent <name>', 'Agent name (e.g. jarvis)')
25
+ .requiredOption('-o, --org <name>', 'Organisation name (e.g. coppen)')
26
+ .option('-d, --directory <url>', 'Directory server URL', process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory')
27
+ .option('-f, --force', 'Overwrite existing identity')
28
+ .action(async (opts: { agent: string; org: string; directory?: string; force?: boolean }) => {
29
+ await cmdInit(opts)
30
+ })
31
+
32
+ // ─── beam register ────────────────────────────────────────────────────────────
33
+ program
34
+ .command('register')
35
+ .description('Register this agent with a Beam directory')
36
+ .option('-n, --display-name <name>', 'Human-readable display name')
37
+ .option('-c, --capabilities <list>', 'Comma-separated capabilities (e.g. query,answer,write)')
38
+ .option('-d, --directory <url>', 'Override directory URL')
39
+ .action(async (opts: { displayName?: string; capabilities?: string; directory?: string }) => {
40
+ await cmdRegister(opts)
41
+ })
42
+
43
+ // ─── beam lookup ──────────────────────────────────────────────────────────────
44
+ program
45
+ .command('lookup <beamId>')
46
+ .description('Look up an agent by Beam ID')
47
+ .option('-d, --directory <url>', 'Override directory URL')
48
+ .option('--json', 'Output raw JSON')
49
+ .action(async (beamId: string, opts: { directory?: string; json?: boolean }) => {
50
+ await cmdLookup(beamId, opts)
51
+ })
52
+
53
+ // ─── beam search ──────────────────────────────────────────────────────────────
54
+ program
55
+ .command('search')
56
+ .description('Search for agents in the directory')
57
+ .option('--org <org>', 'Filter by organisation')
58
+ .option('--capability <cap>', 'Filter by capability')
59
+ .option('--min-trust <score>', 'Minimum trust score (0.0-1.0)')
60
+ .option('--limit <n>', 'Max results', '20')
61
+ .option('-d, --directory <url>', 'Override directory URL')
62
+ .option('--json', 'Output raw JSON')
63
+ .action(async (opts: { org?: string; capability?: string; minTrust?: string; limit?: string; directory?: string; json?: boolean }) => {
64
+ await cmdSearch(opts)
65
+ })
66
+
67
+ // ─── beam send ────────────────────────────────────────────────────────────────
68
+ program
69
+ .command('send <to> <intent> [params]')
70
+ .description('Send an intent to an agent and print the result')
71
+ .option('-d, --directory <url>', 'Override directory URL')
72
+ .option('-t, --timeout <seconds>', 'Timeout in seconds', '10')
73
+ .option('--json', 'Output raw JSON')
74
+ .action(async (to: string, intent: string, params: string | undefined, opts: { directory?: string; timeout?: string; json?: boolean }) => {
75
+ await cmdSend(to, intent, params, opts)
76
+ })
77
+
78
+ // ─── Error handling ───────────────────────────────────────────────────────────
79
+ program.configureOutput({
80
+ writeErr: str => process.stderr.write(chalk.red(str))
81
+ })
82
+
83
+ program.parse()
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "resolveJsonModule": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }