@hasna/accounts 0.1.2 → 0.1.3

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
 
package/dist/cli.js CHANGED
@@ -7248,8 +7248,8 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
7248
7248
  writeJsonFile(profileKeychainSnapshot(profileDir), kc, profileDir);
7249
7249
  }
7250
7250
  }
7251
- function ensureProfileAuthSnapshot(profileDir, tool) {
7252
- if (hasAuthSnapshot(profileDir))
7251
+ function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
7252
+ if (!opts.overwrite && hasAuthSnapshot(profileDir))
7253
7253
  return;
7254
7254
  const authDir = profileAuthDir(profileDir);
7255
7255
  assertSafeWritePath(join6(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
@@ -7561,6 +7561,20 @@ function formatExportLines(env2) {
7561
7561
  `);
7562
7562
  }
7563
7563
 
7564
+ // src/lib/login.ts
7565
+ function finalizeLogin(name, toolId) {
7566
+ const profile = getProfile(name, toolId);
7567
+ const tool = getTool(profile.tool);
7568
+ if (tool.id === "claude") {
7569
+ ensureProfileAuthSnapshot(profile.dir, tool, { overwrite: true });
7570
+ redetectEmail(name, tool.id);
7571
+ return { profile: applyProfile(name, tool.id).profile, applied: true };
7572
+ }
7573
+ const updated = redetectEmail(name, tool.id);
7574
+ useProfile(name, tool.id);
7575
+ return { profile: updated, applied: false };
7576
+ }
7577
+
7564
7578
  // src/cli.ts
7565
7579
  var program2 = new Command;
7566
7580
  function die(message) {
@@ -7670,15 +7684,23 @@ program2.command("login").argument("<name>", "profile name").description("launch
7670
7684
  console.log(source_default.dim(` config dir: ${profile.dir}`));
7671
7685
  console.log(source_default.dim(` env: ${formatEnvAssignments(env2)}`));
7672
7686
  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}`));
7687
+ if (tool.id === "claude") {
7688
+ console.log(source_default.dim(" After Claude exits, accounts will make this the live/default Claude account."));
7689
+ }
7675
7690
  const res = spawnSync(tool.bin, loginArgs, {
7676
7691
  stdio: "inherit",
7677
7692
  env: { ...process.env, ...env2 }
7678
7693
  });
7679
7694
  if (res.error)
7680
7695
  die(`failed to launch ${tool.bin}: ${res.error.message}`);
7681
- process.exit(res.status ?? 0);
7696
+ if ((res.status ?? 0) !== 0)
7697
+ process.exit(res.status ?? 1);
7698
+ const finalized = finalizeLogin(name, tool.id);
7699
+ if (finalized.applied) {
7700
+ console.log(source_default.green(`✓ ${source_default.bold(name)} is now the live/default ${tool.label} account`));
7701
+ } else {
7702
+ console.log(source_default.green(`✓ ${source_default.bold(name)} login finished and profile is active`));
7703
+ }
7682
7704
  }));
7683
7705
  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
7706
  const result = await pickProfile({ tool: opts.tool, mode: resolvePickMode(opts) });
package/dist/index.d.ts CHANGED
@@ -8,6 +8,8 @@ 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";
11
13
  export { pickProfile } from "./lib/pick.js";
12
14
  export type { PickOptions, PickResult } from "./lib/pick.js";
13
15
  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,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
@@ -4687,8 +4687,8 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
4687
4687
  function snapshotClaudeAuthToProfile(profileDir, tool) {
4688
4688
  snapshotLiveAuthToProfile(profileDir, tool);
4689
4689
  }
4690
- function ensureProfileAuthSnapshot(profileDir, tool) {
4691
- if (hasAuthSnapshot(profileDir))
4690
+ function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
4691
+ if (!opts.overwrite && hasAuthSnapshot(profileDir))
4692
4692
  return;
4693
4693
  const authDir = profileAuthDir(profileDir);
4694
4694
  assertSafeWritePath(join6(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
@@ -4878,6 +4878,19 @@ function findProfileByName(name, toolId) {
4878
4878
  throw err;
4879
4879
  }
4880
4880
  }
4881
+ // src/lib/login.ts
4882
+ function finalizeLogin(name, toolId) {
4883
+ const profile = getProfile(name, toolId);
4884
+ const tool = getTool(profile.tool);
4885
+ if (tool.id === "claude") {
4886
+ ensureProfileAuthSnapshot(profile.dir, tool, { overwrite: true });
4887
+ redetectEmail(name, tool.id);
4888
+ return { profile: applyProfile(name, tool.id).profile, applied: true };
4889
+ }
4890
+ const updated = redetectEmail(name, tool.id);
4891
+ useProfile(name, tool.id);
4892
+ return { profile: updated, applied: false };
4893
+ }
4881
4894
  // src/lib/pick.ts
4882
4895
  import * as readline from "node:readline/promises";
4883
4896
  import { stdin as input, stdout as output } from "node:process";
@@ -5011,6 +5024,7 @@ export {
5011
5024
  formatExportLines,
5012
5025
  formatEnvAssignments,
5013
5026
  findProfile,
5027
+ finalizeLogin,
5014
5028
  expandPath,
5015
5029
  ensureProfileForLogin,
5016
5030
  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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/accounts",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Manage and switch between multiple Claude Code (and other AI coding tool) profiles/accounts locally — isolated config dirs, per-account email, one-command switching.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "repository": {
49
49
  "type": "git",
50
- "url": "https://github.com/hasna/accounts.git"
50
+ "url": "git+https://github.com/hasna/accounts.git"
51
51
  },
52
52
  "homepage": "https://github.com/hasna/accounts",
53
53
  "bugs": {