githolon 0.24.0 → 0.25.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 +146 -27
- package/package.json +5 -3
package/dist/cli.mjs
CHANGED
|
@@ -25,10 +25,14 @@ __export(governance_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
import { createHash, createPrivateKey, createPublicKey } from "node:crypto";
|
|
27
27
|
import { readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
28
|
-
|
|
28
|
+
async function clientConnect() {
|
|
29
|
+
const mod = await import("@githolon/client");
|
|
30
|
+
return mod.connect;
|
|
31
|
+
}
|
|
29
32
|
async function connectGovernance(cloud, parent) {
|
|
30
33
|
const authToken = await sessionToken().catch(() => void 0);
|
|
31
34
|
const clientId = `githolon-cli-${Date.now().toString(16)}`;
|
|
35
|
+
const connect = await clientConnect();
|
|
32
36
|
return await connect({
|
|
33
37
|
cloud,
|
|
34
38
|
workspace: parent,
|
|
@@ -49,7 +53,7 @@ async function ensureDeviceKey(holon, principal) {
|
|
|
49
53
|
return key;
|
|
50
54
|
}
|
|
51
55
|
function resolveGovernancePrincipal(opts) {
|
|
52
|
-
const principal = opts.principal ??
|
|
56
|
+
const principal = opts.principal ?? activePrincipal();
|
|
53
57
|
if (principal === void 0) {
|
|
54
58
|
throw new Error(
|
|
55
59
|
"signed governance needs a principal \u2014 githolon login --agent (self-onboarding), or pass --principal <your-auth-uid>"
|
|
@@ -120,7 +124,7 @@ async function grantOrRevoke(verb, kind, subject, opts) {
|
|
|
120
124
|
}
|
|
121
125
|
async function keyEnroll(opts) {
|
|
122
126
|
const cloud = cloudBase(opts.cloud);
|
|
123
|
-
const principal = opts.principal ??
|
|
127
|
+
const principal = opts.principal ?? activePrincipal();
|
|
124
128
|
if (principal === void 0) {
|
|
125
129
|
err("enroll needs a principal \u2014 githolon login --agent first (or --principal <uid>)");
|
|
126
130
|
return 1;
|
|
@@ -151,7 +155,7 @@ async function keyEnroll(opts) {
|
|
|
151
155
|
return 0;
|
|
152
156
|
}
|
|
153
157
|
async function keyShow(opts) {
|
|
154
|
-
const principal = opts.principal ??
|
|
158
|
+
const principal = opts.principal ?? activePrincipal();
|
|
155
159
|
if (principal === void 0) {
|
|
156
160
|
out("no principal on file \u2014 githolon login --agent, or pass --principal <uid>");
|
|
157
161
|
return 0;
|
|
@@ -188,7 +192,7 @@ function seedFromInput(input, opts) {
|
|
|
188
192
|
);
|
|
189
193
|
}
|
|
190
194
|
async function keyImport(opts) {
|
|
191
|
-
const principal = opts.principal ??
|
|
195
|
+
const principal = opts.principal ?? activePrincipal();
|
|
192
196
|
if (principal === void 0) {
|
|
193
197
|
err("key import needs --principal <uid> (the auth-uid this key authors as)");
|
|
194
198
|
return 1;
|
|
@@ -217,7 +221,7 @@ async function keyImport(opts) {
|
|
|
217
221
|
return 0;
|
|
218
222
|
}
|
|
219
223
|
async function keyExport(opts) {
|
|
220
|
-
const principal = opts.principal ??
|
|
224
|
+
const principal = opts.principal ?? activePrincipal();
|
|
221
225
|
if (principal === void 0) {
|
|
222
226
|
err("key export needs --principal <uid>");
|
|
223
227
|
return 1;
|
|
@@ -347,6 +351,9 @@ var init_governance = __esm({
|
|
|
347
351
|
// src/cloud.ts
|
|
348
352
|
var cloud_exports = {};
|
|
349
353
|
__export(cloud_exports, {
|
|
354
|
+
activePrincipal: () => activePrincipal,
|
|
355
|
+
authUse: () => authUse,
|
|
356
|
+
clearActAs: () => clearActAs,
|
|
350
357
|
cloudBase: () => cloudBase,
|
|
351
358
|
configDir: () => configDir,
|
|
352
359
|
currentPrincipal: () => currentPrincipal,
|
|
@@ -362,6 +369,7 @@ __export(cloud_exports, {
|
|
|
362
369
|
secretRotate: () => secretRotate,
|
|
363
370
|
secretSet: () => secretSet,
|
|
364
371
|
sessionToken: () => sessionToken,
|
|
372
|
+
setActAs: () => setActAs,
|
|
365
373
|
setDeviceKey: () => setDeviceKey,
|
|
366
374
|
setPrincipal: () => setPrincipal,
|
|
367
375
|
setSecret: () => setSecret,
|
|
@@ -416,6 +424,43 @@ function currentPrincipal() {
|
|
|
416
424
|
const c = loadCreds();
|
|
417
425
|
return c.session?.uid ?? c.principal;
|
|
418
426
|
}
|
|
427
|
+
function activePrincipal() {
|
|
428
|
+
return loadCreds().actAs ?? currentPrincipal();
|
|
429
|
+
}
|
|
430
|
+
function setActAs(principal) {
|
|
431
|
+
const c = loadCreds();
|
|
432
|
+
c.actAs = principal;
|
|
433
|
+
saveCreds(c);
|
|
434
|
+
}
|
|
435
|
+
function clearActAs() {
|
|
436
|
+
const c = loadCreds();
|
|
437
|
+
delete c.actAs;
|
|
438
|
+
saveCreds(c);
|
|
439
|
+
}
|
|
440
|
+
async function authUse(principal, opts = {}) {
|
|
441
|
+
if (opts.clear === true) {
|
|
442
|
+
clearActAs();
|
|
443
|
+
out2("\u2713 cleared the active signing principal \u2014 signed lanes fall back to the session / bare default");
|
|
444
|
+
return 0;
|
|
445
|
+
}
|
|
446
|
+
if (principal === void 0) {
|
|
447
|
+
const c = loadCreds();
|
|
448
|
+
const active = c.actAs;
|
|
449
|
+
out2(active !== void 0 ? `acting as ${active}${getDeviceKey(active) ? " (key on file \u2713)" : " \u26A0 no signing key \u2014 githolon key import --principal " + active}` : "no active signing principal set (githolon use <uid>) \u2014 signed lanes use the session / bare default");
|
|
450
|
+
const keyed = Object.keys(c.devices ?? {});
|
|
451
|
+
if (keyed.length > 0) {
|
|
452
|
+
out2(`keys on file:`);
|
|
453
|
+
for (const p of keyed) out2(` ${p}${p === active ? " \u2190 active" : ""}`);
|
|
454
|
+
}
|
|
455
|
+
return 0;
|
|
456
|
+
}
|
|
457
|
+
setActAs(principal);
|
|
458
|
+
out2(`\u2713 now acting as ${principal} (signed deploy/gov/grant/key author as this principal)`);
|
|
459
|
+
if (getDeviceKey(principal) === void 0) {
|
|
460
|
+
out2(` \u26A0 no signing key on file for ${principal} yet \u2014 import it: githolon key import --principal ${principal} --secret <key>`);
|
|
461
|
+
}
|
|
462
|
+
return 0;
|
|
463
|
+
}
|
|
419
464
|
function getDeviceKey(principal) {
|
|
420
465
|
return loadCreds().devices?.[principal];
|
|
421
466
|
}
|
|
@@ -506,13 +551,21 @@ async function whoami() {
|
|
|
506
551
|
const c = loadCreds();
|
|
507
552
|
if (c.session !== void 0) {
|
|
508
553
|
out2(`session: ${c.session.anonymous ? "anonymous agent" : "account"} uid ${c.session.uid} (auth ${c.session.url})`);
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
if (c.principal !== void 0) {
|
|
554
|
+
} else if (c.principal !== void 0) {
|
|
512
555
|
out2(`bare principal (transitional, unverified): ${c.principal}`);
|
|
513
|
-
|
|
556
|
+
} else {
|
|
557
|
+
out2("not logged in \u2014 githolon login --agent, or pass --principal <uid> per birth");
|
|
558
|
+
}
|
|
559
|
+
const active = activePrincipal();
|
|
560
|
+
if (c.actAs !== void 0) {
|
|
561
|
+
out2(`acting as: ${c.actAs}${getDeviceKey(c.actAs) ? " (key on file \u2713)" : " \u26A0 no signing key"} [githolon use <uid> to switch]`);
|
|
562
|
+
} else if (active !== void 0) {
|
|
563
|
+
out2(`signed lanes act as: ${active} (the session/bare default \u2014 githolon use <uid> to switch)`);
|
|
564
|
+
}
|
|
565
|
+
const keyed = Object.keys(c.devices ?? {});
|
|
566
|
+
if (keyed.length > 0) {
|
|
567
|
+
out2(`signing keys on file: ${keyed.map((p) => p === active ? `${p} \u2190active` : p).join(", ")}`);
|
|
514
568
|
}
|
|
515
|
-
out2("not logged in \u2014 githolon login --agent, or pass --principal <uid> per birth");
|
|
516
569
|
return 0;
|
|
517
570
|
}
|
|
518
571
|
async function logout() {
|
|
@@ -653,7 +706,7 @@ async function deploy(ws, opts) {
|
|
|
653
706
|
}
|
|
654
707
|
const fileName = file.split("/").pop();
|
|
655
708
|
const before = await fetch(`${cloud}/v2/workspaces/${ws}/domains`).then((br) => br.json()).then((bd) => bd.ok === true ? bd.domains ?? [] : []).catch(() => []);
|
|
656
|
-
const principal = opts.principal ??
|
|
709
|
+
const principal = opts.principal ?? activePrincipal();
|
|
657
710
|
const signed = opts.principal !== void 0 || principal !== void 0 && getDeviceKey(principal) !== void 0;
|
|
658
711
|
let phaseSuffix = "";
|
|
659
712
|
let deployedHash;
|
|
@@ -1493,7 +1546,43 @@ function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
1493
1546
|
if (cb.lawHashField !== void 0) payload[cb.lawHashField] = lawHash;
|
|
1494
1547
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1495
1548
|
for (const f of cb.birthAutoStamped) payload[f] = stamp;
|
|
1496
|
-
const
|
|
1549
|
+
const actor = actorFromPayload(payload, cb.birthActorField);
|
|
1550
|
+
if (cb.birthRequiresRelation !== void 0 && actor === void 0) {
|
|
1551
|
+
return done(false, `child birth ${cb.parentDomain}/${cb.birthDirectiveId} is gated by .requires("${cb.birthRequiresRelation}") but the proof could not discover an actor field from the birth recipe \u2014 route the genesis step actor from a payload subject field`);
|
|
1552
|
+
}
|
|
1553
|
+
let parentWs = ws;
|
|
1554
|
+
if (cb.parentSetup !== void 0) {
|
|
1555
|
+
const setup = cb.parentSetup;
|
|
1556
|
+
const setupPayload = { ...setup.birthPayload };
|
|
1557
|
+
if (setup.frameworkHashField !== void 0) setupPayload[setup.frameworkHashField] = fw;
|
|
1558
|
+
if (setup.lawHashField !== void 0) setupPayload[setup.lawHashField] = lawHash;
|
|
1559
|
+
for (const f of setup.birthAutoStamped) setupPayload[f] = stamp;
|
|
1560
|
+
if (setup.birthActorField !== void 0 && cb.birthActorField !== void 0 && payload[cb.birthActorField] !== void 0) {
|
|
1561
|
+
setupPayload[setup.birthActorField] = payload[cb.birthActorField];
|
|
1562
|
+
}
|
|
1563
|
+
const setupActor = actorFromPayload(setupPayload, setup.birthActorField) ?? actor;
|
|
1564
|
+
const setupOpts = setupActor !== void 0 ? { actor: setupActor } : {};
|
|
1565
|
+
const setupRes = author(
|
|
1566
|
+
eng,
|
|
1567
|
+
ws,
|
|
1568
|
+
setup.parentDomain,
|
|
1569
|
+
setup.birthDirectiveId,
|
|
1570
|
+
setupPayload,
|
|
1571
|
+
lawHash,
|
|
1572
|
+
setupOpts
|
|
1573
|
+
);
|
|
1574
|
+
if (setupRes.ok === false) {
|
|
1575
|
+
return done(false, `parent setup ${setup.parentDomain}/${setup.birthDirectiveId} refused: ${setupRes.error ?? "unknown"} \u2014 the proof could not birth the parent workspace needed before gated child birth`);
|
|
1576
|
+
}
|
|
1577
|
+
const bornParent = (setupRes.born ?? []).map((b) => b?.workspace).find((w) => typeof w === "string" && w.length > 0);
|
|
1578
|
+
if (bornParent === void 0) {
|
|
1579
|
+
return done(false, `parent setup ${setup.parentDomain}/${setup.birthDirectiveId} admitted but spawned no parent workspace (born=${JSON.stringify(setupRes.born ?? [])})`);
|
|
1580
|
+
}
|
|
1581
|
+
parentWs = bornParent;
|
|
1582
|
+
lines.push(`\u2713 parent setup ${setup.parentDomain}/${setup.birthDirectiveId} \u2014 ${parentWs} born before gated child birth`);
|
|
1583
|
+
}
|
|
1584
|
+
const opts = actor !== void 0 ? { actor } : {};
|
|
1585
|
+
const res = author(eng, parentWs, cb.parentDomain, cb.birthDirectiveId, payload, lawHash, opts);
|
|
1497
1586
|
if (res.ok === false) {
|
|
1498
1587
|
return done(false, `child birth ${cb.parentDomain}/${cb.birthDirectiveId} refused: ${res.error ?? "unknown"} \u2014 the parent's own gate rejected the birth offer (check the .births() plan + payload)`);
|
|
1499
1588
|
}
|
|
@@ -1547,6 +1636,11 @@ function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
1547
1636
|
lines.push(`\u2713 verify_chain GREEN on the born child ${childWs} (${verdict.plansRerun ?? "?"} plans re-run \u2014 it self-validates from intent 0 through its OWN gate)`);
|
|
1548
1637
|
return done(true);
|
|
1549
1638
|
}
|
|
1639
|
+
function actorFromPayload(payload, field) {
|
|
1640
|
+
if (field === void 0) return void 0;
|
|
1641
|
+
const value = payload[field];
|
|
1642
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1643
|
+
}
|
|
1550
1644
|
async function runOfflineProofStandalone(proofPath, cloud, domain) {
|
|
1551
1645
|
const src = readFileSync4(proofPath, "utf8");
|
|
1552
1646
|
const packageName = basename(proofPath).replace(/\.proof\.mts$/, "");
|
|
@@ -1789,7 +1883,6 @@ Re-run with --force to replace it.`
|
|
|
1789
1883
|
|
|
1790
1884
|
// src/cli.ts
|
|
1791
1885
|
init_cloud();
|
|
1792
|
-
init_governance();
|
|
1793
1886
|
|
|
1794
1887
|
// src/compile.ts
|
|
1795
1888
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -2374,7 +2467,16 @@ var HELP = {
|
|
|
2374
2467
|
},
|
|
2375
2468
|
whoami: {
|
|
2376
2469
|
usage: "githolon whoami",
|
|
2377
|
-
what: "Show the principal births will ride (session uid, or the transitional bare uid)."
|
|
2470
|
+
what: "Show the principal births will ride (session uid, or the transitional bare uid), the ACTIVE\nsigning principal (githolon use), and the signing keys on file."
|
|
2471
|
+
},
|
|
2472
|
+
use: {
|
|
2473
|
+
usage: "githolon use [<uid>] [--clear]",
|
|
2474
|
+
what: "Set, show, or clear the ACTIVE signing principal \u2014 the one the signed lanes (deploy, gov, grant,\nkey) author as by DEFAULT, without an explicit --as. Pair with `githolon key import` to hold an\nenrolled key per principal (a platform admin key, your own uid, \u2026) and switch which one acts with\none command. `--as`/`--principal` still overrides per-command. No argument shows the active\nprincipal + keys on file; `--clear` falls back to the session/bare default. Stored in ~/.holon.",
|
|
2475
|
+
flags: [
|
|
2476
|
+
["<uid>", "the auth-uid to act as (must have a signing key \u2014 githolon key import)"],
|
|
2477
|
+
["--clear", "clear the active principal (signed lanes use the session/bare default)"]
|
|
2478
|
+
],
|
|
2479
|
+
examples: ["githolon use d205ca94-...", "githolon use", "githolon use --clear"]
|
|
2378
2480
|
},
|
|
2379
2481
|
logout: {
|
|
2380
2482
|
usage: "githolon logout",
|
|
@@ -2450,14 +2552,15 @@ var HELP = {
|
|
|
2450
2552
|
examples: ["githolon revoke creation 32c7100e-\u2026", "githolon revoke admin 32c7100e-\u2026"]
|
|
2451
2553
|
},
|
|
2452
2554
|
deploy: {
|
|
2453
|
-
usage: "githolon deploy [<ws>] [--file <deploy.json>] [--cloud <url>] [--target <name>]",
|
|
2454
|
-
what: "
|
|
2555
|
+
usage: "githolon deploy [<ws>] [--as <uid>] [--file <deploy.json>] [--cloud <url>] [--target <name>]",
|
|
2556
|
+
what: "Deploy build/*.deploy.json \u2014 kernel-gated, no host secret. TWO lanes, picked automatically:\n\u2022 SIGNED (a WARRANTED ws, or when --as / the active `githolon use` principal has a signing key on\n file): signs a `nomos/installDomain` offer with that key and relays it; the kernel re-verifies the\n signature + judges the installDomain relation. Required for warranted platforms (co2, tbx) \u2014 an\n unsigned install is refused there.\n\u2022 OPEN (unwarranted ws / no key): the open POST /domains, still kernel-judged.\nAfter the POST it re-reads the workspace and CONFIRMS the deployed hash is the CURRENT serving law\n(exit 2 if committed-but-not-current). Prints what MOVED (old \u2192 new law hash). With no <ws>, the\nproject's `workspace` binding in nomos.package.mjs resolves it.",
|
|
2455
2557
|
flags: [
|
|
2558
|
+
["--as <uid>", "deploy as this principal via the SIGNED lane (needs its key \u2014 githolon key import; else githolon use)"],
|
|
2456
2559
|
["--file <path>", "an explicit deploy body (default: the one build/*.deploy.json)"],
|
|
2457
2560
|
["--target <name>", "pick among named targets (workspace: { dev: \u2026, prod: \u2026 })"],
|
|
2458
2561
|
["--cloud <url>", "target cloud"]
|
|
2459
2562
|
],
|
|
2460
|
-
examples: ["githolon deploy", "githolon deploy my-guestbook", "githolon deploy --
|
|
2563
|
+
examples: ["githolon deploy", "githolon deploy my-guestbook", "githolon use <admin-uid> && githolon deploy co2-platform", "githolon deploy tbx --as <admin-uid>"]
|
|
2461
2564
|
},
|
|
2462
2565
|
secret: {
|
|
2463
2566
|
usage: "githolon secret <set <ws> <push-password> | rotate <ws>> [--cloud <url>]",
|
|
@@ -2944,7 +3047,9 @@ Authoring:
|
|
|
2944
3047
|
Identity (~/.holon/credentials.json \u2014 sessions auto-refresh):
|
|
2945
3048
|
githolon login --agent anonymous sign-in: a verified self-onboarded identity
|
|
2946
3049
|
githolon login --token <refresh_token> adopt an existing captain app session
|
|
2947
|
-
githolon whoami show the principal births will ride
|
|
3050
|
+
githolon whoami show the principal births will ride + keys on file
|
|
3051
|
+
githolon use [<uid>] [--clear] set/show/clear the ACTIVE signing principal: the one
|
|
3052
|
+
deploy/gov/grant/key author as (--as overrides per-cmd)
|
|
2948
3053
|
githolon logout clear the session (workspace secrets kept)
|
|
2949
3054
|
githolon key enroll [--principal <uid>] [--parent <ws>] mint a signing device key + enroll it on-chain
|
|
2950
3055
|
(secret stays local; warrants SIGNED governance)
|
|
@@ -3000,12 +3105,13 @@ function cloudArgs(rest) {
|
|
|
3000
3105
|
const pos = [];
|
|
3001
3106
|
const opts = {};
|
|
3002
3107
|
const VALUE_FLAGS = ["--cloud", "--principal", "--as", "--file", "--target", "--parent", "--via", "--max", "--label", "--secret", "--payload", "--payload-file", "--save", "--format"];
|
|
3003
|
-
const BOOL_FLAGS = ["--sha256", "--stamp", "--yes"];
|
|
3108
|
+
const BOOL_FLAGS = ["--sha256", "--stamp", "--yes", "--clear"];
|
|
3004
3109
|
for (let i = 0; i < rest.length; i++) {
|
|
3005
3110
|
const a = rest[i];
|
|
3006
3111
|
if (BOOL_FLAGS.includes(a)) {
|
|
3007
3112
|
if (a === "--sha256") opts.sha256 = true;
|
|
3008
3113
|
else if (a === "--stamp") opts.stamp = true;
|
|
3114
|
+
else if (a === "--clear") opts.clear = true;
|
|
3009
3115
|
else opts.yes = true;
|
|
3010
3116
|
} else if (VALUE_FLAGS.includes(a)) {
|
|
3011
3117
|
const v = rest[++i];
|
|
@@ -3332,6 +3438,7 @@ ${commandHelp("status")}`);
|
|
|
3332
3438
|
return runCloud(argv);
|
|
3333
3439
|
}
|
|
3334
3440
|
if (argv[0] === "key") {
|
|
3441
|
+
const { keyEnroll: keyEnroll2, keyExport: keyExport2, keyImport: keyImport2, keyShow: keyShow2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3335
3442
|
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
3336
3443
|
if (bad !== void 0) {
|
|
3337
3444
|
process.stderr.write(`error: ${bad}
|
|
@@ -3340,16 +3447,17 @@ ${USAGE}`);
|
|
|
3340
3447
|
return 1;
|
|
3341
3448
|
}
|
|
3342
3449
|
const [sub] = pos;
|
|
3343
|
-
if (sub === "enroll") return
|
|
3344
|
-
if (sub === "show") return
|
|
3345
|
-
if (sub === "import") return
|
|
3346
|
-
if (sub === "export") return
|
|
3450
|
+
if (sub === "enroll") return keyEnroll2(opts);
|
|
3451
|
+
if (sub === "show") return keyShow2(opts);
|
|
3452
|
+
if (sub === "import") return keyImport2(opts);
|
|
3453
|
+
if (sub === "export") return keyExport2(opts);
|
|
3347
3454
|
process.stderr.write(`error: expected: githolon key <enroll|show|import|export> [--principal <uid>]
|
|
3348
3455
|
|
|
3349
3456
|
${USAGE}`);
|
|
3350
3457
|
return 1;
|
|
3351
3458
|
}
|
|
3352
3459
|
if (argv[0] === "gov") {
|
|
3460
|
+
const { governanceOffer: governanceOffer2, governanceRelay: governanceRelay2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3353
3461
|
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
3354
3462
|
if (bad !== void 0) {
|
|
3355
3463
|
process.stderr.write(`error: ${bad}
|
|
@@ -3365,7 +3473,7 @@ ${commandHelp("gov") ?? USAGE}`);
|
|
|
3365
3473
|
${commandHelp("gov") ?? USAGE}`);
|
|
3366
3474
|
return 1;
|
|
3367
3475
|
}
|
|
3368
|
-
return
|
|
3476
|
+
return governanceRelay2(ws2, file, opts);
|
|
3369
3477
|
}
|
|
3370
3478
|
const [ws, directiveId] = pos;
|
|
3371
3479
|
if (ws === void 0 || directiveId === void 0) {
|
|
@@ -3374,9 +3482,10 @@ ${commandHelp("gov") ?? USAGE}`);
|
|
|
3374
3482
|
${commandHelp("gov") ?? USAGE}`);
|
|
3375
3483
|
return 1;
|
|
3376
3484
|
}
|
|
3377
|
-
return
|
|
3485
|
+
return governanceOffer2(ws, directiveId, opts);
|
|
3378
3486
|
}
|
|
3379
3487
|
if (argv[0] === "grant" || argv[0] === "revoke") {
|
|
3488
|
+
const { grantOrRevoke: grantOrRevoke2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3380
3489
|
const verb = argv[0];
|
|
3381
3490
|
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
3382
3491
|
if (bad !== void 0) {
|
|
@@ -3392,7 +3501,7 @@ ${USAGE}`);
|
|
|
3392
3501
|
${USAGE}`);
|
|
3393
3502
|
return 1;
|
|
3394
3503
|
}
|
|
3395
|
-
return
|
|
3504
|
+
return grantOrRevoke2(verb, kind, subject, opts);
|
|
3396
3505
|
}
|
|
3397
3506
|
if (argv[0] === "login") {
|
|
3398
3507
|
const agent = argv.includes("--agent");
|
|
@@ -3406,6 +3515,16 @@ ${USAGE}`);
|
|
|
3406
3515
|
}
|
|
3407
3516
|
if (argv[0] === "whoami") return whoami();
|
|
3408
3517
|
if (argv[0] === "logout") return logout();
|
|
3518
|
+
if (argv[0] === "use") {
|
|
3519
|
+
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
3520
|
+
if (bad !== void 0) {
|
|
3521
|
+
process.stderr.write(`error: ${bad}
|
|
3522
|
+
|
|
3523
|
+
${USAGE}`);
|
|
3524
|
+
return 1;
|
|
3525
|
+
}
|
|
3526
|
+
return authUse(pos[0], { clear: opts.clear === true });
|
|
3527
|
+
}
|
|
3409
3528
|
if (argv[0] === "ledger") {
|
|
3410
3529
|
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
3411
3530
|
if (bad !== void 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.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",
|
|
@@ -21,14 +21,16 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "node build.mjs",
|
|
23
23
|
"prepare": "npm run build",
|
|
24
|
+
"pretest": "npm run build",
|
|
24
25
|
"holon": "tsx src/cli.ts",
|
|
25
26
|
"test": "vitest run",
|
|
27
|
+
"pretypecheck": "npm run build",
|
|
26
28
|
"typecheck": "tsc --noEmit"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
31
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
30
|
-
"@githolon/client": "^0.
|
|
31
|
-
"@githolon/dsl": "^0.
|
|
32
|
+
"@githolon/client": "^0.25.0",
|
|
33
|
+
"@githolon/dsl": "^0.25.0",
|
|
32
34
|
"isomorphic-git": "^1.38.4"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|