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.
Files changed (2) hide show
  1. package/dist/cli.mjs +265 -123
  2. 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
- import git from "isomorphic-git";
455
- import http from "isomorphic-git/http/web";
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", enc2.encode(t));
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 = enc2.encode(JSON.stringify({ mode, ...fields }));
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(dec2.decode(new Uint8Array(ex.memory.buffer, ptr, len).slice()));
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(enc2.encode(bootstrapPkg)));
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, checkpoint = null;
690
+ let restored = false, remoteMain = null, restoreError = null;
539
691
  try {
540
- const info = await git.getRemoteInfo({ http, url: ledger.remote, headers: ledger.headers });
541
- remoteMain = info.refs && info.refs.heads && info.refs.heads.main || null;
692
+ await custodySkeleton(eng, gitdir);
693
+ remoteMain = await custodyFetch(eng, ws, ledger, { remoteRef: "refs/heads/main" });
542
694
  if (remoteMain) {
543
- await git.init({ fs: eng.fs, gitdir, bare: true, defaultBranch: "main" });
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, checkpoint };
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`, enc2.encode(JSON.stringify(payload)));
590
- writeWork(eng, `envelope-${seq}.json`, enc2.encode(stringifyBig(envelope)));
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 res = JSON.parse(call(eng.ex, "author", { 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 } : {}, ...defer ? { deferProjection: true } : {} }, eng.STDERR));
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 importCheckpoint(eng, ws, blobB64, frontierB64) {
598
- return JSON.parse(call(eng.ex, "checkpoint_import", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH, blob: blobB64, ...frontierB64 ? { frontier: frontierB64 } : {} }, eng.STDERR));
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
- return (await git.readBlob({ fs, gitdir, oid, filepath })).blob;
636
- } catch {
637
- return null;
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
- return null;
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 applyIntentBytes(eng, ws, bytes) {
663
- const name = `intent-in-${eng.seq++}.json`;
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
- return JSON.parse(call(eng.ex, "apply_intent", { repoArg: repoArgOf(ws), workspace: ws, intentFile: `/work/${name}`, branch: BRANCH }, eng.STDERR));
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, "verify_chain", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH }, eng.STDERR));
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 enc2, dec2, BRANCH, repoArgOf, gitdirOf, unpack, installPayload, qById, query, cryptoUnwrapKey, count, sum;
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
- enc2 = new TextEncoder();
677
- dec2 = new TextDecoder();
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
- qById = (eng, ws, id, principal = "", keys = []) => JSON.parse(call(eng.ex, "query_by_id", { repoArg: repoArgOf(ws), workspace: ws, aggregateId: id, principal, keys, branch: BRANCH }, eng.STDERR));
687
- query = (eng, ws, queryId, paramsJson, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryId, paramsJson, principal, keys, branch: BRANCH }, eng.STDERR));
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, "count", { repoArg: repoArgOf(ws), workspace: ws, countId, groupKey, branch: BRANCH }, eng.STDERR));
690
- sum = (eng, ws, sumId, groupKey) => JSON.parse(call(eng.ex, "sum", { repoArg: repoArgOf(ws), workspace: ws, sumId, groupKey, branch: BRANCH }, eng.STDERR));
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 dec3 = new TextDecoder();
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(dec3.decode(c)));
1327
- child.stderr?.on("data", (c) => chunks.push(dec3.decode(c)));
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 dec3 = new TextDecoder();
1494
- const body = chunks.map((c) => dec3.decode(c)).join("") || "{}";
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 git2(args, opts = {}) {
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 (git2(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git2(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
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 (git2(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
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 (git2(["remote", "add", name, url], { quiet: true }) !== 0) {
1775
- if (git2(["remote", "set-url", name, url], { quiet: true }) !== 0) {
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 (git2(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
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 git3 from "isomorphic-git";
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 dec3 = new TextDecoder();
2212
+ const dec4 = new TextDecoder();
2071
2213
  const entries = [];
2072
- for (const c of await git3.log({ fs: eng.fs, gitdir, ref: "main" })) {
2214
+ for (const c of await git2.log({ fs: eng.fs, gitdir, ref: "main" })) {
2073
2215
  try {
2074
- const { blob } = await git3.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
2075
- entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec3.decode(blob)) });
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.15.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.15.0",
30
+ "@githolon/dsl": "^0.16.0",
31
31
  "isomorphic-git": "^1.38.4"
32
32
  },
33
33
  "devDependencies": {