@mneme-ai/core 2.12.0 → 2.13.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.
- package/dist/cosmic/aurelian.bench.d.ts +25 -0
- package/dist/cosmic/aurelian.bench.d.ts.map +1 -0
- package/dist/cosmic/aurelian.bench.js +127 -0
- package/dist/cosmic/aurelian.bench.js.map +1 -0
- package/dist/cosmic/aurelian_audit.d.ts +112 -0
- package/dist/cosmic/aurelian_audit.d.ts.map +1 -0
- package/dist/cosmic/aurelian_audit.js +236 -0
- package/dist/cosmic/aurelian_audit.js.map +1 -0
- package/dist/cosmic/aurelian_recheck.test.d.ts +25 -0
- package/dist/cosmic/aurelian_recheck.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_recheck.test.js +127 -0
- package/dist/cosmic/aurelian_recheck.test.js.map +1 -0
- package/dist/cosmic/benchmark.d.ts +47 -0
- package/dist/cosmic/benchmark.d.ts.map +1 -0
- package/dist/cosmic/benchmark.js +162 -0
- package/dist/cosmic/benchmark.js.map +1 -0
- package/dist/cosmic/choir.d.ts +93 -0
- package/dist/cosmic/choir.d.ts.map +1 -0
- package/dist/cosmic/choir.js +140 -0
- package/dist/cosmic/choir.js.map +1 -0
- package/dist/cosmic/diff.d.ts +41 -0
- package/dist/cosmic/diff.d.ts.map +1 -0
- package/dist/cosmic/diff.js +154 -0
- package/dist/cosmic/diff.js.map +1 -0
- package/dist/cosmic/echo_commit.d.ts +79 -0
- package/dist/cosmic/echo_commit.d.ts.map +1 -0
- package/dist/cosmic/echo_commit.js +108 -0
- package/dist/cosmic/echo_commit.js.map +1 -0
- package/dist/cosmic/echo_commit.test.d.ts +2 -0
- package/dist/cosmic/echo_commit.test.d.ts.map +1 -0
- package/dist/cosmic/echo_commit.test.js +81 -0
- package/dist/cosmic/echo_commit.test.js.map +1 -0
- package/dist/cosmic/index.d.ts +32 -0
- package/dist/cosmic/index.d.ts.map +1 -1
- package/dist/cosmic/index.js +94 -19
- package/dist/cosmic/index.js.map +1 -1
- package/dist/cosmic/v213.test.d.ts +2 -0
- package/dist/cosmic/v213.test.d.ts.map +1 -0
- package/dist/cosmic/v213.test.js +267 -0
- package/dist/cosmic/v213.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/cosmic/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,SAAS,GAAG,OAAO,CAAC;AAoBzB;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,SAAK,GAAG,WAAW,EAAE,CA8BzF;AAoBD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,SAAS,CAM1E;AA4BD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAK/E"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.13.0 — Minimal JSON Patch (RFC 6902 subset) for cosmic incremental
|
|
3
|
+
* publishes.
|
|
4
|
+
*
|
|
5
|
+
* Why not pull a dep? Cosmic state is small (typically < 4KB), the patch
|
|
6
|
+
* shape is bounded (publishes are version + commit + timestamp updates),
|
|
7
|
+
* and the cosmic server is single-file zero-deps. A 100-line implementation
|
|
8
|
+
* we control beats a 50KB transitive tree we don't.
|
|
9
|
+
*
|
|
10
|
+
* Supported ops: add / replace / remove. Move/copy/test omitted as they
|
|
11
|
+
* don't appear in any cosmic state-update pattern.
|
|
12
|
+
*
|
|
13
|
+
* Path encoding follows RFC 6901 (JSON Pointer): "/a/b" → state.a.b.
|
|
14
|
+
* "/" is the root. ~0 escapes ~, ~1 escapes /.
|
|
15
|
+
*/
|
|
16
|
+
function isObject(v) {
|
|
17
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
18
|
+
}
|
|
19
|
+
function escapePart(s) {
|
|
20
|
+
return s.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
21
|
+
}
|
|
22
|
+
function unescapePart(s) {
|
|
23
|
+
return s.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
24
|
+
}
|
|
25
|
+
function pointerToParts(ptr) {
|
|
26
|
+
if (ptr === "" || ptr === "/")
|
|
27
|
+
return [];
|
|
28
|
+
return ptr.split("/").slice(1).map(unescapePart);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Diff two JSON values; returns a list of patch ops that, applied to `before`,
|
|
32
|
+
* produce `after`. Optimised for cosmic state shape (objects of scalars +
|
|
33
|
+
* small arrays). Arrays are handled by full-replace when they differ — a
|
|
34
|
+
* cosmic publish never makes large array edits, so structural array diffing
|
|
35
|
+
* isn't worth the byte cost.
|
|
36
|
+
*/
|
|
37
|
+
export function makePatch(before, after, prefix = "") {
|
|
38
|
+
// Same reference / primitive equal — no-op.
|
|
39
|
+
if (before === after)
|
|
40
|
+
return [];
|
|
41
|
+
if (typeof before !== typeof after || Array.isArray(before) !== Array.isArray(after) || (before === null) !== (after === null)) {
|
|
42
|
+
return [{ op: "replace", path: prefix || "/", value: after }];
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(before) && Array.isArray(after)) {
|
|
45
|
+
// Compare structurally; if arrays match shallowly, no op. Otherwise replace.
|
|
46
|
+
if (before.length === after.length && before.every((v, i) => deepEqual(v, after[i])))
|
|
47
|
+
return [];
|
|
48
|
+
return [{ op: "replace", path: prefix || "/", value: after }];
|
|
49
|
+
}
|
|
50
|
+
if (isObject(before) && isObject(after)) {
|
|
51
|
+
const ops = [];
|
|
52
|
+
// Removals first — keys present in before but not after.
|
|
53
|
+
for (const k of Object.keys(before)) {
|
|
54
|
+
if (!(k in after))
|
|
55
|
+
ops.push({ op: "remove", path: `${prefix}/${escapePart(k)}` });
|
|
56
|
+
}
|
|
57
|
+
// Additions / replacements.
|
|
58
|
+
for (const k of Object.keys(after)) {
|
|
59
|
+
const path = `${prefix}/${escapePart(k)}`;
|
|
60
|
+
if (!(k in before))
|
|
61
|
+
ops.push({ op: "add", path, value: after[k] });
|
|
62
|
+
else if (!deepEqual(before[k], after[k])) {
|
|
63
|
+
// Recurse so we get fine-grained patches inside nested objects.
|
|
64
|
+
ops.push(...makePatch(before[k], after[k], path));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return ops;
|
|
68
|
+
}
|
|
69
|
+
// Both are scalars and differ.
|
|
70
|
+
return [{ op: "replace", path: prefix || "/", value: after }];
|
|
71
|
+
}
|
|
72
|
+
function deepEqual(a, b) {
|
|
73
|
+
if (a === b)
|
|
74
|
+
return true;
|
|
75
|
+
if (a === null || b === null)
|
|
76
|
+
return a === b;
|
|
77
|
+
if (typeof a !== typeof b)
|
|
78
|
+
return false;
|
|
79
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
80
|
+
if (a.length !== b.length)
|
|
81
|
+
return false;
|
|
82
|
+
for (let i = 0; i < a.length; i++)
|
|
83
|
+
if (!deepEqual(a[i], b[i]))
|
|
84
|
+
return false;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (isObject(a) && isObject(b)) {
|
|
88
|
+
const ak = Object.keys(a), bk = Object.keys(b);
|
|
89
|
+
if (ak.length !== bk.length)
|
|
90
|
+
return false;
|
|
91
|
+
for (const k of ak)
|
|
92
|
+
if (!deepEqual(a[k], b[k]))
|
|
93
|
+
return false;
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
/** Apply a patch list to a deep copy of `state` and return the new value. */
|
|
99
|
+
export function applyPatch(state, ops) {
|
|
100
|
+
let cur = JSON.parse(JSON.stringify(state ?? null));
|
|
101
|
+
for (const op of ops) {
|
|
102
|
+
cur = applyOne(cur, op);
|
|
103
|
+
}
|
|
104
|
+
return cur;
|
|
105
|
+
}
|
|
106
|
+
function applyOne(state, op) {
|
|
107
|
+
const parts = pointerToParts(op.path);
|
|
108
|
+
if (parts.length === 0) {
|
|
109
|
+
// Operating on root.
|
|
110
|
+
if (op.op === "remove")
|
|
111
|
+
return null;
|
|
112
|
+
return op.value ?? null;
|
|
113
|
+
}
|
|
114
|
+
const last = parts[parts.length - 1];
|
|
115
|
+
let cur = state;
|
|
116
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
117
|
+
const k = parts[i];
|
|
118
|
+
if (!isObject(cur) && !Array.isArray(cur))
|
|
119
|
+
throw new Error(`patch path traverses non-object at ${parts.slice(0, i + 1).join("/")}`);
|
|
120
|
+
cur = cur[k];
|
|
121
|
+
if (cur === undefined)
|
|
122
|
+
throw new Error(`patch path missing at ${parts.slice(0, i + 1).join("/")}`);
|
|
123
|
+
}
|
|
124
|
+
if (!isObject(cur) && !Array.isArray(cur))
|
|
125
|
+
throw new Error(`patch parent not container for ${op.path}`);
|
|
126
|
+
if (op.op === "remove") {
|
|
127
|
+
if (Array.isArray(cur))
|
|
128
|
+
cur.splice(parseInt(last, 10), 1);
|
|
129
|
+
else
|
|
130
|
+
delete cur[last];
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
if (Array.isArray(cur))
|
|
134
|
+
cur[parseInt(last, 10)] = op.value;
|
|
135
|
+
else
|
|
136
|
+
cur[last] = op.value;
|
|
137
|
+
}
|
|
138
|
+
return state;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Decide whether a patch is "worth shipping" vs sending the full state.
|
|
142
|
+
* For cosmic, shipping the patch is only smarter than the full state when
|
|
143
|
+
* the patch is materially smaller. We require at least 30% reduction OR
|
|
144
|
+
* a 200-byte savings — below that, the round-trip risk (server applies
|
|
145
|
+
* patch wrong, drift) outweighs the byte win.
|
|
146
|
+
*/
|
|
147
|
+
export function patchIsWorthIt(beforeBytes, patchBytes) {
|
|
148
|
+
const saving = beforeBytes - patchBytes;
|
|
149
|
+
if (saving <= 0)
|
|
150
|
+
return false;
|
|
151
|
+
const ratio = saving / beforeBytes;
|
|
152
|
+
return ratio >= 0.3 || saving >= 200;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/cosmic/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.13.0 — ECHO-FROM-COMMITS
|
|
3
|
+
*
|
|
4
|
+
* "When every server in your choir is unreachable AND your laptop is
|
|
5
|
+
* closed AND the dpaste rescue paste was deleted — git itself still
|
|
6
|
+
* remembers. The last cosmic state lives as an HMAC-signed git note
|
|
7
|
+
* on HEAD. Clone the repo, run `git notes show`, recover the state
|
|
8
|
+
* with zero network."
|
|
9
|
+
*
|
|
10
|
+
* Wild because: every other handoff system assumes "the network is up".
|
|
11
|
+
* ECHO-FROM-COMMITS treats the user's git history as the deepest possible
|
|
12
|
+
* fallback. State travels with the code that produced it. A teammate
|
|
13
|
+
* pulling the repo six months later can verify what the AI thought was
|
|
14
|
+
* true at commit X.
|
|
15
|
+
*
|
|
16
|
+
* Wise because: it composes with git's existing storage, refspecs, and
|
|
17
|
+
* push semantics. Nothing custom; just a structured payload in the
|
|
18
|
+
* `refs/notes/cosmic` namespace.
|
|
19
|
+
*
|
|
20
|
+
* Performance: writes ~1KB per commit. git's own gc handles cleanup.
|
|
21
|
+
* Reads are O(1) via `git notes show`.
|
|
22
|
+
*/
|
|
23
|
+
export interface EchoEnvelope {
|
|
24
|
+
v: 1;
|
|
25
|
+
/** ISO timestamp of when the echo was written. */
|
|
26
|
+
ts: string;
|
|
27
|
+
/** Cosmic state at the time of the echo. */
|
|
28
|
+
state: Record<string, unknown>;
|
|
29
|
+
/** Optional cosmic publicUrl — useful for the reader to know the live URL. */
|
|
30
|
+
cosmicUrl?: string;
|
|
31
|
+
/** Per-seat hashes if echoed alongside a CELESTIAL CHOIR session. */
|
|
32
|
+
choirHashes?: Array<{
|
|
33
|
+
serverUrl: string;
|
|
34
|
+
stateHash: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** HMAC over canonical(envelope-without-sig). */
|
|
37
|
+
sig: string;
|
|
38
|
+
}
|
|
39
|
+
export interface WriteEchoInput {
|
|
40
|
+
repoDir: string;
|
|
41
|
+
commitSha?: string;
|
|
42
|
+
state: Record<string, unknown>;
|
|
43
|
+
cosmicUrl?: string;
|
|
44
|
+
choirHashes?: Array<{
|
|
45
|
+
serverUrl: string;
|
|
46
|
+
stateHash: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** HMAC secret — must be the same secret the reader uses to verify. */
|
|
49
|
+
secret: string;
|
|
50
|
+
}
|
|
51
|
+
export interface WriteEchoResult {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
commitSha?: string;
|
|
54
|
+
envelope?: EchoEnvelope;
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Write an HMAC-signed echo envelope as a git note on the target commit. */
|
|
58
|
+
export declare function writeEchoToCommit(input: WriteEchoInput): WriteEchoResult;
|
|
59
|
+
export interface ReadEchoResult {
|
|
60
|
+
ok: boolean;
|
|
61
|
+
commitSha?: string;
|
|
62
|
+
envelope?: EchoEnvelope;
|
|
63
|
+
/** True iff the HMAC verified against the supplied secret. */
|
|
64
|
+
verified: boolean;
|
|
65
|
+
reason?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Read + verify an echo envelope from the target commit. */
|
|
68
|
+
export declare function readEchoFromCommit(repoDir: string, commitSha: string | undefined, secret: string): ReadEchoResult;
|
|
69
|
+
/** Push the echoes ref to a remote so collaborators get them on fetch. */
|
|
70
|
+
export declare function pushEchoesToRemote(repoDir: string, remote?: string): {
|
|
71
|
+
ok: boolean;
|
|
72
|
+
error?: string;
|
|
73
|
+
};
|
|
74
|
+
/** Pull the echoes ref from a remote. */
|
|
75
|
+
export declare function fetchEchoesFromRemote(repoDir: string, remote?: string): {
|
|
76
|
+
ok: boolean;
|
|
77
|
+
error?: string;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=echo_commit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo_commit.d.ts","sourceRoot":"","sources":["../../src/cosmic/echo_commit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,CAAC,CAAC;IACL,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;CACb;AAmBD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAyBxE;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAoBjH;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAGtG;AAED,yCAAyC;AACzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAGzG"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.13.0 — ECHO-FROM-COMMITS
|
|
3
|
+
*
|
|
4
|
+
* "When every server in your choir is unreachable AND your laptop is
|
|
5
|
+
* closed AND the dpaste rescue paste was deleted — git itself still
|
|
6
|
+
* remembers. The last cosmic state lives as an HMAC-signed git note
|
|
7
|
+
* on HEAD. Clone the repo, run `git notes show`, recover the state
|
|
8
|
+
* with zero network."
|
|
9
|
+
*
|
|
10
|
+
* Wild because: every other handoff system assumes "the network is up".
|
|
11
|
+
* ECHO-FROM-COMMITS treats the user's git history as the deepest possible
|
|
12
|
+
* fallback. State travels with the code that produced it. A teammate
|
|
13
|
+
* pulling the repo six months later can verify what the AI thought was
|
|
14
|
+
* true at commit X.
|
|
15
|
+
*
|
|
16
|
+
* Wise because: it composes with git's existing storage, refspecs, and
|
|
17
|
+
* push semantics. Nothing custom; just a structured payload in the
|
|
18
|
+
* `refs/notes/cosmic` namespace.
|
|
19
|
+
*
|
|
20
|
+
* Performance: writes ~1KB per commit. git's own gc handles cleanup.
|
|
21
|
+
* Reads are O(1) via `git notes show`.
|
|
22
|
+
*/
|
|
23
|
+
import { spawnSync } from "node:child_process";
|
|
24
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
25
|
+
const NOTES_REF = "refs/notes/cosmic";
|
|
26
|
+
function gitArgs(repoDir, args) {
|
|
27
|
+
const r = spawnSync("git", args, { cwd: repoDir, encoding: "utf8" });
|
|
28
|
+
return { ok: r.status === 0, stdout: r.stdout?.trim() ?? "", stderr: r.stderr?.trim() ?? "" };
|
|
29
|
+
}
|
|
30
|
+
/** Stable JSON serialisation so the HMAC matches across implementations. */
|
|
31
|
+
function canonicalise(v) {
|
|
32
|
+
if (v === null || typeof v !== "object")
|
|
33
|
+
return JSON.stringify(v);
|
|
34
|
+
if (Array.isArray(v))
|
|
35
|
+
return "[" + v.map(canonicalise).join(",") + "]";
|
|
36
|
+
const keys = Object.keys(v).sort();
|
|
37
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canonicalise(v[k])).join(",") + "}";
|
|
38
|
+
}
|
|
39
|
+
function signEnvelope(env, secret) {
|
|
40
|
+
return createHmac("sha256", secret).update(canonicalise(env)).digest("hex");
|
|
41
|
+
}
|
|
42
|
+
/** Write an HMAC-signed echo envelope as a git note on the target commit. */
|
|
43
|
+
export function writeEchoToCommit(input) {
|
|
44
|
+
// Resolve target commit.
|
|
45
|
+
const ref = input.commitSha ?? "HEAD";
|
|
46
|
+
const rev = gitArgs(input.repoDir, ["rev-parse", ref]);
|
|
47
|
+
if (!rev.ok)
|
|
48
|
+
return { ok: false, error: `git rev-parse failed: ${rev.stderr}` };
|
|
49
|
+
const sha = rev.stdout;
|
|
50
|
+
const envWithoutSig = {
|
|
51
|
+
v: 1,
|
|
52
|
+
ts: new Date().toISOString(),
|
|
53
|
+
state: input.state,
|
|
54
|
+
...(input.cosmicUrl ? { cosmicUrl: input.cosmicUrl } : {}),
|
|
55
|
+
...(input.choirHashes ? { choirHashes: input.choirHashes } : {}),
|
|
56
|
+
};
|
|
57
|
+
const sig = signEnvelope(envWithoutSig, input.secret);
|
|
58
|
+
const envelope = { ...envWithoutSig, sig };
|
|
59
|
+
const payload = JSON.stringify(envelope);
|
|
60
|
+
// git notes add -f --ref refs/notes/cosmic -m <payload> <sha>
|
|
61
|
+
// -f overwrites any prior echo on the same commit (last-write-wins).
|
|
62
|
+
const add = gitArgs(input.repoDir, [
|
|
63
|
+
"notes", "--ref", NOTES_REF, "add", "-f", "-m", payload, sha,
|
|
64
|
+
]);
|
|
65
|
+
if (!add.ok)
|
|
66
|
+
return { ok: false, error: `git notes add failed: ${add.stderr}` };
|
|
67
|
+
return { ok: true, commitSha: sha, envelope };
|
|
68
|
+
}
|
|
69
|
+
/** Read + verify an echo envelope from the target commit. */
|
|
70
|
+
export function readEchoFromCommit(repoDir, commitSha, secret) {
|
|
71
|
+
const ref = commitSha ?? "HEAD";
|
|
72
|
+
const rev = gitArgs(repoDir, ["rev-parse", ref]);
|
|
73
|
+
if (!rev.ok)
|
|
74
|
+
return { ok: false, verified: false, reason: `git rev-parse failed: ${rev.stderr}` };
|
|
75
|
+
const sha = rev.stdout;
|
|
76
|
+
const show = gitArgs(repoDir, ["notes", "--ref", NOTES_REF, "show", sha]);
|
|
77
|
+
if (!show.ok)
|
|
78
|
+
return { ok: false, commitSha: sha, verified: false, reason: `no echo at ${sha.slice(0, 8)}` };
|
|
79
|
+
let envelope;
|
|
80
|
+
try {
|
|
81
|
+
envelope = JSON.parse(show.stdout);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return { ok: false, commitSha: sha, verified: false, reason: "envelope is not valid JSON" };
|
|
85
|
+
}
|
|
86
|
+
// Verify HMAC.
|
|
87
|
+
const { sig, ...rest } = envelope;
|
|
88
|
+
const expected = signEnvelope(rest, secret);
|
|
89
|
+
let verified = false;
|
|
90
|
+
try {
|
|
91
|
+
verified = timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(sig, "hex"));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
verified = false;
|
|
95
|
+
}
|
|
96
|
+
return { ok: true, commitSha: sha, envelope, verified, reason: verified ? undefined : "HMAC mismatch — wrong secret or tampered" };
|
|
97
|
+
}
|
|
98
|
+
/** Push the echoes ref to a remote so collaborators get them on fetch. */
|
|
99
|
+
export function pushEchoesToRemote(repoDir, remote = "origin") {
|
|
100
|
+
const r = gitArgs(repoDir, ["push", remote, `${NOTES_REF}:${NOTES_REF}`]);
|
|
101
|
+
return { ok: r.ok, error: r.ok ? undefined : r.stderr };
|
|
102
|
+
}
|
|
103
|
+
/** Pull the echoes ref from a remote. */
|
|
104
|
+
export function fetchEchoesFromRemote(repoDir, remote = "origin") {
|
|
105
|
+
const r = gitArgs(repoDir, ["fetch", remote, `${NOTES_REF}:${NOTES_REF}`]);
|
|
106
|
+
return { ok: r.ok, error: r.ok ? undefined : r.stderr };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=echo_commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo_commit.js","sourceRoot":"","sources":["../../src/cosmic/echo_commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo_commit.test.d.ts","sourceRoot":"","sources":["../../src/cosmic/echo_commit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import { writeEchoToCommit, readEchoFromCommit } from "./echo_commit.js";
|
|
7
|
+
function git(repo, args) {
|
|
8
|
+
const r = spawnSync("git", args, { cwd: repo, encoding: "utf8" });
|
|
9
|
+
return { ok: r.status === 0, stdout: r.stdout?.trim() ?? "", stderr: r.stderr?.trim() ?? "" };
|
|
10
|
+
}
|
|
11
|
+
function makeRepo() {
|
|
12
|
+
const dir = mkdtempSync(join(tmpdir(), "cosmic-echo-"));
|
|
13
|
+
git(dir, ["init", "-q"]);
|
|
14
|
+
git(dir, ["config", "user.email", "test@cosmic.local"]);
|
|
15
|
+
git(dir, ["config", "user.name", "Cosmic Test"]);
|
|
16
|
+
// Disable signing so the test runs in CI without GPG.
|
|
17
|
+
git(dir, ["config", "commit.gpgsign", "false"]);
|
|
18
|
+
writeFileSync(join(dir, "README.md"), "test repo for cosmic echo\n");
|
|
19
|
+
git(dir, ["add", "README.md"]);
|
|
20
|
+
const ci = git(dir, ["commit", "-q", "-m", "init"]);
|
|
21
|
+
if (!ci.ok)
|
|
22
|
+
throw new Error(`git commit failed: ${ci.stderr}`);
|
|
23
|
+
return dir;
|
|
24
|
+
}
|
|
25
|
+
describe("v2.13 · ECHO-FROM-COMMITS (HMAC-signed git note)", () => {
|
|
26
|
+
let repo;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
repo = makeRepo();
|
|
29
|
+
});
|
|
30
|
+
it("writes a signed envelope and reads it back verified", () => {
|
|
31
|
+
const w = writeEchoToCommit({
|
|
32
|
+
repoDir: repo,
|
|
33
|
+
state: { v: "2.13.0", note: "echo test" },
|
|
34
|
+
cosmicUrl: "https://cosmic.example.com/sessions/abc",
|
|
35
|
+
secret: "echo-test-secret",
|
|
36
|
+
});
|
|
37
|
+
if (!w.ok) {
|
|
38
|
+
console.error("write failed:", w.error);
|
|
39
|
+
}
|
|
40
|
+
expect(w.ok).toBe(true);
|
|
41
|
+
expect(w.commitSha).toMatch(/^[0-9a-f]{40}$/);
|
|
42
|
+
const r = readEchoFromCommit(repo, w.commitSha, "echo-test-secret");
|
|
43
|
+
expect(r.ok).toBe(true);
|
|
44
|
+
expect(r.verified).toBe(true);
|
|
45
|
+
expect(r.envelope?.state).toEqual({ v: "2.13.0", note: "echo test" });
|
|
46
|
+
expect(r.envelope?.cosmicUrl).toBe("https://cosmic.example.com/sessions/abc");
|
|
47
|
+
});
|
|
48
|
+
it("verify=false when wrong secret presented (tamper-evident)", () => {
|
|
49
|
+
writeEchoToCommit({
|
|
50
|
+
repoDir: repo,
|
|
51
|
+
state: { v: "2.13.0" },
|
|
52
|
+
secret: "right-secret",
|
|
53
|
+
});
|
|
54
|
+
const r = readEchoFromCommit(repo, undefined, "wrong-secret");
|
|
55
|
+
expect(r.ok).toBe(true);
|
|
56
|
+
expect(r.verified).toBe(false);
|
|
57
|
+
expect(r.reason).toContain("HMAC mismatch");
|
|
58
|
+
});
|
|
59
|
+
it("survives state with nested objects + arrays", () => {
|
|
60
|
+
const state = { v: "2.13.0", commits: [{ sha: "abc", subject: "feat" }, { sha: "def", subject: "fix" }], meta: { live: true } };
|
|
61
|
+
const w = writeEchoToCommit({ repoDir: repo, state, secret: "s" });
|
|
62
|
+
expect(w.ok).toBe(true);
|
|
63
|
+
const r = readEchoFromCommit(repo, w.commitSha, "s");
|
|
64
|
+
expect(r.envelope?.state).toEqual(state);
|
|
65
|
+
expect(r.verified).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it("write -f overwrites a prior echo on the same commit", () => {
|
|
68
|
+
const w1 = writeEchoToCommit({ repoDir: repo, state: { v: "first" }, secret: "s" });
|
|
69
|
+
expect(w1.ok).toBe(true);
|
|
70
|
+
const w2 = writeEchoToCommit({ repoDir: repo, state: { v: "second" }, secret: "s" });
|
|
71
|
+
expect(w2.ok).toBe(true);
|
|
72
|
+
const r = readEchoFromCommit(repo, w1.commitSha, "s");
|
|
73
|
+
expect((r.envelope?.state).v).toBe("second");
|
|
74
|
+
});
|
|
75
|
+
it("read returns ok=false when no echo exists", () => {
|
|
76
|
+
const r = readEchoFromCommit(repo, undefined, "s");
|
|
77
|
+
expect(r.ok).toBe(false);
|
|
78
|
+
expect(r.reason).toContain("no echo");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=echo_commit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo_commit.test.js","sourceRoot":"","sources":["../../src/cosmic/echo_commit.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cosmic/index.d.ts
CHANGED
|
@@ -123,6 +123,33 @@ export interface PresenceWatcher {
|
|
|
123
123
|
vendor: string;
|
|
124
124
|
secondsAgo: number;
|
|
125
125
|
}
|
|
126
|
+
/** Publish an incremental JSON Patch instead of full state. The caller
|
|
127
|
+
* supplies prevState (what they last successfully published) and the
|
|
128
|
+
* basedOnSig the server returned. The server applies the patch on top
|
|
129
|
+
* of its current state and returns 409 if basedOnSig is stale.
|
|
130
|
+
*
|
|
131
|
+
* Falls back to a full publish automatically if the patch is no smaller
|
|
132
|
+
* than the full body (see patchIsWorthIt). */
|
|
133
|
+
export declare function publishIncrementalToCosmic(input: {
|
|
134
|
+
session: CosmicSession;
|
|
135
|
+
prevState: Record<string, unknown>;
|
|
136
|
+
nextState: Record<string, unknown>;
|
|
137
|
+
basedOnSig: string;
|
|
138
|
+
fetchOverride?: typeof fetch;
|
|
139
|
+
}): Promise<PublishResult & {
|
|
140
|
+
mode?: "patch" | "full";
|
|
141
|
+
}>;
|
|
142
|
+
/** Conditional read using ETag: server returns 304 (not_modified) when
|
|
143
|
+
* state hasn't changed. Saves ~99% bandwidth on poll cycles. */
|
|
144
|
+
export declare function readCosmicWithEtag(jsonUrl: string, prevEtag: string | null, fetchOverride?: typeof fetch): Promise<{
|
|
145
|
+
ok: boolean;
|
|
146
|
+
notModified?: boolean;
|
|
147
|
+
state?: Record<string, unknown>;
|
|
148
|
+
etag?: string;
|
|
149
|
+
rescueUrl?: string | null;
|
|
150
|
+
zombie?: boolean;
|
|
151
|
+
error?: string;
|
|
152
|
+
}>;
|
|
126
153
|
/** Open Google-Docs-style watcher list. Anyone with the token can see
|
|
127
154
|
* who else is reading + what vendor they appear to be. Useful for the
|
|
128
155
|
* parent AI to know if the receiver actually opened the URL. */
|
|
@@ -135,4 +162,9 @@ export declare function getCosmicPresence(jsonUrl: string, fetchOverride?: typeo
|
|
|
135
162
|
lastHeartbeatTs?: number | null;
|
|
136
163
|
error?: string;
|
|
137
164
|
}>;
|
|
165
|
+
export * as diff from "./diff.js";
|
|
166
|
+
export * as choir from "./choir.js";
|
|
167
|
+
export * as echoCommit from "./echo_commit.js";
|
|
168
|
+
export * as audit from "./aurelian_audit.js";
|
|
169
|
+
export * as benchmark from "./benchmark.js";
|
|
138
170
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cosmic/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,MAAM,WAAW,SAAS;IACxB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf;wEACoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;4CAC4C;AAC5C,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAc3D;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cosmic/index.ts"],"names":[],"mappings":"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"}
|