@agent-wire/terminal 1.7.5 → 1.7.6
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/api.d.ts +3 -1
- package/dist/api.js +32 -11
- package/dist/api.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/mcp-server.js +73 -13
- package/dist/mcp-server.js.map +1 -1
- package/dist/sync/preview.d.ts +4 -1
- package/dist/sync/preview.js +16 -4
- package/dist/sync/preview.js.map +1 -1
- package/dist/wait-cli.js +14 -5
- package/dist/wait-cli.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
// migration window.
|
|
22
22
|
loadDeviceRecord, saveDeviceRecord, deleteDeviceRecord, loadAuthPending, saveAuthPending, deleteAuthPending, getStableDeviceFingerprint, hasAnyLocalIdentityForEmail, acquireIdentityLock, releaseIdentityLock, } from './identity.js';
|
|
23
23
|
import { acquireLock, releaseLock, isWorkerRunning } from './lockfile.js';
|
|
24
|
-
import { walkDirectory, computeDiff, pushFiles, pullFiles, parseManifest, serializeManifest, updateManifest, paginateAll, } from './sync/index.js';
|
|
24
|
+
import { walkDirectory, computeDiff, pushFiles, pullFiles, parseManifest, serializeManifest, updateManifest, paginateAll, generatePreviewJson, } from './sync/index.js';
|
|
25
25
|
import { WIRE_HELP_POINTER } from './help-pointer.js';
|
|
26
26
|
import { pullLocalSubscriptions } from './local-pull.js';
|
|
27
27
|
const SURFACE_REFRESH_TTL_MS = 60_000;
|
|
@@ -1591,9 +1591,21 @@ export async function startMcpServer(options) {
|
|
|
1591
1591
|
}
|
|
1592
1592
|
});
|
|
1593
1593
|
// ── Tool: wire_corpora (split from wire_discover — corpus browser) ──
|
|
1594
|
-
server.tool('wire_corpora', 'Browse source corpora. List
|
|
1594
|
+
server.tool('wire_corpora', 'Browse or create source corpora. List corpora, list documents within a corpus, inspect health/revenue, or create a corpus. FREE except writes require approval.', {
|
|
1595
|
+
action: z.enum(['list', 'documents', 'create', 'health', 'revenue', 'bulk_ingest']).optional().describe('Action to perform. Defaults to documents when slug is present, otherwise list.'),
|
|
1595
1596
|
slug: z.string().optional().describe('Corpus slug to browse. Omit to list all corpora.'),
|
|
1597
|
+
title: z.string().optional().describe('Corpus title for create.'),
|
|
1598
|
+
description: z.string().optional().describe('Corpus description for create.'),
|
|
1599
|
+
material_class: z.string().optional().describe('Corpus material class for create.'),
|
|
1596
1600
|
visibility: z.enum(['public', 'private', 'all']).optional().describe('Filter by visibility (default: public)'),
|
|
1601
|
+
themes: z.array(z.string()).optional().describe('Optional corpus themes for create.'),
|
|
1602
|
+
default_author_share: z.number().optional().describe('Default author revenue share for create.'),
|
|
1603
|
+
default_steward_share: z.number().optional().describe('Default steward revenue share for create.'),
|
|
1604
|
+
split_justification: z.string().optional().describe('Revenue split justification for create.'),
|
|
1605
|
+
provenance_note: z.string().optional().describe('Provenance note for create.'),
|
|
1606
|
+
manifest: z.record(z.unknown()).optional().describe('Optional corpus manifest for create.'),
|
|
1607
|
+
days: z.number().optional().describe('Revenue lookback days for revenue action.'),
|
|
1608
|
+
documents: z.array(z.record(z.unknown())).optional().describe('Documents for bulk_ingest action.'),
|
|
1597
1609
|
limit: z.number().optional().describe('Max results'),
|
|
1598
1610
|
offset: z.number().optional().describe('Pagination offset'),
|
|
1599
1611
|
}, async (params) => {
|
|
@@ -1602,13 +1614,54 @@ export async function startMcpServer(options) {
|
|
|
1602
1614
|
return { content: [gate], isError: true };
|
|
1603
1615
|
try {
|
|
1604
1616
|
let result;
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1617
|
+
const action = params.action ?? (params.slug ? 'documents' : 'list');
|
|
1618
|
+
switch (action) {
|
|
1619
|
+
case 'list':
|
|
1620
|
+
result = await api.listCorpora();
|
|
1621
|
+
break;
|
|
1622
|
+
case 'documents':
|
|
1623
|
+
if (!params.slug)
|
|
1624
|
+
return { content: [{ type: 'text', text: 'Error: slug is required for documents action' }], isError: true };
|
|
1625
|
+
result = await api.getCorpusDocuments(params.slug, params.limit, params.offset);
|
|
1626
|
+
break;
|
|
1627
|
+
case 'create':
|
|
1628
|
+
if (!params.slug)
|
|
1629
|
+
return { content: [{ type: 'text', text: 'Error: slug is required for create action' }], isError: true };
|
|
1630
|
+
if (!params.title)
|
|
1631
|
+
return { content: [{ type: 'text', text: 'Error: title is required for create action' }], isError: true };
|
|
1632
|
+
result = await api.createCorpus({
|
|
1633
|
+
slug: params.slug,
|
|
1634
|
+
title: params.title,
|
|
1635
|
+
description: params.description,
|
|
1636
|
+
material_class: params.material_class,
|
|
1637
|
+
visibility: params.visibility === 'all' ? undefined : params.visibility,
|
|
1638
|
+
themes: params.themes,
|
|
1639
|
+
default_author_share: params.default_author_share,
|
|
1640
|
+
default_steward_share: params.default_steward_share,
|
|
1641
|
+
split_justification: params.split_justification,
|
|
1642
|
+
provenance_note: params.provenance_note,
|
|
1643
|
+
manifest: params.manifest,
|
|
1644
|
+
});
|
|
1645
|
+
break;
|
|
1646
|
+
case 'health':
|
|
1647
|
+
if (!params.slug)
|
|
1648
|
+
return { content: [{ type: 'text', text: 'Error: slug is required for health action' }], isError: true };
|
|
1649
|
+
result = await api.getCorpusHealth(params.slug);
|
|
1650
|
+
break;
|
|
1651
|
+
case 'revenue':
|
|
1652
|
+
if (!params.slug)
|
|
1653
|
+
return { content: [{ type: 'text', text: 'Error: slug is required for revenue action' }], isError: true };
|
|
1654
|
+
result = await api.getCorpusRevenue(params.slug, params.days);
|
|
1655
|
+
break;
|
|
1656
|
+
case 'bulk_ingest':
|
|
1657
|
+
if (!params.slug)
|
|
1658
|
+
return { content: [{ type: 'text', text: 'Error: slug is required for bulk_ingest action' }], isError: true };
|
|
1659
|
+
if (!params.documents)
|
|
1660
|
+
return { content: [{ type: 'text', text: 'Error: documents is required for bulk_ingest action' }], isError: true };
|
|
1661
|
+
result = await api.bulkIngestDocuments(params.slug, params.documents);
|
|
1662
|
+
break;
|
|
1610
1663
|
}
|
|
1611
|
-
const shaped = shapeCorpora(result, params.slug);
|
|
1664
|
+
const shaped = action === 'list' || action === 'documents' ? shapeCorpora(result, action === 'documents' ? params.slug : undefined) : result;
|
|
1612
1665
|
return { content: [{ type: 'text', text: JSON.stringify(shaped, null, 2) }] };
|
|
1613
1666
|
}
|
|
1614
1667
|
catch (err) {
|
|
@@ -1783,6 +1836,7 @@ export async function startMcpServer(options) {
|
|
|
1783
1836
|
action: z.enum(['diff', 'push', 'pull', 'preview']).describe('Sync action to perform'),
|
|
1784
1837
|
publish: z.boolean().optional().describe('Legacy push only: publish new document versions instead of drafts'),
|
|
1785
1838
|
market_native_docs_ingest: z.enum(['off', 'auto', 'all']).optional().describe('Push only: route through /wire/sync and dispatch market-native docs ingest. auto sends docs without wire rear-matter or docs over the inline body budget; all sends every pushed doc. Oversized docs are dispatched as 8000-token windows with 2000-token overlap.'),
|
|
1839
|
+
include_content: z.boolean().optional().describe('Diff/preview only: include full local file bodies. Defaults false; previews normally return hash + sizeBytes only.'),
|
|
1786
1840
|
}, async (params) => {
|
|
1787
1841
|
const gate = await requireConfirmed();
|
|
1788
1842
|
if (gate)
|
|
@@ -1791,6 +1845,7 @@ export async function startMcpServer(options) {
|
|
|
1791
1845
|
const { dir, corpus, action } = params;
|
|
1792
1846
|
const publish = params.publish ?? false;
|
|
1793
1847
|
const marketNativeDocsIngest = (params.market_native_docs_ingest ?? 'off');
|
|
1848
|
+
const includeContent = params.include_content === true;
|
|
1794
1849
|
// ── Path traversal protection ──
|
|
1795
1850
|
if (!isAbsolute(dir)) {
|
|
1796
1851
|
return { content: [{ type: 'text', text: 'Error: dir must be an absolute path' }], isError: true };
|
|
@@ -1828,7 +1883,7 @@ export async function startMcpServer(options) {
|
|
|
1828
1883
|
const remoteDocs = await paginateAll(async (page, pageSize) => {
|
|
1829
1884
|
const offset = (page - 1) * pageSize;
|
|
1830
1885
|
const result = await api.getCorpusDocuments(corpus, pageSize, offset);
|
|
1831
|
-
return result.documents || [];
|
|
1886
|
+
return result.documents || result.items || [];
|
|
1832
1887
|
});
|
|
1833
1888
|
// 4. Compute diff
|
|
1834
1889
|
const diff = await computeDiff(localFiles, remoteDocs, manifest);
|
|
@@ -1843,11 +1898,15 @@ export async function startMcpServer(options) {
|
|
|
1843
1898
|
conflicts: diff.conflicts.length,
|
|
1844
1899
|
};
|
|
1845
1900
|
const output = {
|
|
1901
|
+
...generatePreviewJson({
|
|
1902
|
+
corpus_slug: corpus,
|
|
1903
|
+
local_dir: dir,
|
|
1904
|
+
diff,
|
|
1905
|
+
summary,
|
|
1906
|
+
}, { includeContent }),
|
|
1846
1907
|
corpus_slug: corpus,
|
|
1847
1908
|
local_dir: dir,
|
|
1848
1909
|
action,
|
|
1849
|
-
diff,
|
|
1850
|
-
summary,
|
|
1851
1910
|
};
|
|
1852
1911
|
return { content: [{ type: 'text', text: JSON.stringify(output, null, 2) }] };
|
|
1853
1912
|
}
|
|
@@ -2200,7 +2259,7 @@ export async function startMcpServer(options) {
|
|
|
2200
2259
|
server.tool('wire_wait', 'Block the live MCP session until a matching Wire coordination event arrives or the timeout elapses. Layer 1 uses SSE + cursor replay; durable wire_watch is not included.', {
|
|
2201
2260
|
triggers: z.array(z.string()).max(20).optional().describe('Event triggers to wait for, e.g. message.unread, task.assigned, task.moved, board.changed, circle.message. Supports prefix wildcards such as message.*. Omit to wait on any message.*, task.*, board.*, or circle.* event addressable to you.'),
|
|
2202
2261
|
filters: z.record(z.unknown()).optional().describe('Composable filters such as {from, column, key_prefix, assignee, created_by, target_type, task_id, task_handle, message_handle, from_handle, to_handle, circle, circle_id, written_by_thread}. Agent filters accept "me", agent UUID, or pseudo-ID when available. Handle filters match the corresponding event payload field exactly.'),
|
|
2203
|
-
timeout_seconds: z.number().int().min(
|
|
2262
|
+
timeout_seconds: z.number().int().min(-1).max(86400).optional().describe('Maximum seconds to block. Defaults to 30; max 86400 (24h). Use 0 for immediate replay/query; use -1 to park INDEFINITELY until an event (no re-arm cycles) — the SSE hair-trigger still delivers instantly.'),
|
|
2204
2263
|
cursor: z.string().optional().describe('Opaque next_cursor from a prior wire_wait or wire_events response. Legacy integer id cursors are accepted. If omitted, wait starts at the current high-water mark.'),
|
|
2205
2264
|
limit: z.number().int().min(1).max(200).optional().describe('Maximum events to return when triggered. Defaults to 50.'),
|
|
2206
2265
|
}, async (params) => {
|
|
@@ -2289,6 +2348,7 @@ export async function startMcpServer(options) {
|
|
|
2289
2348
|
action: z.enum(['supersede', 'propose', 'accept', 'reject']).describe('supersede = direct supersession authorized by target scope, propose = propose supersession (5-credit deposit), accept = approve a proposal, reject = deny a proposal'),
|
|
2290
2349
|
target_id: z.string().describe('Target contribution UUID (the one being superseded for supersede/propose, or the proposal UUID for accept/reject)'),
|
|
2291
2350
|
contribution_id: z.string().optional().describe('Your replacement contribution UUID (required for supersede and propose)'),
|
|
2351
|
+
allow_type_change: z.boolean().optional().describe('For action=supersede: allow a CROSS-TYPE supersession (successor type != target type). Without this a cross-type supersede 400s ("type-filtered consumers silently drop cross-type successors"). Pass true only when the type change is deliberate.'),
|
|
2292
2352
|
}, async (params) => {
|
|
2293
2353
|
const gate = await requireConfirmed();
|
|
2294
2354
|
if (gate)
|
|
@@ -2312,7 +2372,7 @@ export async function startMcpServer(options) {
|
|
|
2312
2372
|
if (!params.contribution_id) {
|
|
2313
2373
|
return { content: [{ type: 'text', text: 'contribution_id is required for supersede' }], isError: true };
|
|
2314
2374
|
}
|
|
2315
|
-
result = await api.executeSupersession(params.target_id, params.contribution_id);
|
|
2375
|
+
result = await api.executeSupersession(params.target_id, params.contribution_id, params.allow_type_change);
|
|
2316
2376
|
break;
|
|
2317
2377
|
default:
|
|
2318
2378
|
return { content: [{ type: 'text', text: 'Invalid action' }], isError: true };
|