@ilucky21c/ajp-cli 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/index.js +45 -28
  2. package/package.json +18 -4
package/index.js CHANGED
@@ -2,18 +2,22 @@
2
2
  /**
3
3
  * ajp-cli — Agent Job Protocol CLI
4
4
  *
5
- * Requires Provenance identity (PROVENANCE_ID + PROVENANCE_PRIVATE_KEY).
6
- * For identity setup: npx provenance keygen / npx provenance register
5
+ * Requires a Provenance identity (PROVENANCE_ID + PROVENANCE_PRIVATE_KEY).
6
+ * For identity setup: npx provenance-protocol keygen, then publish a signed
7
+ * declaration (npx provenance-protocol sign).
7
8
  *
8
9
  * Usage:
9
10
  * ajp hire <provenance_id> --instruction <text> [--budget <usd>] [--timeout <s>]
10
11
  * ajp jobs <job_id> --endpoint <url>
11
12
  */
12
13
 
13
- import { createPrivateKey, sign as nodeSign, randomBytes } from 'crypto';
14
+ import { randomBytes } from 'crypto';
15
+ import { createRequire } from 'module';
16
+ import YAML from 'yaml';
17
+ import { signWithKey, declarationEndpointResolver, indexEndpointResolver } from 'ajp-protocol';
18
+ import { Provenance } from 'provenance-protocol/index-client';
14
19
 
15
- const API = process.env.PROVENANCE_API_URL || 'https://provenance-web-mu.vercel.app';
16
- const VERSION = '0.1.0';
20
+ const VERSION = createRequire(import.meta.url)('./package.json').version;
17
21
 
18
22
  // ── Colours ───────────────────────────────────────────────────────────────────
19
23
 
@@ -50,11 +54,16 @@ function generateJobId() {
50
54
  return `job_${Date.now().toString(36)}${randomBytes(6).toString('hex')}`;
51
55
  }
52
56
 
53
- function signOffer(offer, privateKeyBase64) {
54
- const { signature: _, ...rest } = offer;
55
- const canonical = JSON.stringify(rest, Object.keys(rest).sort());
56
- const key = createPrivateKey({ key: Buffer.from(privateKeyBase64, 'base64'), format: 'der', type: 'pkcs8' });
57
- return `ed25519:${nodeSign(null, Buffer.from(canonical, 'utf8'), key).toString('base64')}`;
57
+ // Where to send the job. By default, read from the recipient's own signed
58
+ // declaration — no index involved. --endpoint skips resolution; --index asks
59
+ // an index you name instead.
60
+ async function resolveEndpoint(targetId, args) {
61
+ if (typeof args.endpoint === 'string') return args.endpoint.replace(/\/$/, '');
62
+ const index = args.index || process.env.PROVENANCE_INDEX_URL;
63
+ const resolver = typeof index === 'string'
64
+ ? indexEndpointResolver(new Provenance({ apiUrl: index }))
65
+ : declarationEndpointResolver({ parseDeclaration: (text) => YAML.parse(text) });
66
+ return resolver(targetId);
58
67
  }
59
68
 
60
69
  // ── Commands ──────────────────────────────────────────────────────────────────
@@ -69,20 +78,20 @@ async function cmdHire(args) {
69
78
 
70
79
  if (!targetId) { console.error(err('Usage: ajp hire <provenance_id> --instruction <text>')); process.exit(1); }
71
80
  if (!instruction) { console.error(err('--instruction required')); process.exit(1); }
72
- if (!privateKey) { console.error(err('PROVENANCE_PRIVATE_KEY not set. Run: npx provenance keygen')); process.exit(1); }
73
- if (!provenanceId) { console.error(err('PROVENANCE_ID not set. Run: npx provenance register')); process.exit(1); }
81
+ if (!privateKey) { console.error(err('PROVENANCE_PRIVATE_KEY not set. Run: npx provenance-protocol keygen')); process.exit(1); }
82
+ if (!provenanceId) { console.error(err('PROVENANCE_ID not set — your agent\'s provenance id')); process.exit(1); }
74
83
 
75
84
  console.log(`\n${amb('Hiring')} ${hi(targetId)}...\n`);
76
85
 
77
- // Resolve endpoint
78
86
  process.stdout.write(dim(' Resolving endpoint...'));
79
- const agentRes = await fetch(`${API}/api/agent/${targetId.replace('provenance:', '').replace(':', '/')}`);
80
- const agentData = await agentRes.json();
81
- if (!agentData?.ajp?.endpoint) {
82
- console.log('\n' + err('Agent has no AJP endpoint. Ask them to add ajp.endpoint to PROVENANCE.yml.'));
83
- process.exit(1);
87
+ let endpoint;
88
+ try {
89
+ endpoint = await resolveEndpoint(targetId, args);
90
+ } catch (e) {
91
+ console.log('\n' + err(e.message));
92
+ console.log(dim(' Nothing was sent. Pass --endpoint <url> if you know where the agent accepts jobs.'));
93
+ process.exit(2);
84
94
  }
85
- const endpoint = agentData.ajp.endpoint.replace(/\/$/, '');
86
95
  console.log(` ${c.green}${endpoint}${c.reset}`);
87
96
 
88
97
  // Build and sign offer
@@ -92,7 +101,10 @@ async function cmdHire(args) {
92
101
 
93
102
  const offer = {
94
103
  ajp: '0.1', job_id: jobId, parent_job_id: null,
95
- from: { type: 'orchestrator', id: null, provenance_id: provenanceId },
104
+ from: {
105
+ type: 'orchestrator', id: null, provenance_id: provenanceId,
106
+ declaration_url: args['declaration-url'] || process.env.PROVENANCE_DECLARATION_URL || null,
107
+ },
96
108
  to: { provenance_id: targetId },
97
109
  task: { type: 'task', instruction, input: {}, output_format: 'json' },
98
110
  context: { credentials: {}, memory: [], constraints: [] },
@@ -102,7 +114,7 @@ async function cmdHire(args) {
102
114
  expires_at: expiresAt.toISOString(),
103
115
  signature: '',
104
116
  };
105
- offer.signature = signOffer(offer, privateKey);
117
+ offer.signature = signWithKey(offer, privateKey);
106
118
 
107
119
  // Submit
108
120
  process.stdout.write(dim(' Submitting job...'));
@@ -191,26 +203,31 @@ ${amb('Commands:')}
191
203
  [--timeout <seconds>] Max wait time (default: 120)
192
204
  [--from-id <id>] Your Provenance ID (default: $PROVENANCE_ID)
193
205
  [--private-key <key>] Your private key (default: $PROVENANCE_PRIVATE_KEY)
206
+ [--declaration-url <url>] Where your signed declaration is published
207
+ [--endpoint <url>] Send here instead of reading the recipient's declaration
208
+ [--index <url>] Resolve the recipient through this index instead
194
209
 
195
210
  ${hi('jobs')} <job_id> Check status of a job
196
211
  --endpoint <url> The agent's AJP endpoint URL
197
212
 
198
213
  ${amb('Environment variables:')}
199
- PROVENANCE_ID Your Provenance ID (set up with: npx provenance register)
200
- PROVENANCE_PRIVATE_KEY Your Ed25519 private key (set up with: npx provenance keygen)
201
- PROVENANCE_API_URL Override Provenance API base URL
214
+ PROVENANCE_ID Your provenance id
215
+ PROVENANCE_PRIVATE_KEY Your Ed25519 private key (npx provenance-protocol keygen)
216
+ PROVENANCE_DECLARATION_URL Where your signed declaration is published
217
+ PROVENANCE_INDEX_URL Resolve recipients through this index (optional)
202
218
 
203
219
  ${amb('Examples:')}
204
- ajp hire provenance:github:alice/summarizer \\
220
+ ajp hire provenance:domain:summarizer.example.com \\
205
221
  --instruction "Summarize https://arxiv.org/abs/2501.00001" \\
206
222
  --budget 0.50 --timeout 60
207
223
 
208
224
  ajp jobs job_m0abc123 --endpoint https://alice-agent.example.com/api/agent
209
225
 
210
226
  ${amb('Identity setup (first time):')}
211
- npx provenance keygen
212
- npx provenance register --id provenance:github:your-org/your-agent --url <url>
213
- ${dim('Then set PROVENANCE_ID and PROVENANCE_PRIVATE_KEY in your environment.')}
227
+ npx provenance-protocol keygen
228
+ npx provenance-protocol sign PROVENANCE.yml
229
+ ${dim('Publish the declaration where your provenance id says, then set')}
230
+ ${dim('PROVENANCE_ID and PROVENANCE_PRIVATE_KEY in your environment.')}
214
231
  `);
215
232
  }
216
233
 
package/package.json CHANGED
@@ -1,17 +1,31 @@
1
1
  {
2
2
  "name": "@ilucky21c/ajp-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "CLI for the Agent Job Protocol — hire agents and check job status from the terminal",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ajp": "./index.js"
8
8
  },
9
- "engines": { "node": ">=18" },
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
10
12
  "repository": {
11
13
  "type": "git",
12
14
  "url": "git+https://github.com/ilucky21c/ajp-protocol.git",
13
15
  "directory": "cli"
14
16
  },
15
- "keywords": ["ajp", "agent-job-protocol", "provenance", "ai", "agents", "cli"],
16
- "license": "MIT"
17
+ "keywords": [
18
+ "ajp",
19
+ "agent-job-protocol",
20
+ "provenance",
21
+ "ai",
22
+ "agents",
23
+ "cli"
24
+ ],
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "ajp-protocol": "^0.3.0",
28
+ "provenance-protocol": "^0.6.0",
29
+ "yaml": "^2.9.1"
30
+ }
17
31
  }