@hasna/accounts 0.1.2 → 0.1.4

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
@@ -37,10 +37,8 @@ accounts add work --email work@company.com
37
37
  accounts add personal --email me@gmail.com
38
38
 
39
39
  # 3. Log in once per profile (isolated dir)
40
- accounts login work # run /login inside Claude, then /exit
41
- accounts detect work
42
- accounts login personal
43
- accounts detect personal
40
+ accounts login work # run /login inside Claude, then /exit; accounts auto-applies it
41
+ accounts login personal # same: login, exit; it becomes the live/default account
44
42
 
45
43
  # 4. Switch
46
44
  accounts apply work --tool claude # Cursor / VS Code — live ~/.claude auth
@@ -51,8 +49,10 @@ accounts launch work --tool claude
51
49
  eval "$(accounts env personal --tool claude)" # other terminal
52
50
  ```
53
51
 
54
- Do **not** run `accounts apply` until after `accounts login` and `accounts detect` — apply
55
- refuses profiles without an auth snapshot so live OAuth is not wiped.
52
+ After `accounts login <name> --tool claude`, `accounts` snapshots the auth Claude
53
+ wrote, updates the detected email, and applies that profile to live `~/.claude`
54
+ paths automatically. `accounts apply` still refuses profiles without auth so live
55
+ OAuth is not wiped.
56
56
 
57
57
  ## Three pointers (active, applied, isolated)
58
58
 
@@ -91,6 +91,7 @@ Implementation details: [docs/IMPLEMENT.md](docs/IMPLEMENT.md).
91
91
  | `accounts login <name> --tool <tool>` | Launch the tool's login flow in an isolated profile dir. |
92
92
  | `accounts apply <name> --tool claude` | Apply profile auth to live Claude paths (requires snapshot; Claude-only). |
93
93
  | `accounts pick` | Interactive picker; default applies. `--env`, `--no-act`. |
94
+ | `accounts switch <name> --tool <tool>` | Switch profile and print a restart/resume command. Add `--resume`; add `--launch` to run it. |
94
95
  | `accounts use <name> --tool <tool>` | Mark profile active; prints apply/env hints. |
95
96
  | `accounts list` (`ls`) | List profiles (`●` active, `◉` applied, `●◉` both). |
96
97
  | `accounts show <name> --tool <tool>` | Profile details including active/applied flags. |
@@ -108,6 +109,36 @@ Implementation details: [docs/IMPLEMENT.md](docs/IMPLEMENT.md).
108
109
 
109
110
  See `accounts --help` for `set`, `rename`, `remove`, `tools`, etc.
110
111
 
112
+ ## Agent / MCP Switching
113
+
114
+ `accounts` ships a stdio MCP server:
115
+
116
+ ```bash
117
+ accounts-mcp
118
+ ```
119
+
120
+ Add it to Claude/Codex/opencode/Cursor MCP config as a command server named
121
+ `accounts`. It exposes:
122
+
123
+ - `list_tools`
124
+ - `list_profiles`
125
+ - `current_profile`
126
+ - `switch_profile`
127
+
128
+ `switch_profile` applies Claude live auth when the target profile is Claude and
129
+ returns a restart handoff command. MCP servers cannot safely kill their parent
130
+ agent process, so the tool returns an instruction such as: exit this session and
131
+ run `CLAUDE_CONFIG_DIR=... claude --continue`.
132
+
133
+ Human equivalent:
134
+
135
+ ```bash
136
+ accounts switch account001 --tool claude --resume
137
+ accounts switch account001 --tool claude --resume --launch
138
+ accounts switch codex-work --tool codex --resume
139
+ accounts switch ops --tool opencode --resume
140
+ ```
141
+
111
142
  ## Shell hook (optional)
112
143
 
113
144
  ```bash
package/dist/cli.js CHANGED
@@ -6577,6 +6577,7 @@ var toolDefSchema = exports_external.object({
6577
6577
  bin: exports_external.string().min(1),
6578
6578
  loginArgs: exports_external.array(exports_external.string()).optional(),
6579
6579
  loginHint: exports_external.string().optional(),
6580
+ resumeArgs: exports_external.array(exports_external.string()).optional(),
6580
6581
  accountFile: exports_external.string().optional(),
6581
6582
  emailPath: exports_external.array(exports_external.string()).optional()
6582
6583
  });
@@ -6745,6 +6746,7 @@ var BUILTIN_TOOLS = [
6745
6746
  defaultDir: join2(homedir2(), ".claude"),
6746
6747
  bin: "claude",
6747
6748
  loginHint: "run /login inside Claude, then /exit when done",
6749
+ resumeArgs: ["--continue"],
6748
6750
  accountFile: ".claude.json",
6749
6751
  emailPath: ["oauthAccount", "emailAddress"]
6750
6752
  },
@@ -6755,7 +6757,8 @@ var BUILTIN_TOOLS = [
6755
6757
  defaultDir: join2(homedir2(), ".codex"),
6756
6758
  bin: "codex",
6757
6759
  loginArgs: ["login"],
6758
- loginHint: "complete the Codex login flow for this CODEX_HOME"
6760
+ loginHint: "complete the Codex login flow for this CODEX_HOME",
6761
+ resumeArgs: ["resume", "--last"]
6759
6762
  },
6760
6763
  {
6761
6764
  id: "opencode",
@@ -6768,7 +6771,8 @@ var BUILTIN_TOOLS = [
6768
6771
  defaultDir: join2(homedir2(), ".config", "opencode"),
6769
6772
  bin: "opencode",
6770
6773
  loginArgs: ["auth", "login"],
6771
- loginHint: "complete opencode auth login for this isolated config/data root"
6774
+ loginHint: "complete opencode auth login for this isolated config/data root",
6775
+ resumeArgs: ["--continue"]
6772
6776
  },
6773
6777
  {
6774
6778
  id: "cursor",
@@ -7248,8 +7252,8 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
7248
7252
  writeJsonFile(profileKeychainSnapshot(profileDir), kc, profileDir);
7249
7253
  }
7250
7254
  }
7251
- function ensureProfileAuthSnapshot(profileDir, tool) {
7252
- if (hasAuthSnapshot(profileDir))
7255
+ function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
7256
+ if (!opts.overwrite && hasAuthSnapshot(profileDir))
7253
7257
  return;
7254
7258
  const authDir = profileAuthDir(profileDir);
7255
7259
  assertSafeWritePath(join6(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
@@ -7561,6 +7565,64 @@ function formatExportLines(env2) {
7561
7565
  `);
7562
7566
  }
7563
7567
 
7568
+ // src/lib/login.ts
7569
+ function finalizeLogin(name, toolId) {
7570
+ const profile = getProfile(name, toolId);
7571
+ const tool = getTool(profile.tool);
7572
+ if (tool.id === "claude") {
7573
+ ensureProfileAuthSnapshot(profile.dir, tool, { overwrite: true });
7574
+ redetectEmail(name, tool.id);
7575
+ return { profile: applyProfile(name, tool.id).profile, applied: true };
7576
+ }
7577
+ const updated = redetectEmail(name, tool.id);
7578
+ useProfile(name, tool.id);
7579
+ return { profile: updated, applied: false };
7580
+ }
7581
+
7582
+ // src/lib/switch.ts
7583
+ function shellQuote(value) {
7584
+ if (/^[A-Za-z0-9_./:=@+-]+$/.test(value))
7585
+ return value;
7586
+ return `'${value.replaceAll("'", "'\\''")}'`;
7587
+ }
7588
+ function commandLine(env2, command) {
7589
+ return `${formatEnvAssignments(env2)} ${command.map(shellQuote).join(" ")}`.trim();
7590
+ }
7591
+ function commandFor(tool, opts) {
7592
+ return [tool.bin, ...opts.resume ? tool.resumeArgs ?? [] : [], ...opts.args ?? []];
7593
+ }
7594
+ function switchProfile(name, opts = {}) {
7595
+ const profile = getProfile(name, opts.tool);
7596
+ const tool = getTool(profile.tool);
7597
+ const mode = opts.mode ?? "auto";
7598
+ if (!["auto", "apply", "env", "active"].includes(mode)) {
7599
+ throw new AccountsError(`invalid switch mode "${mode}"`);
7600
+ }
7601
+ const env2 = profileEnv(profile, tool);
7602
+ let applied = false;
7603
+ if (mode === "apply" || mode === "auto" && tool.id === "claude") {
7604
+ applyProfile(name, tool.id);
7605
+ applied = true;
7606
+ } else {
7607
+ useProfile(name, tool.id);
7608
+ }
7609
+ const command = commandFor(tool, opts);
7610
+ const restartRequired = opts.resume === true || applied || mode === "env";
7611
+ const message = applied ? `${profile.name} is now the live/default ${tool.label} profile` : `${profile.name} is now the active ${tool.label} profile`;
7612
+ return {
7613
+ profile: getProfile(name, tool.id),
7614
+ tool,
7615
+ applied,
7616
+ active: true,
7617
+ env: env2,
7618
+ exports: formatExportLines(env2),
7619
+ command,
7620
+ commandLine: commandLine(env2, command),
7621
+ restartRequired,
7622
+ message
7623
+ };
7624
+ }
7625
+
7564
7626
  // src/cli.ts
7565
7627
  var program2 = new Command;
7566
7628
  function die(message) {
@@ -7670,15 +7732,23 @@ program2.command("login").argument("<name>", "profile name").description("launch
7670
7732
  console.log(source_default.dim(` config dir: ${profile.dir}`));
7671
7733
  console.log(source_default.dim(` env: ${formatEnvAssignments(env2)}`));
7672
7734
  console.log(source_default.yellow(` ${tool.loginHint ?? "complete the login flow, then exit when done"}`));
7673
- const next = tool.id === "claude" ? `accounts detect ${name} --tool ${tool.id} && accounts apply ${name} --tool ${tool.id}` : `accounts detect ${name} --tool ${tool.id}`;
7674
- console.log(source_default.dim(` Then: ${next}`));
7735
+ if (tool.id === "claude") {
7736
+ console.log(source_default.dim(" After Claude exits, accounts will make this the live/default Claude account."));
7737
+ }
7675
7738
  const res = spawnSync(tool.bin, loginArgs, {
7676
7739
  stdio: "inherit",
7677
7740
  env: { ...process.env, ...env2 }
7678
7741
  });
7679
7742
  if (res.error)
7680
7743
  die(`failed to launch ${tool.bin}: ${res.error.message}`);
7681
- process.exit(res.status ?? 0);
7744
+ if ((res.status ?? 0) !== 0)
7745
+ process.exit(res.status ?? 1);
7746
+ const finalized = finalizeLogin(name, tool.id);
7747
+ if (finalized.applied) {
7748
+ console.log(source_default.green(`✓ ${source_default.bold(name)} is now the live/default ${tool.label} account`));
7749
+ } else {
7750
+ console.log(source_default.green(`✓ ${source_default.bold(name)} login finished and profile is active`));
7751
+ }
7682
7752
  }));
7683
7753
  program2.command("pick").description("interactively choose a profile (default: mark active and apply to live Claude paths)").option("-t, --tool <tool>", "filter by tool", DEFAULT_TOOL).option("--env", "print env export after selection instead of apply").option("--no-act", "only mark active (store current); do not apply or print env").action(action(async (opts) => {
7684
7754
  const result = await pickProfile({ tool: opts.tool, mode: resolvePickMode(opts) });
@@ -7708,6 +7778,30 @@ program2.command("applied").argument("[tool]", "tool id (default: claude)").desc
7708
7778
  die(`no applied profile for "${tool}". Run \`accounts apply <name>\` first.`);
7709
7779
  console.log(p.name);
7710
7780
  }));
7781
+ program2.command("switch").argument("<name>", "profile name").argument("[args...]", "extra args passed when printing/launching the tool").description("switch to a profile and print a restart/resume command; use --launch to run it").option("-t, --tool <tool>", "tool when the profile name exists for multiple tools").option("--mode <mode>", "switch mode: auto, apply, env, active", "auto").option("--resume", "include the tool's resume/continue args in the handoff command").option("--launch", "launch the tool after switching").option("--json", "output JSON").action(action((name, args, opts) => {
7782
+ const result = switchProfile(name, { tool: opts.tool, mode: opts.mode, resume: opts.resume, args });
7783
+ if (opts.json) {
7784
+ console.log(JSON.stringify(result, null, 2));
7785
+ } else {
7786
+ console.log(source_default.green(`✓ ${result.message}`));
7787
+ if (result.applied)
7788
+ console.log(source_default.dim(" live/default auth updated"));
7789
+ console.log(source_default.dim(` restart command: ${result.commandLine}`));
7790
+ if (!opts.launch) {
7791
+ console.log(source_default.yellow(" Exit the current agent session, then run the restart command above."));
7792
+ }
7793
+ }
7794
+ if (opts.launch) {
7795
+ const [bin, ...launchArgs] = result.command;
7796
+ const res = spawnSync(bin, launchArgs, {
7797
+ stdio: "inherit",
7798
+ env: { ...process.env, ...result.env }
7799
+ });
7800
+ if (res.error)
7801
+ die(`failed to launch ${bin}: ${res.error.message}`);
7802
+ process.exit(res.status ?? 0);
7803
+ }
7804
+ }));
7711
7805
  var hook = program2.command("hook").description("install a shell wrapper for claude");
7712
7806
  hook.command("install").description(`write ${join10(accountsHome(), "claude-hook.sh")}`).action(action(() => {
7713
7807
  const { path, created } = installHook();
package/dist/index.d.ts CHANGED
@@ -8,6 +8,10 @@ export type { AddOptions, RemoveOptions, UpdateOptions } from "./lib/profiles.js
8
8
  export { applyProfile, appliedProfile } from "./lib/apply.js";
9
9
  export { importProfile, ensureProfileForLogin } from "./lib/import-profile.js";
10
10
  export type { ImportOptions } from "./lib/import-profile.js";
11
+ export { finalizeLogin } from "./lib/login.js";
12
+ export type { FinalizeLoginResult } from "./lib/login.js";
13
+ export { switchProfile } from "./lib/switch.js";
14
+ export type { SwitchMode, SwitchOptions, SwitchResult } from "./lib/switch.js";
11
15
  export { pickProfile } from "./lib/pick.js";
12
16
  export type { PickOptions, PickResult } from "./lib/pick.js";
13
17
  export { installHook, uninstallHook, hookPath, hookScript, shellSnippet } from "./lib/hook.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,EACL,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,EACzB,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,EACL,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,EACzB,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -3998,6 +3998,7 @@ var toolDefSchema = exports_external.object({
3998
3998
  bin: exports_external.string().min(1),
3999
3999
  loginArgs: exports_external.array(exports_external.string()).optional(),
4000
4000
  loginHint: exports_external.string().optional(),
4001
+ resumeArgs: exports_external.array(exports_external.string()).optional(),
4001
4002
  accountFile: exports_external.string().optional(),
4002
4003
  emailPath: exports_external.array(exports_external.string()).optional()
4003
4004
  });
@@ -4162,6 +4163,7 @@ var BUILTIN_TOOLS = [
4162
4163
  defaultDir: join2(homedir2(), ".claude"),
4163
4164
  bin: "claude",
4164
4165
  loginHint: "run /login inside Claude, then /exit when done",
4166
+ resumeArgs: ["--continue"],
4165
4167
  accountFile: ".claude.json",
4166
4168
  emailPath: ["oauthAccount", "emailAddress"]
4167
4169
  },
@@ -4172,7 +4174,8 @@ var BUILTIN_TOOLS = [
4172
4174
  defaultDir: join2(homedir2(), ".codex"),
4173
4175
  bin: "codex",
4174
4176
  loginArgs: ["login"],
4175
- loginHint: "complete the Codex login flow for this CODEX_HOME"
4177
+ loginHint: "complete the Codex login flow for this CODEX_HOME",
4178
+ resumeArgs: ["resume", "--last"]
4176
4179
  },
4177
4180
  {
4178
4181
  id: "opencode",
@@ -4185,7 +4188,8 @@ var BUILTIN_TOOLS = [
4185
4188
  defaultDir: join2(homedir2(), ".config", "opencode"),
4186
4189
  bin: "opencode",
4187
4190
  loginArgs: ["auth", "login"],
4188
- loginHint: "complete opencode auth login for this isolated config/data root"
4191
+ loginHint: "complete opencode auth login for this isolated config/data root",
4192
+ resumeArgs: ["--continue"]
4189
4193
  },
4190
4194
  {
4191
4195
  id: "cursor",
@@ -4687,8 +4691,8 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
4687
4691
  function snapshotClaudeAuthToProfile(profileDir, tool) {
4688
4692
  snapshotLiveAuthToProfile(profileDir, tool);
4689
4693
  }
4690
- function ensureProfileAuthSnapshot(profileDir, tool) {
4691
- if (hasAuthSnapshot(profileDir))
4694
+ function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
4695
+ if (!opts.overwrite && hasAuthSnapshot(profileDir))
4692
4696
  return;
4693
4697
  const authDir = profileAuthDir(profileDir);
4694
4698
  assertSafeWritePath(join6(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
@@ -4878,6 +4882,62 @@ function findProfileByName(name, toolId) {
4878
4882
  throw err;
4879
4883
  }
4880
4884
  }
4885
+ // src/lib/login.ts
4886
+ function finalizeLogin(name, toolId) {
4887
+ const profile = getProfile(name, toolId);
4888
+ const tool = getTool(profile.tool);
4889
+ if (tool.id === "claude") {
4890
+ ensureProfileAuthSnapshot(profile.dir, tool, { overwrite: true });
4891
+ redetectEmail(name, tool.id);
4892
+ return { profile: applyProfile(name, tool.id).profile, applied: true };
4893
+ }
4894
+ const updated = redetectEmail(name, tool.id);
4895
+ useProfile(name, tool.id);
4896
+ return { profile: updated, applied: false };
4897
+ }
4898
+ // src/lib/switch.ts
4899
+ function shellQuote(value) {
4900
+ if (/^[A-Za-z0-9_./:=@+-]+$/.test(value))
4901
+ return value;
4902
+ return `'${value.replaceAll("'", "'\\''")}'`;
4903
+ }
4904
+ function commandLine(env, command) {
4905
+ return `${formatEnvAssignments(env)} ${command.map(shellQuote).join(" ")}`.trim();
4906
+ }
4907
+ function commandFor(tool, opts) {
4908
+ return [tool.bin, ...opts.resume ? tool.resumeArgs ?? [] : [], ...opts.args ?? []];
4909
+ }
4910
+ function switchProfile(name, opts = {}) {
4911
+ const profile = getProfile(name, opts.tool);
4912
+ const tool = getTool(profile.tool);
4913
+ const mode = opts.mode ?? "auto";
4914
+ if (!["auto", "apply", "env", "active"].includes(mode)) {
4915
+ throw new AccountsError(`invalid switch mode "${mode}"`);
4916
+ }
4917
+ const env = profileEnv(profile, tool);
4918
+ let applied = false;
4919
+ if (mode === "apply" || mode === "auto" && tool.id === "claude") {
4920
+ applyProfile(name, tool.id);
4921
+ applied = true;
4922
+ } else {
4923
+ useProfile(name, tool.id);
4924
+ }
4925
+ const command = commandFor(tool, opts);
4926
+ const restartRequired = opts.resume === true || applied || mode === "env";
4927
+ const message = applied ? `${profile.name} is now the live/default ${tool.label} profile` : `${profile.name} is now the active ${tool.label} profile`;
4928
+ return {
4929
+ profile: getProfile(name, tool.id),
4930
+ tool,
4931
+ applied,
4932
+ active: true,
4933
+ env,
4934
+ exports: formatExportLines(env),
4935
+ command,
4936
+ commandLine: commandLine(env, command),
4937
+ restartRequired,
4938
+ message
4939
+ };
4940
+ }
4881
4941
  // src/lib/pick.ts
4882
4942
  import * as readline from "node:readline/promises";
4883
4943
  import { stdin as input, stdout as output } from "node:process";
@@ -4977,6 +5037,7 @@ export {
4977
5037
  updateProfile,
4978
5038
  uninstallHook,
4979
5039
  toolDefSchema,
5040
+ switchProfile,
4980
5041
  storeSchema,
4981
5042
  storePath,
4982
5043
  snapshotLiveAuthToProfile,
@@ -5011,6 +5072,7 @@ export {
5011
5072
  formatExportLines,
5012
5073
  formatEnvAssignments,
5013
5074
  findProfile,
5075
+ finalizeLogin,
5014
5076
  expandPath,
5015
5077
  ensureProfileForLogin,
5016
5078
  ensureProfileAuthSnapshot,
@@ -4,7 +4,9 @@ export declare function snapshotLiveAuthToProfile(profileDir: string, _tool: Too
4
4
  /** @deprecated Use snapshotLiveAuthToProfile */
5
5
  export declare function snapshotClaudeAuthToProfile(profileDir: string, tool: ToolDef): void;
6
6
  /** Build auth snapshots from files already present in the profile config dir. */
7
- export declare function ensureProfileAuthSnapshot(profileDir: string, tool: ToolDef): void;
7
+ export declare function ensureProfileAuthSnapshot(profileDir: string, tool: ToolDef, opts?: {
8
+ overwrite?: boolean;
9
+ }): void;
8
10
  export declare function profileHasAuth(profileDir: string, tool: ToolDef): boolean;
9
11
  /** Restore profile auth snapshots onto live Claude paths. */
10
12
  export declare function restoreClaudeAuthFromProfile(profileDir: string, tool: ToolDef, profileName?: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"claude-auth.d.ts","sourceRoot":"","sources":["../../src/lib/claude-auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA2E3C,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAmBlF;AAED,gDAAgD;AAChD,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAejF;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAEzE;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAqDN;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAM3D"}
1
+ {"version":3,"file":"claude-auth.d.ts","sourceRoot":"","sources":["../../src/lib/claude-auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA2E3C,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAmBlF;AAED,gDAAgD;AAChD,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,IAAI,CAeN;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAEzE;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAqDN;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAM3D"}
@@ -0,0 +1,12 @@
1
+ import type { Profile } from "../types.js";
2
+ export interface FinalizeLoginResult {
3
+ profile: Profile;
4
+ applied: boolean;
5
+ }
6
+ /**
7
+ * Finish an isolated login after the tool process exits successfully.
8
+ * Claude login becomes the live/default account; other tools are marked active
9
+ * and have metadata re-detected where possible.
10
+ */
11
+ export declare function finalizeLogin(name: string, toolId?: string): FinalizeLoginResult;
12
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/lib/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAM3C,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAahF"}
@@ -0,0 +1,22 @@
1
+ import type { Profile, ToolDef } from "../types.js";
2
+ export type SwitchMode = "auto" | "apply" | "env" | "active";
3
+ export interface SwitchOptions {
4
+ tool?: string;
5
+ mode?: SwitchMode;
6
+ resume?: boolean;
7
+ args?: string[];
8
+ }
9
+ export interface SwitchResult {
10
+ profile: Profile;
11
+ tool: ToolDef;
12
+ applied: boolean;
13
+ active: boolean;
14
+ env: Record<string, string>;
15
+ exports: string;
16
+ command: string[];
17
+ commandLine: string;
18
+ restartRequired: boolean;
19
+ message: string;
20
+ }
21
+ export declare function switchProfile(name: string, opts?: SwitchOptions): SwitchResult;
22
+ //# sourceMappingURL=switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/lib/switch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAOpD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAeD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,YAAY,CAmClF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAgC,MAAM,aAAa,CAAC;AAGzE;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,OAAO,EA4DlC,CAAC;AAEF,eAAO,MAAM,YAAY,WAAW,CAAC;AAIrC,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,oFAAoF;AACpF,wBAAgB,SAAS,IAAI,OAAO,EAAE,CAMrC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAS3C;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAanD;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAWjD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAgC,MAAM,aAAa,CAAC;AAGzE;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,OAAO,EA+DlC,CAAC;AAEF,eAAO,MAAM,YAAY,WAAW,CAAC;AAIrC,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,oFAAoF;AACpF,wBAAgB,SAAS,IAAI,OAAO,EAAE,CAMrC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAS3C;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAanD;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAWjD"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":""}