beam-protocol-cli 0.3.0 → 0.5.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/package.json +2 -2
- package/src/commands/browse.ts +61 -0
- package/src/commands/delegate.ts +52 -0
- package/src/commands/init.ts +6 -4
- package/src/commands/lookup.ts +6 -8
- package/src/commands/profile-update.ts +47 -0
- package/src/commands/register.ts +1 -1
- package/src/commands/report.ts +49 -0
- package/src/commands/search.ts +3 -6
- package/src/commands/send.ts +4 -9
- package/src/commands/stats.ts +40 -0
- package/src/commands/verify-check.ts +41 -0
- package/src/commands/verify-domain.ts +42 -0
- package/src/config.ts +16 -5
- package/src/index.ts +91 -12
- package/tsconfig.json +7 -2
- package/dist/commands/init.d.ts +0 -9
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -45
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/lookup.d.ts +0 -7
- package/dist/commands/lookup.d.ts.map +0 -1
- package/dist/commands/lookup.js +0 -58
- package/dist/commands/lookup.js.map +0 -1
- package/dist/commands/register.d.ts +0 -8
- package/dist/commands/register.d.ts.map +0 -1
- package/dist/commands/register.js +0 -46
- package/dist/commands/register.js.map +0 -1
- package/dist/commands/search.d.ts +0 -11
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js +0 -73
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/send.d.ts +0 -8
- package/dist/commands/send.d.ts.map +0 -1
- package/dist/commands/send.js +0 -78
- package/dist/commands/send.js.map +0 -1
- package/dist/config.d.ts +0 -13
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -26
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -73
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beam-protocol-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Beam Protocol CLI \u2014 manage Beam identities, register agents, send intents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
"ai-agents",
|
|
35
35
|
"cli"
|
|
36
36
|
]
|
|
37
|
-
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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
CHANGED
|
@@ -5,7 +5,7 @@ import { configExists, saveConfig, DEFAULT_DIRECTORY_URL } from '../config.js'
|
|
|
5
5
|
|
|
6
6
|
interface InitOptions {
|
|
7
7
|
agent: string
|
|
8
|
-
org
|
|
8
|
+
org?: string
|
|
9
9
|
force?: boolean
|
|
10
10
|
directory?: string
|
|
11
11
|
}
|
|
@@ -13,12 +13,11 @@ interface InitOptions {
|
|
|
13
13
|
export async function cmdInit(options: InitOptions): Promise<void> {
|
|
14
14
|
const { agent, org, force, directory = DEFAULT_DIRECTORY_URL } = options
|
|
15
15
|
|
|
16
|
-
// Validate inputs
|
|
17
16
|
if (!/^[a-z0-9_-]+$/.test(agent)) {
|
|
18
17
|
console.error(chalk.red('✖ Agent name must match [a-z0-9_-]'))
|
|
19
18
|
process.exit(1)
|
|
20
19
|
}
|
|
21
|
-
if (!/^[a-z0-9_-]+$/.test(org)) {
|
|
20
|
+
if (org && !/^[a-z0-9_-]+$/.test(org)) {
|
|
22
21
|
console.error(chalk.red('✖ Org name must match [a-z0-9_-]'))
|
|
23
22
|
process.exit(1)
|
|
24
23
|
}
|
|
@@ -55,5 +54,8 @@ export async function cmdInit(options: InitOptions): Promise<void> {
|
|
|
55
54
|
console.log(chalk.yellow('⚠ Keep .beam/identity.json secret — it contains your private key!'))
|
|
56
55
|
console.log(chalk.dim(' Add .beam/ to your .gitignore'))
|
|
57
56
|
console.log('')
|
|
58
|
-
console.log(
|
|
57
|
+
console.log(
|
|
58
|
+
chalk.green('Next step:'),
|
|
59
|
+
`beam register --display-name "${org ? agent : 'My Consumer Agent'}" --capabilities "query,answer"`
|
|
60
|
+
)
|
|
59
61
|
}
|
package/src/commands/lookup.ts
CHANGED
|
@@ -2,7 +2,7 @@ import chalk from 'chalk'
|
|
|
2
2
|
import ora from 'ora'
|
|
3
3
|
import { BeamDirectory } from '@beam-protocol/sdk'
|
|
4
4
|
import type { BeamIdString } from '@beam-protocol/sdk'
|
|
5
|
-
import {
|
|
5
|
+
import { BEAM_ID_PATTERN, resolveDirectoryUrl } from '../config.js'
|
|
6
6
|
|
|
7
7
|
interface LookupOptions {
|
|
8
8
|
directory?: string
|
|
@@ -10,13 +10,11 @@ interface LookupOptions {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export async function cmdLookup(beamId: string, options: LookupOptions): Promise<void> {
|
|
13
|
-
const
|
|
14
|
-
const directoryUrl = options.directory ?? config.directoryUrl
|
|
13
|
+
const directoryUrl = resolveDirectoryUrl(options.directory)
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
if (!beamId.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
|
|
15
|
+
if (!BEAM_ID_PATTERN.test(beamId)) {
|
|
18
16
|
console.error(chalk.red(`✖ Invalid Beam ID format: ${beamId}`))
|
|
19
|
-
console.error(chalk.dim(' Expected: agent@org.beam.directory'))
|
|
17
|
+
console.error(chalk.dim(' Expected: agent@beam.directory or agent@org.beam.directory'))
|
|
20
18
|
process.exit(1)
|
|
21
19
|
}
|
|
22
20
|
|
|
@@ -44,11 +42,11 @@ export async function cmdLookup(beamId: string, options: LookupOptions): Promise
|
|
|
44
42
|
console.log(chalk.bold(`🤖 ${record.displayName}`))
|
|
45
43
|
console.log(chalk.dim('─'.repeat(40)))
|
|
46
44
|
console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`)
|
|
47
|
-
console.log(`${chalk.cyan('Org:')} ${record.org}`)
|
|
45
|
+
console.log(`${chalk.cyan('Org:')} ${record.org ?? chalk.dim('consumer')}`)
|
|
48
46
|
console.log(`${chalk.cyan('Trust Score:')} ${trustBar} ${(record.trustScore * 100).toFixed(0)}%`)
|
|
49
47
|
console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('✓ Verified') : chalk.yellow('Unverified')}`)
|
|
50
48
|
if (record.capabilities.length > 0) {
|
|
51
|
-
console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.map(
|
|
49
|
+
console.log(`${chalk.cyan('Capabilities:')} ${record.capabilities.map((capability: string) => chalk.blue(capability)).join(', ')}`)
|
|
52
50
|
}
|
|
53
51
|
console.log(`${chalk.cyan('Last Seen:')} ${new Date(record.lastSeen).toLocaleString()}`)
|
|
54
52
|
console.log(`${chalk.cyan('Registered:')} ${new Date(record.createdAt).toLocaleString()}`)
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
}
|
package/src/commands/register.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function cmdRegister(options: RegisterOptions): Promise<void> {
|
|
|
41
41
|
console.log(chalk.dim('─'.repeat(40)))
|
|
42
42
|
console.log(`${chalk.cyan('Beam ID:')} ${chalk.bold(record.beamId)}`)
|
|
43
43
|
console.log(`${chalk.cyan('Display:')} ${record.displayName}`)
|
|
44
|
-
console.log(`${chalk.cyan('Org:')} ${record.org}`)
|
|
44
|
+
console.log(`${chalk.cyan('Org:')} ${record.org ?? chalk.dim('consumer')}`)
|
|
45
45
|
console.log(`${chalk.cyan('Trust Score:')} ${(record.trustScore * 100).toFixed(0)}%`)
|
|
46
46
|
console.log(`${chalk.cyan('Verified:')} ${record.verified ? chalk.green('Yes ✓') : chalk.yellow('No')}`)
|
|
47
47
|
if (record.capabilities.length > 0) {
|
|
@@ -0,0 +1,49 @@
|
|
|
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 ReportOptions {
|
|
7
|
+
reason?: string
|
|
8
|
+
directory?: string
|
|
9
|
+
json?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function cmdReport(targetBeamId: string, options: ReportOptions): Promise<void> {
|
|
13
|
+
if (!BEAM_ID_PATTERN.test(targetBeamId)) {
|
|
14
|
+
console.error(chalk.red(`✖ Invalid Beam ID: ${targetBeamId}`))
|
|
15
|
+
process.exit(1)
|
|
16
|
+
}
|
|
17
|
+
if (!options.reason) {
|
|
18
|
+
console.error(chalk.red('✖ Missing required --reason value'))
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const config = loadConfig()
|
|
23
|
+
const directoryUrl = options.directory ?? config.directoryUrl
|
|
24
|
+
const spinner = ora(`Submitting report for ${chalk.bold(targetBeamId)}...`).start()
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
28
|
+
const report = await client.report(targetBeamId, options.reason)
|
|
29
|
+
spinner.stop()
|
|
30
|
+
|
|
31
|
+
if (options.json) {
|
|
32
|
+
console.log(JSON.stringify(report, null, 2))
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log('')
|
|
37
|
+
console.log(chalk.bold.yellow('⚠ Agent reported'))
|
|
38
|
+
console.log(chalk.dim('─'.repeat(40)))
|
|
39
|
+
console.log(`${chalk.cyan('Reporter:')} ${report.reporterBeamId}`)
|
|
40
|
+
console.log(`${chalk.cyan('Target:')} ${report.targetBeamId}`)
|
|
41
|
+
console.log(`${chalk.cyan('Reason:')} ${report.reason}`)
|
|
42
|
+
if (report.status) console.log(`${chalk.cyan('Status:')} ${report.status}`)
|
|
43
|
+
console.log('')
|
|
44
|
+
} catch (err) {
|
|
45
|
+
spinner.fail('Report failed')
|
|
46
|
+
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
47
|
+
process.exit(1)
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/commands/search.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk'
|
|
2
2
|
import ora from 'ora'
|
|
3
3
|
import { BeamDirectory } from '@beam-protocol/sdk'
|
|
4
|
-
import {
|
|
4
|
+
import { resolveDirectoryUrl } from '../config.js'
|
|
5
5
|
|
|
6
6
|
interface SearchOptions {
|
|
7
7
|
org?: string
|
|
@@ -13,8 +13,7 @@ interface SearchOptions {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export async function cmdSearch(options: SearchOptions): Promise<void> {
|
|
16
|
-
const
|
|
17
|
-
const directoryUrl = options.directory ?? config.directoryUrl
|
|
16
|
+
const directoryUrl = resolveDirectoryUrl(options.directory)
|
|
18
17
|
|
|
19
18
|
const query = {
|
|
20
19
|
org: options.org,
|
|
@@ -57,9 +56,7 @@ export async function cmdSearch(options: SearchOptions): Promise<void> {
|
|
|
57
56
|
? chalk.dim(` [${agent.capabilities.join(', ')}]`)
|
|
58
57
|
: ''
|
|
59
58
|
|
|
60
|
-
console.log(
|
|
61
|
-
` ${verified} ${chalk.bold(agent.beamId)}${caps}`
|
|
62
|
-
)
|
|
59
|
+
console.log(` ${verified} ${chalk.bold(agent.beamId)}${caps}`)
|
|
63
60
|
console.log(
|
|
64
61
|
` ${chalk.dim(agent.displayName)} · Trust: ${getTrustColored(agent.trustScore, trustPct + '%')} · Last seen: ${formatRelative(agent.lastSeen)}`
|
|
65
62
|
)
|
package/src/commands/send.ts
CHANGED
|
@@ -2,7 +2,7 @@ import chalk from 'chalk'
|
|
|
2
2
|
import ora from 'ora'
|
|
3
3
|
import { BeamClient } from '@beam-protocol/sdk'
|
|
4
4
|
import type { BeamIdString } from '@beam-protocol/sdk'
|
|
5
|
-
import { loadConfig } from '../config.js'
|
|
5
|
+
import { BEAM_ID_PATTERN, loadConfig } from '../config.js'
|
|
6
6
|
|
|
7
7
|
interface SendOptions {
|
|
8
8
|
directory?: string
|
|
@@ -20,14 +20,12 @@ export async function cmdSend(
|
|
|
20
20
|
const directoryUrl = options.directory ?? config.directoryUrl
|
|
21
21
|
const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1000 : 10000
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
if (!to.match(/^[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory$/)) {
|
|
23
|
+
if (!BEAM_ID_PATTERN.test(to)) {
|
|
25
24
|
console.error(chalk.red(`✖ Invalid Beam ID: ${to}`))
|
|
26
|
-
console.error(chalk.dim(' Expected: agent@org.beam.directory'))
|
|
25
|
+
console.error(chalk.dim(' Expected: agent@beam.directory or agent@org.beam.directory'))
|
|
27
26
|
process.exit(1)
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
// Parse params
|
|
31
29
|
let params: Record<string, unknown> = {}
|
|
32
30
|
if (paramsJson) {
|
|
33
31
|
try {
|
|
@@ -43,10 +41,7 @@ export async function cmdSend(
|
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
const spinner = ora(
|
|
47
|
-
`Sending ${chalk.bold(intent)} to ${chalk.bold(to)}...`
|
|
48
|
-
).start()
|
|
49
|
-
|
|
44
|
+
const spinner = ora(`Sending ${chalk.bold(intent)} to ${chalk.bold(to)}...`).start()
|
|
50
45
|
const startTime = Date.now()
|
|
51
46
|
|
|
52
47
|
try {
|
|
@@ -0,0 +1,40 @@
|
|
|
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 StatsOptions {
|
|
7
|
+
directory?: string
|
|
8
|
+
json?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function cmdStats(options: StatsOptions): Promise<void> {
|
|
12
|
+
const config = loadConfig()
|
|
13
|
+
const directoryUrl = options.directory ?? config.directoryUrl
|
|
14
|
+
const spinner = ora('Fetching directory statistics...').start()
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
18
|
+
const stats = await client.getStats()
|
|
19
|
+
spinner.stop()
|
|
20
|
+
|
|
21
|
+
if (options.json) {
|
|
22
|
+
console.log(JSON.stringify(stats, null, 2))
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log('')
|
|
27
|
+
console.log(chalk.bold('📈 Directory statistics'))
|
|
28
|
+
console.log(chalk.dim('─'.repeat(40)))
|
|
29
|
+
console.log(`${chalk.cyan('Total agents:')} ${stats.totalAgents}`)
|
|
30
|
+
console.log(`${chalk.cyan('Verified:')} ${stats.verifiedAgents}`)
|
|
31
|
+
console.log(`${chalk.cyan('Intents:')} ${stats.intentsProcessed}`)
|
|
32
|
+
if (stats.consumerAgents !== undefined) console.log(`${chalk.cyan('Consumers:')} ${stats.consumerAgents}`)
|
|
33
|
+
if (stats.version) console.log(`${chalk.cyan('Version:')} ${stats.version}`)
|
|
34
|
+
console.log('')
|
|
35
|
+
} catch (err) {
|
|
36
|
+
spinner.fail('Stats failed')
|
|
37
|
+
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
38
|
+
process.exit(1)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 VerifyCheckOptions {
|
|
7
|
+
directory?: string
|
|
8
|
+
json?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function cmdVerifyCheck(options: VerifyCheckOptions): Promise<void> {
|
|
12
|
+
const config = loadConfig()
|
|
13
|
+
const directoryUrl = options.directory ?? config.directoryUrl
|
|
14
|
+
const spinner = ora('Checking verification status...').start()
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
18
|
+
const verification = await client.checkDomainVerification()
|
|
19
|
+
spinner.stop()
|
|
20
|
+
|
|
21
|
+
if (options.json) {
|
|
22
|
+
console.log(JSON.stringify(verification, null, 2))
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log('')
|
|
27
|
+
console.log(chalk.bold('🔎 Verification status'))
|
|
28
|
+
console.log(chalk.dim('─'.repeat(40)))
|
|
29
|
+
console.log(`${chalk.cyan('Domain:')} ${verification.domain || chalk.dim('—')}`)
|
|
30
|
+
console.log(`${chalk.cyan('Verified:')} ${verification.verified ? chalk.green('Yes ✓') : chalk.yellow('Pending')}`)
|
|
31
|
+
console.log(`${chalk.cyan('Status:')} ${verification.status ?? chalk.dim('—')}`)
|
|
32
|
+
if (verification.tier) {
|
|
33
|
+
console.log(`${chalk.cyan('Tier:')} ${verification.tier}`)
|
|
34
|
+
}
|
|
35
|
+
console.log('')
|
|
36
|
+
} catch (err) {
|
|
37
|
+
spinner.fail('Verification check failed')
|
|
38
|
+
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
39
|
+
process.exit(1)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
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 VerifyDomainOptions {
|
|
7
|
+
directory?: string
|
|
8
|
+
json?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function cmdVerifyDomain(domain: string, options: VerifyDomainOptions): Promise<void> {
|
|
12
|
+
const config = loadConfig()
|
|
13
|
+
const directoryUrl = options.directory ?? config.directoryUrl
|
|
14
|
+
const spinner = ora(`Starting DNS verification for ${chalk.bold(domain)}...`).start()
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const client = new BeamClient({ identity: config.identity, directoryUrl })
|
|
18
|
+
const verification = await client.verifyDomain(domain)
|
|
19
|
+
spinner.stop()
|
|
20
|
+
|
|
21
|
+
if (options.json) {
|
|
22
|
+
console.log(JSON.stringify(verification, null, 2))
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log('')
|
|
27
|
+
console.log(chalk.bold('🌐 Domain verification started'))
|
|
28
|
+
console.log(chalk.dim('─'.repeat(40)))
|
|
29
|
+
console.log(`${chalk.cyan('Domain:')} ${verification.domain}`)
|
|
30
|
+
console.log(`${chalk.cyan('Verified:')} ${verification.verified ? chalk.green('Yes') : chalk.yellow('Pending')}`)
|
|
31
|
+
if (verification.txtName) console.log(`${chalk.cyan('TXT Name:')} ${verification.txtName}`)
|
|
32
|
+
if (verification.txtValue ?? verification.expected) {
|
|
33
|
+
console.log(`${chalk.cyan('TXT Value:')} ${verification.txtValue ?? verification.expected}`)
|
|
34
|
+
}
|
|
35
|
+
console.log('')
|
|
36
|
+
console.log(chalk.dim('After adding the TXT record, run: beam verify check'))
|
|
37
|
+
} catch (err) {
|
|
38
|
+
spinner.fail('Domain verification failed')
|
|
39
|
+
console.error(chalk.red(`✖ ${(err as Error).message}`))
|
|
40
|
+
process.exit(1)
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -20,21 +20,32 @@ export function configExists(cwd = process.cwd()): boolean {
|
|
|
20
20
|
return existsSync(getConfigPath(cwd))
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function
|
|
23
|
+
export function loadOptionalConfig(cwd = process.cwd()): BeamConfig | null {
|
|
24
24
|
const path = getConfigPath(cwd)
|
|
25
25
|
if (!existsSync(path)) {
|
|
26
|
-
|
|
27
|
-
`No Beam identity found. Run 'beam init' first.`
|
|
28
|
-
)
|
|
26
|
+
return null
|
|
29
27
|
}
|
|
30
28
|
const raw = readFileSync(path, 'utf8')
|
|
31
29
|
return JSON.parse(raw) as BeamConfig
|
|
32
30
|
}
|
|
33
31
|
|
|
32
|
+
export function loadConfig(cwd = process.cwd()): BeamConfig {
|
|
33
|
+
const config = loadOptionalConfig(cwd)
|
|
34
|
+
if (!config) {
|
|
35
|
+
throw new Error(`No Beam identity found. Run 'beam init' first.`)
|
|
36
|
+
}
|
|
37
|
+
return config
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveDirectoryUrl(override?: string, cwd = process.cwd()): string {
|
|
41
|
+
return override ?? loadOptionalConfig(cwd)?.directoryUrl ?? DEFAULT_DIRECTORY_URL
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
export function saveConfig(config: BeamConfig, cwd = process.cwd()): void {
|
|
35
45
|
const dir = getConfigDir(cwd)
|
|
36
46
|
mkdirSync(dir, { recursive: true })
|
|
37
47
|
writeFileSync(getConfigPath(cwd), JSON.stringify(config, null, 2), 'utf8')
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
export const DEFAULT_DIRECTORY_URL = process.env['BEAM_DIRECTORY_URL'] ?? '
|
|
50
|
+
export const DEFAULT_DIRECTORY_URL = process.env['BEAM_DIRECTORY_URL'] ?? 'https://api.beam.directory'
|
|
51
|
+
export const BEAM_ID_PATTERN = /^(?:[a-z0-9_-]+@beam\.directory|[a-z0-9_-]+@[a-z0-9_-]+\.beam\.directory)$/
|