@agent-wire/terminal 1.7.6 → 1.7.9
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/README.md +492 -403
- package/dist/api-token.d.ts +7 -0
- package/dist/api-token.js +42 -0
- package/dist/api-token.js.map +1 -0
- package/dist/api.d.ts +84 -21
- package/dist/api.js +179 -55
- package/dist/api.js.map +1 -1
- package/dist/cli-projection.d.ts +8 -0
- package/dist/cli-projection.js +139 -0
- package/dist/cli-projection.js.map +1 -0
- package/dist/cli.js +62 -961
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +4 -1
- package/dist/config.js +20 -9
- package/dist/config.js.map +1 -1
- package/dist/contracts/credit-amount.d.ts +19 -0
- package/dist/contracts/credit-amount.js +87 -0
- package/dist/contracts/credit-amount.js.map +1 -0
- package/dist/local-pull.js +1 -1
- package/dist/local-pull.js.map +1 -1
- package/dist/mcp-server.js +258 -133
- package/dist/mcp-server.js.map +1 -1
- package/dist/response-shaper.js +54 -14
- package/dist/response-shaper.js.map +1 -1
- package/dist/resume.d.ts +7 -0
- package/dist/resume.js +15 -0
- package/dist/resume.js.map +1 -0
- package/dist/sync/paginate.d.ts +2 -16
- package/dist/sync/paginate.js +2 -33
- package/dist/sync/paginate.js.map +1 -1
- package/dist/tool-projection.d.ts +10 -0
- package/dist/tool-projection.js +54 -0
- package/dist/tool-projection.js.map +1 -1
- package/dist/wait-cli.js +46 -21
- package/dist/wait-cli.js.map +1 -1
- package/package.json +4 -2
package/dist/api.js
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
const normalizedUrlNotices = new Set();
|
|
2
|
+
export function normalizeWireApiUrl(value) {
|
|
3
|
+
const url = new URL(value);
|
|
4
|
+
if (url.pathname === '/' || !url.pathname) {
|
|
5
|
+
url.pathname = '/api/v1';
|
|
6
|
+
if (!normalizedUrlNotices.has(value)) {
|
|
7
|
+
console.error('[wire] WIRE_API_URL has no API path; appended /api/v1.');
|
|
8
|
+
normalizedUrlNotices.add(value);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return url.toString().replace(/\/+$/, '');
|
|
12
|
+
}
|
|
2
13
|
const DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS = 600_000;
|
|
3
14
|
const TRUSTED_CHAIN_CLIENT_GRACE_MS = 5_000;
|
|
4
15
|
const DEFAULT_WIRE_SYNC_TIMEOUT_MS = DEFAULT_TRUSTED_CHAIN_TIMEOUT_MS + TRUSTED_CHAIN_CLIENT_GRACE_MS;
|
|
5
16
|
const DEFAULT_ACTION_QUOTE_TIMEOUT_MS = 30_000;
|
|
17
|
+
export class RegistrationError extends Error {
|
|
18
|
+
status;
|
|
19
|
+
constructor(status, message) {
|
|
20
|
+
super(`Registration failed (${status}): ${message}`);
|
|
21
|
+
this.status = status;
|
|
22
|
+
this.name = 'RegistrationError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
6
25
|
function legacyActionRequestOptions(params) {
|
|
7
26
|
if (params.mode === 'quote') {
|
|
8
27
|
return { body: params, timeoutMs: DEFAULT_ACTION_QUOTE_TIMEOUT_MS };
|
|
@@ -13,6 +32,14 @@ function legacyActionRequestOptions(params) {
|
|
|
13
32
|
timeoutMs: timeoutMs + TRUSTED_CHAIN_CLIENT_GRACE_MS,
|
|
14
33
|
};
|
|
15
34
|
}
|
|
35
|
+
function meshQuery(params, extra = {}) {
|
|
36
|
+
const query = new URLSearchParams(extra);
|
|
37
|
+
if (params.scope)
|
|
38
|
+
query.set('scope', params.scope);
|
|
39
|
+
if (params.circle_id)
|
|
40
|
+
query.set('circle_id', params.circle_id);
|
|
41
|
+
return query.size ? `?${query}` : '';
|
|
42
|
+
}
|
|
16
43
|
const DEFAULT_WAIT_TIMEOUT_SECONDS = 30;
|
|
17
44
|
// Raised from 1800 (30m): the SSE event stream is server-side UNCAPPED + 30s-keepalived, so a long
|
|
18
45
|
// client park is just a client-side deadline, not an infra limit. 86400 = 24h finite ceiling.
|
|
@@ -69,7 +96,7 @@ function appendWaitParams(url, params) {
|
|
|
69
96
|
url.searchParams.set(key, String(value));
|
|
70
97
|
}
|
|
71
98
|
}
|
|
72
|
-
function normalizeHelpTopic(topic) {
|
|
99
|
+
export function normalizeHelpTopic(topic) {
|
|
73
100
|
return (topic || '')
|
|
74
101
|
.trim()
|
|
75
102
|
.replace(/^https?:\/\/[^/]+\/api\/v1\/help\/?/i, '')
|
|
@@ -130,7 +157,25 @@ function parseSseBlock(block) {
|
|
|
130
157
|
return { event, data: rawData };
|
|
131
158
|
}
|
|
132
159
|
}
|
|
160
|
+
/** Keep actionable server refusals intact across MCP and terminal transports. */
|
|
161
|
+
export class WireApiRefusal extends Error {
|
|
162
|
+
status;
|
|
163
|
+
body;
|
|
164
|
+
constructor(status, body) {
|
|
165
|
+
super(JSON.stringify(body));
|
|
166
|
+
this.status = status;
|
|
167
|
+
this.body = body;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
133
170
|
export class WireAPI {
|
|
171
|
+
httpFetch;
|
|
172
|
+
async claims(params) {
|
|
173
|
+
const { action, claim_id } = params;
|
|
174
|
+
if (action === 'get' || action === 'list') {
|
|
175
|
+
return this.request('GET', '/wire/claims' + (claim_id ? `?claim_id=${encodeURIComponent(String(claim_id))}` : ''));
|
|
176
|
+
}
|
|
177
|
+
return this.request('POST', '/wire/claims', params, 120_000);
|
|
178
|
+
}
|
|
134
179
|
baseUrl;
|
|
135
180
|
token;
|
|
136
181
|
nodeId;
|
|
@@ -139,8 +184,9 @@ export class WireAPI {
|
|
|
139
184
|
localNodeEnabled;
|
|
140
185
|
localNodeToken;
|
|
141
186
|
localContributionRouteStatus;
|
|
142
|
-
constructor(config, threadId) {
|
|
143
|
-
this.
|
|
187
|
+
constructor(config, threadId, httpFetch) {
|
|
188
|
+
this.httpFetch = httpFetch;
|
|
189
|
+
this.baseUrl = normalizeWireApiUrl(config.apiUrl);
|
|
144
190
|
this.token = config.apiToken;
|
|
145
191
|
this.nodeId = config.nodeId;
|
|
146
192
|
this.threadId = threadId || null;
|
|
@@ -162,7 +208,7 @@ export class WireAPI {
|
|
|
162
208
|
if (this.threadId) {
|
|
163
209
|
headers['X-Wire-Thread'] = this.threadId;
|
|
164
210
|
}
|
|
165
|
-
const res = await fetch(url, {
|
|
211
|
+
const res = await (this.httpFetch ?? fetch)(url, {
|
|
166
212
|
method,
|
|
167
213
|
headers,
|
|
168
214
|
body: body ? JSON.stringify(body) : undefined,
|
|
@@ -170,6 +216,8 @@ export class WireAPI {
|
|
|
170
216
|
});
|
|
171
217
|
if (!res.ok) {
|
|
172
218
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
219
|
+
if (err.code === 'confirm_original')
|
|
220
|
+
throw new WireApiRefusal(res.status, err);
|
|
173
221
|
throw new Error(`API ${method} ${path} failed (${res.status}): ${err.error || res.statusText}`);
|
|
174
222
|
}
|
|
175
223
|
return res.json();
|
|
@@ -183,7 +231,7 @@ export class WireAPI {
|
|
|
183
231
|
if (this.threadId) {
|
|
184
232
|
headers['X-Wire-Thread'] = this.threadId;
|
|
185
233
|
}
|
|
186
|
-
const res = await fetch(url, {
|
|
234
|
+
const res = await (this.httpFetch ?? fetch)(url, {
|
|
187
235
|
method,
|
|
188
236
|
headers,
|
|
189
237
|
body: body ? JSON.stringify(body) : undefined,
|
|
@@ -222,7 +270,7 @@ export class WireAPI {
|
|
|
222
270
|
return response;
|
|
223
271
|
}
|
|
224
272
|
async getMe() {
|
|
225
|
-
return this.request('GET', '/me');
|
|
273
|
+
return this.unwrapEnvelopeOrPlain(await this.request('GET', '/me'));
|
|
226
274
|
}
|
|
227
275
|
async registerNode(name, capabilities) {
|
|
228
276
|
return this.request('POST', '/node/register', { name, capabilities });
|
|
@@ -234,7 +282,7 @@ export class WireAPI {
|
|
|
234
282
|
async registerAgent(params) {
|
|
235
283
|
// Registration doesn't require auth — use a raw fetch
|
|
236
284
|
const url = `${this.baseUrl}/register`;
|
|
237
|
-
const res = await fetch(url, {
|
|
285
|
+
const res = await (this.httpFetch ?? fetch)(url, {
|
|
238
286
|
method: 'POST',
|
|
239
287
|
headers: { 'Content-Type': 'application/json' },
|
|
240
288
|
body: JSON.stringify(params),
|
|
@@ -242,7 +290,7 @@ export class WireAPI {
|
|
|
242
290
|
});
|
|
243
291
|
if (!res.ok) {
|
|
244
292
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
245
|
-
throw new
|
|
293
|
+
throw new RegistrationError(res.status, err.error || res.statusText);
|
|
246
294
|
}
|
|
247
295
|
// Server wraps response in wireEnvelope: { data: { ... }, mesh, fleet, ... }
|
|
248
296
|
const envelope = await res.json();
|
|
@@ -263,21 +311,10 @@ export class WireAPI {
|
|
|
263
311
|
}
|
|
264
312
|
async query(params) {
|
|
265
313
|
const qs = new URLSearchParams();
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (params.offset !== undefined)
|
|
271
|
-
qs.set('offset', String(params.offset));
|
|
272
|
-
qs.set('sort', params.sort || 'recency');
|
|
273
|
-
if (params.watchlist)
|
|
274
|
-
qs.set('watchlist', 'true');
|
|
275
|
-
if (params.list)
|
|
276
|
-
qs.set('list', params.list);
|
|
277
|
-
if (params.changed_only)
|
|
278
|
-
qs.set('changed_only', 'true');
|
|
279
|
-
if (params.price_below !== undefined)
|
|
280
|
-
qs.set('price_below', String(params.price_below));
|
|
314
|
+
for (const [key, value] of Object.entries({ domain: 'all', sort: 'recency', ...params })) {
|
|
315
|
+
if (value !== undefined && value !== null)
|
|
316
|
+
qs.set(key, String(value));
|
|
317
|
+
}
|
|
281
318
|
return this.request('GET', `/wire/query?${qs.toString()}`);
|
|
282
319
|
}
|
|
283
320
|
async help(params = {}) {
|
|
@@ -337,6 +374,8 @@ export class WireAPI {
|
|
|
337
374
|
return results;
|
|
338
375
|
}
|
|
339
376
|
async browse(params) {
|
|
377
|
+
if (params.cursor && (params.item_id || params.entity))
|
|
378
|
+
throw new Error('cursor applies to item-list browsing; omit item_id/entity.');
|
|
340
379
|
if (params.item_id) {
|
|
341
380
|
if (params.include_definition) {
|
|
342
381
|
const qs = new URLSearchParams({ mode: 'inspect', include_definition: 'true' });
|
|
@@ -354,10 +393,16 @@ export class WireAPI {
|
|
|
354
393
|
qs.set('arc', params.arc);
|
|
355
394
|
return this.request('GET', `/wire/entities?${qs.toString()}`);
|
|
356
395
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
396
|
+
const qs = new URLSearchParams();
|
|
397
|
+
if (params.arc)
|
|
398
|
+
qs.set('arc', params.arc);
|
|
399
|
+
if (params.cursor)
|
|
400
|
+
qs.set('cursor', params.cursor);
|
|
401
|
+
if (params.limit !== undefined)
|
|
402
|
+
qs.set('limit', String(params.limit));
|
|
403
|
+
if (params.offset !== undefined)
|
|
404
|
+
qs.set('offset', String(params.offset));
|
|
405
|
+
return this.request('GET', `/wire/items${qs.size ? '?' + qs : ''}`);
|
|
361
406
|
}
|
|
362
407
|
async flag(params) {
|
|
363
408
|
return this.request('POST', '/flag', params);
|
|
@@ -411,7 +456,7 @@ export class WireAPI {
|
|
|
411
456
|
if (this.localContributionRouteStatus)
|
|
412
457
|
return this.localContributionRouteStatus;
|
|
413
458
|
try {
|
|
414
|
-
const health = await fetch(`${this.localNodeUrl}/health`, {
|
|
459
|
+
const health = await (this.httpFetch ?? fetch)(`${this.localNodeUrl}/health`, {
|
|
415
460
|
method: 'GET',
|
|
416
461
|
signal: AbortSignal.timeout(2_000),
|
|
417
462
|
});
|
|
@@ -419,7 +464,7 @@ export class WireAPI {
|
|
|
419
464
|
this.localContributionRouteStatus = 'unavailable';
|
|
420
465
|
return this.localContributionRouteStatus;
|
|
421
466
|
}
|
|
422
|
-
const probe = await fetch(`${this.localNodeUrl}${localContributionReadPath('__wire_terminal_route_probe__')}`, {
|
|
467
|
+
const probe = await (this.httpFetch ?? fetch)(`${this.localNodeUrl}${localContributionReadPath('__wire_terminal_route_probe__')}`, {
|
|
423
468
|
method: 'GET',
|
|
424
469
|
headers: this.localHeaders(),
|
|
425
470
|
signal: AbortSignal.timeout(2_000),
|
|
@@ -453,7 +498,7 @@ export class WireAPI {
|
|
|
453
498
|
return null;
|
|
454
499
|
const path = localContributionReadPath(identifier);
|
|
455
500
|
try {
|
|
456
|
-
const res = await fetch(`${this.localNodeUrl}${path}`, {
|
|
501
|
+
const res = await (this.httpFetch ?? fetch)(`${this.localNodeUrl}${path}`, {
|
|
457
502
|
method: 'GET',
|
|
458
503
|
headers: this.localHeaders(),
|
|
459
504
|
signal: AbortSignal.timeout(10_000),
|
|
@@ -476,6 +521,55 @@ export class WireAPI {
|
|
|
476
521
|
return null;
|
|
477
522
|
}
|
|
478
523
|
}
|
|
524
|
+
// ── Pyramid consume-head proxies (spec green playful/176/24) ───────────
|
|
525
|
+
// Thin HTTP proxies to the LOCAL AWN node's read-time pyramid routes
|
|
526
|
+
// (pyramid_routes mounted at /pyramid/*). They forward (slug, args) to the
|
|
527
|
+
// route and return the parsed JSON as-is. Auth: pass the local Bearer token
|
|
528
|
+
// (this.localHeaders()); the AWN routes enforce dual-auth + access-tier +
|
|
529
|
+
// nano-payment. Same local-node fetch pattern as tryLocalContributionRead.
|
|
530
|
+
/**
|
|
531
|
+
* Generic local-node fetch for the pyramid consume-head proxies. Returns the
|
|
532
|
+
* parsed JSON body on success, throws a descriptive error on non-2xx.
|
|
533
|
+
*/
|
|
534
|
+
async localNodeFetch(method, path, body, timeoutMs = 15_000) {
|
|
535
|
+
const res = await (this.httpFetch ?? fetch)(`${this.localNodeUrl}${path}`, {
|
|
536
|
+
method,
|
|
537
|
+
headers: this.localHeaders(),
|
|
538
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
539
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
540
|
+
});
|
|
541
|
+
if (!res.ok) {
|
|
542
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
543
|
+
const message = err.error || res.statusText;
|
|
544
|
+
throw new Error(`Local node ${method} ${path} failed (${res.status}): ${message}`);
|
|
545
|
+
}
|
|
546
|
+
return await res.json();
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* pyramid_map — GET /pyramid/{slug}/map.
|
|
550
|
+
* Apex synthesis + freshness counts + nav skeleton + unresolved gaps.
|
|
551
|
+
* Orient first at boot, then drill via pyramid_hydrate using nav node ids.
|
|
552
|
+
*/
|
|
553
|
+
async getPyramidMap(slug) {
|
|
554
|
+
return this.localNodeFetch('GET', `/pyramid/${encodeURIComponent(slug)}/map`);
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* pyramid_hydrate — GET /pyramid/{slug}/drill/{node_id}.
|
|
558
|
+
* Returns the DrillResult: full node content (headline/distilled/narrative
|
|
559
|
+
* via the node payload) plus children, evidence, gaps, web_edges, and
|
|
560
|
+
* question context. Pull one node/region after orienting via pyramid_map.
|
|
561
|
+
*/
|
|
562
|
+
async getPyramidDrill(slug, nodeId) {
|
|
563
|
+
return this.localNodeFetch('GET', `/pyramid/${encodeURIComponent(slug)}/drill/${encodeURIComponent(nodeId)}`);
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* pyramid_ask — POST /pyramid/{slug}/question body { question }.
|
|
567
|
+
* Cheap (<5s, no-LLM) mechanical retrieval over the existing pyramid;
|
|
568
|
+
* returns a markdown answer plus node-id citations / sources.
|
|
569
|
+
*/
|
|
570
|
+
async askPyramid(slug, question) {
|
|
571
|
+
return this.localNodeFetch('POST', `/pyramid/${encodeURIComponent(slug)}/question`, { question });
|
|
572
|
+
}
|
|
479
573
|
/**
|
|
480
574
|
* Rate a Wire item. Free. Must have accessed it first.
|
|
481
575
|
*/
|
|
@@ -523,7 +617,8 @@ export class WireAPI {
|
|
|
523
617
|
* Read a source document by ID.
|
|
524
618
|
*/
|
|
525
619
|
async readDocument(documentId) {
|
|
526
|
-
|
|
620
|
+
const quote = await this.request('GET', `/wire/documents/${documentId}`, undefined, 30_000);
|
|
621
|
+
return this.request('POST', `/wire/documents/${quote.id ?? quote.data?.id ?? documentId}`, { max_price: quote.current_price ?? quote.data?.current_price ?? 0 }, 30_000);
|
|
527
622
|
}
|
|
528
623
|
/**
|
|
529
624
|
* Find unscouted documents — unclaimed bounties.
|
|
@@ -596,44 +691,44 @@ export class WireAPI {
|
|
|
596
691
|
/**
|
|
597
692
|
* Get full mesh status: active threads, intents, blackboard.
|
|
598
693
|
*/
|
|
599
|
-
async meshStatus() {
|
|
600
|
-
return this.request('GET',
|
|
694
|
+
async meshStatus(scope = {}) {
|
|
695
|
+
return this.request('GET', `/mesh/status${meshQuery(scope)}`);
|
|
601
696
|
}
|
|
602
697
|
/**
|
|
603
698
|
* Read the shared blackboard.
|
|
604
699
|
*/
|
|
605
|
-
async meshBoardRead() {
|
|
606
|
-
return this.request('GET',
|
|
700
|
+
async meshBoardRead(scope = {}) {
|
|
701
|
+
return this.request('GET', `/mesh/board${meshQuery(scope)}`);
|
|
607
702
|
}
|
|
608
703
|
/**
|
|
609
704
|
* Write a key-value entry to the shared blackboard.
|
|
610
705
|
*/
|
|
611
|
-
async meshBoardWrite(key, value, ttl) {
|
|
612
|
-
return this.request('POST', '/mesh/board', { key, value, ttl });
|
|
706
|
+
async meshBoardWrite(key, value, ttl, scope = {}) {
|
|
707
|
+
return this.request('POST', '/mesh/board', { key, value, ttl, ...scope });
|
|
613
708
|
}
|
|
614
709
|
/**
|
|
615
710
|
* Delete a key from the shared blackboard.
|
|
616
711
|
*/
|
|
617
|
-
async meshBoardDelete(key) {
|
|
618
|
-
return this.request('DELETE', `/mesh/board
|
|
712
|
+
async meshBoardDelete(key, scope = {}) {
|
|
713
|
+
return this.request('DELETE', `/mesh/board${meshQuery(scope, { key })}`);
|
|
619
714
|
}
|
|
620
715
|
/**
|
|
621
716
|
* Declare an intent (what this thread is about to do).
|
|
622
717
|
*/
|
|
623
|
-
async meshDeclareIntent(action, domain, meta, ttl) {
|
|
624
|
-
return this.request('POST', '/mesh/intent', { action, domain, meta, ttl });
|
|
718
|
+
async meshDeclareIntent(action, domain, meta, ttl, scope = {}) {
|
|
719
|
+
return this.request('POST', '/mesh/intent', { action, domain, meta, ttl, ...scope });
|
|
625
720
|
}
|
|
626
721
|
/**
|
|
627
722
|
* Release (delete) an intent.
|
|
628
723
|
*/
|
|
629
|
-
async meshReleaseIntent(intentId) {
|
|
630
|
-
return this.request('DELETE', `/mesh/intent
|
|
724
|
+
async meshReleaseIntent(intentId, scope = {}) {
|
|
725
|
+
return this.request('DELETE', `/mesh/intent${meshQuery(scope, { intent_id: intentId })}`);
|
|
631
726
|
}
|
|
632
727
|
/**
|
|
633
728
|
* Get active intents for this agent.
|
|
634
729
|
*/
|
|
635
|
-
async meshGetIntents() {
|
|
636
|
-
return this.request('GET',
|
|
730
|
+
async meshGetIntents(scope = {}) {
|
|
731
|
+
return this.request('GET', `/mesh/intent${meshQuery(scope)}`);
|
|
637
732
|
}
|
|
638
733
|
// ── Prediction Markets ─────────────────────────────────────
|
|
639
734
|
/**
|
|
@@ -645,8 +740,8 @@ export class WireAPI {
|
|
|
645
740
|
* @param side - 'agree' or 'disagree'
|
|
646
741
|
* @param amount - Number of credits to stake (must be >= market's min_stake)
|
|
647
742
|
*/
|
|
648
|
-
async stakeMarket(contributionId, side, amount) {
|
|
649
|
-
return this.request('POST', `/wire/market/${contributionId}/stake`, { side, amount });
|
|
743
|
+
async stakeMarket(contributionId, side, amount, requestId = crypto.randomUUID()) {
|
|
744
|
+
return this.request('POST', `/wire/market/${contributionId}/stake`, { side, amount, request_id: requestId });
|
|
650
745
|
}
|
|
651
746
|
/**
|
|
652
747
|
* Get the current status of a prediction market, including pool sizes,
|
|
@@ -823,7 +918,7 @@ export class WireAPI {
|
|
|
823
918
|
if (this.threadId) {
|
|
824
919
|
headers['X-Wire-Thread'] = this.threadId;
|
|
825
920
|
}
|
|
826
|
-
const res = await fetch(url.toString(), {
|
|
921
|
+
const res = await (this.httpFetch ?? fetch)(url.toString(), {
|
|
827
922
|
method: 'GET',
|
|
828
923
|
headers,
|
|
829
924
|
signal: options.signal,
|
|
@@ -1011,7 +1106,7 @@ export class WireAPI {
|
|
|
1011
1106
|
async executeSupersession(targetId, newContributionId, allowTypeChange) {
|
|
1012
1107
|
// allow_type_change forwards to the REST endpoint (which already honors it) so a CROSS-TYPE
|
|
1013
1108
|
// supersession is reachable via the CLI/MCP, not only via raw REST (WI playful/170/177).
|
|
1014
|
-
const body = {
|
|
1109
|
+
const body = { contribution_id: newContributionId };
|
|
1015
1110
|
if (allowTypeChange)
|
|
1016
1111
|
body.allow_type_change = true;
|
|
1017
1112
|
return this.request('POST', `/wire/contributions/${encodeURIComponent(targetId)}/supersede`, body);
|
|
@@ -1020,6 +1115,9 @@ export class WireAPI {
|
|
|
1020
1115
|
async submitCorrection(targetId, correctionContributionId, depositAmount) {
|
|
1021
1116
|
return this.request('POST', `/wire/contributions/${encodeURIComponent(targetId)}/correct`, { correction_contribution_id: correctionContributionId, deposit_amount: depositAmount });
|
|
1022
1117
|
}
|
|
1118
|
+
async withdrawCorrection(correctionId) {
|
|
1119
|
+
return this.request('DELETE', `/wire/contributions/${encodeURIComponent(correctionId)}/endorse-correction`);
|
|
1120
|
+
}
|
|
1023
1121
|
async endorseCorrection(correctionId, depositAmount) {
|
|
1024
1122
|
return this.request('POST', `/wire/contributions/${encodeURIComponent(correctionId)}/endorse-correction`, { deposit_amount: depositAmount });
|
|
1025
1123
|
}
|
|
@@ -1187,7 +1285,7 @@ export class WireAPI {
|
|
|
1187
1285
|
if (this.threadId) {
|
|
1188
1286
|
headers['X-Wire-Thread'] = this.threadId;
|
|
1189
1287
|
}
|
|
1190
|
-
const res = await fetch(url, { method: 'GET', headers, signal: AbortSignal.timeout(30_000) });
|
|
1288
|
+
const res = await (this.httpFetch ?? fetch)(url, { method: 'GET', headers, signal: AbortSignal.timeout(30_000) });
|
|
1191
1289
|
if (!res.ok) {
|
|
1192
1290
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
1193
1291
|
throw new Error(`API GET /wire/documents/${documentId}/body failed (${res.status}): ${err.error || res.statusText}`);
|
|
@@ -1250,7 +1348,7 @@ export class WireAPI {
|
|
|
1250
1348
|
const body = { email, device_fingerprint: deviceFingerprint };
|
|
1251
1349
|
if (agentMessage)
|
|
1252
1350
|
body.agent_message = agentMessage;
|
|
1253
|
-
const res = await fetch(url, {
|
|
1351
|
+
const res = await (this.httpFetch ?? fetch)(url, {
|
|
1254
1352
|
method: 'POST',
|
|
1255
1353
|
headers: { 'Content-Type': 'application/json' },
|
|
1256
1354
|
body: JSON.stringify(body),
|
|
@@ -1266,7 +1364,7 @@ export class WireAPI {
|
|
|
1266
1364
|
async verifyDeviceCode(email, deviceFingerprint, code) {
|
|
1267
1365
|
// No auth required — raw fetch
|
|
1268
1366
|
const url = `${this.baseUrl}/wire/device-auth`;
|
|
1269
|
-
const res = await fetch(url, {
|
|
1367
|
+
const res = await (this.httpFetch ?? fetch)(url, {
|
|
1270
1368
|
method: 'PUT',
|
|
1271
1369
|
headers: { 'Content-Type': 'application/json' },
|
|
1272
1370
|
body: JSON.stringify({ email, device_fingerprint: deviceFingerprint, code }),
|
|
@@ -1284,7 +1382,7 @@ export class WireAPI {
|
|
|
1284
1382
|
url.searchParams.set('harness', harness);
|
|
1285
1383
|
if (hintName)
|
|
1286
1384
|
url.searchParams.set('hint_name', hintName);
|
|
1287
|
-
const res = await fetch(url.toString(), {
|
|
1385
|
+
const res = await (this.httpFetch ?? fetch)(url.toString(), {
|
|
1288
1386
|
headers: { 'X-Wire-Device-Secret': deviceSecret },
|
|
1289
1387
|
signal: AbortSignal.timeout(15_000),
|
|
1290
1388
|
});
|
|
@@ -1296,7 +1394,7 @@ export class WireAPI {
|
|
|
1296
1394
|
return json.data || json;
|
|
1297
1395
|
}
|
|
1298
1396
|
async resumeAgent(agentName, deviceSecret, nonce) {
|
|
1299
|
-
const res = await fetch(`${this.baseUrl}/wire/agent/resume`, {
|
|
1397
|
+
const res = await (this.httpFetch ?? fetch)(`${this.baseUrl}/wire/agent/resume`, {
|
|
1300
1398
|
method: 'POST',
|
|
1301
1399
|
headers: {
|
|
1302
1400
|
'Content-Type': 'application/json',
|
|
@@ -1313,4 +1411,30 @@ export class WireAPI {
|
|
|
1313
1411
|
return json.data || json;
|
|
1314
1412
|
}
|
|
1315
1413
|
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Paginate through all results from a fetch function.
|
|
1416
|
+
* Concatenates pages until a page returns fewer than pageSize items.
|
|
1417
|
+
*
|
|
1418
|
+
* @param fetchPage - Function that fetches a page (1-indexed page number, pageSize)
|
|
1419
|
+
* @param pageSize - Number of items per page (default 100)
|
|
1420
|
+
* @returns All items concatenated
|
|
1421
|
+
*/
|
|
1422
|
+
export async function paginateAll(fetchPage, pageSize = 100) {
|
|
1423
|
+
const allItems = [];
|
|
1424
|
+
let page = 1;
|
|
1425
|
+
const MAX_PAGES = 500; // 500 pages * 100 per page = 50k docs max
|
|
1426
|
+
while (true) {
|
|
1427
|
+
if (page > MAX_PAGES) {
|
|
1428
|
+
console.error(`[wire-sync] Pagination stopped at ${MAX_PAGES} pages (${allItems.length} items). If your corpus has more documents, contact support.`);
|
|
1429
|
+
break;
|
|
1430
|
+
}
|
|
1431
|
+
const items = await fetchPage(page, pageSize);
|
|
1432
|
+
allItems.push(...items);
|
|
1433
|
+
if (items.length < pageSize) {
|
|
1434
|
+
break;
|
|
1435
|
+
}
|
|
1436
|
+
page++;
|
|
1437
|
+
}
|
|
1438
|
+
return allItems;
|
|
1439
|
+
}
|
|
1316
1440
|
//# sourceMappingURL=api.js.map
|