@senticor/hive 1.87.2 → 1.88.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/hive.cjs +173 -23
- package/package.json +1 -1
package/hive.cjs
CHANGED
|
@@ -8630,6 +8630,21 @@ var ROLE_KEY_RE = /^[a-z0-9][a-z0-9._:-]{0,63}$/;
|
|
|
8630
8630
|
function hasTenantAudienceDelimiter(displayKey) {
|
|
8631
8631
|
return /[\s,]/.test(String(displayKey || "").trim());
|
|
8632
8632
|
}
|
|
8633
|
+
var MAX_TENANT_DISPLAY_NAME_LENGTH = 200;
|
|
8634
|
+
var CONTROL_CHARS = new RegExp("\\p{Cc}", "u");
|
|
8635
|
+
function parseOptionalTenantDisplayName(value, field = "displayName") {
|
|
8636
|
+
if (value === void 0) return void 0;
|
|
8637
|
+
if (value === null) return null;
|
|
8638
|
+
if (typeof value !== "string") throw new Error(`${field} must be a string or null`);
|
|
8639
|
+
const name = value.trim();
|
|
8640
|
+
if (!name) throw new Error(`${field} must be a non-empty string (send null to clear it)`);
|
|
8641
|
+
if (CONTROL_CHARS.test(name)) throw new Error(`${field} must not contain control characters (line breaks, tabs, NUL)`);
|
|
8642
|
+
const length = [...name].length;
|
|
8643
|
+
if (length > MAX_TENANT_DISPLAY_NAME_LENGTH) {
|
|
8644
|
+
throw new Error(`${field} is too long (${length} characters); at most ${MAX_TENANT_DISPLAY_NAME_LENGTH}`);
|
|
8645
|
+
}
|
|
8646
|
+
return name;
|
|
8647
|
+
}
|
|
8633
8648
|
|
|
8634
8649
|
// src/lib/client.ts
|
|
8635
8650
|
init_cjs_shims();
|
|
@@ -8686,6 +8701,14 @@ function promptText(query) {
|
|
|
8686
8701
|
});
|
|
8687
8702
|
});
|
|
8688
8703
|
}
|
|
8704
|
+
var TOKEN_ENV_VARS = ["HIVE_TOKEN", "HIVE_TEST_TOKEN", "HIVE_BEARER_TOKEN"];
|
|
8705
|
+
function envToken(env = process.env) {
|
|
8706
|
+
for (const variable of TOKEN_ENV_VARS) {
|
|
8707
|
+
const token = env[variable];
|
|
8708
|
+
if (token) return { token, variable };
|
|
8709
|
+
}
|
|
8710
|
+
return null;
|
|
8711
|
+
}
|
|
8689
8712
|
function parseJwt(token) {
|
|
8690
8713
|
try {
|
|
8691
8714
|
const parts = token.split(".");
|
|
@@ -9375,7 +9398,7 @@ var HiveClient = class {
|
|
|
9375
9398
|
const headers = { accept };
|
|
9376
9399
|
if (this.tenant) headers["x-hive-tenant"] = this.tenant;
|
|
9377
9400
|
try {
|
|
9378
|
-
const token =
|
|
9401
|
+
const token = envToken()?.token || await getValidToken();
|
|
9379
9402
|
if (token) headers["authorization"] = `Bearer ${token}`;
|
|
9380
9403
|
} catch (e) {
|
|
9381
9404
|
if (this.verbose) console.error("Warning: Could not fetch auth token", e.message);
|
|
@@ -9654,6 +9677,7 @@ var CliCommandError = class extends Error {
|
|
|
9654
9677
|
remediation;
|
|
9655
9678
|
tenant;
|
|
9656
9679
|
problemType;
|
|
9680
|
+
details;
|
|
9657
9681
|
constructor(symbolicCode, exitCode, message, options) {
|
|
9658
9682
|
super(message, options);
|
|
9659
9683
|
this.name = "CliCommandError";
|
|
@@ -9662,6 +9686,7 @@ var CliCommandError = class extends Error {
|
|
|
9662
9686
|
this.remediation = options?.remediation;
|
|
9663
9687
|
this.tenant = options?.tenant;
|
|
9664
9688
|
this.problemType = options?.problemType;
|
|
9689
|
+
this.details = options?.details;
|
|
9665
9690
|
}
|
|
9666
9691
|
};
|
|
9667
9692
|
function commandError(symbolicCode, exitCode, message, options) {
|
|
@@ -9693,6 +9718,16 @@ function remoteProblemType(data) {
|
|
|
9693
9718
|
const body = data;
|
|
9694
9719
|
return typeof body.type === "string" && typeof body.title === "string" && typeof body.status === "number" ? body.type : void 0;
|
|
9695
9720
|
}
|
|
9721
|
+
function remoteProblemDetails(data) {
|
|
9722
|
+
if (!remoteProblemType(data)) return void 0;
|
|
9723
|
+
const raw = data.details;
|
|
9724
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
9725
|
+
const out = {};
|
|
9726
|
+
for (const [name, value] of Object.entries(raw)) {
|
|
9727
|
+
if (value === null || ["string", "number", "boolean"].includes(typeof value)) out[name] = value;
|
|
9728
|
+
}
|
|
9729
|
+
return Object.keys(out).length ? out : void 0;
|
|
9730
|
+
}
|
|
9696
9731
|
function fieldText(value) {
|
|
9697
9732
|
if (value === null || value === void 0) return "";
|
|
9698
9733
|
if (typeof value === "object") {
|
|
@@ -9737,11 +9772,17 @@ function remoteFailureError(status2, data, action, exitCode = exitCodeForStatus(
|
|
|
9737
9772
|
const remediation = remoteFailureRemediation(data);
|
|
9738
9773
|
const tenant = remoteFailureTenant(data);
|
|
9739
9774
|
const problemType = remoteProblemType(data);
|
|
9775
|
+
const details = remoteProblemDetails(data);
|
|
9740
9776
|
return commandError(
|
|
9741
9777
|
"REMOTE_FAILED",
|
|
9742
9778
|
exitCode,
|
|
9743
9779
|
`${action} failed${status2 ? ` (HTTP ${status2})` : ""}: ${remoteFailureText(data)}${remediation ? ` \u2014 ${remediation}` : ""}`,
|
|
9744
|
-
remediation || tenant || problemType
|
|
9780
|
+
remediation || tenant || problemType || details ? {
|
|
9781
|
+
...remediation ? { remediation } : {},
|
|
9782
|
+
...tenant ? { tenant } : {},
|
|
9783
|
+
...problemType ? { problemType } : {},
|
|
9784
|
+
...details ? { details } : {}
|
|
9785
|
+
} : void 0
|
|
9745
9786
|
);
|
|
9746
9787
|
}
|
|
9747
9788
|
function remoteFailureText(data) {
|
|
@@ -9751,7 +9792,10 @@ function remoteFailureText(data) {
|
|
|
9751
9792
|
const parts = [code, message, ...isProblem ? [] : [fieldText(body?.detail)]].filter(Boolean);
|
|
9752
9793
|
const fields = isProblem ? [] : schemaErrorFields(data);
|
|
9753
9794
|
if (fields.length) parts.push(`(offending field${fields.length > 1 ? "s" : ""}: ${fields.join(", ")})`);
|
|
9754
|
-
|
|
9795
|
+
const text = [...new Set(parts)].join(": ") || "unexpected response";
|
|
9796
|
+
const details = remoteProblemDetails(data);
|
|
9797
|
+
if (!details) return text;
|
|
9798
|
+
return `${text} (${Object.entries(details).map(([name, value]) => `${name}: ${JSON.stringify(value)}`).join(", ")})`;
|
|
9755
9799
|
}
|
|
9756
9800
|
function toStructuredError(err) {
|
|
9757
9801
|
const e = err;
|
|
@@ -9764,7 +9808,8 @@ function toStructuredError(err) {
|
|
|
9764
9808
|
message,
|
|
9765
9809
|
...e?.remediation ? { remediation: e.remediation } : {},
|
|
9766
9810
|
...e?.problemType ? { type: e.problemType } : {},
|
|
9767
|
-
...e?.tenant ? { tenant: e.tenant } : {}
|
|
9811
|
+
...e?.tenant ? { tenant: e.tenant } : {},
|
|
9812
|
+
...e?.details ? { details: e.details } : {}
|
|
9768
9813
|
}
|
|
9769
9814
|
};
|
|
9770
9815
|
}
|
|
@@ -9815,11 +9860,19 @@ function installRemoteFailureExit() {
|
|
|
9815
9860
|
const remediation = remoteFailureRemediation(failure2.body) ?? (failure2.status === 401 ? "Run 'hive login' to authenticate, or set HIVE_TOKEN." : void 0);
|
|
9816
9861
|
const tenant = remoteFailureTenant(failure2.body);
|
|
9817
9862
|
const problemType = remoteProblemType(failure2.body);
|
|
9863
|
+
const details = remoteProblemDetails(failure2.body);
|
|
9818
9864
|
const message = `${failure2.method} ${failure2.path} failed${failure2.status ? ` (HTTP ${failure2.status})` : ""}: ${remoteFailureText(failure2.body)}`;
|
|
9819
9865
|
if (isJsonMode()) {
|
|
9820
9866
|
console.error(JSON.stringify({
|
|
9821
9867
|
ok: false,
|
|
9822
|
-
error: {
|
|
9868
|
+
error: {
|
|
9869
|
+
code: symbolic,
|
|
9870
|
+
message,
|
|
9871
|
+
...problemType ? { type: problemType } : {},
|
|
9872
|
+
...remediation ? { remediation } : {},
|
|
9873
|
+
...tenant ? { tenant } : {},
|
|
9874
|
+
...details ? { details } : {}
|
|
9875
|
+
}
|
|
9823
9876
|
}));
|
|
9824
9877
|
} else {
|
|
9825
9878
|
console.error(`\x1B[31mError:\x1B[0m ${symbolic}: ${message}`);
|
|
@@ -10376,22 +10429,22 @@ var artifactName = injectedString(
|
|
|
10376
10429
|
true ? "hive-cli" : void 0
|
|
10377
10430
|
) || String(process.env.HIVE_CLI_ARTIFACT_NAME || "hive-cli").trim() || "hive-cli";
|
|
10378
10431
|
var packageVersion = injectedString(
|
|
10379
|
-
true ? "1.
|
|
10432
|
+
true ? "1.88.1" : void 0
|
|
10380
10433
|
) || String(process.env.HIVE_CLI_PACKAGE_VERSION || "").trim() || readPackageVersion();
|
|
10381
10434
|
var releaseVersion = injectedString(
|
|
10382
|
-
true ? "1.
|
|
10435
|
+
true ? "1.88.1" : void 0
|
|
10383
10436
|
) || String(process.env.HIVE_CLI_RELEASE_VERSION || "").trim() || packageVersion || "dev";
|
|
10384
10437
|
var releaseChannel = injectedString(
|
|
10385
10438
|
true ? "final" : void 0
|
|
10386
10439
|
) || String(process.env.HIVE_CLI_RELEASE_CHANNEL || "").trim() || (releaseVersion.includes("-rc.") ? "rc" : releaseVersion === "dev" ? "dev" : "final");
|
|
10387
10440
|
var buildCommit = injectedString(
|
|
10388
|
-
true ? "
|
|
10441
|
+
true ? "0389229ca319d58530b1a250cc0eaed6c50ab3e2" : void 0
|
|
10389
10442
|
) || String(process.env.HIVE_CLI_BUILD_COMMIT || "").trim() || "unknown";
|
|
10390
10443
|
var buildTimestamp = injectedString(
|
|
10391
|
-
true ? "2026-10-
|
|
10444
|
+
true ? "2026-10-30T08:47:32Z" : void 0
|
|
10392
10445
|
) || String(process.env.HIVE_CLI_BUILD_TIMESTAMP || "").trim() || "unknown";
|
|
10393
10446
|
var ociRef = injectedString(
|
|
10394
|
-
true ? "registry.onstackit.cloud/senticor/hive-cli:1.
|
|
10447
|
+
true ? "registry.onstackit.cloud/senticor/hive-cli:1.88.1" : void 0
|
|
10395
10448
|
) || String(process.env.HIVE_CLI_OCI_REF || "").trim() || `registry.onstackit.cloud/senticor/${artifactName}:${releaseVersion}`;
|
|
10396
10449
|
var RELEASE_INFO = Object.freeze({
|
|
10397
10450
|
packageVersion,
|
|
@@ -11386,21 +11439,64 @@ var logout = defineCommand({
|
|
|
11386
11439
|
console.log("Signed out. Local tokens deleted.");
|
|
11387
11440
|
}
|
|
11388
11441
|
});
|
|
11442
|
+
var claimText = (v) => typeof v === "string" && v ? v : null;
|
|
11443
|
+
function currentSession() {
|
|
11444
|
+
const env = envToken();
|
|
11445
|
+
if (env) {
|
|
11446
|
+
const claims2 = parseJwt(env.token);
|
|
11447
|
+
const exp = typeof claims2?.exp === "number" ? claims2.exp * 1e3 : null;
|
|
11448
|
+
return {
|
|
11449
|
+
loggedIn: true,
|
|
11450
|
+
source: "env",
|
|
11451
|
+
variable: env.variable,
|
|
11452
|
+
verified: false,
|
|
11453
|
+
subject: claimText(claims2?.sub),
|
|
11454
|
+
user: claimText(claims2?.preferred_username) ?? claimText(claims2?.email),
|
|
11455
|
+
issuer: claimText(claims2?.iss),
|
|
11456
|
+
expiresAt: exp === null ? null : new Date(exp).toISOString(),
|
|
11457
|
+
expired: exp === null ? null : exp <= Date.now()
|
|
11458
|
+
};
|
|
11459
|
+
}
|
|
11460
|
+
const creds = getStoredCredentials();
|
|
11461
|
+
if (!creds || !creds.access_token) return null;
|
|
11462
|
+
const expiresAt = Number.isFinite(creds.expires_at) ? creds.expires_at : null;
|
|
11463
|
+
return {
|
|
11464
|
+
loggedIn: true,
|
|
11465
|
+
source: "stored",
|
|
11466
|
+
variable: null,
|
|
11467
|
+
verified: false,
|
|
11468
|
+
subject: claimText(parseJwt(creds.access_token)?.sub),
|
|
11469
|
+
user: creds.user ?? null,
|
|
11470
|
+
issuer: creds.issuer ?? null,
|
|
11471
|
+
expiresAt: expiresAt === null ? null : new Date(expiresAt).toISOString(),
|
|
11472
|
+
expired: expiresAt === null ? null : expiresAt <= Date.now()
|
|
11473
|
+
};
|
|
11474
|
+
}
|
|
11389
11475
|
var whoami = defineCommand({
|
|
11390
|
-
meta: { name: "whoami", description: "Show
|
|
11476
|
+
meta: { name: "whoami", description: "Show the session the next command uses (HIVE_TOKEN or the stored login)" },
|
|
11391
11477
|
args: { ...globalArgs },
|
|
11392
|
-
run() {
|
|
11393
|
-
const
|
|
11394
|
-
|
|
11395
|
-
|
|
11478
|
+
run({ args }) {
|
|
11479
|
+
const asJson = args.json === true || String(args.format ?? "").toLowerCase() === "json";
|
|
11480
|
+
const session = currentSession();
|
|
11481
|
+
if (!session) {
|
|
11482
|
+
if (asJson) console.log(JSON.stringify({ loggedIn: false }, null, 2));
|
|
11483
|
+
else console.log("\x1B[33mNot logged in. Run 'hive login' to authenticate, or set HIVE_TOKEN.\x1B[0m");
|
|
11396
11484
|
process.exit(1);
|
|
11397
11485
|
}
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11486
|
+
if (asJson) {
|
|
11487
|
+
console.log(JSON.stringify(session, null, 2));
|
|
11488
|
+
} else {
|
|
11489
|
+
const unknown2 = "(not in token)";
|
|
11490
|
+
const left = session.expiresAt === null ? null : Math.floor((Date.parse(session.expiresAt) - Date.now()) / 1e3);
|
|
11491
|
+
console.log(`User: \x1B[36m${session.user ?? unknown2}\x1B[0m`);
|
|
11492
|
+
if (session.subject) console.log(`Subject: ${session.subject}`);
|
|
11493
|
+
console.log(`Issuer: ${session.issuer ?? unknown2}`);
|
|
11494
|
+
console.log(
|
|
11495
|
+
`Status: ${left === null ? "Expiry unknown" : left > 0 ? `\x1B[32mActive\x1B[0m (expires in ${Math.floor(left / 60)} min)` : "\x1B[31mExpired\x1B[0m"}`
|
|
11496
|
+
);
|
|
11497
|
+
console.log(session.source === "env" ? `Source: env (${session.variable}); claims read from the token, not verified` : "Source: stored login (hive login)");
|
|
11498
|
+
}
|
|
11499
|
+
if (session.source === "env" && session.expired === true) process.exit(1);
|
|
11404
11500
|
}
|
|
11405
11501
|
});
|
|
11406
11502
|
|
|
@@ -32465,8 +32561,27 @@ var orgArgs = withArgs({
|
|
|
32465
32561
|
role: { type: "string", description: "Role key (repeat as comma-separated values where supported)" },
|
|
32466
32562
|
roles: { type: "string", description: "Comma-separated role keys" },
|
|
32467
32563
|
reuse: { type: "boolean", description: "On already-exists, reuse the existing tenant" },
|
|
32468
|
-
pin: { type: "boolean", description: "Pin created/reused tenant display key in ~/.hive/config.json" }
|
|
32564
|
+
pin: { type: "boolean", description: "Pin created/reused tenant display key in ~/.hive/config.json" },
|
|
32565
|
+
orgName: { type: "string", description: "The organisation's display name for choosers (a label; --display-key stays the selector)" },
|
|
32566
|
+
clearOrgName: { type: "boolean", description: "rename: clear the organisation's display name, so clients show the key" },
|
|
32567
|
+
expectOrgName: { type: "string", description: "rename: change only if the stored name is this one ('' = no name yet)" }
|
|
32469
32568
|
});
|
|
32569
|
+
function orgNameArg(args) {
|
|
32570
|
+
if (args.orgName === void 0) return void 0;
|
|
32571
|
+
try {
|
|
32572
|
+
return parseOptionalTenantDisplayName(String(args.orgName), "--org-name") ?? void 0;
|
|
32573
|
+
} catch (err) {
|
|
32574
|
+
throw commandError("INVALID_ORG_NAME", 1, err.message);
|
|
32575
|
+
}
|
|
32576
|
+
}
|
|
32577
|
+
function orgNameApplied(tenant, requested, reused) {
|
|
32578
|
+
if (!reused || tenant.displayName === requested) return true;
|
|
32579
|
+
const key = String(tenant.displayKey || "");
|
|
32580
|
+
console.error(
|
|
32581
|
+
`Note: tenant '${key}' already exists; its display name was not changed. Run: hive org rename --tenant-key ${key} --org-name ${JSON.stringify(requested)}`
|
|
32582
|
+
);
|
|
32583
|
+
return false;
|
|
32584
|
+
}
|
|
32470
32585
|
function ensureOk(status2, data, action) {
|
|
32471
32586
|
if (isHttpOk(status2)) return;
|
|
32472
32587
|
throw remoteFailureError(status2, data, action);
|
|
@@ -32733,10 +32848,12 @@ var org = defineCommand({
|
|
|
32733
32848
|
printContextNotice(args, { adminScope: true });
|
|
32734
32849
|
req(args, "displayKey");
|
|
32735
32850
|
assertCanonicalTenantSelector(String(args.displayKey), "--display-key");
|
|
32851
|
+
const orgName = orgNameArg(args);
|
|
32736
32852
|
const body = {
|
|
32737
32853
|
kind: args.kind || "organization",
|
|
32738
32854
|
displayKey: args.displayKey
|
|
32739
32855
|
};
|
|
32856
|
+
if (orgName !== void 0) body.displayName = orgName;
|
|
32740
32857
|
applyRuntimeConfig(args, body);
|
|
32741
32858
|
if (args.ownerPrincipalId) body.ownerPrincipalId = args.ownerPrincipalId;
|
|
32742
32859
|
const requestedKind = String(body.kind || "organization").trim();
|
|
@@ -32777,7 +32894,37 @@ var org = defineCommand({
|
|
|
32777
32894
|
const pinKey = canonicalPinKey(tenant);
|
|
32778
32895
|
const pinnable = Boolean(args.pin && pinKey);
|
|
32779
32896
|
if (pinnable && pinKey) saveConfig({ tenant: pinKey });
|
|
32780
|
-
|
|
32897
|
+
const named = orgName === void 0 ? {} : { orgNameApplied: orgNameApplied(tenant, orgName, reused) };
|
|
32898
|
+
return output({ ...recordOf2(res.data), reused, pinned: pinnable, ...named }, fmt);
|
|
32899
|
+
}
|
|
32900
|
+
}),
|
|
32901
|
+
rename: defineCommand({
|
|
32902
|
+
meta: {
|
|
32903
|
+
name: "rename",
|
|
32904
|
+
description: "Set or clear an organisation's display name (--org-name or --clear-org-name; [--expect-org-name])"
|
|
32905
|
+
},
|
|
32906
|
+
args: orgArgs,
|
|
32907
|
+
async run({ args }) {
|
|
32908
|
+
printContextNotice(args, { adminScope: true });
|
|
32909
|
+
const name = orgNameArg(args);
|
|
32910
|
+
if (args.clearOrgName && name !== void 0) {
|
|
32911
|
+
throw commandError("CONFLICTING_ARGS", EXIT_GUARDRAIL, "Pass --org-name or --clear-org-name, not both.");
|
|
32912
|
+
}
|
|
32913
|
+
if (!args.clearOrgName && name === void 0) {
|
|
32914
|
+
throw commandError("ORG_NAME_REQUIRED", 1, "Pass --org-name <name>, or --clear-org-name to remove the name.");
|
|
32915
|
+
}
|
|
32916
|
+
const body = { displayName: args.clearOrgName ? null : name };
|
|
32917
|
+
if (args.expectOrgName !== void 0) {
|
|
32918
|
+
const expected = String(args.expectOrgName).trim();
|
|
32919
|
+
body.expectedDisplayName = expected || null;
|
|
32920
|
+
}
|
|
32921
|
+
const { tenantId } = await resolveTenantId(args);
|
|
32922
|
+
const { client, fmt } = adminCtx(args);
|
|
32923
|
+
const res = await client.patch(`/api/admin/orgs/${enc(tenantId)}`, body);
|
|
32924
|
+
ensureAuthorized(res.status, "Renaming an organisation");
|
|
32925
|
+
ensureOk(res.status, res.data, "rename organisation");
|
|
32926
|
+
const data = recordOf2(res.data);
|
|
32927
|
+
return output({ ...data, idempotent: data.changed === false }, fmt);
|
|
32781
32928
|
}
|
|
32782
32929
|
}),
|
|
32783
32930
|
members: defineCommand({
|
|
@@ -32898,7 +33045,9 @@ var org = defineCommand({
|
|
|
32898
33045
|
}
|
|
32899
33046
|
const kind = String(args.kind || "organization").trim();
|
|
32900
33047
|
const { client, fmt } = adminCtx(args);
|
|
33048
|
+
const orgName = orgNameArg(args);
|
|
32901
33049
|
const createBody = { kind, displayKey: args.displayKey };
|
|
33050
|
+
if (orgName !== void 0) createBody.displayName = orgName;
|
|
32902
33051
|
applyRuntimeConfig(args, createBody);
|
|
32903
33052
|
if (args.ownerPrincipalId) createBody.ownerPrincipalId = args.ownerPrincipalId;
|
|
32904
33053
|
let reusedTenant = false;
|
|
@@ -32947,6 +33096,7 @@ var org = defineCommand({
|
|
|
32947
33096
|
if (!tenantId) {
|
|
32948
33097
|
throw commandError("TENANT_NOT_FOUND", 1, "Tenant was created/reused but no id was returned.");
|
|
32949
33098
|
}
|
|
33099
|
+
if (orgName !== void 0) orgNameApplied(tenant, orgName, reusedTenant);
|
|
32950
33100
|
const admitBody = { email: email3, roles };
|
|
32951
33101
|
if (args.displayName) admitBody.displayName = args.displayName;
|
|
32952
33102
|
const admitRes = await client.post(`/api/admin/orgs/${enc(tenantId)}/members`, admitBody);
|