@hasna/accounts 0.1.19 → 0.1.20

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/dist/cli.js CHANGED
@@ -12804,8 +12804,8 @@ More information can be found at: https://a.co/c895JFp`);
12804
12804
  };
12805
12805
  var createUserAgentStringParsingProvider = ({ serviceId, clientVersion }) => async (config2) => {
12806
12806
  const module2 = await Promise.resolve().then(() => __toESM(require_es5()));
12807
- const parse = module2.parse ?? module2.default.parse ?? (() => "");
12808
- const parsedUA = typeof window !== "undefined" && window?.navigator?.userAgent ? parse(window.navigator.userAgent) : undefined;
12807
+ const parse2 = module2.parse ?? module2.default.parse ?? (() => "");
12808
+ const parsedUA = typeof window !== "undefined" && window?.navigator?.userAgent ? parse2(window.navigator.userAgent) : undefined;
12809
12809
  const sections = [
12810
12810
  ["aws-sdk-js", clientVersion],
12811
12811
  ["ua", "2.1"],
@@ -14563,7 +14563,7 @@ var require_dist_cjs9 = __commonJS((exports) => {
14563
14563
  var require_util = __commonJS((exports) => {
14564
14564
  var protocols = require_protocols();
14565
14565
  var validate = (str) => typeof str === "string" && str.indexOf("arn:") === 0 && str.split(":").length >= 6;
14566
- var parse = (arn) => {
14566
+ var parse2 = (arn) => {
14567
14567
  const segments = arn.split(":");
14568
14568
  if (segments.length < 6 || segments[0] !== "arn")
14569
14569
  throw new Error("Malformed ARN");
@@ -14613,7 +14613,7 @@ var require_util = __commonJS((exports) => {
14613
14613
  }
14614
14614
  exports.build = build;
14615
14615
  exports.formatUrl = formatUrl;
14616
- exports.parse = parse;
14616
+ exports.parse = parse2;
14617
14617
  exports.validate = validate;
14618
14618
  });
14619
14619
 
@@ -30104,12 +30104,12 @@ var require_fromHttp = __commonJS((exports) => {
30104
30104
  var fromHttp = (options = {}) => {
30105
30105
  options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
30106
30106
  let host;
30107
- const relative = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
30107
+ const relative2 = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
30108
30108
  const full = options.awsContainerCredentialsFullUri ?? process.env[AWS_CONTAINER_CREDENTIALS_FULL_URI];
30109
30109
  const token = options.awsContainerAuthorizationToken ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN];
30110
30110
  const tokenFile = options.awsContainerAuthorizationTokenFile ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE];
30111
30111
  const warn = options.logger?.constructor?.name === "NoOpLogger" || !options.logger?.warn ? console.warn : options.logger.warn.bind(options.logger);
30112
- if (relative && full) {
30112
+ if (relative2 && full) {
30113
30113
  warn("@aws-sdk/credential-provider-http: " + "you have set both awsContainerCredentialsRelativeUri and awsContainerCredentialsFullUri.");
30114
30114
  warn("awsContainerCredentialsFullUri will take precedence.");
30115
30115
  }
@@ -30119,8 +30119,8 @@ var require_fromHttp = __commonJS((exports) => {
30119
30119
  }
30120
30120
  if (full) {
30121
30121
  host = full;
30122
- } else if (relative) {
30123
- host = `${DEFAULT_LINK_LOCAL_HOST}${relative}`;
30122
+ } else if (relative2) {
30123
+ host = `${DEFAULT_LINK_LOCAL_HOST}${relative2}`;
30124
30124
  } else {
30125
30125
  throw new config_1.CredentialsProviderError(`No HTTP credential provider host provided.
30126
30126
  Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.`, { logger: options.logger });
@@ -36799,7 +36799,7 @@ var require_dist_cjs22 = __commonJS((exports) => {
36799
36799
  import { spawnSync as spawnSync2 } from "node:child_process";
36800
36800
  import { existsSync as existsSync13, readFileSync as readFileSync8 } from "node:fs";
36801
36801
  import { homedir as homedir6 } from "node:os";
36802
- import { dirname as dirname5, join as join13 } from "node:path";
36802
+ import { dirname as dirname5, join as join14 } from "node:path";
36803
36803
  import { fileURLToPath } from "node:url";
36804
36804
 
36805
36805
  // node_modules/commander/esm.mjs
@@ -42002,62 +42002,131 @@ class AccountsError extends Error {
42002
42002
 
42003
42003
  // src/lib/tools.ts
42004
42004
  import { homedir as homedir3 } from "node:os";
42005
- import { join as join3 } from "node:path";
42005
+ import { join as join4 } from "node:path";
42006
42006
 
42007
42007
  // src/storage.ts
42008
42008
  import { homedir as homedir2 } from "node:os";
42009
42009
  import { hostname } from "node:os";
42010
- import { join as join2 } from "node:path";
42010
+ import { join as join3 } from "node:path";
42011
42011
  import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "node:fs";
42012
42012
 
42013
42013
  // src/lib/safe-path.ts
42014
42014
  import { existsSync as existsSync2, lstatSync, mkdirSync, realpathSync } from "node:fs";
42015
- import { dirname, resolve } from "node:path";
42015
+ import { dirname, isAbsolute, join as join2, parse, relative, resolve, sep } from "node:path";
42016
+ function lstatIfExists(path) {
42017
+ try {
42018
+ return lstatSync(path);
42019
+ } catch (err) {
42020
+ if (err.code !== "ENOENT")
42021
+ throw err;
42022
+ return;
42023
+ }
42024
+ }
42016
42025
  function throwIfSymlink(path, label) {
42017
- if (existsSync2(path) && lstatSync(path).isSymbolicLink()) {
42026
+ if (lstatIfExists(path)?.isSymbolicLink()) {
42018
42027
  throw new AccountsError(`${label}: ${path}`);
42019
42028
  }
42020
42029
  }
42021
- function assertDirChainSafe(targetFile, mustStayUnder) {
42022
- const absFile = resolve(targetFile);
42023
- const parent = dirname(absFile);
42024
- const base = mustStayUnder ? resolve(mustStayUnder) : undefined;
42025
- if (base) {
42026
- const rel = absFile.startsWith(base + "/") ? absFile.slice(base.length + 1) : "";
42027
- if (!rel && absFile !== base) {
42028
- throw new AccountsError(`refusing to write outside profile directory: ${targetFile}`);
42029
- }
42030
- const segments = rel.split("/").filter(Boolean);
42031
- if (segments.some((s) => s === "..")) {
42032
- throw new AccountsError(`refusing path traversal: ${targetFile}`);
42033
- }
42034
- let cursor = base;
42035
- for (let i = 0;i < segments.length - 1; i++) {
42036
- cursor = resolve(cursor, segments[i]);
42037
- throwIfSymlink(cursor, "refusing to write under symlink directory");
42030
+ function isAllowedSystemDirectorySymlink(path) {
42031
+ if (path !== "/var" && path !== "/tmp")
42032
+ return false;
42033
+ try {
42034
+ return realpathSync(path) === `/private${path}`;
42035
+ } catch {
42036
+ return false;
42037
+ }
42038
+ }
42039
+ function assertDirectory(path, label, opts) {
42040
+ const stat = lstatIfExists(path);
42041
+ if (!stat) {
42042
+ throw new AccountsError(`refusing to write under missing directory: ${path}`);
42043
+ }
42044
+ if (stat.isSymbolicLink()) {
42045
+ if (opts?.allowSystemSymlink && isAllowedSystemDirectorySymlink(path))
42046
+ return;
42047
+ throw new AccountsError(`${label}: ${path}`);
42048
+ }
42049
+ if (!stat.isDirectory()) {
42050
+ throw new AccountsError(`refusing to write under non-directory path: ${path}`);
42051
+ }
42052
+ }
42053
+ function assertInsideBase(absPath, base, originalPath) {
42054
+ const rel = relative(base, absPath);
42055
+ if (rel === "")
42056
+ return rel;
42057
+ if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
42058
+ throw new AccountsError(`refusing to write outside profile directory: ${originalPath}`);
42059
+ }
42060
+ return rel;
42061
+ }
42062
+ function assertExistingDirectoryComponentsSafe(path, label) {
42063
+ const root = parse(path).root;
42064
+ const rel = relative(root, path);
42065
+ const segments = rel ? rel.split(sep).filter(Boolean) : [];
42066
+ let cursor = root;
42067
+ assertDirectory(cursor, label, { allowSystemSymlink: true });
42068
+ for (const segment of segments) {
42069
+ cursor = join2(cursor, segment);
42070
+ if (!lstatIfExists(cursor))
42071
+ return;
42072
+ assertDirectory(cursor, label, { allowSystemSymlink: true });
42073
+ }
42074
+ }
42075
+ function ensureBoundaryRootSafe(base) {
42076
+ const missing = [];
42077
+ let cursor = base;
42078
+ while (!lstatIfExists(cursor)) {
42079
+ missing.unshift(cursor);
42080
+ const parent = dirname(cursor);
42081
+ if (parent === cursor)
42082
+ break;
42083
+ cursor = parent;
42084
+ }
42085
+ assertDirectory(cursor, "refusing to use symlink base directory");
42086
+ for (const dir of missing) {
42087
+ if (lstatIfExists(dir)) {
42088
+ assertDirectory(dir, "refusing to use symlink base directory");
42089
+ } else {
42090
+ mkdirSync(dir);
42091
+ assertDirectory(dir, "refusing to use symlink base directory");
42038
42092
  }
42039
- } else {
42040
- let cursor = parent;
42041
- for (;; ) {
42042
- throwIfSymlink(cursor, "refusing to write under symlink directory");
42043
- const next = dirname(cursor);
42044
- if (next === cursor)
42045
- break;
42046
- cursor = next;
42093
+ }
42094
+ assertDirectory(base, "refusing to use symlink base directory");
42095
+ }
42096
+ function ensureDirectoryChainSafe(parent, startAt) {
42097
+ const root = startAt ?? parse(parent).root;
42098
+ const rel = relative(root, parent);
42099
+ const segments = rel ? rel.split(sep).filter(Boolean) : [];
42100
+ let cursor = root;
42101
+ if (startAt)
42102
+ assertDirectory(startAt, "refusing to write under symlink directory");
42103
+ for (const segment of segments) {
42104
+ cursor = join2(cursor, segment);
42105
+ if (lstatIfExists(cursor)) {
42106
+ assertDirectory(cursor, "refusing to write under symlink directory");
42107
+ } else {
42108
+ mkdirSync(cursor);
42109
+ assertDirectory(cursor, "refusing to write under symlink directory");
42047
42110
  }
42048
42111
  }
42049
42112
  }
42050
42113
  function assertSafeWritePath(filePath, opts) {
42051
42114
  const absFile = resolve(filePath);
42052
42115
  const parent = dirname(absFile);
42053
- if (!existsSync2(parent))
42054
- mkdirSync(parent, { recursive: true });
42116
+ const base = opts?.mustStayUnder ? resolve(opts.mustStayUnder) : undefined;
42117
+ if (base) {
42118
+ assertInsideBase(absFile, base, filePath);
42119
+ assertExistingDirectoryComponentsSafe(base, "refusing to use symlink base directory");
42120
+ ensureBoundaryRootSafe(base);
42121
+ ensureDirectoryChainSafe(parent, base);
42122
+ } else {
42123
+ ensureDirectoryChainSafe(parent);
42124
+ }
42055
42125
  throwIfSymlink(absFile, "refusing to write through symlink");
42056
- assertDirChainSafe(absFile, opts?.mustStayUnder);
42057
42126
  const resolved = realpathSync(existsSync2(absFile) ? absFile : parent);
42058
- if (opts?.mustStayUnder) {
42059
- const base = realpathSync(resolve(opts.mustStayUnder));
42060
- if (resolved !== base && !resolved.startsWith(base + "/")) {
42127
+ if (base) {
42128
+ const realBase = realpathSync(base);
42129
+ if (resolved !== realBase && !resolved.startsWith(realBase + sep)) {
42061
42130
  throw new AccountsError(`refusing to write outside profile directory: ${filePath}`);
42062
42131
  }
42063
42132
  }
@@ -42096,16 +42165,16 @@ function accountsHome() {
42096
42165
  const override = process.env.ACCOUNTS_HOME;
42097
42166
  if (override && override.trim())
42098
42167
  return validateEnvPath(override, "ACCOUNTS_HOME");
42099
- return join2(homedir2(), ".hasna", "accounts");
42168
+ return join3(homedir2(), ".hasna", "accounts");
42100
42169
  }
42101
42170
  function storePath() {
42102
42171
  const override = process.env.ACCOUNTS_STORE_PATH;
42103
42172
  if (override && override.trim())
42104
42173
  return validateEnvPath(override, "ACCOUNTS_STORE_PATH");
42105
- return join2(accountsHome(), "accounts.json");
42174
+ return join3(accountsHome(), "accounts.json");
42106
42175
  }
42107
42176
  function profilesDir() {
42108
- return join2(accountsHome(), "profiles");
42177
+ return join3(accountsHome(), "profiles");
42109
42178
  }
42110
42179
  var EMPTY_STORE = { version: 1, current: {}, applied: {}, profiles: [], tools: [] };
42111
42180
  function loadStore() {
@@ -42148,7 +42217,7 @@ function loadStore() {
42148
42217
  function saveStore(store) {
42149
42218
  const path = storePath();
42150
42219
  assertSafeWritePath(path, { mustStayUnder: accountsHome() });
42151
- mkdirSync2(join2(path, ".."), { recursive: true });
42220
+ mkdirSync2(join3(path, ".."), { recursive: true });
42152
42221
  if (existsSync3(path))
42153
42222
  chmodSync(path, 384);
42154
42223
  writeFileSync(path, JSON.stringify(store, null, 2) + `
@@ -42302,7 +42371,7 @@ var BUILTIN_TOOLS = [
42302
42371
  extraEnv: {
42303
42372
  TELEGRAM_STATE_DIR: "{profileDir}/channels/telegram"
42304
42373
  },
42305
- defaultDir: join3(homedir3(), ".claude"),
42374
+ defaultDir: join4(homedir3(), ".claude"),
42306
42375
  bin: "claude",
42307
42376
  loginHint: "run /login inside Claude, then /exit when done",
42308
42377
  resumeArgs: ["--continue"],
@@ -42322,7 +42391,7 @@ var BUILTIN_TOOLS = [
42322
42391
  id: "codex-app",
42323
42392
  label: "Codex App",
42324
42393
  envVar: "CODEX_HOME",
42325
- defaultDir: join3(homedir3(), ".codex"),
42394
+ defaultDir: join4(homedir3(), ".codex"),
42326
42395
  bin: "/Applications/Codex.app/Contents/MacOS/Codex",
42327
42396
  loginHint: "sign in inside Codex.app, then quit the app when the profile is ready",
42328
42397
  launchArgs: ["--user-data-dir={profileDir}/electron-user-data"],
@@ -42332,7 +42401,7 @@ var BUILTIN_TOOLS = [
42332
42401
  id: "codex",
42333
42402
  label: "Codex CLI",
42334
42403
  envVar: "CODEX_HOME",
42335
- defaultDir: join3(homedir3(), ".codex"),
42404
+ defaultDir: join4(homedir3(), ".codex"),
42336
42405
  bin: "codex",
42337
42406
  loginArgs: ["login"],
42338
42407
  loginHint: "complete the Codex login flow for this CODEX_HOME",
@@ -42345,7 +42414,7 @@ var BUILTIN_TOOLS = [
42345
42414
  id: "takumi",
42346
42415
  label: "Takumi",
42347
42416
  envVar: "TAKUMI_CONFIG_DIR",
42348
- defaultDir: join3(homedir3(), ".takumi"),
42417
+ defaultDir: join4(homedir3(), ".takumi"),
42349
42418
  bin: "takumi",
42350
42419
  loginHint: "complete Takumi auth in this TAKUMI_CONFIG_DIR",
42351
42420
  resumeArgs: ["--continue"],
@@ -42365,7 +42434,7 @@ var BUILTIN_TOOLS = [
42365
42434
  id: "gemini",
42366
42435
  label: "Gemini CLI",
42367
42436
  envVar: "GEMINI_CONFIG_DIR",
42368
- defaultDir: join3(homedir3(), ".gemini"),
42437
+ defaultDir: join4(homedir3(), ".gemini"),
42369
42438
  bin: "gemini",
42370
42439
  loginHint: "complete Gemini auth in this GEMINI_CONFIG_DIR",
42371
42440
  permissionArgs: {
@@ -42383,7 +42452,7 @@ var BUILTIN_TOOLS = [
42383
42452
  XDG_CONFIG_HOME: "{profileDir}/xdg-config",
42384
42453
  XDG_DATA_HOME: "{profileDir}/xdg-data"
42385
42454
  },
42386
- defaultDir: join3(homedir3(), ".config", "opencode"),
42455
+ defaultDir: join4(homedir3(), ".config", "opencode"),
42387
42456
  bin: "opencode",
42388
42457
  loginArgs: ["auth", "login"],
42389
42458
  loginHint: "complete opencode auth login for this isolated config/data root",
@@ -42393,7 +42462,7 @@ var BUILTIN_TOOLS = [
42393
42462
  id: "cursor",
42394
42463
  label: "Cursor Agent",
42395
42464
  envVar: "CURSOR_CONFIG_DIR",
42396
- defaultDir: join3(homedir3(), ".cursor"),
42465
+ defaultDir: join4(homedir3(), ".cursor"),
42397
42466
  bin: "cursor-agent",
42398
42467
  loginArgs: ["login"],
42399
42468
  loginHint: "complete cursor-agent login for this CURSOR_CONFIG_DIR"
@@ -42402,7 +42471,7 @@ var BUILTIN_TOOLS = [
42402
42471
  id: "pi",
42403
42472
  label: "Pi Coding Agent",
42404
42473
  envVar: "PI_CODING_AGENT_HOME",
42405
- defaultDir: join3(homedir3(), ".pi"),
42474
+ defaultDir: join4(homedir3(), ".pi"),
42406
42475
  bin: "pi",
42407
42476
  loginHint: "complete Pi coding agent auth in this PI_CODING_AGENT_HOME"
42408
42477
  },
@@ -42410,7 +42479,7 @@ var BUILTIN_TOOLS = [
42410
42479
  id: "hermes",
42411
42480
  label: "Hermes",
42412
42481
  envVar: "HERMES_HOME",
42413
- defaultDir: join3(homedir3(), ".hermes"),
42482
+ defaultDir: join4(homedir3(), ".hermes"),
42414
42483
  bin: "hermes",
42415
42484
  loginHint: "complete Hermes auth in this HERMES_HOME",
42416
42485
  permissionArgs: {
@@ -42422,7 +42491,7 @@ var BUILTIN_TOOLS = [
42422
42491
  id: "kimi",
42423
42492
  label: "Kimi Code",
42424
42493
  envVar: "KIMI_CODE_HOME",
42425
- defaultDir: join3(homedir3(), ".kimi-code"),
42494
+ defaultDir: join4(homedir3(), ".kimi-code"),
42426
42495
  bin: "kimi",
42427
42496
  loginArgs: ["login"],
42428
42497
  loginHint: "complete kimi login for this KIMI_CODE_HOME",
@@ -42437,7 +42506,7 @@ var BUILTIN_TOOLS = [
42437
42506
  id: "grok",
42438
42507
  label: "Grok Build",
42439
42508
  envVar: "HOME",
42440
- defaultDir: join3(homedir3(), ".grok"),
42509
+ defaultDir: join4(homedir3(), ".grok"),
42441
42510
  bin: "grok",
42442
42511
  loginArgs: ["login"],
42443
42512
  loginHint: "complete grok login in this process-scoped HOME; prefer launch/shell over exporting HOME globally"
@@ -42544,18 +42613,18 @@ function removeCustomTool(id) {
42544
42613
 
42545
42614
  // src/lib/profiles.ts
42546
42615
  import { homedir as homedir4 } from "node:os";
42547
- import { isAbsolute, join as join5, relative, resolve as resolve2 } from "node:path";
42616
+ import { isAbsolute as isAbsolute2, join as join6, relative as relative2, resolve as resolve2 } from "node:path";
42548
42617
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, rmSync } from "node:fs";
42549
42618
 
42550
42619
  // src/lib/detect.ts
42551
42620
  import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
42552
- import { dirname as dirname2, join as join4 } from "node:path";
42621
+ import { dirname as dirname2, join as join5 } from "node:path";
42553
42622
  function detectEmail(dir, tool) {
42554
42623
  if (!tool.accountFile || !tool.emailPath)
42555
42624
  return;
42556
- const candidates = [join4(dir, tool.accountFile)];
42625
+ const candidates = [join5(dir, tool.accountFile)];
42557
42626
  if (dir === tool.defaultDir)
42558
- candidates.push(join4(dirname2(dir), tool.accountFile));
42627
+ candidates.push(join5(dirname2(dir), tool.accountFile));
42559
42628
  for (const file of candidates) {
42560
42629
  const email = readEmail(file, tool.emailPath);
42561
42630
  if (email)
@@ -42591,8 +42660,8 @@ function expandPath(p) {
42591
42660
  if (out === "~")
42592
42661
  out = homedir4();
42593
42662
  else if (out.startsWith("~/"))
42594
- out = join5(homedir4(), out.slice(2));
42595
- return isAbsolute(out) ? out : resolve2(process.cwd(), out);
42663
+ out = join6(homedir4(), out.slice(2));
42664
+ return isAbsolute2(out) ? out : resolve2(process.cwd(), out);
42596
42665
  }
42597
42666
  function listProfiles(toolId) {
42598
42667
  const profiles = loadStore().profiles;
@@ -42603,8 +42672,8 @@ function profileMatches(name, toolId) {
42603
42672
  return loadStore().profiles.filter((p) => p.name === name && (!toolId || p.tool === toolId));
42604
42673
  }
42605
42674
  function isManagedProfileDir(dir) {
42606
- const rel = relative(resolve2(profilesDir()), resolve2(dir));
42607
- return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
42675
+ const rel = relative2(resolve2(profilesDir()), resolve2(dir));
42676
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
42608
42677
  }
42609
42678
  function getProfile(name, toolId) {
42610
42679
  const matches = profileMatches(name, toolId);
@@ -42629,7 +42698,7 @@ function addProfile(opts) {
42629
42698
  if (store.profiles.some((p) => p.name === name && p.tool === toolId)) {
42630
42699
  throw new AccountsError(`a ${toolId} profile named "${name}" already exists`);
42631
42700
  }
42632
- const dir = opts.dir ? expandPath(opts.dir) : join5(profilesDir(), toolId, name);
42701
+ const dir = opts.dir ? expandPath(opts.dir) : join6(profilesDir(), toolId, name);
42633
42702
  if (store.profiles.some((p) => p.dir === dir)) {
42634
42703
  throw new AccountsError(`a profile already uses config dir ${dir}`);
42635
42704
  }
@@ -42771,11 +42840,11 @@ function currentProfile(toolId) {
42771
42840
 
42772
42841
  // src/lib/claude-auth.ts
42773
42842
  import { copyFileSync, existsSync as existsSync6, lstatSync as lstatSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync3, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
42774
- import { dirname as dirname4, join as join7 } from "node:path";
42843
+ import { dirname as dirname4, join as join8 } from "node:path";
42775
42844
 
42776
42845
  // src/lib/claude-layout.ts
42777
42846
  import { homedir as homedir5 } from "node:os";
42778
- import { dirname as dirname3, join as join6 } from "node:path";
42847
+ import { dirname as dirname3, join as join7 } from "node:path";
42779
42848
  var CLAUDE_KEYCHAIN_SERVICE = "Claude Code-credentials";
42780
42849
  var ACCOUNTS_AUTH_DIR = ".accounts-auth";
42781
42850
  var OAUTH_SNAPSHOT = "oauth-account.json";
@@ -42787,32 +42856,32 @@ function liveClaudeBase() {
42787
42856
  }
42788
42857
  function liveClaudePaths() {
42789
42858
  const base = liveClaudeBase();
42790
- const configDir = join6(base, ".claude");
42859
+ const configDir = join7(base, ".claude");
42791
42860
  return {
42792
42861
  configDir,
42793
- homeJson: join6(base, ".claude.json"),
42794
- credentialsFile: join6(configDir, ".credentials.json")
42862
+ homeJson: join7(base, ".claude.json"),
42863
+ credentialsFile: join7(configDir, ".credentials.json")
42795
42864
  };
42796
42865
  }
42797
42866
  function profileAccountJsonPaths(profileDir, tool) {
42798
42867
  if (!tool.accountFile)
42799
42868
  return [];
42800
- const paths = [join6(profileDir, tool.accountFile)];
42869
+ const paths = [join7(profileDir, tool.accountFile)];
42801
42870
  if (profileDir === tool.defaultDir)
42802
- paths.push(join6(dirname3(profileDir), tool.accountFile));
42871
+ paths.push(join7(dirname3(profileDir), tool.accountFile));
42803
42872
  return paths;
42804
42873
  }
42805
42874
  function profileAuthDir(profileDir) {
42806
- return join6(profileDir, ACCOUNTS_AUTH_DIR);
42875
+ return join7(profileDir, ACCOUNTS_AUTH_DIR);
42807
42876
  }
42808
42877
  function profileOAuthSnapshot(profileDir) {
42809
- return join6(profileAuthDir(profileDir), OAUTH_SNAPSHOT);
42878
+ return join7(profileAuthDir(profileDir), OAUTH_SNAPSHOT);
42810
42879
  }
42811
42880
  function profileCredentialsSnapshot(profileDir) {
42812
- return join6(profileAuthDir(profileDir), CREDENTIALS_SNAPSHOT);
42881
+ return join7(profileAuthDir(profileDir), CREDENTIALS_SNAPSHOT);
42813
42882
  }
42814
42883
  function profileKeychainSnapshot(profileDir) {
42815
- return join6(profileAuthDir(profileDir), KEYCHAIN_SNAPSHOT);
42884
+ return join7(profileAuthDir(profileDir), KEYCHAIN_SNAPSHOT);
42816
42885
  }
42817
42886
 
42818
42887
  // src/lib/keychain.ts
@@ -42966,7 +43035,7 @@ function mergeOAuthInto(paths, oauth, allowDelete, stayUnder) {
42966
43035
  }
42967
43036
  }
42968
43037
  function sanitizeSettingsFile(configDir, stayUnder) {
42969
- const settingsPath = join7(configDir, "settings.json");
43038
+ const settingsPath = join8(configDir, "settings.json");
42970
43039
  const settings = readJsonFile(settingsPath);
42971
43040
  if (!settings)
42972
43041
  return false;
@@ -43013,7 +43082,7 @@ function liveOAuthEmail() {
43013
43082
  }
43014
43083
  function snapshotLiveAuthToProfile(profileDir, _tool) {
43015
43084
  const authDir = profileAuthDir(profileDir);
43016
- assertSafeWritePath(join7(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43085
+ assertSafeWritePath(join8(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43017
43086
  mkdirSync4(authDir, { recursive: true });
43018
43087
  const live = liveClaudePaths();
43019
43088
  const oauth = readOAuthFromPaths([live.homeJson]);
@@ -43032,14 +43101,14 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
43032
43101
  }
43033
43102
  function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
43034
43103
  const authDir = profileAuthDir(profileDir);
43035
- assertSafeWritePath(join7(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43104
+ assertSafeWritePath(join8(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43036
43105
  mkdirSync4(authDir, { recursive: true });
43037
43106
  const oauthSource = findOAuthSource(profileAccountJsonPaths(profileDir, tool));
43038
43107
  const oauthSnap = profileOAuthSnapshot(profileDir);
43039
43108
  if (oauthSource && (opts.overwrite || snapshotIsStale(oauthSource.path, oauthSnap))) {
43040
43109
  writeJsonFile(oauthSnap, { oauthAccount: oauthSource.oauth }, profileDir);
43041
43110
  }
43042
- const credFile = join7(profileDir, ".credentials.json");
43111
+ const credFile = join8(profileDir, ".credentials.json");
43043
43112
  const credSnap = profileCredentialsSnapshot(profileDir);
43044
43113
  if (existsSync6(credFile) && (opts.overwrite || snapshotIsStale(credFile, credSnap))) {
43045
43114
  assertSafeWritePath(credSnap, { mustStayUnder: profileDir });
@@ -43101,9 +43170,9 @@ function hasAuthSnapshot(profileDir) {
43101
43170
 
43102
43171
  // src/lib/apply-lock.ts
43103
43172
  import { closeSync, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
43104
- import { join as join8 } from "node:path";
43173
+ import { join as join9 } from "node:path";
43105
43174
  function lockPath() {
43106
- return join8(accountsHome(), ".apply.lock");
43175
+ return join9(accountsHome(), ".apply.lock");
43107
43176
  }
43108
43177
  function withApplyLock(fn) {
43109
43178
  const home = accountsHome();
@@ -43352,7 +43421,7 @@ function listAgentsAcrossProfiles(opts = {}) {
43352
43421
 
43353
43422
  // src/lib/import-profile.ts
43354
43423
  import { cpSync, existsSync as existsSync9 } from "node:fs";
43355
- import { join as join9 } from "node:path";
43424
+ import { join as join10 } from "node:path";
43356
43425
  function importProfile(opts) {
43357
43426
  const toolId = opts.tool ?? DEFAULT_TOOL;
43358
43427
  const tool = getTool(toolId);
@@ -43362,7 +43431,7 @@ function importProfile(opts) {
43362
43431
  throw new AccountsError(`config dir does not exist: ${sourceDir}`);
43363
43432
  }
43364
43433
  if (opts.copy) {
43365
- const targetDir = join9(profilesDir(), toolId, name);
43434
+ const targetDir = join10(profilesDir(), toolId, name);
43366
43435
  if (existsSync9(targetDir)) {
43367
43436
  throw new AccountsError(`managed copy target already exists: ${targetDir}`);
43368
43437
  }
@@ -43448,7 +43517,7 @@ async function pickProfile(opts = {}) {
43448
43517
 
43449
43518
  // src/lib/hook.ts
43450
43519
  import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "node:fs";
43451
- import { join as join10 } from "node:path";
43520
+ import { join as join11 } from "node:path";
43452
43521
  var HOOK_FILE = "claude-hook.sh";
43453
43522
  var MARKER = "# accounts-claude-hook";
43454
43523
  var NAME_PATTERN = "^[a-z0-9][a-z0-9-]*$";
@@ -43456,7 +43525,7 @@ function shellQuotePath(path) {
43456
43525
  return `'${path.replace(/'/g, `'\\''`)}'`;
43457
43526
  }
43458
43527
  function hookPath() {
43459
- return join10(accountsHome(), HOOK_FILE);
43528
+ return join11(accountsHome(), HOOK_FILE);
43460
43529
  }
43461
43530
  function hookScript() {
43462
43531
  const quotedHook = shellQuotePath(hookPath());
@@ -43507,7 +43576,7 @@ function shellSnippet() {
43507
43576
 
43508
43577
  // src/lib/codex-app.ts
43509
43578
  import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
43510
- import { join as join11 } from "node:path";
43579
+ import { join as join12 } from "node:path";
43511
43580
  var FILE_CREDENTIALS_LINE = 'cli_auth_credentials_store = "file"';
43512
43581
  function insertRootConfigLine(config, line) {
43513
43582
  if (config.trim() === "")
@@ -43534,7 +43603,7 @@ ${after}${after.endsWith(`
43534
43603
  }
43535
43604
  function ensureCodexAppProfileConfig(profileDir) {
43536
43605
  mkdirSync7(profileDir, { recursive: true });
43537
- const configPath = join11(profileDir, "config.toml");
43606
+ const configPath = join12(profileDir, "config.toml");
43538
43607
  const current = existsSync11(configPath) ? readFileSync6(configPath, "utf8") : "";
43539
43608
  if (/^\s*cli_auth_credentials_store\s*=/.test(current))
43540
43609
  return;
@@ -43634,20 +43703,20 @@ import { spawn as spawn2 } from "node:child_process";
43634
43703
  import { createHash } from "node:crypto";
43635
43704
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync7, readdirSync, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
43636
43705
  import { createConnection, createServer } from "node:net";
43637
- import { basename, join as join12 } from "node:path";
43706
+ import { basename, join as join13 } from "node:path";
43638
43707
  var STATE_SUFFIX = ".json";
43639
43708
  function supervisorDir() {
43640
- return join12(accountsHome(), "supervisors");
43709
+ return join13(accountsHome(), "supervisors");
43641
43710
  }
43642
43711
  function supervisorStatePath(toolId) {
43643
- return join12(supervisorDir(), `${toolId}${STATE_SUFFIX}`);
43712
+ return join13(supervisorDir(), `${toolId}${STATE_SUFFIX}`);
43644
43713
  }
43645
43714
  function supervisorSocketPath(toolId) {
43646
43715
  if (process.platform === "win32") {
43647
43716
  const hash = createHash("sha1").update(accountsHome()).digest("hex").slice(0, 12);
43648
43717
  return `\\\\.\\pipe\\hasna-accounts-${hash}-${toolId}`;
43649
43718
  }
43650
- return join12(supervisorDir(), `${toolId}.sock`);
43719
+ return join13(supervisorDir(), `${toolId}.sock`);
43651
43720
  }
43652
43721
  function nowIso2() {
43653
43722
  return new Date().toISOString();
@@ -44245,7 +44314,7 @@ program2.command("switch").argument("<name>", "profile name").argument("[args...
44245
44314
  }
44246
44315
  }));
44247
44316
  var hook = program2.command("hook").description("install a shell wrapper for claude");
44248
- hook.command("install").description(`write ${join13(accountsHome(), "claude-hook.sh")}`).action(action(() => {
44317
+ hook.command("install").description(`write ${join14(accountsHome(), "claude-hook.sh")}`).action(action(() => {
44249
44318
  const { path, created } = installHook();
44250
44319
  console.log(source_default.green(created ? `✓ installed hook at ${path}` : `✓ updated hook at ${path}`));
44251
44320
  console.log(source_default.dim(` add to ~/.zshrc: ${shellSnippet()}`));
@@ -44485,7 +44554,7 @@ tools.command("add").argument("<id>", "tool id, e.g. cursor").description("regis
44485
44554
  label: opts.label,
44486
44555
  envVar: opts.envVar,
44487
44556
  bin: opts.bin,
44488
- defaultDir: opts.defaultDir ? expandPath(opts.defaultDir) : join13(homedir6(), `.${id}`),
44557
+ defaultDir: opts.defaultDir ? expandPath(opts.defaultDir) : join14(homedir6(), `.${id}`),
44489
44558
  ...Object.keys(extraEnv).length > 0 ? { extraEnv } : {},
44490
44559
  ...opts.loginArg ? { loginArgs: opts.loginArg } : {},
44491
44560
  ...opts.launchArg ? { launchArgs: opts.launchArg } : {},
@@ -44557,7 +44626,7 @@ program2.parseAsync(process.argv);
44557
44626
  function getVersion() {
44558
44627
  try {
44559
44628
  const here = dirname5(fileURLToPath(import.meta.url));
44560
- for (const candidate of [join13(here, "..", "package.json"), join13(here, "package.json")]) {
44629
+ for (const candidate of [join14(here, "..", "package.json"), join14(here, "package.json")]) {
44561
44630
  if (existsSync13(candidate)) {
44562
44631
  const pkg = JSON.parse(readFileSync8(candidate, "utf8"));
44563
44632
  if (pkg.version)