create-agent 0.0.13 → 0.0.15

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/CNAME ADDED
@@ -0,0 +1 @@
1
+ init-agent.com
package/README.md CHANGED
@@ -6,7 +6,9 @@
6
6
 
7
7
  > **Your AI agent has no identity.** It can't prove who it is. It can't sign anything. It can't be trusted.
8
8
 
9
- Instantly generates a cryptographic identity with a [W3C DID document](https://www.w3.org/TR/did-core/) — the emerging standard for autonomous agent identity.
9
+ Instantly generates a cryptographic identity with a [W3C DID document](https://www.w3.org/TR/did-core/) — the foundation for **safe AI agents you can trust**.
10
+
11
+ Use with [aam](https://aam.wtf) to sign and verify skills and agents.
10
12
 
11
13
  ---
12
14
 
@@ -146,6 +148,7 @@ fe70102<pubkey>
146
148
 
147
149
  | Application | Description |
148
150
  |-------------|-------------|
151
+ | **Sign Skills & Agents** | Cryptographically sign AI skills with [aam](https://aam.wtf) |
149
152
  | **AI Agents** | Verifiable identity for autonomous systems |
150
153
  | **Nostr Bots** | Generate keypairs for automated accounts |
151
154
  | **Testing** | Create ephemeral identities for integration tests |
@@ -165,6 +168,31 @@ The CLI outputs private keys to `stderr` only, allowing safe piping of the DID d
165
168
 
166
169
  ---
167
170
 
171
+ ## Next Steps: Sign Your Agents
172
+
173
+ Use your identity to sign skills and agents with [aam](https://aam.wtf):
174
+
175
+ ```bash
176
+ # 1. Generate your identity
177
+ npm init agent
178
+ # Save your privkey (hex format)
179
+
180
+ # 2. Install aam
181
+ npm install -g aam
182
+
183
+ # 3. Sign a skill you've created
184
+ aam skill sign my-skill --privkey <your-privkey> --repo user/repo
185
+
186
+ # 4. Others can verify your signature
187
+ aam skill verify my-skill
188
+ ```
189
+
190
+ This creates a **Nostr event (kind 31337)** cryptographically linking your identity to the skill. No black boxes. No hidden motives. Trust through transparency.
191
+
192
+ Learn more at [aam.wtf](https://aam.wtf)
193
+
194
+ ---
195
+
168
196
  ## Specification
169
197
 
170
198
  This implementation follows the [did:nostr Method Specification](https://nostrcg.github.io/did-nostr/) maintained by the [W3C Nostr Community Group](https://www.w3.org/community/nostr/).
@@ -173,6 +201,7 @@ This implementation follows the [did:nostr Method Specification](https://nostrcg
173
201
 
174
202
  ## Related
175
203
 
204
+ - [aam](https://aam.wtf) — Sign and verify AI skills and agents
176
205
  - [did:nostr Specification](https://nostrcg.github.io/did-nostr/)
177
206
  - [DID:nostr Explorer](https://nostrapps.github.io/did-explorer/)
178
207
  - [nostr-tools](https://github.com/nbd-wtf/nostr-tools)
@@ -1,46 +1,70 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { generateAgent } from '../index.js'
4
+ import { execSync } from 'child_process'
5
+ import fs from 'fs'
6
+
7
+ // Check if in a git repo
8
+ function isGitRepo() {
9
+ try {
10
+ execSync('git rev-parse --git-dir', { stdio: 'ignore' })
11
+ return true
12
+ } catch {
13
+ return false
14
+ }
15
+ }
16
+
17
+ // Check if privkey already exists
18
+ function hasPrivkey() {
19
+ try {
20
+ const result = execSync('git config nostr.privkey', { encoding: 'utf8' }).trim()
21
+ return result.length > 0
22
+ } catch {
23
+ return false
24
+ }
25
+ }
26
+
27
+ // Main
28
+ if (!isGitRepo()) {
29
+ console.error('\x1b[31mError: Not in a git repository.\x1b[0m')
30
+ console.error('Run \x1b[33mgit init\x1b[0m first.')
31
+ process.exit(1)
32
+ }
33
+
34
+ if (hasPrivkey()) {
35
+ console.error('\x1b[33mAgent identity already exists.\x1b[0m')
36
+ console.error('Privkey found in: git config nostr.privkey')
37
+ console.error('To regenerate, first run: git config --unset nostr.privkey')
38
+ process.exit(1)
39
+ }
4
40
 
5
41
  // Generate agent identity
6
42
  const { privkey, pubkey, nsec, npub, did } = generateAgent()
7
43
 
8
- // =============================================================================
9
- // CONSOLE OUTPUT
10
- // =============================================================================
11
- // First output the initial warning message to stderr
12
- process.stderr.write('\x1b[36m🤖 Creating new Nostr agent identity...\x1b[0m\n');
13
- process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
14
- process.stderr.write('\x1b[33m⚠️ IMPORTANT: Keep your private key (nsec/privkey) secret!\x1b[0m\n');
15
- process.stderr.write('\x1b[33m Never share it with anyone or input it on websites.\x1b[0m\n');
16
- process.stderr.write('\n');
17
-
18
- // Then output the Nostr identity information to stderr
19
- process.stderr.write('\n\x1b[32m📋 Your Nostr Identity:\x1b[0m\n');
20
- process.stderr.write('\x1b[32m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
21
- process.stderr.write(`\x1b[0mPublic Key (hex) : \x1b[33m${pubkey}\x1b[0m\n`);
22
- process.stderr.write(`\x1b[0mNostr Public Key : \x1b[33m${npub}\x1b[0m\n`);
23
- process.stderr.write(`\x1b[0mPrivate Key (hex): \x1b[31m${privkey}\x1b[0m\n`);
24
- process.stderr.write(`\x1b[0mNostr Secret Key : \x1b[31m${nsec}\x1b[0m\n`);
25
- process.stderr.write('\n');
26
- process.stderr.write('\x1b[36m🔍 Usage:\x1b[0m\n');
27
- process.stderr.write('\x1b[0m- Use your npub to identify yourself to others\x1b[0m\n');
28
- process.stderr.write('\x1b[0m- Add relays to the services array for discovery\x1b[0m\n');
29
- process.stderr.write('\x1b[0m- Use nsec to sign into Nostr clients (handle with extreme care!)\x1b[0m\n');
30
- process.stderr.write('\n');
31
-
32
-
33
- // Then output the DID document to stdout with a clear header in the output
34
- process.stderr.write('\x1b[36m📄 DID Nostr Document:\x1b[0m\n');
35
- process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
36
- console.log(JSON.stringify(did, null, 2));
37
- process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
38
-
39
- // Suggest next steps with aam
40
- process.stderr.write('\n');
41
- process.stderr.write('\x1b[36m🚀 Next Steps:\x1b[0m\n');
42
- process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
43
- process.stderr.write('\x1b[0m- Install the Agentic App Manager: \x1b[33mnpm install -g aam\x1b[0m\n');
44
- process.stderr.write('\x1b[0m- Add skills to your agent: \x1b[33maam skills anthropics/skills\x1b[0m\n');
45
- process.stderr.write('\x1b[0m- Browse the registry: \x1b[33mhttps://aam.wtf\x1b[0m\n');
46
- process.stderr.write('\n');
44
+ // Save DID document to file
45
+ const didFile = 'agent.did.json'
46
+ fs.writeFileSync(didFile, JSON.stringify(did, null, 2) + '\n')
47
+
48
+ // Save privkey to git config
49
+ execSync(`git config nostr.privkey ${privkey}`)
50
+
51
+ // Also output DID to stdout (clean JSON, no npm noise)
52
+ console.log(JSON.stringify(did, null, 2))
53
+
54
+ // Status messages to stderr
55
+ process.stderr.write('\n')
56
+ process.stderr.write('\x1b[32m✓ Agent identity created\x1b[0m\n')
57
+ process.stderr.write(`\x1b[32m✓ DID saved to ${didFile}\x1b[0m\n`)
58
+ process.stderr.write('\x1b[32m✓ Private key saved to git config nostr.privkey\x1b[0m\n')
59
+ process.stderr.write('\n')
60
+ process.stderr.write(`\x1b[36m Public key: \x1b[33m${pubkey}\x1b[0m\n`)
61
+ process.stderr.write(`\x1b[36m npub: \x1b[33m${npub}\x1b[0m\n`)
62
+ process.stderr.write(`\x1b[36m DID: \x1b[33m${did.id}\x1b[0m\n`)
63
+ process.stderr.write('\n')
64
+ process.stderr.write('\x1b[33m⚠ Keep your privkey secret - never commit it\x1b[0m\n')
65
+ process.stderr.write('\x1b[0m View with: git config nostr.privkey\x1b[0m\n')
66
+ process.stderr.write('\n')
67
+ process.stderr.write('\x1b[36mNext steps:\x1b[0m\n')
68
+ process.stderr.write('\x1b[0m npm install -g aam\x1b[0m\n')
69
+ process.stderr.write('\x1b[0m aam skill sign <name> --repo you/repo\x1b[0m\n')
70
+ process.stderr.write('\n')
package/index.html ADDED
@@ -0,0 +1,391 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>npm init agent - Cryptographic Identity for AI Agents</title>
7
+ <meta name="description" content="Give your AI agent an identity. Generate cryptographic keys with did:nostr in one command. The foundation for safe AI agents you can trust.">
8
+
9
+ <!-- Open Graph -->
10
+ <meta property="og:type" content="website">
11
+ <meta property="og:url" content="https://init-agent.com/">
12
+ <meta property="og:title" content="npm init agent - Identity for AI Agents">
13
+ <meta property="og:description" content="Give your AI agent an identity. Generate cryptographic keys with did:nostr in one command.">
14
+
15
+ <!-- Twitter -->
16
+ <meta name="twitter:card" content="summary_large_image">
17
+ <meta name="twitter:title" content="npm init agent - Identity for AI Agents">
18
+ <meta name="twitter:description" content="Give your AI agent an identity. Generate cryptographic keys with did:nostr in one command.">
19
+
20
+ <link rel="preconnect" href="https://fonts.googleapis.com">
21
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
22
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
23
+ <style>
24
+ :root {
25
+ --bg: #f0f0f8;
26
+ --bg-hero: linear-gradient(180deg, #e8e8f4 0%, #f0f0f8 100%);
27
+ --bg-card: #ffffff;
28
+ --border: #e0e0ec;
29
+ --text: #1a1a2e;
30
+ --text-dim: #6b6b80;
31
+ --accent: #7c3aed;
32
+ --accent-light: #a78bfa;
33
+ --accent-soft: #7c3aed12;
34
+ --green: #10b981;
35
+ }
36
+
37
+ * {
38
+ box-sizing: border-box;
39
+ margin: 0;
40
+ padding: 0;
41
+ }
42
+
43
+ body {
44
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
45
+ background: var(--bg);
46
+ color: var(--text);
47
+ min-height: 100vh;
48
+ line-height: 1.6;
49
+ }
50
+
51
+ .container {
52
+ max-width: 800px;
53
+ margin: 0 auto;
54
+ padding: 0 1.5rem;
55
+ }
56
+
57
+ /* Hero */
58
+ .hero {
59
+ background: var(--bg-hero);
60
+ padding: 5rem 0 4rem;
61
+ text-align: center;
62
+ }
63
+
64
+ .hero h1 {
65
+ font-size: 3rem;
66
+ font-weight: 800;
67
+ line-height: 1.15;
68
+ margin-bottom: 1.25rem;
69
+ color: var(--text);
70
+ letter-spacing: -0.02em;
71
+ }
72
+
73
+ .hero h1 .gradient {
74
+ background: linear-gradient(135deg, var(--accent) 0%, var(--accent-light) 100%);
75
+ -webkit-background-clip: text;
76
+ -webkit-text-fill-color: transparent;
77
+ background-clip: text;
78
+ }
79
+
80
+ .hero p {
81
+ color: var(--text-dim);
82
+ font-size: 1.125rem;
83
+ max-width: 500px;
84
+ margin: 0 auto 2.5rem;
85
+ }
86
+
87
+ .hero p strong {
88
+ color: var(--text);
89
+ }
90
+
91
+ /* Install Box */
92
+ .install-box {
93
+ max-width: 400px;
94
+ margin: 0 auto 2rem;
95
+ background: white;
96
+ border-radius: 12px;
97
+ padding: 1.25rem 1.75rem;
98
+ box-shadow: 0 4px 32px rgba(0, 0, 0, 0.08);
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: space-between;
102
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
103
+ font-size: 1.1rem;
104
+ border: 1px solid var(--border);
105
+ }
106
+
107
+ .install-box .prompt { color: var(--text-dim); }
108
+ .install-box .cmd { color: var(--accent); }
109
+ .install-box .pkg { color: var(--green); }
110
+
111
+ .copy-btn {
112
+ background: var(--bg);
113
+ border: 1px solid var(--border);
114
+ color: var(--text-dim);
115
+ padding: 0.5rem 0.875rem;
116
+ border-radius: 6px;
117
+ cursor: pointer;
118
+ font-size: 0.75rem;
119
+ font-weight: 500;
120
+ font-family: 'Inter', sans-serif;
121
+ transition: all 0.2s;
122
+ }
123
+
124
+ .copy-btn:hover {
125
+ background: var(--accent-soft);
126
+ border-color: var(--accent);
127
+ color: var(--accent);
128
+ }
129
+
130
+ /* Flow */
131
+ .flow {
132
+ padding: 3rem 0;
133
+ background: white;
134
+ }
135
+
136
+ .flow h2 {
137
+ text-align: center;
138
+ font-size: 1.5rem;
139
+ margin-bottom: 2rem;
140
+ }
141
+
142
+ .flow-steps {
143
+ display: flex;
144
+ justify-content: center;
145
+ gap: 1rem;
146
+ flex-wrap: wrap;
147
+ }
148
+
149
+ .flow-step {
150
+ background: var(--bg);
151
+ border: 1px solid var(--border);
152
+ border-radius: 12px;
153
+ padding: 1.5rem;
154
+ text-align: center;
155
+ flex: 1;
156
+ min-width: 200px;
157
+ max-width: 250px;
158
+ }
159
+
160
+ .flow-step .number {
161
+ width: 36px;
162
+ height: 36px;
163
+ background: var(--accent);
164
+ color: white;
165
+ border-radius: 50%;
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ margin: 0 auto 1rem;
170
+ font-weight: 700;
171
+ }
172
+
173
+ .flow-step h3 {
174
+ font-size: 1rem;
175
+ margin-bottom: 0.5rem;
176
+ }
177
+
178
+ .flow-step p {
179
+ font-size: 0.875rem;
180
+ color: var(--text-dim);
181
+ }
182
+
183
+ .flow-step code {
184
+ display: block;
185
+ margin-top: 0.75rem;
186
+ background: white;
187
+ border: 1px solid var(--border);
188
+ padding: 0.5rem;
189
+ border-radius: 6px;
190
+ font-size: 0.75rem;
191
+ color: var(--green);
192
+ }
193
+
194
+ /* Output Preview */
195
+ .output {
196
+ padding: 3rem 0;
197
+ }
198
+
199
+ .output h2 {
200
+ text-align: center;
201
+ font-size: 1.5rem;
202
+ margin-bottom: 1.5rem;
203
+ }
204
+
205
+ .output pre {
206
+ background: #1a1a2e;
207
+ color: #e0e0ec;
208
+ padding: 1.5rem;
209
+ border-radius: 12px;
210
+ overflow-x: auto;
211
+ font-size: 0.8rem;
212
+ line-height: 1.5;
213
+ }
214
+
215
+ .output pre .key { color: #a78bfa; }
216
+ .output pre .str { color: #10b981; }
217
+
218
+ /* CTA */
219
+ .cta {
220
+ padding: 3rem 0;
221
+ background: white;
222
+ text-align: center;
223
+ border-top: 1px solid var(--border);
224
+ }
225
+
226
+ .cta h2 {
227
+ font-size: 1.5rem;
228
+ margin-bottom: 0.75rem;
229
+ }
230
+
231
+ .cta p {
232
+ color: var(--text-dim);
233
+ margin-bottom: 1.5rem;
234
+ }
235
+
236
+ .btn {
237
+ display: inline-flex;
238
+ align-items: center;
239
+ gap: 0.5rem;
240
+ padding: 0.9rem 1.75rem;
241
+ border-radius: 10px;
242
+ font-size: 0.9375rem;
243
+ font-weight: 600;
244
+ text-decoration: none;
245
+ transition: all 0.2s ease;
246
+ margin: 0 0.5rem;
247
+ }
248
+
249
+ .btn-primary {
250
+ background: var(--accent);
251
+ color: white;
252
+ box-shadow: 0 2px 8px rgba(124, 58, 237, 0.25);
253
+ }
254
+
255
+ .btn-primary:hover {
256
+ background: #6d28d9;
257
+ transform: translateY(-2px);
258
+ }
259
+
260
+ .btn-secondary {
261
+ background: white;
262
+ color: var(--text);
263
+ border: 1.5px solid var(--border);
264
+ }
265
+
266
+ .btn-secondary:hover {
267
+ border-color: var(--accent);
268
+ }
269
+
270
+ /* Footer */
271
+ footer {
272
+ padding: 2rem 0;
273
+ text-align: center;
274
+ color: var(--text-dim);
275
+ font-size: 0.875rem;
276
+ }
277
+
278
+ footer a {
279
+ color: var(--accent);
280
+ text-decoration: none;
281
+ }
282
+
283
+ footer a:hover {
284
+ text-decoration: underline;
285
+ }
286
+
287
+ @media (max-width: 768px) {
288
+ .hero h1 { font-size: 2rem; }
289
+ .install-box {
290
+ flex-direction: column;
291
+ gap: 1rem;
292
+ text-align: center;
293
+ }
294
+ .flow-steps { flex-direction: column; align-items: center; }
295
+ .flow-step { max-width: 100%; }
296
+ }
297
+ </style>
298
+ </head>
299
+ <body>
300
+ <!-- Hero -->
301
+ <section class="hero">
302
+ <div class="container">
303
+ <h1>Give Your Agent<br>an <span class="gradient">Identity</span></h1>
304
+ <p>Your AI agent can't prove who it is. <strong>Fix that in one command.</strong> Generate cryptographic keys with did:nostr.</p>
305
+
306
+ <div class="install-box">
307
+ <div>
308
+ <span class="prompt">$</span>
309
+ <span class="cmd">npm</span> init
310
+ <span class="pkg">agent</span>
311
+ </div>
312
+ <button class="copy-btn" onclick="copyInstall()">Copy</button>
313
+ </div>
314
+ </div>
315
+ </section>
316
+
317
+ <!-- Flow -->
318
+ <section class="flow">
319
+ <div class="container">
320
+ <h2>From Zero to Trusted Agent</h2>
321
+ <div class="flow-steps">
322
+ <div class="flow-step">
323
+ <div class="number">1</div>
324
+ <h3>Create Identity</h3>
325
+ <p>Generate did:nostr keypair</p>
326
+ <code>npm init agent</code>
327
+ </div>
328
+ <div class="flow-step">
329
+ <div class="number">2</div>
330
+ <h3>Sign Your Work</h3>
331
+ <p>Cryptographically sign skills</p>
332
+ <code>aam skill sign</code>
333
+ </div>
334
+ <div class="flow-step">
335
+ <div class="number">3</div>
336
+ <h3>Build Trust</h3>
337
+ <p>Others verify your identity</p>
338
+ <code>aam skill verify</code>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ </section>
343
+
344
+ <!-- Output Preview -->
345
+ <section class="output">
346
+ <div class="container">
347
+ <h2>What You Get</h2>
348
+ <pre>{
349
+ <span class="key">"id"</span>: <span class="str">"did:nostr:73ca7fc7184ceb1095183663b1d9b2d3..."</span>,
350
+ <span class="key">"type"</span>: <span class="str">"DIDNostr"</span>,
351
+ <span class="key">"verificationMethod"</span>: [{
352
+ <span class="key">"type"</span>: <span class="str">"Multikey"</span>,
353
+ <span class="key">"publicKeyMultibase"</span>: <span class="str">"fe70102..."</span>
354
+ }],
355
+ <span class="key">"authentication"</span>: [<span class="str">"#key1"</span>]
356
+ }</pre>
357
+ </div>
358
+ </section>
359
+
360
+ <!-- CTA -->
361
+ <section class="cta">
362
+ <div class="container">
363
+ <h2>Ready to Sign Your Agents?</h2>
364
+ <p>Use your identity with aam to create safe, trusted AI agents.</p>
365
+ <a href="https://aam.wtf" class="btn btn-primary">Get Started with AAM</a>
366
+ <a href="https://github.com/melvincarvalho/create-agent" class="btn btn-secondary">View on GitHub</a>
367
+ </div>
368
+ </section>
369
+
370
+ <!-- Footer -->
371
+ <footer>
372
+ <div class="container">
373
+ <p>
374
+ <strong>create-agent</strong> |
375
+ <a href="https://aam.wtf">aam.wtf</a> |
376
+ <a href="https://github.com/melvincarvalho/create-agent">GitHub</a> |
377
+ MIT License
378
+ </p>
379
+ </div>
380
+ </footer>
381
+
382
+ <script>
383
+ function copyInstall() {
384
+ navigator.clipboard.writeText('npm init agent');
385
+ const btn = document.querySelector('.copy-btn');
386
+ btn.textContent = 'Copied!';
387
+ setTimeout(() => btn.textContent = 'Copy', 2000);
388
+ }
389
+ </script>
390
+ </body>
391
+ </html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-agent",
3
3
  "type": "module",
4
- "version": "0.0.13",
4
+ "version": "0.0.15",
5
5
  "description": "create an agent",
6
6
  "scripts": {
7
7
  "test": "node --test"