cc-claw 0.22.5 → 0.22.6
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 +431 -401
- 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.22.
|
|
36
|
+
VERSION = true ? "0.22.6" : (() => {
|
|
37
37
|
try {
|
|
38
38
|
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
|
|
39
39
|
} catch {
|
|
@@ -9642,9 +9642,9 @@ function resolveSkillForTask(skillName) {
|
|
|
9642
9642
|
for (const candidate of SKILL_FILE_CANDIDATES3) {
|
|
9643
9643
|
const skillPath = join10(SKILLS_PATH, skillName, candidate);
|
|
9644
9644
|
try {
|
|
9645
|
-
const { readFileSync:
|
|
9646
|
-
if (!
|
|
9647
|
-
const raw =
|
|
9645
|
+
const { readFileSync: readFileSync33, existsSync: existsSync62 } = __require("fs");
|
|
9646
|
+
if (!existsSync62(skillPath)) continue;
|
|
9647
|
+
const raw = readFileSync33(skillPath, "utf-8");
|
|
9648
9648
|
const fm = parseFrontmatter(raw, skillName, "cc-claw");
|
|
9649
9649
|
if (fm.status !== "approved") {
|
|
9650
9650
|
log(`[skills] Skill "${skillName}" has status "${fm.status}" \u2014 only approved skills can be used as task worker identity`);
|
|
@@ -9948,8 +9948,10 @@ var init_cost = __esm({
|
|
|
9948
9948
|
|
|
9949
9949
|
// src/mcps/propagate.ts
|
|
9950
9950
|
import { execFile } from "child_process";
|
|
9951
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync11 } from "fs";
|
|
9951
9952
|
import { promisify } from "util";
|
|
9952
9953
|
import { homedir as homedir4 } from "os";
|
|
9954
|
+
import { join as join12 } from "path";
|
|
9953
9955
|
async function discoverExistingMcps(runner) {
|
|
9954
9956
|
try {
|
|
9955
9957
|
const listCmd = runner.getMcpListCommand();
|
|
@@ -10021,10 +10023,33 @@ function defToConfig(def) {
|
|
|
10021
10023
|
return null;
|
|
10022
10024
|
}
|
|
10023
10025
|
}
|
|
10026
|
+
function injectMcpToCursorConfig(config2) {
|
|
10027
|
+
const configPath = join12(homedir4(), ".cursor", "mcp.json");
|
|
10028
|
+
let existing = {};
|
|
10029
|
+
try {
|
|
10030
|
+
if (existsSync11(configPath)) {
|
|
10031
|
+
existing = JSON.parse(readFileSync7(configPath, "utf-8"));
|
|
10032
|
+
}
|
|
10033
|
+
} catch {
|
|
10034
|
+
}
|
|
10035
|
+
const servers = existing.mcpServers ?? {};
|
|
10036
|
+
if (servers[config2.name]) return false;
|
|
10037
|
+
const entry = {};
|
|
10038
|
+
if (config2.command) entry.command = config2.command;
|
|
10039
|
+
if (config2.args?.length) entry.args = config2.args;
|
|
10040
|
+
if (config2.url) entry.url = config2.url;
|
|
10041
|
+
if (config2.env) entry.env = config2.env;
|
|
10042
|
+
servers[config2.name] = entry;
|
|
10043
|
+
existing.mcpServers = servers;
|
|
10044
|
+
writeFileSync3(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
10045
|
+
log(`[mcp] Wrote ${config2.name} to ${configPath}`);
|
|
10046
|
+
return true;
|
|
10047
|
+
}
|
|
10024
10048
|
async function injectMcps(runner, mcpNames, db3, scope) {
|
|
10025
10049
|
const added = [];
|
|
10026
10050
|
const exe = runner.getExecutablePath();
|
|
10027
10051
|
const runnerId = runner.id;
|
|
10052
|
+
const isCursor = runnerId === "cursor";
|
|
10028
10053
|
const results = await Promise.allSettled(
|
|
10029
10054
|
mcpNames.map(async (name) => {
|
|
10030
10055
|
const def = getMcpServer(db3, name);
|
|
@@ -10032,6 +10057,11 @@ async function injectMcps(runner, mcpNames, db3, scope) {
|
|
|
10032
10057
|
try {
|
|
10033
10058
|
const config2 = defToConfig(def);
|
|
10034
10059
|
if (!config2) return null;
|
|
10060
|
+
if (isCursor) {
|
|
10061
|
+
const wrote = injectMcpToCursorConfig(config2);
|
|
10062
|
+
if (wrote) addPropagation(db3, name, runnerId, scope);
|
|
10063
|
+
return wrote ? name : null;
|
|
10064
|
+
}
|
|
10035
10065
|
const addCmd = runner.getMcpAddCommand(config2);
|
|
10036
10066
|
const args = addCmd.slice(1);
|
|
10037
10067
|
await execFileAsync(exe, args, { encoding: "utf-8" });
|
|
@@ -10077,14 +10107,14 @@ var init_propagate = __esm({
|
|
|
10077
10107
|
});
|
|
10078
10108
|
|
|
10079
10109
|
// src/agents/mcp-config.ts
|
|
10080
|
-
import { mkdirSync as mkdirSync5, writeFileSync as
|
|
10081
|
-
import { join as
|
|
10110
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4, existsSync as existsSync12, readdirSync as readdirSync4, unlinkSync as unlinkSync3 } from "fs";
|
|
10111
|
+
import { join as join13, dirname as dirname2 } from "path";
|
|
10082
10112
|
import { fileURLToPath } from "url";
|
|
10083
10113
|
function generateOrchestratorMcpConfig(opts) {
|
|
10084
10114
|
const port = opts.port ?? process.env.DASHBOARD_PORT ?? "3141";
|
|
10085
|
-
const distPath =
|
|
10086
|
-
const tsxPath =
|
|
10087
|
-
const useTs = !
|
|
10115
|
+
const distPath = join13(__dirname, "agents", "mcp-server.js");
|
|
10116
|
+
const tsxPath = join13(__dirname, "..", "src", "agents", "mcp-server.ts");
|
|
10117
|
+
const useTs = !existsSync12(distPath);
|
|
10088
10118
|
return {
|
|
10089
10119
|
name: opts.agentId === "main" ? "cc-claw" : `cc-claw-${opts.agentId.slice(0, 8)}`,
|
|
10090
10120
|
transport: "stdio",
|
|
@@ -10109,20 +10139,20 @@ function writeMcpConfigFile(config2) {
|
|
|
10109
10139
|
}
|
|
10110
10140
|
};
|
|
10111
10141
|
const safeName = config2.name.replace(/[^a-zA-Z0-9-]/g, "_");
|
|
10112
|
-
const configPath =
|
|
10142
|
+
const configPath = join13(MCP_CONFIG_DIR, `mcp-${safeName}.json`);
|
|
10113
10143
|
const configJson = JSON.stringify(jsonConfig, null, 2);
|
|
10114
10144
|
if (configJson !== lastWrittenConfig.get(configPath)) {
|
|
10115
|
-
if (!
|
|
10145
|
+
if (!existsSync12(MCP_CONFIG_DIR)) {
|
|
10116
10146
|
mkdirSync5(MCP_CONFIG_DIR, { recursive: true, mode: 448 });
|
|
10117
10147
|
}
|
|
10118
|
-
|
|
10148
|
+
writeFileSync4(configPath, configJson, { mode: 384 });
|
|
10119
10149
|
lastWrittenConfig.set(configPath, configJson);
|
|
10120
10150
|
}
|
|
10121
10151
|
return configPath;
|
|
10122
10152
|
}
|
|
10123
10153
|
function deleteMcpConfigFile(mcpName) {
|
|
10124
10154
|
const safeName = mcpName.replace(/[^a-zA-Z0-9-]/g, "_");
|
|
10125
|
-
const configPath =
|
|
10155
|
+
const configPath = join13(MCP_CONFIG_DIR, `mcp-${safeName}.json`);
|
|
10126
10156
|
lastWrittenConfig.delete(configPath);
|
|
10127
10157
|
try {
|
|
10128
10158
|
unlinkSync3(configPath);
|
|
@@ -10131,12 +10161,12 @@ function deleteMcpConfigFile(mcpName) {
|
|
|
10131
10161
|
}
|
|
10132
10162
|
function cleanupOrphanedMcpConfigs() {
|
|
10133
10163
|
try {
|
|
10134
|
-
if (!
|
|
10164
|
+
if (!existsSync12(MCP_CONFIG_DIR)) return;
|
|
10135
10165
|
const files = readdirSync4(MCP_CONFIG_DIR);
|
|
10136
10166
|
for (const file of files) {
|
|
10137
10167
|
if (file.startsWith("mcp-cc-claw-") && file.endsWith(".json")) {
|
|
10138
10168
|
try {
|
|
10139
|
-
unlinkSync3(
|
|
10169
|
+
unlinkSync3(join13(MCP_CONFIG_DIR, file));
|
|
10140
10170
|
} catch {
|
|
10141
10171
|
}
|
|
10142
10172
|
}
|
|
@@ -10151,7 +10181,7 @@ var init_mcp_config = __esm({
|
|
|
10151
10181
|
init_paths();
|
|
10152
10182
|
__filename = fileURLToPath(import.meta.url);
|
|
10153
10183
|
__dirname = dirname2(__filename);
|
|
10154
|
-
MCP_CONFIG_DIR =
|
|
10184
|
+
MCP_CONFIG_DIR = join13(CC_CLAW_HOME, "mcp-configs");
|
|
10155
10185
|
lastWrittenConfig = /* @__PURE__ */ new Map();
|
|
10156
10186
|
}
|
|
10157
10187
|
});
|
|
@@ -10162,8 +10192,8 @@ __export(loader_exports, {
|
|
|
10162
10192
|
getTemplate: () => getTemplate,
|
|
10163
10193
|
listTemplates: () => listTemplates
|
|
10164
10194
|
});
|
|
10165
|
-
import { readdirSync as readdirSync5, readFileSync as
|
|
10166
|
-
import { join as
|
|
10195
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync8 } from "fs";
|
|
10196
|
+
import { join as join14 } from "path";
|
|
10167
10197
|
function parseFrontmatter2(content) {
|
|
10168
10198
|
const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/m);
|
|
10169
10199
|
if (!match || match.index !== 0) return { meta: {}, body: content.trim() };
|
|
@@ -10201,9 +10231,9 @@ function scanTemplates() {
|
|
|
10201
10231
|
return;
|
|
10202
10232
|
}
|
|
10203
10233
|
for (const file of files) {
|
|
10204
|
-
const filePath =
|
|
10234
|
+
const filePath = join14(AGENTS_PATH, file);
|
|
10205
10235
|
try {
|
|
10206
|
-
const raw =
|
|
10236
|
+
const raw = readFileSync8(filePath, "utf-8");
|
|
10207
10237
|
const { meta, body } = parseFrontmatter2(raw);
|
|
10208
10238
|
const name = meta.name ?? file.replace(/\.md$/, "");
|
|
10209
10239
|
const template = {
|
|
@@ -10250,8 +10280,8 @@ var init_loader2 = __esm({
|
|
|
10250
10280
|
});
|
|
10251
10281
|
|
|
10252
10282
|
// src/agents/agent-log.ts
|
|
10253
|
-
import { writeFileSync as
|
|
10254
|
-
import { join as
|
|
10283
|
+
import { writeFileSync as writeFileSync5, readdirSync as readdirSync6, statSync as statSync3, unlinkSync as unlinkSync4, mkdirSync as mkdirSync6 } from "fs";
|
|
10284
|
+
import { join as join15 } from "path";
|
|
10255
10285
|
function truncate(text, maxBytes) {
|
|
10256
10286
|
if (Buffer.byteLength(text, "utf-8") <= maxBytes) return text;
|
|
10257
10287
|
let lo = 0, hi = text.length;
|
|
@@ -10266,7 +10296,7 @@ function truncate(text, maxBytes) {
|
|
|
10266
10296
|
[...truncated ${droppedBytes} bytes...]`;
|
|
10267
10297
|
}
|
|
10268
10298
|
function writeAgentLog(data) {
|
|
10269
|
-
const logPath =
|
|
10299
|
+
const logPath = join15(AGENTS_PATH, `${data.agentId}.log`);
|
|
10270
10300
|
const exitDisplay = data.exitCodeForced ? `${data.exitCode} (forced \u2014 no output from original exit code 0)` : String(data.exitCode ?? "null");
|
|
10271
10301
|
const stderrContent = truncate(data.stderr || "(empty)", MAX_STDERR_BYTES);
|
|
10272
10302
|
const stdoutContent = truncate(data.rawStdoutLines.join("\n") || "(empty)", MAX_STDOUT_BYTES);
|
|
@@ -10291,7 +10321,7 @@ function writeAgentLog(data) {
|
|
|
10291
10321
|
];
|
|
10292
10322
|
try {
|
|
10293
10323
|
mkdirSync6(AGENTS_PATH, { recursive: true });
|
|
10294
|
-
|
|
10324
|
+
writeFileSync5(logPath, lines.join("\n"), "utf-8");
|
|
10295
10325
|
} catch (err) {
|
|
10296
10326
|
log(`[agent-log] Failed to write log for ${data.agentId}: ${err}`);
|
|
10297
10327
|
}
|
|
@@ -10301,7 +10331,7 @@ function pruneAgentLogs() {
|
|
|
10301
10331
|
try {
|
|
10302
10332
|
mkdirSync6(AGENTS_PATH, { recursive: true });
|
|
10303
10333
|
const files = readdirSync6(AGENTS_PATH).filter((f) => f.endsWith(".log")).map((f) => {
|
|
10304
|
-
const fullPath =
|
|
10334
|
+
const fullPath = join15(AGENTS_PATH, f);
|
|
10305
10335
|
const stat4 = statSync3(fullPath);
|
|
10306
10336
|
return { path: fullPath, mtime: stat4.mtimeMs, size: stat4.size };
|
|
10307
10337
|
});
|
|
@@ -10360,7 +10390,7 @@ __export(orchestrator_exports, {
|
|
|
10360
10390
|
shutdownOrchestrator: () => shutdownOrchestrator,
|
|
10361
10391
|
spawnSubAgent: () => spawnSubAgent
|
|
10362
10392
|
});
|
|
10363
|
-
import { existsSync as
|
|
10393
|
+
import { existsSync as existsSync13 } from "fs";
|
|
10364
10394
|
async function withRunnerLock(runnerId, fn) {
|
|
10365
10395
|
const prev = runnerLocks.get(runnerId) ?? Promise.resolve();
|
|
10366
10396
|
const next = prev.then(fn, () => fn());
|
|
@@ -10478,7 +10508,7 @@ async function spawnSubAgent(chatId, opts) {
|
|
|
10478
10508
|
async function startAgent(agentId, chatId, opts) {
|
|
10479
10509
|
const db3 = getDb();
|
|
10480
10510
|
const runner = getRunner(opts.runner);
|
|
10481
|
-
if (opts.cwd && !
|
|
10511
|
+
if (opts.cwd && !existsSync13(opts.cwd)) {
|
|
10482
10512
|
const msg = `Directory not found: ${opts.cwd}`;
|
|
10483
10513
|
error(`[orchestrator] Agent ${agentId}: ${msg}`);
|
|
10484
10514
|
updateAgentStatus(db3, agentId, "failed");
|
|
@@ -10500,7 +10530,7 @@ async function startAgent(agentId, chatId, opts) {
|
|
|
10500
10530
|
return;
|
|
10501
10531
|
}
|
|
10502
10532
|
const exePath = runner.getExecutablePath();
|
|
10503
|
-
if (exePath.startsWith("/") && !
|
|
10533
|
+
if (exePath.startsWith("/") && !existsSync13(exePath)) {
|
|
10504
10534
|
const msg = `Executable not found: ${exePath}`;
|
|
10505
10535
|
error(`[orchestrator] Agent ${agentId}: ${msg}`);
|
|
10506
10536
|
updateAgentStatus(db3, agentId, "failed");
|
|
@@ -10774,10 +10804,10 @@ async function startAgent(agentId, chatId, opts) {
|
|
|
10774
10804
|
function diagnoseSpawnError(err, exePath, cwd) {
|
|
10775
10805
|
const nodeErr = err;
|
|
10776
10806
|
if (nodeErr.code === "ENOENT") {
|
|
10777
|
-
if (cwd && !
|
|
10807
|
+
if (cwd && !existsSync13(cwd)) {
|
|
10778
10808
|
return `Directory not found: ${cwd}`;
|
|
10779
10809
|
}
|
|
10780
|
-
if (exePath.startsWith("/") && !
|
|
10810
|
+
if (exePath.startsWith("/") && !existsSync13(exePath)) {
|
|
10781
10811
|
return `Executable not found: ${exePath}`;
|
|
10782
10812
|
}
|
|
10783
10813
|
return `ENOENT spawning ${exePath} (cwd: ${cwd ?? "inherited"}) \u2014 check that both the binary and directory exist`;
|
|
@@ -11170,7 +11200,7 @@ var init_registry2 = __esm({
|
|
|
11170
11200
|
});
|
|
11171
11201
|
|
|
11172
11202
|
// src/dashboard/routes/orchestrator.ts
|
|
11173
|
-
import { existsSync as
|
|
11203
|
+
import { existsSync as existsSync14 } from "fs";
|
|
11174
11204
|
var handleSpawn, handleCancel, handleCancelAll, handleCreateTask, handleUpdateTask, handleSendMessage, handleReadInbox, handleSetState, handleGetState, handleListState, handleBroadcast, handleListRunners, handleListMcps, handleListTemplates, handleCheckAgent;
|
|
11175
11205
|
var init_orchestrator2 = __esm({
|
|
11176
11206
|
"src/dashboard/routes/orchestrator.ts"() {
|
|
@@ -11186,7 +11216,7 @@ var init_orchestrator2 = __esm({
|
|
|
11186
11216
|
handleSpawn = async (req, res) => {
|
|
11187
11217
|
try {
|
|
11188
11218
|
const body = JSON.parse(await readBody(req));
|
|
11189
|
-
if (body.cwd && !
|
|
11219
|
+
if (body.cwd && !existsSync14(body.cwd)) {
|
|
11190
11220
|
return jsonResponse(res, { error: `Directory not found: ${body.cwd}` }, 400);
|
|
11191
11221
|
}
|
|
11192
11222
|
if (!body.permMode || body.permMode === "inherit") {
|
|
@@ -12444,8 +12474,8 @@ __export(analyze_exports, {
|
|
|
12444
12474
|
});
|
|
12445
12475
|
import { spawn as spawn4 } from "child_process";
|
|
12446
12476
|
import { createInterface as createInterface3 } from "readline";
|
|
12447
|
-
import { readFileSync as
|
|
12448
|
-
import { join as
|
|
12477
|
+
import { readFileSync as readFileSync9, existsSync as existsSync15, readdirSync as readdirSync7, statSync as statSync4 } from "fs";
|
|
12478
|
+
import { join as join16 } from "path";
|
|
12449
12479
|
import { homedir as homedir5 } from "os";
|
|
12450
12480
|
function applySignalDecay(confidence, createdAt) {
|
|
12451
12481
|
const ageMs = Date.now() - (/* @__PURE__ */ new Date(createdAt + (createdAt.endsWith("Z") ? "" : "Z"))).getTime();
|
|
@@ -12454,19 +12484,19 @@ function applySignalDecay(confidence, createdAt) {
|
|
|
12454
12484
|
return decayed >= SIGNAL_DECAY_MIN_CONFIDENCE ? Math.round(decayed * 100) / 100 : 0;
|
|
12455
12485
|
}
|
|
12456
12486
|
function discoverReflectionTargets() {
|
|
12457
|
-
const ccClawHome =
|
|
12487
|
+
const ccClawHome = join16(homedir5(), ".cc-claw");
|
|
12458
12488
|
const targets = [];
|
|
12459
12489
|
try {
|
|
12460
|
-
const skillsDir =
|
|
12461
|
-
if (
|
|
12490
|
+
const skillsDir = join16(ccClawHome, "workspace", "skills");
|
|
12491
|
+
if (existsSync15(skillsDir)) {
|
|
12462
12492
|
for (const entry of readdirSync7(skillsDir)) {
|
|
12463
|
-
const entryPath =
|
|
12493
|
+
const entryPath = join16(skillsDir, entry);
|
|
12464
12494
|
if (!statSync4(entryPath).isDirectory()) continue;
|
|
12465
|
-
const skillFile =
|
|
12466
|
-
if (!
|
|
12495
|
+
const skillFile = join16(entryPath, "SKILL.md");
|
|
12496
|
+
if (!existsSync15(skillFile)) continue;
|
|
12467
12497
|
let desc = "skill";
|
|
12468
12498
|
try {
|
|
12469
|
-
const content =
|
|
12499
|
+
const content = readFileSync9(skillFile, "utf-8");
|
|
12470
12500
|
const descMatch = content.match(/description:\s*["']?([^"'\n]+)/);
|
|
12471
12501
|
if (descMatch) desc = descMatch[1].trim().slice(0, 80);
|
|
12472
12502
|
} catch {
|
|
@@ -12477,8 +12507,8 @@ function discoverReflectionTargets() {
|
|
|
12477
12507
|
} catch {
|
|
12478
12508
|
}
|
|
12479
12509
|
try {
|
|
12480
|
-
const contextDir =
|
|
12481
|
-
if (
|
|
12510
|
+
const contextDir = join16(ccClawHome, "workspace", "context");
|
|
12511
|
+
if (existsSync15(contextDir)) {
|
|
12482
12512
|
for (const entry of readdirSync7(contextDir)) {
|
|
12483
12513
|
if (!entry.endsWith(".md")) continue;
|
|
12484
12514
|
const name = entry.replace(/\.md$/, "");
|
|
@@ -12675,7 +12705,7 @@ function resolveReflectionAdapter(chatId) {
|
|
|
12675
12705
|
}
|
|
12676
12706
|
function readIdentityFile(filename) {
|
|
12677
12707
|
try {
|
|
12678
|
-
return
|
|
12708
|
+
return readFileSync9(join16(IDENTITY_PATH, filename), "utf-8");
|
|
12679
12709
|
} catch {
|
|
12680
12710
|
return "";
|
|
12681
12711
|
}
|
|
@@ -12819,7 +12849,7 @@ async function runAnalysisImpl(chatId, opts) {
|
|
|
12819
12849
|
const availableTargets = discoverReflectionTargets();
|
|
12820
12850
|
const SKILL_CONTENT_CAP = 15e3;
|
|
12821
12851
|
const skillContents = [];
|
|
12822
|
-
const ccClawHome =
|
|
12852
|
+
const ccClawHome = join16(homedir5(), ".cc-claw");
|
|
12823
12853
|
const signalCorpus = signals.map((s) => s.trigger).join(" ").toLowerCase();
|
|
12824
12854
|
const convCorpus = (conversations ?? "").toLowerCase();
|
|
12825
12855
|
const searchCorpus = signalCorpus + " " + convCorpus;
|
|
@@ -12832,9 +12862,9 @@ async function runAnalysisImpl(chatId, opts) {
|
|
|
12832
12862
|
const isRelevant = searchCorpus.includes(skillNameNorm) || searchCorpus.includes(skillName.toLowerCase()) || descNorm.split(/\s+/).some((word) => word.length > 4 && searchCorpus.includes(word));
|
|
12833
12863
|
if (!isRelevant) continue;
|
|
12834
12864
|
try {
|
|
12835
|
-
const fullPath =
|
|
12836
|
-
if (
|
|
12837
|
-
const content =
|
|
12865
|
+
const fullPath = join16(ccClawHome, target.path);
|
|
12866
|
+
if (existsSync15(fullPath)) {
|
|
12867
|
+
const content = readFileSync9(fullPath, "utf-8");
|
|
12838
12868
|
if (totalSkillChars + content.length > SKILL_CONTENT_CAP) break;
|
|
12839
12869
|
skillContents.push({ path: target.path, content });
|
|
12840
12870
|
totalSkillChars += content.length;
|
|
@@ -13214,8 +13244,8 @@ __export(apply_exports, {
|
|
|
13214
13244
|
isTargetAllowed: () => isTargetAllowed,
|
|
13215
13245
|
rollbackInsight: () => rollbackInsight
|
|
13216
13246
|
});
|
|
13217
|
-
import { readFileSync as
|
|
13218
|
-
import { join as
|
|
13247
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync8, unlinkSync as unlinkSync5 } from "fs";
|
|
13248
|
+
import { join as join17, dirname as dirname3 } from "path";
|
|
13219
13249
|
function isTargetAllowed(relativePath) {
|
|
13220
13250
|
if (relativePath.includes("..")) return false;
|
|
13221
13251
|
if (!relativePath.endsWith(".md")) return false;
|
|
@@ -13269,7 +13299,7 @@ function pruneBackups(absolutePath) {
|
|
|
13269
13299
|
const dir = dirname3(absolutePath);
|
|
13270
13300
|
const baseName = absolutePath.split("/").pop() ?? "";
|
|
13271
13301
|
try {
|
|
13272
|
-
const backups = readdirSync8(dir).filter((f) => f.startsWith(baseName + ".bak.")).sort().map((f) =>
|
|
13302
|
+
const backups = readdirSync8(dir).filter((f) => f.startsWith(baseName + ".bak.")).sort().map((f) => join17(dir, f));
|
|
13273
13303
|
while (backups.length > MAX_BACKUPS_PER_FILE) {
|
|
13274
13304
|
const oldest = backups.shift();
|
|
13275
13305
|
try {
|
|
@@ -13295,10 +13325,10 @@ async function applyInsight(insightId) {
|
|
|
13295
13325
|
if (!isTargetAllowed(insight.targetFile)) {
|
|
13296
13326
|
return { success: false, message: `Target file "${insight.targetFile}" is not in the allowed list` };
|
|
13297
13327
|
}
|
|
13298
|
-
const absolutePath =
|
|
13328
|
+
const absolutePath = join17(CC_CLAW_HOME, insight.targetFile);
|
|
13299
13329
|
if (insight.proposedAction === "append" && insight.targetFile === "identity/SOUL.md") {
|
|
13300
|
-
if (
|
|
13301
|
-
const currentContent =
|
|
13330
|
+
if (existsSync16(absolutePath)) {
|
|
13331
|
+
const currentContent = readFileSync10(absolutePath, "utf-8");
|
|
13302
13332
|
const lineCount = currentContent.split("\n").length;
|
|
13303
13333
|
if (lineCount >= SOUL_LINE_CAP) {
|
|
13304
13334
|
return {
|
|
@@ -13319,8 +13349,8 @@ async function applyInsight(insightId) {
|
|
|
13319
13349
|
};
|
|
13320
13350
|
}
|
|
13321
13351
|
let original = "";
|
|
13322
|
-
if (
|
|
13323
|
-
original =
|
|
13352
|
+
if (existsSync16(absolutePath)) {
|
|
13353
|
+
original = readFileSync10(absolutePath, "utf-8");
|
|
13324
13354
|
} else if (insight.proposedAction !== "create") {
|
|
13325
13355
|
return { success: false, message: `Target file "${insight.targetFile}" does not exist` };
|
|
13326
13356
|
}
|
|
@@ -13328,11 +13358,11 @@ async function applyInsight(insightId) {
|
|
|
13328
13358
|
const backupPath = absolutePath + `.bak.${timestamp}`;
|
|
13329
13359
|
try {
|
|
13330
13360
|
const parentDir = dirname3(absolutePath);
|
|
13331
|
-
if (!
|
|
13361
|
+
if (!existsSync16(parentDir)) {
|
|
13332
13362
|
mkdirSync7(parentDir, { recursive: true });
|
|
13333
13363
|
}
|
|
13334
13364
|
if (original) {
|
|
13335
|
-
|
|
13365
|
+
writeFileSync6(backupPath, original, "utf-8");
|
|
13336
13366
|
pruneBackups(absolutePath);
|
|
13337
13367
|
}
|
|
13338
13368
|
let newContent;
|
|
@@ -13360,7 +13390,7 @@ async function applyInsight(insightId) {
|
|
|
13360
13390
|
} else {
|
|
13361
13391
|
newContent = applyDiff(original, insight.proposedDiff, insight.proposedAction);
|
|
13362
13392
|
}
|
|
13363
|
-
|
|
13393
|
+
writeFileSync6(absolutePath, newContent, "utf-8");
|
|
13364
13394
|
const rollbackData = JSON.stringify({ original, backupPath, appliedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
13365
13395
|
updateInsightRollback(db3, insightId, rollbackData);
|
|
13366
13396
|
updateInsightStatus(db3, insightId, "applied");
|
|
@@ -13388,7 +13418,7 @@ async function applyInsight(insightId) {
|
|
|
13388
13418
|
warn(`[reflection/apply] Failed to apply insight #${insightId}: ${msg}`);
|
|
13389
13419
|
try {
|
|
13390
13420
|
if (original) {
|
|
13391
|
-
|
|
13421
|
+
writeFileSync6(absolutePath, original, "utf-8");
|
|
13392
13422
|
}
|
|
13393
13423
|
} catch {
|
|
13394
13424
|
}
|
|
@@ -13416,9 +13446,9 @@ async function rollbackInsight(insightId) {
|
|
|
13416
13446
|
} catch {
|
|
13417
13447
|
return { success: false, message: `Insight #${insightId} has malformed rollback data` };
|
|
13418
13448
|
}
|
|
13419
|
-
const absolutePath =
|
|
13449
|
+
const absolutePath = join17(CC_CLAW_HOME, insight.targetFile);
|
|
13420
13450
|
try {
|
|
13421
|
-
|
|
13451
|
+
writeFileSync6(absolutePath, rollback.original, "utf-8");
|
|
13422
13452
|
updateInsightStatus(db3, insightId, "rolled_back");
|
|
13423
13453
|
syncNativeCliFiles();
|
|
13424
13454
|
const chatId = insight.chatId ?? "global";
|
|
@@ -13449,8 +13479,8 @@ function calculateDrift(chatId) {
|
|
|
13449
13479
|
if (!row || !row.baselineSoulMd && !row.baselineUserMd) {
|
|
13450
13480
|
return null;
|
|
13451
13481
|
}
|
|
13452
|
-
const soulPath =
|
|
13453
|
-
const userPath =
|
|
13482
|
+
const soulPath = join17(CC_CLAW_HOME, "identity/SOUL.md");
|
|
13483
|
+
const userPath = join17(CC_CLAW_HOME, "identity/USER.md");
|
|
13454
13484
|
const soulDrift = computeLineDrift(row.baselineSoulMd, soulPath);
|
|
13455
13485
|
const userDrift = computeLineDrift(row.baselineUserMd, userPath);
|
|
13456
13486
|
return { soulDrift, userDrift };
|
|
@@ -13459,8 +13489,8 @@ function computeLineDrift(baseline, absolutePath) {
|
|
|
13459
13489
|
if (!baseline) return 0;
|
|
13460
13490
|
let current = "";
|
|
13461
13491
|
try {
|
|
13462
|
-
if (
|
|
13463
|
-
current =
|
|
13492
|
+
if (existsSync16(absolutePath)) {
|
|
13493
|
+
current = readFileSync10(absolutePath, "utf-8");
|
|
13464
13494
|
}
|
|
13465
13495
|
} catch {
|
|
13466
13496
|
return 1;
|
|
@@ -13559,12 +13589,12 @@ var init_evolve = __esm({
|
|
|
13559
13589
|
const body = JSON.parse(await readBody(req));
|
|
13560
13590
|
const { setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
13561
13591
|
const { existsSync: fileExists, readFileSync: fileRead } = await import("fs");
|
|
13562
|
-
const { join:
|
|
13592
|
+
const { join: join41 } = await import("path");
|
|
13563
13593
|
const { CC_CLAW_HOME: home } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
13564
13594
|
const chatId = resolveChatId(body);
|
|
13565
13595
|
if (!chatId) return jsonResponse(res, { error: "No chatId provided and ALLOWED_CHAT_ID is not set" }, 400);
|
|
13566
|
-
const soulPath =
|
|
13567
|
-
const userPath =
|
|
13596
|
+
const soulPath = join41(home, "identity/SOUL.md");
|
|
13597
|
+
const userPath = join41(home, "identity/USER.md");
|
|
13568
13598
|
const soul = fileExists(soulPath) ? fileRead(soulPath, "utf-8") : "";
|
|
13569
13599
|
const user = fileExists(userPath) ? fileRead(userPath, "utf-8") : "";
|
|
13570
13600
|
setReflectionStatus2(getDb(), chatId, "active", soul, user);
|
|
@@ -13617,9 +13647,9 @@ var init_evolve = __esm({
|
|
|
13617
13647
|
});
|
|
13618
13648
|
|
|
13619
13649
|
// src/dashboard/routes/files.ts
|
|
13620
|
-
import { createWriteStream, existsSync as
|
|
13650
|
+
import { createWriteStream, existsSync as existsSync17 } from "fs";
|
|
13621
13651
|
import { readdir as readdir2, stat, unlink, mkdir } from "fs/promises";
|
|
13622
|
-
import { join as
|
|
13652
|
+
import { join as join18, extname } from "path";
|
|
13623
13653
|
function getUploadHtml(token, host) {
|
|
13624
13654
|
return `<!DOCTYPE html>
|
|
13625
13655
|
<html lang="en">
|
|
@@ -13800,7 +13830,7 @@ async function handleFileList(req, res) {
|
|
|
13800
13830
|
const files = [];
|
|
13801
13831
|
for (const name of entries) {
|
|
13802
13832
|
try {
|
|
13803
|
-
const s = await stat(
|
|
13833
|
+
const s = await stat(join18(INCOMING_PATH, name));
|
|
13804
13834
|
if (!s.isFile()) continue;
|
|
13805
13835
|
files.push({
|
|
13806
13836
|
name,
|
|
@@ -13824,8 +13854,8 @@ async function handleFileServe(req, res, url) {
|
|
|
13824
13854
|
res.end("Invalid filename");
|
|
13825
13855
|
return;
|
|
13826
13856
|
}
|
|
13827
|
-
const filePath =
|
|
13828
|
-
if (!
|
|
13857
|
+
const filePath = join18(INCOMING_PATH, filename);
|
|
13858
|
+
if (!existsSync17(filePath)) {
|
|
13829
13859
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
13830
13860
|
res.end("File not found");
|
|
13831
13861
|
return;
|
|
@@ -13900,7 +13930,7 @@ function parseMultipartUpload(req, boundary) {
|
|
|
13900
13930
|
const originalName = nameMatch[1].replace(/[^\w.-]/g, "_");
|
|
13901
13931
|
const ext = extname(originalName) || ".bin";
|
|
13902
13932
|
const filename = `upload-${Date.now()}${ext}`;
|
|
13903
|
-
const filePath =
|
|
13933
|
+
const filePath = join18(INCOMING_PATH, filename);
|
|
13904
13934
|
cleanupPath = filePath;
|
|
13905
13935
|
const fileStart = headerEnd + 4;
|
|
13906
13936
|
const closingBoundary = Buffer.from(`\r
|
|
@@ -13936,7 +13966,7 @@ var init_files = __esm({
|
|
|
13936
13966
|
init_paths();
|
|
13937
13967
|
init_middleware();
|
|
13938
13968
|
init_log();
|
|
13939
|
-
INCOMING_PATH =
|
|
13969
|
+
INCOMING_PATH = join18(MEDIA_PATH, "incoming");
|
|
13940
13970
|
MAX_UPLOAD_BYTES = 200 * 1024 * 1024;
|
|
13941
13971
|
BLOCKED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
13942
13972
|
".exe",
|
|
@@ -16017,11 +16047,11 @@ var init_telegram_throttle = __esm({
|
|
|
16017
16047
|
});
|
|
16018
16048
|
|
|
16019
16049
|
// src/health/checks.ts
|
|
16020
|
-
import { existsSync as
|
|
16050
|
+
import { existsSync as existsSync18, statSync as statSync5, readFileSync as readFileSync11 } from "fs";
|
|
16021
16051
|
import { execFileSync, execSync as execSync3 } from "child_process";
|
|
16022
16052
|
function getRecentErrors() {
|
|
16023
|
-
if (!
|
|
16024
|
-
const logContent =
|
|
16053
|
+
if (!existsSync18(ERROR_LOG_PATH)) return null;
|
|
16054
|
+
const logContent = readFileSync11(ERROR_LOG_PATH, "utf-8");
|
|
16025
16055
|
const allLines = logContent.split("\n").filter(Boolean).slice(-500);
|
|
16026
16056
|
const last24h = Date.now() - 864e5;
|
|
16027
16057
|
const lines = allLines.filter((line) => {
|
|
@@ -16042,7 +16072,7 @@ function getRecentErrors() {
|
|
|
16042
16072
|
}
|
|
16043
16073
|
function checkDatabase() {
|
|
16044
16074
|
const checks = [];
|
|
16045
|
-
if (
|
|
16075
|
+
if (existsSync18(DB_PATH)) {
|
|
16046
16076
|
const size = statSync5(DB_PATH).size;
|
|
16047
16077
|
checks.push({ name: "Database", status: "ok", message: `${(size / 1024).toFixed(0)}KB` });
|
|
16048
16078
|
} else {
|
|
@@ -16250,8 +16280,8 @@ __export(heartbeat_exports, {
|
|
|
16250
16280
|
stopHeartbeatForChat: () => stopHeartbeatForChat,
|
|
16251
16281
|
updateHeartbeatConfig: () => updateHeartbeatConfig
|
|
16252
16282
|
});
|
|
16253
|
-
import { readFileSync as
|
|
16254
|
-
import { join as
|
|
16283
|
+
import { readFileSync as readFileSync12, existsSync as existsSync19 } from "fs";
|
|
16284
|
+
import { join as join19 } from "path";
|
|
16255
16285
|
function findHeartbeatJob() {
|
|
16256
16286
|
try {
|
|
16257
16287
|
const { getDb: getDb2 } = (init_store5(), __toCommonJS(store_exports5));
|
|
@@ -16382,9 +16412,9 @@ ${healthText}`);
|
|
|
16382
16412
|
sections.push(`[Active Watches \u2014 execute these checks using your tools]
|
|
16383
16413
|
${watchLines.join("\n")}`);
|
|
16384
16414
|
}
|
|
16385
|
-
if (
|
|
16415
|
+
if (existsSync19(HEARTBEAT_MD_PATH)) {
|
|
16386
16416
|
try {
|
|
16387
|
-
const custom =
|
|
16417
|
+
const custom = readFileSync12(HEARTBEAT_MD_PATH, "utf-8").trim();
|
|
16388
16418
|
if (custom) {
|
|
16389
16419
|
sections.push(`[Custom checks from HEARTBEAT.md]
|
|
16390
16420
|
${custom}`);
|
|
@@ -16444,7 +16474,7 @@ var init_heartbeat2 = __esm({
|
|
|
16444
16474
|
init_store5();
|
|
16445
16475
|
init_checks();
|
|
16446
16476
|
init_log();
|
|
16447
|
-
HEARTBEAT_MD_PATH =
|
|
16477
|
+
HEARTBEAT_MD_PATH = join19(WORKSPACE_PATH, "HEARTBEAT.md");
|
|
16448
16478
|
HEARTBEAT_OK = "HEARTBEAT_OK";
|
|
16449
16479
|
HEARTBEAT_JOB_TYPE = "heartbeat";
|
|
16450
16480
|
DEFAULT_INTERVAL_MS = 30 * 60 * 1e3;
|
|
@@ -16453,8 +16483,8 @@ var init_heartbeat2 = __esm({
|
|
|
16453
16483
|
});
|
|
16454
16484
|
|
|
16455
16485
|
// src/bootstrap/profile.ts
|
|
16456
|
-
import { readFileSync as
|
|
16457
|
-
import { join as
|
|
16486
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, existsSync as existsSync20 } from "fs";
|
|
16487
|
+
import { join as join20 } from "path";
|
|
16458
16488
|
function hasActiveProfile(chatId) {
|
|
16459
16489
|
return activeProfiles.has(chatId);
|
|
16460
16490
|
}
|
|
@@ -16557,7 +16587,7 @@ async function finalizeProfile(chatId, state, channel) {
|
|
|
16557
16587
|
"<!-- Add any additional preferences below this line -->",
|
|
16558
16588
|
""
|
|
16559
16589
|
].join("\n");
|
|
16560
|
-
|
|
16590
|
+
writeFileSync7(USER_PATH2, content, "utf-8");
|
|
16561
16591
|
activeProfiles.delete(chatId);
|
|
16562
16592
|
log(`[profile] User profile saved for chat ${chatId}`);
|
|
16563
16593
|
await channel.sendText(
|
|
@@ -16583,14 +16613,14 @@ function extractUserUpdates(text) {
|
|
|
16583
16613
|
return { cleanText, updates };
|
|
16584
16614
|
}
|
|
16585
16615
|
function appendToUserProfile(key, value) {
|
|
16586
|
-
if (!
|
|
16587
|
-
const content =
|
|
16616
|
+
if (!existsSync20(USER_PATH2)) return;
|
|
16617
|
+
const content = readFileSync13(USER_PATH2, "utf-8");
|
|
16588
16618
|
const line = `- **${key}**: ${value}`;
|
|
16589
16619
|
if (content.includes(line)) return;
|
|
16590
16620
|
const updated = content.trimEnd() + `
|
|
16591
16621
|
${line}
|
|
16592
16622
|
`;
|
|
16593
|
-
|
|
16623
|
+
writeFileSync7(USER_PATH2, updated, "utf-8");
|
|
16594
16624
|
log(`[profile] Appended preference: ${key}=${value}`);
|
|
16595
16625
|
}
|
|
16596
16626
|
var USER_PATH2, activeProfiles;
|
|
@@ -16599,7 +16629,7 @@ var init_profile = __esm({
|
|
|
16599
16629
|
"use strict";
|
|
16600
16630
|
init_paths();
|
|
16601
16631
|
init_log();
|
|
16602
|
-
USER_PATH2 =
|
|
16632
|
+
USER_PATH2 = join20(IDENTITY_PATH, "USER.md");
|
|
16603
16633
|
activeProfiles = /* @__PURE__ */ new Map();
|
|
16604
16634
|
}
|
|
16605
16635
|
});
|
|
@@ -18090,8 +18120,8 @@ __export(session_log_exports2, {
|
|
|
18090
18120
|
startSessionLogCleanupTimer: () => startSessionLogCleanupTimer,
|
|
18091
18121
|
tailSessionLog: () => tailSessionLog
|
|
18092
18122
|
});
|
|
18093
|
-
import { existsSync as
|
|
18094
|
-
import { join as
|
|
18123
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync8, appendFileSync, readdirSync as readdirSync9, unlinkSync as unlinkSync6, statSync as statSync6, createReadStream } from "fs";
|
|
18124
|
+
import { join as join21, basename } from "path";
|
|
18095
18125
|
import { createInterface as createInterface6 } from "readline";
|
|
18096
18126
|
function getRetentionDays() {
|
|
18097
18127
|
const env = process.env.SESSION_LOG_RETENTION_DAYS;
|
|
@@ -18103,13 +18133,13 @@ function getRetentionDays() {
|
|
|
18103
18133
|
}
|
|
18104
18134
|
function cleanupSessionLogs(retentionDays) {
|
|
18105
18135
|
const days = retentionDays ?? getRetentionDays();
|
|
18106
|
-
if (!
|
|
18136
|
+
if (!existsSync21(SESSION_LOGS_PATH)) return 0;
|
|
18107
18137
|
const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
|
|
18108
18138
|
let cleaned = 0;
|
|
18109
18139
|
try {
|
|
18110
18140
|
for (const file of readdirSync9(SESSION_LOGS_PATH)) {
|
|
18111
18141
|
if (!file.startsWith("session-") || !file.endsWith(".log")) continue;
|
|
18112
|
-
const filePath =
|
|
18142
|
+
const filePath = join21(SESSION_LOGS_PATH, file);
|
|
18113
18143
|
try {
|
|
18114
18144
|
const { mtimeMs } = statSync6(filePath);
|
|
18115
18145
|
if (mtimeMs < cutoff) {
|
|
@@ -18135,11 +18165,11 @@ function startSessionLogCleanupTimer() {
|
|
|
18135
18165
|
return timer;
|
|
18136
18166
|
}
|
|
18137
18167
|
function listSessionLogs() {
|
|
18138
|
-
if (!
|
|
18168
|
+
if (!existsSync21(SESSION_LOGS_PATH)) return [];
|
|
18139
18169
|
const logs = [];
|
|
18140
18170
|
for (const file of readdirSync9(SESSION_LOGS_PATH)) {
|
|
18141
18171
|
if (!file.startsWith("session-") || !file.endsWith(".log")) continue;
|
|
18142
|
-
const filePath =
|
|
18172
|
+
const filePath = join21(SESSION_LOGS_PATH, file);
|
|
18143
18173
|
try {
|
|
18144
18174
|
const stat4 = statSync6(filePath);
|
|
18145
18175
|
const match = file.match(/^session-(.+?)-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})\.log$/);
|
|
@@ -18158,7 +18188,7 @@ function listSessionLogs() {
|
|
|
18158
18188
|
return logs;
|
|
18159
18189
|
}
|
|
18160
18190
|
async function* tailSessionLog(filePath, lines = 50) {
|
|
18161
|
-
if (!
|
|
18191
|
+
if (!existsSync21(filePath)) {
|
|
18162
18192
|
yield `File not found: ${filePath}`;
|
|
18163
18193
|
return;
|
|
18164
18194
|
}
|
|
@@ -18186,12 +18216,12 @@ var init_session_log2 = __esm({
|
|
|
18186
18216
|
constructor(chatId, backend2, model2) {
|
|
18187
18217
|
this.backend = backend2;
|
|
18188
18218
|
this.model = model2;
|
|
18189
|
-
if (!
|
|
18219
|
+
if (!existsSync21(SESSION_LOGS_PATH)) {
|
|
18190
18220
|
mkdirSync8(SESSION_LOGS_PATH, { recursive: true });
|
|
18191
18221
|
}
|
|
18192
18222
|
const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18193
18223
|
const sanitizedChatId = chatId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
18194
|
-
this.filePath =
|
|
18224
|
+
this.filePath = join21(SESSION_LOGS_PATH, `session-${sanitizedChatId}-${ts2}.log`);
|
|
18195
18225
|
const header2 = [
|
|
18196
18226
|
"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
|
|
18197
18227
|
`CC-Claw Agent Session \u2014 ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
@@ -18598,8 +18628,8 @@ var init_gate = __esm({
|
|
|
18598
18628
|
import crypto from "crypto";
|
|
18599
18629
|
import { execFile as execFile2, execFileSync as execFileSync2 } from "child_process";
|
|
18600
18630
|
import { readFile as readFile3, unlink as unlink2, mkdir as mkdir2, writeFile } from "fs/promises";
|
|
18601
|
-
import { existsSync as
|
|
18602
|
-
import { join as
|
|
18631
|
+
import { existsSync as existsSync22 } from "fs";
|
|
18632
|
+
import { join as join22 } from "path";
|
|
18603
18633
|
import { promisify as promisify2 } from "util";
|
|
18604
18634
|
function ensureFfmpeg() {
|
|
18605
18635
|
if (ffmpegAvailable === true) return;
|
|
@@ -18698,10 +18728,10 @@ function getWhisperBin() {
|
|
|
18698
18728
|
return null;
|
|
18699
18729
|
}
|
|
18700
18730
|
function whisperModelPath(model2) {
|
|
18701
|
-
return
|
|
18731
|
+
return join22(WHISPER_MODELS_PATH, `ggml-${model2}.bin`);
|
|
18702
18732
|
}
|
|
18703
18733
|
function isWhisperModelDownloaded(model2) {
|
|
18704
|
-
return
|
|
18734
|
+
return existsSync22(whisperModelPath(model2));
|
|
18705
18735
|
}
|
|
18706
18736
|
async function downloadWhisperModel(model2, onProgress) {
|
|
18707
18737
|
await mkdir2(WHISPER_MODELS_PATH, { recursive: true });
|
|
@@ -18733,7 +18763,7 @@ async function transcribeWithLocalWhisper(audioBuffer, model2, onProgress) {
|
|
|
18733
18763
|
const result = await execFileAsync2(bin, ["-m", modelFile, "-f", tmpWav, "-nt", "--output-txt", "-of", `/tmp/cc-claw-stt-${id}`]);
|
|
18734
18764
|
const txtFile = `/tmp/cc-claw-stt-${id}.txt`;
|
|
18735
18765
|
let transcript = "";
|
|
18736
|
-
if (
|
|
18766
|
+
if (existsSync22(txtFile)) {
|
|
18737
18767
|
transcript = (await readFile3(txtFile, "utf-8")).trim();
|
|
18738
18768
|
unlink2(txtFile).catch(() => {
|
|
18739
18769
|
});
|
|
@@ -18924,9 +18954,9 @@ var init_stt = __esm({
|
|
|
18924
18954
|
});
|
|
18925
18955
|
|
|
18926
18956
|
// src/media/image-gen.ts
|
|
18927
|
-
import { mkdirSync as mkdirSync9, existsSync as
|
|
18957
|
+
import { mkdirSync as mkdirSync9, existsSync as existsSync23, unlink as unlink3, readdir as readdir3, stat as stat2 } from "fs";
|
|
18928
18958
|
import { writeFile as writeFile2 } from "fs/promises";
|
|
18929
|
-
import { join as
|
|
18959
|
+
import { join as join23 } from "path";
|
|
18930
18960
|
async function generateImage(prompt) {
|
|
18931
18961
|
const apiKey = process.env.GEMINI_API_KEY;
|
|
18932
18962
|
if (!apiKey) {
|
|
@@ -18973,12 +19003,12 @@ async function generateImage(prompt) {
|
|
|
18973
19003
|
if (!imageData) {
|
|
18974
19004
|
throw new Error(textResponse ?? "Gemini did not generate an image. The prompt may have been filtered.");
|
|
18975
19005
|
}
|
|
18976
|
-
if (!
|
|
19006
|
+
if (!existsSync23(IMAGE_OUTPUT_DIR)) {
|
|
18977
19007
|
mkdirSync9(IMAGE_OUTPUT_DIR, { recursive: true });
|
|
18978
19008
|
}
|
|
18979
19009
|
const ext = mimeType.includes("jpeg") || mimeType.includes("jpg") ? "jpg" : "png";
|
|
18980
19010
|
const filename = `img_${Date.now()}.${ext}`;
|
|
18981
|
-
const filePath =
|
|
19011
|
+
const filePath = join23(IMAGE_OUTPUT_DIR, filename);
|
|
18982
19012
|
const buffer = Buffer.from(imageData, "base64");
|
|
18983
19013
|
await writeFile2(filePath, buffer);
|
|
18984
19014
|
log(`[image-gen] Saved ${buffer.length} bytes to ${filePath}`);
|
|
@@ -18996,7 +19026,7 @@ function cleanupGeneratedImage(filePath) {
|
|
|
18996
19026
|
function pruneImageCache() {
|
|
18997
19027
|
readdir3(IMAGE_OUTPUT_DIR, (err, files) => {
|
|
18998
19028
|
if (err || !files) return;
|
|
18999
|
-
const imageFiles = files.filter((f) => /\.(png|jpg)$/.test(f)).map((f) =>
|
|
19029
|
+
const imageFiles = files.filter((f) => /\.(png|jpg)$/.test(f)).map((f) => join23(IMAGE_OUTPUT_DIR, f));
|
|
19000
19030
|
if (imageFiles.length === 0) return;
|
|
19001
19031
|
const now = Date.now();
|
|
19002
19032
|
let statsPending = imageFiles.length;
|
|
@@ -19028,8 +19058,8 @@ var init_image_gen = __esm({
|
|
|
19028
19058
|
MAX_GENERATED_IMAGES = 20;
|
|
19029
19059
|
IMAGE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
19030
19060
|
IMAGE_MODEL = "gemini-3.1-flash-image-preview";
|
|
19031
|
-
IMAGE_OUTPUT_DIR =
|
|
19032
|
-
process.env.CC_CLAW_HOME ??
|
|
19061
|
+
IMAGE_OUTPUT_DIR = join23(
|
|
19062
|
+
process.env.CC_CLAW_HOME ?? join23(process.env.HOME ?? "/tmp", ".cc-claw"),
|
|
19033
19063
|
"data",
|
|
19034
19064
|
"images"
|
|
19035
19065
|
);
|
|
@@ -19467,7 +19497,7 @@ var init_video = __esm({
|
|
|
19467
19497
|
});
|
|
19468
19498
|
|
|
19469
19499
|
// src/router/media.ts
|
|
19470
|
-
import { join as
|
|
19500
|
+
import { join as join24 } from "path";
|
|
19471
19501
|
import { mkdir as mkdir3, writeFile as writeFile3, readdir as readdir4, stat as stat3, unlink as unlink4 } from "fs/promises";
|
|
19472
19502
|
function getMediaRetentionMs() {
|
|
19473
19503
|
const hours = parseInt(process.env.MEDIA_RETENTION_HOURS ?? "24", 10);
|
|
@@ -19476,7 +19506,7 @@ function getMediaRetentionMs() {
|
|
|
19476
19506
|
async function saveMedia(buffer, prefix, ext) {
|
|
19477
19507
|
await mkdir3(MEDIA_INCOMING_PATH, { recursive: true });
|
|
19478
19508
|
const filename = `${prefix}-${Date.now()}.${ext}`;
|
|
19479
|
-
const fullPath =
|
|
19509
|
+
const fullPath = join24(MEDIA_INCOMING_PATH, filename);
|
|
19480
19510
|
await writeFile3(fullPath, buffer);
|
|
19481
19511
|
return fullPath;
|
|
19482
19512
|
}
|
|
@@ -19490,7 +19520,7 @@ async function cleanupOldMedia() {
|
|
|
19490
19520
|
let removed = 0;
|
|
19491
19521
|
for (const file of files) {
|
|
19492
19522
|
try {
|
|
19493
|
-
const filePath =
|
|
19523
|
+
const filePath = join24(MEDIA_INCOMING_PATH, file);
|
|
19494
19524
|
const s = await stat3(filePath);
|
|
19495
19525
|
if (now - s.mtimeMs > retentionMs) {
|
|
19496
19526
|
await unlink4(filePath);
|
|
@@ -19766,7 +19796,7 @@ var init_media = __esm({
|
|
|
19766
19796
|
init_helpers();
|
|
19767
19797
|
init_response();
|
|
19768
19798
|
init_live_status();
|
|
19769
|
-
MEDIA_INCOMING_PATH =
|
|
19799
|
+
MEDIA_INCOMING_PATH = join24(MEDIA_PATH, "incoming");
|
|
19770
19800
|
}
|
|
19771
19801
|
});
|
|
19772
19802
|
|
|
@@ -20080,8 +20110,8 @@ __export(install_exports, {
|
|
|
20080
20110
|
installSkillFromGitHub: () => installSkillFromGitHub
|
|
20081
20111
|
});
|
|
20082
20112
|
import { mkdir as mkdir4, readdir as readdir5, readFile as readFile5, cp } from "fs/promises";
|
|
20083
|
-
import { existsSync as
|
|
20084
|
-
import { join as
|
|
20113
|
+
import { existsSync as existsSync24 } from "fs";
|
|
20114
|
+
import { join as join25, basename as basename2 } from "path";
|
|
20085
20115
|
import { execSync as execSync4 } from "child_process";
|
|
20086
20116
|
async function installSkillFromGitHub(urlOrShorthand) {
|
|
20087
20117
|
let repoUrl;
|
|
@@ -20092,36 +20122,36 @@ async function installSkillFromGitHub(urlOrShorthand) {
|
|
|
20092
20122
|
}
|
|
20093
20123
|
repoUrl = parsed.cloneUrl;
|
|
20094
20124
|
subPath = parsed.subPath;
|
|
20095
|
-
const tmpDir =
|
|
20125
|
+
const tmpDir = join25("/tmp", `cc-claw-skill-${Date.now()}`);
|
|
20096
20126
|
try {
|
|
20097
20127
|
log(`[skill-install] Cloning ${repoUrl} to ${tmpDir}`);
|
|
20098
20128
|
execSync4(`git clone --depth 1 ${repoUrl} ${tmpDir}`, {
|
|
20099
20129
|
stdio: "pipe",
|
|
20100
20130
|
timeout: 3e4
|
|
20101
20131
|
});
|
|
20102
|
-
if (!
|
|
20132
|
+
if (!existsSync24(join25(tmpDir, ".git"))) {
|
|
20103
20133
|
return { success: false, error: "Git clone failed: no .git directory produced" };
|
|
20104
20134
|
}
|
|
20105
|
-
const searchRoot = subPath ?
|
|
20135
|
+
const searchRoot = subPath ? join25(tmpDir, subPath) : tmpDir;
|
|
20106
20136
|
const skillDir = await findSkillDir(searchRoot);
|
|
20107
20137
|
if (!skillDir) {
|
|
20108
20138
|
return { success: false, error: "No SKILL.md found in the repository." };
|
|
20109
20139
|
}
|
|
20110
20140
|
const skillFolderName = basename2(skillDir);
|
|
20111
|
-
const destDir =
|
|
20112
|
-
if (
|
|
20141
|
+
const destDir = join25(SKILLS_PATH, skillFolderName);
|
|
20142
|
+
if (existsSync24(destDir)) {
|
|
20113
20143
|
log(`[skill-install] Overwriting existing skill at ${destDir}`);
|
|
20114
20144
|
}
|
|
20115
20145
|
await mkdir4(destDir, { recursive: true });
|
|
20116
20146
|
await cp(skillDir, destDir, { recursive: true });
|
|
20117
20147
|
let skillName = skillFolderName;
|
|
20118
20148
|
try {
|
|
20119
|
-
const content = await readFile5(
|
|
20149
|
+
const content = await readFile5(join25(destDir, "SKILL.md"), "utf-8");
|
|
20120
20150
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
20121
20151
|
if (nameMatch) skillName = nameMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
20122
20152
|
} catch {
|
|
20123
20153
|
try {
|
|
20124
|
-
const content = await readFile5(
|
|
20154
|
+
const content = await readFile5(join25(destDir, "skill.md"), "utf-8");
|
|
20125
20155
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
20126
20156
|
if (nameMatch) skillName = nameMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
20127
20157
|
} catch {
|
|
@@ -20156,15 +20186,15 @@ function parseGitHubUrl(input) {
|
|
|
20156
20186
|
async function findSkillDir(root) {
|
|
20157
20187
|
const candidates = ["SKILL.md", "skill.md"];
|
|
20158
20188
|
for (const c of candidates) {
|
|
20159
|
-
if (
|
|
20189
|
+
if (existsSync24(join25(root, c))) return root;
|
|
20160
20190
|
}
|
|
20161
20191
|
try {
|
|
20162
20192
|
const entries = await readdir5(root, { withFileTypes: true });
|
|
20163
20193
|
for (const entry of entries) {
|
|
20164
20194
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
20165
20195
|
for (const c of candidates) {
|
|
20166
|
-
if (
|
|
20167
|
-
return
|
|
20196
|
+
if (existsSync24(join25(root, entry.name, c))) {
|
|
20197
|
+
return join25(root, entry.name);
|
|
20168
20198
|
}
|
|
20169
20199
|
}
|
|
20170
20200
|
}
|
|
@@ -20176,15 +20206,15 @@ async function findSkillDir(root) {
|
|
|
20176
20206
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
20177
20207
|
let subEntries;
|
|
20178
20208
|
try {
|
|
20179
|
-
subEntries = await readdir5(
|
|
20209
|
+
subEntries = await readdir5(join25(root, entry.name), { withFileTypes: true });
|
|
20180
20210
|
} catch {
|
|
20181
20211
|
continue;
|
|
20182
20212
|
}
|
|
20183
20213
|
for (const sub of subEntries) {
|
|
20184
20214
|
if (!sub.isDirectory() || sub.name.startsWith(".")) continue;
|
|
20185
20215
|
for (const c of candidates) {
|
|
20186
|
-
if (
|
|
20187
|
-
return
|
|
20216
|
+
if (existsSync24(join25(root, entry.name, sub.name, c))) {
|
|
20217
|
+
return join25(root, entry.name, sub.name);
|
|
20188
20218
|
}
|
|
20189
20219
|
}
|
|
20190
20220
|
}
|
|
@@ -21480,13 +21510,13 @@ async function handleEvolveCallback(chatId, data, channel) {
|
|
|
21480
21510
|
const { getReflectionStatus: getReflectionStatus2, setReflectionStatus: setReflectionStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
21481
21511
|
const current = getReflectionStatus2(getDb(), chatId);
|
|
21482
21512
|
if (current === "frozen") {
|
|
21483
|
-
const { readFileSync:
|
|
21484
|
-
const { join:
|
|
21513
|
+
const { readFileSync: readFileSync33, existsSync: existsSync62 } = await import("fs");
|
|
21514
|
+
const { join: join41 } = await import("path");
|
|
21485
21515
|
const { CC_CLAW_HOME: CC_CLAW_HOME3 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
21486
|
-
const soulPath =
|
|
21487
|
-
const userPath =
|
|
21488
|
-
const soul =
|
|
21489
|
-
const user =
|
|
21516
|
+
const soulPath = join41(CC_CLAW_HOME3, "identity/SOUL.md");
|
|
21517
|
+
const userPath = join41(CC_CLAW_HOME3, "identity/USER.md");
|
|
21518
|
+
const soul = existsSync62(soulPath) ? readFileSync33(soulPath, "utf-8") : "";
|
|
21519
|
+
const user = existsSync62(userPath) ? readFileSync33(userPath, "utf-8") : "";
|
|
21490
21520
|
setReflectionStatus2(getDb(), chatId, "active", soul, user);
|
|
21491
21521
|
const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
|
|
21492
21522
|
logActivity2(getDb(), { chatId, source: "telegram", eventType: "reflection_unfrozen", summary: "Reflection enabled" });
|
|
@@ -21563,11 +21593,11 @@ var init_evolve2 = __esm({
|
|
|
21563
21593
|
});
|
|
21564
21594
|
|
|
21565
21595
|
// src/optimizer/identity-audit.ts
|
|
21566
|
-
import { readFileSync as
|
|
21567
|
-
import { join as
|
|
21596
|
+
import { readFileSync as readFileSync14, existsSync as existsSync25, readdirSync as readdirSync10, statSync as statSync7 } from "fs";
|
|
21597
|
+
import { join as join26 } from "path";
|
|
21568
21598
|
function readIdentityFile2(filename) {
|
|
21569
21599
|
try {
|
|
21570
|
-
return
|
|
21600
|
+
return readFileSync14(join26(IDENTITY_PATH, filename), "utf-8");
|
|
21571
21601
|
} catch {
|
|
21572
21602
|
return "";
|
|
21573
21603
|
}
|
|
@@ -21582,13 +21612,13 @@ function getMtime(filepath) {
|
|
|
21582
21612
|
function findBackupFiles() {
|
|
21583
21613
|
const backups = [];
|
|
21584
21614
|
const dirs = [IDENTITY_PATH];
|
|
21585
|
-
const contextDir =
|
|
21586
|
-
if (
|
|
21615
|
+
const contextDir = join26(IDENTITY_PATH, "..", "workspace", "context");
|
|
21616
|
+
if (existsSync25(contextDir)) dirs.push(contextDir);
|
|
21587
21617
|
for (const dir of dirs) {
|
|
21588
21618
|
try {
|
|
21589
21619
|
for (const entry of readdirSync10(dir)) {
|
|
21590
21620
|
if (entry.endsWith(".bak") || /\.bak\.\d{4}-\d{2}-\d{2}/.test(entry)) {
|
|
21591
|
-
backups.push(
|
|
21621
|
+
backups.push(join26(dir, entry));
|
|
21592
21622
|
}
|
|
21593
21623
|
}
|
|
21594
21624
|
} catch {
|
|
@@ -21609,9 +21639,9 @@ function computeIdentityStats(pendingProposals, driftPercent) {
|
|
|
21609
21639
|
userChars,
|
|
21610
21640
|
ccClawChars,
|
|
21611
21641
|
boilerplateChars,
|
|
21612
|
-
soulMtime: getMtime(
|
|
21613
|
-
userMtime: getMtime(
|
|
21614
|
-
ccClawMtime: getMtime(
|
|
21642
|
+
soulMtime: getMtime(join26(IDENTITY_PATH, "SOUL.md")),
|
|
21643
|
+
userMtime: getMtime(join26(IDENTITY_PATH, "USER.md")),
|
|
21644
|
+
ccClawMtime: getMtime(join26(IDENTITY_PATH, "CC-CLAW.md")),
|
|
21615
21645
|
backupFiles: findBackupFiles(),
|
|
21616
21646
|
estimatedTokens: Math.ceil(ccClawChars / 4),
|
|
21617
21647
|
pendingEvolveProposals: pendingProposals,
|
|
@@ -21720,8 +21750,8 @@ var init_identity_audit = __esm({
|
|
|
21720
21750
|
});
|
|
21721
21751
|
|
|
21722
21752
|
// src/optimizer/skill-audit.ts
|
|
21723
|
-
import { readFileSync as
|
|
21724
|
-
import { join as
|
|
21753
|
+
import { readFileSync as readFileSync15, existsSync as existsSync26 } from "fs";
|
|
21754
|
+
import { join as join27, basename as basename3 } from "path";
|
|
21725
21755
|
function parseFrontmatter3(content) {
|
|
21726
21756
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
21727
21757
|
if (!fmMatch) return {};
|
|
@@ -21766,10 +21796,10 @@ function detectDependentSkills(content) {
|
|
|
21766
21796
|
return Array.from(deps);
|
|
21767
21797
|
}
|
|
21768
21798
|
function computeSkillStats(skillPath) {
|
|
21769
|
-
const content =
|
|
21799
|
+
const content = readFileSync15(skillPath, "utf-8");
|
|
21770
21800
|
const lines = content.split("\n");
|
|
21771
21801
|
return {
|
|
21772
|
-
skillName: basename3(skillPath, ".md") === "SKILL" ? basename3(
|
|
21802
|
+
skillName: basename3(skillPath, ".md") === "SKILL" ? basename3(join27(skillPath, "..")) : basename3(skillPath, ".md"),
|
|
21773
21803
|
skillPath,
|
|
21774
21804
|
lineCount: lines.length,
|
|
21775
21805
|
charCount: content.length,
|
|
@@ -21789,13 +21819,13 @@ function loadDependentSkillContents(depNames, ccClawSkillsDir) {
|
|
|
21789
21819
|
const results = [];
|
|
21790
21820
|
for (const name of depNames) {
|
|
21791
21821
|
const candidates = [
|
|
21792
|
-
|
|
21793
|
-
|
|
21822
|
+
join27(ccClawSkillsDir, name, "SKILL.md"),
|
|
21823
|
+
join27(ccClawSkillsDir, `${name}-skill`, "SKILL.md")
|
|
21794
21824
|
];
|
|
21795
21825
|
for (const candidate of candidates) {
|
|
21796
|
-
if (
|
|
21826
|
+
if (existsSync26(candidate)) {
|
|
21797
21827
|
try {
|
|
21798
|
-
const content =
|
|
21828
|
+
const content = readFileSync15(candidate, "utf-8");
|
|
21799
21829
|
results.push({
|
|
21800
21830
|
name,
|
|
21801
21831
|
content: content.length > 3e3 ? content.slice(0, 3e3) + "\n[...truncated]" : content
|
|
@@ -21939,8 +21969,8 @@ __export(analyze_exports2, {
|
|
|
21939
21969
|
});
|
|
21940
21970
|
import { spawn as spawn7 } from "child_process";
|
|
21941
21971
|
import { createInterface as createInterface7 } from "readline";
|
|
21942
|
-
import { readFileSync as
|
|
21943
|
-
import { join as
|
|
21972
|
+
import { readFileSync as readFileSync16, existsSync as existsSync27, readdirSync as readdirSync12 } from "fs";
|
|
21973
|
+
import { join as join28 } from "path";
|
|
21944
21974
|
import { homedir as homedir7 } from "os";
|
|
21945
21975
|
function parseOptimizeOutput(raw, validAreas) {
|
|
21946
21976
|
if (!raw || raw.includes("NO_FINDINGS")) return [];
|
|
@@ -22070,20 +22100,20 @@ function getModelDisplayInfo(chatId) {
|
|
|
22070
22100
|
}
|
|
22071
22101
|
function readIdentityFile3(filename) {
|
|
22072
22102
|
try {
|
|
22073
|
-
return
|
|
22103
|
+
return readFileSync16(join28(IDENTITY_PATH, filename), "utf-8");
|
|
22074
22104
|
} catch {
|
|
22075
22105
|
return "";
|
|
22076
22106
|
}
|
|
22077
22107
|
}
|
|
22078
22108
|
function loadContextFiles2() {
|
|
22079
|
-
const contextDir =
|
|
22109
|
+
const contextDir = join28(homedir7(), ".cc-claw", "workspace", "context");
|
|
22080
22110
|
const results = [];
|
|
22081
|
-
if (!
|
|
22111
|
+
if (!existsSync27(contextDir)) return results;
|
|
22082
22112
|
try {
|
|
22083
22113
|
for (const entry of readdirSync12(contextDir)) {
|
|
22084
22114
|
if (!entry.endsWith(".md")) continue;
|
|
22085
22115
|
try {
|
|
22086
|
-
const content =
|
|
22116
|
+
const content = readFileSync16(join28(contextDir, entry), "utf-8");
|
|
22087
22117
|
results.push({ name: entry, content });
|
|
22088
22118
|
} catch {
|
|
22089
22119
|
}
|
|
@@ -22134,8 +22164,8 @@ async function runSkillAudit(chatId, skillPath) {
|
|
|
22134
22164
|
const stats = computeSkillStats(skillPath);
|
|
22135
22165
|
log(`[optimizer] Running skill audit on ${stats.skillName} with ${adapter.id}:${model2}`);
|
|
22136
22166
|
const soulMd = readIdentityFile3("SOUL.md");
|
|
22137
|
-
const ccClawSkillsDir =
|
|
22138
|
-
const skillContent =
|
|
22167
|
+
const ccClawSkillsDir = join28(homedir7(), ".cc-claw", "workspace", "skills");
|
|
22168
|
+
const skillContent = readFileSync16(skillPath, "utf-8");
|
|
22139
22169
|
const prompt = buildSkillAuditPrompt(skillContent, stats, soulMd, ccClawSkillsDir);
|
|
22140
22170
|
const raw = await spawnAnalysis2(adapter, model2, prompt);
|
|
22141
22171
|
const findings = parseOptimizeOutput(raw, VALID_SKILL_AREAS);
|
|
@@ -22149,16 +22179,16 @@ async function runSkillAudit(chatId, skillPath) {
|
|
|
22149
22179
|
};
|
|
22150
22180
|
}
|
|
22151
22181
|
function listCcClawSkills() {
|
|
22152
|
-
const skillsDir =
|
|
22182
|
+
const skillsDir = join28(homedir7(), ".cc-claw", "workspace", "skills");
|
|
22153
22183
|
const entries = [];
|
|
22154
|
-
if (!
|
|
22184
|
+
if (!existsSync27(skillsDir)) return entries;
|
|
22155
22185
|
try {
|
|
22156
22186
|
for (const dir of readdirSync12(skillsDir)) {
|
|
22157
|
-
const skillFile =
|
|
22158
|
-
if (!
|
|
22187
|
+
const skillFile = join28(skillsDir, dir, "SKILL.md");
|
|
22188
|
+
if (!existsSync27(skillFile)) continue;
|
|
22159
22189
|
let description = "skill";
|
|
22160
22190
|
try {
|
|
22161
|
-
const content =
|
|
22191
|
+
const content = readFileSync16(skillFile, "utf-8");
|
|
22162
22192
|
const descMatch = content.match(/description:\s*>?\s*\n?\s*(.+)/);
|
|
22163
22193
|
if (descMatch) description = descMatch[1].trim().slice(0, 60);
|
|
22164
22194
|
} catch {
|
|
@@ -22485,8 +22515,8 @@ __export(optimize_exports, {
|
|
|
22485
22515
|
handleOptimizeCallback: () => handleOptimizeCallback,
|
|
22486
22516
|
handleOptimizeCommand: () => handleOptimizeCommand
|
|
22487
22517
|
});
|
|
22488
|
-
import { readFileSync as
|
|
22489
|
-
import { join as
|
|
22518
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync8, existsSync as existsSync28, readdirSync as readdirSync13, unlinkSync as unlinkSync7 } from "fs";
|
|
22519
|
+
import { join as join29, dirname as dirname4 } from "path";
|
|
22490
22520
|
import { homedir as homedir8 } from "os";
|
|
22491
22521
|
async function handleOptimizeCommand(chatId, channel, _args) {
|
|
22492
22522
|
const { getModelDisplayInfo: getModelDisplayInfo2 } = await Promise.resolve().then(() => (init_analyze2(), analyze_exports2));
|
|
@@ -22667,7 +22697,7 @@ async function runSkillAuditFlow(chatId, channel, skillName) {
|
|
|
22667
22697
|
} = await Promise.resolve().then(() => (init_ui2(), ui_exports));
|
|
22668
22698
|
const modelInfo = getModelDisplayInfo2(chatId);
|
|
22669
22699
|
if (!modelInfo) return;
|
|
22670
|
-
const skillPath =
|
|
22700
|
+
const skillPath = join29(homedir8(), ".cc-claw", "workspace", "skills", skillName, "SKILL.md");
|
|
22671
22701
|
const progressMsgId = typeof channel.sendTextReturningId === "function" ? await channel.sendTextReturningId(
|
|
22672
22702
|
chatId,
|
|
22673
22703
|
buildProgressMessage2(`skill: ${skillName}`, modelInfo.backend, modelInfo.model, modelInfo.thinkingLevel),
|
|
@@ -22756,15 +22786,15 @@ async function applyFinding(chatId, channel, index) {
|
|
|
22756
22786
|
await showFinding(chatId, channel, index + 1);
|
|
22757
22787
|
return;
|
|
22758
22788
|
}
|
|
22759
|
-
if (!
|
|
22789
|
+
if (!existsSync28(targetPath)) {
|
|
22760
22790
|
await channel.sendText(chatId, `Target file not found: ${targetPath}`, { parseMode: "plain" });
|
|
22761
22791
|
session2.skipped.push(index);
|
|
22762
22792
|
await showFinding(chatId, channel, index + 1);
|
|
22763
22793
|
return;
|
|
22764
22794
|
}
|
|
22765
|
-
const original =
|
|
22795
|
+
const original = readFileSync17(targetPath, "utf-8");
|
|
22766
22796
|
const backupPath = targetPath + `.bak.${Date.now()}`;
|
|
22767
|
-
|
|
22797
|
+
writeFileSync8(backupPath, original, "utf-8");
|
|
22768
22798
|
pruneBackups2(targetPath);
|
|
22769
22799
|
let newContent;
|
|
22770
22800
|
try {
|
|
@@ -22794,7 +22824,7 @@ async function applyFinding(chatId, channel, index) {
|
|
|
22794
22824
|
await showFinding(chatId, channel, index + 1);
|
|
22795
22825
|
return;
|
|
22796
22826
|
}
|
|
22797
|
-
|
|
22827
|
+
writeFileSync8(targetPath, newContent, "utf-8");
|
|
22798
22828
|
session2.applied.push(index);
|
|
22799
22829
|
if (targetPath.includes("identity/")) {
|
|
22800
22830
|
try {
|
|
@@ -22838,14 +22868,14 @@ async function finishReview(chatId, channel) {
|
|
|
22838
22868
|
activeSessions.delete(chatId);
|
|
22839
22869
|
}
|
|
22840
22870
|
function resolveTargetFile(location, auditTarget) {
|
|
22841
|
-
const ccClawHome =
|
|
22871
|
+
const ccClawHome = join29(homedir8(), ".cc-claw");
|
|
22842
22872
|
const filePart = location.split(":")[0]?.trim();
|
|
22843
22873
|
if (!filePart) return null;
|
|
22844
|
-
if (filePart === "SOUL.md") return
|
|
22845
|
-
if (filePart === "USER.md") return
|
|
22846
|
-
if (filePart === "CC-CLAW.md") return
|
|
22874
|
+
if (filePart === "SOUL.md") return join29(ccClawHome, "identity", "SOUL.md");
|
|
22875
|
+
if (filePart === "USER.md") return join29(ccClawHome, "identity", "USER.md");
|
|
22876
|
+
if (filePart === "CC-CLAW.md") return join29(ccClawHome, "identity", "CC-CLAW.md");
|
|
22847
22877
|
if (filePart === "SKILL.md" && auditTarget !== "identity") {
|
|
22848
|
-
return
|
|
22878
|
+
return join29(ccClawHome, "workspace", "skills", auditTarget, "SKILL.md");
|
|
22849
22879
|
}
|
|
22850
22880
|
return null;
|
|
22851
22881
|
}
|
|
@@ -22853,7 +22883,7 @@ function pruneBackups2(absolutePath) {
|
|
|
22853
22883
|
const dir = dirname4(absolutePath);
|
|
22854
22884
|
const baseName = absolutePath.split("/").pop() ?? "";
|
|
22855
22885
|
try {
|
|
22856
|
-
const backups = readdirSync13(dir).filter((f) => f.startsWith(baseName + ".bak.")).sort().map((f) =>
|
|
22886
|
+
const backups = readdirSync13(dir).filter((f) => f.startsWith(baseName + ".bak.")).sort().map((f) => join29(dir, f));
|
|
22857
22887
|
while (backups.length > 3) {
|
|
22858
22888
|
const oldest = backups.shift();
|
|
22859
22889
|
try {
|
|
@@ -23095,7 +23125,7 @@ __export(auto_create_exports, {
|
|
|
23095
23125
|
saveSkill: () => saveSkill,
|
|
23096
23126
|
storePendingDraft: () => storePendingDraft
|
|
23097
23127
|
});
|
|
23098
|
-
import { join as
|
|
23128
|
+
import { join as join30 } from "path";
|
|
23099
23129
|
import { writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
23100
23130
|
function isSkillWorthy(signals) {
|
|
23101
23131
|
const { toolUseCount, tokenOutput, elapsedMs, userMessage } = signals;
|
|
@@ -23277,9 +23307,9 @@ async function saveSkill(name, content, opts = {}) {
|
|
|
23277
23307
|
warn(`[auto-skill] Quality warning for "${name}": ${w}`);
|
|
23278
23308
|
}
|
|
23279
23309
|
}
|
|
23280
|
-
const dir =
|
|
23310
|
+
const dir = join30(SKILLS_PATH, name);
|
|
23281
23311
|
await mkdir5(dir, { recursive: true });
|
|
23282
|
-
const filePath =
|
|
23312
|
+
const filePath = join30(dir, "SKILL.md");
|
|
23283
23313
|
await writeFile5(filePath, withFrontmatter, "utf-8");
|
|
23284
23314
|
invalidateSkillCache();
|
|
23285
23315
|
log(`[auto-skill] Saved skill "${name}" to ${filePath}`);
|
|
@@ -27096,7 +27126,7 @@ ${lines.join("\n")}`, { parseMode: "plain" });
|
|
|
27096
27126
|
try {
|
|
27097
27127
|
const { readFile: readFileFs } = await import("fs/promises");
|
|
27098
27128
|
const { mkdir: mkdir7, writeFile: writeFileFs } = await import("fs/promises");
|
|
27099
|
-
const { join:
|
|
27129
|
+
const { join: join41 } = await import("path");
|
|
27100
27130
|
const { SKILLS_PATH: SKILLS_PATH2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
27101
27131
|
const { updateFrontmatter: updateFrontmatter2, ensureThreeTierFrontmatter: ensureThreeTierFrontmatter2 } = await Promise.resolve().then(() => (init_frontmatter(), frontmatter_exports));
|
|
27102
27132
|
const { invalidateSkillCache: invalidateSkillCache2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
|
|
@@ -27104,9 +27134,9 @@ ${lines.join("\n")}`, { parseMode: "plain" });
|
|
|
27104
27134
|
let updated = ensureThreeTierFrontmatter2(raw, { name: skillName, source });
|
|
27105
27135
|
const targetStatus = doApprove ? "approved" : "imported";
|
|
27106
27136
|
updated = updateFrontmatter2(updated, { status: targetStatus });
|
|
27107
|
-
const targetDir =
|
|
27137
|
+
const targetDir = join41(SKILLS_PATH2, skillName);
|
|
27108
27138
|
await mkdir7(targetDir, { recursive: true });
|
|
27109
|
-
await writeFileFs(
|
|
27139
|
+
await writeFileFs(join41(targetDir, "SKILL.md"), updated, "utf-8");
|
|
27110
27140
|
invalidateSkillCache2();
|
|
27111
27141
|
if (doApprove) {
|
|
27112
27142
|
await channel.sendText(
|
|
@@ -27235,13 +27265,13 @@ ${formatValidationReport2(validation)}` : "\n\n\u2705 Quality checks passed.";
|
|
|
27235
27265
|
return;
|
|
27236
27266
|
}
|
|
27237
27267
|
try {
|
|
27238
|
-
const { readFileSync:
|
|
27268
|
+
const { readFileSync: readFileSync33, writeFileSync: writeFileSync15 } = await import("fs");
|
|
27239
27269
|
const { updateFrontmatter: updateFrontmatter2, ensureThreeTierFrontmatter: ensureThreeTierFrontmatter2 } = await Promise.resolve().then(() => (init_frontmatter(), frontmatter_exports));
|
|
27240
27270
|
const { invalidateSkillCache: invalidateSkillCache2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
|
|
27241
|
-
const raw =
|
|
27271
|
+
const raw = readFileSync33(skill.filePath, "utf-8");
|
|
27242
27272
|
let updated = ensureThreeTierFrontmatter2(raw, { name: skillName, source: "cc-claw" });
|
|
27243
27273
|
updated = updateFrontmatter2(updated, { status: "approved" });
|
|
27244
|
-
|
|
27274
|
+
writeFileSync15(skill.filePath, updated, "utf-8");
|
|
27245
27275
|
invalidateSkillCache2();
|
|
27246
27276
|
await channel.sendText(chatId, `\u2705 "${skillName}" approved.`, { parseMode: "plain" });
|
|
27247
27277
|
const refreshedSkills = await discoverAllSkills();
|
|
@@ -27288,17 +27318,17 @@ ${formatValidationReport2(validation)}` : "\n\n\u2705 Quality checks passed.";
|
|
|
27288
27318
|
return;
|
|
27289
27319
|
}
|
|
27290
27320
|
try {
|
|
27291
|
-
const { readFileSync:
|
|
27321
|
+
const { readFileSync: readFileSync33, writeFileSync: writeFileSync15 } = await import("fs");
|
|
27292
27322
|
const { updateFrontmatter: updateFrontmatter2, ensureThreeTierFrontmatter: ensureThreeTierFrontmatter2 } = await Promise.resolve().then(() => (init_frontmatter(), frontmatter_exports));
|
|
27293
27323
|
const { invalidateSkillCache: invalidateSkillCache2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
|
|
27294
27324
|
let approvedCount = 0;
|
|
27295
27325
|
const issues = [];
|
|
27296
27326
|
for (const skill of unapproved) {
|
|
27297
27327
|
try {
|
|
27298
|
-
const raw =
|
|
27328
|
+
const raw = readFileSync33(skill.filePath, "utf-8");
|
|
27299
27329
|
let updated = ensureThreeTierFrontmatter2(raw, { name: skill.name, source: "cc-claw" });
|
|
27300
27330
|
updated = updateFrontmatter2(updated, { status: "approved" });
|
|
27301
|
-
|
|
27331
|
+
writeFileSync15(skill.filePath, updated, "utf-8");
|
|
27302
27332
|
approvedCount++;
|
|
27303
27333
|
} catch (e) {
|
|
27304
27334
|
issues.push(`${skill.name}: ${e.message}`);
|
|
@@ -28896,7 +28926,7 @@ var init_cron = __esm({
|
|
|
28896
28926
|
});
|
|
28897
28927
|
|
|
28898
28928
|
// src/agents/runners/wrap-backend.ts
|
|
28899
|
-
import { join as
|
|
28929
|
+
import { join as join31 } from "path";
|
|
28900
28930
|
function buildMcpCommands(backendId) {
|
|
28901
28931
|
const exe = backendId === BACKEND.CURSOR ? "agent" : backendId;
|
|
28902
28932
|
return {
|
|
@@ -28992,7 +29022,7 @@ function wrapBackendAdapter(adapter) {
|
|
|
28992
29022
|
const configPath = writeMcpConfigFile(server);
|
|
28993
29023
|
return ["--mcp-config", configPath];
|
|
28994
29024
|
},
|
|
28995
|
-
getSkillPath: () =>
|
|
29025
|
+
getSkillPath: () => join31(SKILLS_PATH, `agent-${adapter.id}.md`)
|
|
28996
29026
|
};
|
|
28997
29027
|
}
|
|
28998
29028
|
var BACKEND_CAPABILITIES;
|
|
@@ -29054,18 +29084,18 @@ var init_wrap_backend = __esm({
|
|
|
29054
29084
|
});
|
|
29055
29085
|
|
|
29056
29086
|
// src/agents/runners/config-loader.ts
|
|
29057
|
-
import { readFileSync as
|
|
29058
|
-
import { join as
|
|
29087
|
+
import { readFileSync as readFileSync18, readdirSync as readdirSync14, existsSync as existsSync29, mkdirSync as mkdirSync10, watchFile, unwatchFile } from "fs";
|
|
29088
|
+
import { join as join32 } from "path";
|
|
29059
29089
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
29060
29090
|
function resolveExecutable2(config2) {
|
|
29061
|
-
if (
|
|
29091
|
+
if (existsSync29(config2.executable)) return config2.executable;
|
|
29062
29092
|
try {
|
|
29063
29093
|
return execFileSync3("which", [config2.executable], { encoding: "utf-8" }).trim();
|
|
29064
29094
|
} catch {
|
|
29065
29095
|
}
|
|
29066
29096
|
for (const fallback of config2.executableFallbacks ?? []) {
|
|
29067
29097
|
const resolved = fallback.replace(/^~/, process.env.HOME ?? "");
|
|
29068
|
-
if (
|
|
29098
|
+
if (existsSync29(resolved)) return resolved;
|
|
29069
29099
|
}
|
|
29070
29100
|
return config2.executable;
|
|
29071
29101
|
}
|
|
@@ -29191,12 +29221,12 @@ function configToRunner(config2) {
|
|
|
29191
29221
|
prepareMcpInjection() {
|
|
29192
29222
|
return [];
|
|
29193
29223
|
},
|
|
29194
|
-
getSkillPath: () =>
|
|
29224
|
+
getSkillPath: () => join32(SKILLS_PATH, `agent-${config2.id}.md`)
|
|
29195
29225
|
};
|
|
29196
29226
|
}
|
|
29197
29227
|
function loadRunnerConfig(filePath) {
|
|
29198
29228
|
try {
|
|
29199
|
-
const content =
|
|
29229
|
+
const content = readFileSync18(filePath, "utf-8");
|
|
29200
29230
|
return JSON.parse(content);
|
|
29201
29231
|
} catch (err) {
|
|
29202
29232
|
warn(`[runners] Failed to load config ${filePath}: ${err}`);
|
|
@@ -29204,14 +29234,14 @@ function loadRunnerConfig(filePath) {
|
|
|
29204
29234
|
}
|
|
29205
29235
|
}
|
|
29206
29236
|
function loadAllRunnerConfigs() {
|
|
29207
|
-
if (!
|
|
29237
|
+
if (!existsSync29(RUNNERS_PATH)) {
|
|
29208
29238
|
mkdirSync10(RUNNERS_PATH, { recursive: true });
|
|
29209
29239
|
return [];
|
|
29210
29240
|
}
|
|
29211
29241
|
const files = readdirSync14(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
|
|
29212
29242
|
const configs = [];
|
|
29213
29243
|
for (const file of files) {
|
|
29214
|
-
const config2 = loadRunnerConfig(
|
|
29244
|
+
const config2 = loadRunnerConfig(join32(RUNNERS_PATH, file));
|
|
29215
29245
|
if (config2) configs.push(config2);
|
|
29216
29246
|
}
|
|
29217
29247
|
return configs;
|
|
@@ -29232,16 +29262,16 @@ function registerConfigRunners() {
|
|
|
29232
29262
|
return count;
|
|
29233
29263
|
}
|
|
29234
29264
|
function watchRunnerConfigs(onChange) {
|
|
29235
|
-
if (!
|
|
29265
|
+
if (!existsSync29(RUNNERS_PATH)) return;
|
|
29236
29266
|
for (const prev of watchedFiles) {
|
|
29237
|
-
if (!
|
|
29267
|
+
if (!existsSync29(prev)) {
|
|
29238
29268
|
unwatchFile(prev);
|
|
29239
29269
|
watchedFiles.delete(prev);
|
|
29240
29270
|
}
|
|
29241
29271
|
}
|
|
29242
29272
|
const files = readdirSync14(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
|
|
29243
29273
|
for (const file of files) {
|
|
29244
|
-
const fullPath =
|
|
29274
|
+
const fullPath = join32(RUNNERS_PATH, file);
|
|
29245
29275
|
if (watchedFiles.has(fullPath)) continue;
|
|
29246
29276
|
watchedFiles.add(fullPath);
|
|
29247
29277
|
watchFile(fullPath, { interval: 5e3 }, () => {
|
|
@@ -29759,8 +29789,8 @@ var init_telegram2 = __esm({
|
|
|
29759
29789
|
/** Watchdog interval that detects silent polling death */
|
|
29760
29790
|
pollingWatchdog = null;
|
|
29761
29791
|
/** Max time without any update before we consider polling dead (ms) */
|
|
29762
|
-
static POLLING_SILENCE_THRESHOLD_MS =
|
|
29763
|
-
//
|
|
29792
|
+
static POLLING_SILENCE_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
29793
|
+
// 5 minutes
|
|
29764
29794
|
/** How often the watchdog checks for polling health (ms) */
|
|
29765
29795
|
static POLLING_WATCHDOG_INTERVAL_MS = 60 * 1e3;
|
|
29766
29796
|
// 60 seconds
|
|
@@ -30005,8 +30035,8 @@ var init_telegram2 = __esm({
|
|
|
30005
30035
|
if (!this.pollingExpected) return;
|
|
30006
30036
|
const silenceMs = Date.now() - this.lastUpdateAt;
|
|
30007
30037
|
if (silenceMs > _TelegramChannel.POLLING_SILENCE_THRESHOLD_MS) {
|
|
30008
|
-
|
|
30009
|
-
`[telegram]
|
|
30038
|
+
warn(
|
|
30039
|
+
`[telegram] No updates received for ${Math.round(silenceMs / 1e3)}s \u2014 triggering reconnect`
|
|
30010
30040
|
);
|
|
30011
30041
|
markChannelDown("telegram", `No updates for ${Math.round(silenceMs / 1e3)}s`);
|
|
30012
30042
|
this.lastUpdateAt = Date.now();
|
|
@@ -30533,19 +30563,19 @@ var init_telegram2 = __esm({
|
|
|
30533
30563
|
});
|
|
30534
30564
|
|
|
30535
30565
|
// src/skills/bootstrap.ts
|
|
30536
|
-
import { existsSync as
|
|
30566
|
+
import { existsSync as existsSync30, readFileSync as readFileSync19, writeFileSync as writeFileSync9, copyFileSync as copyFileSync3, readdirSync as readdirSync15 } from "fs";
|
|
30537
30567
|
import { readdir as readdir6, readFile as readFile8, writeFile as writeFile6, copyFile } from "fs/promises";
|
|
30538
|
-
import { join as
|
|
30568
|
+
import { join as join33, dirname as dirname5 } from "path";
|
|
30539
30569
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
30540
30570
|
async function copyAgentManifestSkills() {
|
|
30541
|
-
if (!
|
|
30571
|
+
if (!existsSync30(PKG_SKILLS)) return;
|
|
30542
30572
|
try {
|
|
30543
30573
|
const entries = await readdir6(PKG_SKILLS, { withFileTypes: true });
|
|
30544
30574
|
for (const entry of entries) {
|
|
30545
30575
|
if (!entry.isFile() || !entry.name.startsWith("agent-") || !entry.name.endsWith(".md")) continue;
|
|
30546
|
-
const src =
|
|
30547
|
-
const dest =
|
|
30548
|
-
if (
|
|
30576
|
+
const src = join33(PKG_SKILLS, entry.name);
|
|
30577
|
+
const dest = join33(SKILLS_PATH, entry.name);
|
|
30578
|
+
if (existsSync30(dest)) continue;
|
|
30549
30579
|
await copyFile(src, dest);
|
|
30550
30580
|
log(`[skills] Bootstrapped ${entry.name} to ${SKILLS_PATH}`);
|
|
30551
30581
|
}
|
|
@@ -30556,8 +30586,8 @@ async function copyAgentManifestSkills() {
|
|
|
30556
30586
|
async function bootstrapSkills() {
|
|
30557
30587
|
await copyAgentManifestSkills();
|
|
30558
30588
|
migrateSkillsToThreeTier();
|
|
30559
|
-
const usmDir =
|
|
30560
|
-
if (
|
|
30589
|
+
const usmDir = join33(SKILLS_PATH, USM_DIR_NAME);
|
|
30590
|
+
if (existsSync30(usmDir)) return;
|
|
30561
30591
|
try {
|
|
30562
30592
|
const entries = await readdir6(SKILLS_PATH);
|
|
30563
30593
|
const dirs = entries.filter((e) => !e.startsWith("."));
|
|
@@ -30580,8 +30610,8 @@ async function bootstrapSkills() {
|
|
|
30580
30610
|
}
|
|
30581
30611
|
}
|
|
30582
30612
|
async function patchUsmForCcClaw(usmDir) {
|
|
30583
|
-
const skillPath =
|
|
30584
|
-
if (!
|
|
30613
|
+
const skillPath = join33(usmDir, "SKILL.md");
|
|
30614
|
+
if (!existsSync30(skillPath)) return;
|
|
30585
30615
|
try {
|
|
30586
30616
|
let content = await readFile8(skillPath, "utf-8");
|
|
30587
30617
|
let patched = false;
|
|
@@ -30620,9 +30650,9 @@ async function patchUsmForCcClaw(usmDir) {
|
|
|
30620
30650
|
}
|
|
30621
30651
|
}
|
|
30622
30652
|
function migrateSkillsToThreeTier() {
|
|
30623
|
-
const markerPath =
|
|
30624
|
-
if (
|
|
30625
|
-
if (!
|
|
30653
|
+
const markerPath = join33(SKILLS_PATH, MIGRATION_MARKER);
|
|
30654
|
+
if (existsSync30(markerPath)) return;
|
|
30655
|
+
if (!existsSync30(SKILLS_PATH)) return;
|
|
30626
30656
|
let entries;
|
|
30627
30657
|
try {
|
|
30628
30658
|
entries = readdirSync15(SKILLS_PATH, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
@@ -30636,15 +30666,15 @@ function migrateSkillsToThreeTier() {
|
|
|
30636
30666
|
for (const dirName of entries) {
|
|
30637
30667
|
let skillPath;
|
|
30638
30668
|
for (const candidate of SKILL_FILE_CANDIDATES2) {
|
|
30639
|
-
const p =
|
|
30640
|
-
if (
|
|
30669
|
+
const p = join33(SKILLS_PATH, dirName, candidate);
|
|
30670
|
+
if (existsSync30(p)) {
|
|
30641
30671
|
skillPath = p;
|
|
30642
30672
|
break;
|
|
30643
30673
|
}
|
|
30644
30674
|
}
|
|
30645
30675
|
if (!skillPath) continue;
|
|
30646
30676
|
try {
|
|
30647
|
-
const raw =
|
|
30677
|
+
const raw = readFileSync19(skillPath, "utf-8");
|
|
30648
30678
|
const fmMatch = raw.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
30649
30679
|
if (fmMatch) {
|
|
30650
30680
|
const fm = fmMatch[1];
|
|
@@ -30658,7 +30688,7 @@ function migrateSkillsToThreeTier() {
|
|
|
30658
30688
|
copyFileSync3(skillPath, backupPath);
|
|
30659
30689
|
let updated = ensureThreeTierFrontmatter(raw, { name: dirName, source: "cc-claw" });
|
|
30660
30690
|
updated = updateFrontmatter(updated, { status: "approved" });
|
|
30661
|
-
|
|
30691
|
+
writeFileSync9(skillPath, updated, "utf-8");
|
|
30662
30692
|
migrated++;
|
|
30663
30693
|
log(`[skills] Migrated "${dirName}" to three-tier format (backed up to ${backupPath})`);
|
|
30664
30694
|
} catch (err) {
|
|
@@ -30667,7 +30697,7 @@ function migrateSkillsToThreeTier() {
|
|
|
30667
30697
|
}
|
|
30668
30698
|
}
|
|
30669
30699
|
try {
|
|
30670
|
-
|
|
30700
|
+
writeFileSync9(markerPath, [
|
|
30671
30701
|
`# Three-tier skill migration completed`,
|
|
30672
30702
|
`# Date: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
30673
30703
|
`# Migrated: ${migrated}, Skipped: ${skipped}, Failed: ${failed}`,
|
|
@@ -30693,8 +30723,8 @@ var init_bootstrap = __esm({
|
|
|
30693
30723
|
USM_REPO = "jacob-bd/universal-skills-manager";
|
|
30694
30724
|
USM_DIR_NAME = "universal-skills-manager";
|
|
30695
30725
|
CC_CLAW_ECOSYSTEM_PATCH = `| **CC-Claw** | \`~/.cc-claw/workspace/skills/\` | N/A (daemon, no project scope) |`;
|
|
30696
|
-
PKG_ROOT =
|
|
30697
|
-
PKG_SKILLS =
|
|
30726
|
+
PKG_ROOT = join33(dirname5(fileURLToPath2(import.meta.url)), "..", "..");
|
|
30727
|
+
PKG_SKILLS = join33(PKG_ROOT, "skills");
|
|
30698
30728
|
MIGRATION_MARKER = ".three-tier-migrated";
|
|
30699
30729
|
SKILL_FILE_CANDIDATES2 = ["SKILL.md", "skill.md"];
|
|
30700
30730
|
}
|
|
@@ -30809,13 +30839,13 @@ __export(ai_skill_exports, {
|
|
|
30809
30839
|
generateAiSkill: () => generateAiSkill,
|
|
30810
30840
|
installAiSkill: () => installAiSkill
|
|
30811
30841
|
});
|
|
30812
|
-
import { existsSync as
|
|
30813
|
-
import { join as
|
|
30842
|
+
import { existsSync as existsSync31, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11 } from "fs";
|
|
30843
|
+
import { join as join34 } from "path";
|
|
30814
30844
|
import { homedir as homedir9 } from "os";
|
|
30815
30845
|
function generateAiSkill() {
|
|
30816
30846
|
const version = VERSION;
|
|
30817
30847
|
let systemState = "";
|
|
30818
|
-
if (
|
|
30848
|
+
if (existsSync31(DB_PATH)) {
|
|
30819
30849
|
try {
|
|
30820
30850
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = (init_store5(), __toCommonJS(store_exports5));
|
|
30821
30851
|
const readDb = openDatabaseReadOnly2();
|
|
@@ -31257,11 +31287,11 @@ function installAiSkill() {
|
|
|
31257
31287
|
const failed = [];
|
|
31258
31288
|
for (const [backend2, dirs] of Object.entries(BACKEND_SKILL_DIRS2)) {
|
|
31259
31289
|
for (const dir of dirs) {
|
|
31260
|
-
const skillDir =
|
|
31261
|
-
const skillPath =
|
|
31290
|
+
const skillDir = join34(dir, "cc-claw-cli");
|
|
31291
|
+
const skillPath = join34(skillDir, "SKILL.md");
|
|
31262
31292
|
try {
|
|
31263
31293
|
mkdirSync11(skillDir, { recursive: true });
|
|
31264
|
-
|
|
31294
|
+
writeFileSync10(skillPath, skill, "utf-8");
|
|
31265
31295
|
installed.push(skillPath);
|
|
31266
31296
|
} catch {
|
|
31267
31297
|
failed.push(skillPath);
|
|
@@ -31277,11 +31307,11 @@ var init_ai_skill = __esm({
|
|
|
31277
31307
|
init_paths();
|
|
31278
31308
|
init_version();
|
|
31279
31309
|
BACKEND_SKILL_DIRS2 = {
|
|
31280
|
-
"cc-claw": [
|
|
31281
|
-
claude: [
|
|
31282
|
-
gemini: [
|
|
31283
|
-
codex: [
|
|
31284
|
-
cursor: [
|
|
31310
|
+
"cc-claw": [join34(homedir9(), ".cc-claw", "workspace", "skills")],
|
|
31311
|
+
claude: [join34(homedir9(), ".claude", "skills")],
|
|
31312
|
+
gemini: [join34(homedir9(), ".gemini", "skills")],
|
|
31313
|
+
codex: [join34(homedir9(), ".agents", "skills")],
|
|
31314
|
+
cursor: [join34(homedir9(), ".cursor", "skills"), join34(homedir9(), ".cursor", "skills-cursor")]
|
|
31285
31315
|
};
|
|
31286
31316
|
}
|
|
31287
31317
|
});
|
|
@@ -31291,21 +31321,21 @@ var index_exports = {};
|
|
|
31291
31321
|
__export(index_exports, {
|
|
31292
31322
|
main: () => main
|
|
31293
31323
|
});
|
|
31294
|
-
import { mkdirSync as mkdirSync12, existsSync as
|
|
31295
|
-
import { join as
|
|
31324
|
+
import { mkdirSync as mkdirSync12, existsSync as existsSync32, renameSync as renameSync2, statSync as statSync8, readFileSync as readFileSync21 } from "fs";
|
|
31325
|
+
import { join as join35 } from "path";
|
|
31296
31326
|
import dotenv from "dotenv";
|
|
31297
31327
|
function migrateLayout() {
|
|
31298
31328
|
const moves = [
|
|
31299
|
-
[
|
|
31300
|
-
[
|
|
31301
|
-
[
|
|
31302
|
-
[
|
|
31303
|
-
[
|
|
31304
|
-
[
|
|
31305
|
-
[
|
|
31329
|
+
[join35(CC_CLAW_HOME, "cc-claw.db"), join35(DATA_PATH, "cc-claw.db")],
|
|
31330
|
+
[join35(CC_CLAW_HOME, "cc-claw.db-shm"), join35(DATA_PATH, "cc-claw.db-shm")],
|
|
31331
|
+
[join35(CC_CLAW_HOME, "cc-claw.db-wal"), join35(DATA_PATH, "cc-claw.db-wal")],
|
|
31332
|
+
[join35(CC_CLAW_HOME, "cc-claw.log"), join35(LOGS_PATH, "cc-claw.log")],
|
|
31333
|
+
[join35(CC_CLAW_HOME, "cc-claw.log.1"), join35(LOGS_PATH, "cc-claw.log.1")],
|
|
31334
|
+
[join35(CC_CLAW_HOME, "cc-claw.error.log"), join35(LOGS_PATH, "cc-claw.error.log")],
|
|
31335
|
+
[join35(CC_CLAW_HOME, "cc-claw.error.log.1"), join35(LOGS_PATH, "cc-claw.error.log.1")]
|
|
31306
31336
|
];
|
|
31307
31337
|
for (const [from, to] of moves) {
|
|
31308
|
-
if (
|
|
31338
|
+
if (existsSync32(from) && !existsSync32(to)) {
|
|
31309
31339
|
try {
|
|
31310
31340
|
renameSync2(from, to);
|
|
31311
31341
|
} catch {
|
|
@@ -31334,7 +31364,7 @@ async function main() {
|
|
|
31334
31364
|
let version = "unknown";
|
|
31335
31365
|
try {
|
|
31336
31366
|
const pkgPath = new URL("../package.json", import.meta.url);
|
|
31337
|
-
version = JSON.parse(
|
|
31367
|
+
version = JSON.parse(readFileSync21(pkgPath, "utf-8")).version;
|
|
31338
31368
|
} catch {
|
|
31339
31369
|
}
|
|
31340
31370
|
log(`[cc-claw] Starting v${version}`);
|
|
@@ -31481,11 +31511,11 @@ async function main() {
|
|
|
31481
31511
|
bootstrapSkills().catch((err) => error("[cc-claw] Skill bootstrap failed:", err));
|
|
31482
31512
|
try {
|
|
31483
31513
|
const { generateAiSkill: generateAiSkill2 } = await Promise.resolve().then(() => (init_ai_skill(), ai_skill_exports));
|
|
31484
|
-
const { writeFileSync:
|
|
31485
|
-
const { join:
|
|
31486
|
-
const skillDir =
|
|
31514
|
+
const { writeFileSync: writeFileSync15, mkdirSync: mkdirSync19 } = await import("fs");
|
|
31515
|
+
const { join: join41 } = await import("path");
|
|
31516
|
+
const skillDir = join41(SKILLS_PATH, "cc-claw-cli");
|
|
31487
31517
|
mkdirSync19(skillDir, { recursive: true });
|
|
31488
|
-
|
|
31518
|
+
writeFileSync15(join41(skillDir, "SKILL.md"), generateAiSkill2(), "utf-8");
|
|
31489
31519
|
log("[cc-claw] AI skill updated");
|
|
31490
31520
|
} catch {
|
|
31491
31521
|
}
|
|
@@ -31585,10 +31615,10 @@ var init_index = __esm({
|
|
|
31585
31615
|
init_health3();
|
|
31586
31616
|
init_image_gen();
|
|
31587
31617
|
for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SESSION_LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
|
|
31588
|
-
if (!
|
|
31618
|
+
if (!existsSync32(dir)) mkdirSync12(dir, { recursive: true });
|
|
31589
31619
|
}
|
|
31590
31620
|
migrateLayout();
|
|
31591
|
-
if (
|
|
31621
|
+
if (existsSync32(ENV_PATH)) {
|
|
31592
31622
|
dotenv.config({ path: ENV_PATH });
|
|
31593
31623
|
} else {
|
|
31594
31624
|
console.error(`[cc-claw] Config not found at ${ENV_PATH} \u2014 run 'cc-claw setup' first`);
|
|
@@ -31609,12 +31639,12 @@ __export(api_client_exports, {
|
|
|
31609
31639
|
apiPost: () => apiPost,
|
|
31610
31640
|
isDaemonRunning: () => isDaemonRunning
|
|
31611
31641
|
});
|
|
31612
|
-
import { readFileSync as
|
|
31642
|
+
import { readFileSync as readFileSync22, existsSync as existsSync33 } from "fs";
|
|
31613
31643
|
import { request as httpRequest, Agent } from "http";
|
|
31614
31644
|
function getToken() {
|
|
31615
31645
|
if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
|
|
31616
31646
|
try {
|
|
31617
|
-
if (
|
|
31647
|
+
if (existsSync33(TOKEN_PATH)) return readFileSync22(TOKEN_PATH, "utf-8").trim();
|
|
31618
31648
|
} catch {
|
|
31619
31649
|
}
|
|
31620
31650
|
return null;
|
|
@@ -31713,10 +31743,10 @@ __export(service_exports2, {
|
|
|
31713
31743
|
serviceStatus: () => serviceStatus,
|
|
31714
31744
|
uninstallService: () => uninstallService
|
|
31715
31745
|
});
|
|
31716
|
-
import { existsSync as
|
|
31746
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, unlinkSync as unlinkSync8 } from "fs";
|
|
31717
31747
|
import { execFileSync as execFileSync4, execSync as execSync5 } from "child_process";
|
|
31718
31748
|
import { homedir as homedir10, platform } from "os";
|
|
31719
|
-
import { join as
|
|
31749
|
+
import { join as join36, dirname as dirname6 } from "path";
|
|
31720
31750
|
function xmlEscape(s) {
|
|
31721
31751
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
31722
31752
|
}
|
|
@@ -31725,7 +31755,7 @@ function resolveExecutable3(name) {
|
|
|
31725
31755
|
return execFileSync4("which", [name], { encoding: "utf-8" }).trim();
|
|
31726
31756
|
} catch {
|
|
31727
31757
|
const fallback = process.argv[1];
|
|
31728
|
-
if (fallback &&
|
|
31758
|
+
if (fallback && existsSync34(fallback)) return fallback;
|
|
31729
31759
|
throw new Error(`Cannot find '${name}' executable. Install globally: npm install -g cc-claw`);
|
|
31730
31760
|
}
|
|
31731
31761
|
}
|
|
@@ -31734,14 +31764,14 @@ function getPathDirs() {
|
|
|
31734
31764
|
const home = homedir10();
|
|
31735
31765
|
const dirs = /* @__PURE__ */ new Set([
|
|
31736
31766
|
nodeBin,
|
|
31737
|
-
|
|
31767
|
+
join36(home, ".local", "bin"),
|
|
31738
31768
|
"/usr/local/bin",
|
|
31739
31769
|
"/usr/bin",
|
|
31740
31770
|
"/bin"
|
|
31741
31771
|
]);
|
|
31742
31772
|
try {
|
|
31743
31773
|
const prefix = execSync5("npm config get prefix", { encoding: "utf-8" }).trim();
|
|
31744
|
-
if (prefix) dirs.add(
|
|
31774
|
+
if (prefix) dirs.add(join36(prefix, "bin"));
|
|
31745
31775
|
} catch {
|
|
31746
31776
|
}
|
|
31747
31777
|
return [...dirs].join(":");
|
|
@@ -31800,21 +31830,21 @@ function generatePlist() {
|
|
|
31800
31830
|
}
|
|
31801
31831
|
function installMacOS() {
|
|
31802
31832
|
const agentsDir = dirname6(PLIST_PATH);
|
|
31803
|
-
if (!
|
|
31804
|
-
if (!
|
|
31805
|
-
if (
|
|
31833
|
+
if (!existsSync34(agentsDir)) mkdirSync13(agentsDir, { recursive: true });
|
|
31834
|
+
if (!existsSync34(LOGS_PATH)) mkdirSync13(LOGS_PATH, { recursive: true });
|
|
31835
|
+
if (existsSync34(PLIST_PATH)) {
|
|
31806
31836
|
try {
|
|
31807
31837
|
execFileSync4("launchctl", ["unload", PLIST_PATH]);
|
|
31808
31838
|
} catch {
|
|
31809
31839
|
}
|
|
31810
31840
|
}
|
|
31811
|
-
|
|
31841
|
+
writeFileSync11(PLIST_PATH, generatePlist());
|
|
31812
31842
|
console.log(` Installed: ${PLIST_PATH}`);
|
|
31813
31843
|
execFileSync4("launchctl", ["load", PLIST_PATH]);
|
|
31814
31844
|
console.log(" Service loaded and starting.");
|
|
31815
31845
|
}
|
|
31816
31846
|
function uninstallMacOS() {
|
|
31817
|
-
if (!
|
|
31847
|
+
if (!existsSync34(PLIST_PATH)) {
|
|
31818
31848
|
console.log(" No service found to uninstall.");
|
|
31819
31849
|
return;
|
|
31820
31850
|
}
|
|
@@ -31889,9 +31919,9 @@ WantedBy=default.target
|
|
|
31889
31919
|
`;
|
|
31890
31920
|
}
|
|
31891
31921
|
function installLinux() {
|
|
31892
|
-
if (!
|
|
31893
|
-
if (!
|
|
31894
|
-
|
|
31922
|
+
if (!existsSync34(SYSTEMD_DIR)) mkdirSync13(SYSTEMD_DIR, { recursive: true });
|
|
31923
|
+
if (!existsSync34(LOGS_PATH)) mkdirSync13(LOGS_PATH, { recursive: true });
|
|
31924
|
+
writeFileSync11(UNIT_PATH, generateUnit());
|
|
31895
31925
|
console.log(` Installed: ${UNIT_PATH}`);
|
|
31896
31926
|
execFileSync4("systemctl", ["--user", "daemon-reload"]);
|
|
31897
31927
|
execFileSync4("systemctl", ["--user", "enable", "cc-claw"]);
|
|
@@ -31899,7 +31929,7 @@ function installLinux() {
|
|
|
31899
31929
|
console.log(" Service enabled and started.");
|
|
31900
31930
|
}
|
|
31901
31931
|
function uninstallLinux() {
|
|
31902
|
-
if (!
|
|
31932
|
+
if (!existsSync34(UNIT_PATH)) {
|
|
31903
31933
|
console.log(" No service found to uninstall.");
|
|
31904
31934
|
return;
|
|
31905
31935
|
}
|
|
@@ -31924,7 +31954,7 @@ function statusLinux() {
|
|
|
31924
31954
|
}
|
|
31925
31955
|
}
|
|
31926
31956
|
function installService() {
|
|
31927
|
-
if (!
|
|
31957
|
+
if (!existsSync34(join36(CC_CLAW_HOME, ".env"))) {
|
|
31928
31958
|
console.error(` Config not found at ${CC_CLAW_HOME}/.env`);
|
|
31929
31959
|
console.error(" Run 'cc-claw setup' before installing the service.");
|
|
31930
31960
|
process.exitCode = 1;
|
|
@@ -31953,9 +31983,9 @@ var init_service2 = __esm({
|
|
|
31953
31983
|
"use strict";
|
|
31954
31984
|
init_paths();
|
|
31955
31985
|
PLIST_LABEL = "com.cc-claw";
|
|
31956
|
-
PLIST_PATH =
|
|
31957
|
-
SYSTEMD_DIR =
|
|
31958
|
-
UNIT_PATH =
|
|
31986
|
+
PLIST_PATH = join36(homedir10(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
31987
|
+
SYSTEMD_DIR = join36(homedir10(), ".config", "systemd", "user");
|
|
31988
|
+
UNIT_PATH = join36(SYSTEMD_DIR, "cc-claw.service");
|
|
31959
31989
|
}
|
|
31960
31990
|
});
|
|
31961
31991
|
|
|
@@ -32122,13 +32152,13 @@ var init_daemon = __esm({
|
|
|
32122
32152
|
});
|
|
32123
32153
|
|
|
32124
32154
|
// src/cli/resolve-chat.ts
|
|
32125
|
-
import { readFileSync as
|
|
32155
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
32126
32156
|
function resolveChatId2(globalOpts) {
|
|
32127
32157
|
const explicit = globalOpts.chat;
|
|
32128
32158
|
if (explicit) return explicit;
|
|
32129
32159
|
if (_cachedDefault) return _cachedDefault;
|
|
32130
32160
|
try {
|
|
32131
|
-
const content =
|
|
32161
|
+
const content = readFileSync24(ENV_PATH, "utf-8");
|
|
32132
32162
|
const match = content.match(/^ALLOWED_CHAT_ID=(.+)$/m);
|
|
32133
32163
|
if (match) {
|
|
32134
32164
|
_cachedDefault = match[1].split(",")[0].trim();
|
|
@@ -32152,7 +32182,7 @@ var status_exports = {};
|
|
|
32152
32182
|
__export(status_exports, {
|
|
32153
32183
|
statusCommand: () => statusCommand
|
|
32154
32184
|
});
|
|
32155
|
-
import { existsSync as
|
|
32185
|
+
import { existsSync as existsSync35, statSync as statSync9 } from "fs";
|
|
32156
32186
|
async function statusCommand(globalOpts, localOpts) {
|
|
32157
32187
|
try {
|
|
32158
32188
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
@@ -32192,7 +32222,7 @@ async function statusCommand(globalOpts, localOpts) {
|
|
|
32192
32222
|
const cwdRow = readDb.prepare("SELECT cwd FROM chat_cwd WHERE chat_id = ?").get(chatId);
|
|
32193
32223
|
const voiceRow = readDb.prepare("SELECT enabled FROM chat_voice WHERE chat_id = ?").get(chatId);
|
|
32194
32224
|
const usageRow = readDb.prepare("SELECT * FROM chat_usage WHERE chat_id = ?").get(chatId);
|
|
32195
|
-
const dbStat =
|
|
32225
|
+
const dbStat = existsSync35(DB_PATH) ? statSync9(DB_PATH) : null;
|
|
32196
32226
|
let daemonRunning = false;
|
|
32197
32227
|
let daemonInfo = {};
|
|
32198
32228
|
try {
|
|
@@ -32304,13 +32334,13 @@ __export(doctor_exports, {
|
|
|
32304
32334
|
doctorCommand: () => doctorCommand,
|
|
32305
32335
|
doctorErrors: () => doctorErrors
|
|
32306
32336
|
});
|
|
32307
|
-
import { existsSync as
|
|
32337
|
+
import { existsSync as existsSync36, accessSync, constants } from "fs";
|
|
32308
32338
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
32309
32339
|
async function doctorCommand(globalOpts, localOpts) {
|
|
32310
32340
|
const checks = [];
|
|
32311
32341
|
const dbChecks = checkDatabase();
|
|
32312
32342
|
checks.push(...dbChecks);
|
|
32313
|
-
if (
|
|
32343
|
+
if (existsSync36(DB_PATH)) {
|
|
32314
32344
|
try {
|
|
32315
32345
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
32316
32346
|
const readDb = openDatabaseReadOnly2();
|
|
@@ -32336,7 +32366,7 @@ async function doctorCommand(globalOpts, localOpts) {
|
|
|
32336
32366
|
checks.push({ name: "Database health", status: "error", message: err.message });
|
|
32337
32367
|
}
|
|
32338
32368
|
}
|
|
32339
|
-
if (
|
|
32369
|
+
if (existsSync36(ENV_PATH)) {
|
|
32340
32370
|
checks.push({ name: "Environment", status: "ok", message: `.env loaded` });
|
|
32341
32371
|
} else {
|
|
32342
32372
|
checks.push({ name: "Environment", status: "error", message: "No .env found", fix: "cc-claw setup" });
|
|
@@ -32379,7 +32409,7 @@ async function doctorCommand(globalOpts, localOpts) {
|
|
|
32379
32409
|
} catch {
|
|
32380
32410
|
}
|
|
32381
32411
|
const tokenPath = `${DATA_PATH}/api-token`;
|
|
32382
|
-
if (
|
|
32412
|
+
if (existsSync36(tokenPath)) {
|
|
32383
32413
|
try {
|
|
32384
32414
|
accessSync(tokenPath, constants.R_OK);
|
|
32385
32415
|
checks.push({ name: "API token", status: "ok", message: "token file readable" });
|
|
@@ -32445,10 +32475,10 @@ async function doctorCommand(globalOpts, localOpts) {
|
|
|
32445
32475
|
const errorChecks = checks.filter(
|
|
32446
32476
|
(c) => ["Rate limits", "Content silence", "Spawn timeouts", "Other errors"].includes(c.name) && c.status !== "ok"
|
|
32447
32477
|
);
|
|
32448
|
-
if (errorChecks.length > 0 &&
|
|
32478
|
+
if (errorChecks.length > 0 && existsSync36(ERROR_LOG_PATH)) {
|
|
32449
32479
|
try {
|
|
32450
|
-
const { writeFileSync:
|
|
32451
|
-
|
|
32480
|
+
const { writeFileSync: writeFileSync15 } = await import("fs");
|
|
32481
|
+
writeFileSync15(ERROR_LOG_PATH, "");
|
|
32452
32482
|
for (const c of errorChecks) {
|
|
32453
32483
|
c.status = "ok";
|
|
32454
32484
|
c.message = "cleared (log truncated)";
|
|
@@ -32574,15 +32604,15 @@ var logs_exports = {};
|
|
|
32574
32604
|
__export(logs_exports, {
|
|
32575
32605
|
logsCommand: () => logsCommand
|
|
32576
32606
|
});
|
|
32577
|
-
import { existsSync as
|
|
32607
|
+
import { existsSync as existsSync37, readFileSync as readFileSync26, watchFile as watchFile2, unwatchFile as unwatchFile2 } from "fs";
|
|
32578
32608
|
async function logsCommand(opts) {
|
|
32579
32609
|
const logFile = opts.error ? ERROR_LOG_PATH : LOG_PATH;
|
|
32580
|
-
if (!
|
|
32610
|
+
if (!existsSync37(logFile)) {
|
|
32581
32611
|
outputError("LOG_NOT_FOUND", `Log file not found: ${logFile}`);
|
|
32582
32612
|
process.exit(1);
|
|
32583
32613
|
}
|
|
32584
32614
|
const maxLines = parseInt(opts.lines ?? "100", 10);
|
|
32585
|
-
const content =
|
|
32615
|
+
const content = readFileSync26(logFile, "utf-8");
|
|
32586
32616
|
const allLines = content.split("\n");
|
|
32587
32617
|
const tailLines = allLines.slice(-maxLines);
|
|
32588
32618
|
console.log(muted(` \u2500\u2500 ${logFile} (last ${tailLines.length} lines) \u2500\u2500`));
|
|
@@ -32592,7 +32622,7 @@ async function logsCommand(opts) {
|
|
|
32592
32622
|
let lastLength = content.length;
|
|
32593
32623
|
watchFile2(logFile, { interval: 500 }, () => {
|
|
32594
32624
|
try {
|
|
32595
|
-
const newContent =
|
|
32625
|
+
const newContent = readFileSync26(logFile, "utf-8");
|
|
32596
32626
|
if (newContent.length > lastLength) {
|
|
32597
32627
|
const newPart = newContent.slice(lastLength);
|
|
32598
32628
|
process.stdout.write(newPart);
|
|
@@ -32624,7 +32654,7 @@ __export(session_logs_exports, {
|
|
|
32624
32654
|
sessionLogsList: () => sessionLogsList,
|
|
32625
32655
|
sessionLogsTail: () => sessionLogsTail
|
|
32626
32656
|
});
|
|
32627
|
-
import { readFileSync as
|
|
32657
|
+
import { readFileSync as readFileSync27, watchFile as watchFile3, unwatchFile as unwatchFile3 } from "fs";
|
|
32628
32658
|
async function sessionLogsList(opts) {
|
|
32629
32659
|
const logs = listSessionLogs();
|
|
32630
32660
|
if (logs.length === 0) {
|
|
@@ -32681,12 +32711,12 @@ async function sessionLogsTail(opts) {
|
|
|
32681
32711
|
console.log(muted("\n Following... (Ctrl+C to stop)\n"));
|
|
32682
32712
|
let lastLength = 0;
|
|
32683
32713
|
try {
|
|
32684
|
-
lastLength =
|
|
32714
|
+
lastLength = readFileSync27(targetPath, "utf-8").length;
|
|
32685
32715
|
} catch {
|
|
32686
32716
|
}
|
|
32687
32717
|
watchFile3(targetPath, { interval: 500 }, () => {
|
|
32688
32718
|
try {
|
|
32689
|
-
const content =
|
|
32719
|
+
const content = readFileSync27(targetPath, "utf-8");
|
|
32690
32720
|
if (content.length > lastLength) {
|
|
32691
32721
|
process.stdout.write(content.slice(lastLength));
|
|
32692
32722
|
lastLength = content.length;
|
|
@@ -32730,11 +32760,11 @@ __export(gemini_exports, {
|
|
|
32730
32760
|
geminiReorder: () => geminiReorder,
|
|
32731
32761
|
geminiRotation: () => geminiRotation
|
|
32732
32762
|
});
|
|
32733
|
-
import { existsSync as
|
|
32734
|
-
import { join as
|
|
32763
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync14, writeFileSync as writeFileSync12, readFileSync as readFileSync28, chmodSync } from "fs";
|
|
32764
|
+
import { join as join37 } from "path";
|
|
32735
32765
|
import { createInterface as createInterface8 } from "readline";
|
|
32736
32766
|
function requireDb() {
|
|
32737
|
-
if (!
|
|
32767
|
+
if (!existsSync39(DB_PATH)) {
|
|
32738
32768
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
32739
32769
|
process.exit(1);
|
|
32740
32770
|
}
|
|
@@ -32759,9 +32789,9 @@ async function resolveSlotId(idOrLabel) {
|
|
|
32759
32789
|
function resolveOAuthEmail(configHome) {
|
|
32760
32790
|
if (!configHome) return null;
|
|
32761
32791
|
try {
|
|
32762
|
-
const accountsPath =
|
|
32763
|
-
if (!
|
|
32764
|
-
const accounts = JSON.parse(
|
|
32792
|
+
const accountsPath = join37(configHome, ".gemini", "google_accounts.json");
|
|
32793
|
+
if (!existsSync39(accountsPath)) return null;
|
|
32794
|
+
const accounts = JSON.parse(readFileSync28(accountsPath, "utf-8"));
|
|
32765
32795
|
return accounts.active || null;
|
|
32766
32796
|
} catch {
|
|
32767
32797
|
return null;
|
|
@@ -32843,14 +32873,14 @@ async function geminiAddKey(globalOpts, opts) {
|
|
|
32843
32873
|
}
|
|
32844
32874
|
async function geminiAddAccount(globalOpts, opts) {
|
|
32845
32875
|
await requireWriteDb();
|
|
32846
|
-
const slotsDir =
|
|
32847
|
-
if (!
|
|
32876
|
+
const slotsDir = join37(CC_CLAW_HOME, "gemini-slots");
|
|
32877
|
+
if (!existsSync39(slotsDir)) mkdirSync14(slotsDir, { recursive: true });
|
|
32848
32878
|
const { addGeminiSlot: addGeminiSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
32849
32879
|
const tempId = Date.now();
|
|
32850
|
-
const slotDir =
|
|
32880
|
+
const slotDir = join37(slotsDir, `slot-${tempId}`);
|
|
32851
32881
|
mkdirSync14(slotDir, { recursive: true, mode: 448 });
|
|
32852
|
-
mkdirSync14(
|
|
32853
|
-
|
|
32882
|
+
mkdirSync14(join37(slotDir, ".gemini"), { recursive: true });
|
|
32883
|
+
writeFileSync12(join37(slotDir, ".gemini", "settings.json"), JSON.stringify({
|
|
32854
32884
|
security: { auth: { selectedType: "oauth-personal" } }
|
|
32855
32885
|
}, null, 2));
|
|
32856
32886
|
console.log("");
|
|
@@ -32867,8 +32897,8 @@ async function geminiAddAccount(globalOpts, opts) {
|
|
|
32867
32897
|
});
|
|
32868
32898
|
} catch {
|
|
32869
32899
|
}
|
|
32870
|
-
const oauthPath =
|
|
32871
|
-
if (!
|
|
32900
|
+
const oauthPath = join37(slotDir, ".gemini", "oauth_creds.json");
|
|
32901
|
+
if (!existsSync39(oauthPath)) {
|
|
32872
32902
|
console.log(error2("\n No OAuth credentials found. Sign-in may have failed."));
|
|
32873
32903
|
console.log(" The slot directory is preserved at: " + slotDir);
|
|
32874
32904
|
console.log(" Re-run: cc-claw gemini add-account\n");
|
|
@@ -32876,7 +32906,7 @@ async function geminiAddAccount(globalOpts, opts) {
|
|
|
32876
32906
|
}
|
|
32877
32907
|
let accountEmail = "unknown";
|
|
32878
32908
|
try {
|
|
32879
|
-
const accounts = JSON.parse(__require("fs").readFileSync(
|
|
32909
|
+
const accounts = JSON.parse(__require("fs").readFileSync(join37(slotDir, ".gemini", "google_accounts.json"), "utf-8"));
|
|
32880
32910
|
accountEmail = accounts.active || accountEmail;
|
|
32881
32911
|
} catch {
|
|
32882
32912
|
}
|
|
@@ -32987,10 +33017,10 @@ async function geminiRelogin(globalOpts, idOrLabel) {
|
|
|
32987
33017
|
outputError("NO_CONFIG", `Slot "${idOrLabel}" has no config directory \u2014 cannot re-login.`);
|
|
32988
33018
|
return;
|
|
32989
33019
|
}
|
|
32990
|
-
const settingsPath =
|
|
32991
|
-
if (!
|
|
32992
|
-
mkdirSync14(
|
|
32993
|
-
|
|
33020
|
+
const settingsPath = join37(slot.configHome, ".gemini", "settings.json");
|
|
33021
|
+
if (!existsSync39(settingsPath)) {
|
|
33022
|
+
mkdirSync14(join37(slot.configHome, ".gemini"), { recursive: true });
|
|
33023
|
+
writeFileSync12(settingsPath, JSON.stringify({
|
|
32994
33024
|
security: { auth: { selectedType: "oauth-personal" } }
|
|
32995
33025
|
}, null, 2));
|
|
32996
33026
|
}
|
|
@@ -33013,8 +33043,8 @@ async function geminiRelogin(globalOpts, idOrLabel) {
|
|
|
33013
33043
|
});
|
|
33014
33044
|
} catch {
|
|
33015
33045
|
}
|
|
33016
|
-
const oauthPath =
|
|
33017
|
-
if (!
|
|
33046
|
+
const oauthPath = join37(slot.configHome, ".gemini", "oauth_creds.json");
|
|
33047
|
+
if (!existsSync39(oauthPath)) {
|
|
33018
33048
|
console.log(error2("\n Re-login failed \u2014 no OAuth credentials found."));
|
|
33019
33049
|
console.log(` Try again: cc-claw gemini re-login ${idOrLabel}
|
|
33020
33050
|
`);
|
|
@@ -33024,7 +33054,7 @@ async function geminiRelogin(globalOpts, idOrLabel) {
|
|
|
33024
33054
|
setGeminiSlotEnabled2(slotId, true);
|
|
33025
33055
|
let accountEmail = slot.label;
|
|
33026
33056
|
try {
|
|
33027
|
-
const accounts = JSON.parse(
|
|
33057
|
+
const accounts = JSON.parse(readFileSync28(join37(slot.configHome, ".gemini", "google_accounts.json"), "utf-8"));
|
|
33028
33058
|
if (accounts.active) accountEmail = accounts.active;
|
|
33029
33059
|
} catch {
|
|
33030
33060
|
}
|
|
@@ -33083,11 +33113,11 @@ __export(backend_cmd_factory_exports, {
|
|
|
33083
33113
|
makeReorder: () => makeReorder,
|
|
33084
33114
|
registerBackendSlotCommands: () => registerBackendSlotCommands
|
|
33085
33115
|
});
|
|
33086
|
-
import { existsSync as
|
|
33087
|
-
import { join as
|
|
33116
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync15, readFileSync as readFileSync29 } from "fs";
|
|
33117
|
+
import { join as join38 } from "path";
|
|
33088
33118
|
import { createInterface as createInterface9 } from "readline";
|
|
33089
33119
|
function requireDb2() {
|
|
33090
|
-
if (!
|
|
33120
|
+
if (!existsSync40(DB_PATH)) {
|
|
33091
33121
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
33092
33122
|
process.exit(1);
|
|
33093
33123
|
}
|
|
@@ -33176,10 +33206,10 @@ function makeAddAccount(backend2, displayName) {
|
|
|
33176
33206
|
process.exit(1);
|
|
33177
33207
|
}
|
|
33178
33208
|
await requireWriteDb2();
|
|
33179
|
-
const slotsDir =
|
|
33180
|
-
if (!
|
|
33209
|
+
const slotsDir = join38(CC_CLAW_HOME, config2.slotsSubdir);
|
|
33210
|
+
if (!existsSync40(slotsDir)) mkdirSync15(slotsDir, { recursive: true });
|
|
33181
33211
|
const tempId = Date.now();
|
|
33182
|
-
const slotDir =
|
|
33212
|
+
const slotDir = join38(slotsDir, `slot-${tempId}`);
|
|
33183
33213
|
mkdirSync15(slotDir, { recursive: true, mode: 448 });
|
|
33184
33214
|
if (config2.preSetup) config2.preSetup(slotDir);
|
|
33185
33215
|
console.log("");
|
|
@@ -33430,22 +33460,22 @@ var init_backend_cmd_factory = __esm({
|
|
|
33430
33460
|
envValue: (slotDir) => slotDir,
|
|
33431
33461
|
envOverrides: { ANTHROPIC_API_KEY: void 0 },
|
|
33432
33462
|
preSetup: (slotDir) => {
|
|
33433
|
-
mkdirSync15(
|
|
33463
|
+
mkdirSync15(join38(slotDir, ".claude"), { recursive: true });
|
|
33434
33464
|
},
|
|
33435
33465
|
verifyCredentials: (slotDir) => {
|
|
33436
|
-
const claudeJson =
|
|
33437
|
-
const claudeJsonNested =
|
|
33438
|
-
if (
|
|
33466
|
+
const claudeJson = join38(slotDir, ".claude.json");
|
|
33467
|
+
const claudeJsonNested = join38(slotDir, ".claude", ".claude.json");
|
|
33468
|
+
if (existsSync40(claudeJson)) {
|
|
33439
33469
|
try {
|
|
33440
|
-
const data = JSON.parse(
|
|
33470
|
+
const data = JSON.parse(readFileSync29(claudeJson, "utf-8"));
|
|
33441
33471
|
return Boolean(data.oauthAccount);
|
|
33442
33472
|
} catch {
|
|
33443
33473
|
return false;
|
|
33444
33474
|
}
|
|
33445
33475
|
}
|
|
33446
|
-
if (
|
|
33476
|
+
if (existsSync40(claudeJsonNested)) {
|
|
33447
33477
|
try {
|
|
33448
|
-
const data = JSON.parse(
|
|
33478
|
+
const data = JSON.parse(readFileSync29(claudeJsonNested, "utf-8"));
|
|
33449
33479
|
return Boolean(data.oauthAccount);
|
|
33450
33480
|
} catch {
|
|
33451
33481
|
return false;
|
|
@@ -33466,9 +33496,9 @@ var init_backend_cmd_factory = __esm({
|
|
|
33466
33496
|
} catch {
|
|
33467
33497
|
}
|
|
33468
33498
|
try {
|
|
33469
|
-
const claudeJson =
|
|
33470
|
-
if (
|
|
33471
|
-
const data = JSON.parse(
|
|
33499
|
+
const claudeJson = join38(slotDir, ".claude.json");
|
|
33500
|
+
if (existsSync40(claudeJson)) {
|
|
33501
|
+
const data = JSON.parse(readFileSync29(claudeJson, "utf-8"));
|
|
33472
33502
|
if (data.oauthAccount?.emailAddress) return data.oauthAccount.emailAddress;
|
|
33473
33503
|
}
|
|
33474
33504
|
} catch {
|
|
@@ -33483,11 +33513,11 @@ var init_backend_cmd_factory = __esm({
|
|
|
33483
33513
|
envValue: (slotDir) => slotDir,
|
|
33484
33514
|
envOverrides: { OPENAI_API_KEY: void 0 },
|
|
33485
33515
|
verifyCredentials: (slotDir) => {
|
|
33486
|
-
return
|
|
33516
|
+
return existsSync40(join38(slotDir, "auth.json"));
|
|
33487
33517
|
},
|
|
33488
33518
|
extractLabel: (slotDir) => {
|
|
33489
33519
|
try {
|
|
33490
|
-
const authData = JSON.parse(
|
|
33520
|
+
const authData = JSON.parse(readFileSync29(join38(slotDir, "auth.json"), "utf-8"));
|
|
33491
33521
|
if (authData.email) return authData.email;
|
|
33492
33522
|
if (authData.account_name) return authData.account_name;
|
|
33493
33523
|
if (authData.user?.email) return authData.user.email;
|
|
@@ -33511,9 +33541,9 @@ __export(ollama_exports3, {
|
|
|
33511
33541
|
ollamaRemove: () => ollamaRemove,
|
|
33512
33542
|
ollamaTest: () => ollamaTest
|
|
33513
33543
|
});
|
|
33514
|
-
import { existsSync as
|
|
33544
|
+
import { existsSync as existsSync41 } from "fs";
|
|
33515
33545
|
function requireDb3() {
|
|
33516
|
-
if (!
|
|
33546
|
+
if (!existsSync41(DB_PATH)) {
|
|
33517
33547
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
33518
33548
|
process.exit(1);
|
|
33519
33549
|
}
|
|
@@ -33772,12 +33802,12 @@ __export(backend_exports, {
|
|
|
33772
33802
|
backendList: () => backendList,
|
|
33773
33803
|
backendSet: () => backendSet
|
|
33774
33804
|
});
|
|
33775
|
-
import { existsSync as
|
|
33805
|
+
import { existsSync as existsSync42 } from "fs";
|
|
33776
33806
|
async function backendList(globalOpts) {
|
|
33777
33807
|
const { getAvailableAdapters: getAvailableAdapters3 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
|
|
33778
33808
|
const chatId = resolveChatId2(globalOpts);
|
|
33779
33809
|
let activeBackend = null;
|
|
33780
|
-
if (
|
|
33810
|
+
if (existsSync42(DB_PATH)) {
|
|
33781
33811
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
33782
33812
|
const readDb = openDatabaseReadOnly2();
|
|
33783
33813
|
try {
|
|
@@ -33808,7 +33838,7 @@ async function backendList(globalOpts) {
|
|
|
33808
33838
|
}
|
|
33809
33839
|
async function backendGet(globalOpts) {
|
|
33810
33840
|
const chatId = resolveChatId2(globalOpts);
|
|
33811
|
-
if (!
|
|
33841
|
+
if (!existsSync42(DB_PATH)) {
|
|
33812
33842
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
33813
33843
|
process.exit(1);
|
|
33814
33844
|
}
|
|
@@ -33852,13 +33882,13 @@ __export(model_exports, {
|
|
|
33852
33882
|
modelList: () => modelList,
|
|
33853
33883
|
modelSet: () => modelSet
|
|
33854
33884
|
});
|
|
33855
|
-
import { existsSync as
|
|
33885
|
+
import { existsSync as existsSync43 } from "fs";
|
|
33856
33886
|
async function modelList(globalOpts) {
|
|
33857
33887
|
const chatId = resolveChatId2(globalOpts);
|
|
33858
33888
|
const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
33859
33889
|
const { getAdapter: getAdapter4, getAllAdapters: getAllAdapters5 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
|
|
33860
33890
|
let backendId = "claude";
|
|
33861
|
-
if (
|
|
33891
|
+
if (existsSync43(DB_PATH)) {
|
|
33862
33892
|
const readDb = openDatabaseReadOnly2();
|
|
33863
33893
|
try {
|
|
33864
33894
|
const row = readDb.prepare("SELECT backend FROM chat_backend WHERE chat_id = ?").get(chatId);
|
|
@@ -33891,7 +33921,7 @@ async function modelList(globalOpts) {
|
|
|
33891
33921
|
}
|
|
33892
33922
|
async function modelGet(globalOpts) {
|
|
33893
33923
|
const chatId = resolveChatId2(globalOpts);
|
|
33894
|
-
if (!
|
|
33924
|
+
if (!existsSync43(DB_PATH)) {
|
|
33895
33925
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
33896
33926
|
process.exit(1);
|
|
33897
33927
|
}
|
|
@@ -33935,9 +33965,9 @@ __export(memory_exports2, {
|
|
|
33935
33965
|
memoryList: () => memoryList,
|
|
33936
33966
|
memorySearch: () => memorySearch
|
|
33937
33967
|
});
|
|
33938
|
-
import { existsSync as
|
|
33968
|
+
import { existsSync as existsSync44 } from "fs";
|
|
33939
33969
|
async function memoryList(globalOpts) {
|
|
33940
|
-
if (!
|
|
33970
|
+
if (!existsSync44(DB_PATH)) {
|
|
33941
33971
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
33942
33972
|
process.exit(1);
|
|
33943
33973
|
}
|
|
@@ -33961,7 +33991,7 @@ async function memoryList(globalOpts) {
|
|
|
33961
33991
|
});
|
|
33962
33992
|
}
|
|
33963
33993
|
async function memorySearch(globalOpts, query) {
|
|
33964
|
-
if (!
|
|
33994
|
+
if (!existsSync44(DB_PATH)) {
|
|
33965
33995
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
33966
33996
|
process.exit(1);
|
|
33967
33997
|
}
|
|
@@ -33983,7 +34013,7 @@ async function memorySearch(globalOpts, query) {
|
|
|
33983
34013
|
});
|
|
33984
34014
|
}
|
|
33985
34015
|
async function memoryHistory(globalOpts, opts) {
|
|
33986
|
-
if (!
|
|
34016
|
+
if (!existsSync44(DB_PATH)) {
|
|
33987
34017
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
33988
34018
|
process.exit(1);
|
|
33989
34019
|
}
|
|
@@ -34031,7 +34061,7 @@ __export(cron_exports2, {
|
|
|
34031
34061
|
cronList: () => cronList,
|
|
34032
34062
|
cronRuns: () => cronRuns
|
|
34033
34063
|
});
|
|
34034
|
-
import { existsSync as
|
|
34064
|
+
import { existsSync as existsSync45 } from "fs";
|
|
34035
34065
|
function parseFallbacks(raw) {
|
|
34036
34066
|
return raw.slice(0, 3).map((f) => {
|
|
34037
34067
|
const [backend2, ...rest] = f.split(":");
|
|
@@ -34052,7 +34082,7 @@ function parseAndValidateTimeout(raw) {
|
|
|
34052
34082
|
return val;
|
|
34053
34083
|
}
|
|
34054
34084
|
async function cronList(globalOpts) {
|
|
34055
|
-
if (!
|
|
34085
|
+
if (!existsSync45(DB_PATH)) {
|
|
34056
34086
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34057
34087
|
process.exit(1);
|
|
34058
34088
|
}
|
|
@@ -34090,7 +34120,7 @@ async function cronList(globalOpts) {
|
|
|
34090
34120
|
});
|
|
34091
34121
|
}
|
|
34092
34122
|
async function cronHealth(globalOpts) {
|
|
34093
|
-
if (!
|
|
34123
|
+
if (!existsSync45(DB_PATH)) {
|
|
34094
34124
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34095
34125
|
process.exit(1);
|
|
34096
34126
|
}
|
|
@@ -34274,7 +34304,7 @@ async function cronEdit(globalOpts, id, opts) {
|
|
|
34274
34304
|
}
|
|
34275
34305
|
}
|
|
34276
34306
|
async function cronRuns(globalOpts, jobId, opts) {
|
|
34277
|
-
if (!
|
|
34307
|
+
if (!existsSync45(DB_PATH)) {
|
|
34278
34308
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34279
34309
|
process.exit(1);
|
|
34280
34310
|
}
|
|
@@ -34321,9 +34351,9 @@ __export(agents_exports, {
|
|
|
34321
34351
|
runnersList: () => runnersList,
|
|
34322
34352
|
tasksList: () => tasksList
|
|
34323
34353
|
});
|
|
34324
|
-
import { existsSync as
|
|
34354
|
+
import { existsSync as existsSync46 } from "fs";
|
|
34325
34355
|
async function agentsList(globalOpts) {
|
|
34326
|
-
if (!
|
|
34356
|
+
if (!existsSync46(DB_PATH)) {
|
|
34327
34357
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34328
34358
|
process.exit(1);
|
|
34329
34359
|
}
|
|
@@ -34354,7 +34384,7 @@ async function agentsList(globalOpts) {
|
|
|
34354
34384
|
});
|
|
34355
34385
|
}
|
|
34356
34386
|
async function tasksList(globalOpts) {
|
|
34357
|
-
if (!
|
|
34387
|
+
if (!existsSync46(DB_PATH)) {
|
|
34358
34388
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34359
34389
|
process.exit(1);
|
|
34360
34390
|
}
|
|
@@ -34482,10 +34512,10 @@ __export(db_exports, {
|
|
|
34482
34512
|
dbPath: () => dbPath,
|
|
34483
34513
|
dbStats: () => dbStats
|
|
34484
34514
|
});
|
|
34485
|
-
import { existsSync as
|
|
34515
|
+
import { existsSync as existsSync47, statSync as statSync10, copyFileSync as copyFileSync4, mkdirSync as mkdirSync16 } from "fs";
|
|
34486
34516
|
import { dirname as dirname7 } from "path";
|
|
34487
34517
|
async function dbStats(globalOpts) {
|
|
34488
|
-
if (!
|
|
34518
|
+
if (!existsSync47(DB_PATH)) {
|
|
34489
34519
|
outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
|
|
34490
34520
|
process.exit(1);
|
|
34491
34521
|
}
|
|
@@ -34493,7 +34523,7 @@ async function dbStats(globalOpts) {
|
|
|
34493
34523
|
const readDb = openDatabaseReadOnly2();
|
|
34494
34524
|
const mainSize = statSync10(DB_PATH).size;
|
|
34495
34525
|
const walPath = DB_PATH + "-wal";
|
|
34496
|
-
const walSize =
|
|
34526
|
+
const walSize = existsSync47(walPath) ? statSync10(walPath).size : 0;
|
|
34497
34527
|
const tableNames = readDb.prepare(
|
|
34498
34528
|
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '%_fts%' ORDER BY name"
|
|
34499
34529
|
).all();
|
|
@@ -34527,7 +34557,7 @@ async function dbPath(globalOpts) {
|
|
|
34527
34557
|
output({ path: DB_PATH }, (d) => d.path);
|
|
34528
34558
|
}
|
|
34529
34559
|
async function dbBackup(globalOpts, destPath) {
|
|
34530
|
-
if (!
|
|
34560
|
+
if (!existsSync47(DB_PATH)) {
|
|
34531
34561
|
outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
|
|
34532
34562
|
process.exit(1);
|
|
34533
34563
|
}
|
|
@@ -34536,7 +34566,7 @@ async function dbBackup(globalOpts, destPath) {
|
|
|
34536
34566
|
mkdirSync16(dirname7(dest), { recursive: true });
|
|
34537
34567
|
copyFileSync4(DB_PATH, dest);
|
|
34538
34568
|
const walPath = DB_PATH + "-wal";
|
|
34539
|
-
if (
|
|
34569
|
+
if (existsSync47(walPath)) copyFileSync4(walPath, dest + "-wal");
|
|
34540
34570
|
output({ path: dest, sizeBytes: statSync10(dest).size }, (d) => {
|
|
34541
34571
|
const b = d;
|
|
34542
34572
|
return `
|
|
@@ -34565,9 +34595,9 @@ __export(usage_exports, {
|
|
|
34565
34595
|
usageCost: () => usageCost,
|
|
34566
34596
|
usageTokens: () => usageTokens
|
|
34567
34597
|
});
|
|
34568
|
-
import { existsSync as
|
|
34598
|
+
import { existsSync as existsSync48 } from "fs";
|
|
34569
34599
|
function ensureDb() {
|
|
34570
|
-
if (!
|
|
34600
|
+
if (!existsSync48(DB_PATH)) {
|
|
34571
34601
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
34572
34602
|
process.exit(1);
|
|
34573
34603
|
}
|
|
@@ -34757,9 +34787,9 @@ __export(config_exports2, {
|
|
|
34757
34787
|
configList: () => configList,
|
|
34758
34788
|
configSet: () => configSet
|
|
34759
34789
|
});
|
|
34760
|
-
import { existsSync as
|
|
34790
|
+
import { existsSync as existsSync49, readFileSync as readFileSync30 } from "fs";
|
|
34761
34791
|
async function configList(globalOpts) {
|
|
34762
|
-
if (!
|
|
34792
|
+
if (!existsSync49(DB_PATH)) {
|
|
34763
34793
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34764
34794
|
process.exit(1);
|
|
34765
34795
|
}
|
|
@@ -34793,7 +34823,7 @@ async function configGet(globalOpts, key) {
|
|
|
34793
34823
|
outputError("INVALID_KEY", `Unknown config key "${key}". Valid keys: ${RUNTIME_KEYS.join(", ")}`);
|
|
34794
34824
|
process.exit(1);
|
|
34795
34825
|
}
|
|
34796
|
-
if (!
|
|
34826
|
+
if (!existsSync49(DB_PATH)) {
|
|
34797
34827
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34798
34828
|
process.exit(1);
|
|
34799
34829
|
}
|
|
@@ -34839,11 +34869,11 @@ async function configSet(globalOpts, key, value) {
|
|
|
34839
34869
|
}
|
|
34840
34870
|
}
|
|
34841
34871
|
async function configEnv(_globalOpts) {
|
|
34842
|
-
if (!
|
|
34872
|
+
if (!existsSync49(ENV_PATH)) {
|
|
34843
34873
|
outputError("ENV_NOT_FOUND", `No .env file at ${ENV_PATH}. Run cc-claw setup.`);
|
|
34844
34874
|
process.exit(1);
|
|
34845
34875
|
}
|
|
34846
|
-
const content =
|
|
34876
|
+
const content = readFileSync30(ENV_PATH, "utf-8");
|
|
34847
34877
|
const entries = {};
|
|
34848
34878
|
const secretPatterns = /TOKEN|KEY|SECRET|PASSWORD|CREDENTIALS/i;
|
|
34849
34879
|
for (const line of content.split("\n")) {
|
|
@@ -34893,9 +34923,9 @@ __export(session_exports, {
|
|
|
34893
34923
|
sessionGet: () => sessionGet,
|
|
34894
34924
|
sessionNew: () => sessionNew
|
|
34895
34925
|
});
|
|
34896
|
-
import { existsSync as
|
|
34926
|
+
import { existsSync as existsSync50 } from "fs";
|
|
34897
34927
|
async function sessionGet(globalOpts) {
|
|
34898
|
-
if (!
|
|
34928
|
+
if (!existsSync50(DB_PATH)) {
|
|
34899
34929
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34900
34930
|
process.exit(1);
|
|
34901
34931
|
}
|
|
@@ -34956,9 +34986,9 @@ __export(permissions_exports, {
|
|
|
34956
34986
|
verboseGet: () => verboseGet,
|
|
34957
34987
|
verboseSet: () => verboseSet
|
|
34958
34988
|
});
|
|
34959
|
-
import { existsSync as
|
|
34989
|
+
import { existsSync as existsSync51 } from "fs";
|
|
34960
34990
|
function ensureDb2() {
|
|
34961
|
-
if (!
|
|
34991
|
+
if (!existsSync51(DB_PATH)) {
|
|
34962
34992
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
34963
34993
|
process.exit(1);
|
|
34964
34994
|
}
|
|
@@ -35105,9 +35135,9 @@ __export(cwd_exports, {
|
|
|
35105
35135
|
cwdGet: () => cwdGet,
|
|
35106
35136
|
cwdSet: () => cwdSet
|
|
35107
35137
|
});
|
|
35108
|
-
import { existsSync as
|
|
35138
|
+
import { existsSync as existsSync52 } from "fs";
|
|
35109
35139
|
async function cwdGet(globalOpts) {
|
|
35110
|
-
if (!
|
|
35140
|
+
if (!existsSync52(DB_PATH)) {
|
|
35111
35141
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35112
35142
|
process.exit(1);
|
|
35113
35143
|
}
|
|
@@ -35169,9 +35199,9 @@ __export(voice_exports, {
|
|
|
35169
35199
|
voiceGet: () => voiceGet,
|
|
35170
35200
|
voiceSet: () => voiceSet
|
|
35171
35201
|
});
|
|
35172
|
-
import { existsSync as
|
|
35202
|
+
import { existsSync as existsSync53 } from "fs";
|
|
35173
35203
|
async function voiceGet(globalOpts) {
|
|
35174
|
-
if (!
|
|
35204
|
+
if (!existsSync53(DB_PATH)) {
|
|
35175
35205
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35176
35206
|
process.exit(1);
|
|
35177
35207
|
}
|
|
@@ -35220,9 +35250,9 @@ __export(heartbeat_exports2, {
|
|
|
35220
35250
|
heartbeatGet: () => heartbeatGet,
|
|
35221
35251
|
heartbeatSet: () => heartbeatSet
|
|
35222
35252
|
});
|
|
35223
|
-
import { existsSync as
|
|
35253
|
+
import { existsSync as existsSync54 } from "fs";
|
|
35224
35254
|
async function heartbeatGet(globalOpts) {
|
|
35225
|
-
if (!
|
|
35255
|
+
if (!existsSync54(DB_PATH)) {
|
|
35226
35256
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35227
35257
|
process.exit(1);
|
|
35228
35258
|
}
|
|
@@ -35433,9 +35463,9 @@ __export(summarizer_exports, {
|
|
|
35433
35463
|
summarizerGet: () => summarizerGet,
|
|
35434
35464
|
summarizerSet: () => summarizerSet
|
|
35435
35465
|
});
|
|
35436
|
-
import { existsSync as
|
|
35466
|
+
import { existsSync as existsSync55 } from "fs";
|
|
35437
35467
|
async function summarizerGet(globalOpts) {
|
|
35438
|
-
if (!
|
|
35468
|
+
if (!existsSync55(DB_PATH)) {
|
|
35439
35469
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35440
35470
|
process.exit(1);
|
|
35441
35471
|
}
|
|
@@ -35479,9 +35509,9 @@ __export(thinking_exports, {
|
|
|
35479
35509
|
thinkingGet: () => thinkingGet,
|
|
35480
35510
|
thinkingSet: () => thinkingSet
|
|
35481
35511
|
});
|
|
35482
|
-
import { existsSync as
|
|
35512
|
+
import { existsSync as existsSync56 } from "fs";
|
|
35483
35513
|
async function thinkingGet(globalOpts) {
|
|
35484
|
-
if (!
|
|
35514
|
+
if (!existsSync56(DB_PATH)) {
|
|
35485
35515
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35486
35516
|
process.exit(1);
|
|
35487
35517
|
}
|
|
@@ -35525,9 +35555,9 @@ __export(chats_exports, {
|
|
|
35525
35555
|
chatsList: () => chatsList,
|
|
35526
35556
|
chatsRemoveAlias: () => chatsRemoveAlias
|
|
35527
35557
|
});
|
|
35528
|
-
import { existsSync as
|
|
35558
|
+
import { existsSync as existsSync57 } from "fs";
|
|
35529
35559
|
async function chatsList(_globalOpts) {
|
|
35530
|
-
if (!
|
|
35560
|
+
if (!existsSync57(DB_PATH)) {
|
|
35531
35561
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35532
35562
|
process.exit(1);
|
|
35533
35563
|
}
|
|
@@ -35655,9 +35685,9 @@ var mcps_exports2 = {};
|
|
|
35655
35685
|
__export(mcps_exports2, {
|
|
35656
35686
|
mcpsList: () => mcpsList
|
|
35657
35687
|
});
|
|
35658
|
-
import { existsSync as
|
|
35688
|
+
import { existsSync as existsSync58 } from "fs";
|
|
35659
35689
|
async function mcpsList(_globalOpts) {
|
|
35660
|
-
if (!
|
|
35690
|
+
if (!existsSync58(DB_PATH)) {
|
|
35661
35691
|
outputError("DB_NOT_FOUND", "Database not found.");
|
|
35662
35692
|
process.exit(1);
|
|
35663
35693
|
}
|
|
@@ -35694,11 +35724,11 @@ __export(chat_exports2, {
|
|
|
35694
35724
|
chatSend: () => chatSend
|
|
35695
35725
|
});
|
|
35696
35726
|
import { request as httpRequest2 } from "http";
|
|
35697
|
-
import { readFileSync as
|
|
35727
|
+
import { readFileSync as readFileSync31, existsSync as existsSync59 } from "fs";
|
|
35698
35728
|
function getToken2() {
|
|
35699
35729
|
if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
|
|
35700
35730
|
try {
|
|
35701
|
-
if (
|
|
35731
|
+
if (existsSync59(TOKEN_PATH2)) return readFileSync31(TOKEN_PATH2, "utf-8").trim();
|
|
35702
35732
|
} catch {
|
|
35703
35733
|
}
|
|
35704
35734
|
return null;
|
|
@@ -36185,8 +36215,8 @@ var completion_exports = {};
|
|
|
36185
36215
|
__export(completion_exports, {
|
|
36186
36216
|
completionCommand: () => completionCommand
|
|
36187
36217
|
});
|
|
36188
|
-
import { writeFileSync as
|
|
36189
|
-
import { join as
|
|
36218
|
+
import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync17 } from "fs";
|
|
36219
|
+
import { join as join39 } from "path";
|
|
36190
36220
|
import { homedir as homedir11 } from "os";
|
|
36191
36221
|
async function completionCommand(opts) {
|
|
36192
36222
|
const shell = opts.shell ?? detectShell();
|
|
@@ -36202,11 +36232,11 @@ async function completionCommand(opts) {
|
|
|
36202
36232
|
process.exit(1);
|
|
36203
36233
|
}
|
|
36204
36234
|
if (opts.install) {
|
|
36205
|
-
const dir =
|
|
36235
|
+
const dir = join39(homedir11(), ".config", "cc-claw", "completions");
|
|
36206
36236
|
mkdirSync17(dir, { recursive: true });
|
|
36207
36237
|
const filename = shell === "zsh" ? "_cc-claw" : shell === "fish" ? "cc-claw.fish" : "cc-claw.bash";
|
|
36208
|
-
const filepath =
|
|
36209
|
-
|
|
36238
|
+
const filepath = join39(dir, filename);
|
|
36239
|
+
writeFileSync13(filepath, script, "utf-8");
|
|
36210
36240
|
console.log(`\u2713 Completion script written to ${filepath}
|
|
36211
36241
|
`);
|
|
36212
36242
|
if (shell === "zsh") {
|
|
@@ -36378,9 +36408,9 @@ __export(evolve_exports2, {
|
|
|
36378
36408
|
evolveStatus: () => evolveStatus,
|
|
36379
36409
|
evolveUndo: () => evolveUndo
|
|
36380
36410
|
});
|
|
36381
|
-
import { existsSync as
|
|
36411
|
+
import { existsSync as existsSync60 } from "fs";
|
|
36382
36412
|
function ensureDb3() {
|
|
36383
|
-
if (!
|
|
36413
|
+
if (!existsSync60(DB_PATH)) {
|
|
36384
36414
|
outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
|
|
36385
36415
|
process.exit(1);
|
|
36386
36416
|
}
|
|
@@ -36854,10 +36884,10 @@ var init_optimize2 = __esm({
|
|
|
36854
36884
|
|
|
36855
36885
|
// src/setup.ts
|
|
36856
36886
|
var setup_exports = {};
|
|
36857
|
-
import { existsSync as
|
|
36887
|
+
import { existsSync as existsSync61, writeFileSync as writeFileSync14, readFileSync as readFileSync32, copyFileSync as copyFileSync5, mkdirSync as mkdirSync18, statSync as statSync11 } from "fs";
|
|
36858
36888
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
36859
36889
|
import { createInterface as createInterface11 } from "readline";
|
|
36860
|
-
import { join as
|
|
36890
|
+
import { join as join40 } from "path";
|
|
36861
36891
|
function divider2() {
|
|
36862
36892
|
console.log(dim("\u2500".repeat(55)));
|
|
36863
36893
|
}
|
|
@@ -36932,21 +36962,21 @@ async function setup() {
|
|
|
36932
36962
|
}
|
|
36933
36963
|
console.log("");
|
|
36934
36964
|
for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
|
|
36935
|
-
if (!
|
|
36965
|
+
if (!existsSync61(dir)) mkdirSync18(dir, { recursive: true });
|
|
36936
36966
|
}
|
|
36937
36967
|
const env = {};
|
|
36938
|
-
const envSource =
|
|
36968
|
+
const envSource = existsSync61(ENV_PATH) ? ENV_PATH : existsSync61(".env") ? ".env" : null;
|
|
36939
36969
|
if (envSource) {
|
|
36940
36970
|
console.log(yellow(` Found existing config at ${envSource} \u2014 your values will be preserved`));
|
|
36941
36971
|
console.log(yellow(" unless you enter new ones. Just press Enter to keep existing values.\n"));
|
|
36942
|
-
const existing =
|
|
36972
|
+
const existing = readFileSync32(envSource, "utf-8");
|
|
36943
36973
|
for (const line of existing.split("\n")) {
|
|
36944
36974
|
const match = line.match(/^([^#=]+)=(.*)$/);
|
|
36945
36975
|
if (match) env[match[1].trim()] = match[2].trim();
|
|
36946
36976
|
}
|
|
36947
36977
|
}
|
|
36948
|
-
const cwdDb =
|
|
36949
|
-
if (
|
|
36978
|
+
const cwdDb = join40(process.cwd(), "cc-claw.db");
|
|
36979
|
+
if (existsSync61(cwdDb) && !existsSync61(DB_PATH)) {
|
|
36950
36980
|
const { size } = statSync11(cwdDb);
|
|
36951
36981
|
console.log(yellow(` Found existing database at ${cwdDb} (${(size / 1024).toFixed(0)}KB)`));
|
|
36952
36982
|
const migrate = await confirm("Copy database to ~/.cc-claw/? (preserves memories & history)", true);
|
|
@@ -37193,7 +37223,7 @@ async function setup() {
|
|
|
37193
37223
|
envLines.push("", "# Video Analysis", `GEMINI_API_KEY=${env.GEMINI_API_KEY}`);
|
|
37194
37224
|
}
|
|
37195
37225
|
const envContent = envLines.join("\n") + "\n";
|
|
37196
|
-
|
|
37226
|
+
writeFileSync14(ENV_PATH, envContent, { mode: 384 });
|
|
37197
37227
|
console.log(green(` Config saved to ${ENV_PATH} (permissions: owner-only)`));
|
|
37198
37228
|
header(6, TOTAL_STEPS, "Run on Startup (Daemon)");
|
|
37199
37229
|
console.log(" CC-Claw can run automatically in the background, starting");
|