@nebulr-group/bridge-cli 0.4.4 → 0.5.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/README.md CHANGED
@@ -27,10 +27,48 @@ bridge auth login
27
27
  Opens your default browser, runs through a PKCE-secured loopback flow (RFC 8252), and stores a 10-day token at `~/.config/bridge/credentials.json` (mode `0600`). After that, every subsequent `bridge` command picks the token up automatically — no env vars needed.
28
28
 
29
29
  ```bash
30
- bridge auth status # show who you're logged in as and when the token expires
31
- bridge auth logout # revoke the token and delete the credentials file
30
+ bridge auth status # show every stored app, and which one is active
31
+ bridge auth logout # revoke the active token and remove it locally
32
32
  ```
33
33
 
34
+ #### Several apps at once
35
+
36
+ The credentials file holds one credential per app, so you can log in to your
37
+ local, stage and prod apps and move between them without a browser round-trip —
38
+ the tokens are already on disk with days left on them.
39
+
40
+ ```bash
41
+ bridge auth login --label northwhistle-local # once per app
42
+ bridge auth login --label northwhistle-prod
43
+
44
+ bridge auth status # lists both, marks the active one
45
+ bridge auth use northwhistle-local # switch the default, offline
46
+ bridge --profile northwhistle-prod app get # target ONE command, default untouched
47
+ ```
48
+
49
+ A profile is selected by its `--label`, its app id, or its app name, in that
50
+ order. An ambiguous name is an error rather than a guess. `BRIDGE_PROFILE` does
51
+ the same thing as `--profile` for a whole shell session.
52
+
53
+ Prefer `--profile` over `bridge auth use` in scripts and long-running agent
54
+ sessions: `use` mutates state another process may be reading, `--profile` does
55
+ not.
56
+
57
+ Every command prints one line to **stderr** naming the app that answered:
58
+
59
+ ```
60
+ bridge: northwhistle-prod (606b4416fabdc800087d09ec) · https://api.thebridge.dev · via saved default
61
+ ```
62
+
63
+ stdout stays pure JSON, so this does not disturb anything parsing it. Silence it
64
+ with `BRIDGE_NO_BANNER=true` if you are already certain which app you are on.
65
+
66
+ `bridge auth logout` removes the active app only. Use `--profile <name>` for a
67
+ specific one, or `--all` to clear the file.
68
+
69
+ Existing single-app credentials files keep working and are upgraded in place the
70
+ next time something writes.
71
+
34
72
  #### `bridge auth login` flags
35
73
 
36
74
  | Flag | Description |
@@ -56,7 +94,17 @@ For non-interactive contexts (CI/CD pipelines, Docker images, headless agents) s
56
94
  export BRIDGE_API_KEY=<your-api-token>
57
95
  ```
58
96
 
59
- If you have logged in via `bridge auth login`, the credentials file always wins — a fresh login takes effect immediately, even when `BRIDGE_API_KEY` is still exported in your shell. `BRIDGE_API_KEY` is only used when no credentials file is present (the typical CI runner shape). To switch back to env-var auth on a developer machine, run `bridge auth logout` first.
97
+ If you have logged in via `bridge auth login`, the credentials file always wins — a fresh login takes effect immediately, even when `BRIDGE_API_KEY` is still exported in your shell. `BRIDGE_API_KEY` is only used when no credentials file is present (the typical CI runner shape). To switch back to env-var auth on a developer machine, run `bridge auth logout --all` first.
98
+
99
+ Because that trips people up, the CLI now says so at the moment it happens: with
100
+ both present you get a line on stderr telling you `BRIDGE_API_KEY` is set and
101
+ being ignored, and what to do instead. To point the CLI at a different app, use
102
+ `--profile`, not the env vars.
103
+
104
+ **`BRIDGE_APP_ID` has no effect on any path.** The app is carried by the
105
+ credential itself — a login token and an API key are both already scoped to one
106
+ app, so there is nothing for it to change. It is called out on stderr whenever it
107
+ is set, rather than being quietly ignored.
60
108
 
61
109
  Optional configuration (applies to both auth paths):
62
110
 
@@ -139,8 +187,11 @@ bridge auth login # default: open browser, complete PKCE flow
139
187
  bridge auth login --app acme # pin to a specific app
140
188
  bridge auth login --label "work laptop"
141
189
  bridge auth login --no-browser # print the URL (headless / SSH)
142
- bridge auth status # show current login state
143
- bridge auth logout # revoke token + delete local file
190
+ bridge auth status # show every stored app, active one marked
191
+ bridge auth use <label|app-id> # switch the default app, no browser
192
+ bridge auth logout # revoke + remove the active app
193
+ bridge auth logout --all # ...or every stored app
194
+ bridge --profile <label> <cmd> # target one app for one command
144
195
  ```
145
196
 
146
197
  ### Auth Configuration (app-level — separate from `auth login`)
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,eAAO,MAAM,OAAO,SAAgB,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,eAAO,MAAM,OAAO,SAAgB,CAAC"}
package/dist/cli.js CHANGED
@@ -18,6 +18,7 @@ import { registerInfoCommands } from './commands/info.command.js';
18
18
  import { registerGuideCommands } from './commands/guide.command.js';
19
19
  import { registerOpsCommands } from './commands/ops.command.js';
20
20
  import { registerStripeCommands } from './commands/stripe.command.js';
21
+ import { setProfileOverride } from './config.js';
21
22
  // Read version from package.json so `bridge --version` never drifts from the
22
23
  // published package. dist/cli.js lives at <pkg>/dist/cli.js, so `../package.json`
23
24
  // resolves to the package root in both the published tarball and during dev.
@@ -27,7 +28,18 @@ export const program = new Command();
27
28
  program
28
29
  .name('bridge')
29
30
  .description('Bridge platform CLI — optimized for AI coding agents')
30
- .version(version);
31
+ .version(version)
32
+ // TBP-628 — target another stored app for ONE command, without touching the
33
+ // persisted default another process may be reading. Named `--profile` rather
34
+ // than `--app` because `bridge auth login --app` already exists and means
35
+ // something different (which app to authorise), and because `--profile` is
36
+ // what aws/npm users already reach for.
37
+ .option('--profile <label|app-id|app-name>', 'Use a specific stored credential for this command (env: BRIDGE_PROFILE)');
38
+ // Runs before any subcommand action, so `getManagementClient()` sees the
39
+ // override wherever in the tree it is eventually called from.
40
+ program.hook('preAction', (thisCommand) => {
41
+ setProfileOverride(thisCommand.opts().profile);
42
+ });
31
43
  registerAppCommands(program);
32
44
  registerTenantCommands(program);
33
45
  registerUserCommands(program);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,6EAA6E;AAC7E,kFAAkF;AAClF,6EAA6E;AAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AACpF,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAwB,CAAC;AAErF,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAErC,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,sDAAsD,CAAC;KACnE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -3,11 +3,18 @@
3
3
  *
4
4
  * Behavior:
5
5
  * - No credentials file → "Not logged in." (exit 0).
6
- * - File present → call `POST /v1/auth/cli/revoke` with `x-api-key`,
6
+ * - Otherwise → call `POST /v1/auth/cli/revoke` with `x-api-key`,
7
7
  * treat 401 as success (token already gone), then
8
- * delete the file. Network errors → warn but still
9
- * delete (the local file is the source of truth for
8
+ * remove it locally. Network errors → warn but still
9
+ * remove (the local file is the source of truth for
10
10
  * "logged in" on this machine).
11
+ *
12
+ * TBP-628 — the file can hold several apps, so logout now has a scope.
13
+ * Bare `logout` removes the ACTIVE credential and leaves the others; the
14
+ * alternative, wiping every app because you finished with one of them, throws
15
+ * away valid tokens and forces browser round-trips to get them back, which is
16
+ * the friction this ticket exists to remove. `--profile` names one, `--all`
17
+ * asks for the old whole-file behaviour explicitly.
11
18
  */
12
19
  import type { Command } from 'commander';
13
20
  export declare function registerAuthLogoutCommand(auth: Command): void;
@@ -1 +1 @@
1
- {"version":3,"file":"logout.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/logout.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAc7D"}
1
+ {"version":3,"file":"logout.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/logout.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAgB7D"}
@@ -1,13 +1,15 @@
1
- import { credentialsPath, deleteCredentials, readCredentials } from '../../credentials.js';
1
+ import { credentialsPath, CredentialSelectorError, deleteAllCredentials, findCredential, listCredentials, readCredentials, removeCredential, } from '../../credentials.js';
2
2
  import { resetManagementClient } from '../../config.js';
3
3
  import { createCliApiClient, CliAuthApiError } from '../../auth/api-client.js';
4
4
  export function registerAuthLogoutCommand(auth) {
5
5
  auth
6
6
  .command('logout')
7
- .description('Revoke the saved CLI token and delete local credentials')
8
- .action(async () => {
7
+ .description('Revoke the active CLI token and remove it locally')
8
+ .option('--profile <label|app-id|app-name>', 'Log out of one specific stored app')
9
+ .option('--all', 'Log out of every stored app and delete the credentials file')
10
+ .action(async (opts) => {
9
11
  try {
10
- await runLogout();
12
+ await runLogout(opts);
11
13
  process.exitCode = 0;
12
14
  }
13
15
  catch (err) {
@@ -17,41 +19,79 @@ export function registerAuthLogoutCommand(auth) {
17
19
  }
18
20
  });
19
21
  }
20
- async function runLogout() {
22
+ async function runLogout(opts = {}) {
21
23
  const stdout = process.stdout;
22
24
  const stderr = process.stderr;
23
- let creds;
25
+ let entries;
24
26
  try {
25
- creds = readCredentials();
27
+ entries = listCredentials();
26
28
  }
27
29
  catch (err) {
28
- // Malformed credentials file — still try to delete it so the user gets unstuck.
30
+ // Malformed credentials file — still delete it so the user gets unstuck.
29
31
  stderr.write(`Warning: existing credentials file at ${credentialsPath()} could not be parsed (${err instanceof Error ? err.message : String(err)}). Removing it.\n`);
30
- deleteCredentials();
32
+ deleteAllCredentials();
31
33
  stdout.write('Logged out (credentials file removed).\n');
32
34
  return;
33
35
  }
34
- if (!creds) {
36
+ if (entries.length === 0) {
35
37
  stdout.write('Not logged in.\n');
36
38
  return;
37
39
  }
40
+ if (opts.all) {
41
+ for (const entry of entries)
42
+ await revoke(entry.creds, stderr);
43
+ deleteAllCredentials();
44
+ resetManagementClient();
45
+ stdout.write(`Logged out of ${entries.length} app(s).\n`);
46
+ return;
47
+ }
48
+ let target;
49
+ if (opts.profile) {
50
+ try {
51
+ target = findCredential(opts.profile);
52
+ }
53
+ catch (err) {
54
+ if (err instanceof CredentialSelectorError)
55
+ throw new Error(err.message);
56
+ throw err;
57
+ }
58
+ }
59
+ else {
60
+ const active = readCredentials();
61
+ if (!active) {
62
+ // Several stored, none active. Removing one by guess is exactly the
63
+ // silent choice this ticket forbids.
64
+ throw new Error('No active credential. Name one with `--profile <label|app id>`, or use `--all`. ' +
65
+ `Stored: ${entries.map((e) => e.creds.label ?? e.creds.app.name).join(', ')}.`);
66
+ }
67
+ target = entries.find((e) => e.key === active.app.id);
68
+ }
69
+ await revoke(target.creds, stderr);
70
+ const remaining = removeCredential(target.key);
71
+ resetManagementClient();
72
+ const name = target.creds.label ?? target.creds.app.name;
73
+ stdout.write(`Logged out ${target.creds.user.email} from ${name}.\n`);
74
+ if (remaining > 0) {
75
+ const rest = listCredentials();
76
+ const nowActive = rest.find((e) => e.isActive);
77
+ stdout.write(` ${remaining} credential(s) still stored` +
78
+ (nowActive ? `; now using ${nowActive.creds.label ?? nowActive.creds.app.name}` : '') +
79
+ '.\n');
80
+ }
81
+ }
82
+ /** Best-effort server-side revoke. Never fatal — local removal is the point. */
83
+ async function revoke(creds, stderr) {
38
84
  const api = createCliApiClient({ baseUrl: creds.baseUrl });
39
85
  try {
40
86
  await api.revokeToken(creds.apiKey);
41
87
  }
42
88
  catch (err) {
43
- // Network failure — warn but still proceed with local deletion.
44
89
  if (err instanceof CliAuthApiError && err.code === 'network_error') {
45
- stderr.write(`Warning: could not reach bridge-api to revoke server-side (${err.message}). Removing local credentials anyway.\n`);
90
+ stderr.write(`Warning: could not reach bridge-api to revoke ${creds.app.name} server-side (${err.message}). Removing local credentials anyway.\n`);
46
91
  }
47
92
  else {
48
- // Any other API error is also non-fatal for the local cleanup, but we
49
- // surface it so the user knows the server-side revoke didn't happen.
50
- stderr.write(`Warning: server-side revoke returned an error (${err instanceof Error ? err.message : String(err)}). Removing local credentials anyway.\n`);
93
+ stderr.write(`Warning: server-side revoke for ${creds.app.name} returned an error (${err instanceof Error ? err.message : String(err)}). Removing local credentials anyway.\n`);
51
94
  }
52
95
  }
53
- deleteCredentials();
54
- resetManagementClient();
55
- stdout.write(`Logged out ${creds.user.email}.\n`);
56
96
  }
57
97
  //# sourceMappingURL=logout.command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logout.command.js","sourceRoot":"","sources":["../../../src/commands/auth/logout.command.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE/E,MAAM,UAAU,yBAAyB,CAAC,IAAa;IACrD,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,SAAS,EAAE,CAAC;YAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;YACrD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,eAAe,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gFAAgF;QAChF,MAAM,CAAC,KAAK,CACV,yCAAyC,eAAe,EAAE,yBACxD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,mBAAmB,CACpB,CAAC;QACF,iBAAiB,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gEAAgE;QAChE,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACnE,MAAM,CAAC,KAAK,CAAC,8DAA8D,GAAG,CAAC,OAAO,yCAAyC,CAAC,CAAC;QACnI,CAAC;aAAM,CAAC;YACN,sEAAsE;YACtE,qEAAqE;YACrE,MAAM,CAAC,KAAK,CACV,kDACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,yCAAyC,CAC1C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,iBAAiB,EAAE,CAAC;IACpB,qBAAqB,EAAE,CAAC;IACxB,MAAM,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"logout.command.js","sourceRoot":"","sources":["../../../src/commands/auth/logout.command.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,10 @@
8
8
  * optimize for readability over machine-parseability.
9
9
  *
10
10
  * If the user wants JSON, they can run `cat ~/.config/bridge/credentials.json`.
11
+ *
12
+ * TBP-628 — the file can hold several apps, so this lists ALL of them and marks
13
+ * the active one. Knowing which app is in force is the whole reason somebody
14
+ * runs this command, and it was already the only place that told them.
11
15
  */
12
16
  import type { Command } from 'commander';
13
17
  export declare function registerAuthStatusCommand(auth: Command): void;
@@ -1 +1 @@
1
- {"version":3,"file":"status.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/status.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAc7D"}
1
+ {"version":3,"file":"status.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/status.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAc7D"}
@@ -1,4 +1,4 @@
1
- import { credentialsPath, isExpired, readCredentials } from '../../credentials.js';
1
+ import { credentialsPath, isExpired, listCredentials, readCredentialsFile, } from '../../credentials.js';
2
2
  import { formatRelativeTime } from '../../auth/relative-time.js';
3
3
  export function registerAuthStatusCommand(auth) {
4
4
  auth
@@ -18,18 +18,20 @@ export function registerAuthStatusCommand(auth) {
18
18
  }
19
19
  function runStatus() {
20
20
  const stdout = process.stdout;
21
- // Prefer the credentials file; report on `BRIDGE_API_KEY` separately if set
22
- // (so a CI user setting the env var sees something useful).
21
+ // Report on `BRIDGE_API_KEY` separately if set, so a CI user setting the env
22
+ // var sees something useful.
23
23
  const envApiKey = process.env.BRIDGE_API_KEY?.trim();
24
- let creds;
24
+ const envProfile = process.env.BRIDGE_PROFILE?.trim();
25
+ let entries;
25
26
  try {
26
- creds = readCredentials();
27
+ readCredentialsFile();
28
+ entries = listCredentials();
27
29
  }
28
30
  catch (err) {
29
31
  stdout.write(`Credentials file at ${credentialsPath()} is unreadable: ${err instanceof Error ? err.message : String(err)}\n` + 'Run `bridge auth login` to refresh, or delete the file manually.\n');
30
32
  return;
31
33
  }
32
- if (!creds) {
34
+ if (entries.length === 0) {
33
35
  if (envApiKey && envApiKey.length > 0) {
34
36
  stdout.write('Using BRIDGE_API_KEY from environment (service-account / CI path).\n' +
35
37
  'Run `bridge auth login` to switch to interactive credentials.\n');
@@ -38,22 +40,51 @@ function runStatus() {
38
40
  stdout.write('Not logged in. Run `bridge auth login`.\n');
39
41
  return;
40
42
  }
41
- const expiryDate = new Date(creds.expiresAt);
42
- const expiryDelta = expiryDate.getTime() - Date.now();
43
- const expiryRel = formatRelativeTime(expiryDelta);
44
- const expiredLabel = isExpired(creds) ? ' (EXPIRED)' : '';
45
- stdout.write(`Logged in as ${creds.user.email}\n`);
46
- stdout.write(` app=${creds.app.name} (${creds.app.id})\n`);
47
- stdout.write(` expires=${expiryRel} ${creds.expiresAt}${expiredLabel}\n`);
48
- stdout.write(` baseUrl=${creds.baseUrl}\n`);
49
- if (creds.label)
50
- stdout.write(` label=${creds.label}\n`);
43
+ const active = entries.find((e) => e.isActive);
44
+ if (active) {
45
+ stdout.write(`Logged in as ${active.creds.user.email}\n`);
46
+ }
47
+ else {
48
+ // A pointer at a credential that is gone. Say so rather than picking one:
49
+ // an inferred default is exactly what this ticket is about.
50
+ stdout.write('No active credential selected — run `bridge auth use <profile>` to pick one.\n');
51
+ }
52
+ for (const entry of entries) {
53
+ writeEntry(entry, entries.length > 1);
54
+ }
51
55
  stdout.write(` credentials=${credentialsPath()}\n`);
56
+ if (entries.length > 1) {
57
+ stdout.write('\nSwitch the default with `bridge auth use <label|app id>`, ' +
58
+ 'or target one command with `--profile <label|app id>`.\n');
59
+ }
60
+ if (envProfile) {
61
+ stdout.write(`\nBRIDGE_PROFILE=${envProfile} is set — it overrides the active credential above.\n`);
62
+ }
52
63
  if (envApiKey && envApiKey.length > 0) {
53
- stdout.write('\nNote: BRIDGE_API_KEY is also set in your environment it takes precedence over the credentials file.\n');
64
+ // This used to claim the opposite. The credentials file has always won;
65
+ // saying otherwise is how somebody comes to believe they retargeted the
66
+ // CLI when they did not (TBP-628).
67
+ stdout.write('\nNote: BRIDGE_API_KEY is set in your environment but is IGNORED while a ' +
68
+ 'credentials file exists.\nTo use it, run `bridge auth logout --all`. ' +
69
+ 'To target another stored app, use `--profile`.\n');
54
70
  }
55
- if (isExpired(creds)) {
56
- process.exitCode = 0; // status is informational; don't fail just because expired.
71
+ if (process.env.BRIDGE_APP_ID?.trim()) {
72
+ stdout.write('\nNote: BRIDGE_APP_ID has no effect. The app is carried by the credential ' +
73
+ 'itself; use `--profile <label|app id>` to target another one.\n');
57
74
  }
58
75
  }
76
+ function writeEntry(entry, showMarker) {
77
+ const stdout = process.stdout;
78
+ const { creds } = entry;
79
+ const expiryDelta = new Date(creds.expiresAt).getTime() - Date.now();
80
+ const expiryRel = formatRelativeTime(expiryDelta);
81
+ const expiredLabel = isExpired(creds) ? ' (EXPIRED)' : '';
82
+ const marker = showMarker ? (entry.isActive ? '* ' : ' ') : '';
83
+ stdout.write(` ${marker}app=${creds.app.name} (${creds.app.id})\n`);
84
+ if (creds.label)
85
+ stdout.write(` ${marker} label=${creds.label}\n`);
86
+ stdout.write(` ${marker} user=${creds.user.email}\n`);
87
+ stdout.write(` ${marker} expires=${expiryRel} — ${creds.expiresAt}${expiredLabel}\n`);
88
+ stdout.write(` ${marker} baseUrl=${creds.baseUrl}\n`);
89
+ }
59
90
  //# sourceMappingURL=status.command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.command.js","sourceRoot":"","sources":["../../../src/commands/auth/status.command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.command.js","sourceRoot":"","sources":["../../../src/commands/auth/status.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `bridge auth use <profile>` — move the persisted default to another stored
3
+ * credential, without a browser round-trip (TBP-628).
4
+ *
5
+ * The credential is already on disk with days left on it; switching is a
6
+ * pointer move. Before this existed the only way to change apps was
7
+ * `auth logout` + `auth login`, which discarded a perfectly valid token and
8
+ * cost a browser trip, so people did not switch — they ran commands against
9
+ * whichever app happened to be active and read the answers as if they came
10
+ * from the one they meant.
11
+ *
12
+ * For a single command, prefer `--profile` / `BRIDGE_PROFILE`: this command
13
+ * mutates state that other processes read.
14
+ */
15
+ import type { Command } from 'commander';
16
+ export declare function registerAuthUseCommand(auth: Command): void;
17
+ //# sourceMappingURL=use.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/use.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAc1D"}
@@ -0,0 +1,47 @@
1
+ import { CredentialSelectorError, findCredential, isExpired, listCredentials, setActiveCredential, } from '../../credentials.js';
2
+ import { resetManagementClient } from '../../config.js';
3
+ export function registerAuthUseCommand(auth) {
4
+ auth
5
+ .command('use <profile>')
6
+ .description('Switch the default app to another stored credential (no re-login)')
7
+ .action((profile) => {
8
+ try {
9
+ runUse(profile);
10
+ process.exitCode = 0;
11
+ }
12
+ catch (err) {
13
+ const msg = err instanceof Error ? err.message : String(err);
14
+ process.stderr.write(`bridge auth use: ${msg}\n`);
15
+ process.exitCode = 1;
16
+ }
17
+ });
18
+ }
19
+ function runUse(profile) {
20
+ const stdout = process.stdout;
21
+ let entry;
22
+ try {
23
+ entry = findCredential(profile);
24
+ }
25
+ catch (err) {
26
+ if (err instanceof CredentialSelectorError)
27
+ throw new Error(err.message);
28
+ throw err;
29
+ }
30
+ setActiveCredential(entry.key);
31
+ resetManagementClient();
32
+ const name = entry.creds.label ?? entry.creds.app.name;
33
+ stdout.write(`Now using ${name} — ${entry.creds.app.name} (${entry.creds.app.id})\n`);
34
+ stdout.write(` baseUrl=${entry.creds.baseUrl}\n`);
35
+ // Switching TO an expired credential is allowed — it is the user's stated
36
+ // intent, and refusing would leave them unable to make it the default before
37
+ // re-authenticating it. But it must not be a surprise at the next command.
38
+ if (isExpired(entry.creds)) {
39
+ stdout.write(` WARNING: this credential expired ${entry.creds.expiresAt}. ` +
40
+ 'Run `bridge auth login` to refresh it.\n');
41
+ }
42
+ const others = listCredentials().filter((e) => e.key !== entry.key);
43
+ if (others.length > 0) {
44
+ stdout.write(` also stored: ${others.map((e) => e.creds.label ?? e.creds.app.name).join(', ')}\n`);
45
+ }
46
+ }
47
+ //# sourceMappingURL=use.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.command.js","sourceRoot":"","sources":["../../../src/commands/auth/use.command.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,sBAAsB,CAAC,IAAa;IAClD,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,mEAAmE,CAAC;SAChF,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;YAClD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,MAAM,CAAC,OAAe;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,uBAAuB;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,qBAAqB,EAAE,CAAC;IAExB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACtF,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IAEnD,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CACV,sCAAsC,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI;YAC7D,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,KAAK,CACV,kBAAkB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACtF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -5,6 +5,7 @@
5
5
  * - `login` (TBP-113): browser-based PKCE auth.
6
6
  * - `logout` (TBP-113): revoke + delete credentials.
7
7
  * - `status` (TBP-113): show current login state.
8
+ * - `use` (TBP-628): switch the default app, offline.
8
9
  * - `config`/`mfa`/`password-policy`: pre-existing app auth-config commands.
9
10
  */
10
11
  import type { Command } from 'commander';
@@ -1 +1 @@
1
- {"version":3,"file":"auth.command.d.ts","sourceRoot":"","sources":["../../src/commands/auth.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAY3D"}
1
+ {"version":3,"file":"auth.command.d.ts","sourceRoot":"","sources":["../../src/commands/auth.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe3D"}
@@ -1,6 +1,7 @@
1
1
  import { registerAuthLoginCommand } from './auth/login.command.js';
2
2
  import { registerAuthLogoutCommand } from './auth/logout.command.js';
3
3
  import { registerAuthStatusCommand } from './auth/status.command.js';
4
+ import { registerAuthUseCommand } from './auth/use.command.js';
4
5
  import { registerAuthConfigCommands } from './auth/config.command.js';
5
6
  export function registerAuthCommands(program) {
6
7
  const auth = program
@@ -10,6 +11,8 @@ export function registerAuthCommands(program) {
10
11
  registerAuthLoginCommand(auth);
11
12
  registerAuthLogoutCommand(auth);
12
13
  registerAuthStatusCommand(auth);
14
+ // TBP-628 — several apps side by side; switch without a browser round-trip.
15
+ registerAuthUseCommand(auth);
13
16
  // Pre-existing — app-level auth configuration.
14
17
  registerAuthConfigCommands(auth);
15
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.command.js","sourceRoot":"","sources":["../../src/commands/auth.command.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4DAA4D,CAAC,CAAC;IAE7E,qCAAqC;IACrC,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC/B,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAChC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAEhC,+CAA+C;IAC/C,0BAA0B,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"auth.command.js","sourceRoot":"","sources":["../../src/commands/auth.command.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4DAA4D,CAAC,CAAC;IAE7E,qCAAqC;IACrC,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC/B,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAChC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAEhC,4EAA4E;IAC5E,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE7B,+CAA+C;IAC/C,0BAA0B,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
package/dist/config.d.ts CHANGED
@@ -1,22 +1,29 @@
1
1
  import { BridgeManagement } from '@nebulr-group/bridge-auth-core';
2
2
  export declare const DEFAULT_BASE_URL = "https://api.thebridge.dev";
3
+ /** Called once from the CLI entrypoint, before any action runs. */
4
+ export declare function setProfileOverride(profile: string | null | undefined): void;
3
5
  /**
4
6
  * Resolution order:
5
- * 1. `~/.config/bridge/credentials.json` (or `$XDG_CONFIG_HOME/bridge/credentials.json`)
6
- * written by `bridge auth login`. The interactive primary path. Token
7
- * carries the appId baked in by /v1/auth/cli/token, so post-login the
8
- * JWT is the source of truth for which app the CLI operates on.
9
- * 2. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
10
- * credentials file exists typical CI runner shape.
11
- * 3. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
7
+ * 1. `--profile <label|id|name>` / `BRIDGE_PROFILE` a stored credential,
8
+ * named for this one invocation. Never falls back: naming a profile and
9
+ * silently getting a different app is the exact failure TBP-628 exists to
10
+ * stop, so an unknown or expired profile is an error.
11
+ * 2. The ACTIVE credential in `~/.config/bridge/credentials.json` (or
12
+ * `$XDG_CONFIG_HOME/...`), written by `bridge auth login` and moved by
13
+ * `bridge auth use`.
14
+ * 3. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
15
+ * usable credentials file exists — the typical CI runner shape.
16
+ * 4. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
12
17
  *
13
- * Note: credentials-file wins over env so `bridge auth login` does what users
14
- * expect the new login takes effect immediately. CI is unaffected because
15
- * runners typically have no credentials file and fall through to step 2.
18
+ * The credentials file still wins over `BRIDGE_API_KEY`, unchanged, so
19
+ * `bridge auth login` takes effect immediately and CI is unaffected. What HAS
20
+ * changed is that being ignored is now said out loud: `BRIDGE_API_KEY` and
21
+ * `BRIDGE_APP_ID` look like a way to retarget the CLI and are not, and reading
22
+ * that in the output beats discovering it from a write that went to the wrong
23
+ * app (TBP-628).
16
24
  *
17
- * If a credentials file exists but its `expiresAt` is in the past, we fall
18
- * through to env (if set) — same as if there were no file. Otherwise throw a
19
- * friendly error pointing the user back to `bridge auth login`.
25
+ * Every resolution also prints one line to stderr naming the app that is about
26
+ * to answer. See `writeContextBanner`.
20
27
  */
21
28
  export declare function getManagementClient(): BridgeManagement;
22
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAI5D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CA+CtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQnE;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AASlE,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAa5D,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAE3E;AAQD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CA0EtD;AAoDD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQnE;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B"}
package/dist/config.js CHANGED
@@ -1,24 +1,47 @@
1
1
  import { BridgeManagement } from '@nebulr-group/bridge-auth-core';
2
- import { isExpired, readCredentials } from './credentials.js';
2
+ import { CredentialSelectorError, findCredential, isExpired, readCredentials, } from './credentials.js';
3
3
  export const DEFAULT_BASE_URL = 'https://api.thebridge.dev';
4
4
  let _client = null;
5
+ /**
6
+ * The `--profile` value for this invocation, set by the CLI's preAction hook.
7
+ *
8
+ * A per-invocation override rather than a persisted switch, because that is
9
+ * what scripts and long-running agent sessions need: target one app for one
10
+ * command without mutating state another process is reading (TBP-628).
11
+ */
12
+ let _profileOverride = null;
13
+ /** Called once from the CLI entrypoint, before any action runs. */
14
+ export function setProfileOverride(profile) {
15
+ _profileOverride = profile?.trim() || null;
16
+ }
17
+ /** The profile in force: `--profile` beats `BRIDGE_PROFILE`. */
18
+ function activeProfileSelector() {
19
+ if (_profileOverride)
20
+ return _profileOverride;
21
+ return process.env.BRIDGE_PROFILE?.trim() || null;
22
+ }
5
23
  /**
6
24
  * Resolution order:
7
- * 1. `~/.config/bridge/credentials.json` (or `$XDG_CONFIG_HOME/bridge/credentials.json`)
8
- * written by `bridge auth login`. The interactive primary path. Token
9
- * carries the appId baked in by /v1/auth/cli/token, so post-login the
10
- * JWT is the source of truth for which app the CLI operates on.
11
- * 2. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
12
- * credentials file exists typical CI runner shape.
13
- * 3. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
25
+ * 1. `--profile <label|id|name>` / `BRIDGE_PROFILE` a stored credential,
26
+ * named for this one invocation. Never falls back: naming a profile and
27
+ * silently getting a different app is the exact failure TBP-628 exists to
28
+ * stop, so an unknown or expired profile is an error.
29
+ * 2. The ACTIVE credential in `~/.config/bridge/credentials.json` (or
30
+ * `$XDG_CONFIG_HOME/...`), written by `bridge auth login` and moved by
31
+ * `bridge auth use`.
32
+ * 3. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
33
+ * usable credentials file exists — the typical CI runner shape.
34
+ * 4. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
14
35
  *
15
- * Note: credentials-file wins over env so `bridge auth login` does what users
16
- * expect the new login takes effect immediately. CI is unaffected because
17
- * runners typically have no credentials file and fall through to step 2.
36
+ * The credentials file still wins over `BRIDGE_API_KEY`, unchanged, so
37
+ * `bridge auth login` takes effect immediately and CI is unaffected. What HAS
38
+ * changed is that being ignored is now said out loud: `BRIDGE_API_KEY` and
39
+ * `BRIDGE_APP_ID` look like a way to retarget the CLI and are not, and reading
40
+ * that in the output beats discovering it from a write that went to the wrong
41
+ * app (TBP-628).
18
42
  *
19
- * If a credentials file exists but its `expiresAt` is in the past, we fall
20
- * through to env (if set) — same as if there were no file. Otherwise throw a
21
- * friendly error pointing the user back to `bridge auth login`.
43
+ * Every resolution also prints one line to stderr naming the app that is about
44
+ * to answer. See `writeContextBanner`.
22
45
  */
23
46
  export function getManagementClient() {
24
47
  if (_client)
@@ -29,29 +52,56 @@ export function getManagementClient() {
29
52
  let apiKey;
30
53
  let baseUrl;
31
54
  let source;
32
- // 1. Credentials file from `bridge auth login` (interactive primary).
33
- const creds = safeReadCredentials();
34
- if (creds && !isExpired(creds)) {
55
+ let creds = null;
56
+ const selector = activeProfileSelector();
57
+ if (selector) {
58
+ // 1. Explicit profile. Resolve it or fail — no fallback of any kind.
59
+ let entry;
60
+ try {
61
+ entry = findCredential(selector);
62
+ }
63
+ catch (err) {
64
+ if (err instanceof CredentialSelectorError)
65
+ throw new ConfigError(err.message);
66
+ throw err;
67
+ }
68
+ if (isExpired(entry.creds)) {
69
+ throw new ConfigError(`Credential for "${selector}" (${entry.creds.app.name}) expired ` +
70
+ `${entry.creds.expiresAt}. Run \`bridge auth login\` to re-authenticate it. ` +
71
+ 'Refusing to fall back to another app.');
72
+ }
73
+ creds = entry.creds;
35
74
  apiKey = creds.apiKey;
36
- // Env override still wins for baseUrl (useful for hitting a local bridge-api
37
- // with a token issued by prod, or vice versa during dev).
38
75
  baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : creds.baseUrl;
39
- source = 'credentials-file';
40
- }
41
- else if (envApiKey && envApiKey.length > 0) {
42
- // 2. BRIDGE_API_KEY env var (CI / service-account fallback).
43
- apiKey = envApiKey;
44
- baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : DEFAULT_BASE_URL;
45
- source = 'env';
46
- }
47
- else if (creds && isExpired(creds)) {
48
- // 3a. Found a credentials file but token expired; no env fallback either.
49
- throw new ConfigError('Token expired. Run `bridge auth login` to re-authenticate.');
76
+ source = 'profile';
50
77
  }
51
78
  else {
52
- // 3b. No credentials at all.
53
- throw new ConfigError('Not logged in. Run `bridge auth login`.');
79
+ // 2. Active credential from `bridge auth login` / `bridge auth use`.
80
+ const active = safeReadCredentials();
81
+ if (active && !isExpired(active)) {
82
+ creds = active;
83
+ apiKey = active.apiKey;
84
+ // Env override still wins for baseUrl (useful for hitting a local
85
+ // bridge-api with a token issued by prod, or vice versa during dev).
86
+ baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : active.baseUrl;
87
+ source = 'credentials-file';
88
+ }
89
+ else if (envApiKey && envApiKey.length > 0) {
90
+ // 3. BRIDGE_API_KEY env var (CI / service-account fallback).
91
+ apiKey = envApiKey;
92
+ baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : DEFAULT_BASE_URL;
93
+ source = 'env';
94
+ }
95
+ else if (active && isExpired(active)) {
96
+ // 4a. Found a credentials file but token expired; no env fallback either.
97
+ throw new ConfigError('Token expired. Run `bridge auth login` to re-authenticate.');
98
+ }
99
+ else {
100
+ // 4b. No credentials at all.
101
+ throw new ConfigError('Not logged in. Run `bridge auth login`.');
102
+ }
54
103
  }
104
+ writeContextBanner({ creds, source, baseUrl, selector });
55
105
  if (debug) {
56
106
  const baseSource = envBaseUrl && envBaseUrl.length > 0
57
107
  ? 'env'
@@ -63,6 +113,44 @@ export function getManagementClient() {
63
113
  _client = new BridgeManagement({ apiKey, baseUrl, debug });
64
114
  return _client;
65
115
  }
116
+ /**
117
+ * One line on stderr naming the app that is about to answer.
118
+ *
119
+ * On EVERY command, not only writes. The incident behind TBP-628 started with a
120
+ * read: `bridge role list` was believed to describe the local app and described
121
+ * production, and nothing in the output said otherwise. A banner that only
122
+ * appears on writes would not have prevented it, because the wrong belief was
123
+ * already formed by then.
124
+ *
125
+ * stderr, so stdout stays pure JSON for the agents and scripts that parse it.
126
+ * Suppress with `BRIDGE_NO_BANNER=true` — for the one caller who is already
127
+ * certain and is merging the two streams.
128
+ */
129
+ function writeContextBanner(ctx) {
130
+ if (process.env.BRIDGE_NO_BANNER === 'true')
131
+ return;
132
+ const { creds, source, baseUrl, selector } = ctx;
133
+ const who = creds
134
+ ? `${creds.label ?? creds.app.name} (${creds.app.id})`
135
+ : 'BRIDGE_API_KEY (app unknown — the key carries it)';
136
+ const via = source === 'profile'
137
+ ? `--profile ${selector}`
138
+ : source === 'env'
139
+ ? 'BRIDGE_API_KEY'
140
+ : 'saved default';
141
+ process.stderr.write(`bridge: ${who} · ${baseUrl} · via ${via}\n`);
142
+ // The two env vars that look like a way to retarget the CLI and are not.
143
+ // Saying so here, at the moment they are being ignored, is the whole point:
144
+ // the reported incident was a session that set them and believed them.
145
+ if (source !== 'env' && process.env.BRIDGE_API_KEY?.trim()) {
146
+ process.stderr.write('bridge: BRIDGE_API_KEY is set but IGNORED — the credentials file wins. ' +
147
+ 'Use `--profile <label>` to pick a stored app, or `bridge auth logout` to use the key.\n');
148
+ }
149
+ if (process.env.BRIDGE_APP_ID?.trim()) {
150
+ process.stderr.write('bridge: BRIDGE_APP_ID has no effect — the app is carried by the credential itself. ' +
151
+ 'Use `--profile <label|app id>` or `BRIDGE_PROFILE` to target another app.\n');
152
+ }
153
+ }
66
154
  /**
67
155
  * For tests and for `bridge auth logout` / `bridge auth status` — they need
68
156
  * to reset the cached client between operations.
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,eAAe,EAA0B,MAAM,kBAAkB,CAAC;AAEtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAE5D,IAAI,OAAO,GAA4B,IAAI,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,MAAM,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IACrD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAEvD,IAAI,MAAc,CAAC;IACnB,IAAI,OAAe,CAAC;IACpB,IAAI,MAAc,CAAC;IAEnB,sEAAsE;IACtE,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;IACpC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACtB,6EAA6E;QAC7E,0DAA0D;QAC1D,OAAO,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAC3E,MAAM,GAAG,kBAAkB,CAAC;IAC9B,CAAC;SAAM,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,6DAA6D;QAC7D,MAAM,GAAG,SAAS,CAAC;QACnB,OAAO,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC9E,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC;SAAM,IAAI,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,0EAA0E;QAC1E,MAAM,IAAI,WAAW,CACnB,4DAA4D,CAC7D,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,6BAA6B;QAC7B,MAAM,IAAI,WAAW,CAAC,yCAAyC,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,UAAU,GACd,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YACjC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,MAAM,KAAK,KAAK;gBAChB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,kBAAkB,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,sCAAsC,MAAM,aAAa,OAAO,KAAK,UAAU,GAAG,CAAC,CAAC;IACpG,CAAC;IAED,OAAO,GAAG,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAE3D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAA2B;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,WAAW,CACnB,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;;;GAIG;AACH,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,WAAW,CACnB,oCAAoC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI;YACtF,kEAAkE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,21 @@ export interface StoredCredentials {
20
20
  /** Optional human-friendly label set via `bridge auth login --label`. */
21
21
  label?: string;
22
22
  }
23
+ /** Current on-disk shape. See the module docstring for why it is a map. */
24
+ export interface CredentialsFile {
25
+ version: 2;
26
+ /** App id of the credential commands use by default. `null` when empty. */
27
+ active: string | null;
28
+ /** All stored credentials, keyed by `app.id`. */
29
+ credentials: Record<string, StoredCredentials>;
30
+ }
31
+ /** One entry, as `bridge auth status` and the selector logic see it. */
32
+ export interface CredentialEntry {
33
+ /** The map key — always `creds.app.id`. */
34
+ key: string;
35
+ creds: StoredCredentials;
36
+ isActive: boolean;
37
+ }
23
38
  /**
24
39
  * Returns the absolute path to the credentials file based on the current
25
40
  * environment. Does not create directories or files — pure path resolution.
@@ -37,17 +52,65 @@ export interface StoredCredentials {
37
52
  */
38
53
  export declare function credentialsPath(): string;
39
54
  /**
40
- * Reads and parses the credentials file. Returns `null` if the file does not
41
- * exist. Throws if the file exists but is unreadable or contains invalid JSON.
55
+ * Read the whole store, migrating a v1 file in memory. `null` if no file.
56
+ *
57
+ * Throws if the file exists but is unreadable or malformed — a corrupt store is
58
+ * not the same as an absent one, and silently treating it as absent would make
59
+ * `bridge auth status` report "not logged in" to somebody who very much is.
60
+ */
61
+ export declare function readCredentialsFile(): CredentialsFile | null;
62
+ /**
63
+ * The credential commands act on by default: the active one.
64
+ *
65
+ * Kept with its original name and signature because every existing caller wants
66
+ * exactly this, and because "which credential is in force" is a question with
67
+ * one answer whether the file holds one app or ten.
42
68
  */
43
69
  export declare function readCredentials(): StoredCredentials | null;
70
+ /** Every stored credential, active one first, then by app name. */
71
+ export declare function listCredentials(): CredentialEntry[];
72
+ /** Raised when a selector matches nothing, or matches more than one entry. */
73
+ export declare class CredentialSelectorError extends Error {
74
+ constructor(message: string);
75
+ }
76
+ /**
77
+ * Find one stored credential by label, app id, or app name.
78
+ *
79
+ * Label first: users think in environments, not in 24-character object ids, and
80
+ * `--label` exists precisely so they can name one. App id is exact and always
81
+ * works. App name is last because two apps may share one.
82
+ *
83
+ * An ambiguous selector is an ERROR, never a first match. Picking one of two
84
+ * candidate apps silently is the whole failure mode this ticket is about.
85
+ */
86
+ export declare function findCredential(selector: string): CredentialEntry;
44
87
  /**
45
- * Writes the credentials atomically with mode 0600. Creates the parent
46
- * directory with mode 0700 if it does not exist.
88
+ * Upsert a credential by app id and make it active.
89
+ *
90
+ * Same name and signature as before: `bridge auth login` still ends with one
91
+ * call, and still leaves the app it just authorised in force.
47
92
  */
48
93
  export declare function writeCredentials(creds: StoredCredentials): void;
94
+ /** Point the persisted default at an already-stored credential. Offline. */
95
+ export declare function setActiveCredential(key: string): void;
96
+ /** Persist the store atomically with mode 0600, dir 0700. */
97
+ export declare function writeCredentialsFile(file: CredentialsFile): void;
49
98
  /**
50
- * Deletes the credentials file. No-op if it does not exist.
99
+ * Remove ONE credential. Deletes the file entirely when it was the last.
100
+ *
101
+ * Returns the remaining count so a caller can tell the user what is left.
102
+ * Removing the active one moves `active` to another entry rather than leaving a
103
+ * dangling pointer — with credentials still stored, "logged out of everything"
104
+ * would be a lie.
105
+ */
106
+ export declare function removeCredential(key: string): number;
107
+ /** Delete the whole credentials file. No-op if it does not exist. */
108
+ export declare function deleteAllCredentials(): void;
109
+ /**
110
+ * Back-compat alias for the single-app era: remove the active credential.
111
+ *
112
+ * @deprecated Prefer `removeCredential(key)` or `deleteAllCredentials()`, which
113
+ * say which of the two things they do.
51
114
  */
52
115
  export declare function deleteCredentials(): void;
53
116
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,qCAAqC;IACrC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAQxC;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAiB1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CA4B/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAInF"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AA6CA,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,qCAAqC;IACrC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAChD;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAQxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,eAAe,GAAG,IAAI,CAyB5D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAU1D;AAED,mEAAmE;AACnE,wBAAgB,eAAe,IAAI,eAAe,EAAE,CASnD;AAED,8EAA8E;AAC9E,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAmChE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAK/D;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,6DAA6D;AAC7D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA4BhE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,IAAI,IAAI,CAQ3C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAOxC;AAsBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAInF"}
@@ -10,6 +10,34 @@
10
10
  * 2. `~/.config/bridge/credentials.json` otherwise
11
11
  *
12
12
  * File mode: 0600 (owner read/write only). Containing dir created with 0700.
13
+ *
14
+ * ## The file holds MANY apps (TBP-628)
15
+ *
16
+ * It used to hold exactly one. Anyone running the same product as several apps
17
+ * — one appId per environment — had to `logout` + `login` through the browser
18
+ * to move between them, even though the token they already held had days left
19
+ * on it. Worse, nothing in a read command's output said which app answered, so
20
+ * a session holding a prod token could run `role list` believing it described
21
+ * local, and the next step would have rewritten production roles.
22
+ *
23
+ * So the on-disk shape is now a map keyed by app id, plus a pointer at the
24
+ * active one:
25
+ *
26
+ * ```json
27
+ * {
28
+ * "version": 2,
29
+ * "active": "606b4416fabdc800087d09ec",
30
+ * "credentials": { "606b4416fabdc800087d09ec": { …StoredCredentials } }
31
+ * }
32
+ * ```
33
+ *
34
+ * Keyed by app id, not by label: the label is optional and user-chosen, so it
35
+ * is a fine way to SELECT a credential and a bad way to key one.
36
+ *
37
+ * A v1 file (a bare `StoredCredentials` object) is migrated on read, in memory
38
+ * only. Reading never rewrites the file — a read command must not mutate state
39
+ * another process is reading. The v2 shape is persisted the next time
40
+ * something writes.
13
41
  */
14
42
  import * as fs from 'node:fs';
15
43
  import * as path from 'node:path';
@@ -39,10 +67,13 @@ export function credentialsPath() {
39
67
  return path.join(base, '.config', 'bridge', 'credentials.json');
40
68
  }
41
69
  /**
42
- * Reads and parses the credentials file. Returns `null` if the file does not
43
- * exist. Throws if the file exists but is unreadable or contains invalid JSON.
70
+ * Read the whole store, migrating a v1 file in memory. `null` if no file.
71
+ *
72
+ * Throws if the file exists but is unreadable or malformed — a corrupt store is
73
+ * not the same as an absent one, and silently treating it as absent would make
74
+ * `bridge auth status` report "not logged in" to somebody who very much is.
44
75
  */
45
- export function readCredentials() {
76
+ export function readCredentialsFile() {
46
77
  const filePath = credentialsPath();
47
78
  if (!fs.existsSync(filePath))
48
79
  return null;
@@ -54,16 +85,120 @@ export function readCredentials() {
54
85
  catch {
55
86
  throw new Error(`Credentials file at ${filePath} is not valid JSON.`);
56
87
  }
57
- if (!isStoredCredentials(parsed)) {
58
- throw new Error(`Credentials file at ${filePath} is missing required fields.`);
88
+ // v2 — the current shape.
89
+ if (isCredentialsFile(parsed))
90
+ return parsed;
91
+ // v1 — a bare StoredCredentials object. Migrate in memory; do NOT write.
92
+ if (isStoredCredentials(parsed)) {
93
+ return {
94
+ version: 2,
95
+ active: parsed.app.id,
96
+ credentials: { [parsed.app.id]: parsed },
97
+ };
59
98
  }
60
- return parsed;
99
+ throw new Error(`Credentials file at ${filePath} is missing required fields.`);
61
100
  }
62
101
  /**
63
- * Writes the credentials atomically with mode 0600. Creates the parent
64
- * directory with mode 0700 if it does not exist.
102
+ * The credential commands act on by default: the active one.
103
+ *
104
+ * Kept with its original name and signature because every existing caller wants
105
+ * exactly this, and because "which credential is in force" is a question with
106
+ * one answer whether the file holds one app or ten.
107
+ */
108
+ export function readCredentials() {
109
+ const file = readCredentialsFile();
110
+ if (!file)
111
+ return null;
112
+ if (file.active && file.credentials[file.active])
113
+ return file.credentials[file.active];
114
+ // A pointer at a credential that is gone. Fall back to the only entry if
115
+ // there is exactly one — otherwise there is no defensible default, and
116
+ // guessing would pick an app on the user's behalf, which is the failure this
117
+ // ticket exists to stop.
118
+ const keys = Object.keys(file.credentials);
119
+ return keys.length === 1 ? file.credentials[keys[0]] : null;
120
+ }
121
+ /** Every stored credential, active one first, then by app name. */
122
+ export function listCredentials() {
123
+ const file = readCredentialsFile();
124
+ if (!file)
125
+ return [];
126
+ return Object.entries(file.credentials)
127
+ .map(([key, creds]) => ({ key, creds, isActive: key === file.active }))
128
+ .sort((a, b) => {
129
+ if (a.isActive !== b.isActive)
130
+ return a.isActive ? -1 : 1;
131
+ return a.creds.app.name.localeCompare(b.creds.app.name);
132
+ });
133
+ }
134
+ /** Raised when a selector matches nothing, or matches more than one entry. */
135
+ export class CredentialSelectorError extends Error {
136
+ constructor(message) {
137
+ super(message);
138
+ this.name = 'CredentialSelectorError';
139
+ }
140
+ }
141
+ /**
142
+ * Find one stored credential by label, app id, or app name.
143
+ *
144
+ * Label first: users think in environments, not in 24-character object ids, and
145
+ * `--label` exists precisely so they can name one. App id is exact and always
146
+ * works. App name is last because two apps may share one.
147
+ *
148
+ * An ambiguous selector is an ERROR, never a first match. Picking one of two
149
+ * candidate apps silently is the whole failure mode this ticket is about.
150
+ */
151
+ export function findCredential(selector) {
152
+ const needle = selector.trim();
153
+ if (!needle)
154
+ throw new CredentialSelectorError('Empty profile selector.');
155
+ const entries = listCredentials();
156
+ if (entries.length === 0) {
157
+ throw new CredentialSelectorError('No stored credentials. Run `bridge auth login` first.');
158
+ }
159
+ const lower = needle.toLowerCase();
160
+ const byLabel = entries.filter((e) => e.creds.label?.toLowerCase() === lower);
161
+ const byId = entries.filter((e) => e.key === needle);
162
+ const byName = entries.filter((e) => e.creds.app.name.toLowerCase() === lower);
163
+ for (const [what, matches] of [
164
+ ['label', byLabel],
165
+ ['app id', byId],
166
+ ['app name', byName],
167
+ ]) {
168
+ if (matches.length === 1)
169
+ return matches[0];
170
+ if (matches.length > 1) {
171
+ throw new CredentialSelectorError(`"${needle}" matches ${matches.length} stored credentials by ${what} ` +
172
+ `(${matches.map((m) => m.key).join(', ')}). Select by app id instead.`);
173
+ }
174
+ }
175
+ throw new CredentialSelectorError(`No stored credential matches "${needle}". Known: ` +
176
+ entries.map((e) => e.creds.label ?? e.creds.app.name).join(', ') +
177
+ '. Run `bridge auth status` to see them all.');
178
+ }
179
+ /**
180
+ * Upsert a credential by app id and make it active.
181
+ *
182
+ * Same name and signature as before: `bridge auth login` still ends with one
183
+ * call, and still leaves the app it just authorised in force.
65
184
  */
66
185
  export function writeCredentials(creds) {
186
+ const file = readCredentialsFileOrEmpty();
187
+ file.credentials[creds.app.id] = creds;
188
+ file.active = creds.app.id;
189
+ writeCredentialsFile(file);
190
+ }
191
+ /** Point the persisted default at an already-stored credential. Offline. */
192
+ export function setActiveCredential(key) {
193
+ const file = readCredentialsFileOrEmpty();
194
+ if (!file.credentials[key]) {
195
+ throw new CredentialSelectorError(`No stored credential with app id ${key}.`);
196
+ }
197
+ file.active = key;
198
+ writeCredentialsFile(file);
199
+ }
200
+ /** Persist the store atomically with mode 0600, dir 0700. */
201
+ export function writeCredentialsFile(file) {
67
202
  const filePath = credentialsPath();
68
203
  const dir = path.dirname(filePath);
69
204
  // Create dir with restrictive perms. mkdirSync `mode` is masked by umask, so
@@ -80,7 +215,7 @@ export function writeCredentials(creds) {
80
215
  const tmpPath = `${filePath}.${process.pid}.tmp`;
81
216
  const fd = fs.openSync(tmpPath, 'w', 0o600);
82
217
  try {
83
- fs.writeFileSync(fd, JSON.stringify(creds, null, 2) + '\n');
218
+ fs.writeFileSync(fd, JSON.stringify(file, null, 2) + '\n');
84
219
  }
85
220
  finally {
86
221
  fs.closeSync(fd);
@@ -94,9 +229,28 @@ export function writeCredentials(creds) {
94
229
  fs.renameSync(tmpPath, filePath);
95
230
  }
96
231
  /**
97
- * Deletes the credentials file. No-op if it does not exist.
232
+ * Remove ONE credential. Deletes the file entirely when it was the last.
233
+ *
234
+ * Returns the remaining count so a caller can tell the user what is left.
235
+ * Removing the active one moves `active` to another entry rather than leaving a
236
+ * dangling pointer — with credentials still stored, "logged out of everything"
237
+ * would be a lie.
98
238
  */
99
- export function deleteCredentials() {
239
+ export function removeCredential(key) {
240
+ const file = readCredentialsFileOrEmpty();
241
+ delete file.credentials[key];
242
+ const remaining = Object.keys(file.credentials);
243
+ if (remaining.length === 0) {
244
+ deleteAllCredentials();
245
+ return 0;
246
+ }
247
+ if (file.active === key)
248
+ file.active = remaining[0];
249
+ writeCredentialsFile(file);
250
+ return remaining.length;
251
+ }
252
+ /** Delete the whole credentials file. No-op if it does not exist. */
253
+ export function deleteAllCredentials() {
100
254
  const filePath = credentialsPath();
101
255
  try {
102
256
  fs.unlinkSync(filePath);
@@ -107,6 +261,43 @@ export function deleteCredentials() {
107
261
  throw err;
108
262
  }
109
263
  }
264
+ /**
265
+ * Back-compat alias for the single-app era: remove the active credential.
266
+ *
267
+ * @deprecated Prefer `removeCredential(key)` or `deleteAllCredentials()`, which
268
+ * say which of the two things they do.
269
+ */
270
+ export function deleteCredentials() {
271
+ const file = readCredentialsFileOrEmpty();
272
+ if (file.active) {
273
+ removeCredential(file.active);
274
+ return;
275
+ }
276
+ deleteAllCredentials();
277
+ }
278
+ /** The store, or an empty one — for the write paths, which create on demand. */
279
+ function readCredentialsFileOrEmpty() {
280
+ try {
281
+ return readCredentialsFile() ?? { version: 2, active: null, credentials: {} };
282
+ }
283
+ catch {
284
+ // A corrupt file must not wedge `login` — overwriting it is how the user
285
+ // gets unstuck, and the token in it is unusable anyway.
286
+ return { version: 2, active: null, credentials: {} };
287
+ }
288
+ }
289
+ function isCredentialsFile(value) {
290
+ if (!value || typeof value !== 'object')
291
+ return false;
292
+ const v = value;
293
+ if (v.version !== 2)
294
+ return false;
295
+ if (v.active !== null && typeof v.active !== 'string')
296
+ return false;
297
+ if (!v.credentials || typeof v.credentials !== 'object')
298
+ return false;
299
+ return Object.values(v.credentials).every(isStoredCredentials);
300
+ }
110
301
  /**
111
302
  * True if the credentials' `expiresAt` is in the past relative to `now`.
112
303
  */
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebulr-group/bridge-cli",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "Bridge platform CLI for AI coding agents and developers",
5
5
  "author": "Nebulr Group",
6
6
  "license": "MIT",