@topolo/cli 0.4.0 → 0.4.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 +10 -46
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3819,46 +3819,6 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
3819
3819
  return cred;
3820
3820
  }
3821
3821
  }
3822
- async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
3823
- const config = await readConfig();
3824
- const profile = profileForEnvironment(config, environment);
3825
- const context = profile.contexts?.[key];
3826
- const credential = context?.credential;
3827
- if (!credential || credential.kind !== "access_token") return credential ?? null;
3828
- const oauthClientId = context.oauthClientId ?? profile.oauthClientId;
3829
- if (!credential.refreshToken || !credential.expiresAt || !oauthClientId) return credential;
3830
- const now = Math.floor(Date.now() / 1e3);
3831
- if (!options.force && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
3832
- try {
3833
- const oauth = new TopoloOAuth2({
3834
- serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
3835
- });
3836
- const tokens = await oauth.refreshToken({
3837
- clientId: oauthClientId,
3838
- refreshToken: credential.refreshToken
3839
- });
3840
- const refreshed = {
3841
- kind: "access_token",
3842
- accessToken: tokens.access_token,
3843
- ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: credential.refreshToken },
3844
- expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
3845
- };
3846
- await writeConfig(writeProfileConfig(config, environment, {
3847
- ...profile.activeContext === key ? { credential: refreshed } : {},
3848
- contexts: {
3849
- ...profile.contexts ?? {},
3850
- [key]: {
3851
- ...context,
3852
- credential: refreshed,
3853
- oauthClientId
3854
- }
3855
- }
3856
- }));
3857
- return refreshed;
3858
- } catch {
3859
- return credential;
3860
- }
3861
- }
3862
3822
  function resolveAgentName(configAgentName) {
3863
3823
  return process.env.TOPOLO_AGENT_NAME ?? configAgentName;
3864
3824
  }
@@ -4010,7 +3970,7 @@ var CLI_VERSION = readCliVersion();
4010
3970
  // src/commands/auth.ts
4011
3971
  function registerAuthCommands(program2) {
4012
3972
  const auth = program2.command("auth").description("Manage Topolo credentials");
4013
- auth.command("login").description("Authenticate with Topolo via OAuth device flow (default) or store an API key").option("--api-key <key>", "Store an API key directly, skipping the OAuth flow").option("--client-id <id>", "OAuth client_id (or set TOPOLO_CLI_CLIENT_ID)").option("--scope <scope>", "Scopes to request (space-separated)").option("--json", "Output JSON").option("--no-json", "Output human-readable text").action(
3973
+ auth.command("login").description("Authenticate with Topolo via OAuth device flow (default) or store an API key").option("--api-key <key>", "Store an API key directly, skipping the OAuth flow").option("--client-id <id>", "OAuth client_id (or set TOPOLO_CLI_CLIENT_ID)").option("--scope <scope>", "Scopes to request (space-separated)").option("--no-browser", "Print the approval URL without opening a browser").option("--json", "Output JSON").option("--no-json", "Output human-readable text").action(
4014
3974
  async (opts) => {
4015
3975
  const mode = resolveOutputMode(opts.json);
4016
3976
  const environment = selectedEnvironment();
@@ -4039,7 +3999,13 @@ Visit ${apiKeyIssuanceUrl(environment)} to mint one, or configure an OAuth clien
4039
3999
  await storeApiKey(apiKey, environment, mode);
4040
4000
  return;
4041
4001
  }
4042
- await runDeviceFlow({ clientId, environment, scope: opts.scope, mode });
4002
+ await runDeviceFlow({
4003
+ clientId,
4004
+ environment,
4005
+ scope: opts.scope,
4006
+ mode,
4007
+ openBrowser: opts.browser !== false
4008
+ });
4043
4009
  } catch (err) {
4044
4010
  fail(err, mode);
4045
4011
  }
@@ -4113,7 +4079,7 @@ async function runDeviceFlow(options) {
4113
4079
  });
4114
4080
  const verifyUrl = start.verification_uri_complete ?? start.verification_uri;
4115
4081
  const expiresMin = Math.round(start.expires_in / 60);
4116
- const opened = options.mode === "pretty" ? tryOpenBrowser(verifyUrl) : false;
4082
+ const opened = options.mode === "pretty" && options.openBrowser ? tryOpenBrowser(verifyUrl) : false;
4117
4083
  if (options.mode === "pretty") {
4118
4084
  process.stderr.write(
4119
4085
  `
@@ -11268,7 +11234,6 @@ function registerContextCommand(program2) {
11268
11234
  }
11269
11235
  const wantPersonal = /^(personal|me)$/i.test(target.trim());
11270
11236
  let resolved;
11271
- let exchangeCredential = cred;
11272
11237
  const needle = target.trim().toLowerCase();
11273
11238
  const storedEntry = Object.entries(profile.contexts ?? {}).find(([, candidate]) => {
11274
11239
  if (wantPersonal) return candidate.contextType === "personal";
@@ -11276,7 +11241,6 @@ function registerContextCommand(program2) {
11276
11241
  });
11277
11242
  const storedContext = storedEntry?.[1];
11278
11243
  if (storedEntry && storedContext?.credential) {
11279
- exchangeCredential = await refreshContextCredentialIfNeeded(environment, storedEntry[0]) ?? storedContext.credential;
11280
11244
  resolved = {
11281
11245
  contextType: storedContext.contextType,
11282
11246
  organizationId: storedContext.organizationId,
@@ -11305,7 +11269,7 @@ function registerContextCommand(program2) {
11305
11269
  }
11306
11270
  const key = contextKey(resolved.contextType, resolved.organizationId);
11307
11271
  const existing = profile.contexts?.[key];
11308
- const newCredential = await exchangeForContext(exchangeCredential, serviceUrls, {
11272
+ const newCredential = await exchangeForContext(cred, serviceUrls, {
11309
11273
  type: resolved.contextType,
11310
11274
  id: resolved.organizationId
11311
11275
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topolo/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Command-line interface for Topolo developers, operators, and agents, with internal first-party scaffolding available under the topolo platform namespace.",
5
5
  "type": "module",
6
6
  "bin": {