githolon 0.1.6 → 0.2.1
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 +85 -15
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
5
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
|
|
5
6
|
import { createRequire } from "node:module";
|
|
6
|
-
import { dirname as dirname2, join as join4 } from "node:path";
|
|
7
|
+
import { dirname as dirname2, join as join4, resolve } from "node:path";
|
|
7
8
|
import { pathToFileURL } from "node:url";
|
|
8
9
|
|
|
9
10
|
// src/generate.ts
|
|
@@ -78,8 +79,8 @@ export const ${n.pascal} = aggregate("${n.pascal}", {
|
|
|
78
79
|
function domainTemplate(raw) {
|
|
79
80
|
const n = namesFor(raw);
|
|
80
81
|
return `${HEADER(raw, "domain")}
|
|
81
|
-
import { z } from "zod";
|
|
82
82
|
import {
|
|
83
|
+
z,
|
|
83
84
|
aggregate,
|
|
84
85
|
directive,
|
|
85
86
|
t,
|
|
@@ -140,8 +141,7 @@ ${aggregateBlock(n)}
|
|
|
140
141
|
function intentTemplate(raw) {
|
|
141
142
|
const n = namesFor(raw);
|
|
142
143
|
return `${HEADER(raw, "intent (directive)")}
|
|
143
|
-
import { z } from "
|
|
144
|
-
import { aggregate, directive, t, Conflict, set } from "@githolon/dsl";
|
|
144
|
+
import { z, aggregate, directive, t, Conflict, set } from "@githolon/dsl";
|
|
145
145
|
|
|
146
146
|
// Stub target \u2014 in a real domain, import the existing aggregate handle instead.
|
|
147
147
|
export const ${n.pascal} = aggregate("${n.pascal}", {
|
|
@@ -332,12 +332,23 @@ async function logout() {
|
|
|
332
332
|
}
|
|
333
333
|
async function wsCreate(name, opts) {
|
|
334
334
|
const cloud = cloudBase(opts.cloud);
|
|
335
|
-
|
|
335
|
+
let principal = opts.principal ?? await sessionToken().catch((e) => (err(e.message), void 0)) ?? loadCreds().principal;
|
|
336
336
|
if (principal === void 0) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
)
|
|
340
|
-
|
|
337
|
+
const d2 = await gotrue("/auth/v1/signup", "{}");
|
|
338
|
+
const s = sessionFromGotrue(d2);
|
|
339
|
+
if (s === void 0) {
|
|
340
|
+
err(
|
|
341
|
+
`a birth needs a principal, and automatic agent login failed: ${d2.error_description ?? d2.error ?? d2.msg ?? JSON.stringify(d2)}
|
|
342
|
+
githolon login --agent (self-onboarding), githolon login --token <refresh>,
|
|
343
|
+
or pass --principal <your-auth-uid or access token> (saved as the default)`
|
|
344
|
+
);
|
|
345
|
+
return 1;
|
|
346
|
+
}
|
|
347
|
+
saveSession(s);
|
|
348
|
+
out(`no principal on file \u2014 self-onboarded an anonymous agent identity (githolon login --agent)`);
|
|
349
|
+
out(` principal uid ${s.uid} (linkable to a full account later)`);
|
|
350
|
+
out(` session saved \u2192 ${credsPath()} (auto-refreshed; births ride x-nomos-auth)`);
|
|
351
|
+
principal = s.accessToken;
|
|
341
352
|
}
|
|
342
353
|
const r = await fetch(`${cloud}/v1/workspaces/${name}`, {
|
|
343
354
|
method: "POST",
|
|
@@ -587,7 +598,7 @@ function makeGitFs(preopen, mount, { File: File3, Directory: Directory3 }) {
|
|
|
587
598
|
const rel = p.slice(mount.length + 1).replace(/\/+$/, "");
|
|
588
599
|
return rel === "" ? [] : rel.split("/");
|
|
589
600
|
}
|
|
590
|
-
function
|
|
601
|
+
function resolve2(ps) {
|
|
591
602
|
let cur = root;
|
|
592
603
|
for (const part of ps) {
|
|
593
604
|
if (!isDir(cur)) return null;
|
|
@@ -597,11 +608,11 @@ function makeGitFs(preopen, mount, { File: File3, Directory: Directory3 }) {
|
|
|
597
608
|
}
|
|
598
609
|
return cur;
|
|
599
610
|
}
|
|
600
|
-
const parent = (ps) =>
|
|
611
|
+
const parent = (ps) => resolve2(ps.slice(0, -1));
|
|
601
612
|
const leaf = (ps) => ps[ps.length - 1];
|
|
602
613
|
const promises = {
|
|
603
614
|
async readFile(p, opts) {
|
|
604
|
-
const n =
|
|
615
|
+
const n = resolve2(parts(p));
|
|
605
616
|
if (n === null) throw fsErr("ENOENT", p);
|
|
606
617
|
if (isDir(n)) throw fsErr("EISDIR", p);
|
|
607
618
|
const data = n.data ?? new Uint8Array(0);
|
|
@@ -620,7 +631,7 @@ function makeGitFs(preopen, mount, { File: File3, Directory: Directory3 }) {
|
|
|
620
631
|
if (!isDir(par) || !par.contents.delete(leaf(ps))) throw fsErr("ENOENT", p);
|
|
621
632
|
},
|
|
622
633
|
async readdir(p) {
|
|
623
|
-
const n =
|
|
634
|
+
const n = resolve2(parts(p));
|
|
624
635
|
if (n === null) throw fsErr("ENOENT", p);
|
|
625
636
|
if (!isDir(n)) throw fsErr("ENOTDIR", p);
|
|
626
637
|
return [...n.contents.keys()];
|
|
@@ -640,7 +651,7 @@ function makeGitFs(preopen, mount, { File: File3, Directory: Directory3 }) {
|
|
|
640
651
|
return promises.lstat(p);
|
|
641
652
|
},
|
|
642
653
|
async lstat(p) {
|
|
643
|
-
const n =
|
|
654
|
+
const n = resolve2(parts(p));
|
|
644
655
|
if (n === null) throw fsErr("ENOENT", p);
|
|
645
656
|
const dir = isDir(n);
|
|
646
657
|
return {
|
|
@@ -949,6 +960,8 @@ var USAGE = `githolon \u2014 the Nomos developer CLI
|
|
|
949
960
|
|
|
950
961
|
Authoring:
|
|
951
962
|
githolon compile [compiler args] compile the package by ./nomos.package.mjs
|
|
963
|
+
githolon proof [build/<name>.proof.mts] run the proof GENERATED from your law, live
|
|
964
|
+
(every compile emits it; ALL GREEN or it names the jam)
|
|
952
965
|
githolon generate <domain|aggregate|intent> <name> [options]
|
|
953
966
|
githolon g <domain|aggregate|intent> <name> [options]
|
|
954
967
|
|
|
@@ -960,6 +973,7 @@ Identity (~/.holon/credentials.json \u2014 sessions auto-refresh):
|
|
|
960
973
|
|
|
961
974
|
Nomos Cloud (secrets live in ~/.holon/credentials.json \u2014 never copy one by hand):
|
|
962
975
|
githolon ws create <name> [--principal <uid|token>] birth a workspace; SAVES its one-time secret
|
|
976
|
+
(no identity on file? it self-onboards an agent login)
|
|
963
977
|
githolon ws status <name> workspace status (lineage, phase, verdicts)
|
|
964
978
|
githolon ws retire <name> retire a workspace (owner) \u2014 quota freed; data retained
|
|
965
979
|
per the license; reads keep serving
|
|
@@ -1051,11 +1065,64 @@ function runCompile(args) {
|
|
|
1051
1065
|
const r = spawnSync3(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
|
|
1052
1066
|
return r.status ?? 1;
|
|
1053
1067
|
}
|
|
1068
|
+
function runProof(args) {
|
|
1069
|
+
const refuse = (m) => {
|
|
1070
|
+
process.stderr.write(`error: ${m}
|
|
1071
|
+
`);
|
|
1072
|
+
return 1;
|
|
1073
|
+
};
|
|
1074
|
+
const explicit = args.find((a) => !a.startsWith("--"));
|
|
1075
|
+
let proofPath;
|
|
1076
|
+
if (explicit !== void 0) {
|
|
1077
|
+
proofPath = resolve(process.cwd(), explicit);
|
|
1078
|
+
if (!existsSync4(proofPath)) return refuse(`proof not found: ${proofPath} \u2014 run \`githolon compile\` to (re)generate it`);
|
|
1079
|
+
} else {
|
|
1080
|
+
const buildDir = join4(process.cwd(), "build");
|
|
1081
|
+
if (!existsSync4(buildDir)) {
|
|
1082
|
+
return refuse("no build/ directory here \u2014 run `githolon compile` first (every compile generates build/<name>.proof.mts from your law)");
|
|
1083
|
+
}
|
|
1084
|
+
const proofs = readdirSync3(buildDir).filter((f) => f.endsWith(".proof.mts"));
|
|
1085
|
+
if (proofs.length === 0) {
|
|
1086
|
+
return refuse("no build/*.proof.mts found \u2014 run `githolon compile` (every compile generates the proof from your law; the compile summary says why when it can't)");
|
|
1087
|
+
}
|
|
1088
|
+
if (proofs.length > 1) {
|
|
1089
|
+
return refuse(`found ${proofs.length} proofs (${proofs.join(", ")}) \u2014 name one: githolon proof build/<name>.proof.mts`);
|
|
1090
|
+
}
|
|
1091
|
+
proofPath = join4(buildDir, proofs[0]);
|
|
1092
|
+
}
|
|
1093
|
+
const resolvePkgDir = (name, fromDir) => {
|
|
1094
|
+
try {
|
|
1095
|
+
return dirname2(createRequire(pathToFileURL(join4(fromDir, "noop.js"))).resolve(`${name}/package.json`));
|
|
1096
|
+
} catch {
|
|
1097
|
+
return void 0;
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1100
|
+
const dslDir = (() => {
|
|
1101
|
+
try {
|
|
1102
|
+
return dirname2(createRequire(pathToFileURL(join4(process.cwd(), "noop.js"))).resolve("@githolon/dsl/package.json"));
|
|
1103
|
+
} catch {
|
|
1104
|
+
try {
|
|
1105
|
+
return dirname2(createRequire(import.meta.url).resolve("@githolon/dsl/package.json"));
|
|
1106
|
+
} catch {
|
|
1107
|
+
return void 0;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
})();
|
|
1111
|
+
const tsxDir = resolvePkgDir("tsx", process.cwd()) ?? (dslDir !== void 0 ? resolvePkgDir("tsx", dslDir) : void 0);
|
|
1112
|
+
if (tsxDir === void 0) {
|
|
1113
|
+
return refuse("tsx not found \u2014 add @githolon/dsl to your project's dependencies (tsx rides along) and npm install");
|
|
1114
|
+
}
|
|
1115
|
+
const tsxPkg = JSON.parse(readFileSync4(join4(tsxDir, "package.json"), "utf8"));
|
|
1116
|
+
const tsxBinRel = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.["tsx"];
|
|
1117
|
+
const tsxCli = join4(tsxDir, tsxBinRel ?? "dist/cli.mjs");
|
|
1118
|
+
const r = spawnSync3(process.execPath, [tsxCli, proofPath], { stdio: "inherit", cwd: process.cwd() });
|
|
1119
|
+
return r.status ?? 1;
|
|
1120
|
+
}
|
|
1054
1121
|
function parseArgs(argv) {
|
|
1055
1122
|
const [command, ...rest] = argv;
|
|
1056
1123
|
if (command !== "generate" && command !== "g") {
|
|
1057
1124
|
throw new Error(
|
|
1058
|
-
`Unknown command '${command ?? "(none)"}'. Expected compile | generate | ws | deploy | secret.`
|
|
1125
|
+
`Unknown command '${command ?? "(none)"}'. Expected compile | proof | generate | ws | deploy | secret.`
|
|
1059
1126
|
);
|
|
1060
1127
|
}
|
|
1061
1128
|
let outDir = DEFAULT_OUT;
|
|
@@ -1101,6 +1168,9 @@ async function main(argv) {
|
|
|
1101
1168
|
if (argv[0] === "compile") {
|
|
1102
1169
|
return runCompile(argv.slice(1));
|
|
1103
1170
|
}
|
|
1171
|
+
if (argv[0] === "proof") {
|
|
1172
|
+
return runProof(argv.slice(1));
|
|
1173
|
+
}
|
|
1104
1174
|
if (argv[0] === "ws" || argv[0] === "deploy" || argv[0] === "secret") {
|
|
1105
1175
|
return runCloud(argv);
|
|
1106
1176
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "githolon
|
|
5
|
+
"description": "githolon \u2014 the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
30
|
-
"@githolon/dsl": "^0.1
|
|
30
|
+
"@githolon/dsl": "^0.2.1",
|
|
31
31
|
"isomorphic-git": "^1.38.4"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|