@izagood/avcs 0.17.0 → 0.19.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 (43) hide show
  1. package/dist/api/repo.d.ts +78 -0
  2. package/dist/api/repo.d.ts.map +1 -1
  3. package/dist/api/repo.js +221 -5
  4. package/dist/api/repo.js.map +1 -1
  5. package/dist/cli.js +42 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/hub/hubServer.d.ts +9 -2
  8. package/dist/hub/hubServer.d.ts.map +1 -1
  9. package/dist/hub/hubServer.js +106 -4
  10. package/dist/hub/hubServer.js.map +1 -1
  11. package/dist/hub/syncWatch.d.ts +56 -0
  12. package/dist/hub/syncWatch.d.ts.map +1 -0
  13. package/dist/hub/syncWatch.js +186 -0
  14. package/dist/hub/syncWatch.js.map +1 -0
  15. package/dist/index.d.ts +3 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/mcp/guide.d.ts +5 -0
  20. package/dist/mcp/guide.d.ts.map +1 -0
  21. package/dist/mcp/guide.js +67 -0
  22. package/dist/mcp/guide.js.map +1 -0
  23. package/dist/mcp/respond.d.ts +32 -0
  24. package/dist/mcp/respond.d.ts.map +1 -0
  25. package/dist/mcp/respond.js +74 -0
  26. package/dist/mcp/respond.js.map +1 -0
  27. package/dist/mcp/server.d.ts +19 -0
  28. package/dist/mcp/server.d.ts.map +1 -1
  29. package/dist/mcp/server.js +200 -37
  30. package/dist/mcp/server.js.map +1 -1
  31. package/dist/merge/merge3.d.ts +13 -0
  32. package/dist/merge/merge3.d.ts.map +1 -1
  33. package/dist/merge/merge3.js +1 -1
  34. package/dist/merge/merge3.js.map +1 -1
  35. package/dist/query/diff.d.ts +13 -0
  36. package/dist/query/diff.d.ts.map +1 -1
  37. package/dist/query/diff.js +61 -0
  38. package/dist/query/diff.js.map +1 -1
  39. package/dist/store/lock.d.ts +8 -0
  40. package/dist/store/lock.d.ts.map +1 -1
  41. package/dist/store/lock.js +33 -0
  42. package/dist/store/lock.js.map +1 -1
  43. package/package.json +1 -1
@@ -0,0 +1,186 @@
1
+ // Phase 15.2 (docs/17 §15.2): the live-convergence daemon behind `avcs sync --watch`.
2
+ //
3
+ // Loop: long-poll the hub's GET /events (the objlog cursor shared with /sync) → on a
4
+ // wake, one incremental sync (cursor pull + redaction propagation + governance-ref
5
+ // adoption, then push local deltas) → early conflict warning when an incoming op's keys
6
+ // cross local work (Phase 15.3) → structured log. Network errors back off with jitter;
7
+ // a hub without /events (pre-v4) degrades to plain periodic polling.
8
+ //
9
+ // Exactly ONE watcher per repo: the loop runs under the cross-process "syncd" lock,
10
+ // kept fresh by the lock heartbeat so a live daemon is never reclaimed as stale while
11
+ // a crashed one frees the lock via the normal stale path.
12
+ import { keysOf } from "../reducer/reducer.js";
13
+ /** Abortable sleep that never rejects — an abort just wakes it early. */
14
+ function sleep(ms, signal) {
15
+ return new Promise((resolve) => {
16
+ if (signal?.aborted) {
17
+ resolve();
18
+ return;
19
+ }
20
+ const done = () => { clearTimeout(t); signal?.removeEventListener("abort", done); resolve(); };
21
+ const t = setTimeout(done, ms);
22
+ signal?.addEventListener("abort", done, { once: true });
23
+ });
24
+ }
25
+ /** The client side of the shared objlog cursor: what pullFromHub last recorded. */
26
+ async function readCursor(repo, url) {
27
+ const raw = await repo.store.readAux("sync-cursors.json");
28
+ if (!raw)
29
+ return 0;
30
+ try {
31
+ const cursors = JSON.parse(raw.toString("utf8"));
32
+ return cursors[url] ?? 0;
33
+ }
34
+ catch {
35
+ return 0;
36
+ }
37
+ }
38
+ async function longPoll(base, since, timeoutMs, signal) {
39
+ const res = await fetch(`${base}/events?since=${since}&timeoutMs=${timeoutMs}`, signal ? { signal } : {});
40
+ if (!res.ok)
41
+ throw new Error(`GET /events failed: ${res.status} ${res.statusText}`);
42
+ return (await res.json());
43
+ }
44
+ /** Local protected-head refs, view → checkpoint oid. */
45
+ async function headRefs(repo) {
46
+ const out = new Map();
47
+ for (const [name, oid] of await repo.store.listRefs()) {
48
+ if (name.startsWith("head:"))
49
+ out.set(name.slice("head:".length), oid);
50
+ }
51
+ return out;
52
+ }
53
+ /**
54
+ * Run the live-convergence loop until `opts.signal` aborts. Throws immediately when
55
+ * another watcher already holds this repo's "syncd" lock — one instance per repo.
56
+ */
57
+ export async function runSyncWatch(repo, opts = {}) {
58
+ const remote = opts.remote ?? "origin";
59
+ const url = await repo.remoteUrl(remote);
60
+ try {
61
+ await repo.store.withLock("syncd", () => watchLoop(repo, remote, url, opts),
62
+ // The heartbeat keeps the live daemon's stamp fresh; a crashed daemon stops
63
+ // stamping and is reclaimed after staleMs by the next starter.
64
+ { maxWaitMs: 100, staleMs: 60_000, heartbeatMs: 10_000 });
65
+ }
66
+ catch (e) {
67
+ if (/lock timeout/.test(String(e.message))) {
68
+ throw new Error('sync --watch is already running for this repo (lock "syncd" is held) — one watcher per repo');
69
+ }
70
+ throw e;
71
+ }
72
+ }
73
+ async function watchLoop(repo, remote, url, opts) {
74
+ const signal = opts.signal;
75
+ const timeoutMs = opts.timeoutMs ?? 30_000;
76
+ const minBackoff = opts.minBackoffMs ?? 500;
77
+ const maxBackoff = opts.maxBackoffMs ?? 30_000;
78
+ const emit = (ev) => {
79
+ repo.logger.info(`watch.${ev.type}`, ev);
80
+ opts.onEvent?.(ev);
81
+ };
82
+ // Capability detection: a pre-v4 hub has no /events — degrade to periodic polling.
83
+ let live = false;
84
+ try {
85
+ const v = (await (await fetch(`${url}/version`, signal ? { signal } : {})).json());
86
+ live = v.events === true;
87
+ }
88
+ catch { /* unreachable /version → the loop's error path will report and back off */ }
89
+ emit({ type: "started", remote, url, legacyPolling: !live });
90
+ let backoff = minBackoff;
91
+ let lastHeads = new Map();
92
+ // Initial full convergence — also seeds the shared objlog cursor for the long-poll.
93
+ try {
94
+ const r = await repo.sync(remote, { as: opts.as });
95
+ emit({ type: "synced", pulled: r.pulled, pushed: r.pushed });
96
+ lastHeads = await headRefs(repo);
97
+ for (const [view, cp] of lastHeads)
98
+ emit({ type: "head", view, checkpoint: cp });
99
+ }
100
+ catch (e) {
101
+ emit({ type: "error", error: String(e.message), backoffMs: backoff });
102
+ await sleep(backoff + Math.floor(Math.random() * backoff), signal);
103
+ backoff = Math.min(backoff * 2, maxBackoff);
104
+ }
105
+ while (!signal?.aborted) {
106
+ let payload = null;
107
+ if (live) {
108
+ const since = await readCursor(repo, url);
109
+ try {
110
+ payload = await longPoll(url, since, timeoutMs, signal);
111
+ backoff = minBackoff;
112
+ }
113
+ catch (e) {
114
+ if (signal?.aborted)
115
+ break;
116
+ emit({ type: "error", error: String(e.message), backoffMs: backoff });
117
+ await sleep(backoff + Math.floor(Math.random() * backoff), signal);
118
+ backoff = Math.min(backoff * 2, maxBackoff);
119
+ continue;
120
+ }
121
+ // Heartbeat (nothing new, no head movement) — just park again.
122
+ const headsMoved = Object.entries(payload.refs).some(([name, oid]) => name.startsWith("head:") && lastHeads.get(name.slice("head:".length)) !== oid);
123
+ if (!payload.oids.length && !headsMoved) {
124
+ emit({ type: "heartbeat", cursor: payload.cursor });
125
+ continue;
126
+ }
127
+ }
128
+ else {
129
+ await sleep(timeoutMs, signal);
130
+ if (signal?.aborted)
131
+ break;
132
+ }
133
+ // Which of the announced oids are genuinely new HERE? Decided before the pull so
134
+ // the contention pass below only inspects actual arrivals (not our own echoes).
135
+ const incoming = [];
136
+ if (payload)
137
+ for (const oid of payload.oids)
138
+ if (!(await repo.store.has(oid)))
139
+ incoming.push(oid);
140
+ try {
141
+ const r = await repo.sync(remote, { as: opts.as });
142
+ emit({ type: "synced", pulled: r.pulled, pushed: r.pushed });
143
+ backoff = minBackoff;
144
+ const heads = await headRefs(repo);
145
+ for (const [view, cp] of heads)
146
+ if (lastHeads.get(view) !== cp)
147
+ emit({ type: "head", view, checkpoint: cp });
148
+ lastHeads = heads;
149
+ // Early conflict warning (Phase 15.3): an incoming op landed on a key that has
150
+ // live local work by someone else — "agent B's op arrived on your key K", raised
151
+ // at ARRIVAL time instead of at finalize. Perspective is the incoming actor's, so
152
+ // `theirs` is exactly the local work the arrival did not build on.
153
+ for (const oid of incoming) {
154
+ if (!(await repo.store.has(oid)))
155
+ continue; // announced but not transferred (raced eviction)
156
+ const obj = await repo.store.get(oid);
157
+ if (obj.type !== "operation")
158
+ continue;
159
+ const op = obj;
160
+ if (op.private)
161
+ continue;
162
+ const warnings = await repo.contention({ keys: keysOf(op), actorId: op.actor.id, line: op.line });
163
+ for (const w of warnings) {
164
+ if (!w.theirs.length)
165
+ continue;
166
+ emit({
167
+ type: "contention",
168
+ key: w.key,
169
+ incomingOp: oid,
170
+ incomingActor: op.actor.id,
171
+ localOps: w.theirs.map((t) => ({ op: t.op, actor: t.actor, purpose: t.purpose })),
172
+ });
173
+ }
174
+ }
175
+ }
176
+ catch (e) {
177
+ if (signal?.aborted)
178
+ break;
179
+ emit({ type: "error", error: String(e.message), backoffMs: backoff });
180
+ await sleep(backoff + Math.floor(Math.random() * backoff), signal);
181
+ backoff = Math.min(backoff * 2, maxBackoff);
182
+ }
183
+ }
184
+ emit({ type: "stopped", reason: signal?.aborted ? "aborted" : "loop-exit" });
185
+ }
186
+ //# sourceMappingURL=syncWatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncWatch.js","sourceRoot":"","sources":["../../src/hub/syncWatch.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Repo } from "./api/repo.ts";
2
- export type { GitMode, RemoteConfig } from "./api/repo.ts";
2
+ export type { GitMode, RemoteConfig, ContentionWarning } from "./api/repo.ts";
3
3
  export { canonicalize, computeOid, sha256hex } from "./core/canonical.ts";
4
4
  export { reduce, snapshotReduce, reduceIncremental, keysOf, conflictIdFor, detectFileConflicts } from "./reducer/reducer.ts";
5
5
  export type { ReduceInput, ReductionResult, ReduceSnapshot, Conflict, AutoDecision } from "./reducer/reducer.ts";
@@ -10,6 +10,8 @@ export { startHub, HUB_PROTOCOL_VERSION } from "./hub/hubServer.ts";
10
10
  export type { HubHandle } from "./hub/hubServer.ts";
11
11
  export { pushToHub, pullFromHub, finalizeOnHub } from "./hub/hubClient.ts";
12
12
  export type { HubSigner } from "./hub/hubClient.ts";
13
+ export { runSyncWatch } from "./hub/syncWatch.ts";
14
+ export type { SyncWatchEvent, SyncWatchOpts } from "./hub/syncWatch.ts";
13
15
  export { buildAuthHeader, parseAuthHeader, verifyAuth, canonicalRequest, NonceCache, AUTH_SCHEME, DEFAULT_AUTH_WINDOW_MS } from "./hub/transportAuth.ts";
14
16
  export type { AuthCredential, AuthResult, PublicKeyResolver } from "./hub/transportAuth.ts";
15
17
  export { Keyring, generateKeypair, signMessage, verifyMessage } from "./core/identity.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG1E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC7H,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKjH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGtF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACzJ,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAO9E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG1E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC7H,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKjH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGtF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACzJ,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -23,6 +23,8 @@ export { ObjectStore, CorruptObjectError } from "./store/objectStore.js";
23
23
  // Hub (server + client) — the replication / trust boundary avcshub productionizes
24
24
  export { startHub, HUB_PROTOCOL_VERSION } from "./hub/hubServer.js";
25
25
  export { pushToHub, pullFromHub, finalizeOnHub } from "./hub/hubClient.js";
26
+ // Live convergence (Phase 15): the sync-watch daemon behind `avcs sync --watch`.
27
+ export { runSyncWatch } from "./hub/syncWatch.js";
26
28
  // SSH-style transport auth: embedders (e.g. a hosted hub) inject `resolvePublicKey` into
27
29
  // startHub({ auth }); these helpers also let a client build/verify the credential directly.
28
30
  export { buildAuthHeader, parseAuthHeader, verifyAuth, canonicalRequest, NonceCache, AUTH_SCHEME, DEFAULT_AUTH_WINDOW_MS } from "./hub/transportAuth.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,EAAE;AACF,mFAAmF;AACnF,yFAAyF;AACzF,wFAAwF;AACxF,iFAAiF;AAEjF,+BAA+B;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,mFAAmF;AACnF,uFAAuF;AACvF,sFAAsF;AACtF,wFAAwF;AACxF,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG7H,iFAAiF;AACjF,qFAAqF;AACrF,yDAAyD;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGzE,kFAAkF;AAClF,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3E,yFAAyF;AACzF,4FAA4F;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGzJ,8DAA8D;AAC9D,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG1F,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,EAAE;AACF,mFAAmF;AACnF,yFAAyF;AACzF,wFAAwF;AACxF,iFAAiF;AAEjF,+BAA+B;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,mFAAmF;AACnF,uFAAuF;AACvF,sFAAsF;AACtF,wFAAwF;AACxF,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG7H,iFAAiF;AACjF,qFAAqF;AACrF,yDAAyD;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGzE,kFAAkF;AAClF,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3E,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,yFAAyF;AACzF,4FAA4F;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGzJ,8DAA8D;AAC9D,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG1F,uEAAuE;AACvE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ToolDef } from "./server.ts";
2
+ export type GuideTopic = "workflow" | "tools" | "sync" | "rules" | "errors";
3
+ /** Build the guide. `tools` is the live table so the index is generated, never restated. */
4
+ export declare function buildGuide(tools: ToolDef[], topic?: string): Record<string, unknown>;
5
+ //# sourceMappingURL=guide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/mcp/guide.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAqC5E,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBpF"}
@@ -0,0 +1,67 @@
1
+ // Phase 16 M1.3 (docs/18 §1.3) — avcs.guide: on-demand self-onboarding.
2
+ //
3
+ // The economics this exists for: a tool's `description` is paid on EVERY session, by every
4
+ // agent, whether or not it needs teaching. A guide is paid only when called. So the
5
+ // teaching moves here and descriptions shrink to identification — which nets out smaller
6
+ // even after adding tools (§1.2's description-slimming pass is the other half of the deal).
7
+ //
8
+ // The hazard with any hand-written guide is drift: it describes a server that no longer
9
+ // exists. Everything derivable is therefore GENERATED from the live tables — the tool index
10
+ // from TOOLS, the error map from RECOVERY — so the guide cannot disagree with the server.
11
+ import { RECOVERY } from "./respond.js";
12
+ /**
13
+ * The canonical loop an agent runs. Every `tool` here must be REGISTERED — a loop naming a
14
+ * tool that does not exist teaches the agent to fail. Phase 16 M2/M3 insert
15
+ * `avcs.context.build` after intent.read and collapse the closing three steps into
16
+ * `avcs.sync.land`; until those ship, this is the loop that actually works.
17
+ */
18
+ const LOOP = [
19
+ { step: 1, tool: "avcs.intent.read", why: "learn the declared goal and the scopes you may touch" },
20
+ { step: 2, tool: "avcs.session.start", why: "bind your work to that intent under your actor identity" },
21
+ { step: 3, tool: "avcs.contention.check", why: "see other actors' live work on your keys before you edit, not at finalize" },
22
+ { step: 4, tool: "avcs.lease.request", why: "claim the scopes you are about to write" },
23
+ { step: 5, tool: "avcs.operation.propose", why: "submit the change as an operation; never write final files yourself" },
24
+ { step: 6, tool: "avcs.validate.run", why: "produce evidence; a behaviour change is not acceptable without it" },
25
+ { step: 7, tool: "avcs.evidence.attach", why: "bind that evidence to the ops it justifies" },
26
+ { step: 8, tool: "avcs.view.materialize", why: "check the work actually merges, and read any open conflicts" },
27
+ { step: 9, tool: "avcs.checkpoint.create", why: "package the accepted state for submission" },
28
+ { step: 10, tool: "avcs.integration.submit", why: "land it; the queue re-reduces for you, so you are never told to pull and redo" },
29
+ ];
30
+ /** The agent obligations from docs/06, in a form a machine can carry in a system prompt. */
31
+ const RULES = [
32
+ "Never write final files directly — submit avcs.operation.propose.",
33
+ "Declare effects (changesBehavior / breaksPublicApi) honestly.",
34
+ "A behaviour change cannot be accepted without passing-test evidence.",
35
+ "On a conflict, produce options for a human; do not silently overwrite.",
36
+ "Stay inside the intent's allowed scopes; widen the intent instead of exceeding it.",
37
+ "Read a failure's nextActions and follow them; do not improvise recovery from the message text.",
38
+ ];
39
+ const SYNC = [
40
+ "avcs.integration.submit lands work; a moved head is re-reduced for you, not bounced back.",
41
+ "avcs.integration.status re-reads a ticket; the verdict is advanced | conflict | needs_evidence | queued.",
42
+ "A conflict verdict needs a human decision — avcs.conflict.list then avcs.decision.record.",
43
+ ];
44
+ /** Build the guide. `tools` is the live table so the index is generated, never restated. */
45
+ export function buildGuide(tools, topic) {
46
+ const base = { v: 1 };
47
+ switch (topic) {
48
+ case "tools":
49
+ // One line per tool, straight off the server's own table.
50
+ return { ...base, tools: tools.map((t) => ({ name: t.name, description: t.description })) };
51
+ case "rules":
52
+ return { ...base, rules: RULES };
53
+ case "sync":
54
+ return { ...base, sync: SYNC };
55
+ case "errors":
56
+ return {
57
+ ...base,
58
+ errors: RECOVERY.map((r) => ({ when: r.re.source, hint: r.hint, nextActions: r.nextActions })),
59
+ };
60
+ case "workflow":
61
+ default:
62
+ // No topic (or an unknown one) answers with the canonical loop rather than erroring:
63
+ // an agent guessing a topic name should still get the thing it most likely wanted.
64
+ return { ...base, loop: LOOP, rules: RULES, topics: ["workflow", "tools", "sync", "rules", "errors"] };
65
+ }
66
+ }
67
+ //# sourceMappingURL=guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/mcp/guide.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,2FAA2F;AAC3F,oFAAoF;AACpF,yFAAyF;AACzF,4FAA4F;AAC5F,EAAE;AACF,wFAAwF;AACxF,4FAA4F;AAC5F,0FAA0F;AAE1F,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAKxC;;;;;GAKG;AACH,MAAM,IAAI,GAAkD;IAC1D,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,sDAAsD,EAAE;IAClG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG,EAAE,yDAAyD,EAAE;IACvG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,GAAG,EAAE,2EAA2E,EAAE;IAC5H,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG,EAAE,yCAAyC,EAAE;IACvF,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,GAAG,EAAE,qEAAqE,EAAE;IACvH,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,mEAAmE,EAAE;IAChH,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,GAAG,EAAE,4CAA4C,EAAE;IAC5F,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,GAAG,EAAE,6DAA6D,EAAE;IAC9G,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,GAAG,EAAE,2CAA2C,EAAE;IAC7F,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,GAAG,EAAE,+EAA+E,EAAE;CACpI,CAAC;AAEF,4FAA4F;AAC5F,MAAM,KAAK,GAAa;IACtB,mEAAmE;IACnE,+DAA+D;IAC/D,sEAAsE;IACtE,wEAAwE;IACxE,oFAAoF;IACpF,gGAAgG;CACjG,CAAC;AAEF,MAAM,IAAI,GAAa;IACrB,2FAA2F;IAC3F,0GAA0G;IAC1G,2FAA2F;CAC5F,CAAC;AAEF,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,KAAgB,EAAE,KAAc;IACzD,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,CAAU,EAAE,CAAC;IAC/B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,0DAA0D;YAC1D,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9F,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,KAAK,QAAQ;YACX,OAAO;gBACL,GAAG,IAAI;gBACP,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;aAC/F,CAAC;QACJ,KAAK,UAAU,CAAC;QAChB;YACE,qFAAqF;YACrF,mFAAmF;YACnF,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC3G,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** The serialized form of a failed tool call. `nextActions` are tool calls or commands, in
2
+ * the order worth trying; absent when the failure class is unrecognized (never invented). */
3
+ export interface ErrorEnvelope {
4
+ error: string;
5
+ hint?: string;
6
+ nextActions?: string[];
7
+ }
8
+ /** A known failure class and the way out of it. */
9
+ export interface RecoveryRule {
10
+ re: RegExp;
11
+ hint?: string;
12
+ nextActions: string[];
13
+ }
14
+ /**
15
+ * Known failure classes → what to do about them. Every dotted `avcs.*` name here must be a
16
+ * REGISTERED tool — a hint pointing at a tool that does not exist is worse than prose,
17
+ * because the agent follows it and fails. A test pins this against the live tool list.
18
+ */
19
+ export declare const RECOVERY: RecoveryRule[];
20
+ /**
21
+ * Normalize a caller-supplied limit against a default (Phase 16 M1.2). A missing, negative,
22
+ * zero, or non-finite value falls back to the default rather than returning nothing or
23
+ * everything — an unbounded read is the failure mode this layer exists to prevent.
24
+ */
25
+ export declare function boundedLimit(raw: unknown, fallback: number): number;
26
+ /** Serialize a successful tool result. Compact unless a human asked for readability. */
27
+ export declare function serializeResult(result: unknown, opts?: {
28
+ verbose?: boolean;
29
+ }): string;
30
+ /** Translate a thrown value into the failure envelope the transport sends. */
31
+ export declare function errorEnvelope(e: unknown): ErrorEnvelope;
32
+ //# sourceMappingURL=respond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respond.d.ts","sourceRoot":"","sources":["../../src/mcp/respond.ts"],"names":[],"mappings":"AAcA;8FAC8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,YAAY,EAiClC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAErF;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,aAAa,CAKvD"}
@@ -0,0 +1,74 @@
1
+ // Phase 16 M1.1 (docs/18 §1.1) — the MCP response layer.
2
+ //
3
+ // Tokens are a budget (docs/18 §2 principle 2). Two consequences live here:
4
+ //
5
+ // - Serialization is COMPACT by default. Pretty-printing costs indentation tokens on
6
+ // every call an agent ever makes, for a reader that is not human. `verbose` restores
7
+ // it for the times a person is actually looking.
8
+ // - Every failure becomes a machine-readable envelope carrying `nextActions`, so an
9
+ // agent recovers by following a list instead of parsing prose and flailing (§1 gap 6).
10
+ //
11
+ // What this layer deliberately does NOT do: wrap success shapes. Existing consumers and
12
+ // tests parse the raw shape, so compatibility is absolute — additive fields only
13
+ // (§2 principle 1, and the second recorded risk in §5).
14
+ /**
15
+ * Known failure classes → what to do about them. Every dotted `avcs.*` name here must be a
16
+ * REGISTERED tool — a hint pointing at a tool that does not exist is worse than prose,
17
+ * because the agent follows it and fails. A test pins this against the live tool list.
18
+ */
19
+ export const RECOVERY = [
20
+ {
21
+ // The Phase 14 integration queue exists precisely so a submit is never told to pull
22
+ // and redo; naming it turns the one error an agent used to flail on into a call.
23
+ re: /head moved|not up to date|stale (parent|head)/i,
24
+ hint: "the view's head advanced while you worked; the integration queue re-reduces for you",
25
+ nextActions: ["avcs.integration.submit", "avcs.integration.status"],
26
+ },
27
+ {
28
+ re: /no local signing key|signing key|keystore/i,
29
+ hint: "this action must be signed by an actor key held locally",
30
+ nextActions: ["avcs key provision <actor-id>", "avcs key ls"],
31
+ },
32
+ {
33
+ re: /not an AVCS repo|no \.avcs/i,
34
+ hint: "the resolved directory has no .avcs/ at or above it",
35
+ nextActions: ["pass cwd: <repo dir> with the call", "avcs init <dir>"],
36
+ },
37
+ {
38
+ re: /open conflict|conflicts? remain|unresolved conflict/i,
39
+ hint: "a human decision is required; do not retry through it",
40
+ nextActions: ["avcs.conflict.list", "avcs.decision.record"],
41
+ },
42
+ {
43
+ re: /lease|held by/i,
44
+ hint: "another actor holds a write lease overlapping your scope",
45
+ nextActions: ["avcs.contention.check", "avcs.lease.request"],
46
+ },
47
+ {
48
+ re: /validation failed|checks? failed|evidence/i,
49
+ hint: "the gate wants passing evidence bound to this tree",
50
+ nextActions: ["avcs.validate.run", "avcs.evidence.attach", "avcs.repair.context"],
51
+ },
52
+ ];
53
+ /**
54
+ * Normalize a caller-supplied limit against a default (Phase 16 M1.2). A missing, negative,
55
+ * zero, or non-finite value falls back to the default rather than returning nothing or
56
+ * everything — an unbounded read is the failure mode this layer exists to prevent.
57
+ */
58
+ export function boundedLimit(raw, fallback) {
59
+ const n = typeof raw === "number" ? raw : Number(raw);
60
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
61
+ }
62
+ /** Serialize a successful tool result. Compact unless a human asked for readability. */
63
+ export function serializeResult(result, opts) {
64
+ return opts?.verbose ? JSON.stringify(result, null, 2) : JSON.stringify(result);
65
+ }
66
+ /** Translate a thrown value into the failure envelope the transport sends. */
67
+ export function errorEnvelope(e) {
68
+ const error = e instanceof Error ? e.message : String(e);
69
+ const rule = RECOVERY.find((r) => r.re.test(error));
70
+ if (!rule)
71
+ return { error };
72
+ return { error, hint: rule.hint, nextActions: rule.nextActions };
73
+ }
74
+ //# sourceMappingURL=respond.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respond.js","sourceRoot":"","sources":["../../src/mcp/respond.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,sFAAsF;AACtF,wFAAwF;AACxF,oDAAoD;AACpD,qFAAqF;AACrF,0FAA0F;AAC1F,EAAE;AACF,wFAAwF;AACxF,iFAAiF;AACjF,wDAAwD;AAiBxD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC;QACE,oFAAoF;QACpF,iFAAiF;QACjF,EAAE,EAAE,gDAAgD;QACpD,IAAI,EAAE,qFAAqF;QAC3F,WAAW,EAAE,CAAC,yBAAyB,EAAE,yBAAyB,CAAC;KACpE;IACD;QACE,EAAE,EAAE,4CAA4C;QAChD,IAAI,EAAE,yDAAyD;QAC/D,WAAW,EAAE,CAAC,+BAA+B,EAAE,aAAa,CAAC;KAC9D;IACD;QACE,EAAE,EAAE,6BAA6B;QACjC,IAAI,EAAE,qDAAqD;QAC3D,WAAW,EAAE,CAAC,oCAAoC,EAAE,iBAAiB,CAAC;KACvE;IACD;QACE,EAAE,EAAE,sDAAsD;QAC1D,IAAI,EAAE,uDAAuD;QAC7D,WAAW,EAAE,CAAC,oBAAoB,EAAE,sBAAsB,CAAC;KAC5D;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,0DAA0D;QAChE,WAAW,EAAE,CAAC,uBAAuB,EAAE,oBAAoB,CAAC;KAC7D;IACD;QACE,EAAE,EAAE,4CAA4C;QAChD,IAAI,EAAE,oDAAoD;QAC1D,WAAW,EAAE,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,qBAAqB,CAAC;KAClF;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY,EAAE,QAAgB;IACzD,MAAM,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,eAAe,CAAC,MAAe,EAAE,IAA4B;IAC3E,OAAO,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAClF,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;AACnE,CAAC"}
@@ -17,6 +17,25 @@ export interface ToolDef {
17
17
  handler: (repo: Repo, input: Record<string, unknown>, ctx?: ToolCtx) => Promise<unknown>;
18
18
  }
19
19
  export declare function actorOf(input: Record<string, unknown>): Actor;
20
+ /** The schema advertised to clients: the tool's own inputs plus the universal `cwd` and
21
+ * `verbose`. Returns a fresh object — the ToolDef's own schema is never mutated. */
22
+ export declare function advertisedSchema(t: ToolDef): Record<string, unknown>;
23
+ /**
24
+ * Run one tool call and render it for the transport (Phase 16 M1.1, docs/18 §1.1).
25
+ * Exported so the layer is testable without booting the SDK, the same way the handlers are.
26
+ *
27
+ * Success keeps its raw shape — only the serialization changes (§2 principle 1). Failure
28
+ * becomes `{ error, hint?, nextActions? }` so the agent recovers from a list instead of
29
+ * parsing prose; it is returned with `isError`, not thrown, because a thrown error reaches
30
+ * the agent as an opaque transport failure and loses the recovery hints entirely.
31
+ */
32
+ export declare function runTool(tool: ToolDef, repo: Repo, args: Record<string, unknown>, ctx?: ToolCtx): Promise<{
33
+ content: {
34
+ type: "text";
35
+ text: string;
36
+ }[];
37
+ isError?: boolean;
38
+ }>;
20
39
  /**
21
40
  * Resolve which AVCS repo a tool call targets, returning its `.avcs` root dir.
22
41
  *
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAGtC,OAAO,KAAK,EAAE,KAAK,EAAmB,MAAM,qBAAqB,CAAC;AAuBlE,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wFAAwF;AACxF,MAAM,WAAW,OAAO;IACtB,kEAAkE;IAClE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAChG;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAG7D;AAuBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAED,eAAO,MAAM,KAAK,EAAE,OAAO,EAuc1B,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiIpD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAMtC,OAAO,KAAK,EAAE,KAAK,EAAmB,MAAM,qBAAqB,CAAC;AAuBlE,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wFAAwF;AACxF,MAAM,WAAW,OAAO;IACtB,kEAAkE;IAClE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAChG;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAG7D;AA+BD;qFACqF;AACrF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAQ3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAED,eAAO,MAAM,KAAK,EAAE,OAAO,EAqkB1B,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA6HpD"}