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.
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +45 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lookup.d.ts +7 -0
- package/dist/commands/lookup.d.ts.map +1 -0
- package/dist/commands/lookup.js +58 -0
- package/dist/commands/lookup.js.map +1 -0
- package/dist/commands/register.d.ts +8 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +46 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/search.d.ts +11 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +73 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/send.d.ts +8 -0
- package/dist/commands/send.d.ts.map +1 -0
- package/dist/commands/send.js +78 -0
- package/dist/commands/send.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +26 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
- package/src/commands/init.ts +59 -0
- package/src/commands/lookup.ts +70 -0
- package/src/commands/register.ts +58 -0
- package/src/commands/search.ts +90 -0
- package/src/commands/send.ts +97 -0
- package/src/config.ts +40 -0
- package/src/index.ts +83 -0
- package/tsconfig.json +18 -0
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|
|
@@ -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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAQzC,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,EAAU,EACV,MAAc,EACd,UAA8B,EAC9B,OAAoB;IAEpB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAA;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA;IAEhF,0BAA0B;IAC1B,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,4CAA4C,CAAC,EAAE,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,CAAA;QACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAA;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,eAAe;IACf,IAAI,MAAM,GAA4B,EAAE,CAAA;IACxC,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,MAAM,GAAG,MAAiC,CAAA;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;YACjD,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA2B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CACjB,WAAW,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CACxD,CAAC,KAAK,EAAE,CAAA;IAET,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;YAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY;SACb,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;QAC/E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;QAEtC,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,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAA;YAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;YAClE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;YAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,MAAM,EAAE,CAAC,CAAA;YACjD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,OAAO,IAAI,CAAC,CAAA;YACrD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAA;gBAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACtD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAA;YAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAA;YAC7E,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;YAChE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,OAAO,IAAI,CAAC,CAAA;QACvD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAC3B,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"}
|
package/dist/config.d.ts
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|