githolon 0.15.0 → 0.16.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/cli.mjs +265 -123
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -449,12 +449,164 @@ var init_tree = __esm({
|
|
|
449
449
|
}
|
|
450
450
|
});
|
|
451
451
|
|
|
452
|
+
// vendor/engine/custody-transport.mjs
|
|
453
|
+
function concatBytes(chunks) {
|
|
454
|
+
let n = 0;
|
|
455
|
+
for (const c of chunks) n += c.length;
|
|
456
|
+
const out10 = new Uint8Array(n);
|
|
457
|
+
let o = 0;
|
|
458
|
+
for (const c of chunks) {
|
|
459
|
+
out10.set(c, o);
|
|
460
|
+
o += c.length;
|
|
461
|
+
}
|
|
462
|
+
return out10;
|
|
463
|
+
}
|
|
464
|
+
function pkt(payload) {
|
|
465
|
+
const body = typeof payload === "string" ? enc2.encode(payload) : payload;
|
|
466
|
+
const len = (body.length + 4).toString(16).padStart(4, "0");
|
|
467
|
+
return concatBytes([enc2.encode(len), body]);
|
|
468
|
+
}
|
|
469
|
+
function readPktLines(buf, off = 0) {
|
|
470
|
+
const lines = [];
|
|
471
|
+
while (off + 4 <= buf.length) {
|
|
472
|
+
const hex = dec2.decode(buf.subarray(off, off + 4));
|
|
473
|
+
if (!/^[0-9a-f]{4}$/.test(hex)) break;
|
|
474
|
+
const len = parseInt(hex, 16);
|
|
475
|
+
if (len === 0) {
|
|
476
|
+
off += 4;
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
if (len < 4 || off + len > buf.length) break;
|
|
480
|
+
lines.push(buf.subarray(off + 4, off + len));
|
|
481
|
+
off += len;
|
|
482
|
+
}
|
|
483
|
+
return { lines, rest: off };
|
|
484
|
+
}
|
|
485
|
+
async function lsRefs(remote, headers = {}, { service = "git-upload-pack", prefix = null } = {}) {
|
|
486
|
+
const r = await fetch(`${remote}/info/refs?service=${service}`, { headers });
|
|
487
|
+
if (!r.ok) {
|
|
488
|
+
if (r.status === 404) return {};
|
|
489
|
+
throw new Error(`info/refs ${r.status}: ${(await r.text()).slice(0, 180)}`);
|
|
490
|
+
}
|
|
491
|
+
const buf = new Uint8Array(await r.arrayBuffer());
|
|
492
|
+
const banner = readPktLines(buf, 0);
|
|
493
|
+
const { lines } = readPktLines(buf, banner.rest);
|
|
494
|
+
const refs = {};
|
|
495
|
+
for (const line of lines) {
|
|
496
|
+
let s = dec2.decode(line).replace(/\n$/, "");
|
|
497
|
+
if (s.startsWith("#")) continue;
|
|
498
|
+
const nul = s.indexOf("\0");
|
|
499
|
+
if (nul >= 0) s = s.slice(0, nul);
|
|
500
|
+
const sp = s.indexOf(" ");
|
|
501
|
+
if (sp !== 40) continue;
|
|
502
|
+
const oid = s.slice(0, 40), name = s.slice(41);
|
|
503
|
+
if (!/^[0-9a-f]{40}$/.test(oid)) continue;
|
|
504
|
+
if (prefix && !name.startsWith(prefix)) continue;
|
|
505
|
+
refs[name] = oid;
|
|
506
|
+
}
|
|
507
|
+
return refs;
|
|
508
|
+
}
|
|
509
|
+
async function fetchPack(remote, headers = {}, { wants = [], haves = [] } = {}) {
|
|
510
|
+
wants = wants.filter((w) => /^[0-9a-f]{40}$/.test(w) && w !== ZERO_OID);
|
|
511
|
+
if (!wants.length) return null;
|
|
512
|
+
const caps = "thin-pack ofs-delta agent=nomos-cloud";
|
|
513
|
+
const parts = [];
|
|
514
|
+
wants.forEach((w, i) => parts.push(pkt(`want ${w}${i === 0 ? " " + caps : ""}
|
|
515
|
+
`)));
|
|
516
|
+
parts.push(FLUSH);
|
|
517
|
+
for (const h of haves) if (/^[0-9a-f]{40}$/.test(h) && h !== ZERO_OID) parts.push(pkt(`have ${h}
|
|
518
|
+
`));
|
|
519
|
+
parts.push(pkt("done\n"));
|
|
520
|
+
const r = await fetch(`${remote}/git-upload-pack`, {
|
|
521
|
+
method: "POST",
|
|
522
|
+
headers: { "content-type": "application/x-git-upload-pack-request", "accept": "application/x-git-upload-pack-result", ...headers },
|
|
523
|
+
body: concatBytes(parts)
|
|
524
|
+
});
|
|
525
|
+
if (!r.ok) throw new Error(`upload-pack ${r.status}: ${(await r.text()).slice(0, 180)}`);
|
|
526
|
+
const buf = new Uint8Array(await r.arrayBuffer());
|
|
527
|
+
const { lines, rest } = readPktLines(buf, 0);
|
|
528
|
+
const packChunks = [];
|
|
529
|
+
let sideband = false;
|
|
530
|
+
for (const line of lines) {
|
|
531
|
+
if (line.length === 0) continue;
|
|
532
|
+
const head = dec2.decode(line.subarray(0, Math.min(line.length, 3)));
|
|
533
|
+
if (head === "NAK" || head === "ACK" || head === "ERR" || head.startsWith("sha")) continue;
|
|
534
|
+
const band = line[0];
|
|
535
|
+
if (band === 1) {
|
|
536
|
+
packChunks.push(line.subarray(1));
|
|
537
|
+
sideband = true;
|
|
538
|
+
} else if (band === 2) {
|
|
539
|
+
} else if (band === 3) {
|
|
540
|
+
throw new Error("upload-pack fatal: " + dec2.decode(line.subarray(1)).slice(0, 180));
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const pack = sideband ? concatBytes(packChunks) : buf.subarray(rest);
|
|
544
|
+
if (pack.length < 12 || dec2.decode(pack.subarray(0, 4)) !== "PACK") {
|
|
545
|
+
throw new Error(`upload-pack: no pack in response (${pack.length}B, sideband=${sideband})`);
|
|
546
|
+
}
|
|
547
|
+
return pack;
|
|
548
|
+
}
|
|
549
|
+
var enc2, dec2, ZERO_OID, EMPTY_PACK, FLUSH;
|
|
550
|
+
var init_custody_transport = __esm({
|
|
551
|
+
"vendor/engine/custody-transport.mjs"() {
|
|
552
|
+
"use strict";
|
|
553
|
+
enc2 = new TextEncoder();
|
|
554
|
+
dec2 = new TextDecoder();
|
|
555
|
+
ZERO_OID = "0".repeat(40);
|
|
556
|
+
EMPTY_PACK = new Uint8Array([
|
|
557
|
+
80,
|
|
558
|
+
65,
|
|
559
|
+
67,
|
|
560
|
+
75,
|
|
561
|
+
0,
|
|
562
|
+
0,
|
|
563
|
+
0,
|
|
564
|
+
2,
|
|
565
|
+
0,
|
|
566
|
+
0,
|
|
567
|
+
0,
|
|
568
|
+
0,
|
|
569
|
+
// "PACK", ver 2, 0 objects
|
|
570
|
+
2,
|
|
571
|
+
157,
|
|
572
|
+
8,
|
|
573
|
+
130,
|
|
574
|
+
59,
|
|
575
|
+
216,
|
|
576
|
+
168,
|
|
577
|
+
234,
|
|
578
|
+
181,
|
|
579
|
+
16,
|
|
580
|
+
173,
|
|
581
|
+
106,
|
|
582
|
+
// sha1(the 12 header bytes)
|
|
583
|
+
199,
|
|
584
|
+
92,
|
|
585
|
+
130,
|
|
586
|
+
60,
|
|
587
|
+
253,
|
|
588
|
+
62,
|
|
589
|
+
211,
|
|
590
|
+
30
|
|
591
|
+
]);
|
|
592
|
+
FLUSH = enc2.encode("0000");
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
|
|
452
596
|
// vendor/engine/engine.mjs
|
|
453
597
|
import { WASI, File, Directory, OpenFile, ConsoleStdout, PreopenDirectory } from "@bjorn3/browser_wasi_shim";
|
|
454
|
-
|
|
455
|
-
|
|
598
|
+
function b64Bytes(bytes) {
|
|
599
|
+
let s = "";
|
|
600
|
+
for (let i = 0; i < bytes.length; i += 32768) {
|
|
601
|
+
s += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
602
|
+
}
|
|
603
|
+
return btoa(s);
|
|
604
|
+
}
|
|
605
|
+
function b64Json(o) {
|
|
606
|
+
return b64Bytes(enc3.encode(JSON.stringify(o)));
|
|
607
|
+
}
|
|
456
608
|
async function sha256hex(t) {
|
|
457
|
-
const b = await crypto.subtle.digest("SHA-256",
|
|
609
|
+
const b = await crypto.subtle.digest("SHA-256", enc3.encode(t));
|
|
458
610
|
return [...new Uint8Array(b)].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
459
611
|
}
|
|
460
612
|
function osEntropyBuffer(n) {
|
|
@@ -472,7 +624,7 @@ function stringifyBig(o) {
|
|
|
472
624
|
return JSON.stringify(o, (_k, v) => typeof v === "bigint" ? `@@B:${v}@@` : v).replace(/"@@B:(\d+)@@"/g, "$1");
|
|
473
625
|
}
|
|
474
626
|
function call(ex, mode, fields, STDERR) {
|
|
475
|
-
const req =
|
|
627
|
+
const req = enc3.encode(JSON.stringify({ mode, ...fields }));
|
|
476
628
|
const reqPtr = ex.git_holon_alloc(req.length);
|
|
477
629
|
try {
|
|
478
630
|
new Uint8Array(ex.memory.buffer, reqPtr, req.length).set(req);
|
|
@@ -485,7 +637,7 @@ function call(ex, mode, fields, STDERR) {
|
|
|
485
637
|
}
|
|
486
638
|
const { ptr, len } = unpack(packed);
|
|
487
639
|
try {
|
|
488
|
-
const e = JSON.parse(
|
|
640
|
+
const e = JSON.parse(dec3.decode(new Uint8Array(ex.memory.buffer, ptr, len).slice()));
|
|
489
641
|
if (!e.ok) throw new Error((e.error || "holon error") + (STDERR.length ? ` | ${STDERR.slice(-4).join(" / ")}` : ""));
|
|
490
642
|
return e.result;
|
|
491
643
|
} finally {
|
|
@@ -498,7 +650,7 @@ function call(ex, mode, fields, STDERR) {
|
|
|
498
650
|
async function createEngine({ wasmModule, bootstrapPkg, nomosPkg, replica, installedBy = "nomos-cloud" }) {
|
|
499
651
|
const hashes = { bootstrap: await sha256hex(bootstrapPkg), nomos: await sha256hex(nomosPkg) };
|
|
500
652
|
const root = /* @__PURE__ */ new Map();
|
|
501
|
-
root.set("domain.package.usda", new File(
|
|
653
|
+
root.set("domain.package.usda", new File(enc3.encode(bootstrapPkg)));
|
|
502
654
|
root.set("ws", new Directory(/* @__PURE__ */ new Map()));
|
|
503
655
|
const preopen = new PreopenDirectory("/work", root);
|
|
504
656
|
const STDERR = [];
|
|
@@ -535,39 +687,18 @@ async function mountWorkspace(eng, ws, ledger) {
|
|
|
535
687
|
if (eng.mounted.has(ws)) return eng.mounted.get(ws);
|
|
536
688
|
stageWorkspaceDir(eng, ws);
|
|
537
689
|
const gitdir = gitdirOf(ws);
|
|
538
|
-
let restored = false, remoteMain = null, restoreError = null
|
|
690
|
+
let restored = false, remoteMain = null, restoreError = null;
|
|
539
691
|
try {
|
|
540
|
-
|
|
541
|
-
remoteMain =
|
|
692
|
+
await custodySkeleton(eng, gitdir);
|
|
693
|
+
remoteMain = await custodyFetch(eng, ws, ledger, { remoteRef: "refs/heads/main" });
|
|
542
694
|
if (remoteMain) {
|
|
543
|
-
|
|
544
|
-
await git.addRemote({ fs: eng.fs, gitdir, remote: "origin", url: ledger.remote, force: true });
|
|
545
|
-
const ckpt = await discoverCheckpointFromCustody(ledger).catch(() => null);
|
|
546
|
-
let shallowOk = false;
|
|
547
|
-
if (ckpt?.cursor && ckpt.frontier) {
|
|
548
|
-
const steps = [32, 96, 256, 1024];
|
|
549
|
-
for (let i = 0; i < steps.length; i++) {
|
|
550
|
-
const depth = steps[i], relative = i > 0;
|
|
551
|
-
await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, depth, relative, headers: ledger.headers });
|
|
552
|
-
if (await git.readCommit({ fs: eng.fs, gitdir, oid: ckpt.cursor }).then(() => true, () => false)) {
|
|
553
|
-
shallowOk = true;
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
if (!shallowOk) await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, headers: ledger.headers });
|
|
559
|
-
await git.writeRef({ fs: eng.fs, gitdir, ref: "refs/heads/main", value: remoteMain, force: true });
|
|
560
|
-
await git.writeRef({ fs: eng.fs, gitdir, ref: "HEAD", value: "ref: refs/heads/main", force: true, symbolic: true });
|
|
561
|
-
if (shallowOk && ckpt?.blob) {
|
|
562
|
-
const r = importCheckpoint(eng, ws, ckpt.blob, ckpt.frontier);
|
|
563
|
-
checkpoint = { restored: !!(r && r.restored), frontierSeeded: !!(r && r.frontierSeeded), cursor: r && r.cursor ? r.cursor : ckpt.cursor, ref: ckpt.ref };
|
|
564
|
-
}
|
|
695
|
+
kgit.writeRef(eng, gitdir, "HEAD", "ref: refs/heads/main");
|
|
565
696
|
restored = true;
|
|
566
697
|
}
|
|
567
698
|
} catch (e) {
|
|
568
699
|
restoreError = String(e && e.stack || e).split("\n").slice(0, 5).join(" | ");
|
|
569
700
|
}
|
|
570
|
-
const m = { restored, remoteMain, restoreError
|
|
701
|
+
const m = { restored, remoteMain, restoreError };
|
|
571
702
|
eng.mounted.set(ws, m);
|
|
572
703
|
return m;
|
|
573
704
|
}
|
|
@@ -586,95 +717,69 @@ function mintId(eng, typeTag) {
|
|
|
586
717
|
function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
|
|
587
718
|
const seq = eng.seq++;
|
|
588
719
|
const envelope = { payload: { domain, directiveId, payload }, captured_ports: { clock: { physical: Date.now(), logical: 0, replica: eng.replica }, rng: osEntropyBuffer(opts.rngDraws ?? 64) }, policy_version: 1, policy_domain: "Nomos", policy_gas: 0, policy_memory: 0 };
|
|
589
|
-
writeWork(eng, `payload-${seq}.json`,
|
|
590
|
-
writeWork(eng, `envelope-${seq}.json`,
|
|
720
|
+
writeWork(eng, `payload-${seq}.json`, enc3.encode(JSON.stringify(payload)));
|
|
721
|
+
writeWork(eng, `envelope-${seq}.json`, enc3.encode(stringifyBig(envelope)));
|
|
591
722
|
const genesis = !controllerHash;
|
|
592
723
|
const defer = opts.deferProjection !== false;
|
|
593
|
-
const
|
|
724
|
+
const v = JSON.parse(call(eng.ex, "offer", { repoArg: repoArgOf(ws), workspace: ws, domain, directiveId, payloadFile: `/work/payload-${seq}.json`, envelopeFile: `/work/envelope-${seq}.json`, seq, actor: opts.actor ?? "", domainFile: genesis ? "/work/domain.package.usda" : "", domainHash: genesis ? "" : controllerHash, branch: BRANCH, ...opts.authorSecret ? { authorSecret: opts.authorSecret } : {}, ...opts.dryRun ? { dryRun: true } : defer ? { deferProjection: true } : {} }, eng.STDERR));
|
|
725
|
+
const res = v.outcome === "admitted" ? { ok: true, head: v.head, intentOut: v.intentOut } : v.outcome === "refused" ? { ok: false, error: v.verdict?.reason ?? v.error } : v;
|
|
594
726
|
if (defer && res.ok) (eng.pendingProjection ??= /* @__PURE__ */ new Set()).add(ws);
|
|
595
727
|
return res;
|
|
596
728
|
}
|
|
597
|
-
function
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
async function streamAll(stream) {
|
|
601
|
-
const chunks = [];
|
|
602
|
-
const reader = stream.getReader();
|
|
603
|
-
for (; ; ) {
|
|
604
|
-
const { done, value } = await reader.read();
|
|
605
|
-
if (done) break;
|
|
606
|
-
chunks.push(value);
|
|
607
|
-
}
|
|
608
|
-
let len = 0;
|
|
609
|
-
for (const c of chunks) len += c.length;
|
|
610
|
-
const out10 = new Uint8Array(len);
|
|
611
|
-
let at = 0;
|
|
612
|
-
for (const c of chunks) {
|
|
613
|
-
out10.set(c, at);
|
|
614
|
-
at += c.length;
|
|
615
|
-
}
|
|
616
|
-
return out10;
|
|
617
|
-
}
|
|
618
|
-
async function gunzip(bytes) {
|
|
619
|
-
const ds = new DecompressionStream("gzip");
|
|
620
|
-
return streamAll(new Response(bytes).body.pipeThrough(ds));
|
|
621
|
-
}
|
|
622
|
-
async function discoverCheckpointFromCustody(ledger) {
|
|
623
|
-
const freshHeaders = () => ({ ...ledger.headers || {} });
|
|
624
|
-
const refs = (await git.listServerRefs({ http, url: ledger.remote, headers: freshHeaders(), prefix: "refs/meta/checkpoint/", protocolVersion: 2 }) || []).filter((r) => r.ref && r.ref.startsWith("refs/meta/checkpoint/") && r.oid);
|
|
625
|
-
if (!refs.length) return null;
|
|
626
|
-
const root = /* @__PURE__ */ new Map();
|
|
627
|
-
root.set("ckpt", new Directory(/* @__PURE__ */ new Map()));
|
|
628
|
-
const preopen = new PreopenDirectory("/work", root);
|
|
629
|
-
const fs = makeGitFs(preopen, "/work", { File, Directory });
|
|
630
|
-
const gitdir = "/work/ckpt/nomos.git";
|
|
631
|
-
await git.init({ fs, gitdir, bare: true, defaultBranch: BRANCH });
|
|
632
|
-
await git.addRemote({ fs, gitdir, remote: "origin", url: ledger.remote, force: true });
|
|
633
|
-
const readFile = async (oid, filepath) => {
|
|
729
|
+
async function custodySkeleton(eng, gitdir) {
|
|
730
|
+
const p = eng.fs.promises;
|
|
731
|
+
for (const d of ["", "/objects", "/objects/pack", "/objects/info", "/refs", "/refs/heads"]) {
|
|
634
732
|
try {
|
|
635
|
-
|
|
636
|
-
} catch {
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
for (let i = refs.length - 1; i >= 0 && i >= refs.length - 3; i--) {
|
|
641
|
-
const { ref, oid } = refs[i];
|
|
642
|
-
try {
|
|
643
|
-
await git.fetch({ fs, http, gitdir, remote: "origin", ref, singleBranch: true, depth: 1, headers: freshHeaders() });
|
|
644
|
-
const gz = await readFile(oid, "checkpoint");
|
|
645
|
-
if (!gz) continue;
|
|
646
|
-
let meta = {};
|
|
647
|
-
try {
|
|
648
|
-
const mb = await readFile(oid, "meta");
|
|
649
|
-
if (mb) meta = JSON.parse(dec2.decode(mb));
|
|
650
|
-
} catch {
|
|
651
|
-
}
|
|
652
|
-
const codec = meta.codec ?? "gzip";
|
|
653
|
-
const blob = dec2.decode(codec === "gzip" ? await gunzip(gz) : gz);
|
|
654
|
-
const fgz = await readFile(oid, "frontier");
|
|
655
|
-
const frontier = fgz ? dec2.decode(codec === "gzip" ? await gunzip(fgz) : fgz) : null;
|
|
656
|
-
return { ref, oid, cursor: meta.cursor || null, blob, frontier };
|
|
657
|
-
} catch {
|
|
733
|
+
await p.mkdir(`${gitdir}${d}`);
|
|
734
|
+
} catch (e) {
|
|
735
|
+
if (e && e.code !== "EEXIST") throw e;
|
|
658
736
|
}
|
|
659
737
|
}
|
|
660
|
-
|
|
738
|
+
try {
|
|
739
|
+
await p.writeFile(`${gitdir}/HEAD`, `ref: refs/heads/${BRANCH}
|
|
740
|
+
`);
|
|
741
|
+
} catch {
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
await p.writeFile(`${gitdir}/config`, "[core]\n repositoryformatversion = 0\n bare = true\n");
|
|
745
|
+
} catch {
|
|
746
|
+
}
|
|
661
747
|
}
|
|
662
|
-
function
|
|
663
|
-
const
|
|
748
|
+
async function custodyFetch(eng, ws, ledger, { remoteRef = "refs/heads/main", localRef = null, have = null } = {}) {
|
|
749
|
+
const remoteRefFull = fullRef(remoteRef);
|
|
750
|
+
const refs = await custodyLsRefs(ledger, remoteRefFull);
|
|
751
|
+
const tip = refs[remoteRefFull] || null;
|
|
752
|
+
if (!tip) return null;
|
|
753
|
+
if (tip !== have) applyPackInto(eng, ws, await fetchPack(ledger.remote, ledger.headers || {}, { wants: [tip], haves: have ? [have] : [] }));
|
|
754
|
+
kgit.writeRef(eng, gitdirOf(ws), fullRef(localRef || remoteRef), tip);
|
|
755
|
+
return tip;
|
|
756
|
+
}
|
|
757
|
+
function offerIntent(eng, ws, bytes, opts) {
|
|
758
|
+
const name = `offer-in-${eng.seq++}.json`;
|
|
664
759
|
writeWork(eng, name, bytes);
|
|
665
|
-
|
|
760
|
+
const deferProjection = !!(opts && opts.defer);
|
|
761
|
+
const branch = opts && opts.branch || BRANCH;
|
|
762
|
+
return JSON.parse(call(eng.ex, "offer", { repoArg: repoArgOf(ws), workspace: ws, intentFile: `/work/${name}`, branch, deferProjection }, eng.STDERR));
|
|
763
|
+
}
|
|
764
|
+
function offerAdmit(eng, ws, bytes, opts) {
|
|
765
|
+
const v = offerIntent(eng, ws, bytes, opts);
|
|
766
|
+
return v.outcome === "admitted" ? { ok: true, head: v.head } : { ok: false, error: v.verdict?.reason ?? v.error ?? "the offer was refused" };
|
|
767
|
+
}
|
|
768
|
+
function applyIntentBytes(eng, ws, bytes, opts) {
|
|
769
|
+
return offerAdmit(eng, ws, bytes, opts);
|
|
666
770
|
}
|
|
667
771
|
function verifyChainLocal(eng, ws) {
|
|
668
|
-
return JSON.parse(call(eng.ex, "
|
|
772
|
+
return JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "verifyChain" }), branch: BRANCH }, eng.STDERR));
|
|
669
773
|
}
|
|
670
|
-
var
|
|
774
|
+
var enc3, dec3, BRANCH, repoArgOf, gitdirOf, unpack, repoArgOfGitdir, bytesFromB64, kgit, installPayload, fullRef, applyPackInto, custodyLsRefs, qById, query, cryptoUnwrapKey, count, sum;
|
|
671
775
|
var init_engine = __esm({
|
|
672
776
|
"vendor/engine/engine.mjs"() {
|
|
673
777
|
"use strict";
|
|
674
778
|
init_git_fs();
|
|
675
779
|
init_tree();
|
|
676
|
-
|
|
677
|
-
|
|
780
|
+
init_custody_transport();
|
|
781
|
+
enc3 = new TextEncoder();
|
|
782
|
+
dec3 = new TextDecoder();
|
|
678
783
|
BRANCH = "main";
|
|
679
784
|
repoArgOf = (ws) => `/work/ws/${ws}`;
|
|
680
785
|
gitdirOf = (ws) => `/work/ws/${ws}/nomos.git`;
|
|
@@ -682,12 +787,49 @@ var init_engine = __esm({
|
|
|
682
787
|
const v = typeof p === "bigint" ? p : BigInt(p);
|
|
683
788
|
return { ptr: Number(v >> 32n), len: Number(v & 0xffffffffn) };
|
|
684
789
|
};
|
|
790
|
+
repoArgOfGitdir = (gitdir) => gitdir.replace(/\/nomos\.git$/, "");
|
|
791
|
+
bytesFromB64 = (b64) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
792
|
+
kgit = {
|
|
793
|
+
// resolveRef → tip oid hex, or null if the ref is absent (replaces git.resolveRef(...).catch(()=>null)).
|
|
794
|
+
resolveRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "resolve_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)).oid,
|
|
795
|
+
// readBlob → the blob bytes at `path` inside commit `oid`, or null if not found (no throw).
|
|
796
|
+
readBlob: (eng, gitdir, oid, path) => {
|
|
797
|
+
const r = JSON.parse(call(eng.ex, "read_blob", { repoArg: repoArgOfGitdir(gitdir), oid, path }, eng.STDERR));
|
|
798
|
+
return r.ok ? bytesFromB64(r.blobB64) : null;
|
|
799
|
+
},
|
|
800
|
+
// intentsAbove → [{ oid, intentB64 }] oldest→newest over (base, head] (replaces log + readBlob intent.json).
|
|
801
|
+
// `limit` (0 = all) caps to the most-recent N intent commits (replaces git.log depth).
|
|
802
|
+
intentsAbove: (eng, gitdir, head, base = "", limit = 0) => JSON.parse(call(eng.ex, "intents_above", { repoArg: repoArgOfGitdir(gitdir), head, base, limit }, eng.STDERR)).intents,
|
|
803
|
+
// listRefs → [{ ref, oid }] under prefix (replaces git.listRefs for LOCAL refs).
|
|
804
|
+
listRefs: (eng, gitdir, prefix) => JSON.parse(call(eng.ex, "list_refs", { repoArg: repoArgOfGitdir(gitdir), prefix }, eng.STDERR)).refs,
|
|
805
|
+
// writeRef → force-point a ref (plain oid or `ref:`-symbolic) (replaces git.writeRef).
|
|
806
|
+
writeRef: (eng, gitdir, ref, value) => JSON.parse(call(eng.ex, "write_ref", { repoArg: repoArgOfGitdir(gitdir), ref, value }, eng.STDERR)),
|
|
807
|
+
// deleteRef → remove a local ref, idempotent (replaces git.deleteRef).
|
|
808
|
+
deleteRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "delete_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)),
|
|
809
|
+
// writeMetaCommit → blobs→tree→commit→ref for a CUSTODY-META fact (checkpoint/refused/outbox/shape).
|
|
810
|
+
// `files`: [{ path, bytes:Uint8Array }]; returns the commit oid (replaces writeBlob+writeTree+writeCommit[+writeRef]).
|
|
811
|
+
writeMetaCommit: (eng, gitdir, { parents = [], files, message = "nomos custody meta", timeSecs = 0, ref = "" }) => JSON.parse(call(eng.ex, "write_meta_commit", {
|
|
812
|
+
repoArg: repoArgOfGitdir(gitdir),
|
|
813
|
+
parents,
|
|
814
|
+
files: files.map((f) => ({ path: f.path, blobB64: b64Bytes(f.bytes) })),
|
|
815
|
+
message,
|
|
816
|
+
timeSecs,
|
|
817
|
+
ref
|
|
818
|
+
}, eng.STDERR)).oid
|
|
819
|
+
};
|
|
685
820
|
installPayload = (hash, usda, installedBy, dispositions) => ({ domainHash: hash, packageUsda: usda, installedBy, dependencies: [], finalizers: [], ...dispositions ? { dispositions } : {} });
|
|
686
|
-
|
|
687
|
-
|
|
821
|
+
fullRef = (r) => r === "HEAD" || r.startsWith("refs/") ? r : `refs/heads/${r}`;
|
|
822
|
+
applyPackInto = (eng, ws, pack) => {
|
|
823
|
+
if (!pack || !pack.length) return;
|
|
824
|
+
const r = JSON.parse(call(eng.ex, "apply_pack", { repoArg: repoArgOf(ws), packB64: b64Bytes(pack) }, eng.STDERR));
|
|
825
|
+
if (!r || r.ok !== true) throw new Error(`apply_pack: ${r && r.error}`);
|
|
826
|
+
};
|
|
827
|
+
custodyLsRefs = (ledger, prefix = null) => lsRefs(ledger.remote, ledger.headers || {}, { service: "git-upload-pack", prefix });
|
|
828
|
+
qById = (eng, ws, id, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "byId", aggregateId: id }), principal, keys, branch: BRANCH }, eng.STDERR));
|
|
829
|
+
query = (eng, ws, queryId, paramsJson, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ kind: "query", queryId, paramsJson }), principal, keys, branch: BRANCH }, eng.STDERR));
|
|
688
830
|
cryptoUnwrapKey = (eng, { secret, hpkeEpk, ct }) => JSON.parse(call(eng.ex, "crypto_unwrap_key", { secret, hpkeEpk, ct }, eng.STDERR)).scopeKey;
|
|
689
|
-
count = (eng, ws, countId, groupKey) => JSON.parse(call(eng.ex, "
|
|
690
|
-
sum = (eng, ws, sumId, groupKey) => JSON.parse(call(eng.ex, "
|
|
831
|
+
count = (eng, ws, countId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "count", countId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
|
|
832
|
+
sum = (eng, ws, sumId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "sum", sumId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
|
|
691
833
|
}
|
|
692
834
|
});
|
|
693
835
|
|
|
@@ -1321,10 +1463,10 @@ function compileAsync(cwd, args = []) {
|
|
|
1321
1463
|
}
|
|
1322
1464
|
return new Promise((resolveRun) => {
|
|
1323
1465
|
const chunks = [];
|
|
1324
|
-
const
|
|
1466
|
+
const dec4 = new TextDecoder();
|
|
1325
1467
|
const child = spawn(process.execPath, [launcher, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
1326
|
-
child.stdout?.on("data", (c) => chunks.push(
|
|
1327
|
-
child.stderr?.on("data", (c) => chunks.push(
|
|
1468
|
+
child.stdout?.on("data", (c) => chunks.push(dec4.decode(c)));
|
|
1469
|
+
child.stderr?.on("data", (c) => chunks.push(dec4.decode(c)));
|
|
1328
1470
|
child.on("error", (e) => resolveRun({ ok: false, ms: performance.now() - t0, output: String(e) }));
|
|
1329
1471
|
child.on(
|
|
1330
1472
|
"close",
|
|
@@ -1490,8 +1632,8 @@ function startServer(s) {
|
|
|
1490
1632
|
req.on("data", (c) => chunks.push(c));
|
|
1491
1633
|
req.on("end", () => {
|
|
1492
1634
|
try {
|
|
1493
|
-
const
|
|
1494
|
-
const body = chunks.map((c) =>
|
|
1635
|
+
const dec4 = new TextDecoder();
|
|
1636
|
+
const body = chunks.map((c) => dec4.decode(c)).join("") || "{}";
|
|
1495
1637
|
const r = author(s.eng, WS, decodeURIComponent(dispatch[1]), decodeURIComponent(dispatch[2]), JSON.parse(body), s.lawHash);
|
|
1496
1638
|
if (r["ok"] === false) return respond(422, { ok: false, error: r["error"] });
|
|
1497
1639
|
s.intents++;
|
|
@@ -1709,7 +1851,7 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
1709
1851
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
1710
1852
|
var out5 = (s) => void process.stdout.write(s + "\n");
|
|
1711
1853
|
var err5 = (s) => void process.stderr.write("error: " + s + "\n");
|
|
1712
|
-
function
|
|
1854
|
+
function git(args, opts = {}) {
|
|
1713
1855
|
const r = spawnSync3("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
|
|
1714
1856
|
return r.status ?? 1;
|
|
1715
1857
|
}
|
|
@@ -1753,7 +1895,7 @@ async function gitSetup(opts) {
|
|
|
1753
1895
|
return 1;
|
|
1754
1896
|
}
|
|
1755
1897
|
const helper = `!"${process.execPath}" "${self}" git-credential`;
|
|
1756
|
-
if (
|
|
1898
|
+
if (git(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
|
|
1757
1899
|
err5("git config failed \u2014 is git installed?");
|
|
1758
1900
|
return 1;
|
|
1759
1901
|
}
|
|
@@ -1763,7 +1905,7 @@ async function gitSetup(opts) {
|
|
|
1763
1905
|
}
|
|
1764
1906
|
async function gitRemote(ws, name, opts) {
|
|
1765
1907
|
const cloud = cloudBase(opts.cloud);
|
|
1766
|
-
if (
|
|
1908
|
+
if (git(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
|
|
1767
1909
|
err5("not a git repository \u2014 run inside your repo (git init first)");
|
|
1768
1910
|
return 1;
|
|
1769
1911
|
}
|
|
@@ -1771,8 +1913,8 @@ async function gitRemote(ws, name, opts) {
|
|
|
1771
1913
|
if (setupRc !== 0) return setupRc;
|
|
1772
1914
|
ensureSecret(cloud, ws);
|
|
1773
1915
|
const url = `${cloud}/v1/workspaces/${ws}/git`;
|
|
1774
|
-
if (
|
|
1775
|
-
if (
|
|
1916
|
+
if (git(["remote", "add", name, url], { quiet: true }) !== 0) {
|
|
1917
|
+
if (git(["remote", "set-url", name, url], { quiet: true }) !== 0) {
|
|
1776
1918
|
err5(`could not add or update remote '${name}'`);
|
|
1777
1919
|
return 1;
|
|
1778
1920
|
}
|
|
@@ -1788,7 +1930,7 @@ async function gitRemote(ws, name, opts) {
|
|
|
1788
1930
|
);
|
|
1789
1931
|
return 1;
|
|
1790
1932
|
}
|
|
1791
|
-
if (
|
|
1933
|
+
if (git(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
|
|
1792
1934
|
err5("git config failed setting the principal header");
|
|
1793
1935
|
return 1;
|
|
1794
1936
|
}
|
|
@@ -2012,7 +2154,7 @@ init_cloud();
|
|
|
2012
2154
|
init_local_holon();
|
|
2013
2155
|
import { existsSync as existsSync8 } from "node:fs";
|
|
2014
2156
|
import { join as join9 } from "node:path";
|
|
2015
|
-
import
|
|
2157
|
+
import git2 from "isomorphic-git";
|
|
2016
2158
|
var out7 = (s) => void process.stdout.write(s + "\n");
|
|
2017
2159
|
var err7 = (s) => void process.stderr.write("error: " + s + "\n");
|
|
2018
2160
|
var SOURCE = "source";
|
|
@@ -2067,12 +2209,12 @@ function typeOf(ev) {
|
|
|
2067
2209
|
}
|
|
2068
2210
|
async function walkChain(eng, ws) {
|
|
2069
2211
|
const gitdir = gitdirOf(ws);
|
|
2070
|
-
const
|
|
2212
|
+
const dec4 = new TextDecoder();
|
|
2071
2213
|
const entries = [];
|
|
2072
|
-
for (const c of await
|
|
2214
|
+
for (const c of await git2.log({ fs: eng.fs, gitdir, ref: "main" })) {
|
|
2073
2215
|
try {
|
|
2074
|
-
const { blob } = await
|
|
2075
|
-
entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(
|
|
2216
|
+
const { blob } = await git2.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
|
|
2217
|
+
entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec4.decode(blob)) });
|
|
2076
2218
|
} catch {
|
|
2077
2219
|
}
|
|
2078
2220
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
30
|
-
"@githolon/dsl": "^0.
|
|
30
|
+
"@githolon/dsl": "^0.16.0",
|
|
31
31
|
"isomorphic-git": "^1.38.4"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|