agentdex-cli 0.3.0 → 0.3.2

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/cli.js CHANGED
@@ -6,7 +6,7 @@ import inquirer from 'inquirer';
6
6
  import qrcode from 'qrcode-terminal';
7
7
  import { readFileSync } from 'fs';
8
8
  import { AgentdexClient } from './client.js';
9
- import { parseSecretKey, getNpub, getPubkeyHex, createProfileEvent, createKind0Event, publishToRelays, createNote, updateKind0, generateAndSaveKeypair } from './nostr.js';
9
+ import { parseSecretKey, getNpub, getPubkeyHex, createProfileEvent, createKind0Event, publishToRelays, createNote, generateAndSaveKeypair } from './nostr.js';
10
10
  import { payInvoice } from './nwc.js';
11
11
  const program = new Command();
12
12
  program
@@ -57,6 +57,7 @@ program
57
57
  .option('--framework <fw>', 'Framework (e.g., langchain, openclaw)')
58
58
  .option('--model <model>', 'Model (e.g., claude-3.5-sonnet)')
59
59
  .option('--website <url>', 'Website URL')
60
+ .option('--avatar <url>', 'Avatar image URL (sets picture in kind 0 profile)')
60
61
  .option('--lightning <addr>', 'Lightning address (sets lud16 in kind 0 profile)')
61
62
  .option('--owner-x <handle>', 'Owner X/Twitter handle (e.g., @username)')
62
63
  .option('--portfolio <entry>', 'Portfolio URL (format: "url,name,description") — repeatable', (val, acc) => [...acc, val], [])
@@ -162,13 +163,20 @@ program
162
163
  console.log(chalk.gray(` Published to: ${published.join(', ')}`));
163
164
  console.log('');
164
165
  console.log(chalk.gray(` Run ${chalk.white('agentdex claim <name>')} to get ${chalk.hex('#D4A574')('<name>@agentdex.id')}`));
165
- // Update kind 0 with lightning address if provided
166
- if (options.lightning) {
167
- try {
168
- await updateKind0(sk, { lud16: options.lightning }, relays);
169
- console.log(chalk.gray(` ⚡ Lightning address set in kind 0: ${options.lightning}`));
170
- }
171
- catch { }
166
+ // Publish kind 0 profile (name, about, avatar, website, lud16)
167
+ const k0Spinner = ora('Publishing kind 0 profile to Nostr relays...').start();
168
+ try {
169
+ const kind0 = createKind0Event(sk, {
170
+ name,
171
+ about: description || undefined,
172
+ picture: options.avatar || undefined,
173
+ lud16: options.lightning || undefined,
174
+ });
175
+ await publishToRelays(kind0, relays);
176
+ k0Spinner.succeed('Kind 0 published — visible on all Nostr clients');
177
+ }
178
+ catch {
179
+ k0Spinner.warn('Kind 0 publish failed — agent may not appear on standard Nostr clients');
172
180
  }
173
181
  }
174
182
  return;
@@ -201,16 +209,25 @@ program
201
209
  console.log('');
202
210
  console.log(chalk.gray(` Run ${chalk.white('agentdex claim <name>')} to get ${chalk.hex('#D4A574')('<name>@agentdex.id')}`));
203
211
  console.log('');
204
- // Update kind 0 with lightning address if provided
205
- if (options.lightning) {
206
- try {
207
- await updateKind0(sk, { lud16: options.lightning }, relays);
208
- console.log(chalk.gray(` ⚡ Lightning address set in kind 0: ${options.lightning}`));
209
- }
210
- catch { }
212
+ // Publish kind 0 profile (name, about, avatar, website, lud16)
213
+ // Kind 0 is canonical for basic profile; kind 31337 is agent-specific metadata
214
+ const k0Spinner = ora('Publishing kind 0 profile to Nostr relays...').start();
215
+ try {
216
+ const kind0 = createKind0Event(sk, {
217
+ name,
218
+ about: description || undefined,
219
+ picture: options.avatar || undefined,
220
+ lud16: options.lightning || undefined,
221
+ });
222
+ await publishToRelays(kind0, relays);
223
+ k0Spinner.succeed('Kind 0 published — visible on all Nostr clients');
224
+ }
225
+ catch {
226
+ k0Spinner.warn('Kind 0 publish failed — agent may not appear on standard Nostr clients');
211
227
  }
212
228
  console.log(chalk.gray(' Next: Claim a NIP-05 name to get verified (first 100 free, then 5000 sats).'));
213
229
  }
230
+ process.exit(0);
214
231
  }
215
232
  catch (err) {
216
233
  const apiErr = err;
package/dist/nostr.d.ts CHANGED
@@ -53,7 +53,7 @@ export declare function createProfileEvent(sk: Uint8Array, profile: AgentProfile
53
53
  /**
54
54
  * Publish an event to Nostr relays
55
55
  */
56
- export declare function publishToRelays(event: object, relays?: string[]): Promise<string[]>;
56
+ export declare function publishToRelays(event: object, relays?: string[], timeoutMs?: number): Promise<string[]>;
57
57
  /**
58
58
  * Fetch existing kind 0, merge new fields, and republish.
59
59
  * Used to set lud16 (lightning address) during registration.
package/dist/nostr.js CHANGED
@@ -60,8 +60,11 @@ export function getPubkeyHex(sk) {
60
60
  export function createProfileEvent(sk, profile) {
61
61
  const tags = [
62
62
  ['d', 'agentdex-profile'],
63
- ['name', profile.name],
64
63
  ];
64
+ // name is optional in kind 31337 (canonical source is kind 0)
65
+ // included for backward compatibility and standalone profiles
66
+ if (profile.name)
67
+ tags.push(['name', profile.name]);
65
68
  if (profile.description)
66
69
  tags.push(['description', profile.description]);
67
70
  if (profile.capabilities) {
@@ -122,12 +125,15 @@ export function createProfileEvent(sk, profile) {
122
125
  /**
123
126
  * Publish an event to Nostr relays
124
127
  */
125
- export async function publishToRelays(event, relays = DEFAULT_RELAYS) {
128
+ export async function publishToRelays(event, relays = DEFAULT_RELAYS, timeoutMs = 10000) {
126
129
  const pool = new SimplePool();
127
130
  const published = [];
128
131
  try {
129
132
  const results = await Promise.allSettled(relays.map(async (relay) => {
130
- await pool.publish([relay], event);
133
+ await Promise.race([
134
+ pool.publish([relay], event),
135
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeoutMs)),
136
+ ]);
131
137
  return relay;
132
138
  }));
133
139
  for (const result of results) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentdex-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "CLI and SDK for the agentdex AI agent directory",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -64,6 +64,7 @@ program
64
64
  .option('--framework <fw>', 'Framework (e.g., langchain, openclaw)')
65
65
  .option('--model <model>', 'Model (e.g., claude-3.5-sonnet)')
66
66
  .option('--website <url>', 'Website URL')
67
+ .option('--avatar <url>', 'Avatar image URL (sets picture in kind 0 profile)')
67
68
  .option('--lightning <addr>', 'Lightning address (sets lud16 in kind 0 profile)')
68
69
  .option('--owner-x <handle>', 'Owner X/Twitter handle (e.g., @username)')
69
70
  .option('--portfolio <entry>', 'Portfolio URL (format: "url,name,description") — repeatable', (val: string, acc: string[]) => [...acc, val], [])
@@ -180,12 +181,20 @@ program
180
181
  console.log(chalk.gray(` Published to: ${published.join(', ')}`));
181
182
  console.log('');
182
183
  console.log(chalk.gray(` Run ${chalk.white('agentdex claim <name>')} to get ${chalk.hex('#D4A574')('<name>@agentdex.id')}`));
183
- // Update kind 0 with lightning address if provided
184
- if (options.lightning) {
185
- try {
186
- await updateKind0(sk, { lud16: options.lightning }, relays);
187
- console.log(chalk.gray(` ⚡ Lightning address set in kind 0: ${options.lightning}`));
188
- } catch {}
184
+
185
+ // Publish kind 0 profile (name, about, avatar, website, lud16)
186
+ const k0Spinner = ora('Publishing kind 0 profile to Nostr relays...').start();
187
+ try {
188
+ const kind0 = createKind0Event(sk, {
189
+ name,
190
+ about: description || undefined,
191
+ picture: options.avatar || undefined,
192
+ lud16: options.lightning || undefined,
193
+ });
194
+ await publishToRelays(kind0, relays);
195
+ k0Spinner.succeed('Kind 0 published — visible on all Nostr clients');
196
+ } catch {
197
+ k0Spinner.warn('Kind 0 publish failed — agent may not appear on standard Nostr clients');
189
198
  }
190
199
  }
191
200
  return;
@@ -221,15 +230,25 @@ program
221
230
  console.log('');
222
231
  console.log(chalk.gray(` Run ${chalk.white('agentdex claim <name>')} to get ${chalk.hex('#D4A574')('<name>@agentdex.id')}`));
223
232
  console.log('');
224
- // Update kind 0 with lightning address if provided
225
- if (options.lightning) {
226
- try {
227
- await updateKind0(sk, { lud16: options.lightning }, relays);
228
- console.log(chalk.gray(` ⚡ Lightning address set in kind 0: ${options.lightning}`));
229
- } catch {}
233
+ // Publish kind 0 profile (name, about, avatar, website, lud16)
234
+ // Kind 0 is canonical for basic profile; kind 31337 is agent-specific metadata
235
+ const k0Spinner = ora('Publishing kind 0 profile to Nostr relays...').start();
236
+ try {
237
+ const kind0 = createKind0Event(sk, {
238
+ name,
239
+ about: description || undefined,
240
+ picture: options.avatar || undefined,
241
+ lud16: options.lightning || undefined,
242
+ });
243
+ await publishToRelays(kind0, relays);
244
+ k0Spinner.succeed('Kind 0 published — visible on all Nostr clients');
245
+ } catch {
246
+ k0Spinner.warn('Kind 0 publish failed — agent may not appear on standard Nostr clients');
230
247
  }
248
+
231
249
  console.log(chalk.gray(' Next: Claim a NIP-05 name to get verified (first 100 free, then 5000 sats).'));
232
250
  }
251
+ process.exit(0);
233
252
  } catch (err) {
234
253
  const apiErr = err as any;
235
254
  if (apiErr.status === 503) {
package/src/nostr.ts CHANGED
@@ -94,9 +94,11 @@ export function getPubkeyHex(sk: Uint8Array): string {
94
94
  export function createProfileEvent(sk: Uint8Array, profile: AgentProfile) {
95
95
  const tags: string[][] = [
96
96
  ['d', 'agentdex-profile'],
97
- ['name', profile.name],
98
97
  ];
99
98
 
99
+ // name is optional in kind 31337 (canonical source is kind 0)
100
+ // included for backward compatibility and standalone profiles
101
+ if (profile.name) tags.push(['name', profile.name]);
100
102
  if (profile.description) tags.push(['description', profile.description]);
101
103
  if (profile.capabilities) {
102
104
  for (const cap of profile.capabilities) {
@@ -147,14 +149,17 @@ export function createProfileEvent(sk: Uint8Array, profile: AgentProfile) {
147
149
  /**
148
150
  * Publish an event to Nostr relays
149
151
  */
150
- export async function publishToRelays(event: object, relays: string[] = DEFAULT_RELAYS): Promise<string[]> {
152
+ export async function publishToRelays(event: object, relays: string[] = DEFAULT_RELAYS, timeoutMs = 10000): Promise<string[]> {
151
153
  const pool = new SimplePool();
152
154
  const published: string[] = [];
153
155
 
154
156
  try {
155
157
  const results = await Promise.allSettled(
156
158
  relays.map(async (relay) => {
157
- await pool.publish([relay], event as any);
159
+ await Promise.race([
160
+ pool.publish([relay], event as any),
161
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeoutMs)),
162
+ ]);
158
163
  return relay;
159
164
  })
160
165
  );