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