cc-claw 0.15.2 → 0.16.1
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 +768 -95
- 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.
|
|
36
|
+
VERSION = true ? "0.16.1" : (() => {
|
|
37
37
|
try {
|
|
38
38
|
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
|
|
39
39
|
} catch {
|
|
@@ -1729,6 +1729,30 @@ function initSchema(db3) {
|
|
|
1729
1729
|
mode TEXT NOT NULL DEFAULT 'auto'
|
|
1730
1730
|
);
|
|
1731
1731
|
`);
|
|
1732
|
+
db3.exec(`
|
|
1733
|
+
CREATE TABLE IF NOT EXISTS backend_credentials (
|
|
1734
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1735
|
+
backend TEXT NOT NULL,
|
|
1736
|
+
slot_type TEXT NOT NULL DEFAULT 'api_key',
|
|
1737
|
+
label TEXT,
|
|
1738
|
+
api_key TEXT,
|
|
1739
|
+
config_home TEXT,
|
|
1740
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
1741
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
1742
|
+
cooldown_until TEXT,
|
|
1743
|
+
last_used TEXT,
|
|
1744
|
+
consecutive_errors INTEGER NOT NULL DEFAULT 0,
|
|
1745
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
1746
|
+
);
|
|
1747
|
+
`);
|
|
1748
|
+
db3.exec(`
|
|
1749
|
+
CREATE TABLE IF NOT EXISTS chat_backend_slot (
|
|
1750
|
+
chat_id TEXT NOT NULL,
|
|
1751
|
+
backend TEXT NOT NULL,
|
|
1752
|
+
slot_id INTEGER,
|
|
1753
|
+
PRIMARY KEY (chat_id, backend)
|
|
1754
|
+
);
|
|
1755
|
+
`);
|
|
1732
1756
|
try {
|
|
1733
1757
|
const deleted = db3.prepare(
|
|
1734
1758
|
"DELETE FROM usage_log WHERE created_at < datetime('now', '-90 days')"
|
|
@@ -3311,10 +3335,108 @@ var init_gemini_slots = __esm({
|
|
|
3311
3335
|
}
|
|
3312
3336
|
});
|
|
3313
3337
|
|
|
3338
|
+
// src/memory/backend-slots.ts
|
|
3339
|
+
function getBackendSlots(backend2) {
|
|
3340
|
+
return getDb().prepare(`
|
|
3341
|
+
SELECT ${SLOT_COLUMNS}
|
|
3342
|
+
FROM backend_credentials WHERE backend = ? ORDER BY priority ASC, id ASC
|
|
3343
|
+
`).all(backend2);
|
|
3344
|
+
}
|
|
3345
|
+
function getEligibleBackendSlots(backend2) {
|
|
3346
|
+
return getDb().prepare(`
|
|
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
|
|
3352
|
+
`).all(backend2);
|
|
3353
|
+
}
|
|
3354
|
+
function getChatBackendSlotId(chatId, backend2) {
|
|
3355
|
+
const row = getDb().prepare(
|
|
3356
|
+
"SELECT slot_id FROM chat_backend_slot WHERE chat_id = ? AND backend = ?"
|
|
3357
|
+
).get(chatId, backend2);
|
|
3358
|
+
return row?.slot_id ?? null;
|
|
3359
|
+
}
|
|
3360
|
+
function getNextBackendSlot(chatId, backend2) {
|
|
3361
|
+
const pinned = getDb().prepare(`
|
|
3362
|
+
SELECT ${SLOT_COLUMNS}
|
|
3363
|
+
FROM backend_credentials bc
|
|
3364
|
+
JOIN chat_backend_slot cbs ON cbs.slot_id = bc.id
|
|
3365
|
+
WHERE cbs.chat_id = ? AND cbs.backend = ? AND bc.enabled = 1
|
|
3366
|
+
AND (bc.cooldown_until IS NULL OR bc.cooldown_until <= datetime('now'))
|
|
3367
|
+
`).get(chatId, backend2);
|
|
3368
|
+
if (pinned) return pinned;
|
|
3369
|
+
const eligible = getEligibleBackendSlots(backend2);
|
|
3370
|
+
return eligible.length > 0 ? eligible[0] : null;
|
|
3371
|
+
}
|
|
3372
|
+
function markBackendSlotSuccess(slotId) {
|
|
3373
|
+
getDb().prepare(`
|
|
3374
|
+
UPDATE backend_credentials
|
|
3375
|
+
SET last_used = datetime('now'), consecutive_errors = 0,
|
|
3376
|
+
cooldown_until = CASE WHEN cooldown_until < datetime('now') THEN NULL ELSE cooldown_until END
|
|
3377
|
+
WHERE id = ?
|
|
3378
|
+
`).run(slotId);
|
|
3379
|
+
}
|
|
3380
|
+
function markBackendSlotExhausted(slotId, cooldownHours = 6) {
|
|
3381
|
+
getDb().prepare(`
|
|
3382
|
+
UPDATE backend_credentials
|
|
3383
|
+
SET cooldown_until = datetime('now', '+' || ? || ' hours'),
|
|
3384
|
+
consecutive_errors = consecutive_errors + 1,
|
|
3385
|
+
enabled = CASE WHEN consecutive_errors + 1 >= 10 THEN 0 ELSE enabled END
|
|
3386
|
+
WHERE id = ?
|
|
3387
|
+
`).run(cooldownHours, slotId);
|
|
3388
|
+
}
|
|
3389
|
+
function pinChatBackendSlot(chatId, backend2, slotId) {
|
|
3390
|
+
getDb().prepare(`
|
|
3391
|
+
INSERT INTO chat_backend_slot (chat_id, backend, slot_id) VALUES (?, ?, ?)
|
|
3392
|
+
ON CONFLICT(chat_id, backend) DO UPDATE SET slot_id = excluded.slot_id
|
|
3393
|
+
`).run(chatId, backend2, slotId);
|
|
3394
|
+
}
|
|
3395
|
+
function clearChatBackendSlot(chatId, backend2) {
|
|
3396
|
+
getDb().prepare("DELETE FROM chat_backend_slot WHERE chat_id = ? AND backend = ?").run(chatId, backend2);
|
|
3397
|
+
}
|
|
3398
|
+
function addBackendSlot(opts) {
|
|
3399
|
+
const result = getDb().prepare(`
|
|
3400
|
+
INSERT INTO backend_credentials (backend, slot_type, label, api_key, config_home, priority)
|
|
3401
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
3402
|
+
`).run(opts.backend, opts.slotType, opts.label ?? null, opts.apiKey ?? null, opts.configHome ?? null, opts.priority ?? 0);
|
|
3403
|
+
return Number(result.lastInsertRowid);
|
|
3404
|
+
}
|
|
3405
|
+
function removeBackendSlot(id) {
|
|
3406
|
+
getDb().prepare("DELETE FROM chat_backend_slot WHERE slot_id = ?").run(id);
|
|
3407
|
+
return getDb().prepare("DELETE FROM backend_credentials WHERE id = ?").run(id).changes > 0;
|
|
3408
|
+
}
|
|
3409
|
+
function setBackendSlotEnabled(id, enabled) {
|
|
3410
|
+
getDb().prepare("UPDATE backend_credentials SET enabled = ? WHERE id = ?").run(enabled ? 1 : 0, id);
|
|
3411
|
+
}
|
|
3412
|
+
function reorderBackendSlot(id, priority) {
|
|
3413
|
+
getDb().prepare("UPDATE backend_credentials SET priority = ? WHERE id = ?").run(priority, id);
|
|
3414
|
+
}
|
|
3415
|
+
function reenableBackendSlot(slotId) {
|
|
3416
|
+
getDb().prepare(`
|
|
3417
|
+
UPDATE backend_credentials
|
|
3418
|
+
SET enabled = 1, consecutive_errors = 0, cooldown_until = NULL
|
|
3419
|
+
WHERE id = ?
|
|
3420
|
+
`).run(slotId);
|
|
3421
|
+
}
|
|
3422
|
+
var SLOT_COLUMNS;
|
|
3423
|
+
var init_backend_slots = __esm({
|
|
3424
|
+
"src/memory/backend-slots.ts"() {
|
|
3425
|
+
"use strict";
|
|
3426
|
+
init_store5();
|
|
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
|
|
3431
|
+
`;
|
|
3432
|
+
}
|
|
3433
|
+
});
|
|
3434
|
+
|
|
3314
3435
|
// src/memory/store.ts
|
|
3315
3436
|
var store_exports5 = {};
|
|
3316
3437
|
__export(store_exports5, {
|
|
3317
3438
|
ALL_TOOLS: () => ALL_TOOLS,
|
|
3439
|
+
addBackendSlot: () => addBackendSlot,
|
|
3318
3440
|
addGeminiSlot: () => addGeminiSlot,
|
|
3319
3441
|
addHeartbeatWatch: () => addHeartbeatWatch,
|
|
3320
3442
|
addUsage: () => addUsage,
|
|
@@ -3325,6 +3447,7 @@ __export(store_exports5, {
|
|
|
3325
3447
|
clearAgentMode: () => clearAgentMode,
|
|
3326
3448
|
clearAllSessions: () => clearAllSessions,
|
|
3327
3449
|
clearBackendLimit: () => clearBackendLimit,
|
|
3450
|
+
clearChatBackendSlot: () => clearChatBackendSlot,
|
|
3328
3451
|
clearChatGeminiSlot: () => clearChatGeminiSlot,
|
|
3329
3452
|
clearCwd: () => clearCwd,
|
|
3330
3453
|
clearMessageLog: () => clearMessageLog,
|
|
@@ -3352,13 +3475,16 @@ __export(store_exports5, {
|
|
|
3352
3475
|
getAllTimeUsage: () => getAllTimeUsage,
|
|
3353
3476
|
getBackend: () => getBackend,
|
|
3354
3477
|
getBackendLimit: () => getBackendLimit,
|
|
3478
|
+
getBackendSlots: () => getBackendSlots,
|
|
3355
3479
|
getBackendUsageInWindow: () => getBackendUsageInWindow,
|
|
3356
3480
|
getBookmark: () => getBookmark,
|
|
3481
|
+
getChatBackendSlotId: () => getChatBackendSlotId,
|
|
3357
3482
|
getChatGeminiSlotId: () => getChatGeminiSlotId,
|
|
3358
3483
|
getChatIdByAlias: () => getChatIdByAlias,
|
|
3359
3484
|
getChatUsageByModel: () => getChatUsageByModel,
|
|
3360
3485
|
getCwd: () => getCwd,
|
|
3361
3486
|
getDb: () => getDb,
|
|
3487
|
+
getEligibleBackendSlots: () => getEligibleBackendSlots,
|
|
3362
3488
|
getEligibleGeminiSlots: () => getEligibleGeminiSlots,
|
|
3363
3489
|
getEnabledTools: () => getEnabledTools,
|
|
3364
3490
|
getGeminiRotationMode: () => getGeminiRotationMode,
|
|
@@ -3371,6 +3497,7 @@ __export(store_exports5, {
|
|
|
3371
3497
|
getMode: () => getMode,
|
|
3372
3498
|
getModel: () => getModel,
|
|
3373
3499
|
getModelSignature: () => getModelSignature,
|
|
3500
|
+
getNextBackendSlot: () => getNextBackendSlot,
|
|
3374
3501
|
getNextGeminiSlot: () => getNextGeminiSlot,
|
|
3375
3502
|
getPendingEscalation: () => getPendingEscalation,
|
|
3376
3503
|
getRecentBookmarks: () => getRecentBookmarks,
|
|
@@ -3394,18 +3521,24 @@ __export(store_exports5, {
|
|
|
3394
3521
|
insertJobRun: () => insertJobRun,
|
|
3395
3522
|
listMemories: () => listMemories,
|
|
3396
3523
|
listSessionSummaries: () => listSessionSummaries,
|
|
3524
|
+
markBackendSlotExhausted: () => markBackendSlotExhausted,
|
|
3525
|
+
markBackendSlotSuccess: () => markBackendSlotSuccess,
|
|
3397
3526
|
markMessageLogSummarized: () => markMessageLogSummarized,
|
|
3398
3527
|
markSlotExhausted: () => markSlotExhausted,
|
|
3399
3528
|
markSlotSuccess: () => markSlotSuccess,
|
|
3400
3529
|
openDatabaseReadOnly: () => openDatabaseReadOnly,
|
|
3530
|
+
pinChatBackendSlot: () => pinChatBackendSlot,
|
|
3401
3531
|
pinChatGeminiSlot: () => pinChatGeminiSlot,
|
|
3402
3532
|
pruneJobRuns: () => pruneJobRuns,
|
|
3403
3533
|
pruneMessageLog: () => pruneMessageLog,
|
|
3534
|
+
reenableBackendSlot: () => reenableBackendSlot,
|
|
3404
3535
|
reenableSlot: () => reenableSlot,
|
|
3536
|
+
removeBackendSlot: () => removeBackendSlot,
|
|
3405
3537
|
removeChatAlias: () => removeChatAlias,
|
|
3406
3538
|
removeGeminiSlot: () => removeGeminiSlot,
|
|
3407
3539
|
removeHeartbeatWatch: () => removeHeartbeatWatch,
|
|
3408
3540
|
removePendingEscalation: () => removePendingEscalation,
|
|
3541
|
+
reorderBackendSlot: () => reorderBackendSlot,
|
|
3409
3542
|
reorderGeminiSlot: () => reorderGeminiSlot,
|
|
3410
3543
|
resetJobFailures: () => resetJobFailures,
|
|
3411
3544
|
resetTools: () => resetTools,
|
|
@@ -3420,6 +3553,7 @@ __export(store_exports5, {
|
|
|
3420
3553
|
setAgentMode: () => setAgentMode,
|
|
3421
3554
|
setBackend: () => setBackend,
|
|
3422
3555
|
setBackendLimit: () => setBackendLimit,
|
|
3556
|
+
setBackendSlotEnabled: () => setBackendSlotEnabled,
|
|
3423
3557
|
setBootTime: () => setBootTime,
|
|
3424
3558
|
setChatAlias: () => setChatAlias,
|
|
3425
3559
|
setCwd: () => setCwd,
|
|
@@ -3480,6 +3614,7 @@ var init_store5 = __esm({
|
|
|
3480
3614
|
init_aliases();
|
|
3481
3615
|
init_message_log();
|
|
3482
3616
|
init_gemini_slots();
|
|
3617
|
+
init_backend_slots();
|
|
3483
3618
|
}
|
|
3484
3619
|
});
|
|
3485
3620
|
|
|
@@ -3672,6 +3807,16 @@ var init_claude = __esm({
|
|
|
3672
3807
|
env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
|
|
3673
3808
|
return env;
|
|
3674
3809
|
}
|
|
3810
|
+
getEnvForSlot(slot) {
|
|
3811
|
+
const env = this.getEnv();
|
|
3812
|
+
if (slot.slotType === "api_key" && slot.apiKey) {
|
|
3813
|
+
env.ANTHROPIC_API_KEY = slot.apiKey;
|
|
3814
|
+
} else if (slot.slotType === "oauth" && slot.configHome) {
|
|
3815
|
+
env.HOME = slot.configHome;
|
|
3816
|
+
delete env.ANTHROPIC_API_KEY;
|
|
3817
|
+
}
|
|
3818
|
+
return env;
|
|
3819
|
+
}
|
|
3675
3820
|
applyThinkingConfig(level, model2) {
|
|
3676
3821
|
if (level === "auto") return {};
|
|
3677
3822
|
if (level === "off") return { envOverrides: { MAX_THINKING_TOKENS: "0" } };
|
|
@@ -3961,7 +4106,7 @@ var init_gemini = __esm({
|
|
|
3961
4106
|
* OAuth slots set GEMINI_CLI_HOME for isolated config and unset GEMINI_API_KEY so
|
|
3962
4107
|
* the CLI uses OAuth instead. Returns the slot used (or null for default behavior).
|
|
3963
4108
|
*/
|
|
3964
|
-
|
|
4109
|
+
resolveSlotEnv(chatId, thinkingOverrides, mode) {
|
|
3965
4110
|
const slot = getNextGeminiSlot(chatId, mode);
|
|
3966
4111
|
const env = this.getEnv(thinkingOverrides);
|
|
3967
4112
|
if (!slot) return { env, slot: null };
|
|
@@ -4072,6 +4217,15 @@ var init_codex = __esm({
|
|
|
4072
4217
|
getEnv(thinkingOverrides) {
|
|
4073
4218
|
return buildBaseEnv(thinkingOverrides);
|
|
4074
4219
|
}
|
|
4220
|
+
getEnvForSlot(slot) {
|
|
4221
|
+
const env = this.getEnv();
|
|
4222
|
+
if (slot.slotType === "api_key" && slot.apiKey) {
|
|
4223
|
+
env.OPENAI_API_KEY = slot.apiKey;
|
|
4224
|
+
} else if (slot.slotType === "oauth" && slot.configHome) {
|
|
4225
|
+
env.CODEX_HOME = slot.configHome;
|
|
4226
|
+
}
|
|
4227
|
+
return env;
|
|
4228
|
+
}
|
|
4075
4229
|
applyThinkingConfig(level, _model) {
|
|
4076
4230
|
if (level === "auto") return {};
|
|
4077
4231
|
const mapped = level === "off" ? "low" : level === "extra_high" ? "xhigh" : level;
|
|
@@ -9778,11 +9932,11 @@ var init_evolve = __esm({
|
|
|
9778
9932
|
const body = JSON.parse(await readBody(req));
|
|
9779
9933
|
const { setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
9780
9934
|
const { existsSync: fileExists, readFileSync: fileRead } = await import("fs");
|
|
9781
|
-
const { join:
|
|
9935
|
+
const { join: join29 } = await import("path");
|
|
9782
9936
|
const { CC_CLAW_HOME: home } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
9783
9937
|
const chatId = body.chatId || (process.env.ALLOWED_CHAT_ID ?? "").split(",")[0]?.trim() || "default";
|
|
9784
|
-
const soulPath =
|
|
9785
|
-
const userPath =
|
|
9938
|
+
const soulPath = join29(home, "identity/SOUL.md");
|
|
9939
|
+
const userPath = join29(home, "identity/USER.md");
|
|
9786
9940
|
const soul = fileExists(soulPath) ? fileRead(soulPath, "utf-8") : "";
|
|
9787
9941
|
const user = fileExists(userPath) ? fileRead(userPath, "utf-8") : "";
|
|
9788
9942
|
setReflectionStatus2(getDb(), chatId, "active", soul, user);
|
|
@@ -10572,6 +10726,53 @@ Partial output: ${accumulatedText.slice(-500)}`;
|
|
|
10572
10726
|
});
|
|
10573
10727
|
});
|
|
10574
10728
|
}
|
|
10729
|
+
async function spawnWithSlotRotation(chatId, adapter, baseConfig, configWithSession, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, opts, onSlotRotation) {
|
|
10730
|
+
const slots = getEligibleBackendSlots(adapter.id);
|
|
10731
|
+
if (slots.length === 0) {
|
|
10732
|
+
return spawnQuery(adapter, configWithSession, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, opts);
|
|
10733
|
+
}
|
|
10734
|
+
const maxAttempts = slots.length;
|
|
10735
|
+
let lastError;
|
|
10736
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
10737
|
+
const slot = getNextBackendSlot(chatId, adapter.id);
|
|
10738
|
+
if (!slot) break;
|
|
10739
|
+
const slotLabel = slot.label || `slot-${slot.id}`;
|
|
10740
|
+
log(`[agent:${adapter.id}-rotation] Trying ${slotLabel} (${slot.slotType}, attempt ${i + 1}/${maxAttempts})`);
|
|
10741
|
+
if (i === 0) pinChatBackendSlot(chatId, adapter.id, slot.id);
|
|
10742
|
+
const slotEnv = adapter.getEnvForSlot?.(slot) ?? adapter.getEnv();
|
|
10743
|
+
const effectiveConfig = i === 0 ? configWithSession : baseConfig;
|
|
10744
|
+
try {
|
|
10745
|
+
const result = await spawnQuery(adapter, effectiveConfig, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, { ...opts, envOverride: slotEnv });
|
|
10746
|
+
markBackendSlotSuccess(slot.id);
|
|
10747
|
+
return result;
|
|
10748
|
+
} catch (err) {
|
|
10749
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
10750
|
+
if (/rate.?limit|too many requests|429|503|timeout/i.test(errMsg)) {
|
|
10751
|
+
throw err;
|
|
10752
|
+
}
|
|
10753
|
+
const isExhausted = /quota|exhausted|exceeded|insufficient|credit|billing|unauthorized|forbidden|401|403/i.test(errMsg);
|
|
10754
|
+
if (isExhausted) {
|
|
10755
|
+
warn(`[agent:${adapter.id}-rotation] Slot ${slotLabel} exhausted: ${errMsg.slice(0, 200)}`);
|
|
10756
|
+
markBackendSlotExhausted(slot.id, 6);
|
|
10757
|
+
lastError = err instanceof Error ? err : new Error(errMsg);
|
|
10758
|
+
try {
|
|
10759
|
+
await summarizeWithFallbackChain(chatId, void 0, adapter.id);
|
|
10760
|
+
clearSession(chatId);
|
|
10761
|
+
} catch {
|
|
10762
|
+
}
|
|
10763
|
+
const nextSlot = getEligibleBackendSlots(adapter.id)[0];
|
|
10764
|
+
if (nextSlot && onSlotRotation) {
|
|
10765
|
+
const nextLabel = nextSlot.label || `slot-${nextSlot.id}`;
|
|
10766
|
+
onSlotRotation(slotLabel, nextLabel);
|
|
10767
|
+
pinChatBackendSlot(chatId, adapter.id, nextSlot.id);
|
|
10768
|
+
}
|
|
10769
|
+
continue;
|
|
10770
|
+
}
|
|
10771
|
+
throw err;
|
|
10772
|
+
}
|
|
10773
|
+
}
|
|
10774
|
+
throw lastError ?? new Error(`All ${adapter.id} credential slots exhausted`);
|
|
10775
|
+
}
|
|
10575
10776
|
async function spawnGeminiWithRotation(chatId, adapter, baseConfig, configWithSession, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, rotationMode, opts, onSlotRotation, parentChatId, onModelDowngrade) {
|
|
10576
10777
|
const geminiAdapter = adapter;
|
|
10577
10778
|
const slots = getEligibleGeminiSlots(rotationMode);
|
|
@@ -10579,14 +10780,14 @@ async function spawnGeminiWithRotation(chatId, adapter, baseConfig, configWithSe
|
|
|
10579
10780
|
return spawnQuery(adapter, configWithSession, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, opts);
|
|
10580
10781
|
}
|
|
10581
10782
|
if (parentChatId) {
|
|
10582
|
-
const { env } = geminiAdapter.
|
|
10783
|
+
const { env } = geminiAdapter.resolveSlotEnv(parentChatId, void 0, rotationMode);
|
|
10583
10784
|
return await spawnQuery(adapter, configWithSession, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, { ...opts, envOverride: env });
|
|
10584
10785
|
}
|
|
10585
10786
|
const maxAttempts = slots.length;
|
|
10586
10787
|
let lastError;
|
|
10587
10788
|
let unknownRetried = false;
|
|
10588
10789
|
for (let i = 0; i < maxAttempts; i++) {
|
|
10589
|
-
const { env, slot } = geminiAdapter.
|
|
10790
|
+
const { env, slot } = geminiAdapter.resolveSlotEnv(chatId, void 0, rotationMode);
|
|
10590
10791
|
if (!slot) break;
|
|
10591
10792
|
const slotLabel = slot.label || `slot-${slot.id}`;
|
|
10592
10793
|
log(`[agent:gemini-rotation] Trying ${slotLabel} (${slot.slotType}, attempt ${i + 1}/${maxAttempts})`);
|
|
@@ -10739,16 +10940,20 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10739
10940
|
let result = { resultText: "", sessionId: void 0, input: 0, output: 0, cacheRead: 0, sawToolEvents: false, sawResultEvent: false };
|
|
10740
10941
|
const rotationMode = adapter.id === "gemini" ? getGeminiRotationMode() : "off";
|
|
10741
10942
|
const useGeminiRotation = rotationMode !== "off" && getEligibleGeminiSlots(rotationMode).length > 0;
|
|
10943
|
+
const useBackendRotation = adapter.id !== "gemini" && getEligibleBackendSlots(adapter.id).length > 0;
|
|
10742
10944
|
try {
|
|
10743
10945
|
if (useGeminiRotation) {
|
|
10744
10946
|
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
10745
10947
|
const downgradeCb = onModelDowngrade ? (from, to, reason) => onModelDowngrade(chatId, from, to, reason) : void 0;
|
|
10746
10948
|
result = await spawnGeminiWithRotation(chatId, adapter, baseConfig, configWithSession, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, rotationMode, spawnOpts, rotationCb, settingsSourceChatId, downgradeCb);
|
|
10949
|
+
} else if (useBackendRotation) {
|
|
10950
|
+
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
10951
|
+
result = await spawnWithSlotRotation(chatId, adapter, baseConfig, configWithSession, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, spawnOpts, rotationCb);
|
|
10747
10952
|
} else {
|
|
10748
10953
|
const slotSpawnOpts = (() => {
|
|
10749
10954
|
if (adapter.id !== "gemini") return spawnOpts;
|
|
10750
10955
|
const geminiAdapter = adapter;
|
|
10751
|
-
const { env, slot } = geminiAdapter.
|
|
10956
|
+
const { env, slot } = geminiAdapter.resolveSlotEnv(chatId);
|
|
10752
10957
|
if (slot) {
|
|
10753
10958
|
log(`[agent] rotation=off, using pinned slot: ${slot.label || `slot-${slot.id}`} (${slot.slotType})`);
|
|
10754
10959
|
return { ...spawnOpts, envOverride: env };
|
|
@@ -10795,11 +11000,14 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10795
11000
|
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
10796
11001
|
const downgradeCb = onModelDowngrade ? (from, to, reason) => onModelDowngrade(chatId, from, to, reason) : void 0;
|
|
10797
11002
|
result = await spawnGeminiWithRotation(chatId, adapter, baseConfig, baseConfig, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, rotationMode, spawnOpts, rotationCb, settingsSourceChatId, downgradeCb);
|
|
11003
|
+
} else if (useBackendRotation) {
|
|
11004
|
+
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
11005
|
+
result = await spawnWithSlotRotation(chatId, adapter, baseConfig, baseConfig, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, spawnOpts, rotationCb);
|
|
10798
11006
|
} else {
|
|
10799
11007
|
const retryOpts = (() => {
|
|
10800
11008
|
if (adapter.id !== "gemini") return spawnOpts;
|
|
10801
11009
|
const geminiAdapter = adapter;
|
|
10802
|
-
const { env, slot } = geminiAdapter.
|
|
11010
|
+
const { env, slot } = geminiAdapter.resolveSlotEnv(chatId);
|
|
10803
11011
|
if (slot) return { ...spawnOpts, envOverride: env };
|
|
10804
11012
|
return spawnOpts;
|
|
10805
11013
|
})();
|
|
@@ -10815,11 +11023,14 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10815
11023
|
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
10816
11024
|
const downgradeCb = onModelDowngrade ? (from, to, reason) => onModelDowngrade(chatId, from, to, reason) : void 0;
|
|
10817
11025
|
result = await spawnGeminiWithRotation(chatId, adapter, baseConfig, baseConfig, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, rotationMode, spawnOpts, rotationCb, settingsSourceChatId, downgradeCb);
|
|
11026
|
+
} else if (useBackendRotation) {
|
|
11027
|
+
const rotationCb = onSlotRotation ? (from, to) => onSlotRotation(chatId, from, to) : void 0;
|
|
11028
|
+
result = await spawnWithSlotRotation(chatId, adapter, baseConfig, baseConfig, resolvedModel, cancelState, thinkingLevel, timeoutMs, maxTurns, spawnOpts, rotationCb);
|
|
10818
11029
|
} else {
|
|
10819
11030
|
const retryOpts = (() => {
|
|
10820
11031
|
if (adapter.id !== "gemini") return spawnOpts;
|
|
10821
11032
|
const geminiAdapter = adapter;
|
|
10822
|
-
const { env, slot } = geminiAdapter.
|
|
11033
|
+
const { env, slot } = geminiAdapter.resolveSlotEnv(chatId);
|
|
10823
11034
|
if (slot) return { ...spawnOpts, envOverride: env };
|
|
10824
11035
|
return spawnOpts;
|
|
10825
11036
|
})();
|
|
@@ -10944,6 +11155,7 @@ var init_agent = __esm({
|
|
|
10944
11155
|
init_summarize();
|
|
10945
11156
|
init_quota();
|
|
10946
11157
|
init_store5();
|
|
11158
|
+
init_store5();
|
|
10947
11159
|
init_server();
|
|
10948
11160
|
init_mcp_config();
|
|
10949
11161
|
init_store5();
|
|
@@ -12812,7 +13024,10 @@ var init_helpers = __esm({
|
|
|
12812
13024
|
{ cmd: "/thinking", desc: "Adjust thinking level" },
|
|
12813
13025
|
{ cmd: "/permissions", desc: "Set permission mode" },
|
|
12814
13026
|
{ cmd: "/response_style", desc: "Set response verbosity" },
|
|
12815
|
-
{ cmd: "/model_signature", desc: "Toggle model signature" }
|
|
13027
|
+
{ cmd: "/model_signature", desc: "Toggle model signature" },
|
|
13028
|
+
{ cmd: "/gemini_accounts", desc: "Gemini credential slots" },
|
|
13029
|
+
{ cmd: "/claude_accounts", desc: "Claude credential slots" },
|
|
13030
|
+
{ cmd: "/codex_accounts", desc: "Codex credential slots" }
|
|
12816
13031
|
],
|
|
12817
13032
|
Memory: [
|
|
12818
13033
|
{ cmd: "/memory", desc: "Browse stored memories" },
|
|
@@ -15687,13 +15902,13 @@ async function handleEvolveCallback(chatId, data, channel) {
|
|
|
15687
15902
|
const { getReflectionStatus: getReflectionStatus2, setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
15688
15903
|
const current = getReflectionStatus2(getDb(), chatId);
|
|
15689
15904
|
if (current === "frozen") {
|
|
15690
|
-
const { readFileSync:
|
|
15691
|
-
const { join:
|
|
15905
|
+
const { readFileSync: readFileSync22, existsSync: existsSync49 } = await import("fs");
|
|
15906
|
+
const { join: join29 } = await import("path");
|
|
15692
15907
|
const { CC_CLAW_HOME: CC_CLAW_HOME3 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
15693
|
-
const soulPath =
|
|
15694
|
-
const userPath =
|
|
15695
|
-
const soul =
|
|
15696
|
-
const user =
|
|
15908
|
+
const soulPath = join29(CC_CLAW_HOME3, "identity/SOUL.md");
|
|
15909
|
+
const userPath = join29(CC_CLAW_HOME3, "identity/USER.md");
|
|
15910
|
+
const soul = existsSync49(soulPath) ? readFileSync22(soulPath, "utf-8") : "";
|
|
15911
|
+
const user = existsSync49(userPath) ? readFileSync22(userPath, "utf-8") : "";
|
|
15697
15912
|
setReflectionStatus2(getDb(), chatId, "active", soul, user);
|
|
15698
15913
|
const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
|
|
15699
15914
|
logActivity2(getDb(), { chatId, source: "telegram", eventType: "reflection_unfrozen", summary: "Reflection enabled" });
|
|
@@ -16036,14 +16251,28 @@ Tap to toggle:`,
|
|
|
16036
16251
|
}
|
|
16037
16252
|
const iStats = getIntentStats();
|
|
16038
16253
|
const iTotal = iStats.chat + iStats.agentic;
|
|
16039
|
-
let
|
|
16254
|
+
let slotInfo = "";
|
|
16040
16255
|
if ((backendId ?? "claude") === "gemini") {
|
|
16041
16256
|
try {
|
|
16042
16257
|
const active = getNextGeminiSlot(chatId);
|
|
16043
16258
|
const totalSlots = getEligibleGeminiSlots().length;
|
|
16044
16259
|
if (active) {
|
|
16045
16260
|
const label2 = active.label || `slot-${active.id}`;
|
|
16046
|
-
|
|
16261
|
+
slotInfo = ` \xB7 \u{1F511} ${label2} (${totalSlots} slots)`;
|
|
16262
|
+
}
|
|
16263
|
+
} catch {
|
|
16264
|
+
}
|
|
16265
|
+
} else if (backendId === "claude" || backendId === "codex") {
|
|
16266
|
+
try {
|
|
16267
|
+
const slots = getBackendSlots(backendId);
|
|
16268
|
+
const enabledSlots = slots.filter((s) => s.enabled);
|
|
16269
|
+
if (enabledSlots.length > 0) {
|
|
16270
|
+
const pinnedId = getChatBackendSlotId(chatId, backendId);
|
|
16271
|
+
const active = pinnedId ? slots.find((s) => s.id === pinnedId) : enabledSlots[0];
|
|
16272
|
+
if (active) {
|
|
16273
|
+
const label2 = active.label || `slot-${active.id}`;
|
|
16274
|
+
slotInfo = ` \xB7 \u{1F511} ${label2} (${enabledSlots.length} slots)`;
|
|
16275
|
+
}
|
|
16047
16276
|
}
|
|
16048
16277
|
} catch {
|
|
16049
16278
|
}
|
|
@@ -16057,7 +16286,7 @@ Tap to toggle:`,
|
|
|
16057
16286
|
`\u23F1 Uptime: ${uptimeStr}`,
|
|
16058
16287
|
``,
|
|
16059
16288
|
buildSectionHeader("Engine"),
|
|
16060
|
-
`\u{1F9E0} ${adapter?.displayName ?? backendId ?? "not set"} \xB7 ${formatModelShort(model2)}${
|
|
16289
|
+
`\u{1F9E0} ${adapter?.displayName ?? backendId ?? "not set"} \xB7 ${formatModelShort(model2)}${slotInfo}`,
|
|
16061
16290
|
`\u{1F4AD} Think: ${thinking2} \xB7 Mode: ${mode}`,
|
|
16062
16291
|
`\u{1F916} Agents: ${getAgentMode(chatId)}`,
|
|
16063
16292
|
`\u{1F507} Voice: ${voice2 ? "on" : "off"} \xB7 Sig: ${modelSig}`,
|
|
@@ -16176,6 +16405,42 @@ Use: /gemini_accounts <name> to pin`, { parseMode: "plain" });
|
|
|
16176
16405
|
}
|
|
16177
16406
|
break;
|
|
16178
16407
|
}
|
|
16408
|
+
case "claude_accounts":
|
|
16409
|
+
case "codex_accounts": {
|
|
16410
|
+
const slotBackend = command === "claude_accounts" ? "claude" : "codex";
|
|
16411
|
+
const slotDisplayName = command === "claude_accounts" ? "Claude" : "Codex";
|
|
16412
|
+
const slots = getBackendSlots(slotBackend);
|
|
16413
|
+
if (slots.length === 0) {
|
|
16414
|
+
await channel.sendText(chatId, `No ${slotDisplayName} credentials configured.
|
|
16415
|
+
Add with: <code>cc-claw ${slotBackend} add-key</code>`, { parseMode: "html" });
|
|
16416
|
+
break;
|
|
16417
|
+
}
|
|
16418
|
+
if (typeof channel.sendKeyboard === "function") {
|
|
16419
|
+
const pinnedSlotId = getChatBackendSlotId(chatId, slotBackend);
|
|
16420
|
+
const slotButtons = slots.filter((s) => s.enabled).map((s) => {
|
|
16421
|
+
const label2 = s.label || `slot-${s.id}`;
|
|
16422
|
+
const icon = s.slotType === "oauth" ? "\u{1F468}\u{1F3FD}\u200D\u{1F4BB}" : "\u{1F511}";
|
|
16423
|
+
const marker = pinnedSlotId === s.id ? " \u2713" : "";
|
|
16424
|
+
return { label: `${icon} ${label2}${marker}`, data: `bslot:${slotBackend}:${s.id}` };
|
|
16425
|
+
});
|
|
16426
|
+
const rows = [];
|
|
16427
|
+
for (let i = 0; i < slotButtons.length; i += 2) {
|
|
16428
|
+
rows.push(slotButtons.slice(i, i + 2));
|
|
16429
|
+
}
|
|
16430
|
+
rows.push([{ label: "\u{1F504} Auto (rotation)", data: `bslot:${slotBackend}:auto` }]);
|
|
16431
|
+
await channel.sendKeyboard(chatId, `${slotDisplayName} Accounts:`, rows);
|
|
16432
|
+
} else {
|
|
16433
|
+
const list = slots.filter((s) => s.enabled).map((s) => {
|
|
16434
|
+
const icon = s.slotType === "oauth" ? "\u{1F468}\u{1F3FD}\u200D\u{1F4BB}" : "\u{1F511}";
|
|
16435
|
+
return `${icon} ${s.label || `slot-${s.id}`} (#${s.id})`;
|
|
16436
|
+
}).join("\n");
|
|
16437
|
+
await channel.sendText(chatId, `${slotDisplayName} Slots:
|
|
16438
|
+
${list}
|
|
16439
|
+
|
|
16440
|
+
Use: /${command} <name> to pin`, { parseMode: "plain" });
|
|
16441
|
+
}
|
|
16442
|
+
break;
|
|
16443
|
+
}
|
|
16179
16444
|
case "model": {
|
|
16180
16445
|
let adapter;
|
|
16181
16446
|
try {
|
|
@@ -17791,6 +18056,28 @@ ${rotationNote}`, { parseMode: "html" });
|
|
|
17791
18056
|
await channel.sendKeyboard(chatId, "Gemini Accounts & Rotation:", rows);
|
|
17792
18057
|
}
|
|
17793
18058
|
return;
|
|
18059
|
+
} else if (data.startsWith("bslot:")) {
|
|
18060
|
+
const parts = data.split(":");
|
|
18061
|
+
const backend2 = parts[1];
|
|
18062
|
+
const val = parts[2];
|
|
18063
|
+
const displayName = backend2 === "claude" ? "Claude" : "Codex";
|
|
18064
|
+
if (val === "auto") {
|
|
18065
|
+
clearChatBackendSlot(chatId, backend2);
|
|
18066
|
+
clearSession(chatId);
|
|
18067
|
+
await channel.sendText(chatId, `${displayName} slot set to <b>\u{1F504} auto rotation</b>.`, { parseMode: "html" });
|
|
18068
|
+
} else {
|
|
18069
|
+
const slotId = parseInt(val, 10);
|
|
18070
|
+
const slots = getBackendSlots(backend2);
|
|
18071
|
+
const slot = slots.find((s) => s.id === slotId);
|
|
18072
|
+
if (slot) {
|
|
18073
|
+
pinChatBackendSlot(chatId, backend2, slotId);
|
|
18074
|
+
clearSession(chatId);
|
|
18075
|
+
const label2 = slot.label || `slot-${slot.id}`;
|
|
18076
|
+
const icon = slot.slotType === "oauth" ? "\u{1F468}\u{1F3FD}\u200D\u{1F4BB}" : "\u{1F511}";
|
|
18077
|
+
await channel.sendText(chatId, `${icon} ${displayName} account set to <b>${label2}</b>`, { parseMode: "html" });
|
|
18078
|
+
}
|
|
18079
|
+
}
|
|
18080
|
+
return;
|
|
17794
18081
|
} else if (data.startsWith("shell:")) {
|
|
17795
18082
|
const parts = data.split(":");
|
|
17796
18083
|
const action = parts[1];
|
|
@@ -18549,6 +18836,12 @@ You're still in discussion mode \u2014 try again or click a button to exit.`, {
|
|
|
18549
18836
|
const slot = getGeminiSlots().find((s) => s.id === slotId);
|
|
18550
18837
|
if (slot) slotTag = ` \xB7 ${slot.label || `slot-${slot.id}`}`;
|
|
18551
18838
|
}
|
|
18839
|
+
} else if (adapter.id === "claude" || adapter.id === "codex") {
|
|
18840
|
+
const slotId = getChatBackendSlotId(chatId, adapter.id);
|
|
18841
|
+
if (slotId) {
|
|
18842
|
+
const slot = getBackendSlots(adapter.id).find((s) => s.id === slotId);
|
|
18843
|
+
if (slot) slotTag = ` \xB7 ${slot.label || `slot-${slot.id}`}`;
|
|
18844
|
+
}
|
|
18552
18845
|
}
|
|
18553
18846
|
responseText += `
|
|
18554
18847
|
|
|
@@ -19748,6 +20041,8 @@ var init_telegram2 = __esm({
|
|
|
19748
20041
|
{ command: "claude", description: "Switch to Claude backend" },
|
|
19749
20042
|
{ command: "gemini", description: "Switch to Gemini backend" },
|
|
19750
20043
|
{ command: "gemini_accounts", description: "Manage Gemini credentials & rotation" },
|
|
20044
|
+
{ command: "claude_accounts", description: "Manage Claude credentials & rotation" },
|
|
20045
|
+
{ command: "codex_accounts", description: "Manage Codex credentials & rotation" },
|
|
19751
20046
|
{ command: "codex", description: "Switch to Codex backend" },
|
|
19752
20047
|
{ command: "cursor", description: "Switch to Cursor backend" },
|
|
19753
20048
|
{ command: "model", description: "Switch model for active backend" },
|
|
@@ -21102,11 +21397,11 @@ async function main() {
|
|
|
21102
21397
|
bootstrapSkills().catch((err) => error("[cc-claw] Skill bootstrap failed:", err));
|
|
21103
21398
|
try {
|
|
21104
21399
|
const { generateAiSkill: generateAiSkill2 } = await Promise.resolve().then(() => (init_ai_skill(), ai_skill_exports));
|
|
21105
|
-
const { writeFileSync: writeFileSync12, mkdirSync:
|
|
21106
|
-
const { join:
|
|
21107
|
-
const skillDir =
|
|
21108
|
-
|
|
21109
|
-
writeFileSync12(
|
|
21400
|
+
const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync17 } = await import("fs");
|
|
21401
|
+
const { join: join29 } = await import("path");
|
|
21402
|
+
const skillDir = join29(SKILLS_PATH, "cc-claw-cli");
|
|
21403
|
+
mkdirSync17(skillDir, { recursive: true });
|
|
21404
|
+
writeFileSync12(join29(skillDir, "SKILL.md"), generateAiSkill2(), "utf-8");
|
|
21110
21405
|
log("[cc-claw] AI skill updated");
|
|
21111
21406
|
} catch {
|
|
21112
21407
|
}
|
|
@@ -21991,8 +22286,8 @@ async function doctorCommand(globalOpts, localOpts) {
|
|
|
21991
22286
|
}
|
|
21992
22287
|
if (existsSync25(ERROR_LOG_PATH)) {
|
|
21993
22288
|
try {
|
|
21994
|
-
const { readFileSync:
|
|
21995
|
-
const logContent =
|
|
22289
|
+
const { readFileSync: readFileSync22 } = await import("fs");
|
|
22290
|
+
const logContent = readFileSync22(ERROR_LOG_PATH, "utf-8");
|
|
21996
22291
|
const recentLines = logContent.split("\n").filter(Boolean).slice(-100);
|
|
21997
22292
|
const last24h = Date.now() - 864e5;
|
|
21998
22293
|
const recentErrors = recentLines.filter((line) => {
|
|
@@ -22415,6 +22710,347 @@ var init_gemini2 = __esm({
|
|
|
22415
22710
|
}
|
|
22416
22711
|
});
|
|
22417
22712
|
|
|
22713
|
+
// src/cli/commands/backend-cmd-factory.ts
|
|
22714
|
+
var backend_cmd_factory_exports = {};
|
|
22715
|
+
__export(backend_cmd_factory_exports, {
|
|
22716
|
+
makeAddAccount: () => makeAddAccount,
|
|
22717
|
+
makeAddKey: () => makeAddKey,
|
|
22718
|
+
makeDisable: () => makeDisable,
|
|
22719
|
+
makeEnable: () => makeEnable,
|
|
22720
|
+
makeList: () => makeList,
|
|
22721
|
+
makeRefresh: () => makeRefresh,
|
|
22722
|
+
makeRemove: () => makeRemove,
|
|
22723
|
+
makeReorder: () => makeReorder,
|
|
22724
|
+
registerBackendSlotCommands: () => registerBackendSlotCommands
|
|
22725
|
+
});
|
|
22726
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync13, readFileSync as readFileSync18 } from "fs";
|
|
22727
|
+
import { join as join26 } from "path";
|
|
22728
|
+
import { createInterface as createInterface6 } from "readline";
|
|
22729
|
+
function requireDb2() {
|
|
22730
|
+
if (!existsSync28(DB_PATH)) {
|
|
22731
|
+
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
22732
|
+
process.exit(1);
|
|
22733
|
+
}
|
|
22734
|
+
}
|
|
22735
|
+
async function requireWriteDb2() {
|
|
22736
|
+
requireDb2();
|
|
22737
|
+
if (!dbInitialized2) {
|
|
22738
|
+
const { initDatabase: initDatabase2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22739
|
+
initDatabase2();
|
|
22740
|
+
dbInitialized2 = true;
|
|
22741
|
+
}
|
|
22742
|
+
}
|
|
22743
|
+
async function resolveSlotId2(backend2, idOrLabel) {
|
|
22744
|
+
const numeric = parseInt(idOrLabel, 10);
|
|
22745
|
+
if (!isNaN(numeric)) return numeric;
|
|
22746
|
+
const { getBackendSlots: getBackendSlots2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22747
|
+
const match = getBackendSlots2(backend2).find(
|
|
22748
|
+
(s) => s.label?.toLowerCase() === idOrLabel.toLowerCase()
|
|
22749
|
+
);
|
|
22750
|
+
return match?.id ?? null;
|
|
22751
|
+
}
|
|
22752
|
+
function makeList(backend2, displayName) {
|
|
22753
|
+
return async function list(_globalOpts) {
|
|
22754
|
+
requireDb2();
|
|
22755
|
+
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22756
|
+
const readDb = openDatabaseReadOnly2();
|
|
22757
|
+
const slots = readDb.prepare(`
|
|
22758
|
+
SELECT id, slot_type, label, config_home, priority, enabled, cooldown_until, last_used, consecutive_errors, created_at
|
|
22759
|
+
FROM backend_credentials WHERE backend = ? ORDER BY priority ASC, id ASC
|
|
22760
|
+
`).all(backend2);
|
|
22761
|
+
readDb.close();
|
|
22762
|
+
if (slots.length === 0) {
|
|
22763
|
+
output({ slots: [] }, () => `No ${displayName} credential slots configured.
|
|
22764
|
+
Add one with: cc-claw ${backend2} add-account or cc-claw ${backend2} add-key`);
|
|
22765
|
+
return;
|
|
22766
|
+
}
|
|
22767
|
+
output(slots, (data) => {
|
|
22768
|
+
const list2 = data;
|
|
22769
|
+
const lines = ["", divider(`${displayName} Credential Slots`), ""];
|
|
22770
|
+
for (const s of list2) {
|
|
22771
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
22772
|
+
const inCooldown = s.cooldown_until && s.cooldown_until > now;
|
|
22773
|
+
const icon = !s.enabled ? error2("\u25CB disabled") : inCooldown ? warning("\u25D1 cooldown") : success("\u25CF active");
|
|
22774
|
+
const label2 = s.label || `slot-${s.id}`;
|
|
22775
|
+
const type = s.slot_type === "oauth" ? "\u{1F468}\u{1F3FD}\u200D\u{1F4BB}" : "\u{1F511}";
|
|
22776
|
+
lines.push(` ${icon} ${label2} ${muted(`(${type}, #${s.id}, priority ${s.priority})`)}`);
|
|
22777
|
+
if (inCooldown) lines.push(` Cooldown until: ${warning(s.cooldown_until)}`);
|
|
22778
|
+
if (s.consecutive_errors > 0) lines.push(` Consecutive errors: ${warning(String(s.consecutive_errors))}`);
|
|
22779
|
+
if (s.last_used) lines.push(` Last used: ${muted(s.last_used)}`);
|
|
22780
|
+
}
|
|
22781
|
+
lines.push("");
|
|
22782
|
+
return lines.join("\n");
|
|
22783
|
+
});
|
|
22784
|
+
};
|
|
22785
|
+
}
|
|
22786
|
+
function makeAddKey(backend2, displayName) {
|
|
22787
|
+
return async function addKey(_globalOpts, opts) {
|
|
22788
|
+
await requireWriteDb2();
|
|
22789
|
+
const rl2 = createInterface6({ input: process.stdin, output: process.stdout });
|
|
22790
|
+
const ask2 = (q) => new Promise((r) => rl2.question(q, r));
|
|
22791
|
+
const key = await ask2(`Paste your ${displayName} API key: `);
|
|
22792
|
+
rl2.close();
|
|
22793
|
+
if (!key.trim()) {
|
|
22794
|
+
outputError("EMPTY_KEY", "No key provided.");
|
|
22795
|
+
process.exit(1);
|
|
22796
|
+
}
|
|
22797
|
+
const { addBackendSlot: addBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22798
|
+
const id = addBackendSlot2({
|
|
22799
|
+
backend: backend2,
|
|
22800
|
+
slotType: "api_key",
|
|
22801
|
+
label: opts.label,
|
|
22802
|
+
apiKey: key.trim(),
|
|
22803
|
+
priority: opts.priority ? parseInt(opts.priority, 10) : 0
|
|
22804
|
+
});
|
|
22805
|
+
output(
|
|
22806
|
+
{ id, type: "api_key", backend: backend2, label: opts.label ?? null },
|
|
22807
|
+
() => success(`Added ${displayName} API key slot #${id}${opts.label ? ` (${opts.label})` : ""}`)
|
|
22808
|
+
);
|
|
22809
|
+
};
|
|
22810
|
+
}
|
|
22811
|
+
function makeAddAccount(backend2, displayName) {
|
|
22812
|
+
return async function addAccount(_globalOpts, opts) {
|
|
22813
|
+
const config2 = ADD_ACCOUNT_CONFIGS[backend2];
|
|
22814
|
+
if (!config2) {
|
|
22815
|
+
outputError("UNSUPPORTED", `add-account is not supported for ${displayName}. Use add-key instead.`);
|
|
22816
|
+
process.exit(1);
|
|
22817
|
+
}
|
|
22818
|
+
await requireWriteDb2();
|
|
22819
|
+
const slotsDir = join26(CC_CLAW_HOME, config2.slotsSubdir);
|
|
22820
|
+
if (!existsSync28(slotsDir)) mkdirSync13(slotsDir, { recursive: true });
|
|
22821
|
+
const tempId = Date.now();
|
|
22822
|
+
const slotDir = join26(slotsDir, `slot-${tempId}`);
|
|
22823
|
+
mkdirSync13(slotDir, { recursive: true, mode: 448 });
|
|
22824
|
+
if (config2.preSetup) config2.preSetup(slotDir);
|
|
22825
|
+
console.log("");
|
|
22826
|
+
console.log(` Opening ${displayName} CLI for sign-in...`);
|
|
22827
|
+
console.log(` Sign in with the account you want for this slot.`);
|
|
22828
|
+
console.log(` After sign-in completes, return here.`);
|
|
22829
|
+
console.log("");
|
|
22830
|
+
const { execSync: execSync8 } = await import("child_process");
|
|
22831
|
+
const loginEnv = {
|
|
22832
|
+
...process.env,
|
|
22833
|
+
[config2.envKey]: config2.envValue(slotDir),
|
|
22834
|
+
...config2.envOverrides
|
|
22835
|
+
};
|
|
22836
|
+
try {
|
|
22837
|
+
execSync8(config2.loginCommand.join(" "), {
|
|
22838
|
+
stdio: "inherit",
|
|
22839
|
+
env: loginEnv,
|
|
22840
|
+
cwd: slotDir
|
|
22841
|
+
});
|
|
22842
|
+
} catch {
|
|
22843
|
+
}
|
|
22844
|
+
if (!config2.verifyCredentials(slotDir)) {
|
|
22845
|
+
console.log(error2(`
|
|
22846
|
+
No credentials found. Sign-in may have failed.`));
|
|
22847
|
+
console.log(` The slot directory is preserved at: ${slotDir}`);
|
|
22848
|
+
console.log(` Re-run: cc-claw ${backend2} add-account
|
|
22849
|
+
`);
|
|
22850
|
+
process.exit(1);
|
|
22851
|
+
}
|
|
22852
|
+
const accountLabel = opts.label || config2.extractLabel(slotDir);
|
|
22853
|
+
const { addBackendSlot: addBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22854
|
+
const id = addBackendSlot2({
|
|
22855
|
+
backend: backend2,
|
|
22856
|
+
slotType: "oauth",
|
|
22857
|
+
label: accountLabel,
|
|
22858
|
+
configHome: slotDir,
|
|
22859
|
+
priority: opts.priority ? parseInt(opts.priority, 10) : 0
|
|
22860
|
+
});
|
|
22861
|
+
output(
|
|
22862
|
+
{ id, type: "oauth", backend: backend2, label: accountLabel, configHome: slotDir },
|
|
22863
|
+
() => success(`Added ${displayName} subscription slot #${id} (${accountLabel})`)
|
|
22864
|
+
);
|
|
22865
|
+
};
|
|
22866
|
+
}
|
|
22867
|
+
function makeRemove(backend2, displayName) {
|
|
22868
|
+
return async function remove(_globalOpts, idOrLabel) {
|
|
22869
|
+
await requireWriteDb2();
|
|
22870
|
+
const slotId = await resolveSlotId2(backend2, idOrLabel);
|
|
22871
|
+
if (!slotId) {
|
|
22872
|
+
outputError("NOT_FOUND", `Slot "${idOrLabel}" not found.`);
|
|
22873
|
+
return;
|
|
22874
|
+
}
|
|
22875
|
+
const { removeBackendSlot: removeBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22876
|
+
const removed = removeBackendSlot2(slotId);
|
|
22877
|
+
if (removed) {
|
|
22878
|
+
output({ removed: true, id: slotId }, () => success(`Removed slot "${idOrLabel}" (#${slotId})`));
|
|
22879
|
+
} else {
|
|
22880
|
+
outputError("NOT_FOUND", `Slot "${idOrLabel}" not found.`);
|
|
22881
|
+
}
|
|
22882
|
+
};
|
|
22883
|
+
}
|
|
22884
|
+
function makeEnable(backend2, _displayName) {
|
|
22885
|
+
return async function enable(_globalOpts, idOrLabel) {
|
|
22886
|
+
await requireWriteDb2();
|
|
22887
|
+
const slotId = await resolveSlotId2(backend2, idOrLabel);
|
|
22888
|
+
if (!slotId) {
|
|
22889
|
+
outputError("NOT_FOUND", `Slot "${idOrLabel}" not found.`);
|
|
22890
|
+
return;
|
|
22891
|
+
}
|
|
22892
|
+
const { setBackendSlotEnabled: setBackendSlotEnabled2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22893
|
+
setBackendSlotEnabled2(slotId, true);
|
|
22894
|
+
output({ id: slotId, enabled: true }, () => success(`Enabled slot "${idOrLabel}" (#${slotId})`));
|
|
22895
|
+
};
|
|
22896
|
+
}
|
|
22897
|
+
function makeDisable(backend2, _displayName) {
|
|
22898
|
+
return async function disable(_globalOpts, idOrLabel) {
|
|
22899
|
+
await requireWriteDb2();
|
|
22900
|
+
const slotId = await resolveSlotId2(backend2, idOrLabel);
|
|
22901
|
+
if (!slotId) {
|
|
22902
|
+
outputError("NOT_FOUND", `Slot "${idOrLabel}" not found.`);
|
|
22903
|
+
return;
|
|
22904
|
+
}
|
|
22905
|
+
const { setBackendSlotEnabled: setBackendSlotEnabled2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22906
|
+
setBackendSlotEnabled2(slotId, false);
|
|
22907
|
+
output({ id: slotId, enabled: false }, () => warning(`Disabled slot "${idOrLabel}" (#${slotId})`));
|
|
22908
|
+
};
|
|
22909
|
+
}
|
|
22910
|
+
function makeReorder(backend2, _displayName) {
|
|
22911
|
+
return async function reorder(_globalOpts, idOrLabel, priority) {
|
|
22912
|
+
await requireWriteDb2();
|
|
22913
|
+
const slotId = await resolveSlotId2(backend2, idOrLabel);
|
|
22914
|
+
if (!slotId) {
|
|
22915
|
+
outputError("NOT_FOUND", `Slot "${idOrLabel}" not found.`);
|
|
22916
|
+
return;
|
|
22917
|
+
}
|
|
22918
|
+
const { reorderBackendSlot: reorderBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22919
|
+
reorderBackendSlot2(slotId, parseInt(priority, 10));
|
|
22920
|
+
output(
|
|
22921
|
+
{ id: slotId, priority: parseInt(priority, 10) },
|
|
22922
|
+
() => success(`Slot "${idOrLabel}" (#${slotId}) priority set to ${priority}`)
|
|
22923
|
+
);
|
|
22924
|
+
};
|
|
22925
|
+
}
|
|
22926
|
+
function makeRefresh(backend2, displayName) {
|
|
22927
|
+
return async function refresh(_globalOpts) {
|
|
22928
|
+
await requireWriteDb2();
|
|
22929
|
+
const { getBackendSlots: getBackendSlots2, reenableBackendSlot: reenableBackendSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22930
|
+
const slots = getBackendSlots2(backend2);
|
|
22931
|
+
let count = 0;
|
|
22932
|
+
for (const s of slots) {
|
|
22933
|
+
if (!s.enabled || s.cooldownUntil || s.consecutiveErrors > 0) {
|
|
22934
|
+
reenableBackendSlot2(s.id);
|
|
22935
|
+
count++;
|
|
22936
|
+
}
|
|
22937
|
+
}
|
|
22938
|
+
output(
|
|
22939
|
+
{ refreshed: count },
|
|
22940
|
+
() => count > 0 ? success(`Refreshed ${count} ${displayName} slot(s) \u2014 cooldowns cleared, errors reset`) : `All ${displayName} slots are already healthy.`
|
|
22941
|
+
);
|
|
22942
|
+
};
|
|
22943
|
+
}
|
|
22944
|
+
function registerBackendSlotCommands(parentCommand, backend2, displayName, globalOpts) {
|
|
22945
|
+
const cmd = parentCommand.command(backend2).description(`Manage ${displayName} credential slots`);
|
|
22946
|
+
cmd.command("list").description(`Show all configured ${displayName} credential slots`).action(async () => {
|
|
22947
|
+
await makeList(backend2, displayName)(globalOpts());
|
|
22948
|
+
});
|
|
22949
|
+
cmd.command("add-key").description("Add an API key slot (prompts for key in terminal)").option("--label <name>", "Friendly label for this slot").option("--priority <n>", "Priority (lower = preferred)", "0").action(async (opts) => {
|
|
22950
|
+
await makeAddKey(backend2, displayName)(globalOpts(), opts);
|
|
22951
|
+
});
|
|
22952
|
+
cmd.command("remove <id-or-label>").description("Remove a credential slot (by ID or label)").action(async (id) => {
|
|
22953
|
+
await makeRemove(backend2, displayName)(globalOpts(), id);
|
|
22954
|
+
});
|
|
22955
|
+
cmd.command("enable <id-or-label>").description("Re-enable a disabled slot").action(async (id) => {
|
|
22956
|
+
await makeEnable(backend2, displayName)(globalOpts(), id);
|
|
22957
|
+
});
|
|
22958
|
+
cmd.command("disable <id-or-label>").description("Disable a slot").action(async (id) => {
|
|
22959
|
+
await makeDisable(backend2, displayName)(globalOpts(), id);
|
|
22960
|
+
});
|
|
22961
|
+
cmd.command("reorder <id-or-label> <priority>").description("Set slot priority (lower = preferred)").action(async (id, priority) => {
|
|
22962
|
+
await makeReorder(backend2, displayName)(globalOpts(), id, priority);
|
|
22963
|
+
});
|
|
22964
|
+
cmd.command("refresh").description("Re-enable all slots, clear cooldowns and errors").action(async () => {
|
|
22965
|
+
await makeRefresh(backend2, displayName)(globalOpts());
|
|
22966
|
+
});
|
|
22967
|
+
return cmd;
|
|
22968
|
+
}
|
|
22969
|
+
var dbInitialized2, ADD_ACCOUNT_CONFIGS;
|
|
22970
|
+
var init_backend_cmd_factory = __esm({
|
|
22971
|
+
"src/cli/commands/backend-cmd-factory.ts"() {
|
|
22972
|
+
"use strict";
|
|
22973
|
+
init_format2();
|
|
22974
|
+
init_paths();
|
|
22975
|
+
dbInitialized2 = false;
|
|
22976
|
+
ADD_ACCOUNT_CONFIGS = {
|
|
22977
|
+
claude: {
|
|
22978
|
+
slotsSubdir: "claude-slots",
|
|
22979
|
+
loginCommand: ["claude", "auth", "login", "--claudeai"],
|
|
22980
|
+
envKey: "HOME",
|
|
22981
|
+
envValue: (slotDir) => slotDir,
|
|
22982
|
+
envOverrides: { ANTHROPIC_API_KEY: void 0 },
|
|
22983
|
+
preSetup: (slotDir) => {
|
|
22984
|
+
mkdirSync13(join26(slotDir, ".claude"), { recursive: true });
|
|
22985
|
+
},
|
|
22986
|
+
verifyCredentials: (slotDir) => {
|
|
22987
|
+
const claudeJson = join26(slotDir, ".claude.json");
|
|
22988
|
+
const claudeJsonNested = join26(slotDir, ".claude", ".claude.json");
|
|
22989
|
+
if (existsSync28(claudeJson)) {
|
|
22990
|
+
try {
|
|
22991
|
+
const data = JSON.parse(readFileSync18(claudeJson, "utf-8"));
|
|
22992
|
+
return Boolean(data.oauthAccount);
|
|
22993
|
+
} catch {
|
|
22994
|
+
return false;
|
|
22995
|
+
}
|
|
22996
|
+
}
|
|
22997
|
+
if (existsSync28(claudeJsonNested)) {
|
|
22998
|
+
try {
|
|
22999
|
+
const data = JSON.parse(readFileSync18(claudeJsonNested, "utf-8"));
|
|
23000
|
+
return Boolean(data.oauthAccount);
|
|
23001
|
+
} catch {
|
|
23002
|
+
return false;
|
|
23003
|
+
}
|
|
23004
|
+
}
|
|
23005
|
+
return false;
|
|
23006
|
+
},
|
|
23007
|
+
extractLabel: (slotDir) => {
|
|
23008
|
+
try {
|
|
23009
|
+
const { execSync: execSync8 } = __require("child_process");
|
|
23010
|
+
const out = execSync8("claude auth status", {
|
|
23011
|
+
encoding: "utf-8",
|
|
23012
|
+
env: { ...process.env, HOME: slotDir, ANTHROPIC_API_KEY: void 0 },
|
|
23013
|
+
timeout: 1e4
|
|
23014
|
+
});
|
|
23015
|
+
const parsed = JSON.parse(out);
|
|
23016
|
+
if (parsed.email) return parsed.email;
|
|
23017
|
+
} catch {
|
|
23018
|
+
}
|
|
23019
|
+
try {
|
|
23020
|
+
const claudeJson = join26(slotDir, ".claude.json");
|
|
23021
|
+
if (existsSync28(claudeJson)) {
|
|
23022
|
+
const data = JSON.parse(readFileSync18(claudeJson, "utf-8"));
|
|
23023
|
+
if (data.oauthAccount?.emailAddress) return data.oauthAccount.emailAddress;
|
|
23024
|
+
}
|
|
23025
|
+
} catch {
|
|
23026
|
+
}
|
|
23027
|
+
return "subscription";
|
|
23028
|
+
}
|
|
23029
|
+
},
|
|
23030
|
+
codex: {
|
|
23031
|
+
slotsSubdir: "codex-slots",
|
|
23032
|
+
loginCommand: ["codex", "login"],
|
|
23033
|
+
envKey: "CODEX_HOME",
|
|
23034
|
+
envValue: (slotDir) => slotDir,
|
|
23035
|
+
envOverrides: { OPENAI_API_KEY: void 0 },
|
|
23036
|
+
verifyCredentials: (slotDir) => {
|
|
23037
|
+
return existsSync28(join26(slotDir, "auth.json"));
|
|
23038
|
+
},
|
|
23039
|
+
extractLabel: (slotDir) => {
|
|
23040
|
+
try {
|
|
23041
|
+
const authData = JSON.parse(readFileSync18(join26(slotDir, "auth.json"), "utf-8"));
|
|
23042
|
+
if (authData.email) return authData.email;
|
|
23043
|
+
if (authData.account_name) return authData.account_name;
|
|
23044
|
+
if (authData.user?.email) return authData.user.email;
|
|
23045
|
+
} catch {
|
|
23046
|
+
}
|
|
23047
|
+
return "subscription";
|
|
23048
|
+
}
|
|
23049
|
+
}
|
|
23050
|
+
};
|
|
23051
|
+
}
|
|
23052
|
+
});
|
|
23053
|
+
|
|
22418
23054
|
// src/cli/commands/backend.ts
|
|
22419
23055
|
var backend_exports = {};
|
|
22420
23056
|
__export(backend_exports, {
|
|
@@ -22422,12 +23058,12 @@ __export(backend_exports, {
|
|
|
22422
23058
|
backendList: () => backendList,
|
|
22423
23059
|
backendSet: () => backendSet
|
|
22424
23060
|
});
|
|
22425
|
-
import { existsSync as
|
|
23061
|
+
import { existsSync as existsSync29 } from "fs";
|
|
22426
23062
|
async function backendList(globalOpts) {
|
|
22427
23063
|
const { getAvailableAdapters: getAvailableAdapters3 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
|
|
22428
23064
|
const chatId = resolveChatId(globalOpts);
|
|
22429
23065
|
let activeBackend = null;
|
|
22430
|
-
if (
|
|
23066
|
+
if (existsSync29(DB_PATH)) {
|
|
22431
23067
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22432
23068
|
const readDb = openDatabaseReadOnly2();
|
|
22433
23069
|
try {
|
|
@@ -22458,7 +23094,7 @@ async function backendList(globalOpts) {
|
|
|
22458
23094
|
}
|
|
22459
23095
|
async function backendGet(globalOpts) {
|
|
22460
23096
|
const chatId = resolveChatId(globalOpts);
|
|
22461
|
-
if (!
|
|
23097
|
+
if (!existsSync29(DB_PATH)) {
|
|
22462
23098
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
22463
23099
|
process.exit(1);
|
|
22464
23100
|
}
|
|
@@ -22502,13 +23138,13 @@ __export(model_exports, {
|
|
|
22502
23138
|
modelList: () => modelList,
|
|
22503
23139
|
modelSet: () => modelSet
|
|
22504
23140
|
});
|
|
22505
|
-
import { existsSync as
|
|
23141
|
+
import { existsSync as existsSync30 } from "fs";
|
|
22506
23142
|
async function modelList(globalOpts) {
|
|
22507
23143
|
const chatId = resolveChatId(globalOpts);
|
|
22508
23144
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
22509
23145
|
const { getAdapter: getAdapter4, getAllAdapters: getAllAdapters5 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
|
|
22510
23146
|
let backendId = "claude";
|
|
22511
|
-
if (
|
|
23147
|
+
if (existsSync30(DB_PATH)) {
|
|
22512
23148
|
const readDb = openDatabaseReadOnly2();
|
|
22513
23149
|
try {
|
|
22514
23150
|
const row = readDb.prepare("SELECT backend FROM chat_backend WHERE chat_id = ?").get(chatId);
|
|
@@ -22541,7 +23177,7 @@ async function modelList(globalOpts) {
|
|
|
22541
23177
|
}
|
|
22542
23178
|
async function modelGet(globalOpts) {
|
|
22543
23179
|
const chatId = resolveChatId(globalOpts);
|
|
22544
|
-
if (!
|
|
23180
|
+
if (!existsSync30(DB_PATH)) {
|
|
22545
23181
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22546
23182
|
process.exit(1);
|
|
22547
23183
|
}
|
|
@@ -22585,9 +23221,9 @@ __export(memory_exports2, {
|
|
|
22585
23221
|
memoryList: () => memoryList,
|
|
22586
23222
|
memorySearch: () => memorySearch
|
|
22587
23223
|
});
|
|
22588
|
-
import { existsSync as
|
|
23224
|
+
import { existsSync as existsSync31 } from "fs";
|
|
22589
23225
|
async function memoryList(globalOpts) {
|
|
22590
|
-
if (!
|
|
23226
|
+
if (!existsSync31(DB_PATH)) {
|
|
22591
23227
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
22592
23228
|
process.exit(1);
|
|
22593
23229
|
}
|
|
@@ -22611,7 +23247,7 @@ async function memoryList(globalOpts) {
|
|
|
22611
23247
|
});
|
|
22612
23248
|
}
|
|
22613
23249
|
async function memorySearch(globalOpts, query) {
|
|
22614
|
-
if (!
|
|
23250
|
+
if (!existsSync31(DB_PATH)) {
|
|
22615
23251
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22616
23252
|
process.exit(1);
|
|
22617
23253
|
}
|
|
@@ -22633,7 +23269,7 @@ async function memorySearch(globalOpts, query) {
|
|
|
22633
23269
|
});
|
|
22634
23270
|
}
|
|
22635
23271
|
async function memoryHistory(globalOpts, opts) {
|
|
22636
|
-
if (!
|
|
23272
|
+
if (!existsSync31(DB_PATH)) {
|
|
22637
23273
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22638
23274
|
process.exit(1);
|
|
22639
23275
|
}
|
|
@@ -22681,7 +23317,7 @@ __export(cron_exports2, {
|
|
|
22681
23317
|
cronList: () => cronList,
|
|
22682
23318
|
cronRuns: () => cronRuns
|
|
22683
23319
|
});
|
|
22684
|
-
import { existsSync as
|
|
23320
|
+
import { existsSync as existsSync32 } from "fs";
|
|
22685
23321
|
function parseFallbacks(raw) {
|
|
22686
23322
|
return raw.slice(0, 3).map((f) => {
|
|
22687
23323
|
const [backend2, ...rest] = f.split(":");
|
|
@@ -22702,7 +23338,7 @@ function parseAndValidateTimeout(raw) {
|
|
|
22702
23338
|
return val;
|
|
22703
23339
|
}
|
|
22704
23340
|
async function cronList(globalOpts) {
|
|
22705
|
-
if (!
|
|
23341
|
+
if (!existsSync32(DB_PATH)) {
|
|
22706
23342
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22707
23343
|
process.exit(1);
|
|
22708
23344
|
}
|
|
@@ -22740,7 +23376,7 @@ async function cronList(globalOpts) {
|
|
|
22740
23376
|
});
|
|
22741
23377
|
}
|
|
22742
23378
|
async function cronHealth(globalOpts) {
|
|
22743
|
-
if (!
|
|
23379
|
+
if (!existsSync32(DB_PATH)) {
|
|
22744
23380
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22745
23381
|
process.exit(1);
|
|
22746
23382
|
}
|
|
@@ -22899,7 +23535,7 @@ async function cronEdit(globalOpts, id, opts) {
|
|
|
22899
23535
|
}
|
|
22900
23536
|
}
|
|
22901
23537
|
async function cronRuns(globalOpts, jobId, opts) {
|
|
22902
|
-
if (!
|
|
23538
|
+
if (!existsSync32(DB_PATH)) {
|
|
22903
23539
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22904
23540
|
process.exit(1);
|
|
22905
23541
|
}
|
|
@@ -22946,9 +23582,9 @@ __export(agents_exports, {
|
|
|
22946
23582
|
runnersList: () => runnersList,
|
|
22947
23583
|
tasksList: () => tasksList
|
|
22948
23584
|
});
|
|
22949
|
-
import { existsSync as
|
|
23585
|
+
import { existsSync as existsSync33 } from "fs";
|
|
22950
23586
|
async function agentsList(globalOpts) {
|
|
22951
|
-
if (!
|
|
23587
|
+
if (!existsSync33(DB_PATH)) {
|
|
22952
23588
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22953
23589
|
process.exit(1);
|
|
22954
23590
|
}
|
|
@@ -22979,7 +23615,7 @@ async function agentsList(globalOpts) {
|
|
|
22979
23615
|
});
|
|
22980
23616
|
}
|
|
22981
23617
|
async function tasksList(globalOpts) {
|
|
22982
|
-
if (!
|
|
23618
|
+
if (!existsSync33(DB_PATH)) {
|
|
22983
23619
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
22984
23620
|
process.exit(1);
|
|
22985
23621
|
}
|
|
@@ -23107,10 +23743,10 @@ __export(db_exports, {
|
|
|
23107
23743
|
dbPath: () => dbPath,
|
|
23108
23744
|
dbStats: () => dbStats
|
|
23109
23745
|
});
|
|
23110
|
-
import { existsSync as
|
|
23746
|
+
import { existsSync as existsSync34, statSync as statSync8, copyFileSync as copyFileSync2, mkdirSync as mkdirSync14 } from "fs";
|
|
23111
23747
|
import { dirname as dirname5 } from "path";
|
|
23112
23748
|
async function dbStats(globalOpts) {
|
|
23113
|
-
if (!
|
|
23749
|
+
if (!existsSync34(DB_PATH)) {
|
|
23114
23750
|
outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
|
|
23115
23751
|
process.exit(1);
|
|
23116
23752
|
}
|
|
@@ -23118,7 +23754,7 @@ async function dbStats(globalOpts) {
|
|
|
23118
23754
|
const readDb = openDatabaseReadOnly2();
|
|
23119
23755
|
const mainSize = statSync8(DB_PATH).size;
|
|
23120
23756
|
const walPath = DB_PATH + "-wal";
|
|
23121
|
-
const walSize =
|
|
23757
|
+
const walSize = existsSync34(walPath) ? statSync8(walPath).size : 0;
|
|
23122
23758
|
const tableNames = readDb.prepare(
|
|
23123
23759
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '%_fts%' ORDER BY name"
|
|
23124
23760
|
).all();
|
|
@@ -23152,16 +23788,16 @@ async function dbPath(globalOpts) {
|
|
|
23152
23788
|
output({ path: DB_PATH }, (d) => d.path);
|
|
23153
23789
|
}
|
|
23154
23790
|
async function dbBackup(globalOpts, destPath) {
|
|
23155
|
-
if (!
|
|
23791
|
+
if (!existsSync34(DB_PATH)) {
|
|
23156
23792
|
outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
|
|
23157
23793
|
process.exit(1);
|
|
23158
23794
|
}
|
|
23159
23795
|
const dest = destPath ?? `${DB_PATH}.backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
23160
23796
|
try {
|
|
23161
|
-
|
|
23797
|
+
mkdirSync14(dirname5(dest), { recursive: true });
|
|
23162
23798
|
copyFileSync2(DB_PATH, dest);
|
|
23163
23799
|
const walPath = DB_PATH + "-wal";
|
|
23164
|
-
if (
|
|
23800
|
+
if (existsSync34(walPath)) copyFileSync2(walPath, dest + "-wal");
|
|
23165
23801
|
output({ path: dest, sizeBytes: statSync8(dest).size }, (d) => {
|
|
23166
23802
|
const b = d;
|
|
23167
23803
|
return `
|
|
@@ -23190,9 +23826,9 @@ __export(usage_exports, {
|
|
|
23190
23826
|
usageCost: () => usageCost,
|
|
23191
23827
|
usageTokens: () => usageTokens
|
|
23192
23828
|
});
|
|
23193
|
-
import { existsSync as
|
|
23829
|
+
import { existsSync as existsSync35 } from "fs";
|
|
23194
23830
|
function ensureDb() {
|
|
23195
|
-
if (!
|
|
23831
|
+
if (!existsSync35(DB_PATH)) {
|
|
23196
23832
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
23197
23833
|
process.exit(1);
|
|
23198
23834
|
}
|
|
@@ -23382,9 +24018,9 @@ __export(config_exports2, {
|
|
|
23382
24018
|
configList: () => configList,
|
|
23383
24019
|
configSet: () => configSet
|
|
23384
24020
|
});
|
|
23385
|
-
import { existsSync as
|
|
24021
|
+
import { existsSync as existsSync36, readFileSync as readFileSync19 } from "fs";
|
|
23386
24022
|
async function configList(globalOpts) {
|
|
23387
|
-
if (!
|
|
24023
|
+
if (!existsSync36(DB_PATH)) {
|
|
23388
24024
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23389
24025
|
process.exit(1);
|
|
23390
24026
|
}
|
|
@@ -23418,7 +24054,7 @@ async function configGet(globalOpts, key) {
|
|
|
23418
24054
|
outputError("INVALID_KEY", `Unknown config key "${key}". Valid keys: ${RUNTIME_KEYS.join(", ")}`);
|
|
23419
24055
|
process.exit(1);
|
|
23420
24056
|
}
|
|
23421
|
-
if (!
|
|
24057
|
+
if (!existsSync36(DB_PATH)) {
|
|
23422
24058
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23423
24059
|
process.exit(1);
|
|
23424
24060
|
}
|
|
@@ -23464,11 +24100,11 @@ async function configSet(globalOpts, key, value) {
|
|
|
23464
24100
|
}
|
|
23465
24101
|
}
|
|
23466
24102
|
async function configEnv(_globalOpts) {
|
|
23467
|
-
if (!
|
|
24103
|
+
if (!existsSync36(ENV_PATH)) {
|
|
23468
24104
|
outputError("ENV_NOT_FOUND", `No .env file at ${ENV_PATH}. Run cc-claw setup.`);
|
|
23469
24105
|
process.exit(1);
|
|
23470
24106
|
}
|
|
23471
|
-
const content =
|
|
24107
|
+
const content = readFileSync19(ENV_PATH, "utf-8");
|
|
23472
24108
|
const entries = {};
|
|
23473
24109
|
const secretPatterns = /TOKEN|KEY|SECRET|PASSWORD|CREDENTIALS/i;
|
|
23474
24110
|
for (const line of content.split("\n")) {
|
|
@@ -23518,9 +24154,9 @@ __export(session_exports, {
|
|
|
23518
24154
|
sessionGet: () => sessionGet,
|
|
23519
24155
|
sessionNew: () => sessionNew
|
|
23520
24156
|
});
|
|
23521
|
-
import { existsSync as
|
|
24157
|
+
import { existsSync as existsSync37 } from "fs";
|
|
23522
24158
|
async function sessionGet(globalOpts) {
|
|
23523
|
-
if (!
|
|
24159
|
+
if (!existsSync37(DB_PATH)) {
|
|
23524
24160
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23525
24161
|
process.exit(1);
|
|
23526
24162
|
}
|
|
@@ -23581,9 +24217,9 @@ __export(permissions_exports, {
|
|
|
23581
24217
|
verboseGet: () => verboseGet,
|
|
23582
24218
|
verboseSet: () => verboseSet
|
|
23583
24219
|
});
|
|
23584
|
-
import { existsSync as
|
|
24220
|
+
import { existsSync as existsSync38 } from "fs";
|
|
23585
24221
|
function ensureDb2() {
|
|
23586
|
-
if (!
|
|
24222
|
+
if (!existsSync38(DB_PATH)) {
|
|
23587
24223
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23588
24224
|
process.exit(1);
|
|
23589
24225
|
}
|
|
@@ -23730,9 +24366,9 @@ __export(cwd_exports, {
|
|
|
23730
24366
|
cwdGet: () => cwdGet,
|
|
23731
24367
|
cwdSet: () => cwdSet
|
|
23732
24368
|
});
|
|
23733
|
-
import { existsSync as
|
|
24369
|
+
import { existsSync as existsSync39 } from "fs";
|
|
23734
24370
|
async function cwdGet(globalOpts) {
|
|
23735
|
-
if (!
|
|
24371
|
+
if (!existsSync39(DB_PATH)) {
|
|
23736
24372
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23737
24373
|
process.exit(1);
|
|
23738
24374
|
}
|
|
@@ -23794,9 +24430,9 @@ __export(voice_exports, {
|
|
|
23794
24430
|
voiceGet: () => voiceGet,
|
|
23795
24431
|
voiceSet: () => voiceSet
|
|
23796
24432
|
});
|
|
23797
|
-
import { existsSync as
|
|
24433
|
+
import { existsSync as existsSync40 } from "fs";
|
|
23798
24434
|
async function voiceGet(globalOpts) {
|
|
23799
|
-
if (!
|
|
24435
|
+
if (!existsSync40(DB_PATH)) {
|
|
23800
24436
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23801
24437
|
process.exit(1);
|
|
23802
24438
|
}
|
|
@@ -23845,9 +24481,9 @@ __export(heartbeat_exports, {
|
|
|
23845
24481
|
heartbeatGet: () => heartbeatGet,
|
|
23846
24482
|
heartbeatSet: () => heartbeatSet
|
|
23847
24483
|
});
|
|
23848
|
-
import { existsSync as
|
|
24484
|
+
import { existsSync as existsSync41 } from "fs";
|
|
23849
24485
|
async function heartbeatGet(globalOpts) {
|
|
23850
|
-
if (!
|
|
24486
|
+
if (!existsSync41(DB_PATH)) {
|
|
23851
24487
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23852
24488
|
process.exit(1);
|
|
23853
24489
|
}
|
|
@@ -23956,9 +24592,9 @@ __export(summarizer_exports, {
|
|
|
23956
24592
|
summarizerGet: () => summarizerGet,
|
|
23957
24593
|
summarizerSet: () => summarizerSet
|
|
23958
24594
|
});
|
|
23959
|
-
import { existsSync as
|
|
24595
|
+
import { existsSync as existsSync42 } from "fs";
|
|
23960
24596
|
async function summarizerGet(globalOpts) {
|
|
23961
|
-
if (!
|
|
24597
|
+
if (!existsSync42(DB_PATH)) {
|
|
23962
24598
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
23963
24599
|
process.exit(1);
|
|
23964
24600
|
}
|
|
@@ -24002,9 +24638,9 @@ __export(thinking_exports, {
|
|
|
24002
24638
|
thinkingGet: () => thinkingGet,
|
|
24003
24639
|
thinkingSet: () => thinkingSet
|
|
24004
24640
|
});
|
|
24005
|
-
import { existsSync as
|
|
24641
|
+
import { existsSync as existsSync43 } from "fs";
|
|
24006
24642
|
async function thinkingGet(globalOpts) {
|
|
24007
|
-
if (!
|
|
24643
|
+
if (!existsSync43(DB_PATH)) {
|
|
24008
24644
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
24009
24645
|
process.exit(1);
|
|
24010
24646
|
}
|
|
@@ -24048,9 +24684,9 @@ __export(chats_exports, {
|
|
|
24048
24684
|
chatsList: () => chatsList,
|
|
24049
24685
|
chatsRemoveAlias: () => chatsRemoveAlias
|
|
24050
24686
|
});
|
|
24051
|
-
import { existsSync as
|
|
24687
|
+
import { existsSync as existsSync44 } from "fs";
|
|
24052
24688
|
async function chatsList(_globalOpts) {
|
|
24053
|
-
if (!
|
|
24689
|
+
if (!existsSync44(DB_PATH)) {
|
|
24054
24690
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
24055
24691
|
process.exit(1);
|
|
24056
24692
|
}
|
|
@@ -24178,9 +24814,9 @@ var mcps_exports2 = {};
|
|
|
24178
24814
|
__export(mcps_exports2, {
|
|
24179
24815
|
mcpsList: () => mcpsList
|
|
24180
24816
|
});
|
|
24181
|
-
import { existsSync as
|
|
24817
|
+
import { existsSync as existsSync45 } from "fs";
|
|
24182
24818
|
async function mcpsList(_globalOpts) {
|
|
24183
|
-
if (!
|
|
24819
|
+
if (!existsSync45(DB_PATH)) {
|
|
24184
24820
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
24185
24821
|
process.exit(1);
|
|
24186
24822
|
}
|
|
@@ -24217,11 +24853,11 @@ __export(chat_exports2, {
|
|
|
24217
24853
|
chatSend: () => chatSend
|
|
24218
24854
|
});
|
|
24219
24855
|
import { request as httpRequest2 } from "http";
|
|
24220
|
-
import { readFileSync as
|
|
24856
|
+
import { readFileSync as readFileSync20, existsSync as existsSync46 } from "fs";
|
|
24221
24857
|
function getToken2() {
|
|
24222
24858
|
if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
|
|
24223
24859
|
try {
|
|
24224
|
-
if (
|
|
24860
|
+
if (existsSync46(TOKEN_PATH2)) return readFileSync20(TOKEN_PATH2, "utf-8").trim();
|
|
24225
24861
|
} catch {
|
|
24226
24862
|
}
|
|
24227
24863
|
return null;
|
|
@@ -24358,7 +24994,7 @@ var tui_exports = {};
|
|
|
24358
24994
|
__export(tui_exports, {
|
|
24359
24995
|
tuiCommand: () => tuiCommand
|
|
24360
24996
|
});
|
|
24361
|
-
import { createInterface as
|
|
24997
|
+
import { createInterface as createInterface7 } from "readline";
|
|
24362
24998
|
import pc2 from "picocolors";
|
|
24363
24999
|
async function tuiCommand(globalOpts, cmdOpts) {
|
|
24364
25000
|
const { isDaemonRunning: isDaemonRunning2, apiPost: apiPost2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
@@ -24368,7 +25004,7 @@ async function tuiCommand(globalOpts, cmdOpts) {
|
|
|
24368
25004
|
}
|
|
24369
25005
|
const chatId = resolveChatId(globalOpts);
|
|
24370
25006
|
const { chatSend: chatSend2 } = await Promise.resolve().then(() => (init_chat2(), chat_exports2));
|
|
24371
|
-
const rl2 =
|
|
25007
|
+
const rl2 = createInterface7({
|
|
24372
25008
|
input: process.stdin,
|
|
24373
25009
|
output: process.stdout,
|
|
24374
25010
|
prompt: pc2.cyan("you > "),
|
|
@@ -24500,8 +25136,8 @@ var completion_exports = {};
|
|
|
24500
25136
|
__export(completion_exports, {
|
|
24501
25137
|
completionCommand: () => completionCommand
|
|
24502
25138
|
});
|
|
24503
|
-
import { writeFileSync as writeFileSync10, mkdirSync as
|
|
24504
|
-
import { join as
|
|
25139
|
+
import { writeFileSync as writeFileSync10, mkdirSync as mkdirSync15 } from "fs";
|
|
25140
|
+
import { join as join27 } from "path";
|
|
24505
25141
|
import { homedir as homedir9 } from "os";
|
|
24506
25142
|
async function completionCommand(opts) {
|
|
24507
25143
|
const shell = opts.shell ?? detectShell();
|
|
@@ -24517,10 +25153,10 @@ async function completionCommand(opts) {
|
|
|
24517
25153
|
process.exit(1);
|
|
24518
25154
|
}
|
|
24519
25155
|
if (opts.install) {
|
|
24520
|
-
const dir =
|
|
24521
|
-
|
|
25156
|
+
const dir = join27(homedir9(), ".config", "cc-claw", "completions");
|
|
25157
|
+
mkdirSync15(dir, { recursive: true });
|
|
24522
25158
|
const filename = shell === "zsh" ? "_cc-claw" : shell === "fish" ? "cc-claw.fish" : "cc-claw.bash";
|
|
24523
|
-
const filepath =
|
|
25159
|
+
const filepath = join27(dir, filename);
|
|
24524
25160
|
writeFileSync10(filepath, script, "utf-8");
|
|
24525
25161
|
console.log(`\u2713 Completion script written to ${filepath}
|
|
24526
25162
|
`);
|
|
@@ -24691,9 +25327,9 @@ __export(evolve_exports2, {
|
|
|
24691
25327
|
evolveStatus: () => evolveStatus,
|
|
24692
25328
|
evolveUndo: () => evolveUndo
|
|
24693
25329
|
});
|
|
24694
|
-
import { existsSync as
|
|
25330
|
+
import { existsSync as existsSync47 } from "fs";
|
|
24695
25331
|
function ensureDb3() {
|
|
24696
|
-
if (!
|
|
25332
|
+
if (!existsSync47(DB_PATH)) {
|
|
24697
25333
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
24698
25334
|
process.exit(1);
|
|
24699
25335
|
}
|
|
@@ -25109,10 +25745,10 @@ var init_evolve3 = __esm({
|
|
|
25109
25745
|
|
|
25110
25746
|
// src/setup.ts
|
|
25111
25747
|
var setup_exports = {};
|
|
25112
|
-
import { existsSync as
|
|
25748
|
+
import { existsSync as existsSync48, writeFileSync as writeFileSync11, readFileSync as readFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync16, statSync as statSync9 } from "fs";
|
|
25113
25749
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
25114
|
-
import { createInterface as
|
|
25115
|
-
import { join as
|
|
25750
|
+
import { createInterface as createInterface8 } from "readline";
|
|
25751
|
+
import { join as join28 } from "path";
|
|
25116
25752
|
function divider2() {
|
|
25117
25753
|
console.log(dim("\u2500".repeat(55)));
|
|
25118
25754
|
}
|
|
@@ -25187,21 +25823,21 @@ async function setup() {
|
|
|
25187
25823
|
}
|
|
25188
25824
|
console.log("");
|
|
25189
25825
|
for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
|
|
25190
|
-
if (!
|
|
25826
|
+
if (!existsSync48(dir)) mkdirSync16(dir, { recursive: true });
|
|
25191
25827
|
}
|
|
25192
25828
|
const env = {};
|
|
25193
|
-
const envSource =
|
|
25829
|
+
const envSource = existsSync48(ENV_PATH) ? ENV_PATH : existsSync48(".env") ? ".env" : null;
|
|
25194
25830
|
if (envSource) {
|
|
25195
25831
|
console.log(yellow(` Found existing config at ${envSource} \u2014 your values will be preserved`));
|
|
25196
25832
|
console.log(yellow(" unless you enter new ones. Just press Enter to keep existing values.\n"));
|
|
25197
|
-
const existing =
|
|
25833
|
+
const existing = readFileSync21(envSource, "utf-8");
|
|
25198
25834
|
for (const line of existing.split("\n")) {
|
|
25199
25835
|
const match = line.match(/^([^#=]+)=(.*)$/);
|
|
25200
25836
|
if (match) env[match[1].trim()] = match[2].trim();
|
|
25201
25837
|
}
|
|
25202
25838
|
}
|
|
25203
|
-
const cwdDb =
|
|
25204
|
-
if (
|
|
25839
|
+
const cwdDb = join28(process.cwd(), "cc-claw.db");
|
|
25840
|
+
if (existsSync48(cwdDb) && !existsSync48(DB_PATH)) {
|
|
25205
25841
|
const { size } = statSync9(cwdDb);
|
|
25206
25842
|
console.log(yellow(` Found existing database at ${cwdDb} (${(size / 1024).toFixed(0)}KB)`));
|
|
25207
25843
|
const migrate = await confirm("Copy database to ~/.cc-claw/? (preserves memories & history)", true);
|
|
@@ -25474,7 +26110,7 @@ var init_setup = __esm({
|
|
|
25474
26110
|
"src/setup.ts"() {
|
|
25475
26111
|
"use strict";
|
|
25476
26112
|
init_paths();
|
|
25477
|
-
rl =
|
|
26113
|
+
rl = createInterface8({ input: process.stdin, output: process.stdout });
|
|
25478
26114
|
ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
25479
26115
|
bold = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
25480
26116
|
green = (s) => `\x1B[32m${s}\x1B[0m`;
|
|
@@ -25576,6 +26212,43 @@ gemini.command("rotation [mode]").description("Get or set rotation mode (off, al
|
|
|
25576
26212
|
const { geminiRotation: geminiRotation2 } = await Promise.resolve().then(() => (init_gemini2(), gemini_exports));
|
|
25577
26213
|
await geminiRotation2(program.opts(), mode);
|
|
25578
26214
|
});
|
|
26215
|
+
function registerUnifiedSlotCommands(parentCmd, backendId, displayName) {
|
|
26216
|
+
const cmd = parentCmd.command(backendId).description(`Manage ${displayName} credential slots`);
|
|
26217
|
+
cmd.command("list").description(`Show all configured ${displayName} credential slots`).action(async () => {
|
|
26218
|
+
const { makeList: makeList2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26219
|
+
await makeList2(backendId, displayName)(program.opts());
|
|
26220
|
+
});
|
|
26221
|
+
cmd.command("add-key").description("Add an API key slot (prompts for key in terminal)").option("--label <name>", "Friendly label for this slot").option("--priority <n>", "Priority (lower = preferred)", "0").action(async (opts) => {
|
|
26222
|
+
const { makeAddKey: makeAddKey2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26223
|
+
await makeAddKey2(backendId, displayName)(program.opts(), opts);
|
|
26224
|
+
});
|
|
26225
|
+
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) => {
|
|
26226
|
+
const { makeAddAccount: makeAddAccount2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26227
|
+
await makeAddAccount2(backendId, displayName)(program.opts(), opts);
|
|
26228
|
+
});
|
|
26229
|
+
cmd.command("remove <id-or-label>").description("Remove a credential slot (by ID or label)").action(async (id) => {
|
|
26230
|
+
const { makeRemove: makeRemove2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26231
|
+
await makeRemove2(backendId, displayName)(program.opts(), id);
|
|
26232
|
+
});
|
|
26233
|
+
cmd.command("enable <id-or-label>").description("Re-enable a disabled slot").action(async (id) => {
|
|
26234
|
+
const { makeEnable: makeEnable2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26235
|
+
await makeEnable2(backendId, displayName)(program.opts(), id);
|
|
26236
|
+
});
|
|
26237
|
+
cmd.command("disable <id-or-label>").description("Disable a slot").action(async (id) => {
|
|
26238
|
+
const { makeDisable: makeDisable2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26239
|
+
await makeDisable2(backendId, displayName)(program.opts(), id);
|
|
26240
|
+
});
|
|
26241
|
+
cmd.command("reorder <id-or-label> <priority>").description("Set slot priority (lower = preferred)").action(async (id, priority) => {
|
|
26242
|
+
const { makeReorder: makeReorder2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26243
|
+
await makeReorder2(backendId, displayName)(program.opts(), id, priority);
|
|
26244
|
+
});
|
|
26245
|
+
cmd.command("refresh").description("Re-enable all slots, clear cooldowns and errors").action(async () => {
|
|
26246
|
+
const { makeRefresh: makeRefresh2 } = await Promise.resolve().then(() => (init_backend_cmd_factory(), backend_cmd_factory_exports));
|
|
26247
|
+
await makeRefresh2(backendId, displayName)(program.opts());
|
|
26248
|
+
});
|
|
26249
|
+
}
|
|
26250
|
+
registerUnifiedSlotCommands(program, "claude", "Claude");
|
|
26251
|
+
registerUnifiedSlotCommands(program, "codex", "Codex");
|
|
25579
26252
|
var backend = program.command("backend").description("Manage AI backend");
|
|
25580
26253
|
backend.command("list").description("Available backends with status").action(async () => {
|
|
25581
26254
|
const { backendList: backendList2 } = await Promise.resolve().then(() => (init_backend(), backend_exports));
|