@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.
Files changed (2) hide show
  1. package/hive.cjs +139 -19
  2. 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 = process.env.HIVE_TOKEN || process.env.HIVE_TEST_TOKEN || process.env.HIVE_BEARER_TOKEN || await getValidToken();
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.87.2" : void 0
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.87.2" : void 0
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 ? "a96123fb3acccd513fb8e7aa2acd3767c46e56a2" : void 0
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-29T21:57:37Z" : void 0
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.87.2" : void 0
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 active session info" },
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 creds = getStoredCredentials();
11394
- if (!creds || !creds.access_token) {
11395
- console.log("\x1B[33mNot logged in. Run 'hive login' to authenticate.\x1B[0m");
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
- const left = Math.floor((creds.expires_at - Date.now()) / 1e3);
11399
- console.log(`User: \x1B[36m${creds.user}\x1B[0m`);
11400
- console.log(`Issuer: ${creds.issuer}`);
11401
- console.log(
11402
- `Status: ${left > 0 ? `\x1B[32mActive\x1B[0m (expires in ${Math.floor(left / 60)} min)` : "\x1B[31mExpired\x1B[0m"}`
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
- return output({ ...recordOf2(res.data), reused, pinned: pinnable }, fmt);
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senticor/hive",
3
- "version": "1.87.2",
3
+ "version": "1.88.0",
4
4
  "description": "Cognitive Hive OS — unified CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {