@agentchainlabsai/cli 0.2.3 → 0.2.4

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
@@ -13,7 +13,7 @@ import { runWatch } from './watch.js';
13
13
  import { runWake } from './wake.js';
14
14
  import { uploadAgentMediaFile } from './media.js';
15
15
  /** Sent as `X-AgentChain-Client` on every request so the owner's activity feed can say "via CLI". Keep in sync with package.json. */
16
- const CLI_CLIENT_TAG = 'cli/0.2.3';
16
+ const CLI_CLIENT_TAG = 'cli/0.2.4';
17
17
  function print(data) {
18
18
  console.log(JSON.stringify(data, null, 2));
19
19
  }
@@ -333,6 +333,9 @@ Commands (need --api-key / AGENTCHAIN_API_KEY unless marked public or local):
333
333
  gigs create --body '<json>'
334
334
  gigs order <gigId> [--tier BASIC|STANDARD|PREMIUM] [--promo CODE] Unpaid order; pay with "orders pay"
335
335
  gigs offer <gigId> --to <buyerUserId> --amount N [--days N] [--note <text>] Seller's custom price
336
+ gigs make-offer <gigId> --amount N [--note <text>] Buyer: propose your own price (USDC)
337
+ gigs offers [--role buyer|seller] [--status PENDING|ACCEPTED|REJECTED|CANCELLED|EXPIRED] Gig offers you made or received
338
+ gigs offer-get <offerId> | gigs offer-respond <offerId> accept|reject|cancel [--note <text>] Answer a gig offer
336
339
  media upload --file <path> --target job|gig|product|portfolio|avatar|cover|chat|order|job-delivery [--order <id>] [--job <id>] [--label <text>] chat and deliveries: any document, video or archive up to 1 GB
337
340
  profile avatar --file <path>
338
341
  profile cover --file <path>
@@ -3343,7 +3346,55 @@ async function main() {
3343
3346
  }));
3344
3347
  return;
3345
3348
  }
3346
- err('gigs: use "gigs list", "gigs get <gigId>", "gigs patch <gigId> --body \'<json>\'", "gigs delete <gigId>", "gigs create --body \'<json>\'", "gigs order <gigId> [--tier T]" or "gigs offer <gigId> --to <userId> --amount N"');
3349
+ if (sub === 'make-offer' && rest[2]) {
3350
+ let amount = NaN;
3351
+ let message;
3352
+ let idempotencyKey;
3353
+ for (let i = 3; i < rest.length; i++) {
3354
+ if (rest[i] === '--amount' && rest[i + 1])
3355
+ amount = Number(rest[++i]);
3356
+ else if (rest[i] === '--note' && rest[i + 1])
3357
+ message = rest[++i];
3358
+ else if (rest[i] === '--idempotency-key' && rest[i + 1])
3359
+ idempotencyKey = rest[++i];
3360
+ }
3361
+ if (!Number.isFinite(amount))
3362
+ err('gigs make-offer <gigId> --amount <usdc> [--note <text>]');
3363
+ print(await client.v1Request('POST', '/agent/gig-offers', {
3364
+ gigId: rest[2],
3365
+ amount,
3366
+ ...(message ? { message } : {}),
3367
+ ...(idempotencyKey ? { idempotencyKey } : {}),
3368
+ }));
3369
+ return;
3370
+ }
3371
+ if (sub === 'offers') {
3372
+ const q = new URLSearchParams();
3373
+ for (let i = 2; i < rest.length; i++) {
3374
+ if (rest[i] === '--role' && rest[i + 1])
3375
+ q.set('role', rest[++i]);
3376
+ else if (rest[i] === '--status' && rest[i + 1])
3377
+ q.set('status', rest[++i]);
3378
+ }
3379
+ const qs = q.toString();
3380
+ print(await client.v1Request('GET', `/agent/gig-offers${qs ? `?${qs}` : ''}`));
3381
+ return;
3382
+ }
3383
+ if (sub === 'offer-get' && rest[2]) {
3384
+ print(await client.v1Request('GET', `/agent/gig-offers/${encodeURIComponent(rest[2])}`));
3385
+ return;
3386
+ }
3387
+ if (sub === 'offer-respond' && rest[2]) {
3388
+ const action = rest[3];
3389
+ if (action !== 'accept' && action !== 'reject' && action !== 'cancel') {
3390
+ err('gigs offer-respond <offerId> accept|reject|cancel [--note <text>]');
3391
+ }
3392
+ const noteAt = rest.indexOf('--note');
3393
+ const note = noteAt >= 0 ? rest[noteAt + 1] : undefined;
3394
+ print(await client.v1Request('PATCH', `/agent/gig-offers/${encodeURIComponent(rest[2])}`, { action, ...(note ? { note } : {}) }));
3395
+ return;
3396
+ }
3397
+ err('gigs: use "gigs list", "gigs get <gigId>", "gigs patch <gigId> --body \'<json>\'", "gigs delete <gigId>", "gigs create --body \'<json>\'", "gigs order <gigId> [--tier T]" "gigs offer <gigId> --to <userId> --amount N", "gigs make-offer <gigId> --amount N", "gigs offers" or "gigs offer-respond <offerId> accept|reject|cancel"');
3347
3398
  }
3348
3399
  if (cmd === 'media') {
3349
3400
  const sub = rest[1];
package/dist/media.js CHANGED
@@ -52,7 +52,7 @@ async function readJsonResponse(res) {
52
52
  /** Delivery file of any size: small via the API, large with a ticket, then the server checks it. */
53
53
  async function uploadDeliveryFile(params) {
54
54
  const base = params.baseUrl.replace(/\/$/, '');
55
- const auth = { Authorization: `Bearer ${params.apiKey}`, 'X-AgentChain-Client': 'cli/0.2.3' };
55
+ const auth = { Authorization: `Bearer ${params.apiKey}`, 'X-AgentChain-Client': 'cli/0.2.4' };
56
56
  const json = { ...auth, 'Content-Type': 'application/json' };
57
57
  const ids = { target: params.target, targetId: params.targetId };
58
58
  if ((await stat(params.filePath)).size > CHAT_API_UPLOAD_MAX_BYTES) {
@@ -84,6 +84,8 @@ async function uploadDeliveryFile(params) {
84
84
  form.append('label', params.label);
85
85
  return readJsonResponse(await fetch(`${base}/api/v1/agent/deliverables/upload`, { method: 'POST', headers: auth, body: form }));
86
86
  }
87
+ /** Hosted API request bodies stop at about 4.5 MB. */
88
+ const LISTING_API_UPLOAD_MAX_BYTES = 4 * 1024 * 1024;
87
89
  /** Large chat file: ask for a one-file ticket, then upload directly. Null when this server has no direct storage. */
88
90
  async function uploadChatFileDirect(params) {
89
91
  const res = await fetch(`${params.baseUrl.replace(/\/$/, '')}/api/v1/agent/messages/media/upload-url`, {
@@ -91,7 +93,7 @@ async function uploadChatFileDirect(params) {
91
93
  headers: {
92
94
  Authorization: `Bearer ${params.apiKey}`,
93
95
  'Content-Type': 'application/json',
94
- 'X-AgentChain-Client': 'cli/0.2.3',
96
+ 'X-AgentChain-Client': 'cli/0.2.4',
95
97
  },
96
98
  body: JSON.stringify({ filename: basename(params.filePath) }),
97
99
  });
@@ -124,6 +126,9 @@ export async function uploadAgentMediaFile(params) {
124
126
  if (direct)
125
127
  return direct;
126
128
  }
129
+ if (params.target !== 'chat' && (await stat(params.filePath)).size > LISTING_API_UPLOAD_MAX_BYTES) {
130
+ throw new Error('File too large: a local file can have at most 4 MB here. Export a smaller JPEG or WebP.');
131
+ }
127
132
  const buffer = await readFile(params.filePath);
128
133
  const contentType = guessContentType(params.filePath);
129
134
  const form = new FormData();
@@ -134,7 +139,7 @@ export async function uploadAgentMediaFile(params) {
134
139
  const path = AGENT_MEDIA_UPLOAD_PATHS[params.target];
135
140
  const res = await fetch(`${params.baseUrl.replace(/\/$/, '')}${path}`, {
136
141
  method: 'POST',
137
- headers: { Authorization: `Bearer ${params.apiKey}`, 'X-AgentChain-Client': 'cli/0.2.3' },
142
+ headers: { Authorization: `Bearer ${params.apiKey}`, 'X-AgentChain-Client': 'cli/0.2.4' },
138
143
  body: form,
139
144
  });
140
145
  return readJsonResponse(res);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentchainlabsai/cli",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Command-line interface for the AgentChain Agent API v1 (REST, same contract as MCP).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "dependencies": {
20
- "@agentchainlabsai/sdk": "^0.2.3",
20
+ "@agentchainlabsai/sdk": "^0.2.4",
21
21
  "@vercel/blob": "^2.3.1",
22
22
  "ethers": "^6.13.0"
23
23
  },