githolon 0.85.0 → 0.86.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/dev-server.mjs +279 -1
- package/package.json +3 -3
package/dist/dev-server.mjs
CHANGED
|
@@ -594,6 +594,126 @@ function summaryOfCapture(ctx, fromOid, toOid) {
|
|
|
594
594
|
rowsByHome: Object.fromEntries([...ctx.rowsByHome.entries()].sort((a, b) => a[0] < b[0] ? -1 : 1))
|
|
595
595
|
};
|
|
596
596
|
}
|
|
597
|
+
async function admitIntentOffers(eng, ws, ledger, offers, { receiptFence = null, shardRouting = null, clientBase = null, defer = false } = {}) {
|
|
598
|
+
const main = await mainIntentIds(eng, ws);
|
|
599
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
600
|
+
const deadLetters = [];
|
|
601
|
+
let admittedTotal = 0;
|
|
602
|
+
const born = [];
|
|
603
|
+
const birthOutcomes = [];
|
|
604
|
+
const timings = { spans: [], intents: 0, sessions: 0 };
|
|
605
|
+
const summaryCtx = shardRouting && shardRouting.selfLabel && scopedReads(eng).length > 0 ? { reads: scopedReads(eng), prevs: /* @__PURE__ */ new Map(), values: /* @__PURE__ */ new Map(), events: [], rowsDelta: 0, rederived: /* @__PURE__ */ new Set(), rowsByHome: /* @__PURE__ */ new Map(), homeTags: /* @__PURE__ */ new Map(), homeKeySet: /* @__PURE__ */ new Set() } : null;
|
|
606
|
+
if (summaryCtx) {
|
|
607
|
+
try {
|
|
608
|
+
for (const r of query(eng, ws, "aggregatesByType", JSON.stringify({ __type: "NomosHomeReceipt" }))) {
|
|
609
|
+
const hk = r.data && typeof r.data.homeKey === "string" ? r.data.homeKey : null;
|
|
610
|
+
if (!hk) continue;
|
|
611
|
+
summaryCtx.homeKeySet.add(hk);
|
|
612
|
+
summaryCtx.homeTags.set(await routeTagHexOfHomeKey(hk), hk);
|
|
613
|
+
}
|
|
614
|
+
} catch (e) {
|
|
615
|
+
log("home-tag-table-error", { ws, error: String(e).slice(0, 200) });
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
const gitdir0 = gitdirOf(ws);
|
|
619
|
+
const headBefore = summaryCtx ? kgit.resolveRef(eng, gitdir0, BRANCH) : null;
|
|
620
|
+
const t0 = Date.now();
|
|
621
|
+
let seq = 0;
|
|
622
|
+
const span = (name, kind, depth = 1, extra = {}) => {
|
|
623
|
+
const s0 = Date.now();
|
|
624
|
+
return (end = {}) => timings.spans.push({ id: `intent-offer-${t0}-${seq++}`, track: "cloud", name, kind, depth, t0: s0, t1: Date.now(), ...extra, ...end });
|
|
625
|
+
};
|
|
626
|
+
for (const offer of Array.isArray(offers) ? offers : []) {
|
|
627
|
+
const cid = typeof offer?.session === "string" && offer.session ? offer.session : "direct";
|
|
628
|
+
const rec = sessions.get(cid) || { session: cid, admitted: [], rejected: [], skipped: [] };
|
|
629
|
+
sessions.set(cid, rec);
|
|
630
|
+
const done = span(`intent offer ${cid.slice(0, 14)}`, "cadmit", 1, { client: cid });
|
|
631
|
+
let blob = offer?.blob instanceof Uint8Array ? offer.blob : null;
|
|
632
|
+
try {
|
|
633
|
+
if (!blob && typeof offer?.intentB64 === "string") blob = Uint8Array.from(atob(offer.intentB64), (c) => c.charCodeAt(0));
|
|
634
|
+
const maxOfferBytes = offer?.staged ? 64 * 1024 * 1024 : 8 * 1024 * 1024;
|
|
635
|
+
if (!blob || blob.byteLength === 0 || blob.byteLength > maxOfferBytes) {
|
|
636
|
+
rec.rejected.push({ oid: String(offer?.oid || "").slice(0, 10), error: `intent offer must carry intentB64 <= ${maxOfferBytes / (1024 * 1024)} MiB` });
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
let doc = null;
|
|
640
|
+
try {
|
|
641
|
+
doc = JSON.parse(dec3.decode(blob));
|
|
642
|
+
} catch {
|
|
643
|
+
}
|
|
644
|
+
const intentId = typeof doc?.id === "string" ? doc.id : null;
|
|
645
|
+
const dom = typeof doc?.payload?.domain === "string" ? doc.payload.domain : null;
|
|
646
|
+
const dirId = typeof doc?.payload?.directiveId === "string" ? doc.payload.directiveId : null;
|
|
647
|
+
const oid = String(offer?.oid || intentId || "").slice(0, 10);
|
|
648
|
+
if (!dom) {
|
|
649
|
+
rec.rejected.push({ oid, error: "non-authored intent \u2014 governance enters its own admin lane" });
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
if (receiptFence && dirId && Array.isArray(receiptFence[dom]) && receiptFence[dom].includes(dirId)) {
|
|
653
|
+
const error = `'${dom}/${dirId}' is a capability RECEIPT \u2014 receipts are executor/owner writes, never open-session writes. Author it via POST /v1/workspaces/${ws}/author (owner Bearer), or \u2014 if this parked receipt is sanctioned \u2014 the owner unjams it: POST /v1/workspaces/${ws}/dead-letters/retry`;
|
|
654
|
+
rec.rejected.push({ oid, error, deadLettered: true });
|
|
655
|
+
deadLetters.push({ intentId, oid, session: cid, error, blob, domain: dom, directiveId: dirId });
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
if (intentId && main.ids.has(intentId)) {
|
|
659
|
+
rec.skipped.push({ oid, intent: intentId.slice(0, 12), alreadyOnMain: true });
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
const cap = summaryCtx ? beginSummaryCapture(eng, ws, summaryCtx, blob) : null;
|
|
663
|
+
const _tOffer = Date.now();
|
|
664
|
+
const res = offerAdmit(eng, ws, blob, { defer: !summaryCtx });
|
|
665
|
+
log("offer-admit-ms", { ws, ms: Date.now() - _tOffer, deferred: !summaryCtx, ok: res.ok });
|
|
666
|
+
if (res.ok) {
|
|
667
|
+
if (intentId) main.ids.add(intentId);
|
|
668
|
+
main.oids.add(res.head);
|
|
669
|
+
main.head = res.head;
|
|
670
|
+
rec.admitted.push({ oid, head: res.head });
|
|
671
|
+
admittedTotal += 1;
|
|
672
|
+
if (Array.isArray(res.born) && res.born.length) born.push(...res.born);
|
|
673
|
+
if (Array.isArray(res.birthOutcomes) && res.birthOutcomes.length) birthOutcomes.push(...res.birthOutcomes);
|
|
674
|
+
if (cap) finishSummaryCapture(eng, ws, summaryCtx, cap, res.head, intentId);
|
|
675
|
+
} else {
|
|
676
|
+
const error = `${String(res.error || "").slice(0, 300)} \u2014 dead-lettered; fix the law (or the payload), then POST /v1/workspaces/${ws}/dead-letters/retry`;
|
|
677
|
+
rec.rejected.push({ oid, error, deadLettered: true });
|
|
678
|
+
deadLetters.push({ intentId, oid, session: cid, error, blob, domain: dom, directiveId: dirId });
|
|
679
|
+
}
|
|
680
|
+
} catch (e) {
|
|
681
|
+
rec.rejected.push({ oid: String(offer?.oid || "").slice(0, 10), error: String(e).slice(0, 200) });
|
|
682
|
+
} finally {
|
|
683
|
+
done();
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
timings.sessions = sessions.size;
|
|
687
|
+
timings.intents = admittedTotal;
|
|
688
|
+
if (admittedTotal && !summaryCtx) (eng.pendingProjection ??= /* @__PURE__ */ new Set()).add(ws);
|
|
689
|
+
if (deadLetters.length) {
|
|
690
|
+
try {
|
|
691
|
+
await materializeRefused(eng, ws, ledger, deadLetters);
|
|
692
|
+
} catch (e) {
|
|
693
|
+
log("refused-materialize-failed", { ws, error: String(e).slice(0, 200) });
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
const deferDurability = defer && !summaryCtx;
|
|
697
|
+
if (admittedTotal && !deferDurability) {
|
|
698
|
+
const sealDone = span("seal offered intents", "cseal", 1, { admitted: admittedTotal });
|
|
699
|
+
await commitAndPush(eng, ws, ledger);
|
|
700
|
+
sealDone();
|
|
701
|
+
}
|
|
702
|
+
const gitdir = gitdirOf(ws);
|
|
703
|
+
const head = kgit.resolveRef(eng, gitdir, BRANCH) ?? main.head;
|
|
704
|
+
const summary = summaryCtx ? summaryOfCapture(summaryCtx, headBefore, head) : null;
|
|
705
|
+
let resultPackB64 = null;
|
|
706
|
+
if (admittedTotal && head && /^[0-9a-f]{40}$/i.test(clientBase || "") && clientBase !== head) {
|
|
707
|
+
try {
|
|
708
|
+
const p = servePack(eng, ws, clientBase);
|
|
709
|
+
if (p && p.packB64 && p.bytes && p.bytes <= RESULT_PACK_INLINE_MAX) resultPackB64 = p.packB64;
|
|
710
|
+
} catch {
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
log("admit-intent-offers", { ws, sessions: sessions.size, admitted: admittedTotal, rejected: [...sessions.values()].reduce((n, s) => n + s.rejected.length, 0), resultPack: resultPackB64 ? "inline" : "none" });
|
|
714
|
+
const bornPacked = born.length ? packBornChildren(eng, born) : born;
|
|
715
|
+
return { sessions: [...sessions.values()].map((s) => ({ ...s, ...s.skipped.length ? {} : { skipped: void 0 } })), main: head, deadLetters, timings, ...summary ? { summary } : {}, ...bornPacked.length ? { born: bornPacked } : {}, ...birthOutcomes.length ? { birthOutcomes } : {}, ...resultPackB64 ? { resultPackB64, resultBase: clientBase } : {}, ...deferDurability && admittedTotal && head ? { deferred: true, head } : {} };
|
|
716
|
+
}
|
|
597
717
|
async function authorOn(eng, ws, ledger, domain, directiveId, payload, lawHash, opts = {}) {
|
|
598
718
|
await mountWorkspace(eng, ws, ledger);
|
|
599
719
|
let res;
|
|
@@ -1176,6 +1296,35 @@ async function writeRefusedRef(eng, ws, dl) {
|
|
|
1176
1296
|
});
|
|
1177
1297
|
return ref;
|
|
1178
1298
|
}
|
|
1299
|
+
async function listRefusedRefs(eng, ws) {
|
|
1300
|
+
const gitdir = gitdirOf(ws);
|
|
1301
|
+
const refs = kgit.listRefs(eng, gitdir, "refs/heads/refused/");
|
|
1302
|
+
const out = [];
|
|
1303
|
+
for (const { ref, oid } of refs) {
|
|
1304
|
+
try {
|
|
1305
|
+
const vb = kgit.readBlob(eng, gitdir, oid, "verdict.json");
|
|
1306
|
+
const ib = kgit.readBlob(eng, gitdir, oid, "intent.json");
|
|
1307
|
+
const v = JSON.parse(dec3.decode(vb));
|
|
1308
|
+
out.push({ ref, ...v, intentB64: b64Bytes(ib) });
|
|
1309
|
+
} catch {
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
return out;
|
|
1313
|
+
}
|
|
1314
|
+
async function refusedSummary(eng, ws) {
|
|
1315
|
+
const gitdir = gitdirOf(ws);
|
|
1316
|
+
const refs = kgit.listRefs(eng, gitdir, "refs/heads/refused/");
|
|
1317
|
+
let count2 = 0, latestParkedAt = null;
|
|
1318
|
+
for (const { oid } of refs) {
|
|
1319
|
+
try {
|
|
1320
|
+
const v = JSON.parse(dec3.decode(kgit.readBlob(eng, gitdir, oid, "verdict.json")));
|
|
1321
|
+
count2++;
|
|
1322
|
+
if (v && typeof v.parkedAt === "string" && (!latestParkedAt || v.parkedAt > latestParkedAt)) latestParkedAt = v.parkedAt;
|
|
1323
|
+
} catch {
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return { count: count2, latestParkedAt };
|
|
1327
|
+
}
|
|
1179
1328
|
async function materializeRefused(eng, ws, ledger, deadLetters) {
|
|
1180
1329
|
const refs = [];
|
|
1181
1330
|
const unparkedSessions = /* @__PURE__ */ new Set();
|
|
@@ -1191,6 +1340,20 @@ async function materializeRefused(eng, ws, ledger, deadLetters) {
|
|
|
1191
1340
|
}
|
|
1192
1341
|
return { refs, unparkedSessions };
|
|
1193
1342
|
}
|
|
1343
|
+
async function deleteRefusedRef(eng, ws, ledger, offerId) {
|
|
1344
|
+
const gitdir = gitdirOf(ws);
|
|
1345
|
+
const ref = refusedRefName(offerId);
|
|
1346
|
+
try {
|
|
1347
|
+
kgit.deleteRef(eng, gitdir, ref);
|
|
1348
|
+
} catch {
|
|
1349
|
+
}
|
|
1350
|
+
try {
|
|
1351
|
+
await custodyPush(eng, ws, ledger, { remoteRef: ref, del: true });
|
|
1352
|
+
} catch (e) {
|
|
1353
|
+
log("refused-ref-delete-push-failed", { ws, ref, error: String(e).slice(0, 200) });
|
|
1354
|
+
}
|
|
1355
|
+
return ref;
|
|
1356
|
+
}
|
|
1194
1357
|
async function boot(eng, ws, ledger) {
|
|
1195
1358
|
const m = await mountWorkspace(eng, ws, ledger);
|
|
1196
1359
|
if (nomosActive(eng, ws)) {
|
|
@@ -1588,6 +1751,34 @@ function receivePackCommands(raw) {
|
|
|
1588
1751
|
// ../cloud/dev-server/server.mjs
|
|
1589
1752
|
var DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
1590
1753
|
var REPO_ROOT = path.resolve(DIR, "../..");
|
|
1754
|
+
var RECOGNIZED_UNSUPPORTED = /* @__PURE__ */ new Set([
|
|
1755
|
+
"container-status",
|
|
1756
|
+
"recycle-container",
|
|
1757
|
+
"hostnames",
|
|
1758
|
+
"rebirth-custody",
|
|
1759
|
+
"upload-begin",
|
|
1760
|
+
"upload-gate",
|
|
1761
|
+
"upload-verify",
|
|
1762
|
+
"drain-reclaims",
|
|
1763
|
+
"drain-rebirths",
|
|
1764
|
+
"git-read-lease",
|
|
1765
|
+
"poke-admit",
|
|
1766
|
+
"clear-checkpoint",
|
|
1767
|
+
"domain-package",
|
|
1768
|
+
"capabilities"
|
|
1769
|
+
]);
|
|
1770
|
+
var UNSUPPORTED_WHY = {
|
|
1771
|
+
"container-status": "the heavy container tier is Cloudflare-only (the dev cloud is one in-process engine)",
|
|
1772
|
+
"recycle-container": "the heavy container tier is Cloudflare-only (the dev cloud is one in-process engine)",
|
|
1773
|
+
"hostnames": "platform custom-hostname routing is a multi-tenant edge concern",
|
|
1774
|
+
"rebirth-custody": "the custodian rebirth lane is bound to Cloudflare Artifacts custody",
|
|
1775
|
+
"upload-begin": "the staged-upload birth variant \u2014 push to /v2/workspaces/<ws>/git instead (the upload-birth lane works locally)",
|
|
1776
|
+
"upload-gate": "the staged-upload birth variant \u2014 push to /v2/workspaces/<ws>/git instead",
|
|
1777
|
+
"upload-verify": "the staged-upload birth variant \u2014 push to /v2/workspaces/<ws>/git instead",
|
|
1778
|
+
"drain-reclaims": "an operator lawful-recovery drain (multi-node lifecycle)",
|
|
1779
|
+
"drain-rebirths": "an operator lawful-recovery drain (multi-node lifecycle)",
|
|
1780
|
+
"capabilities": "retired everywhere \u2014 host-side capability storage is gone (capabilities are holon-offered obligations now)"
|
|
1781
|
+
};
|
|
1591
1782
|
var _realFetch = globalThis.fetch;
|
|
1592
1783
|
globalThis.fetch = (input, init) => {
|
|
1593
1784
|
const u = typeof input === "string" ? input : input && input.url || "";
|
|
@@ -1903,6 +2094,83 @@ async function startDevCloud(opts = {}) {
|
|
|
1903
2094
|
sendJson(res, { ok: true, ws, sessions: out.sessions, main: out.main, ...out.timings ? { timings: out.timings } : {} });
|
|
1904
2095
|
});
|
|
1905
2096
|
}
|
|
2097
|
+
if (sub[0] === "intent-offers" && req.method === "POST") {
|
|
2098
|
+
return serialize(async () => {
|
|
2099
|
+
const ledger = ledgerFor(ws);
|
|
2100
|
+
await mountWorkspace(eng, ws, ledger);
|
|
2101
|
+
const body = JSON.parse((await readBody(req)).toString("utf8") || "{}");
|
|
2102
|
+
const offers = Array.isArray(body.offers) ? body.offers.slice(0, 100) : [];
|
|
2103
|
+
if (!offers.length) return sendJson(res, { ok: false, error: "body must be { offers:[{session, oid, intentB64}] }" }, 400);
|
|
2104
|
+
const clientBase = /^[0-9a-f]{40}$/i.test(body.base || "") ? body.base : null;
|
|
2105
|
+
const out = await admitIntentOffers(eng, ws, ledger, offers, { ...clientBase ? { clientBase } : {} });
|
|
2106
|
+
if (Array.isArray(out.born) && out.born.length) await persistBorn(out.born);
|
|
2107
|
+
const bornOut = Array.isArray(out.born) ? out.born.map(({ packB64, packBytes, ...b }) => b) : null;
|
|
2108
|
+
sendJson(res, {
|
|
2109
|
+
ok: true,
|
|
2110
|
+
ws,
|
|
2111
|
+
sessions: out.sessions,
|
|
2112
|
+
main: out.main,
|
|
2113
|
+
...bornOut ? { born: bornOut } : {},
|
|
2114
|
+
...out.birthOutcomes ? { birthOutcomes: out.birthOutcomes } : {},
|
|
2115
|
+
...out.mainDelta ? { mainDelta: out.mainDelta } : {},
|
|
2116
|
+
...out.resultPackB64 ? { resultPackB64: out.resultPackB64, resultBase: out.resultBase } : {},
|
|
2117
|
+
...out.deadLetters && out.deadLetters.length ? { deadLetters: out.deadLetters.map(({ blob, ...m }) => m) } : {}
|
|
2118
|
+
});
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
if (sub[0] === "dead-letters" && sub.length === 1 && req.method === "GET") {
|
|
2122
|
+
return serialize(async () => {
|
|
2123
|
+
await mountWorkspace(eng, ws, ledgerFor(ws));
|
|
2124
|
+
sendJson(res, { ok: true, ws, deadLetters: await listRefusedRefs(eng, ws) });
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
if (sub[0] === "dlq-summary" && req.method === "GET") {
|
|
2128
|
+
return serialize(async () => {
|
|
2129
|
+
await mountWorkspace(eng, ws, ledgerFor(ws));
|
|
2130
|
+
sendJson(res, { ok: true, ws, ...await refusedSummary(eng, ws) });
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
if (sub[0] === "dead-letters" && sub[1] === "retry" && req.method === "POST") {
|
|
2134
|
+
return serialize(async () => {
|
|
2135
|
+
const ledger = ledgerFor(ws);
|
|
2136
|
+
await mountWorkspace(eng, ws, ledger);
|
|
2137
|
+
const body = JSON.parse((await readBody(req)).toString("utf8") || "{}");
|
|
2138
|
+
const only = body.id || null;
|
|
2139
|
+
const refs = await listRefusedRefs(eng, ws);
|
|
2140
|
+
const retried = [], failed = [];
|
|
2141
|
+
for (const e of refs) {
|
|
2142
|
+
if (only && e.offerId !== only && e.oid !== only) continue;
|
|
2143
|
+
if (!e.intentB64) {
|
|
2144
|
+
failed.push({ intentId: e.offerId, error: "refused ref carries no intent bytes" });
|
|
2145
|
+
continue;
|
|
2146
|
+
}
|
|
2147
|
+
try {
|
|
2148
|
+
const r2 = offerAdmit(eng, ws, unb64(e.intentB64));
|
|
2149
|
+
if (r2.ok) retried.push({ intentId: e.offerId, head: r2.head });
|
|
2150
|
+
else failed.push({ intentId: e.offerId, error: String(r2.error || "").slice(0, 300) });
|
|
2151
|
+
} catch (err) {
|
|
2152
|
+
failed.push({ intentId: e.offerId, error: String(err).slice(0, 300) });
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
if (retried.length) await commitAndPush(eng, ws, ledger);
|
|
2156
|
+
for (const r2 of retried) await deleteRefusedRef(eng, ws, ledger, r2.intentId);
|
|
2157
|
+
sendJson(res, { ok: true, ws, retried, failed, remaining: (await listRefusedRefs(eng, ws)).length });
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
if (sub[0] === "dead-letters" && (sub[1] === "discard" || req.method === "DELETE")) {
|
|
2161
|
+
return serialize(async () => {
|
|
2162
|
+
const ledger = ledgerFor(ws);
|
|
2163
|
+
await mountWorkspace(eng, ws, ledger);
|
|
2164
|
+
const body = req.method === "DELETE" ? {} : JSON.parse((await readBody(req)).toString("utf8") || "{}");
|
|
2165
|
+
const only = body.id || url.searchParams.get("id") || null;
|
|
2166
|
+
const targets = (await listRefusedRefs(eng, ws)).filter((e) => !only || e.offerId === only || e.oid === only);
|
|
2167
|
+
for (const e of targets) await deleteRefusedRef(eng, ws, ledger, e.offerId || e.oid);
|
|
2168
|
+
sendJson(res, { ok: true, ws, discarded: targets.length });
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
if (sub[0] === "rotate-secret" && req.method === "POST") {
|
|
2172
|
+
return sendJson(res, { ok: false, retired: true, error: "rotate-secret is retired \u2014 ownership is a ledger fact (sha256 of the push password on the law record); re-own by re-birthing via the upload lane" }, 410);
|
|
2173
|
+
}
|
|
1906
2174
|
if (sub[0] === "pack" && req.method === "GET") {
|
|
1907
2175
|
return serialize(async () => {
|
|
1908
2176
|
await mountWorkspace(eng, ws, ledgerFor(ws));
|
|
@@ -1951,7 +2219,17 @@ async function startDevCloud(opts = {}) {
|
|
|
1951
2219
|
const resolved = resolveGatewayOperation(spec, opName, method);
|
|
1952
2220
|
if (resolved.ambiguous) return sendJson(res, { ok: false, error: "ambiguous operation", candidates: resolved.ambiguous }, 409);
|
|
1953
2221
|
const x = resolved.op && resolved.op["x-nomos"];
|
|
1954
|
-
if (!x)
|
|
2222
|
+
if (!x) {
|
|
2223
|
+
if (RECOGNIZED_UNSUPPORTED.has(opName)) {
|
|
2224
|
+
return sendJson(res, {
|
|
2225
|
+
ok: false,
|
|
2226
|
+
unsupported: true,
|
|
2227
|
+
route: opName,
|
|
2228
|
+
error: `'${opName}' is a recognized Nomos Cloud route that 'githolon cloud dev' (single-node local) does not serve \u2014 ${UNSUPPORTED_WHY[opName] || "a multi-node / Cloudflare-infra concern"}. This is NOT an app bug; if you need it locally, ask the Nomos devs.`
|
|
2229
|
+
}, 501);
|
|
2230
|
+
}
|
|
2231
|
+
return sendJson(res, { ok: false, error: "unknown operation", see: `GET /v2/workspaces/${ws}` }, 404);
|
|
2232
|
+
}
|
|
1955
2233
|
const principal = principalOf(req);
|
|
1956
2234
|
const authToken = authTokenOf(req);
|
|
1957
2235
|
if (x.kind === "offer" && method === "post") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.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",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
32
|
-
"@githolon/client": "^0.
|
|
33
|
-
"@githolon/dsl": "^0.
|
|
32
|
+
"@githolon/client": "^0.86.0",
|
|
33
|
+
"@githolon/dsl": "^0.86.0",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|