@hasna/accounts 0.1.18 → 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";
42011
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "node:fs";
42010
+ import { join as join3 } from "node:path";
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,9 +42217,12 @@ 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 });
42221
+ if (existsSync3(path))
42222
+ chmodSync(path, 384);
42152
42223
  writeFileSync(path, JSON.stringify(store, null, 2) + `
42153
42224
  `, { mode: 384 });
42225
+ chmodSync(path, 384);
42154
42226
  }
42155
42227
  function firstEnv(env2, primary, fallback) {
42156
42228
  return env2[primary] || env2[fallback] || undefined;
@@ -42299,7 +42371,7 @@ var BUILTIN_TOOLS = [
42299
42371
  extraEnv: {
42300
42372
  TELEGRAM_STATE_DIR: "{profileDir}/channels/telegram"
42301
42373
  },
42302
- defaultDir: join3(homedir3(), ".claude"),
42374
+ defaultDir: join4(homedir3(), ".claude"),
42303
42375
  bin: "claude",
42304
42376
  loginHint: "run /login inside Claude, then /exit when done",
42305
42377
  resumeArgs: ["--continue"],
@@ -42319,7 +42391,7 @@ var BUILTIN_TOOLS = [
42319
42391
  id: "codex-app",
42320
42392
  label: "Codex App",
42321
42393
  envVar: "CODEX_HOME",
42322
- defaultDir: join3(homedir3(), ".codex"),
42394
+ defaultDir: join4(homedir3(), ".codex"),
42323
42395
  bin: "/Applications/Codex.app/Contents/MacOS/Codex",
42324
42396
  loginHint: "sign in inside Codex.app, then quit the app when the profile is ready",
42325
42397
  launchArgs: ["--user-data-dir={profileDir}/electron-user-data"],
@@ -42329,7 +42401,7 @@ var BUILTIN_TOOLS = [
42329
42401
  id: "codex",
42330
42402
  label: "Codex CLI",
42331
42403
  envVar: "CODEX_HOME",
42332
- defaultDir: join3(homedir3(), ".codex"),
42404
+ defaultDir: join4(homedir3(), ".codex"),
42333
42405
  bin: "codex",
42334
42406
  loginArgs: ["login"],
42335
42407
  loginHint: "complete the Codex login flow for this CODEX_HOME",
@@ -42342,7 +42414,7 @@ var BUILTIN_TOOLS = [
42342
42414
  id: "takumi",
42343
42415
  label: "Takumi",
42344
42416
  envVar: "TAKUMI_CONFIG_DIR",
42345
- defaultDir: join3(homedir3(), ".takumi"),
42417
+ defaultDir: join4(homedir3(), ".takumi"),
42346
42418
  bin: "takumi",
42347
42419
  loginHint: "complete Takumi auth in this TAKUMI_CONFIG_DIR",
42348
42420
  resumeArgs: ["--continue"],
@@ -42362,7 +42434,7 @@ var BUILTIN_TOOLS = [
42362
42434
  id: "gemini",
42363
42435
  label: "Gemini CLI",
42364
42436
  envVar: "GEMINI_CONFIG_DIR",
42365
- defaultDir: join3(homedir3(), ".gemini"),
42437
+ defaultDir: join4(homedir3(), ".gemini"),
42366
42438
  bin: "gemini",
42367
42439
  loginHint: "complete Gemini auth in this GEMINI_CONFIG_DIR",
42368
42440
  permissionArgs: {
@@ -42380,7 +42452,7 @@ var BUILTIN_TOOLS = [
42380
42452
  XDG_CONFIG_HOME: "{profileDir}/xdg-config",
42381
42453
  XDG_DATA_HOME: "{profileDir}/xdg-data"
42382
42454
  },
42383
- defaultDir: join3(homedir3(), ".config", "opencode"),
42455
+ defaultDir: join4(homedir3(), ".config", "opencode"),
42384
42456
  bin: "opencode",
42385
42457
  loginArgs: ["auth", "login"],
42386
42458
  loginHint: "complete opencode auth login for this isolated config/data root",
@@ -42390,7 +42462,7 @@ var BUILTIN_TOOLS = [
42390
42462
  id: "cursor",
42391
42463
  label: "Cursor Agent",
42392
42464
  envVar: "CURSOR_CONFIG_DIR",
42393
- defaultDir: join3(homedir3(), ".cursor"),
42465
+ defaultDir: join4(homedir3(), ".cursor"),
42394
42466
  bin: "cursor-agent",
42395
42467
  loginArgs: ["login"],
42396
42468
  loginHint: "complete cursor-agent login for this CURSOR_CONFIG_DIR"
@@ -42399,7 +42471,7 @@ var BUILTIN_TOOLS = [
42399
42471
  id: "pi",
42400
42472
  label: "Pi Coding Agent",
42401
42473
  envVar: "PI_CODING_AGENT_HOME",
42402
- defaultDir: join3(homedir3(), ".pi"),
42474
+ defaultDir: join4(homedir3(), ".pi"),
42403
42475
  bin: "pi",
42404
42476
  loginHint: "complete Pi coding agent auth in this PI_CODING_AGENT_HOME"
42405
42477
  },
@@ -42407,7 +42479,7 @@ var BUILTIN_TOOLS = [
42407
42479
  id: "hermes",
42408
42480
  label: "Hermes",
42409
42481
  envVar: "HERMES_HOME",
42410
- defaultDir: join3(homedir3(), ".hermes"),
42482
+ defaultDir: join4(homedir3(), ".hermes"),
42411
42483
  bin: "hermes",
42412
42484
  loginHint: "complete Hermes auth in this HERMES_HOME",
42413
42485
  permissionArgs: {
@@ -42419,7 +42491,7 @@ var BUILTIN_TOOLS = [
42419
42491
  id: "kimi",
42420
42492
  label: "Kimi Code",
42421
42493
  envVar: "KIMI_CODE_HOME",
42422
- defaultDir: join3(homedir3(), ".kimi-code"),
42494
+ defaultDir: join4(homedir3(), ".kimi-code"),
42423
42495
  bin: "kimi",
42424
42496
  loginArgs: ["login"],
42425
42497
  loginHint: "complete kimi login for this KIMI_CODE_HOME",
@@ -42434,7 +42506,7 @@ var BUILTIN_TOOLS = [
42434
42506
  id: "grok",
42435
42507
  label: "Grok Build",
42436
42508
  envVar: "HOME",
42437
- defaultDir: join3(homedir3(), ".grok"),
42509
+ defaultDir: join4(homedir3(), ".grok"),
42438
42510
  bin: "grok",
42439
42511
  loginArgs: ["login"],
42440
42512
  loginHint: "complete grok login in this process-scoped HOME; prefer launch/shell over exporting HOME globally"
@@ -42541,18 +42613,18 @@ function removeCustomTool(id) {
42541
42613
 
42542
42614
  // src/lib/profiles.ts
42543
42615
  import { homedir as homedir4 } from "node:os";
42544
- 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";
42545
42617
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, rmSync } from "node:fs";
42546
42618
 
42547
42619
  // src/lib/detect.ts
42548
42620
  import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
42549
- import { dirname as dirname2, join as join4 } from "node:path";
42621
+ import { dirname as dirname2, join as join5 } from "node:path";
42550
42622
  function detectEmail(dir, tool) {
42551
42623
  if (!tool.accountFile || !tool.emailPath)
42552
42624
  return;
42553
- const candidates = [join4(dir, tool.accountFile)];
42625
+ const candidates = [join5(dir, tool.accountFile)];
42554
42626
  if (dir === tool.defaultDir)
42555
- candidates.push(join4(dirname2(dir), tool.accountFile));
42627
+ candidates.push(join5(dirname2(dir), tool.accountFile));
42556
42628
  for (const file of candidates) {
42557
42629
  const email = readEmail(file, tool.emailPath);
42558
42630
  if (email)
@@ -42588,8 +42660,8 @@ function expandPath(p) {
42588
42660
  if (out === "~")
42589
42661
  out = homedir4();
42590
42662
  else if (out.startsWith("~/"))
42591
- out = join5(homedir4(), out.slice(2));
42592
- return isAbsolute(out) ? out : resolve2(process.cwd(), out);
42663
+ out = join6(homedir4(), out.slice(2));
42664
+ return isAbsolute2(out) ? out : resolve2(process.cwd(), out);
42593
42665
  }
42594
42666
  function listProfiles(toolId) {
42595
42667
  const profiles = loadStore().profiles;
@@ -42600,8 +42672,8 @@ function profileMatches(name, toolId) {
42600
42672
  return loadStore().profiles.filter((p) => p.name === name && (!toolId || p.tool === toolId));
42601
42673
  }
42602
42674
  function isManagedProfileDir(dir) {
42603
- const rel = relative(resolve2(profilesDir()), resolve2(dir));
42604
- return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
42675
+ const rel = relative2(resolve2(profilesDir()), resolve2(dir));
42676
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
42605
42677
  }
42606
42678
  function getProfile(name, toolId) {
42607
42679
  const matches = profileMatches(name, toolId);
@@ -42626,7 +42698,7 @@ function addProfile(opts) {
42626
42698
  if (store.profiles.some((p) => p.name === name && p.tool === toolId)) {
42627
42699
  throw new AccountsError(`a ${toolId} profile named "${name}" already exists`);
42628
42700
  }
42629
- const dir = opts.dir ? expandPath(opts.dir) : join5(profilesDir(), toolId, name);
42701
+ const dir = opts.dir ? expandPath(opts.dir) : join6(profilesDir(), toolId, name);
42630
42702
  if (store.profiles.some((p) => p.dir === dir)) {
42631
42703
  throw new AccountsError(`a profile already uses config dir ${dir}`);
42632
42704
  }
@@ -42768,11 +42840,11 @@ function currentProfile(toolId) {
42768
42840
 
42769
42841
  // src/lib/claude-auth.ts
42770
42842
  import { copyFileSync, existsSync as existsSync6, lstatSync as lstatSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync3, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
42771
- import { dirname as dirname4, join as join7 } from "node:path";
42843
+ import { dirname as dirname4, join as join8 } from "node:path";
42772
42844
 
42773
42845
  // src/lib/claude-layout.ts
42774
42846
  import { homedir as homedir5 } from "node:os";
42775
- import { dirname as dirname3, join as join6 } from "node:path";
42847
+ import { dirname as dirname3, join as join7 } from "node:path";
42776
42848
  var CLAUDE_KEYCHAIN_SERVICE = "Claude Code-credentials";
42777
42849
  var ACCOUNTS_AUTH_DIR = ".accounts-auth";
42778
42850
  var OAUTH_SNAPSHOT = "oauth-account.json";
@@ -42784,32 +42856,32 @@ function liveClaudeBase() {
42784
42856
  }
42785
42857
  function liveClaudePaths() {
42786
42858
  const base = liveClaudeBase();
42787
- const configDir = join6(base, ".claude");
42859
+ const configDir = join7(base, ".claude");
42788
42860
  return {
42789
42861
  configDir,
42790
- homeJson: join6(base, ".claude.json"),
42791
- credentialsFile: join6(configDir, ".credentials.json")
42862
+ homeJson: join7(base, ".claude.json"),
42863
+ credentialsFile: join7(configDir, ".credentials.json")
42792
42864
  };
42793
42865
  }
42794
42866
  function profileAccountJsonPaths(profileDir, tool) {
42795
42867
  if (!tool.accountFile)
42796
42868
  return [];
42797
- const paths = [join6(profileDir, tool.accountFile)];
42869
+ const paths = [join7(profileDir, tool.accountFile)];
42798
42870
  if (profileDir === tool.defaultDir)
42799
- paths.push(join6(dirname3(profileDir), tool.accountFile));
42871
+ paths.push(join7(dirname3(profileDir), tool.accountFile));
42800
42872
  return paths;
42801
42873
  }
42802
42874
  function profileAuthDir(profileDir) {
42803
- return join6(profileDir, ACCOUNTS_AUTH_DIR);
42875
+ return join7(profileDir, ACCOUNTS_AUTH_DIR);
42804
42876
  }
42805
42877
  function profileOAuthSnapshot(profileDir) {
42806
- return join6(profileAuthDir(profileDir), OAUTH_SNAPSHOT);
42878
+ return join7(profileAuthDir(profileDir), OAUTH_SNAPSHOT);
42807
42879
  }
42808
42880
  function profileCredentialsSnapshot(profileDir) {
42809
- return join6(profileAuthDir(profileDir), CREDENTIALS_SNAPSHOT);
42881
+ return join7(profileAuthDir(profileDir), CREDENTIALS_SNAPSHOT);
42810
42882
  }
42811
42883
  function profileKeychainSnapshot(profileDir) {
42812
- return join6(profileAuthDir(profileDir), KEYCHAIN_SNAPSHOT);
42884
+ return join7(profileAuthDir(profileDir), KEYCHAIN_SNAPSHOT);
42813
42885
  }
42814
42886
 
42815
42887
  // src/lib/keychain.ts
@@ -42963,7 +43035,7 @@ function mergeOAuthInto(paths, oauth, allowDelete, stayUnder) {
42963
43035
  }
42964
43036
  }
42965
43037
  function sanitizeSettingsFile(configDir, stayUnder) {
42966
- const settingsPath = join7(configDir, "settings.json");
43038
+ const settingsPath = join8(configDir, "settings.json");
42967
43039
  const settings = readJsonFile(settingsPath);
42968
43040
  if (!settings)
42969
43041
  return false;
@@ -43010,7 +43082,7 @@ function liveOAuthEmail() {
43010
43082
  }
43011
43083
  function snapshotLiveAuthToProfile(profileDir, _tool) {
43012
43084
  const authDir = profileAuthDir(profileDir);
43013
- assertSafeWritePath(join7(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43085
+ assertSafeWritePath(join8(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43014
43086
  mkdirSync4(authDir, { recursive: true });
43015
43087
  const live = liveClaudePaths();
43016
43088
  const oauth = readOAuthFromPaths([live.homeJson]);
@@ -43029,14 +43101,14 @@ function snapshotLiveAuthToProfile(profileDir, _tool) {
43029
43101
  }
43030
43102
  function ensureProfileAuthSnapshot(profileDir, tool, opts = {}) {
43031
43103
  const authDir = profileAuthDir(profileDir);
43032
- assertSafeWritePath(join7(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43104
+ assertSafeWritePath(join8(authDir, OAUTH_SNAPSHOT), { mustStayUnder: profileDir });
43033
43105
  mkdirSync4(authDir, { recursive: true });
43034
43106
  const oauthSource = findOAuthSource(profileAccountJsonPaths(profileDir, tool));
43035
43107
  const oauthSnap = profileOAuthSnapshot(profileDir);
43036
43108
  if (oauthSource && (opts.overwrite || snapshotIsStale(oauthSource.path, oauthSnap))) {
43037
43109
  writeJsonFile(oauthSnap, { oauthAccount: oauthSource.oauth }, profileDir);
43038
43110
  }
43039
- const credFile = join7(profileDir, ".credentials.json");
43111
+ const credFile = join8(profileDir, ".credentials.json");
43040
43112
  const credSnap = profileCredentialsSnapshot(profileDir);
43041
43113
  if (existsSync6(credFile) && (opts.overwrite || snapshotIsStale(credFile, credSnap))) {
43042
43114
  assertSafeWritePath(credSnap, { mustStayUnder: profileDir });
@@ -43098,9 +43170,9 @@ function hasAuthSnapshot(profileDir) {
43098
43170
 
43099
43171
  // src/lib/apply-lock.ts
43100
43172
  import { closeSync, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
43101
- import { join as join8 } from "node:path";
43173
+ import { join as join9 } from "node:path";
43102
43174
  function lockPath() {
43103
- return join8(accountsHome(), ".apply.lock");
43175
+ return join9(accountsHome(), ".apply.lock");
43104
43176
  }
43105
43177
  function withApplyLock(fn) {
43106
43178
  const home = accountsHome();
@@ -43349,7 +43421,7 @@ function listAgentsAcrossProfiles(opts = {}) {
43349
43421
 
43350
43422
  // src/lib/import-profile.ts
43351
43423
  import { cpSync, existsSync as existsSync9 } from "node:fs";
43352
- import { join as join9 } from "node:path";
43424
+ import { join as join10 } from "node:path";
43353
43425
  function importProfile(opts) {
43354
43426
  const toolId = opts.tool ?? DEFAULT_TOOL;
43355
43427
  const tool = getTool(toolId);
@@ -43359,7 +43431,7 @@ function importProfile(opts) {
43359
43431
  throw new AccountsError(`config dir does not exist: ${sourceDir}`);
43360
43432
  }
43361
43433
  if (opts.copy) {
43362
- const targetDir = join9(profilesDir(), toolId, name);
43434
+ const targetDir = join10(profilesDir(), toolId, name);
43363
43435
  if (existsSync9(targetDir)) {
43364
43436
  throw new AccountsError(`managed copy target already exists: ${targetDir}`);
43365
43437
  }
@@ -43445,7 +43517,7 @@ async function pickProfile(opts = {}) {
43445
43517
 
43446
43518
  // src/lib/hook.ts
43447
43519
  import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "node:fs";
43448
- import { join as join10 } from "node:path";
43520
+ import { join as join11 } from "node:path";
43449
43521
  var HOOK_FILE = "claude-hook.sh";
43450
43522
  var MARKER = "# accounts-claude-hook";
43451
43523
  var NAME_PATTERN = "^[a-z0-9][a-z0-9-]*$";
@@ -43453,7 +43525,7 @@ function shellQuotePath(path) {
43453
43525
  return `'${path.replace(/'/g, `'\\''`)}'`;
43454
43526
  }
43455
43527
  function hookPath() {
43456
- return join10(accountsHome(), HOOK_FILE);
43528
+ return join11(accountsHome(), HOOK_FILE);
43457
43529
  }
43458
43530
  function hookScript() {
43459
43531
  const quotedHook = shellQuotePath(hookPath());
@@ -43504,7 +43576,7 @@ function shellSnippet() {
43504
43576
 
43505
43577
  // src/lib/codex-app.ts
43506
43578
  import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
43507
- import { join as join11 } from "node:path";
43579
+ import { join as join12 } from "node:path";
43508
43580
  var FILE_CREDENTIALS_LINE = 'cli_auth_credentials_store = "file"';
43509
43581
  function insertRootConfigLine(config, line) {
43510
43582
  if (config.trim() === "")
@@ -43531,7 +43603,7 @@ ${after}${after.endsWith(`
43531
43603
  }
43532
43604
  function ensureCodexAppProfileConfig(profileDir) {
43533
43605
  mkdirSync7(profileDir, { recursive: true });
43534
- const configPath = join11(profileDir, "config.toml");
43606
+ const configPath = join12(profileDir, "config.toml");
43535
43607
  const current = existsSync11(configPath) ? readFileSync6(configPath, "utf8") : "";
43536
43608
  if (/^\s*cli_auth_credentials_store\s*=/.test(current))
43537
43609
  return;
@@ -43631,20 +43703,20 @@ import { spawn as spawn2 } from "node:child_process";
43631
43703
  import { createHash } from "node:crypto";
43632
43704
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync7, readdirSync, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
43633
43705
  import { createConnection, createServer } from "node:net";
43634
- import { basename, join as join12 } from "node:path";
43706
+ import { basename, join as join13 } from "node:path";
43635
43707
  var STATE_SUFFIX = ".json";
43636
43708
  function supervisorDir() {
43637
- return join12(accountsHome(), "supervisors");
43709
+ return join13(accountsHome(), "supervisors");
43638
43710
  }
43639
43711
  function supervisorStatePath(toolId) {
43640
- return join12(supervisorDir(), `${toolId}${STATE_SUFFIX}`);
43712
+ return join13(supervisorDir(), `${toolId}${STATE_SUFFIX}`);
43641
43713
  }
43642
43714
  function supervisorSocketPath(toolId) {
43643
43715
  if (process.platform === "win32") {
43644
43716
  const hash = createHash("sha1").update(accountsHome()).digest("hex").slice(0, 12);
43645
43717
  return `\\\\.\\pipe\\hasna-accounts-${hash}-${toolId}`;
43646
43718
  }
43647
- return join12(supervisorDir(), `${toolId}.sock`);
43719
+ return join13(supervisorDir(), `${toolId}.sock`);
43648
43720
  }
43649
43721
  function nowIso2() {
43650
43722
  return new Date().toISOString();
@@ -44242,7 +44314,7 @@ program2.command("switch").argument("<name>", "profile name").argument("[args...
44242
44314
  }
44243
44315
  }));
44244
44316
  var hook = program2.command("hook").description("install a shell wrapper for claude");
44245
- 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(() => {
44246
44318
  const { path, created } = installHook();
44247
44319
  console.log(source_default.green(created ? `✓ installed hook at ${path}` : `✓ updated hook at ${path}`));
44248
44320
  console.log(source_default.dim(` add to ~/.zshrc: ${shellSnippet()}`));
@@ -44482,7 +44554,7 @@ tools.command("add").argument("<id>", "tool id, e.g. cursor").description("regis
44482
44554
  label: opts.label,
44483
44555
  envVar: opts.envVar,
44484
44556
  bin: opts.bin,
44485
- defaultDir: opts.defaultDir ? expandPath(opts.defaultDir) : join13(homedir6(), `.${id}`),
44557
+ defaultDir: opts.defaultDir ? expandPath(opts.defaultDir) : join14(homedir6(), `.${id}`),
44486
44558
  ...Object.keys(extraEnv).length > 0 ? { extraEnv } : {},
44487
44559
  ...opts.loginArg ? { loginArgs: opts.loginArg } : {},
44488
44560
  ...opts.launchArg ? { launchArgs: opts.launchArg } : {},
@@ -44554,7 +44626,7 @@ program2.parseAsync(process.argv);
44554
44626
  function getVersion() {
44555
44627
  try {
44556
44628
  const here = dirname5(fileURLToPath(import.meta.url));
44557
- 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")]) {
44558
44630
  if (existsSync13(candidate)) {
44559
44631
  const pkg = JSON.parse(readFileSync8(candidate, "utf8"));
44560
44632
  if (pkg.version)