@brainbase-labs/cli 0.21.1 → 0.21.2

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/dist/index.js +178 -30
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
36008
36008
  // package.json
36009
36009
  var package_default = {
36010
36010
  name: "@brainbase-labs/cli",
36011
- version: "0.21.1",
36011
+ version: "0.21.2",
36012
36012
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36013
36013
  type: "module",
36014
36014
  bin: {
@@ -53969,6 +53969,7 @@ class NetworkApiError extends ApiError {
53969
53969
 
53970
53970
  class TaskRecoveryDeadlineError extends ApiError {
53971
53971
  }
53972
+ var GET_NETWORK_RETRY_DELAYS_MS = [100, 250];
53972
53973
  function normalizeControlPlaneUrl(url) {
53973
53974
  const normalized = url?.trim().replace(/\/+$/, "");
53974
53975
  return normalized || DEFAULT_CONTROL_PLANE_BASE;
@@ -54101,9 +54102,33 @@ async function sendWithAuthRetry(session, send) {
54101
54102
  }
54102
54103
  async function request(pathname, init = {}) {
54103
54104
  const credential = await resolveCredential();
54104
- const retrySession = credential.source === "session" && !new Headers(init.headers).has("Authorization") ? credential.session : null;
54105
- const res = await sendWithAuthRetry(retrySession, (refreshed) => sendRequest(`${apiBase(refreshed ?? credential.session)}${pathname}`, init, refreshed?.access_token ?? credential.bearer));
54106
- const text2 = await res.text();
54105
+ let currentSession = credential.session;
54106
+ let refreshSessionAvailable = credential.source === "session" && !new Headers(init.headers).has("Authorization");
54107
+ const method2 = (init.method ?? "GET").toUpperCase();
54108
+ let res;
54109
+ let text2;
54110
+ for (let attempt2 = 0;; attempt2 += 1) {
54111
+ try {
54112
+ res = await sendWithAuthRetry(refreshSessionAvailable ? currentSession : null, async (refreshed) => {
54113
+ if (refreshed) {
54114
+ currentSession = refreshed;
54115
+ refreshSessionAvailable = false;
54116
+ }
54117
+ return await sendRequest(`${apiBase(currentSession)}${pathname}`, init, currentSession?.access_token ?? credential.bearer);
54118
+ });
54119
+ try {
54120
+ text2 = await res.text();
54121
+ } catch (error) {
54122
+ throw new NetworkApiError(`Network error while reading response: ${error.message}`, false);
54123
+ }
54124
+ break;
54125
+ } catch (error) {
54126
+ if (method2 !== "GET" || !(error instanceof NetworkApiError) || attempt2 >= GET_NETWORK_RETRY_DELAYS_MS.length) {
54127
+ throw error;
54128
+ }
54129
+ await new Promise((resolve) => setTimeout(resolve, GET_NETWORK_RETRY_DELAYS_MS[attempt2]));
54130
+ }
54131
+ }
54107
54132
  let body = text2;
54108
54133
  try {
54109
54134
  body = text2 ? JSON.parse(text2) : null;
@@ -68707,6 +68732,10 @@ async function showTokenListCard(props) {
68707
68732
  // src/cli/token.ts
68708
68733
  var DEFAULT_SCOPES = ["read", "publish"];
68709
68734
  var MAX_NAME_LENGTH = 128;
68735
+ var ALLOWED_SCOPES = ["read", "publish", "admin"];
68736
+ function isAllowedScope(value) {
68737
+ return ALLOWED_SCOPES.includes(value);
68738
+ }
68710
68739
  function isExpired2(token) {
68711
68740
  return Boolean(token.expires_at && Date.parse(token.expires_at) <= Date.now());
68712
68741
  }
@@ -68727,7 +68756,14 @@ async function runTokenCreate(args) {
68727
68756
  flagHint: "Pass --name <label>."
68728
68757
  });
68729
68758
  }
68730
- const scopes = args.scopes && args.scopes.length > 0 ? args.scopes : DEFAULT_SCOPES;
68759
+ let scopes;
68760
+ if (args.scopes === undefined) {
68761
+ scopes = DEFAULT_SCOPES;
68762
+ } else if (args.scopes.length === 0) {
68763
+ throw new Error("Usage: brainbase token create --scopes <list> (allowed: read, publish, admin)");
68764
+ } else {
68765
+ scopes = args.scopes;
68766
+ }
68731
68767
  const spinner = de();
68732
68768
  spinner.start("Creating token…");
68733
68769
  const created = await registryApi.createCliToken({
@@ -68812,7 +68848,7 @@ async function runTokenRename(args) {
68812
68848
  return;
68813
68849
  };
68814
68850
  let name;
68815
- if (args.name === undefined) {
68851
+ if (!args.name) {
68816
68852
  const answer = await text({
68817
68853
  message: "New label",
68818
68854
  placeholder: target.name,
@@ -68843,7 +68879,12 @@ async function runTokenRevoke(args) {
68843
68879
  console.error("Usage: brainbase token revoke <id>");
68844
68880
  process.exit(1);
68845
68881
  }
68846
- const tokens = await registryApi.listCliTokens();
68882
+ let tokens;
68883
+ try {
68884
+ tokens = await registryApi.listCliTokens();
68885
+ } catch (error) {
68886
+ throw withLoginHint(error);
68887
+ }
68847
68888
  const target = tokens.find((t) => t.id === args.id);
68848
68889
  if (!target) {
68849
68890
  throw new Error(`No token with id ${args.id}. Run \`brainbase token list\` to see yours.`);
@@ -68866,8 +68907,7 @@ async function runTokenRevoke(args) {
68866
68907
  await registryApi.revokeCliToken(args.id);
68867
68908
  } catch (error) {
68868
68909
  if (error instanceof ApiError && error.status === 404) {
68869
- const expiryPassed = Boolean(target.expires_at && Date.parse(target.expires_at) <= Date.now());
68870
- if (expiryPassed) {
68910
+ if (isExpired2(target)) {
68871
68911
  reconcileDeadToken(target, `${import_picocolors45.default.bold(target.name)} had already expired.`);
68872
68912
  return;
68873
68913
  }
@@ -68915,11 +68955,29 @@ async function runTokenClear() {
68915
68955
  clearToken();
68916
68956
  console.log(`${sym.ok} Cleared local token. (Server-side token still active until revoked.)`);
68917
68957
  }
68958
+ var TOKEN_VALUE_FLAGS = new Set(["--name", "-n", "--scope", "--scopes"]);
68959
+ function isValueOfPriorFlag(rest2, index) {
68960
+ return index > 0 && TOKEN_VALUE_FLAGS.has(rest2[index - 1]);
68961
+ }
68918
68962
  function pickFlag(rest2, ...names) {
68919
68963
  for (const n of names) {
68920
- const i = rest2.indexOf(n);
68921
- if (i !== -1 && i + 1 < rest2.length)
68922
- return rest2[i + 1];
68964
+ const prefix = `${n}=`;
68965
+ for (let i = 0;i < rest2.length; i++) {
68966
+ if (isValueOfPriorFlag(rest2, i))
68967
+ continue;
68968
+ const a3 = rest2[i];
68969
+ if (a3 === n) {
68970
+ const v3 = rest2[i + 1];
68971
+ if (v3 === undefined)
68972
+ return "";
68973
+ const label = n === "--name" || n === "-n";
68974
+ if (!label && v3.startsWith("-"))
68975
+ return "";
68976
+ return v3;
68977
+ }
68978
+ if (a3.startsWith(prefix))
68979
+ return a3.slice(prefix.length);
68980
+ }
68923
68981
  }
68924
68982
  return;
68925
68983
  }
@@ -68938,9 +68996,17 @@ function firstPositional(rest2, ...valueFlags) {
68938
68996
  return;
68939
68997
  }
68940
68998
  function parseScopes(raw) {
68941
- if (!raw)
68999
+ if (raw === undefined)
68942
69000
  return;
68943
- return raw.split(",").map((s3) => s3.trim()).filter((s3) => s3.length > 0);
69001
+ const scopes = raw.split(",").map((s3) => s3.trim().toLowerCase()).filter((s3) => s3.length > 0);
69002
+ if (scopes.length === 0) {
69003
+ throw new Error("Usage: brainbase token create --scopes <list> (allowed: read, publish, admin)");
69004
+ }
69005
+ const unknown = scopes.filter((s3) => !isAllowedScope(s3));
69006
+ if (unknown.length > 0) {
69007
+ throw new Error(`Unknown scope${unknown.length === 1 ? "" : "s"} ${unknown.join(", ")} — allowed: read, publish, admin`);
69008
+ }
69009
+ return scopes;
68944
69010
  }
68945
69011
  async function runToken(sub, rest2, args) {
68946
69012
  const nameFlag = args.name || pickFlag(rest2, "--name", "-n");
@@ -79665,36 +79731,118 @@ function help() {
79665
79731
  console.log(out.join(`
79666
79732
  `));
79667
79733
  }
79668
- function getFlag(args, ...names) {
79734
+ var VALUE_TAKING_FLAGS = new Set([
79735
+ "--scope",
79736
+ "--name",
79737
+ "-n",
79738
+ "--harness",
79739
+ "--web",
79740
+ "--visibility",
79741
+ "--category",
79742
+ "--target",
79743
+ "--page",
79744
+ "--as",
79745
+ "--agent",
79746
+ "--shell",
79747
+ "--skill-version",
79748
+ "--tagline",
79749
+ "--org",
79750
+ "--team",
79751
+ "--description",
79752
+ "--schema",
79753
+ "--from",
79754
+ "--to"
79755
+ ]);
79756
+ function isValueOfPriorFlag2(args, index) {
79757
+ return index > 0 && VALUE_TAKING_FLAGS.has(args[index - 1]);
79758
+ }
79759
+ function findFlag(args, name) {
79760
+ const prefix = `${name}=`;
79761
+ for (let i = 0;i < args.length; i++) {
79762
+ if (isValueOfPriorFlag2(args, i))
79763
+ continue;
79764
+ const a3 = args[i];
79765
+ if (a3 === name)
79766
+ return { index: i };
79767
+ if (a3.startsWith(prefix))
79768
+ return { index: i, joinedValue: a3.slice(prefix.length) };
79769
+ }
79770
+ return null;
79771
+ }
79772
+ function takeFlagOnce(args, names) {
79773
+ let best = null;
79669
79774
  for (const n of names) {
79670
- const i = args.indexOf(n);
79671
- if (i >= 0) {
79672
- const v3 = args[i + 1];
79673
- args.splice(i, v3 && !v3.startsWith("--") && !(n.startsWith("-") && v3.startsWith("-")) ? 2 : 1);
79674
- return v3 && !v3.startsWith("--") ? v3 : "";
79675
- }
79775
+ const hit = findFlag(args, n);
79776
+ if (hit && (!best || hit.index < best.index))
79777
+ best = hit;
79676
79778
  }
79677
- return;
79779
+ if (!best)
79780
+ return;
79781
+ if (best.joinedValue !== undefined) {
79782
+ args.splice(best.index, 1);
79783
+ return best.joinedValue;
79784
+ }
79785
+ const v3 = args[best.index + 1];
79786
+ if (v3 && !v3.startsWith("-")) {
79787
+ args.splice(best.index, 2);
79788
+ return v3;
79789
+ }
79790
+ args.splice(best.index, 1);
79791
+ return "";
79792
+ }
79793
+ function getFlag(args, ...names) {
79794
+ const first = takeFlagOnce(args, names);
79795
+ if (first === undefined)
79796
+ return;
79797
+ while (takeFlagOnce(args, names) !== undefined) {}
79798
+ return first;
79678
79799
  }
79679
79800
  function getFlagAll(args, ...names) {
79680
79801
  const out = [];
79681
- let v3 = getFlag(args, ...names);
79802
+ let v3 = takeFlagOnce(args, names);
79682
79803
  while (v3 !== undefined) {
79683
79804
  if (v3)
79684
79805
  out.push(v3);
79685
- v3 = getFlag(args, ...names);
79806
+ v3 = takeFlagOnce(args, names);
79686
79807
  }
79687
79808
  return out;
79688
79809
  }
79689
- function hasFlag2(args, ...names) {
79690
- for (const n of names) {
79691
- const i = args.indexOf(n);
79692
- if (i >= 0) {
79693
- args.splice(i, 1);
79810
+ function interpretJoinedBoolean(value, name) {
79811
+ const v3 = value.trim().toLowerCase();
79812
+ if (v3 === "")
79813
+ return false;
79814
+ switch (v3) {
79815
+ case "false":
79816
+ case "0":
79817
+ case "no":
79818
+ case "off":
79819
+ return false;
79820
+ case "true":
79821
+ case "1":
79822
+ case "yes":
79823
+ case "on":
79694
79824
  return true;
79825
+ default:
79826
+ throw new Error(`Unrecognised value for ${name}: ${value}`);
79827
+ }
79828
+ }
79829
+ function hasFlag2(args, ...names) {
79830
+ let leftmost;
79831
+ while (true) {
79832
+ let best = null;
79833
+ for (const n of names) {
79834
+ const hit = findFlag(args, n);
79835
+ if (hit && (!best || hit.index < best.index))
79836
+ best = { ...hit, name: n };
79695
79837
  }
79838
+ if (!best)
79839
+ break;
79840
+ args.splice(best.index, 1);
79841
+ const enabled = best.joinedValue === undefined ? true : interpretJoinedBoolean(best.joinedValue, best.name);
79842
+ if (leftmost === undefined)
79843
+ leftmost = enabled;
79696
79844
  }
79697
- return false;
79845
+ return leftmost ?? false;
79698
79846
  }
79699
79847
  async function requireAuth(cmd) {
79700
79848
  if (!PROTECTED.has(cmd))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainbase-labs/cli",
3
- "version": "0.21.1",
3
+ "version": "0.21.2",
4
4
  "description": "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
5
5
  "type": "module",
6
6
  "bin": {