@izagood/avcs 0.1.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 (111) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +221 -0
  3. package/dist/api/repo.d.ts +616 -0
  4. package/dist/api/repo.d.ts.map +1 -0
  5. package/dist/api/repo.js +1772 -0
  6. package/dist/api/repo.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +660 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/concurrency/lease.d.ts +27 -0
  12. package/dist/concurrency/lease.d.ts.map +1 -0
  13. package/dist/concurrency/lease.js +63 -0
  14. package/dist/concurrency/lease.js.map +1 -0
  15. package/dist/core/canonical.d.ts +16 -0
  16. package/dist/core/canonical.d.ts.map +1 -0
  17. package/dist/core/canonical.js +66 -0
  18. package/dist/core/canonical.js.map +1 -0
  19. package/dist/core/cbor.d.ts +9 -0
  20. package/dist/core/cbor.d.ts.map +1 -0
  21. package/dist/core/cbor.js +213 -0
  22. package/dist/core/cbor.js.map +1 -0
  23. package/dist/core/clock.d.ts +18 -0
  24. package/dist/core/clock.d.ts.map +1 -0
  25. package/dist/core/clock.js +32 -0
  26. package/dist/core/clock.js.map +1 -0
  27. package/dist/core/identity.d.ts +34 -0
  28. package/dist/core/identity.d.ts.map +1 -0
  29. package/dist/core/identity.js +62 -0
  30. package/dist/core/identity.js.map +1 -0
  31. package/dist/hub/hubClient.d.ts +38 -0
  32. package/dist/hub/hubClient.d.ts.map +1 -0
  33. package/dist/hub/hubClient.js +157 -0
  34. package/dist/hub/hubClient.js.map +1 -0
  35. package/dist/hub/hubServer.d.ts +28 -0
  36. package/dist/hub/hubServer.d.ts.map +1 -0
  37. package/dist/hub/hubServer.js +365 -0
  38. package/dist/hub/hubServer.js.map +1 -0
  39. package/dist/index.d.ts +13 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +19 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/objects/types.d.ts +352 -0
  44. package/dist/objects/types.d.ts.map +1 -0
  45. package/dist/objects/types.js +17 -0
  46. package/dist/objects/types.js.map +1 -0
  47. package/dist/observe/logger.d.ts +27 -0
  48. package/dist/observe/logger.d.ts.map +1 -0
  49. package/dist/observe/logger.js +37 -0
  50. package/dist/observe/logger.js.map +1 -0
  51. package/dist/observe/metrics.d.ts +20 -0
  52. package/dist/observe/metrics.d.ts.map +1 -0
  53. package/dist/observe/metrics.js +42 -0
  54. package/dist/observe/metrics.js.map +1 -0
  55. package/dist/policy/owners.d.ts +5 -0
  56. package/dist/policy/owners.d.ts.map +1 -0
  57. package/dist/policy/owners.js +38 -0
  58. package/dist/policy/owners.js.map +1 -0
  59. package/dist/policy/reliability.d.ts +7 -0
  60. package/dist/policy/reliability.d.ts.map +1 -0
  61. package/dist/policy/reliability.js +41 -0
  62. package/dist/policy/reliability.js.map +1 -0
  63. package/dist/query/diff.d.ts +16 -0
  64. package/dist/query/diff.d.ts.map +1 -0
  65. package/dist/query/diff.js +32 -0
  66. package/dist/query/diff.js.map +1 -0
  67. package/dist/reducer/incremental.d.ts +2 -0
  68. package/dist/reducer/incremental.d.ts.map +1 -0
  69. package/dist/reducer/incremental.js +14 -0
  70. package/dist/reducer/incremental.js.map +1 -0
  71. package/dist/reducer/policy.d.ts +17 -0
  72. package/dist/reducer/policy.d.ts.map +1 -0
  73. package/dist/reducer/policy.js +143 -0
  74. package/dist/reducer/policy.js.map +1 -0
  75. package/dist/reducer/reducer.d.ts +155 -0
  76. package/dist/reducer/reducer.d.ts.map +1 -0
  77. package/dist/reducer/reducer.js +849 -0
  78. package/dist/reducer/reducer.js.map +1 -0
  79. package/dist/release/sbom.d.ts +7 -0
  80. package/dist/release/sbom.d.ts.map +1 -0
  81. package/dist/release/sbom.js +26 -0
  82. package/dist/release/sbom.js.map +1 -0
  83. package/dist/semantic/contract.d.ts +32 -0
  84. package/dist/semantic/contract.d.ts.map +1 -0
  85. package/dist/semantic/contract.js +150 -0
  86. package/dist/semantic/contract.js.map +1 -0
  87. package/dist/semantic/symbols.d.ts +45 -0
  88. package/dist/semantic/symbols.d.ts.map +1 -0
  89. package/dist/semantic/symbols.js +323 -0
  90. package/dist/semantic/symbols.js.map +1 -0
  91. package/dist/store/applyRedactions.d.ts +16 -0
  92. package/dist/store/applyRedactions.d.ts.map +1 -0
  93. package/dist/store/applyRedactions.js +60 -0
  94. package/dist/store/applyRedactions.js.map +1 -0
  95. package/dist/store/lock.d.ts +12 -0
  96. package/dist/store/lock.d.ts.map +1 -0
  97. package/dist/store/lock.js +63 -0
  98. package/dist/store/lock.js.map +1 -0
  99. package/dist/store/objectStore.d.ts +127 -0
  100. package/dist/store/objectStore.d.ts.map +1 -0
  101. package/dist/store/objectStore.js +549 -0
  102. package/dist/store/objectStore.js.map +1 -0
  103. package/dist/validation/repair.d.ts +31 -0
  104. package/dist/validation/repair.d.ts.map +1 -0
  105. package/dist/validation/repair.js +37 -0
  106. package/dist/validation/repair.js.map +1 -0
  107. package/dist/validation/runner.d.ts +20 -0
  108. package/dist/validation/runner.d.ts.map +1 -0
  109. package/dist/validation/runner.js +90 -0
  110. package/dist/validation/runner.js.map +1 -0
  111. package/package.json +83 -0
@@ -0,0 +1,62 @@
1
+ // Phase 3: cryptographic identity.
2
+ //
3
+ // Until now "this evidence came from ci_bot" and "a human made this decision" were
4
+ // self-reported strings an agent could forge. Identity makes them checkable: an
5
+ // actor holds an ed25519 keypair, signs the content-address (oid) of objects it
6
+ // produces, and the reducer's trust gate only honors evidence/decisions whose
7
+ // signature verifies against a registered public key for the claimed actor.
8
+ //
9
+ // ed25519 via node:crypto — no external dependency.
10
+ import { generateKeyPairSync, sign as nodeSign, verify as nodeVerify } from "node:crypto";
11
+ import { Buffer } from "node:buffer";
12
+ export function generateKeypair() {
13
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
14
+ publicKeyEncoding: { type: "spki", format: "pem" },
15
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
16
+ });
17
+ return { publicKey: publicKey, privateKey: privateKey };
18
+ }
19
+ export function signMessage(privateKeyPem, message) {
20
+ // ed25519 is a one-shot signature: algorithm arg is null.
21
+ return nodeSign(null, Buffer.from(message, "utf8"), privateKeyPem).toString("base64");
22
+ }
23
+ export function verifyMessage(publicKeyPem, message, sigB64) {
24
+ try {
25
+ return nodeVerify(null, Buffer.from(message, "utf8"), publicKeyPem, Buffer.from(sigB64, "base64"));
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ /** A registry of trusted public keys, keyed by keyId. */
32
+ export class Keyring {
33
+ #keys = new Map();
34
+ register(rec) {
35
+ this.#keys.set(rec.keyId, rec);
36
+ }
37
+ get(keyId) {
38
+ return this.#keys.get(keyId);
39
+ }
40
+ has(keyId) {
41
+ return this.#keys.has(keyId);
42
+ }
43
+ get size() {
44
+ return this.#keys.size;
45
+ }
46
+ /**
47
+ * Verify a signature over `oid`, claimed to come from `claimedActorId`.
48
+ * Returns true only if the signing key is registered AND its registered actor
49
+ * matches the claim — i.e. you cannot sign as ci_bot with ai_agent's key.
50
+ */
51
+ verifyFor(claimedActorId, oid, sig) {
52
+ if (!sig)
53
+ return false;
54
+ const rec = this.#keys.get(sig.keyId);
55
+ if (!rec)
56
+ return false;
57
+ if (rec.actorId !== claimedActorId)
58
+ return false;
59
+ return verifyMessage(rec.publicKey, oid, sig.sig);
60
+ }
61
+ }
62
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/core/identity.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,mFAAmF;AACnF,gFAAgF;AAChF,gFAAgF;AAChF,8EAA8E;AAC9E,4EAA4E;AAC5E,EAAE;AACF,oDAAoD;AAEpD,OAAO,EAAE,mBAAmB,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAcrC,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,mBAAmB,CAAC,SAAS,EAAE;QAC/D,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;QAClD,kBAAkB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;KACrD,CAAC,CAAC;IACH,OAAO,EAAE,SAAS,EAAE,SAAmB,EAAE,UAAU,EAAE,UAAoB,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAqB,EAAE,OAAe;IAChE,0DAA0D;IAC1D,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,OAAe,EAAE,MAAc;IACjF,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AASD,yDAAyD;AACzD,MAAM,OAAO,OAAO;IAClB,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAErC,QAAQ,CAAC,GAAc;QACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IACD,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,cAAsB,EAAE,GAAW,EAAE,GAA0B;QACvE,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACvB,IAAI,GAAG,CAAC,OAAO,KAAK,cAAc;YAAE,OAAO,KAAK,CAAC;QACjD,OAAO,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Push objects the hub lacks: diff our local oids against GET /have and POST the
3
+ * missing ones. Private (stash) ops are local-only and never gossiped — same rule as
4
+ * Repo.pull. Returns how many objects were pushed.
5
+ */
6
+ export declare function pushToHub(localRepoDir: string, hubUrl: string): Promise<{
7
+ pushed: number;
8
+ rejected: number;
9
+ }>;
10
+ /**
11
+ * Pull objects the local store lacks: GET /have, then GET each missing /objects/:oid
12
+ * and put it locally (idempotent, content-addressed). Returns how many were pulled.
13
+ */
14
+ export declare function pullFromHub(localRepoDir: string, hubUrl: string): Promise<{
15
+ pulled: number;
16
+ }>;
17
+ /**
18
+ * Request a finalize (= PR merge) on the hub (E6): POST /finalize with the view, the new
19
+ * checkpoint, the parent head being compare-and-swapped, and the finalizer. The hub runs
20
+ * the authoritative CAS+lock+gates. When `signWith` is given the request is signed so a
21
+ * gated hub can authenticate the finalizer. Returns the HTTP status + the hub's verdict.
22
+ */
23
+ export declare function finalizeOnHub(hubUrl: string, args: {
24
+ view: string;
25
+ newCheckpoint: string;
26
+ parentHead: string | null;
27
+ by: string;
28
+ signWith?: {
29
+ keyId: string;
30
+ privateKey: string;
31
+ };
32
+ }): Promise<{
33
+ status: number;
34
+ finalized: boolean;
35
+ head?: string;
36
+ reason?: string;
37
+ }>;
38
+ //# sourceMappingURL=hubClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubClient.d.ts","sourceRoot":"","sources":["../../src/hub/hubClient.ts"],"names":[],"mappings":"AAsDA;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBnH;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsCnG;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACrI,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAWjF"}
@@ -0,0 +1,157 @@
1
+ // Network object-gossip client against an AVCS hub (see hubServer.ts).
2
+ //
3
+ // Content-addressed union semantics, mirroring Repo.pull: only transfer what's missing,
4
+ // never mutate an existing object. push = send objects the hub lacks; pull = fetch
5
+ // objects we lack. Uses the global fetch available in Node 22.
6
+ import { existsSync } from "node:fs";
7
+ import { readFile } from "node:fs/promises";
8
+ import { join } from "node:path";
9
+ import { ObjectStore } from "../store/objectStore.js";
10
+ import { keysOf } from "../reducer/reducer.js";
11
+ /** GET /have → the set of oids the hub holds. */
12
+ async function hubHave(hubUrl) {
13
+ const res = await fetch(`${hubUrl.replace(/\/$/, "")}/have`);
14
+ if (!res.ok)
15
+ throw new Error(`GET /have failed: ${res.status} ${res.statusText}`);
16
+ const oids = (await res.json());
17
+ return new Set(oids);
18
+ }
19
+ /** Per-hub sync cursors persisted under .avcs/sync-cursors.json (E5). */
20
+ async function readCursors(root) {
21
+ const p = join(root, "sync-cursors.json");
22
+ if (!existsSync(p))
23
+ return {};
24
+ try {
25
+ return JSON.parse(await readFile(p, "utf8"));
26
+ }
27
+ catch {
28
+ return {};
29
+ }
30
+ }
31
+ /**
32
+ * Discover the oids to consider pulling. Tries the incremental `GET /sync?since=N`
33
+ * endpoint (E5): only the oids appended since the client's last cursor, plus the new
34
+ * cursor. Falls back to the full `GET /have` against an older hub (cursor stays null).
35
+ * Correctness never depends on the cursor — a wrong/stale one at worst transfers more.
36
+ */
37
+ async function discover(base, since) {
38
+ try {
39
+ const res = await fetch(`${base}/sync?since=${since}`);
40
+ if (res.ok) {
41
+ const j = (await res.json());
42
+ return { oids: j.oids, cursor: j.cursor };
43
+ }
44
+ }
45
+ catch {
46
+ // fall through to /have
47
+ }
48
+ return { oids: [...(await hubHave(base))], cursor: null };
49
+ }
50
+ /** Mirror Repo.pull's import side-effect: maintain the entity index for imported ops. */
51
+ async function indexIfOperation(store, obj, oid) {
52
+ if (obj.type === "operation") {
53
+ for (const k of keysOf(obj))
54
+ await store.appendEntityIndex(k, oid);
55
+ }
56
+ }
57
+ /**
58
+ * Push objects the hub lacks: diff our local oids against GET /have and POST the
59
+ * missing ones. Private (stash) ops are local-only and never gossiped — same rule as
60
+ * Repo.pull. Returns how many objects were pushed.
61
+ */
62
+ export async function pushToHub(localRepoDir, hubUrl) {
63
+ const base = hubUrl.replace(/\/$/, "");
64
+ const store = new ObjectStore(localRepoDir);
65
+ const have = await hubHave(base);
66
+ let pushed = 0;
67
+ let rejected = 0;
68
+ for await (const obj of store.list()) {
69
+ const oid = obj.oid;
70
+ if (have.has(oid))
71
+ continue;
72
+ if (obj.type === "operation" && obj.private)
73
+ continue; // stash stays local
74
+ const res = await fetch(`${base}/objects`, {
75
+ method: "POST",
76
+ headers: { "content-type": "application/json" },
77
+ body: JSON.stringify(obj),
78
+ });
79
+ if (res.status === 403) {
80
+ rejected++; // gated hub refused an unauthorized op
81
+ continue;
82
+ }
83
+ if (!res.ok)
84
+ throw new Error(`POST /objects failed for ${oid}: ${res.status} ${res.statusText}`);
85
+ pushed++;
86
+ }
87
+ return { pushed, rejected };
88
+ }
89
+ /**
90
+ * Pull objects the local store lacks: GET /have, then GET each missing /objects/:oid
91
+ * and put it locally (idempotent, content-addressed). Returns how many were pulled.
92
+ */
93
+ export async function pullFromHub(localRepoDir, hubUrl) {
94
+ const base = hubUrl.replace(/\/$/, "");
95
+ const store = new ObjectStore(localRepoDir);
96
+ await store.init(); // tolerate a fresh local repo dir
97
+ // Incremental discovery (E5): only consider oids the hub added since our last pull.
98
+ const cursors = await readCursors(store.root);
99
+ const since = cursors[base] ?? 0;
100
+ const { oids, cursor } = await discover(base, since);
101
+ let pulled = 0;
102
+ for (const oid of oids) {
103
+ if (await store.has(oid))
104
+ continue;
105
+ const res = await fetch(`${base}/objects/${encodeURIComponent(oid)}`);
106
+ if (res.status === 404)
107
+ continue; // raced eviction; skip
108
+ if (!res.ok)
109
+ throw new Error(`GET /objects/${oid} failed: ${res.status} ${res.statusText}`);
110
+ const obj = (await res.json());
111
+ await store.put(obj);
112
+ await indexIfOperation(store, obj, oid);
113
+ pulled++;
114
+ }
115
+ // Advance the cursor only after the loop completed (a throw aborts before this, so a
116
+ // failed pull retries from the same cursor next time — never a permanent miss).
117
+ if (cursor !== null) {
118
+ cursors[base] = cursor;
119
+ await store.writeAux("sync-cursors.json", JSON.stringify(cursors));
120
+ }
121
+ // Governance distribution: adopt the hub's authoritative governance refs (policy,
122
+ // membership, protection, protected heads). The objects they point to were just
123
+ // pulled above, so the refs resolve. Working refs (view:*/checkpoint:*) stay local.
124
+ const refsRes = await fetch(`${base}/refs`);
125
+ if (refsRes.ok) {
126
+ const { refs } = (await refsRes.json());
127
+ for (const [name, refOid] of Object.entries(refs)) {
128
+ if (!/^(policy$|member:|protection:|head:)/.test(name))
129
+ continue;
130
+ if (await store.has(refOid))
131
+ await store.setRef(name, refOid);
132
+ }
133
+ }
134
+ // Propagate redactions: evict plaintext for blobs redacted after we pulled them.
135
+ const { applyRedactions } = await import("./../store/applyRedactions.js");
136
+ await applyRedactions(store);
137
+ return { pulled };
138
+ }
139
+ /**
140
+ * Request a finalize (= PR merge) on the hub (E6): POST /finalize with the view, the new
141
+ * checkpoint, the parent head being compare-and-swapped, and the finalizer. The hub runs
142
+ * the authoritative CAS+lock+gates. When `signWith` is given the request is signed so a
143
+ * gated hub can authenticate the finalizer. Returns the HTTP status + the hub's verdict.
144
+ */
145
+ export async function finalizeOnHub(hubUrl, args) {
146
+ const base = hubUrl.replace(/\/$/, "");
147
+ const body = { view: args.view, newCheckpoint: args.newCheckpoint, parentHead: args.parentHead, by: args.by };
148
+ if (args.signWith) {
149
+ const { signMessage } = await import("../core/identity.js");
150
+ const msg = `finalize:${args.view}:${args.newCheckpoint}:${args.parentHead ?? ""}`;
151
+ body.sig = { keyId: args.signWith.keyId, alg: "ed25519", sig: signMessage(args.signWith.privateKey, msg) };
152
+ }
153
+ const res = await fetch(`${base}/finalize`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) });
154
+ const j = (await res.json().catch(() => ({})));
155
+ return { status: res.status, finalized: j.finalized ?? false, head: j.head, reason: j.reason };
156
+ }
157
+ //# sourceMappingURL=hubClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubClient.js","sourceRoot":"","sources":["../../src/hub/hubClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type Logger } from "../observe/logger.ts";
2
+ import { Metrics } from "../observe/metrics.ts";
3
+ /** Wire-protocol version the hub speaks (have/objects/refs gossip). Bumped on breaking changes. */
4
+ export declare const HUB_PROTOCOL_VERSION = 1;
5
+ export interface HubHandle {
6
+ url: string;
7
+ port: number;
8
+ metrics: Metrics;
9
+ close(): Promise<void>;
10
+ }
11
+ /**
12
+ * Start an HTTP hub backed by `new ObjectStore(opts.repoDir)`. The store is init()'d
13
+ * so an empty repo dir works. Pass `port: 0` (or omit) to get an OS-assigned port,
14
+ * read back from the returned handle.
15
+ */
16
+ export declare function startHub(opts: {
17
+ repoDir: string;
18
+ port?: number;
19
+ gated?: boolean;
20
+ logger?: Logger;
21
+ metrics?: Metrics;
22
+ /** App-layer per-actor push quota (E7). Omit to disable. */
23
+ rateLimit?: {
24
+ maxPerWindow: number;
25
+ windowMs?: number;
26
+ };
27
+ }): Promise<HubHandle>;
28
+ //# sourceMappingURL=hubServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubServer.d.ts","sourceRoot":"","sources":["../../src/hub/hubServer.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAOhD,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAgFD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IACpF,4DAA4D;IAC5D,SAAS,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD,GAAG,OAAO,CAAC,SAAS,CAAC,CAiErB"}