@senticor/hive 1.87.2 → 1.88.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/hive.cjs +139 -19
- 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);
|
|
@@ -10376,22 +10399,22 @@ var artifactName = injectedString(
|
|
|
10376
10399
|
true ? "hive-cli" : void 0
|
|
10377
10400
|
) || String(process.env.HIVE_CLI_ARTIFACT_NAME || "hive-cli").trim() || "hive-cli";
|
|
10378
10401
|
var packageVersion = injectedString(
|
|
10379
|
-
true ? "1.
|
|
10402
|
+
true ? "1.88.0" : void 0
|
|
10380
10403
|
) || String(process.env.HIVE_CLI_PACKAGE_VERSION || "").trim() || readPackageVersion();
|
|
10381
10404
|
var releaseVersion = injectedString(
|
|
10382
|
-
true ? "1.
|
|
10405
|
+
true ? "1.88.0" : void 0
|
|
10383
10406
|
) || String(process.env.HIVE_CLI_RELEASE_VERSION || "").trim() || packageVersion || "dev";
|
|
10384
10407
|
var releaseChannel = injectedString(
|
|
10385
10408
|
true ? "final" : void 0
|
|
10386
10409
|
) || String(process.env.HIVE_CLI_RELEASE_CHANNEL || "").trim() || (releaseVersion.includes("-rc.") ? "rc" : releaseVersion === "dev" ? "dev" : "final");
|
|
10387
10410
|
var buildCommit = injectedString(
|
|
10388
|
-
true ? "
|
|
10411
|
+
true ? "a4b8f623f85bfc4248ab3a65fb34352f6b190584" : void 0
|
|
10389
10412
|
) || String(process.env.HIVE_CLI_BUILD_COMMIT || "").trim() || "unknown";
|
|
10390
10413
|
var buildTimestamp = injectedString(
|
|
10391
|
-
true ? "2026-10-
|
|
10414
|
+
true ? "2026-10-30T00:41:24Z" : void 0
|
|
10392
10415
|
) || String(process.env.HIVE_CLI_BUILD_TIMESTAMP || "").trim() || "unknown";
|
|
10393
10416
|
var ociRef = injectedString(
|
|
10394
|
-
true ? "registry.onstackit.cloud/senticor/hive-cli:1.
|
|
10417
|
+
true ? "registry.onstackit.cloud/senticor/hive-cli:1.88.0" : void 0
|
|
10395
10418
|
) || String(process.env.HIVE_CLI_OCI_REF || "").trim() || `registry.onstackit.cloud/senticor/${artifactName}:${releaseVersion}`;
|
|
10396
10419
|
var RELEASE_INFO = Object.freeze({
|
|
10397
10420
|
packageVersion,
|
|
@@ -11386,21 +11409,64 @@ var logout = defineCommand({
|
|
|
11386
11409
|
console.log("Signed out. Local tokens deleted.");
|
|
11387
11410
|
}
|
|
11388
11411
|
});
|
|
11412
|
+
var claimText = (v) => typeof v === "string" && v ? v : null;
|
|
11413
|
+
function currentSession() {
|
|
11414
|
+
const env = envToken();
|
|
11415
|
+
if (env) {
|
|
11416
|
+
const claims2 = parseJwt(env.token);
|
|
11417
|
+
const exp = typeof claims2?.exp === "number" ? claims2.exp * 1e3 : null;
|
|
11418
|
+
return {
|
|
11419
|
+
loggedIn: true,
|
|
11420
|
+
source: "env",
|
|
11421
|
+
variable: env.variable,
|
|
11422
|
+
verified: false,
|
|
11423
|
+
subject: claimText(claims2?.sub),
|
|
11424
|
+
user: claimText(claims2?.preferred_username) ?? claimText(claims2?.email),
|
|
11425
|
+
issuer: claimText(claims2?.iss),
|
|
11426
|
+
expiresAt: exp === null ? null : new Date(exp).toISOString(),
|
|
11427
|
+
expired: exp === null ? null : exp <= Date.now()
|
|
11428
|
+
};
|
|
11429
|
+
}
|
|
11430
|
+
const creds = getStoredCredentials();
|
|
11431
|
+
if (!creds || !creds.access_token) return null;
|
|
11432
|
+
const expiresAt = Number.isFinite(creds.expires_at) ? creds.expires_at : null;
|
|
11433
|
+
return {
|
|
11434
|
+
loggedIn: true,
|
|
11435
|
+
source: "stored",
|
|
11436
|
+
variable: null,
|
|
11437
|
+
verified: false,
|
|
11438
|
+
subject: claimText(parseJwt(creds.access_token)?.sub),
|
|
11439
|
+
user: creds.user ?? null,
|
|
11440
|
+
issuer: creds.issuer ?? null,
|
|
11441
|
+
expiresAt: expiresAt === null ? null : new Date(expiresAt).toISOString(),
|
|
11442
|
+
expired: expiresAt === null ? null : expiresAt <= Date.now()
|
|
11443
|
+
};
|
|
11444
|
+
}
|
|
11389
11445
|
var whoami = defineCommand({
|
|
11390
|
-
meta: { name: "whoami", description: "Show
|
|
11446
|
+
meta: { name: "whoami", description: "Show the session the next command uses (HIVE_TOKEN or the stored login)" },
|
|
11391
11447
|
args: { ...globalArgs },
|
|
11392
|
-
run() {
|
|
11393
|
-
const
|
|
11394
|
-
|
|
11395
|
-
|
|
11448
|
+
run({ args }) {
|
|
11449
|
+
const asJson = args.json === true || String(args.format ?? "").toLowerCase() === "json";
|
|
11450
|
+
const session = currentSession();
|
|
11451
|
+
if (!session) {
|
|
11452
|
+
if (asJson) console.log(JSON.stringify({ loggedIn: false }, null, 2));
|
|
11453
|
+
else console.log("\x1B[33mNot logged in. Run 'hive login' to authenticate, or set HIVE_TOKEN.\x1B[0m");
|
|
11396
11454
|
process.exit(1);
|
|
11397
11455
|
}
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11456
|
+
if (asJson) {
|
|
11457
|
+
console.log(JSON.stringify(session, null, 2));
|
|
11458
|
+
} else {
|
|
11459
|
+
const unknown2 = "(not in token)";
|
|
11460
|
+
const left = session.expiresAt === null ? null : Math.floor((Date.parse(session.expiresAt) - Date.now()) / 1e3);
|
|
11461
|
+
console.log(`User: \x1B[36m${session.user ?? unknown2}\x1B[0m`);
|
|
11462
|
+
if (session.subject) console.log(`Subject: ${session.subject}`);
|
|
11463
|
+
console.log(`Issuer: ${session.issuer ?? unknown2}`);
|
|
11464
|
+
console.log(
|
|
11465
|
+
`Status: ${left === null ? "Expiry unknown" : left > 0 ? `\x1B[32mActive\x1B[0m (expires in ${Math.floor(left / 60)} min)` : "\x1B[31mExpired\x1B[0m"}`
|
|
11466
|
+
);
|
|
11467
|
+
console.log(session.source === "env" ? `Source: env (${session.variable}); claims read from the token, not verified` : "Source: stored login (hive login)");
|
|
11468
|
+
}
|
|
11469
|
+
if (session.source === "env" && session.expired === true) process.exit(1);
|
|
11404
11470
|
}
|
|
11405
11471
|
});
|
|
11406
11472
|
|
|
@@ -32465,8 +32531,27 @@ var orgArgs = withArgs({
|
|
|
32465
32531
|
role: { type: "string", description: "Role key (repeat as comma-separated values where supported)" },
|
|
32466
32532
|
roles: { type: "string", description: "Comma-separated role keys" },
|
|
32467
32533
|
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" }
|
|
32534
|
+
pin: { type: "boolean", description: "Pin created/reused tenant display key in ~/.hive/config.json" },
|
|
32535
|
+
orgName: { type: "string", description: "The organisation's display name for choosers (a label; --display-key stays the selector)" },
|
|
32536
|
+
clearOrgName: { type: "boolean", description: "rename: clear the organisation's display name, so clients show the key" },
|
|
32537
|
+
expectOrgName: { type: "string", description: "rename: change only if the stored name is this one ('' = no name yet)" }
|
|
32469
32538
|
});
|
|
32539
|
+
function orgNameArg(args) {
|
|
32540
|
+
if (args.orgName === void 0) return void 0;
|
|
32541
|
+
try {
|
|
32542
|
+
return parseOptionalTenantDisplayName(String(args.orgName), "--org-name") ?? void 0;
|
|
32543
|
+
} catch (err) {
|
|
32544
|
+
throw commandError("INVALID_ORG_NAME", 1, err.message);
|
|
32545
|
+
}
|
|
32546
|
+
}
|
|
32547
|
+
function orgNameApplied(tenant, requested, reused) {
|
|
32548
|
+
if (!reused || tenant.displayName === requested) return true;
|
|
32549
|
+
const key = String(tenant.displayKey || "");
|
|
32550
|
+
console.error(
|
|
32551
|
+
`Note: tenant '${key}' already exists; its display name was not changed. Run: hive org rename --tenant-key ${key} --org-name ${JSON.stringify(requested)}`
|
|
32552
|
+
);
|
|
32553
|
+
return false;
|
|
32554
|
+
}
|
|
32470
32555
|
function ensureOk(status2, data, action) {
|
|
32471
32556
|
if (isHttpOk(status2)) return;
|
|
32472
32557
|
throw remoteFailureError(status2, data, action);
|
|
@@ -32733,10 +32818,12 @@ var org = defineCommand({
|
|
|
32733
32818
|
printContextNotice(args, { adminScope: true });
|
|
32734
32819
|
req(args, "displayKey");
|
|
32735
32820
|
assertCanonicalTenantSelector(String(args.displayKey), "--display-key");
|
|
32821
|
+
const orgName = orgNameArg(args);
|
|
32736
32822
|
const body = {
|
|
32737
32823
|
kind: args.kind || "organization",
|
|
32738
32824
|
displayKey: args.displayKey
|
|
32739
32825
|
};
|
|
32826
|
+
if (orgName !== void 0) body.displayName = orgName;
|
|
32740
32827
|
applyRuntimeConfig(args, body);
|
|
32741
32828
|
if (args.ownerPrincipalId) body.ownerPrincipalId = args.ownerPrincipalId;
|
|
32742
32829
|
const requestedKind = String(body.kind || "organization").trim();
|
|
@@ -32777,7 +32864,37 @@ var org = defineCommand({
|
|
|
32777
32864
|
const pinKey = canonicalPinKey(tenant);
|
|
32778
32865
|
const pinnable = Boolean(args.pin && pinKey);
|
|
32779
32866
|
if (pinnable && pinKey) saveConfig({ tenant: pinKey });
|
|
32780
|
-
|
|
32867
|
+
const named = orgName === void 0 ? {} : { orgNameApplied: orgNameApplied(tenant, orgName, reused) };
|
|
32868
|
+
return output({ ...recordOf2(res.data), reused, pinned: pinnable, ...named }, fmt);
|
|
32869
|
+
}
|
|
32870
|
+
}),
|
|
32871
|
+
rename: defineCommand({
|
|
32872
|
+
meta: {
|
|
32873
|
+
name: "rename",
|
|
32874
|
+
description: "Set or clear an organisation's display name (--org-name or --clear-org-name; [--expect-org-name])"
|
|
32875
|
+
},
|
|
32876
|
+
args: orgArgs,
|
|
32877
|
+
async run({ args }) {
|
|
32878
|
+
printContextNotice(args, { adminScope: true });
|
|
32879
|
+
const name = orgNameArg(args);
|
|
32880
|
+
if (args.clearOrgName && name !== void 0) {
|
|
32881
|
+
throw commandError("CONFLICTING_ARGS", EXIT_GUARDRAIL, "Pass --org-name or --clear-org-name, not both.");
|
|
32882
|
+
}
|
|
32883
|
+
if (!args.clearOrgName && name === void 0) {
|
|
32884
|
+
throw commandError("ORG_NAME_REQUIRED", 1, "Pass --org-name <name>, or --clear-org-name to remove the name.");
|
|
32885
|
+
}
|
|
32886
|
+
const body = { displayName: args.clearOrgName ? null : name };
|
|
32887
|
+
if (args.expectOrgName !== void 0) {
|
|
32888
|
+
const expected = String(args.expectOrgName).trim();
|
|
32889
|
+
body.expectedDisplayName = expected || null;
|
|
32890
|
+
}
|
|
32891
|
+
const { tenantId } = await resolveTenantId(args);
|
|
32892
|
+
const { client, fmt } = adminCtx(args);
|
|
32893
|
+
const res = await client.patch(`/api/admin/orgs/${enc(tenantId)}`, body);
|
|
32894
|
+
ensureAuthorized(res.status, "Renaming an organisation");
|
|
32895
|
+
ensureOk(res.status, res.data, "rename organisation");
|
|
32896
|
+
const data = recordOf2(res.data);
|
|
32897
|
+
return output({ ...data, idempotent: data.changed === false }, fmt);
|
|
32781
32898
|
}
|
|
32782
32899
|
}),
|
|
32783
32900
|
members: defineCommand({
|
|
@@ -32898,7 +33015,9 @@ var org = defineCommand({
|
|
|
32898
33015
|
}
|
|
32899
33016
|
const kind = String(args.kind || "organization").trim();
|
|
32900
33017
|
const { client, fmt } = adminCtx(args);
|
|
33018
|
+
const orgName = orgNameArg(args);
|
|
32901
33019
|
const createBody = { kind, displayKey: args.displayKey };
|
|
33020
|
+
if (orgName !== void 0) createBody.displayName = orgName;
|
|
32902
33021
|
applyRuntimeConfig(args, createBody);
|
|
32903
33022
|
if (args.ownerPrincipalId) createBody.ownerPrincipalId = args.ownerPrincipalId;
|
|
32904
33023
|
let reusedTenant = false;
|
|
@@ -32947,6 +33066,7 @@ var org = defineCommand({
|
|
|
32947
33066
|
if (!tenantId) {
|
|
32948
33067
|
throw commandError("TENANT_NOT_FOUND", 1, "Tenant was created/reused but no id was returned.");
|
|
32949
33068
|
}
|
|
33069
|
+
if (orgName !== void 0) orgNameApplied(tenant, orgName, reusedTenant);
|
|
32950
33070
|
const admitBody = { email: email3, roles };
|
|
32951
33071
|
if (args.displayName) admitBody.displayName = args.displayName;
|
|
32952
33072
|
const admitRes = await client.post(`/api/admin/orgs/${enc(tenantId)}/members`, admitBody);
|