@highway1/cli 0.1.22 → 0.1.24

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highway1/cli",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "CLI tool for Clawiverse network",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "clean": "rm -rf dist"
14
14
  },
15
15
  "dependencies": {
16
- "@highway1/core": "0.1.18",
16
+ "@highway1/core": "0.1.19",
17
17
  "chalk": "^5.3.0",
18
18
  "cli-table3": "^0.6.5",
19
19
  "commander": "^12.1.0",
@@ -16,6 +16,7 @@ export function registerJoinCommand(program: Command): void {
16
16
  .command('join')
17
17
  .description('Join the Clawiverse network')
18
18
  .option('--bootstrap <peers...>', 'Bootstrap peer addresses')
19
+ .option('--relay', 'Run as a relay server and advertise relay capability')
19
20
  .action(async (options) => {
20
21
  try {
21
22
  printHeader('Join Clawiverse Network');
@@ -42,6 +43,7 @@ export function registerJoinCommand(program: Command): void {
42
43
  bootstrapPeers,
43
44
  enableDHT: true,
44
45
  reserveRelaySlot: true,
46
+ enableRelay: options.relay ?? false,
45
47
  });
46
48
 
47
49
  await node.start();
@@ -54,31 +56,50 @@ export function registerJoinCommand(program: Command): void {
54
56
 
55
57
  // Wait for bootstrap peer connection before publishing to DHT
56
58
  const connectSpin = spinner('Connecting to bootstrap peers...');
59
+
60
+ // Phase 1: wait for peer:connect (up to 10s)
57
61
  await new Promise<void>((resolve) => {
58
62
  const timeout = setTimeout(resolve, 10000);
59
63
  node.libp2p.addEventListener('peer:connect', () => {
60
64
  clearTimeout(timeout);
61
- setTimeout(resolve, 500);
65
+ resolve();
62
66
  }, { once: true });
63
67
  });
68
+
69
+ // Phase 2: wait for relay address to appear (up to 5s)
70
+ const hasRelayAddr = () => node.getMultiaddrs().some(a => a.includes('/p2p-circuit'));
71
+ if (!hasRelayAddr()) {
72
+ await new Promise<void>((resolve) => {
73
+ const timeout = setTimeout(resolve, 5000);
74
+ const check = () => {
75
+ if (hasRelayAddr()) { clearTimeout(timeout); resolve(); }
76
+ };
77
+ node.libp2p.addEventListener('self:multiaddress:updated', check);
78
+ setTimeout(() => node.libp2p.removeEventListener('self:multiaddress:updated', check), 5000);
79
+ });
80
+ }
81
+
64
82
  connectSpin.succeed('Connected to network!');
65
83
 
66
84
  // Publish Agent Card with peerId and multiaddrs so others can dial us
67
85
  const cardSpin = spinner('Publishing Agent Card to DHT...');
68
86
 
69
- // Include circuit relay addresses so nodes behind NAT can be reached
70
- const directAddrs = node.getMultiaddrs();
71
- const relayAddrs = bootstrapPeers.map((relayAddr) => {
72
- const peerId = node.getPeerId();
73
- return `${relayAddr}/p2p-circuit/p2p/${peerId}`;
74
- });
75
- const allAddrs = [...directAddrs, ...relayAddrs];
87
+ // Use relay addresses from libp2p (populated after reservation), fall back to manual construction
88
+ const directAddrs = node.getMultiaddrs().filter(a => !a.includes('/p2p-circuit'));
89
+ const relayAddrs = node.getMultiaddrs().filter(a => a.includes('/p2p-circuit'));
90
+ const fallbackRelayAddrs = relayAddrs.length === 0
91
+ ? bootstrapPeers.map(r => `${r}/p2p-circuit/p2p/${node.getPeerId()}`)
92
+ : [];
93
+ const allAddrs = [...directAddrs, ...relayAddrs, ...fallbackRelayAddrs];
94
+
95
+ const capabilities = [...(card.capabilities ?? [])];
96
+ if (options.relay) capabilities.push('relay');
76
97
 
77
98
  const agentCard = createAgentCard(
78
99
  identity.did,
79
100
  card.name,
80
101
  card.description,
81
- card.capabilities,
102
+ capabilities,
82
103
  allAddrs,
83
104
  node.getPeerId()
84
105
  );