beam-protocol-cli 0.5.1 → 0.6.1
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/README.md +154 -0
- package/dist/commands/browse.js +1 -1
- package/dist/commands/browse.js.map +1 -1
- package/dist/commands/delegate.js +1 -1
- package/dist/commands/delegate.js.map +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys-list.d.ts +7 -0
- package/dist/commands/keys-list.d.ts.map +1 -0
- package/dist/commands/keys-list.js +33 -0
- package/dist/commands/keys-list.js.map +1 -0
- package/dist/commands/keys-revoke.d.ts +7 -0
- package/dist/commands/keys-revoke.d.ts.map +1 -0
- package/dist/commands/keys-revoke.js +36 -0
- package/dist/commands/keys-revoke.js.map +1 -0
- package/dist/commands/keys-rotate.d.ts +7 -0
- package/dist/commands/keys-rotate.d.ts.map +1 -0
- package/dist/commands/keys-rotate.js +48 -0
- package/dist/commands/keys-rotate.js.map +1 -0
- package/dist/commands/lookup.js +1 -1
- package/dist/commands/lookup.js.map +1 -1
- package/dist/commands/profile-update.js +1 -1
- package/dist/commands/profile-update.js.map +1 -1
- package/dist/commands/register.js +1 -1
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/report.js +1 -1
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/send.js +1 -1
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/stats.js +1 -1
- package/dist/commands/stats.js.map +1 -1
- package/dist/commands/talk.d.ts +10 -0
- package/dist/commands/talk.d.ts.map +1 -0
- package/dist/commands/talk.js +80 -0
- package/dist/commands/talk.js.map +1 -0
- package/dist/commands/verify-check.js +1 -1
- package/dist/commands/verify-check.js.map +1 -1
- package/dist/commands/verify-domain.js +1 -1
- package/dist/commands/verify-domain.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/index.js +57 -4
- package/dist/index.js.map +1 -1
- package/package.json +15 -3
- package/src/commands/browse.ts +0 -61
- package/src/commands/delegate.ts +0 -52
- package/src/commands/init.ts +0 -61
- package/src/commands/lookup.ts +0 -68
- package/src/commands/profile-update.ts +0 -47
- package/src/commands/register.ts +0 -58
- package/src/commands/report.ts +0 -49
- package/src/commands/search.ts +0 -87
- package/src/commands/send.ts +0 -92
- package/src/commands/stats.ts +0 -40
- package/src/commands/verify-check.ts +0 -41
- package/src/commands/verify-domain.ts +0 -42
- package/src/config.ts +0 -51
- package/src/index.ts +0 -162
- package/tsconfig.json +0 -23
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { BeamClient } from 'beam-protocol-sdk';
|
|
4
|
+
import { BEAM_ID_PATTERN, loadConfig } from '../config.js';
|
|
5
|
+
function parseContext(contextJson) {
|
|
6
|
+
if (!contextJson) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const parsed = JSON.parse(contextJson);
|
|
11
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
throw new Error('Context must be a JSON object');
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
console.error(chalk.red(`✖ Invalid context JSON: ${err.message}`));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function cmdTalk(to, message, options) {
|
|
22
|
+
const config = loadConfig();
|
|
23
|
+
const directoryUrl = options.directory ?? config.directoryUrl;
|
|
24
|
+
const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1000 : 60_000;
|
|
25
|
+
const context = parseContext(options.context);
|
|
26
|
+
if (!BEAM_ID_PATTERN.test(to)) {
|
|
27
|
+
console.error(chalk.red(`✖ Invalid Beam ID: ${to}`));
|
|
28
|
+
console.error(chalk.dim(' Expected: agent@beam.directory or agent@org.beam.directory'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
if (!message.trim()) {
|
|
32
|
+
console.error(chalk.red('✖ Message must be non-empty'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const spinner = ora(`Talking to ${chalk.bold(to)}...`).start();
|
|
36
|
+
const startTime = Date.now();
|
|
37
|
+
try {
|
|
38
|
+
const client = new BeamClient({
|
|
39
|
+
identity: config.identity,
|
|
40
|
+
directoryUrl,
|
|
41
|
+
});
|
|
42
|
+
const reply = await client.talk(to, message, {
|
|
43
|
+
context,
|
|
44
|
+
language: options.language,
|
|
45
|
+
timeoutMs,
|
|
46
|
+
});
|
|
47
|
+
const elapsed = Date.now() - startTime;
|
|
48
|
+
spinner.stop();
|
|
49
|
+
if (options.json) {
|
|
50
|
+
console.log(JSON.stringify(reply, null, 2));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(chalk.bold.green('✅ Message delivered successfully'));
|
|
55
|
+
console.log(chalk.dim('─'.repeat(40)));
|
|
56
|
+
console.log(`${chalk.cyan('From:')} ${config.identity.beamId}`);
|
|
57
|
+
console.log(`${chalk.cyan('To:')} ${to}`);
|
|
58
|
+
console.log(`${chalk.cyan('Intent:')} conversation.message`);
|
|
59
|
+
console.log(`${chalk.cyan('Latency:')} ${elapsed}ms`);
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(chalk.bold('💬 Reply:'));
|
|
62
|
+
console.log(reply.message || chalk.dim('(empty response message)'));
|
|
63
|
+
if (reply.structured && Object.keys(reply.structured).length > 0) {
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log(chalk.bold('📦 Structured Data:'));
|
|
66
|
+
console.log(JSON.stringify(reply.structured, null, 2));
|
|
67
|
+
}
|
|
68
|
+
if (reply.threadId) {
|
|
69
|
+
console.log('');
|
|
70
|
+
console.log(`${chalk.cyan('Thread:')} ${reply.threadId}`);
|
|
71
|
+
}
|
|
72
|
+
console.log('');
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
spinner.fail('Talk failed');
|
|
76
|
+
console.error(chalk.red(`✖ ${err.message}`));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=talk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talk.js","sourceRoot":"","sources":["../../src/commands/talk.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { BeamClient } from '
|
|
3
|
+
import { BeamClient } from 'beam-protocol-sdk';
|
|
4
4
|
import { loadConfig } from '../config.js';
|
|
5
5
|
export async function cmdVerifyCheck(options) {
|
|
6
6
|
const config = loadConfig();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-check.js","sourceRoot":"","sources":["../../src/commands/verify-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"verify-check.js","sourceRoot":"","sources":["../../src/commands/verify-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAOzC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA2B;IAC9D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAA;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,iCAAiC,CAAC,CAAC,KAAK,EAAE,CAAA;IAE9D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;QAC1E,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,uBAAuB,EAAE,CAAA;QAC3D,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAA;QACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAClF,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QACnH,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAClF,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,YAAY,CAAC,IAAI,EAAE,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QACzC,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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { BeamClient } from '
|
|
3
|
+
import { BeamClient } from 'beam-protocol-sdk';
|
|
4
4
|
import { loadConfig } from '../config.js';
|
|
5
5
|
export async function cmdVerifyDomain(domain, options) {
|
|
6
6
|
const config = loadConfig();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-domain.js","sourceRoot":"","sources":["../../src/commands/verify-domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"verify-domain.js","sourceRoot":"","sources":["../../src/commands/verify-domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAOzC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,OAA4B;IAChF,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAA;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,iCAAiC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAErF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;QAC1E,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QACtD,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAA;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;QAChE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QACjH,IAAI,YAAY,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC,CAAA;QAC3F,IAAI,YAAY,CAAC,QAAQ,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,QAAQ,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC9F,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAA;IAC/E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;QAC1C,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
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
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,kBAAkB,CAAC,GAAG,SAAgB,GAAG,UAAU,GAAG,IAAI,CAOzE;AAED,wBAAgB,UAAU,CAAC,GAAG,SAAgB,GAAG,UAAU,CAM1D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAgB,GAAG,MAAM,CAElF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,SAAgB,GAAG,IAAI,CAIxE;AAED,eAAO,MAAM,qBAAqB,QAAoE,CAAA;AACtG,eAAO,MAAM,eAAe,QAA+E,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import { Command } from 'commander';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
5
|
import { cmdInit } from './commands/init.js';
|
|
@@ -13,30 +14,46 @@ import { cmdVerifyCheck } from './commands/verify-check.js';
|
|
|
13
14
|
import { cmdStats } from './commands/stats.js';
|
|
14
15
|
import { cmdDelegate } from './commands/delegate.js';
|
|
15
16
|
import { cmdReport } from './commands/report.js';
|
|
17
|
+
import { cmdTalk } from './commands/talk.js';
|
|
18
|
+
import { cmdKeysList } from './commands/keys-list.js';
|
|
19
|
+
import { cmdKeysRotate } from './commands/keys-rotate.js';
|
|
20
|
+
import { cmdKeysRevoke } from './commands/keys-revoke.js';
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
const { version } = require('../package.json');
|
|
16
23
|
const program = new Command();
|
|
17
24
|
program
|
|
18
25
|
.name('beam')
|
|
19
26
|
.description(chalk.bold('Beam Protocol CLI') + '\n' +
|
|
20
27
|
chalk.dim('SMTP for AI Agents — agent identity, registration & intent routing'))
|
|
21
|
-
.version(
|
|
28
|
+
.version(version);
|
|
22
29
|
program
|
|
23
30
|
.command('init')
|
|
24
31
|
.description('Generate a new Beam identity (writes .beam/identity.json)')
|
|
25
|
-
.
|
|
32
|
+
.option('-a, --agent <name>', 'Agent name (e.g. jarvis)')
|
|
33
|
+
.option('-n, --name <name>', 'Alias for --agent')
|
|
26
34
|
.option('-o, --org <name>', 'Organisation name (optional for consumer Beam-IDs)')
|
|
27
35
|
.option('-d, --directory <url>', 'Directory server URL', process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory')
|
|
28
36
|
.option('-f, --force', 'Overwrite existing identity')
|
|
29
37
|
.action(async (opts) => {
|
|
30
|
-
|
|
38
|
+
const agent = opts.agent ?? opts.name;
|
|
39
|
+
if (!agent) {
|
|
40
|
+
throw new Error('init requires --agent <name>');
|
|
41
|
+
}
|
|
42
|
+
await cmdInit({ agent, org: opts.org, directory: opts.directory, force: opts.force });
|
|
31
43
|
});
|
|
32
44
|
program
|
|
33
45
|
.command('register')
|
|
34
46
|
.description('Register this agent with a Beam directory')
|
|
35
47
|
.option('-n, --display-name <name>', 'Human-readable display name')
|
|
48
|
+
.option('--name <name>', 'Alias for --display-name')
|
|
36
49
|
.option('-c, --capabilities <list>', 'Comma-separated capabilities (e.g. query,answer,write)')
|
|
37
50
|
.option('-d, --directory <url>', 'Override directory URL')
|
|
38
51
|
.action(async (opts) => {
|
|
39
|
-
await cmdRegister(
|
|
52
|
+
await cmdRegister({
|
|
53
|
+
displayName: opts.displayName ?? opts.name,
|
|
54
|
+
capabilities: opts.capabilities,
|
|
55
|
+
directory: opts.directory,
|
|
56
|
+
});
|
|
40
57
|
});
|
|
41
58
|
program
|
|
42
59
|
.command('lookup <beamId>')
|
|
@@ -135,6 +152,42 @@ program
|
|
|
135
152
|
.action(async (to, intent, params, opts) => {
|
|
136
153
|
await cmdSend(to, intent, params, opts);
|
|
137
154
|
});
|
|
155
|
+
program
|
|
156
|
+
.command('talk <to> <message>')
|
|
157
|
+
.description('Send a natural-language message via conversation.message')
|
|
158
|
+
.option('-d, --directory <url>', 'Override directory URL')
|
|
159
|
+
.option('-t, --timeout <seconds>', 'Timeout in seconds', '60')
|
|
160
|
+
.option('-l, --language <language>', 'Language hint, e.g. en or de')
|
|
161
|
+
.option('-c, --context <json>', 'Optional context JSON object')
|
|
162
|
+
.option('--json', 'Output raw JSON')
|
|
163
|
+
.action(async (to, message, opts) => {
|
|
164
|
+
await cmdTalk(to, message, opts);
|
|
165
|
+
});
|
|
166
|
+
const keys = program.command('keys').description('Signing key lifecycle commands');
|
|
167
|
+
keys
|
|
168
|
+
.command('list [beamId]')
|
|
169
|
+
.description('List active and revoked signing keys for an agent')
|
|
170
|
+
.option('-d, --directory <url>', 'Override directory URL')
|
|
171
|
+
.option('--json', 'Output raw JSON')
|
|
172
|
+
.action(async (beamId, opts) => {
|
|
173
|
+
await cmdKeysList(beamId, opts);
|
|
174
|
+
});
|
|
175
|
+
keys
|
|
176
|
+
.command('rotate')
|
|
177
|
+
.description('Rotate the local agent signing key and update .beam/identity.json')
|
|
178
|
+
.option('-d, --directory <url>', 'Override directory URL')
|
|
179
|
+
.option('--json', 'Output raw JSON')
|
|
180
|
+
.action(async (opts) => {
|
|
181
|
+
await cmdKeysRotate(opts);
|
|
182
|
+
});
|
|
183
|
+
keys
|
|
184
|
+
.command('revoke <publicKey>')
|
|
185
|
+
.description('Revoke a previously rotated-out signing key')
|
|
186
|
+
.option('-d, --directory <url>', 'Override directory URL')
|
|
187
|
+
.option('--json', 'Output raw JSON')
|
|
188
|
+
.action(async (publicKey, opts) => {
|
|
189
|
+
await cmdKeysRevoke(publicKey, opts);
|
|
190
|
+
});
|
|
138
191
|
program.configureOutput({
|
|
139
192
|
outputError: (str, write) => write(chalk.red(str))
|
|
140
193
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beam-protocol-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Beam Protocol CLI
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "Beam Protocol CLI for verified B2B handoffs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"beam": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc",
|
|
12
13
|
"dev": "node --watch dist/index.js",
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
"start": "node dist/index.js"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
+
"beam-protocol-sdk": "^0.6.1",
|
|
18
19
|
"chalk": "^5.3.0",
|
|
19
20
|
"commander": "^12.0.0",
|
|
20
21
|
"inquirer": "^9.2.15",
|
|
@@ -27,6 +28,17 @@
|
|
|
27
28
|
"engines": {
|
|
28
29
|
"node": ">=18.0.0"
|
|
29
30
|
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/Beam-directory/beam-protocol.git",
|
|
39
|
+
"directory": "packages/cli"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://beam.directory",
|
|
30
42
|
"license": "Apache-2.0",
|
|
31
43
|
"keywords": [
|
|
32
44
|
"beam-protocol",
|
package/src/commands/browse.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import ora from 'ora'
|
|
3
|
-
import { BeamClient } from '@beam-protocol/sdk'
|
|
4
|
-
import type { BrowseFilters } from '@beam-protocol/sdk'
|
|
5
|
-
import { loadConfig } from '../config.js'
|
|
6
|
-
|
|
7
|
-
interface BrowseOptions {
|
|
8
|
-
page?: string
|
|
9
|
-
capability?: string
|
|
10
|
-
tier?: string
|
|
11
|
-
verifiedOnly?: boolean
|
|
12
|
-
directory?: string
|
|
13
|
-
json?: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function cmdBrowse(options: BrowseOptions): Promise<void> {
|
|
17
|
-
const config = loadConfig()
|
|
18
|
-
const directoryUrl = options.directory ?? config.directoryUrl
|
|
19
|
-
const page = options.page ? parseInt(options.page, 10) : 1
|
|
20
|
-
const filters: BrowseFilters = {
|
|
21
|
-
capability: options.capability,
|
|
22
|
-
tier: options.tier as BrowseFilters['tier'],
|
|
23
|
-
verified_only: options.verifiedOnly,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const spinner = ora(`Browsing directory page ${page}...`).start()
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
30
|
-
const result = await client.browse(page, filters)
|
|
31
|
-
spinner.stop()
|
|
32
|
-
|
|
33
|
-
if (options.json) {
|
|
34
|
-
console.log(JSON.stringify(result, null, 2))
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('')
|
|
39
|
-
console.log(chalk.bold(`📚 Directory Page ${result.page}`))
|
|
40
|
-
console.log(chalk.dim(`Showing ${result.agents.length} of ${result.total} agents`))
|
|
41
|
-
console.log(chalk.dim('─'.repeat(72)))
|
|
42
|
-
|
|
43
|
-
for (const agent of result.agents) {
|
|
44
|
-
const badge = agent.verified ? chalk.green('✓') : chalk.dim('○')
|
|
45
|
-
const tier = agent.verificationTier ? chalk.magenta(agent.verificationTier) : chalk.dim('basic')
|
|
46
|
-
console.log(` ${badge} ${chalk.bold(agent.beamId)} ${chalk.dim(`(${tier})`)}`)
|
|
47
|
-
console.log(` ${agent.displayName}${agent.description ? chalk.dim(` — ${agent.description}`) : ''}`)
|
|
48
|
-
if (agent.capabilities.length > 0) {
|
|
49
|
-
console.log(` ${chalk.cyan('Capabilities:')} ${agent.capabilities.join(', ')}`)
|
|
50
|
-
}
|
|
51
|
-
if (agent.website) {
|
|
52
|
-
console.log(` ${chalk.cyan('Website:')} ${agent.website}`)
|
|
53
|
-
}
|
|
54
|
-
console.log('')
|
|
55
|
-
}
|
|
56
|
-
} catch (err) {
|
|
57
|
-
spinner.fail('Browse failed')
|
|
58
|
-
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
59
|
-
process.exit(1)
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/commands/delegate.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import ora from 'ora'
|
|
3
|
-
import { BeamClient } from '@beam-protocol/sdk'
|
|
4
|
-
import { BEAM_ID_PATTERN, loadConfig } from '../config.js'
|
|
5
|
-
|
|
6
|
-
interface DelegateOptions {
|
|
7
|
-
scope?: string
|
|
8
|
-
expires?: string
|
|
9
|
-
directory?: string
|
|
10
|
-
json?: boolean
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function cmdDelegate(targetBeamId: string, options: DelegateOptions): Promise<void> {
|
|
14
|
-
if (!BEAM_ID_PATTERN.test(targetBeamId)) {
|
|
15
|
-
console.error(chalk.red(`✖ Invalid Beam ID: ${targetBeamId}`))
|
|
16
|
-
process.exit(1)
|
|
17
|
-
}
|
|
18
|
-
if (!options.scope) {
|
|
19
|
-
console.error(chalk.red('✖ Missing required --scope value'))
|
|
20
|
-
process.exit(1)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const config = loadConfig()
|
|
24
|
-
const directoryUrl = options.directory ?? config.directoryUrl
|
|
25
|
-
const expiresIn = options.expires ? parseInt(options.expires, 10) : undefined
|
|
26
|
-
const spinner = ora(`Creating delegation for ${chalk.bold(targetBeamId)}...`).start()
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
30
|
-
const delegation = await client.delegate(targetBeamId, options.scope, expiresIn)
|
|
31
|
-
spinner.stop()
|
|
32
|
-
|
|
33
|
-
if (options.json) {
|
|
34
|
-
console.log(JSON.stringify(delegation, null, 2))
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log('')
|
|
39
|
-
console.log(chalk.bold.green('✅ Delegation created'))
|
|
40
|
-
console.log(chalk.dim('─'.repeat(40)))
|
|
41
|
-
console.log(`${chalk.cyan('From:')} ${delegation.sourceBeamId}`)
|
|
42
|
-
console.log(`${chalk.cyan('To:')} ${delegation.targetBeamId}`)
|
|
43
|
-
console.log(`${chalk.cyan('Scope:')} ${delegation.scope}`)
|
|
44
|
-
if (delegation.expiresAt) console.log(`${chalk.cyan('Expires:')} ${delegation.expiresAt}`)
|
|
45
|
-
if (delegation.status) console.log(`${chalk.cyan('Status:')} ${delegation.status}`)
|
|
46
|
-
console.log('')
|
|
47
|
-
} catch (err) {
|
|
48
|
-
spinner.fail('Delegation failed')
|
|
49
|
-
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
50
|
-
process.exit(1)
|
|
51
|
-
}
|
|
52
|
-
}
|
package/src/commands/init.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
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
|
-
if (!/^[a-z0-9_-]+$/.test(agent)) {
|
|
17
|
-
console.error(chalk.red('✖ Agent name must match [a-z0-9_-]'))
|
|
18
|
-
process.exit(1)
|
|
19
|
-
}
|
|
20
|
-
if (org && !/^[a-z0-9_-]+$/.test(org)) {
|
|
21
|
-
console.error(chalk.red('✖ Org name must match [a-z0-9_-]'))
|
|
22
|
-
process.exit(1)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (configExists() && !force) {
|
|
26
|
-
console.error(chalk.yellow('⚠ Identity already exists at .beam/identity.json'))
|
|
27
|
-
console.error(chalk.dim(' Use --force to overwrite'))
|
|
28
|
-
process.exit(1)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const spinner = ora('Generating Ed25519 keypair...').start()
|
|
32
|
-
|
|
33
|
-
const identity = BeamIdentity.generate({ agentName: agent, orgName: org })
|
|
34
|
-
const identityData = identity.export()
|
|
35
|
-
|
|
36
|
-
saveConfig({
|
|
37
|
-
identity: identityData,
|
|
38
|
-
directoryUrl: directory,
|
|
39
|
-
createdAt: new Date().toISOString()
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
spinner.succeed('Identity generated')
|
|
43
|
-
|
|
44
|
-
console.log('')
|
|
45
|
-
console.log(chalk.bold('🔑 Beam Identity Created'))
|
|
46
|
-
console.log(chalk.dim('─'.repeat(40)))
|
|
47
|
-
console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(identityData.beamId)}`)
|
|
48
|
-
console.log(`${chalk.cyan('Directory:')} ${directory}`)
|
|
49
|
-
console.log(`${chalk.cyan('Config:')} ${process.cwd()}/.beam/identity.json`)
|
|
50
|
-
console.log('')
|
|
51
|
-
console.log(chalk.dim('Public key (SPKI/DER/base64):'))
|
|
52
|
-
console.log(chalk.dim(identityData.publicKeyBase64.substring(0, 64) + '...'))
|
|
53
|
-
console.log('')
|
|
54
|
-
console.log(chalk.yellow('⚠ Keep .beam/identity.json secret — it contains your private key!'))
|
|
55
|
-
console.log(chalk.dim(' Add .beam/ to your .gitignore'))
|
|
56
|
-
console.log('')
|
|
57
|
-
console.log(
|
|
58
|
-
chalk.green('Next step:'),
|
|
59
|
-
`beam register --display-name "${org ? agent : 'My Consumer Agent'}" --capabilities "query,answer"`
|
|
60
|
-
)
|
|
61
|
-
}
|
package/src/commands/lookup.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
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 { BEAM_ID_PATTERN, resolveDirectoryUrl } 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 directoryUrl = resolveDirectoryUrl(options.directory)
|
|
14
|
-
|
|
15
|
-
if (!BEAM_ID_PATTERN.test(beamId)) {
|
|
16
|
-
console.error(chalk.red(`✖ Invalid Beam ID format: ${beamId}`))
|
|
17
|
-
console.error(chalk.dim(' Expected: agent@beam.directory or agent@org.beam.directory'))
|
|
18
|
-
process.exit(1)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const spinner = ora(`Looking up ${chalk.bold(beamId)}...`).start()
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const directory = new BeamDirectory({ baseUrl: directoryUrl })
|
|
25
|
-
const record = await directory.lookup(beamId as BeamIdString)
|
|
26
|
-
|
|
27
|
-
if (!record) {
|
|
28
|
-
spinner.fail(`Agent not found: ${beamId}`)
|
|
29
|
-
process.exit(1)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
spinner.stop()
|
|
33
|
-
|
|
34
|
-
if (options.json) {
|
|
35
|
-
console.log(JSON.stringify(record, null, 2))
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const trustBar = getTrustBar(record.trustScore)
|
|
40
|
-
|
|
41
|
-
console.log('')
|
|
42
|
-
console.log(chalk.bold(`🤖 ${record.displayName}`))
|
|
43
|
-
console.log(chalk.dim('─'.repeat(40)))
|
|
44
|
-
console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`)
|
|
45
|
-
console.log(`${chalk.cyan('Org:')} ${record.org ?? chalk.dim('consumer')}`)
|
|
46
|
-
console.log(`${chalk.cyan('Trust Score:')} ${trustBar} ${(record.trustScore * 100).toFixed(0)}%`)
|
|
47
|
-
console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('✓ Verified') : chalk.yellow('Unverified')}`)
|
|
48
|
-
if (record.capabilities.length > 0) {
|
|
49
|
-
console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.map((capability: string) => chalk.blue(capability)).join(', ')}`)
|
|
50
|
-
}
|
|
51
|
-
console.log(`${chalk.cyan('Last Seen:')} ${new Date(record.lastSeen).toLocaleString()}`)
|
|
52
|
-
console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`)
|
|
53
|
-
console.log('')
|
|
54
|
-
} catch (err) {
|
|
55
|
-
spinner.fail('Lookup failed')
|
|
56
|
-
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
57
|
-
process.exit(1)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function getTrustBar(score: number): string {
|
|
62
|
-
const filled = Math.round(score * 10)
|
|
63
|
-
const empty = 10 - filled
|
|
64
|
-
const bar = '█'.repeat(filled) + '░'.repeat(empty)
|
|
65
|
-
if (score >= 0.8) return chalk.green(bar)
|
|
66
|
-
if (score >= 0.5) return chalk.yellow(bar)
|
|
67
|
-
return chalk.red(bar)
|
|
68
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import ora from 'ora'
|
|
3
|
-
import { BeamClient } from '@beam-protocol/sdk'
|
|
4
|
-
import { loadConfig } from '../config.js'
|
|
5
|
-
|
|
6
|
-
interface ProfileUpdateOptions {
|
|
7
|
-
description?: string
|
|
8
|
-
logoUrl?: string
|
|
9
|
-
website?: string
|
|
10
|
-
directory?: string
|
|
11
|
-
json?: boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export async function cmdProfileUpdate(options: ProfileUpdateOptions): Promise<void> {
|
|
15
|
-
const config = loadConfig()
|
|
16
|
-
const directoryUrl = options.directory ?? config.directoryUrl
|
|
17
|
-
const spinner = ora(`Updating profile for ${chalk.bold(config.identity.beamId)}...`).start()
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
21
|
-
const profile = await client.updateProfile({
|
|
22
|
-
description: options.description,
|
|
23
|
-
logo_url: options.logoUrl,
|
|
24
|
-
website: options.website,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
spinner.stop()
|
|
28
|
-
|
|
29
|
-
if (options.json) {
|
|
30
|
-
console.log(JSON.stringify(profile, null, 2))
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
console.log('')
|
|
35
|
-
console.log(chalk.bold.green('✅ Profile updated'))
|
|
36
|
-
console.log(chalk.dim('─'.repeat(40)))
|
|
37
|
-
console.log(`${chalk.cyan('Beam ID:')} ${profile.beamId}`)
|
|
38
|
-
console.log(`${chalk.cyan('Description:')} ${profile.description ?? chalk.dim('—')}`)
|
|
39
|
-
console.log(`${chalk.cyan('Logo URL:')} ${profile.logoUrl ?? chalk.dim('—')}`)
|
|
40
|
-
console.log(`${chalk.cyan('Website:')} ${profile.website ?? chalk.dim('—')}`)
|
|
41
|
-
console.log('')
|
|
42
|
-
} catch (err) {
|
|
43
|
-
spinner.fail('Profile update failed')
|
|
44
|
-
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
45
|
-
process.exit(1)
|
|
46
|
-
}
|
|
47
|
-
}
|