@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
@@ -5,6 +5,19 @@ export interface TreeDiff {
5
5
  modified: string[];
6
6
  }
7
7
  export declare function diffTrees(a: ReductionResult, b: ReductionResult): TreeDiff;
8
+ /**
9
+ * Unified diff of two texts (Phase 16 M1.2, docs/18 §1.2).
10
+ *
11
+ * Built on merge3's LCS hunk core rather than a second diff implementation: a patch an
12
+ * agent reads must describe the same line changes the reducer would merge, and two
13
+ * independent algorithms would eventually disagree about which lines moved.
14
+ *
15
+ * `context` lines surround each hunk; adjacent hunks whose context would overlap are
16
+ * emitted as one, the way `diff -u` does.
17
+ */
18
+ export declare function unifiedDiff(a: string, b: string, opts?: {
19
+ context?: number;
20
+ }): string;
8
21
  export interface OpSetDiff {
9
22
  /** Accepted in b but not a. */
10
23
  added: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/query/diff.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,QAAQ,CAU1E;AAED,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,SAAS,CASjF"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/query/diff.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,QAAQ,CAU1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAsCzF;AAED,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,SAAS,CASjF"}
@@ -4,6 +4,7 @@
4
4
  // content-derived), so a path whose oid is unchanged is unchanged — diffing is just
5
5
  // a map comparison. The AVCS-only axis is a *policy diff*: reduce the same ops under
6
6
  // two policies and diff the trees to see what the policy change alone did.
7
+ import { diffHunks } from "../merge/merge3.js";
7
8
  export function diffTrees(a, b) {
8
9
  const added = [];
9
10
  const removed = [];
@@ -19,6 +20,66 @@ export function diffTrees(a, b) {
19
20
  removed.push(path);
20
21
  return { added: added.sort(), removed: removed.sort(), modified: modified.sort() };
21
22
  }
23
+ /**
24
+ * Unified diff of two texts (Phase 16 M1.2, docs/18 §1.2).
25
+ *
26
+ * Built on merge3's LCS hunk core rather than a second diff implementation: a patch an
27
+ * agent reads must describe the same line changes the reducer would merge, and two
28
+ * independent algorithms would eventually disagree about which lines moved.
29
+ *
30
+ * `context` lines surround each hunk; adjacent hunks whose context would overlap are
31
+ * emitted as one, the way `diff -u` does.
32
+ */
33
+ export function unifiedDiff(a, b, opts = {}) {
34
+ const ctx = opts.context ?? 3;
35
+ const split = (s) => (s === "" ? [] : s.split("\n").slice(0, s.endsWith("\n") ? -1 : undefined));
36
+ const al = split(a);
37
+ const bl = split(b);
38
+ const hunks = diffHunks(al, bl);
39
+ if (!hunks.length)
40
+ return "";
41
+ // Group hunks whose context windows touch, so the output reads like diff -u.
42
+ const groups = [];
43
+ for (const h of hunks) {
44
+ const last = groups[groups.length - 1];
45
+ const prev = last?.[last.length - 1];
46
+ if (prev && h.start - prev.end <= ctx * 2)
47
+ last.push(h);
48
+ else
49
+ groups.push([h]);
50
+ }
51
+ const out = [];
52
+ for (const group of groups) {
53
+ const first = group[0];
54
+ const last = group[group.length - 1];
55
+ const from = Math.max(0, first.start - ctx);
56
+ const to = Math.min(al.length, last.end + ctx);
57
+ // Count the b-side span: leading context + each hunk's replacement + the gaps between.
58
+ let bCount = 0;
59
+ let cur = from;
60
+ const body = [];
61
+ for (const h of group) {
62
+ for (let i = cur; i < h.start; i++) {
63
+ body.push(` ${al[i]}`);
64
+ bCount++;
65
+ }
66
+ for (let i = h.start; i < h.end; i++)
67
+ body.push(`-${al[i]}`);
68
+ for (const l of h.lines) {
69
+ body.push(`+${l}`);
70
+ bCount++;
71
+ }
72
+ cur = h.end;
73
+ }
74
+ for (let i = cur; i < to; i++) {
75
+ body.push(` ${al[i]}`);
76
+ bCount++;
77
+ }
78
+ const aCount = to - from;
79
+ out.push(`@@ -${from + 1},${aCount} +${from + 1},${bCount} @@`, ...body);
80
+ }
81
+ return out.join("\n") + "\n";
82
+ }
22
83
  /** Symmetric difference of the accepted operation sets of two reductions. */
23
84
  export function diffAcceptedOps(a, b) {
24
85
  const accepted = (r) => new Set([...r.statuses].filter(([, s]) => s === "accepted").map(([oid]) => oid));
@@ -1 +1 @@
1
- {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/query/diff.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,iFAAiF;AACjF,oFAAoF;AACpF,qFAAqF;AACrF,2EAA2E;AAU3E,MAAM,UAAU,SAAS,CAAC,CAAkB,EAAE,CAAkB;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACnC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;AACrF,CAAC;AASD,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,CAAkB,EAAE,CAAkB;IACpE,MAAM,QAAQ,GAAG,CAAC,CAAkB,EAAE,EAAE,CACtC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACvB,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAC/C,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;KAClD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/query/diff.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,14 @@ export interface LockOptions {
3
3
  maxWaitMs?: number;
4
4
  /** Treat a held lock older than this as abandoned and reclaim it. */
5
5
  staleMs?: number;
6
+ /**
7
+ * Re-stamp the owner file on this interval while the lock is held (Phase 15.2).
8
+ * A long-lived holder (the sync-watch daemon) would otherwise exceed any waiter's
9
+ * `staleMs` and get its LIVE lock reclaimed. With a heartbeat the stamp stays fresh
10
+ * while the holder is alive, and a crashed holder stops stamping — so the normal
11
+ * stale-reclaim path still frees the lock. Omit for ordinary short critical sections.
12
+ */
13
+ heartbeatMs?: number;
6
14
  }
7
15
  /**
8
16
  * Run `fn` while holding the named lock under `locksDir`. Serializes concurrent
@@ -1 +1 @@
1
- {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAmDZ"}
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAmFZ"}
@@ -63,10 +63,43 @@ export async function withLock(locksDir, name, fn, opts = {}) {
63
63
  await sleep(5 + Math.floor(Math.random() * 15)); // jittered backoff
64
64
  }
65
65
  }
66
+ // Keep the owner stamp fresh while `fn` runs (write-then-rename, same torn-read
67
+ // discipline as acquisition). Errors are swallowed: if the lock dir vanished the
68
+ // holder is about to find out via its own release, and a failed heartbeat must
69
+ // never crash the critical section it protects.
70
+ let heartbeat = null;
71
+ // Chain the stamp writes rather than firing each into the void. Two reasons, both
72
+ // about a write OUTLIVING the thing it belongs to:
73
+ // - release: clearInterval stops future ticks but not one already in flight. If its
74
+ // rename lands between the release rm's readdir and its rmdir, `owner` is
75
+ // resurrected and rmdir fails ENOTEMPTY — thrown from a `finally`, so it REPLACES
76
+ // fn()'s successful result, and leaves a freshly-stamped lock dir that blocks every
77
+ // waiter for a full staleMs. So release awaits this chain before removing anything.
78
+ // - overlap: a stamp write slower than the interval would otherwise interleave with
79
+ // the next tick; chaining serializes them.
80
+ let stampWrites = Promise.resolve();
81
+ if (opts.heartbeatMs !== undefined && opts.heartbeatMs > 0) {
82
+ heartbeat = setInterval(() => {
83
+ stampWrites = stampWrites.then(async () => {
84
+ try {
85
+ const tmp = join(lockPath, `owner.${process.pid}.hb.tmp`);
86
+ await writeFile(tmp, `${process.pid}:${Date.now()}`, "utf8");
87
+ await rename(tmp, ownerFile);
88
+ }
89
+ catch {
90
+ /* lock released/reclaimed underneath — nothing useful to do here */
91
+ }
92
+ });
93
+ }, opts.heartbeatMs);
94
+ heartbeat.unref?.();
95
+ }
66
96
  try {
67
97
  return await fn();
68
98
  }
69
99
  finally {
100
+ if (heartbeat)
101
+ clearInterval(heartbeat);
102
+ await stampWrites; // no stamp write may survive into (or past) the removal below
70
103
  await rm(lockPath, { recursive: true, force: true });
71
104
  }
72
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@izagood/avcs",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "description": "Agentic Version Control System — an AI-native VCS where intent, session, operation, evidence and decision are first-class objects and code is a materialized projection of an operation graph.",
6
6
  "license": "Apache-2.0",