githolon 0.48.0 → 0.49.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 +153 -21
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -1299,6 +1299,44 @@ var init_git_fs = __esm({
|
|
|
1299
1299
|
});
|
|
1300
1300
|
|
|
1301
1301
|
// vendor/engine/tree.mjs
|
|
1302
|
+
function flatten(dir, prefix, out12) {
|
|
1303
|
+
for (const [name, inode] of dir.contents) {
|
|
1304
|
+
const path = prefix ? prefix + "/" + name : name;
|
|
1305
|
+
if (inode.contents instanceof Map) {
|
|
1306
|
+
out12.push({ path, dir: true });
|
|
1307
|
+
flatten(inode, path, out12);
|
|
1308
|
+
} else {
|
|
1309
|
+
out12.push({ path, dir: false, bytes: inode.data ?? new Uint8Array(0) });
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function serializeTree(workTree) {
|
|
1314
|
+
const entries = [];
|
|
1315
|
+
flatten(workTree, "", entries);
|
|
1316
|
+
const chunks = [];
|
|
1317
|
+
const header = new Uint8Array(4);
|
|
1318
|
+
new DataView(header.buffer).setUint32(0, entries.length, true);
|
|
1319
|
+
chunks.push(header);
|
|
1320
|
+
for (const e of entries) {
|
|
1321
|
+
const pathBytes = enc.encode(e.path);
|
|
1322
|
+
const body = e.dir ? new Uint8Array(0) : e.bytes ?? new Uint8Array(0);
|
|
1323
|
+
const meta = new Uint8Array(9);
|
|
1324
|
+
const dv = new DataView(meta.buffer);
|
|
1325
|
+
dv.setUint8(0, e.dir ? 1 : 0);
|
|
1326
|
+
dv.setUint32(1, pathBytes.length, true);
|
|
1327
|
+
dv.setUint32(5, body.length, true);
|
|
1328
|
+
chunks.push(meta, pathBytes, body);
|
|
1329
|
+
}
|
|
1330
|
+
let total = 0;
|
|
1331
|
+
for (const c of chunks) total += c.length;
|
|
1332
|
+
const out12 = new Uint8Array(total);
|
|
1333
|
+
let off = 0;
|
|
1334
|
+
for (const c of chunks) {
|
|
1335
|
+
out12.set(c, off);
|
|
1336
|
+
off += c.length;
|
|
1337
|
+
}
|
|
1338
|
+
return out12;
|
|
1339
|
+
}
|
|
1302
1340
|
var enc, dec;
|
|
1303
1341
|
var init_tree = __esm({
|
|
1304
1342
|
"vendor/engine/tree.mjs"() {
|
|
@@ -2268,6 +2306,74 @@ var init_proof_offline = __esm({
|
|
|
2268
2306
|
}
|
|
2269
2307
|
});
|
|
2270
2308
|
|
|
2309
|
+
// src/harness.ts
|
|
2310
|
+
var harness_exports = {};
|
|
2311
|
+
__export(harness_exports, {
|
|
2312
|
+
harnessInstall: () => harnessInstall
|
|
2313
|
+
});
|
|
2314
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
2315
|
+
import { join as join10 } from "node:path";
|
|
2316
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
2317
|
+
async function harnessInstall(opts) {
|
|
2318
|
+
const { deploy: deployPaths, workspace, out: outPath } = opts;
|
|
2319
|
+
if (deployPaths.length === 0) die("no --deploy JSON path(s) given");
|
|
2320
|
+
const runtimeDir = opts.runtime || process.env["NOMOS_OFFLINE_RUNTIME"] || join10(configDir(), "runtime");
|
|
2321
|
+
const wasmFile = join10(runtimeDir, "holon.wasm");
|
|
2322
|
+
const pkgsFile = join10(runtimeDir, "packages.json");
|
|
2323
|
+
if (!existsSync9(wasmFile) || !existsSync9(pkgsFile)) {
|
|
2324
|
+
die(
|
|
2325
|
+
`runtime cache missing at ${runtimeDir} (holon.wasm + packages.json). Warm it once with a \`githolon\` run (it fetches + caches the runtime), then re-run offline.`
|
|
2326
|
+
);
|
|
2327
|
+
}
|
|
2328
|
+
const wasm = readFileSync11(wasmFile);
|
|
2329
|
+
const pkgs = JSON.parse(readFileSync11(pkgsFile, "utf8"));
|
|
2330
|
+
const replica = BigInt(`0x${randomBytes3(8).toString("hex")}`) & (1n << 63n) - 1n;
|
|
2331
|
+
const eng = await createEngine({
|
|
2332
|
+
wasmModule: await WebAssembly.compile(wasm),
|
|
2333
|
+
bootstrapPkg: pkgs.bootstrap,
|
|
2334
|
+
nomosPkg: pkgs.nomos,
|
|
2335
|
+
replica,
|
|
2336
|
+
installedBy: "nomos-test-harness"
|
|
2337
|
+
});
|
|
2338
|
+
await mountFresh(eng, workspace);
|
|
2339
|
+
author(eng, workspace, "bootstrap", "installDomain", installPayload(eng.hashes.nomos, eng.nomosPkg, "nomos-test-harness"), "");
|
|
2340
|
+
const lawHashes = [];
|
|
2341
|
+
for (const p of deployPaths) {
|
|
2342
|
+
if (!existsSync9(p)) die(`deploy JSON not found: ${p} \u2014 run \`npx githolon compile\` first`);
|
|
2343
|
+
const deploy2 = JSON.parse(readFileSync11(p, "utf8"));
|
|
2344
|
+
const usda = deploy2.packageUsda;
|
|
2345
|
+
if (typeof usda !== "string" || !usda.startsWith("#usda")) die(`${p} has no #usda packageUsda`);
|
|
2346
|
+
const lawHash = await sha256hex(usda);
|
|
2347
|
+
author(eng, workspace, "nomos", "installDomain", installPayload(lawHash, usda, "nomos-test-harness"), eng.hashes.nomos);
|
|
2348
|
+
lawHashes.push(lawHash);
|
|
2349
|
+
process.stderr.write(`harness-install: installed ${p} (law ${lawHash.slice(0, 12)}\u2026)
|
|
2350
|
+
`);
|
|
2351
|
+
}
|
|
2352
|
+
const wsNode = eng.preopen.dir.contents.get("ws").contents.get(workspace);
|
|
2353
|
+
if (!wsNode) die(`internal: workspace tree '${workspace}' not found after install`);
|
|
2354
|
+
const treeBytes = serializeTree(wsNode);
|
|
2355
|
+
writeFileSync6(outPath, treeBytes);
|
|
2356
|
+
process.stderr.write(`harness-install: snapshot written (${treeBytes.length} bytes) \u2192 ${outPath}
|
|
2357
|
+
`);
|
|
2358
|
+
process.stdout.write(JSON.stringify({ ok: true, snapshot: outPath, workspace, lawHashes }) + "\n");
|
|
2359
|
+
return 0;
|
|
2360
|
+
}
|
|
2361
|
+
var die;
|
|
2362
|
+
var init_harness = __esm({
|
|
2363
|
+
"src/harness.ts"() {
|
|
2364
|
+
"use strict";
|
|
2365
|
+
init_engine();
|
|
2366
|
+
init_tree();
|
|
2367
|
+
init_local_holon();
|
|
2368
|
+
init_cloud();
|
|
2369
|
+
die = (msg) => {
|
|
2370
|
+
process.stderr.write(`harness-install: ${msg}
|
|
2371
|
+
`);
|
|
2372
|
+
process.exit(1);
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2376
|
+
|
|
2271
2377
|
// src/scene_projector.ts
|
|
2272
2378
|
import { createHash as createHash4 } from "node:crypto";
|
|
2273
2379
|
function fnv1a32(s) {
|
|
@@ -2517,8 +2623,10 @@ function glyphSignature(structJson, name, partCount) {
|
|
|
2517
2623
|
return { structureHash: h, facetCount, hue, hueBase, elongation, size, color: hslToRgb(hue, 0.62, 0.6) };
|
|
2518
2624
|
}
|
|
2519
2625
|
function packageLayers(packageUsda) {
|
|
2626
|
+
const b = /nomos:usdJsonB64 = "([A-Za-z0-9+/=]+)"/.exec(packageUsda);
|
|
2627
|
+
if (b) return JSON.parse(Buffer.from(b[1], "base64").toString("utf8")).layers;
|
|
2520
2628
|
const m = /nomos:usdJsonHex = "([0-9a-f]+)"/.exec(packageUsda);
|
|
2521
|
-
if (!m) throw new Error("a chain-installed package carries no nomos:
|
|
2629
|
+
if (!m) throw new Error("a chain-installed package carries no nomos:usdJson blob \u2014 not an openusd-ir package");
|
|
2522
2630
|
return JSON.parse(Buffer.from(m[1], "hex").toString("utf8")).layers;
|
|
2523
2631
|
}
|
|
2524
2632
|
function lawInstallsFromChain(entries) {
|
|
@@ -3322,8 +3430,8 @@ var scene_exports = {};
|
|
|
3322
3430
|
__export(scene_exports, {
|
|
3323
3431
|
scene: () => scene
|
|
3324
3432
|
});
|
|
3325
|
-
import { existsSync as
|
|
3326
|
-
import { join as
|
|
3433
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync4, writeFileSync as writeFileSync7 } from "node:fs";
|
|
3434
|
+
import { join as join11, resolve as resolve2 } from "node:path";
|
|
3327
3435
|
import { createHash as createHash5 } from "node:crypto";
|
|
3328
3436
|
import git3 from "isomorphic-git";
|
|
3329
3437
|
async function walkChain2(eng, ws) {
|
|
@@ -3344,8 +3452,8 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
3344
3452
|
const { eng } = await holonEngine(cloud, void 0, "githolon-scene");
|
|
3345
3453
|
const SOURCE3 = "source";
|
|
3346
3454
|
if (isDir) {
|
|
3347
|
-
const gitDir =
|
|
3348
|
-
if (!
|
|
3455
|
+
const gitDir = existsSync10(join11(target, ".git")) ? join11(target, ".git") : target;
|
|
3456
|
+
if (!existsSync10(join11(gitDir, "HEAD"))) throw new Error(`${target} is not a git repo (no HEAD)`);
|
|
3349
3457
|
await mountFresh(eng, SOURCE3);
|
|
3350
3458
|
eng.preopen.dir.contents.get("ws").contents.get(SOURCE3).contents.set("nomos.git", readTreeFromDisk(gitDir));
|
|
3351
3459
|
} else {
|
|
@@ -3404,7 +3512,7 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
3404
3512
|
}
|
|
3405
3513
|
async function scene(target, opts) {
|
|
3406
3514
|
const cloud = cloudBase(opts.cloud);
|
|
3407
|
-
const isDir =
|
|
3515
|
+
const isDir = existsSync10(target) || target.includes("/") || target.startsWith(".");
|
|
3408
3516
|
const name = isDir ? (resolve2(target).split("/").filter(Boolean).pop() ?? "scene").replace(/\.git$/, "") : target;
|
|
3409
3517
|
out11(`scene \u2014 ${name} (${isDir ? resolve2(target) : `${cloud} :: ${target}`})`);
|
|
3410
3518
|
let first, second;
|
|
@@ -3424,13 +3532,13 @@ async function scene(target, opts) {
|
|
|
3424
3532
|
err11(`the emitted stage violates the portable profile: ${violations.join("; ")}`);
|
|
3425
3533
|
return 1;
|
|
3426
3534
|
}
|
|
3427
|
-
const outDir = resolve2(opts.out ??
|
|
3535
|
+
const outDir = resolve2(opts.out ?? join11("scene", name));
|
|
3428
3536
|
mkdirSync4(outDir, { recursive: true });
|
|
3429
|
-
const usdaPath =
|
|
3430
|
-
const usdzPath =
|
|
3537
|
+
const usdaPath = join11(outDir, `${name}.usda`);
|
|
3538
|
+
const usdzPath = join11(outDir, `${name}.usdz`);
|
|
3431
3539
|
const usdaBytes = new TextEncoder().encode(first.usda);
|
|
3432
|
-
|
|
3433
|
-
|
|
3540
|
+
writeFileSync7(usdaPath, usdaBytes);
|
|
3541
|
+
writeFileSync7(usdzPath, usdzPack([[`${name}.usda`, usdaBytes]]));
|
|
3434
3542
|
const s = first.stats;
|
|
3435
3543
|
out11(` verify_chain ${s.verdictLine}`);
|
|
3436
3544
|
out11(` law canopy ${s.nodes} node(s), ${s.edges} edge(s) \u2014 from the chain's own installed packages`);
|
|
@@ -3456,10 +3564,10 @@ var init_scene = __esm({
|
|
|
3456
3564
|
});
|
|
3457
3565
|
|
|
3458
3566
|
// src/cli.ts
|
|
3459
|
-
import { existsSync as
|
|
3567
|
+
import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "node:fs";
|
|
3460
3568
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
3461
3569
|
import { createRequire as createRequire2 } from "node:module";
|
|
3462
|
-
import { dirname as dirname5, join as
|
|
3570
|
+
import { dirname as dirname5, join as join12, resolve as resolve3 } from "node:path";
|
|
3463
3571
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
3464
3572
|
|
|
3465
3573
|
// src/generate.ts
|
|
@@ -4829,6 +4937,9 @@ Authoring:
|
|
|
4829
4937
|
githolon compile [compiler args] compile the package by ./nomos.package.mjs
|
|
4830
4938
|
githolon proof [build/<name>.proof.mts] run the proof GENERATED from your law, live
|
|
4831
4939
|
(every compile emits it; ALL GREEN or it names the jam)
|
|
4940
|
+
githolon harness-install --deploy <deploy.json[,...]> offline install for the headless TEST HARNESS:
|
|
4941
|
+
--workspace <ws> --out <snapshot> install tenant law IN-CHAIN (no cloud), write the
|
|
4942
|
+
restore snapshot, print { ok, snapshot, lawHashes }
|
|
4832
4943
|
githolon generate <domain|aggregate|intent> <name> [options]
|
|
4833
4944
|
githolon g <domain|aggregate|intent> <name> [options]
|
|
4834
4945
|
|
|
@@ -5009,10 +5120,10 @@ async function runProof(args) {
|
|
|
5009
5120
|
let proofPath;
|
|
5010
5121
|
if (explicit !== void 0) {
|
|
5011
5122
|
proofPath = resolve3(process.cwd(), explicit);
|
|
5012
|
-
if (!
|
|
5123
|
+
if (!existsSync11(proofPath)) return refuse(`proof not found: ${proofPath} \u2014 run \`githolon compile\` to (re)generate it`);
|
|
5013
5124
|
} else {
|
|
5014
|
-
const buildDir =
|
|
5015
|
-
if (!
|
|
5125
|
+
const buildDir = join12(process.cwd(), "build");
|
|
5126
|
+
if (!existsSync11(buildDir)) {
|
|
5016
5127
|
return refuse("no build/ directory here \u2014 run `githolon compile` first (every compile generates build/<name>.proof.mts from your law)");
|
|
5017
5128
|
}
|
|
5018
5129
|
const proofs = readdirSync4(buildDir).filter((f) => f.endsWith(".proof.mts"));
|
|
@@ -5022,7 +5133,7 @@ async function runProof(args) {
|
|
|
5022
5133
|
if (proofs.length > 1) {
|
|
5023
5134
|
return refuse(`found ${proofs.length} proofs (${proofs.join(", ")}) \u2014 name one: githolon proof build/<name>.proof.mts`);
|
|
5024
5135
|
}
|
|
5025
|
-
proofPath =
|
|
5136
|
+
proofPath = join12(buildDir, proofs[0]);
|
|
5026
5137
|
}
|
|
5027
5138
|
if (!live) {
|
|
5028
5139
|
try {
|
|
@@ -5035,14 +5146,14 @@ async function runProof(args) {
|
|
|
5035
5146
|
}
|
|
5036
5147
|
const resolvePkgDir = (name, fromDir) => {
|
|
5037
5148
|
try {
|
|
5038
|
-
return dirname5(createRequire2(pathToFileURL4(
|
|
5149
|
+
return dirname5(createRequire2(pathToFileURL4(join12(fromDir, "noop.js"))).resolve(`${name}/package.json`));
|
|
5039
5150
|
} catch {
|
|
5040
5151
|
return void 0;
|
|
5041
5152
|
}
|
|
5042
5153
|
};
|
|
5043
5154
|
const dslDir = (() => {
|
|
5044
5155
|
try {
|
|
5045
|
-
return dirname5(createRequire2(pathToFileURL4(
|
|
5156
|
+
return dirname5(createRequire2(pathToFileURL4(join12(process.cwd(), "noop.js"))).resolve("@githolon/dsl/package.json"));
|
|
5046
5157
|
} catch {
|
|
5047
5158
|
try {
|
|
5048
5159
|
return dirname5(createRequire2(import.meta.url).resolve("@githolon/dsl/package.json"));
|
|
@@ -5055,9 +5166,9 @@ async function runProof(args) {
|
|
|
5055
5166
|
if (tsxDir === void 0) {
|
|
5056
5167
|
return refuse("tsx not found \u2014 add @githolon/dsl to your project's dependencies (tsx rides along) and npm install");
|
|
5057
5168
|
}
|
|
5058
|
-
const tsxPkg = JSON.parse(
|
|
5169
|
+
const tsxPkg = JSON.parse(readFileSync12(join12(tsxDir, "package.json"), "utf8"));
|
|
5059
5170
|
const tsxBinRel = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.["tsx"];
|
|
5060
|
-
const tsxCli =
|
|
5171
|
+
const tsxCli = join12(tsxDir, tsxBinRel ?? "dist/cli.mjs");
|
|
5061
5172
|
console.log("githolon proof --live \u2014 the full cloud loop (throwaway workspace, retired on exit" + (keep ? "; --keep: kept" : "") + ")");
|
|
5062
5173
|
const { wsCreate: wsCreate2, wsRetire: wsRetire2 } = await Promise.resolve().then(() => (init_cloud(), cloud_exports));
|
|
5063
5174
|
const { resolveGovernancePrincipal: resolveGovernancePrincipal2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
@@ -5168,6 +5279,27 @@ async function main(argv) {
|
|
|
5168
5279
|
if (argv[0] === "proof") {
|
|
5169
5280
|
return runProof(argv.slice(1));
|
|
5170
5281
|
}
|
|
5282
|
+
if (argv[0] === "harness-install") {
|
|
5283
|
+
const rest = argv.slice(1);
|
|
5284
|
+
const pull = (flag) => {
|
|
5285
|
+
const at = rest.indexOf(flag);
|
|
5286
|
+
return at >= 0 ? rest[at + 1] : void 0;
|
|
5287
|
+
};
|
|
5288
|
+
const deployArg = pull("--deploy");
|
|
5289
|
+
const workspace = pull("--workspace") ?? "test-ws";
|
|
5290
|
+
const out12 = pull("--out");
|
|
5291
|
+
const runtime = pull("--runtime");
|
|
5292
|
+
const deploy2 = (deployArg ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
5293
|
+
if (deploy2.length === 0 || out12 === void 0) {
|
|
5294
|
+
process.stderr.write(
|
|
5295
|
+
`error: usage: githolon harness-install --deploy <deploy.json[,deploy.json...]> --workspace <ws> --out <snapshotPath> [--runtime <dir>]
|
|
5296
|
+
`
|
|
5297
|
+
);
|
|
5298
|
+
return 1;
|
|
5299
|
+
}
|
|
5300
|
+
const { harnessInstall: harnessInstall2 } = await Promise.resolve().then(() => (init_harness(), harness_exports));
|
|
5301
|
+
return harnessInstall2({ deploy: deploy2, workspace, out: out12, ...runtime !== void 0 ? { runtime } : {} });
|
|
5302
|
+
}
|
|
5171
5303
|
if (argv[0] === "dev") {
|
|
5172
5304
|
const rest = argv.slice(1);
|
|
5173
5305
|
let cloud;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.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.49.0",
|
|
33
|
+
"@githolon/dsl": "^0.49.0",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|