cc-claw 0.16.0 → 0.16.2

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.
Files changed (2) hide show
  1. package/dist/cli.js +186 -45
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ var VERSION;
33
33
  var init_version = __esm({
34
34
  "src/version.ts"() {
35
35
  "use strict";
36
- VERSION = true ? "0.16.0" : (() => {
36
+ VERSION = true ? "0.16.2" : (() => {
37
37
  try {
38
38
  return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
39
39
  } catch {
@@ -3339,16 +3339,16 @@ var init_gemini_slots = __esm({
3339
3339
  function getBackendSlots(backend2) {
3340
3340
  return getDb().prepare(`
3341
3341
  SELECT ${SLOT_COLUMNS}
3342
- FROM backend_credentials WHERE backend = ? ORDER BY priority ASC, id ASC
3342
+ FROM backend_credentials bc WHERE bc.backend = ? ORDER BY bc.priority ASC, bc.id ASC
3343
3343
  `).all(backend2);
3344
3344
  }
3345
3345
  function getEligibleBackendSlots(backend2) {
3346
3346
  return getDb().prepare(`
3347
3347
  SELECT ${SLOT_COLUMNS}
3348
- FROM backend_credentials
3349
- WHERE backend = ? AND enabled = 1
3350
- AND (cooldown_until IS NULL OR cooldown_until <= datetime('now'))
3351
- ORDER BY priority ASC, last_used ASC NULLS FIRST
3348
+ FROM backend_credentials bc
3349
+ WHERE bc.backend = ? AND bc.enabled = 1
3350
+ AND (bc.cooldown_until IS NULL OR bc.cooldown_until <= datetime('now'))
3351
+ ORDER BY bc.priority ASC, bc.last_used ASC NULLS FIRST
3352
3352
  `).all(backend2);
3353
3353
  }
3354
3354
  function getChatBackendSlotId(chatId, backend2) {
@@ -3425,9 +3425,9 @@ var init_backend_slots = __esm({
3425
3425
  "use strict";
3426
3426
  init_store5();
3427
3427
  SLOT_COLUMNS = `
3428
- id, backend, slot_type AS slotType, label, api_key AS apiKey, config_home AS configHome,
3429
- priority, enabled, cooldown_until AS cooldownUntil, last_used AS lastUsed,
3430
- consecutive_errors AS consecutiveErrors, created_at AS createdAt
3428
+ bc.id, bc.backend, bc.slot_type AS slotType, bc.label, bc.api_key AS apiKey, bc.config_home AS configHome,
3429
+ bc.priority, bc.enabled, bc.cooldown_until AS cooldownUntil, bc.last_used AS lastUsed,
3430
+ bc.consecutive_errors AS consecutiveErrors, bc.created_at AS createdAt
3431
3431
  `;
3432
3432
  }
3433
3433
  });
@@ -9932,11 +9932,11 @@ var init_evolve = __esm({
9932
9932
  const body = JSON.parse(await readBody(req));
9933
9933
  const { setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
9934
9934
  const { existsSync: fileExists, readFileSync: fileRead } = await import("fs");
9935
- const { join: join28 } = await import("path");
9935
+ const { join: join29 } = await import("path");
9936
9936
  const { CC_CLAW_HOME: home } = await Promise.resolve().then(() => (init_paths(), paths_exports));
9937
9937
  const chatId = body.chatId || (process.env.ALLOWED_CHAT_ID ?? "").split(",")[0]?.trim() || "default";
9938
- const soulPath = join28(home, "identity/SOUL.md");
9939
- const userPath = join28(home, "identity/USER.md");
9938
+ const soulPath = join29(home, "identity/SOUL.md");
9939
+ const userPath = join29(home, "identity/USER.md");
9940
9940
  const soul = fileExists(soulPath) ? fileRead(soulPath, "utf-8") : "";
9941
9941
  const user = fileExists(userPath) ? fileRead(userPath, "utf-8") : "";
9942
9942
  setReflectionStatus2(getDb(), chatId, "active", soul, user);
@@ -13697,7 +13697,9 @@ var init_guard = __esm({
13697
13697
  /\bnpm\s+(start|run\s+dev)\b/,
13698
13698
  // daemon-starting npm commands
13699
13699
  // CC-Claw config mutation — agents must not silently change backend/model/permissions
13700
- /\bcc-claw\s+(backend|model|permissions)\s+set\b/
13700
+ /\bcc-claw\s+(backend|model|permissions)\s+set\b/,
13701
+ // Direct database access — agents must use the CLI/API, never raw SQL
13702
+ /\bsqlite3\b.*\bcc-claw\b/
13701
13703
  ];
13702
13704
  pendingCommands = /* @__PURE__ */ new Map();
13703
13705
  PENDING_TTL_MS = 5 * 60 * 1e3;
@@ -15902,13 +15904,13 @@ async function handleEvolveCallback(chatId, data, channel) {
15902
15904
  const { getReflectionStatus: getReflectionStatus2, setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
15903
15905
  const current = getReflectionStatus2(getDb(), chatId);
15904
15906
  if (current === "frozen") {
15905
- const { readFileSync: readFileSync21, existsSync: existsSync49 } = await import("fs");
15906
- const { join: join28 } = await import("path");
15907
+ const { readFileSync: readFileSync22, existsSync: existsSync49 } = await import("fs");
15908
+ const { join: join29 } = await import("path");
15907
15909
  const { CC_CLAW_HOME: CC_CLAW_HOME3 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
15908
- const soulPath = join28(CC_CLAW_HOME3, "identity/SOUL.md");
15909
- const userPath = join28(CC_CLAW_HOME3, "identity/USER.md");
15910
- const soul = existsSync49(soulPath) ? readFileSync21(soulPath, "utf-8") : "";
15911
- const user = existsSync49(userPath) ? readFileSync21(userPath, "utf-8") : "";
15910
+ const soulPath = join29(CC_CLAW_HOME3, "identity/SOUL.md");
15911
+ const userPath = join29(CC_CLAW_HOME3, "identity/USER.md");
15912
+ const soul = existsSync49(soulPath) ? readFileSync22(soulPath, "utf-8") : "";
15913
+ const user = existsSync49(userPath) ? readFileSync22(userPath, "utf-8") : "";
15912
15914
  setReflectionStatus2(getDb(), chatId, "active", soul, user);
15913
15915
  const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
15914
15916
  logActivity2(getDb(), { chatId, source: "telegram", eventType: "reflection_unfrozen", summary: "Reflection enabled" });
@@ -20041,6 +20043,8 @@ var init_telegram2 = __esm({
20041
20043
  { command: "claude", description: "Switch to Claude backend" },
20042
20044
  { command: "gemini", description: "Switch to Gemini backend" },
20043
20045
  { command: "gemini_accounts", description: "Manage Gemini credentials & rotation" },
20046
+ { command: "claude_accounts", description: "Manage Claude credentials & rotation" },
20047
+ { command: "codex_accounts", description: "Manage Codex credentials & rotation" },
20044
20048
  { command: "codex", description: "Switch to Codex backend" },
20045
20049
  { command: "cursor", description: "Switch to Cursor backend" },
20046
20050
  { command: "model", description: "Switch model for active backend" },
@@ -21395,11 +21399,11 @@ async function main() {
21395
21399
  bootstrapSkills().catch((err) => error("[cc-claw] Skill bootstrap failed:", err));
21396
21400
  try {
21397
21401
  const { generateAiSkill: generateAiSkill2 } = await Promise.resolve().then(() => (init_ai_skill(), ai_skill_exports));
21398
- const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync16 } = await import("fs");
21399
- const { join: join28 } = await import("path");
21400
- const skillDir = join28(SKILLS_PATH, "cc-claw-cli");
21401
- mkdirSync16(skillDir, { recursive: true });
21402
- writeFileSync12(join28(skillDir, "SKILL.md"), generateAiSkill2(), "utf-8");
21402
+ const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync17 } = await import("fs");
21403
+ const { join: join29 } = await import("path");
21404
+ const skillDir = join29(SKILLS_PATH, "cc-claw-cli");
21405
+ mkdirSync17(skillDir, { recursive: true });
21406
+ writeFileSync12(join29(skillDir, "SKILL.md"), generateAiSkill2(), "utf-8");
21403
21407
  log("[cc-claw] AI skill updated");
21404
21408
  } catch {
21405
21409
  }
@@ -22284,8 +22288,8 @@ async function doctorCommand(globalOpts, localOpts) {
22284
22288
  }
22285
22289
  if (existsSync25(ERROR_LOG_PATH)) {
22286
22290
  try {
22287
- const { readFileSync: readFileSync21 } = await import("fs");
22288
- const logContent = readFileSync21(ERROR_LOG_PATH, "utf-8");
22291
+ const { readFileSync: readFileSync22 } = await import("fs");
22292
+ const logContent = readFileSync22(ERROR_LOG_PATH, "utf-8");
22289
22293
  const recentLines = logContent.split("\n").filter(Boolean).slice(-100);
22290
22294
  const last24h = Date.now() - 864e5;
22291
22295
  const recentErrors = recentLines.filter((line) => {
@@ -22711,6 +22715,7 @@ var init_gemini2 = __esm({
22711
22715
  // src/cli/commands/backend-cmd-factory.ts
22712
22716
  var backend_cmd_factory_exports = {};
22713
22717
  __export(backend_cmd_factory_exports, {
22718
+ makeAddAccount: () => makeAddAccount,
22714
22719
  makeAddKey: () => makeAddKey,
22715
22720
  makeDisable: () => makeDisable,
22716
22721
  makeEnable: () => makeEnable,
@@ -22720,7 +22725,8 @@ __export(backend_cmd_factory_exports, {
22720
22725
  makeReorder: () => makeReorder,
22721
22726
  registerBackendSlotCommands: () => registerBackendSlotCommands
22722
22727
  });
22723
- import { existsSync as existsSync28 } from "fs";
22728
+ import { existsSync as existsSync28, mkdirSync as mkdirSync13, readFileSync as readFileSync18 } from "fs";
22729
+ import { join as join26 } from "path";
22724
22730
  import { createInterface as createInterface6 } from "readline";
22725
22731
  function requireDb2() {
22726
22732
  if (!existsSync28(DB_PATH)) {
@@ -22757,7 +22763,7 @@ function makeList(backend2, displayName) {
22757
22763
  readDb.close();
22758
22764
  if (slots.length === 0) {
22759
22765
  output({ slots: [] }, () => `No ${displayName} credential slots configured.
22760
- Add one with: cc-claw ${backend2} add-key`);
22766
+ Add one with: cc-claw ${backend2} add-account or cc-claw ${backend2} add-key`);
22761
22767
  return;
22762
22768
  }
22763
22769
  output(slots, (data) => {
@@ -22804,6 +22810,62 @@ function makeAddKey(backend2, displayName) {
22804
22810
  );
22805
22811
  };
22806
22812
  }
22813
+ function makeAddAccount(backend2, displayName) {
22814
+ return async function addAccount(_globalOpts, opts) {
22815
+ const config2 = ADD_ACCOUNT_CONFIGS[backend2];
22816
+ if (!config2) {
22817
+ outputError("UNSUPPORTED", `add-account is not supported for ${displayName}. Use add-key instead.`);
22818
+ process.exit(1);
22819
+ }
22820
+ await requireWriteDb2();
22821
+ const slotsDir = join26(CC_CLAW_HOME, config2.slotsSubdir);
22822
+ if (!existsSync28(slotsDir)) mkdirSync13(slotsDir, { recursive: true });
22823
+ const tempId = Date.now();
22824
+ const slotDir = join26(slotsDir, `slot-${tempId}`);
22825
+ mkdirSync13(slotDir, { recursive: true, mode: 448 });
22826
+ if (config2.preSetup) config2.preSetup(slotDir);
22827
+ console.log("");
22828
+ console.log(` Opening ${displayName} CLI for sign-in...`);
22829
+ console.log(` Sign in with the account you want for this slot.`);
22830
+ console.log(` After sign-in completes, return here.`);
22831
+ console.log("");
22832
+ const { execSync: execSync8 } = await import("child_process");
22833
+ const loginEnv = {
22834
+ ...process.env,
22835
+ [config2.envKey]: config2.envValue(slotDir),
22836
+ ...config2.envOverrides
22837
+ };
22838
+ try {
22839
+ execSync8(config2.loginCommand.join(" "), {
22840
+ stdio: "inherit",
22841
+ env: loginEnv,
22842
+ cwd: slotDir
22843
+ });
22844
+ } catch {
22845
+ }
22846
+ if (!config2.verifyCredentials(slotDir)) {
22847
+ console.log(error2(`
22848
+ No credentials found. Sign-in may have failed.`));
22849
+ console.log(` The slot directory is preserved at: ${slotDir}`);
22850
+ console.log(` Re-run: cc-claw ${backend2} add-account
22851
+ `);
22852
+ process.exit(1);
22853
+ }
22854
+ const accountLabel = opts.label || config2.extractLabel(slotDir);
22855
+ const { addBackendSlot: addBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
22856
+ const id = addBackendSlot2({
22857
+ backend: backend2,
22858
+ slotType: "oauth",
22859
+ label: accountLabel,
22860
+ configHome: slotDir,
22861
+ priority: opts.priority ? parseInt(opts.priority, 10) : 0
22862
+ });
22863
+ output(
22864
+ { id, type: "oauth", backend: backend2, label: accountLabel, configHome: slotDir },
22865
+ () => success(`Added ${displayName} subscription slot #${id} (${accountLabel})`)
22866
+ );
22867
+ };
22868
+ }
22807
22869
  function makeRemove(backend2, displayName) {
22808
22870
  return async function remove(_globalOpts, idOrLabel) {
22809
22871
  await requireWriteDb2();
@@ -22906,13 +22968,88 @@ function registerBackendSlotCommands(parentCommand, backend2, displayName, globa
22906
22968
  });
22907
22969
  return cmd;
22908
22970
  }
22909
- var dbInitialized2;
22971
+ var dbInitialized2, ADD_ACCOUNT_CONFIGS;
22910
22972
  var init_backend_cmd_factory = __esm({
22911
22973
  "src/cli/commands/backend-cmd-factory.ts"() {
22912
22974
  "use strict";
22913
22975
  init_format2();
22914
22976
  init_paths();
22915
22977
  dbInitialized2 = false;
22978
+ ADD_ACCOUNT_CONFIGS = {
22979
+ claude: {
22980
+ slotsSubdir: "claude-slots",
22981
+ loginCommand: ["claude", "auth", "login", "--claudeai"],
22982
+ envKey: "HOME",
22983
+ envValue: (slotDir) => slotDir,
22984
+ envOverrides: { ANTHROPIC_API_KEY: void 0 },
22985
+ preSetup: (slotDir) => {
22986
+ mkdirSync13(join26(slotDir, ".claude"), { recursive: true });
22987
+ },
22988
+ verifyCredentials: (slotDir) => {
22989
+ const claudeJson = join26(slotDir, ".claude.json");
22990
+ const claudeJsonNested = join26(slotDir, ".claude", ".claude.json");
22991
+ if (existsSync28(claudeJson)) {
22992
+ try {
22993
+ const data = JSON.parse(readFileSync18(claudeJson, "utf-8"));
22994
+ return Boolean(data.oauthAccount);
22995
+ } catch {
22996
+ return false;
22997
+ }
22998
+ }
22999
+ if (existsSync28(claudeJsonNested)) {
23000
+ try {
23001
+ const data = JSON.parse(readFileSync18(claudeJsonNested, "utf-8"));
23002
+ return Boolean(data.oauthAccount);
23003
+ } catch {
23004
+ return false;
23005
+ }
23006
+ }
23007
+ return false;
23008
+ },
23009
+ extractLabel: (slotDir) => {
23010
+ try {
23011
+ const { execSync: execSync8 } = __require("child_process");
23012
+ const out = execSync8("claude auth status", {
23013
+ encoding: "utf-8",
23014
+ env: { ...process.env, HOME: slotDir, ANTHROPIC_API_KEY: void 0 },
23015
+ timeout: 1e4
23016
+ });
23017
+ const parsed = JSON.parse(out);
23018
+ if (parsed.email) return parsed.email;
23019
+ } catch {
23020
+ }
23021
+ try {
23022
+ const claudeJson = join26(slotDir, ".claude.json");
23023
+ if (existsSync28(claudeJson)) {
23024
+ const data = JSON.parse(readFileSync18(claudeJson, "utf-8"));
23025
+ if (data.oauthAccount?.emailAddress) return data.oauthAccount.emailAddress;
23026
+ }
23027
+ } catch {
23028
+ }
23029
+ return "subscription";
23030
+ }
23031
+ },
23032
+ codex: {
23033
+ slotsSubdir: "codex-slots",
23034
+ loginCommand: ["codex", "login"],
23035
+ envKey: "CODEX_HOME",
23036
+ envValue: (slotDir) => slotDir,
23037
+ envOverrides: { OPENAI_API_KEY: void 0 },
23038
+ verifyCredentials: (slotDir) => {
23039
+ return existsSync28(join26(slotDir, "auth.json"));
23040
+ },
23041
+ extractLabel: (slotDir) => {
23042
+ try {
23043
+ const authData = JSON.parse(readFileSync18(join26(slotDir, "auth.json"), "utf-8"));
23044
+ if (authData.email) return authData.email;
23045
+ if (authData.account_name) return authData.account_name;
23046
+ if (authData.user?.email) return authData.user.email;
23047
+ } catch {
23048
+ }
23049
+ return "subscription";
23050
+ }
23051
+ }
23052
+ };
22916
23053
  }
22917
23054
  });
22918
23055
 
@@ -23608,7 +23745,7 @@ __export(db_exports, {
23608
23745
  dbPath: () => dbPath,
23609
23746
  dbStats: () => dbStats
23610
23747
  });
23611
- import { existsSync as existsSync34, statSync as statSync8, copyFileSync as copyFileSync2, mkdirSync as mkdirSync13 } from "fs";
23748
+ import { existsSync as existsSync34, statSync as statSync8, copyFileSync as copyFileSync2, mkdirSync as mkdirSync14 } from "fs";
23612
23749
  import { dirname as dirname5 } from "path";
23613
23750
  async function dbStats(globalOpts) {
23614
23751
  if (!existsSync34(DB_PATH)) {
@@ -23659,7 +23796,7 @@ async function dbBackup(globalOpts, destPath) {
23659
23796
  }
23660
23797
  const dest = destPath ?? `${DB_PATH}.backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
23661
23798
  try {
23662
- mkdirSync13(dirname5(dest), { recursive: true });
23799
+ mkdirSync14(dirname5(dest), { recursive: true });
23663
23800
  copyFileSync2(DB_PATH, dest);
23664
23801
  const walPath = DB_PATH + "-wal";
23665
23802
  if (existsSync34(walPath)) copyFileSync2(walPath, dest + "-wal");
@@ -23883,7 +24020,7 @@ __export(config_exports2, {
23883
24020
  configList: () => configList,
23884
24021
  configSet: () => configSet
23885
24022
  });
23886
- import { existsSync as existsSync36, readFileSync as readFileSync18 } from "fs";
24023
+ import { existsSync as existsSync36, readFileSync as readFileSync19 } from "fs";
23887
24024
  async function configList(globalOpts) {
23888
24025
  if (!existsSync36(DB_PATH)) {
23889
24026
  outputError("DB_NOT_FOUND", "Database not found.");
@@ -23969,7 +24106,7 @@ async function configEnv(_globalOpts) {
23969
24106
  outputError("ENV_NOT_FOUND", `No .env file at ${ENV_PATH}. Run cc-claw setup.`);
23970
24107
  process.exit(1);
23971
24108
  }
23972
- const content = readFileSync18(ENV_PATH, "utf-8");
24109
+ const content = readFileSync19(ENV_PATH, "utf-8");
23973
24110
  const entries = {};
23974
24111
  const secretPatterns = /TOKEN|KEY|SECRET|PASSWORD|CREDENTIALS/i;
23975
24112
  for (const line of content.split("\n")) {
@@ -24718,11 +24855,11 @@ __export(chat_exports2, {
24718
24855
  chatSend: () => chatSend
24719
24856
  });
24720
24857
  import { request as httpRequest2 } from "http";
24721
- import { readFileSync as readFileSync19, existsSync as existsSync46 } from "fs";
24858
+ import { readFileSync as readFileSync20, existsSync as existsSync46 } from "fs";
24722
24859
  function getToken2() {
24723
24860
  if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
24724
24861
  try {
24725
- if (existsSync46(TOKEN_PATH2)) return readFileSync19(TOKEN_PATH2, "utf-8").trim();
24862
+ if (existsSync46(TOKEN_PATH2)) return readFileSync20(TOKEN_PATH2, "utf-8").trim();
24726
24863
  } catch {
24727
24864
  }
24728
24865
  return null;
@@ -25001,8 +25138,8 @@ var completion_exports = {};
25001
25138
  __export(completion_exports, {
25002
25139
  completionCommand: () => completionCommand
25003
25140
  });
25004
- import { writeFileSync as writeFileSync10, mkdirSync as mkdirSync14 } from "fs";
25005
- import { join as join26 } from "path";
25141
+ import { writeFileSync as writeFileSync10, mkdirSync as mkdirSync15 } from "fs";
25142
+ import { join as join27 } from "path";
25006
25143
  import { homedir as homedir9 } from "os";
25007
25144
  async function completionCommand(opts) {
25008
25145
  const shell = opts.shell ?? detectShell();
@@ -25018,10 +25155,10 @@ async function completionCommand(opts) {
25018
25155
  process.exit(1);
25019
25156
  }
25020
25157
  if (opts.install) {
25021
- const dir = join26(homedir9(), ".config", "cc-claw", "completions");
25022
- mkdirSync14(dir, { recursive: true });
25158
+ const dir = join27(homedir9(), ".config", "cc-claw", "completions");
25159
+ mkdirSync15(dir, { recursive: true });
25023
25160
  const filename = shell === "zsh" ? "_cc-claw" : shell === "fish" ? "cc-claw.fish" : "cc-claw.bash";
25024
- const filepath = join26(dir, filename);
25161
+ const filepath = join27(dir, filename);
25025
25162
  writeFileSync10(filepath, script, "utf-8");
25026
25163
  console.log(`\u2713 Completion script written to ${filepath}
25027
25164
  `);
@@ -25610,10 +25747,10 @@ var init_evolve3 = __esm({
25610
25747
 
25611
25748
  // src/setup.ts
25612
25749
  var setup_exports = {};
25613
- import { existsSync as existsSync48, writeFileSync as writeFileSync11, readFileSync as readFileSync20, copyFileSync as copyFileSync3, mkdirSync as mkdirSync15, statSync as statSync9 } from "fs";
25750
+ import { existsSync as existsSync48, writeFileSync as writeFileSync11, readFileSync as readFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync16, statSync as statSync9 } from "fs";
25614
25751
  import { execFileSync as execFileSync5 } from "child_process";
25615
25752
  import { createInterface as createInterface8 } from "readline";
25616
- import { join as join27 } from "path";
25753
+ import { join as join28 } from "path";
25617
25754
  function divider2() {
25618
25755
  console.log(dim("\u2500".repeat(55)));
25619
25756
  }
@@ -25688,20 +25825,20 @@ async function setup() {
25688
25825
  }
25689
25826
  console.log("");
25690
25827
  for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
25691
- if (!existsSync48(dir)) mkdirSync15(dir, { recursive: true });
25828
+ if (!existsSync48(dir)) mkdirSync16(dir, { recursive: true });
25692
25829
  }
25693
25830
  const env = {};
25694
25831
  const envSource = existsSync48(ENV_PATH) ? ENV_PATH : existsSync48(".env") ? ".env" : null;
25695
25832
  if (envSource) {
25696
25833
  console.log(yellow(` Found existing config at ${envSource} \u2014 your values will be preserved`));
25697
25834
  console.log(yellow(" unless you enter new ones. Just press Enter to keep existing values.\n"));
25698
- const existing = readFileSync20(envSource, "utf-8");
25835
+ const existing = readFileSync21(envSource, "utf-8");
25699
25836
  for (const line of existing.split("\n")) {
25700
25837
  const match = line.match(/^([^#=]+)=(.*)$/);
25701
25838
  if (match) env[match[1].trim()] = match[2].trim();
25702
25839
  }
25703
25840
  }
25704
- const cwdDb = join27(process.cwd(), "cc-claw.db");
25841
+ const cwdDb = join28(process.cwd(), "cc-claw.db");
25705
25842
  if (existsSync48(cwdDb) && !existsSync48(DB_PATH)) {
25706
25843
  const { size } = statSync9(cwdDb);
25707
25844
  console.log(yellow(` Found existing database at ${cwdDb} (${(size / 1024).toFixed(0)}KB)`));
@@ -26087,6 +26224,10 @@ function registerUnifiedSlotCommands(parentCmd, backendId, displayName) {
26087
26224
  const { makeAddKey: makeAddKey2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
26088
26225
  await makeAddKey2(backendId, displayName)(program.opts(), opts);
26089
26226
  });
26227
+ cmd.command("add-account").description("Add a subscription/OAuth slot (opens browser for sign-in)").option("--label <name>", "Friendly label for this slot").option("--priority <n>", "Priority (lower = preferred)", "0").action(async (opts) => {
26228
+ const { makeAddAccount: makeAddAccount2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
26229
+ await makeAddAccount2(backendId, displayName)(program.opts(), opts);
26230
+ });
26090
26231
  cmd.command("remove <id-or-label>").description("Remove a credential slot (by ID or label)").action(async (id) => {
26091
26232
  const { makeRemove: makeRemove2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
26092
26233
  await makeRemove2(backendId, displayName)(program.opts(), id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-claw",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "CC-Claw: Personal AI assistant on Telegram — multi-backend (Claude, Gemini, Codex, Cursor), sub-agent orchestration, MCP management",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",