cc-claw 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +470 -168
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -72,7 +72,7 @@ var VERSION;
72
72
  var init_version = __esm({
73
73
  "src/version.ts"() {
74
74
  "use strict";
75
- VERSION = true ? "0.11.0" : (() => {
75
+ VERSION = true ? "0.11.2" : (() => {
76
76
  try {
77
77
  return JSON.parse(readFileSync(join2(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
78
78
  } catch {
@@ -703,6 +703,7 @@ __export(store_exports4, {
703
703
  setReflectionModelConfig: () => setReflectionModelConfig,
704
704
  setReflectionStatus: () => setReflectionStatus,
705
705
  updateInsightEffectiveness: () => updateInsightEffectiveness,
706
+ updateInsightProposal: () => updateInsightProposal,
706
707
  updateInsightRollback: () => updateInsightRollback,
707
708
  updateInsightStatus: () => updateInsightStatus,
708
709
  upsertGrowthMetric: () => upsertGrowthMetric
@@ -932,6 +933,11 @@ function updateInsightStatus(db3, id, status) {
932
933
  db3.prepare("UPDATE insights SET status = ? WHERE id = ?").run(status, id);
933
934
  }
934
935
  }
936
+ function updateInsightProposal(db3, id, targetFile, proposedDiff, proposedAction) {
937
+ db3.prepare(`
938
+ UPDATE insights SET targetFile = ?, proposedDiff = ?, proposedAction = ? WHERE id = ?
939
+ `).run(targetFile, proposedDiff ?? null, proposedAction ?? null, id);
940
+ }
935
941
  function updateInsightRollback(db3, id, rollbackData) {
936
942
  db3.prepare("UPDATE insights SET rollbackData = ? WHERE id = ?").run(rollbackData, id);
937
943
  }
@@ -1539,6 +1545,7 @@ function initDatabase() {
1539
1545
  cron TEXT,
1540
1546
  at_time TEXT,
1541
1547
  every_ms INTEGER,
1548
+ title TEXT,
1542
1549
  description TEXT NOT NULL,
1543
1550
  chat_id TEXT NOT NULL,
1544
1551
  backend TEXT,
@@ -1575,6 +1582,7 @@ function initDatabase() {
1575
1582
  cron TEXT,
1576
1583
  at_time TEXT,
1577
1584
  every_ms INTEGER,
1585
+ title TEXT,
1578
1586
  description TEXT NOT NULL,
1579
1587
  chat_id TEXT NOT NULL,
1580
1588
  backend TEXT,
@@ -1669,6 +1677,11 @@ function initDatabase() {
1669
1677
  db.exec("ALTER TABLE jobs ADD COLUMN fallbacks TEXT");
1670
1678
  } catch {
1671
1679
  }
1680
+ try {
1681
+ db.exec("ALTER TABLE jobs ADD COLUMN title TEXT");
1682
+ } catch {
1683
+ }
1684
+ backfillJobTitles(db);
1672
1685
  }
1673
1686
  } catch {
1674
1687
  }
@@ -2515,14 +2528,15 @@ function getBackendUsageInWindow(backend2, windowType) {
2515
2528
  }
2516
2529
  function insertJob(params) {
2517
2530
  const result = db.prepare(`
2518
- INSERT INTO jobs (schedule_type, cron, at_time, every_ms, description, chat_id,
2531
+ INSERT INTO jobs (schedule_type, cron, at_time, every_ms, title, description, chat_id,
2519
2532
  backend, model, thinking, timeout, fallbacks, session_type, channel, target, delivery_mode, timezone)
2520
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2533
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2521
2534
  `).run(
2522
2535
  params.scheduleType,
2523
2536
  params.cron ?? null,
2524
2537
  params.atTime ?? null,
2525
2538
  params.everyMs ?? null,
2539
+ params.title ?? null,
2526
2540
  params.description,
2527
2541
  params.chatId,
2528
2542
  params.backend ?? null,
@@ -2538,6 +2552,26 @@ function insertJob(params) {
2538
2552
  );
2539
2553
  return getJobById(Number(result.lastInsertRowid));
2540
2554
  }
2555
+ function backfillJobTitles(database) {
2556
+ const rows = database.prepare("SELECT id, description FROM jobs WHERE title IS NULL AND active = 1").all();
2557
+ if (rows.length === 0) return;
2558
+ const preamblePatterns = [
2559
+ /^you\s+must\s+call\s+the\s+\w+\s+tool\b[^.]*\.\s*/i,
2560
+ /^important:\s*[^.]*\.\s*/i,
2561
+ /^always\s+use\s+[^.]*\.\s*/i,
2562
+ /^note:\s*[^.]*\.\s*/i
2563
+ ];
2564
+ for (const row of rows) {
2565
+ let text = row.description;
2566
+ for (const pat of preamblePatterns) {
2567
+ text = text.replace(pat, "");
2568
+ }
2569
+ text = text.trim();
2570
+ const firstSentence = text.match(/^[^.!?\n]{5,60}[.!?]?/)?.[0] ?? text.slice(0, 60);
2571
+ const title = firstSentence.length > 60 ? firstSentence.slice(0, 57) + "\u2026" : firstSentence;
2572
+ database.prepare("UPDATE jobs SET title = ? WHERE id = ?").run(title, row.id);
2573
+ }
2574
+ }
2541
2575
  function mapJobRow(row) {
2542
2576
  if (!row) return void 0;
2543
2577
  row.fallbacks = row.fallbacks ? JSON.parse(row.fallbacks) : [];
@@ -2582,6 +2616,7 @@ function updateJob(id, fields) {
2582
2616
  cron: "cron",
2583
2617
  atTime: "at_time",
2584
2618
  everyMs: "every_ms",
2619
+ title: "title",
2585
2620
  description: "description",
2586
2621
  backend: "backend",
2587
2622
  model: "model",
@@ -3026,7 +3061,7 @@ var init_store5 = __esm({
3026
3061
  ALL_TOOLS = ["Read", "Glob", "Grep", "Bash", "Write", "Edit", "WebFetch", "WebSearch", "Agent", "AskUserQuestion"];
3027
3062
  JOB_SELECT = `
3028
3063
  SELECT id, schedule_type as scheduleType, cron, at_time as atTime, every_ms as everyMs,
3029
- description, chat_id as chatId, backend, model, thinking, timeout, fallbacks,
3064
+ title, description, chat_id as chatId, backend, model, thinking, timeout, fallbacks,
3030
3065
  session_type as sessionType, channel, target, delivery_mode as deliveryMode,
3031
3066
  timezone, enabled, active, created_at as createdAt, last_run_at as lastRunAt,
3032
3067
  next_run_at as nextRunAt, consecutive_failures as consecutiveFailures
@@ -6560,8 +6595,45 @@ __export(analyze_exports, {
6560
6595
  });
6561
6596
  import { spawn as spawn4 } from "child_process";
6562
6597
  import { createInterface as createInterface3 } from "readline";
6563
- import { readFileSync as readFileSync6 } from "fs";
6598
+ import { readFileSync as readFileSync6, existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
6564
6599
  import { join as join10 } from "path";
6600
+ import { homedir as homedir4 } from "os";
6601
+ function discoverReflectionTargets() {
6602
+ const ccClawHome = join10(homedir4(), ".cc-claw");
6603
+ const targets = [];
6604
+ try {
6605
+ const skillsDir = join10(ccClawHome, "workspace", "skills");
6606
+ if (existsSync11(skillsDir)) {
6607
+ for (const entry of readdirSync5(skillsDir)) {
6608
+ const entryPath = join10(skillsDir, entry);
6609
+ if (!statSync3(entryPath).isDirectory()) continue;
6610
+ const skillFile = join10(entryPath, "SKILL.md");
6611
+ if (!existsSync11(skillFile)) continue;
6612
+ let desc = "skill";
6613
+ try {
6614
+ const content = readFileSync6(skillFile, "utf-8").slice(0, 500);
6615
+ const descMatch = content.match(/description:\s*["']?([^"'\n]+)/);
6616
+ if (descMatch) desc = descMatch[1].trim().slice(0, 80);
6617
+ } catch {
6618
+ }
6619
+ targets.push({ path: `workspace/skills/${entry}/SKILL.md`, description: desc });
6620
+ }
6621
+ }
6622
+ } catch {
6623
+ }
6624
+ try {
6625
+ const contextDir = join10(ccClawHome, "workspace", "context");
6626
+ if (existsSync11(contextDir)) {
6627
+ for (const entry of readdirSync5(contextDir)) {
6628
+ if (!entry.endsWith(".md")) continue;
6629
+ const name = entry.replace(/\.md$/, "");
6630
+ targets.push({ path: `workspace/context/${entry}`, description: `context file: ${name}` });
6631
+ }
6632
+ }
6633
+ } catch {
6634
+ }
6635
+ return targets;
6636
+ }
6565
6637
  function buildAnalysisPrompt(params) {
6566
6638
  const {
6567
6639
  signals,
@@ -6621,7 +6693,31 @@ ${categoryList}`);
6621
6693
  sections.push(`- [#${ins.id}] (${ins.category}) ${ins.insight}`);
6622
6694
  }
6623
6695
  }
6624
- const targetOptions = codebaseEnabled ? "identity/SOUL.md | identity/USER.md | codebase" : "identity/SOUL.md | identity/USER.md";
6696
+ const { availableTargets } = params;
6697
+ const targetList = [
6698
+ "identity/SOUL.md \u2014 personality, tone, stable behavioral rules, communication style",
6699
+ "identity/USER.md \u2014 user preferences, personal info, timezone, language, profile"
6700
+ ];
6701
+ if (availableTargets) {
6702
+ for (const t of availableTargets) {
6703
+ targetList.push(`${t.path} \u2014 ${t.description}`);
6704
+ }
6705
+ }
6706
+ if (codebaseEnabled) {
6707
+ targetList.push("codebase \u2014 code-level recommendation (advisory only)");
6708
+ }
6709
+ sections.push(`[Target File Routing]
6710
+ Available targets:
6711
+ ${targetList.map((t) => `- ${t}`).join("\n")}
6712
+
6713
+ Choose the MOST SPECIFIC target for each insight:
6714
+ - Workflow or process improvements \u2192 the relevant skill file
6715
+ - Tool usage patterns or domain-specific steps \u2192 the relevant skill file
6716
+ - User preference or profile info \u2192 USER.md
6717
+ - Personality, tone, general behavior \u2192 SOUL.md
6718
+ - Domain knowledge or reference material \u2192 a context file
6719
+ - If no matching skill/context file exists, fall back to SOUL.md or USER.md`);
6720
+ const targetOptions = targetList.map((t) => t.split(" \u2014 ")[0]).join(" | ");
6625
6721
  sections.push(`[Output Format]
6626
6722
  For each insight, output EXACTLY this format. Separate multiple insights with "---" on its own line.
6627
6723
 
@@ -6817,6 +6913,7 @@ async function runAnalysis(chatId, opts = {}) {
6817
6913
  const applied = getAppliedInsights(db3, chatId);
6818
6914
  const rejected = getRejectedInsights(db3, chatId);
6819
6915
  const codebaseEnabled = process.env.REFLECTION_CODEBASE_RECOMMENDATIONS === "1";
6916
+ const availableTargets = discoverReflectionTargets();
6820
6917
  const prompt = buildAnalysisPrompt({
6821
6918
  signals: signals.map((s) => ({
6822
6919
  signalType: s.signalType,
@@ -6838,7 +6935,8 @@ async function runAnalysis(chatId, opts = {}) {
6838
6935
  insight: i.insight,
6839
6936
  category: i.category
6840
6937
  })),
6841
- codebaseEnabled
6938
+ codebaseEnabled,
6939
+ availableTargets
6842
6940
  });
6843
6941
  const resolved = resolveReflectionAdapter(chatId);
6844
6942
  if (!resolved) {
@@ -6942,7 +7040,7 @@ __export(apply_exports, {
6942
7040
  isTargetAllowed: () => isTargetAllowed,
6943
7041
  rollbackInsight: () => rollbackInsight
6944
7042
  });
6945
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync3 } from "fs";
7043
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync3 } from "fs";
6946
7044
  import { join as join11, dirname as dirname2 } from "path";
6947
7045
  function isTargetAllowed(relativePath) {
6948
7046
  if (relativePath.includes("..")) return false;
@@ -7010,7 +7108,7 @@ async function applyInsight(insightId) {
7010
7108
  }
7011
7109
  const absolutePath = join11(CC_CLAW_HOME, insight.targetFile);
7012
7110
  if (insight.proposedAction === "append" && insight.targetFile === "identity/SOUL.md") {
7013
- if (existsSync11(absolutePath)) {
7111
+ if (existsSync12(absolutePath)) {
7014
7112
  const currentContent = readFileSync7(absolutePath, "utf-8");
7015
7113
  const lineCount = currentContent.split("\n").length;
7016
7114
  if (lineCount >= SOUL_LINE_CAP) {
@@ -7030,7 +7128,7 @@ async function applyInsight(insightId) {
7030
7128
  };
7031
7129
  }
7032
7130
  let original = "";
7033
- if (existsSync11(absolutePath)) {
7131
+ if (existsSync12(absolutePath)) {
7034
7132
  original = readFileSync7(absolutePath, "utf-8");
7035
7133
  } else if (insight.proposedAction !== "create") {
7036
7134
  return { success: false, message: `Target file "${insight.targetFile}" does not exist` };
@@ -7039,7 +7137,7 @@ async function applyInsight(insightId) {
7039
7137
  const backupPath = absolutePath + `.bak.${timestamp}`;
7040
7138
  try {
7041
7139
  const parentDir = dirname2(absolutePath);
7042
- if (!existsSync11(parentDir)) {
7140
+ if (!existsSync12(parentDir)) {
7043
7141
  mkdirSync3(parentDir, { recursive: true });
7044
7142
  }
7045
7143
  if (original) {
@@ -7145,7 +7243,7 @@ function computeLineDrift(baseline, absolutePath) {
7145
7243
  if (!baseline) return 0;
7146
7244
  let current = "";
7147
7245
  try {
7148
- if (existsSync11(absolutePath)) {
7246
+ if (existsSync12(absolutePath)) {
7149
7247
  current = readFileSync7(absolutePath, "utf-8");
7150
7248
  }
7151
7249
  } catch {
@@ -7197,7 +7295,7 @@ __export(server_exports, {
7197
7295
  });
7198
7296
  import { createServer } from "http";
7199
7297
  import { randomBytes } from "crypto";
7200
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync12 } from "fs";
7298
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync13 } from "fs";
7201
7299
  function createSubAgentToken(agentId) {
7202
7300
  const token = `sub:${agentId.slice(0, 8)}:${randomBytes(16).toString("hex")}`;
7203
7301
  subAgentTokens.set(token, agentId);
@@ -7368,7 +7466,7 @@ function startDashboard() {
7368
7466
  if (url.pathname === "/api/orchestrator/spawn" && req.method === "POST") {
7369
7467
  try {
7370
7468
  const body = JSON.parse(await readBody(req));
7371
- if (body.cwd && !existsSync12(body.cwd)) {
7469
+ if (body.cwd && !existsSync13(body.cwd)) {
7372
7470
  return jsonResponse(res, { error: `Directory not found: ${body.cwd}` }, 400);
7373
7471
  }
7374
7472
  if (!body.permMode || body.permMode === "inherit") {
@@ -9668,18 +9766,18 @@ var init_wrap_backend = __esm({
9668
9766
  });
9669
9767
 
9670
9768
  // src/agents/runners/config-loader.ts
9671
- import { readFileSync as readFileSync8, readdirSync as readdirSync5, existsSync as existsSync13, mkdirSync as mkdirSync5, watchFile, unwatchFile } from "fs";
9769
+ import { readFileSync as readFileSync8, readdirSync as readdirSync6, existsSync as existsSync14, mkdirSync as mkdirSync5, watchFile, unwatchFile } from "fs";
9672
9770
  import { join as join13 } from "path";
9673
9771
  import { execFileSync } from "child_process";
9674
9772
  function resolveExecutable(config2) {
9675
- if (existsSync13(config2.executable)) return config2.executable;
9773
+ if (existsSync14(config2.executable)) return config2.executable;
9676
9774
  try {
9677
9775
  return execFileSync("which", [config2.executable], { encoding: "utf-8" }).trim();
9678
9776
  } catch {
9679
9777
  }
9680
9778
  for (const fallback of config2.executableFallbacks ?? []) {
9681
9779
  const resolved = fallback.replace(/^~/, process.env.HOME ?? "");
9682
- if (existsSync13(resolved)) return resolved;
9780
+ if (existsSync14(resolved)) return resolved;
9683
9781
  }
9684
9782
  return config2.executable;
9685
9783
  }
@@ -9818,11 +9916,11 @@ function loadRunnerConfig(filePath) {
9818
9916
  }
9819
9917
  }
9820
9918
  function loadAllRunnerConfigs() {
9821
- if (!existsSync13(RUNNERS_PATH)) {
9919
+ if (!existsSync14(RUNNERS_PATH)) {
9822
9920
  mkdirSync5(RUNNERS_PATH, { recursive: true });
9823
9921
  return [];
9824
9922
  }
9825
- const files = readdirSync5(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
9923
+ const files = readdirSync6(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
9826
9924
  const configs = [];
9827
9925
  for (const file of files) {
9828
9926
  const config2 = loadRunnerConfig(join13(RUNNERS_PATH, file));
@@ -9846,14 +9944,14 @@ function registerConfigRunners() {
9846
9944
  return count;
9847
9945
  }
9848
9946
  function watchRunnerConfigs(onChange) {
9849
- if (!existsSync13(RUNNERS_PATH)) return;
9947
+ if (!existsSync14(RUNNERS_PATH)) return;
9850
9948
  for (const prev of watchedFiles) {
9851
- if (!existsSync13(prev)) {
9949
+ if (!existsSync14(prev)) {
9852
9950
  unwatchFile(prev);
9853
9951
  watchedFiles.delete(prev);
9854
9952
  }
9855
9953
  }
9856
- const files = readdirSync5(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
9954
+ const files = readdirSync6(RUNNERS_PATH).filter((f) => f.endsWith(".json"));
9857
9955
  for (const file of files) {
9858
9956
  const fullPath = join13(RUNNERS_PATH, file);
9859
9957
  if (watchedFiles.has(fullPath)) continue;
@@ -10562,7 +10660,7 @@ __export(discover_exports, {
10562
10660
  });
10563
10661
  import { readdir, readFile as readFile2 } from "fs/promises";
10564
10662
  import { createHash } from "crypto";
10565
- import { homedir as homedir4 } from "os";
10663
+ import { homedir as homedir5 } from "os";
10566
10664
  import { join as join14 } from "path";
10567
10665
  function invalidateSkillCache() {
10568
10666
  cachedSkills = null;
@@ -10581,7 +10679,7 @@ async function discoverAllSkills() {
10581
10679
  const rawSkills = [];
10582
10680
  rawSkills.push(...await scanSkillDir(SKILLS_PATH, "cc-claw"));
10583
10681
  for (const backendId of getAllBackendIds()) {
10584
- const dirs = BACKEND_SKILL_DIRS[backendId] ?? [join14(homedir4(), `.${backendId}`, "skills")];
10682
+ const dirs = BACKEND_SKILL_DIRS[backendId] ?? [join14(homedir5(), `.${backendId}`, "skills")];
10585
10683
  for (const dir of dirs) {
10586
10684
  rawSkills.push(...await scanSkillDir(dir, backendId));
10587
10685
  }
@@ -10712,15 +10810,15 @@ var init_discover = __esm({
10712
10810
  init_backends();
10713
10811
  SKILL_FILE_CANDIDATES = ["SKILL.md", "skill.md"];
10714
10812
  BACKEND_SKILL_DIRS = {
10715
- claude: [join14(homedir4(), ".claude", "skills")],
10716
- gemini: [join14(homedir4(), ".gemini", "skills")],
10813
+ claude: [join14(homedir5(), ".claude", "skills")],
10814
+ gemini: [join14(homedir5(), ".gemini", "skills")],
10717
10815
  codex: [
10718
- join14(homedir4(), ".agents", "skills"),
10719
- join14(homedir4(), ".codex", "skills")
10816
+ join14(homedir5(), ".agents", "skills"),
10817
+ join14(homedir5(), ".codex", "skills")
10720
10818
  ],
10721
10819
  cursor: [
10722
- join14(homedir4(), ".cursor", "skills"),
10723
- join14(homedir4(), ".cursor", "skills-cursor")
10820
+ join14(homedir5(), ".cursor", "skills"),
10821
+ join14(homedir5(), ".cursor", "skills-cursor")
10724
10822
  ]
10725
10823
  };
10726
10824
  CACHE_TTL_MS2 = 3e5;
@@ -10736,7 +10834,7 @@ __export(install_exports, {
10736
10834
  installSkillFromGitHub: () => installSkillFromGitHub
10737
10835
  });
10738
10836
  import { mkdir, readdir as readdir2, readFile as readFile3, cp } from "fs/promises";
10739
- import { existsSync as existsSync14 } from "fs";
10837
+ import { existsSync as existsSync15 } from "fs";
10740
10838
  import { join as join15, basename } from "path";
10741
10839
  import { execSync as execSync6 } from "child_process";
10742
10840
  async function installSkillFromGitHub(urlOrShorthand) {
@@ -10755,7 +10853,7 @@ async function installSkillFromGitHub(urlOrShorthand) {
10755
10853
  stdio: "pipe",
10756
10854
  timeout: 3e4
10757
10855
  });
10758
- if (!existsSync14(join15(tmpDir, ".git"))) {
10856
+ if (!existsSync15(join15(tmpDir, ".git"))) {
10759
10857
  return { success: false, error: "Git clone failed: no .git directory produced" };
10760
10858
  }
10761
10859
  const searchRoot = subPath ? join15(tmpDir, subPath) : tmpDir;
@@ -10765,7 +10863,7 @@ async function installSkillFromGitHub(urlOrShorthand) {
10765
10863
  }
10766
10864
  const skillFolderName = basename(skillDir);
10767
10865
  const destDir = join15(SKILLS_PATH, skillFolderName);
10768
- if (existsSync14(destDir)) {
10866
+ if (existsSync15(destDir)) {
10769
10867
  log(`[skill-install] Overwriting existing skill at ${destDir}`);
10770
10868
  }
10771
10869
  await mkdir(destDir, { recursive: true });
@@ -10812,14 +10910,14 @@ function parseGitHubUrl(input) {
10812
10910
  async function findSkillDir(root) {
10813
10911
  const candidates = ["SKILL.md", "skill.md"];
10814
10912
  for (const c of candidates) {
10815
- if (existsSync14(join15(root, c))) return root;
10913
+ if (existsSync15(join15(root, c))) return root;
10816
10914
  }
10817
10915
  try {
10818
10916
  const entries = await readdir2(root, { withFileTypes: true });
10819
10917
  for (const entry of entries) {
10820
10918
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
10821
10919
  for (const c of candidates) {
10822
- if (existsSync14(join15(root, entry.name, c))) {
10920
+ if (existsSync15(join15(root, entry.name, c))) {
10823
10921
  return join15(root, entry.name);
10824
10922
  }
10825
10923
  }
@@ -10839,7 +10937,7 @@ async function findSkillDir(root) {
10839
10937
  for (const sub of subEntries) {
10840
10938
  if (!sub.isDirectory() || sub.name.startsWith(".")) continue;
10841
10939
  for (const c of candidates) {
10842
- if (existsSync14(join15(root, entry.name, sub.name, c))) {
10940
+ if (existsSync15(join15(root, entry.name, sub.name, c))) {
10843
10941
  return join15(root, entry.name, sub.name);
10844
10942
  }
10845
10943
  }
@@ -10858,7 +10956,7 @@ var init_install = __esm({
10858
10956
  });
10859
10957
 
10860
10958
  // src/bootstrap/profile.ts
10861
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as existsSync15 } from "fs";
10959
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as existsSync16 } from "fs";
10862
10960
  import { join as join16 } from "path";
10863
10961
  function hasActiveProfile(chatId) {
10864
10962
  return activeProfiles.has(chatId);
@@ -10988,7 +11086,7 @@ function extractUserUpdates(text) {
10988
11086
  return { cleanText, updates };
10989
11087
  }
10990
11088
  function appendToUserProfile(key, value) {
10991
- if (!existsSync15(USER_PATH2)) return;
11089
+ if (!existsSync16(USER_PATH2)) return;
10992
11090
  const content = readFileSync9(USER_PATH2, "utf-8");
10993
11091
  const line = `- **${key}**: ${value}`;
10994
11092
  if (content.includes(line)) return;
@@ -11010,7 +11108,7 @@ var init_profile = __esm({
11010
11108
  });
11011
11109
 
11012
11110
  // src/bootstrap/heartbeat.ts
11013
- import { readFileSync as readFileSync10, existsSync as existsSync16 } from "fs";
11111
+ import { readFileSync as readFileSync10, existsSync as existsSync17 } from "fs";
11014
11112
  import { join as join17 } from "path";
11015
11113
  function initHeartbeat(channelReg) {
11016
11114
  registry2 = channelReg;
@@ -11149,7 +11247,7 @@ ${healthLines.join("\n")}`);
11149
11247
  sections.push(`[Active watches]
11150
11248
  ${watchLines.join("\n")}`);
11151
11249
  }
11152
- if (existsSync16(HEARTBEAT_MD_PATH)) {
11250
+ if (existsSync17(HEARTBEAT_MD_PATH)) {
11153
11251
  try {
11154
11252
  const custom = readFileSync10(HEARTBEAT_MD_PATH, "utf-8").trim();
11155
11253
  if (custom) {
@@ -11380,7 +11478,7 @@ var init_classify = __esm({
11380
11478
  });
11381
11479
 
11382
11480
  // src/media/image-gen.ts
11383
- import { mkdirSync as mkdirSync6, existsSync as existsSync17 } from "fs";
11481
+ import { mkdirSync as mkdirSync6, existsSync as existsSync18 } from "fs";
11384
11482
  import { writeFile as writeFile2 } from "fs/promises";
11385
11483
  import { join as join18 } from "path";
11386
11484
  async function generateImage(prompt) {
@@ -11429,7 +11527,7 @@ async function generateImage(prompt) {
11429
11527
  if (!imageData) {
11430
11528
  throw new Error(textResponse ?? "Gemini did not generate an image. The prompt may have been filtered.");
11431
11529
  }
11432
- if (!existsSync17(IMAGE_OUTPUT_DIR)) {
11530
+ if (!existsSync18(IMAGE_OUTPUT_DIR)) {
11433
11531
  mkdirSync6(IMAGE_OUTPUT_DIR, { recursive: true });
11434
11532
  }
11435
11533
  const ext = mimeType.includes("jpeg") || mimeType.includes("jpg") ? "jpg" : "png";
@@ -12160,11 +12258,31 @@ async function finalizeJob(chatId, channel) {
12160
12258
  const pending = pendingJobs.get(chatId);
12161
12259
  if (!pending) return;
12162
12260
  const editJobId = pending._editJobId;
12261
+ let title = pending.title ?? null;
12262
+ if (!title && !editJobId) {
12263
+ try {
12264
+ const { askAgent: askAgent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
12265
+ const resp = await askAgent2(chatId, `Summarize this scheduled task in 5-8 words for a job list title. Output ONLY the title, nothing else:
12266
+
12267
+ ${pending.task}`, {
12268
+ bootstrapTier: "chat",
12269
+ maxTurns: 1,
12270
+ timeoutMs: 15e3
12271
+ });
12272
+ const generated = resp.text?.trim().replace(/^["']|["']$/g, "");
12273
+ if (generated && generated.length <= 60) title = generated;
12274
+ } catch {
12275
+ }
12276
+ if (!title) {
12277
+ title = pending.task.length > 60 ? pending.task.slice(0, 57) + "\u2026" : pending.task;
12278
+ }
12279
+ }
12163
12280
  const jobParams = {
12164
12281
  scheduleType: pending.scheduleType ?? "cron",
12165
12282
  cron: pending.cron,
12166
12283
  atTime: pending.at ?? null,
12167
12284
  everyMs: pending.everyMs ?? null,
12285
+ title,
12168
12286
  description: pending.task,
12169
12287
  backend: pending.backend ?? null,
12170
12288
  model: pending.model ?? null,
@@ -12188,6 +12306,7 @@ async function finalizeJob(chatId, channel) {
12188
12306
  chatId,
12189
12307
  `Job #${editJobId} updated!
12190
12308
 
12309
+ Title: ${jobParams.title ?? "\u2014"}
12191
12310
  Task: ${jobParams.description}
12192
12311
  Schedule: ${jobParams.cron ?? "N/A"}
12193
12312
  Timezone: ${jobParams.timezone}`,
@@ -12202,6 +12321,7 @@ Timezone: ${jobParams.timezone}`,
12202
12321
  chatId,
12203
12322
  `Job #${job.id} created!
12204
12323
 
12324
+ Title: ${job.title ?? "\u2014"}
12205
12325
  Task: ${job.description}
12206
12326
  Schedule: ${job.cron ?? "N/A"}
12207
12327
  Timezone: ${job.timezone}
@@ -12680,16 +12800,20 @@ function pct(ratio) {
12680
12800
  return `${Math.round(ratio * 100)}%`;
12681
12801
  }
12682
12802
  function formatProposalCard(params) {
12683
- const { category, insight, why, targetFile, confidence } = params;
12803
+ const { category, insight, why, targetFile, confidence, proposedAction, proposedDiff } = params;
12684
12804
  const header2 = `[${category}] ${insight}`;
12685
- const whyLine = `Why: ${why}`;
12805
+ const whyLine = why ? `Why: ${why}` : null;
12686
12806
  const confidencePct = pct(confidence);
12687
12807
  const showTarget = category !== "codebase" && targetFile && targetFile !== "codebase";
12688
12808
  const targetLine = showTarget ? `Target: ${targetFile} | Confidence: ${confidencePct}` : `Confidence: ${confidencePct}`;
12689
- return `${header2}
12690
-
12691
- ${whyLine}
12692
- ${targetLine}`;
12809
+ const lines = [header2, ""];
12810
+ if (whyLine) lines.push(whyLine);
12811
+ lines.push(targetLine);
12812
+ if (proposedDiff) {
12813
+ const actionLabel = proposedAction ? ` (${proposedAction})` : "";
12814
+ lines.push("", `Proposed change${actionLabel}:`, "```diff", proposedDiff, "```");
12815
+ }
12816
+ return lines.join("\n");
12693
12817
  }
12694
12818
  function formatNightlySummary(insights) {
12695
12819
  const count = insights.length;
@@ -12734,7 +12858,7 @@ function buildProposalKeyboard(insightId, category) {
12734
12858
  return [
12735
12859
  [
12736
12860
  { label: "Show Diff", data: `evolve:diff:${insightId}`, style: "primary" },
12737
- { label: "Skip", data: `evolve:skip:${insightId}` },
12861
+ { label: "Discuss", data: `evolve:discuss:${insightId}` },
12738
12862
  { label: "Reject", data: `evolve:reject:${insightId}`, style: "danger" }
12739
12863
  ]
12740
12864
  ];
@@ -12742,7 +12866,7 @@ function buildProposalKeyboard(insightId, category) {
12742
12866
  return [
12743
12867
  [
12744
12868
  { label: "Apply", data: `evolve:apply:${insightId}`, style: "success" },
12745
- { label: "Skip", data: `evolve:skip:${insightId}` },
12869
+ { label: "Discuss", data: `evolve:discuss:${insightId}` },
12746
12870
  { label: "Reject", data: `evolve:reject:${insightId}`, style: "danger" }
12747
12871
  ]
12748
12872
  ];
@@ -12798,8 +12922,10 @@ var init_propose = __esm({
12798
12922
 
12799
12923
  // src/router.ts
12800
12924
  import { readFile as readFile5, writeFile as writeFile3, unlink as unlink2, mkdir as mkdir2, readdir as readdir3, stat } from "fs/promises";
12925
+ import { existsSync as existsSync19 } from "fs";
12801
12926
  import { randomUUID as randomUUID3 } from "crypto";
12802
12927
  import { resolve as resolvePath, join as join19 } from "path";
12928
+ import { homedir as homedir6 } from "os";
12803
12929
  function parseMcpListOutput(output2) {
12804
12930
  const results = [];
12805
12931
  const seen = /* @__PURE__ */ new Set();
@@ -14517,8 +14643,8 @@ ${agentLines.join("\n")}`, buttons);
14517
14643
  lines.push(` \u2705 <b>cc-claw</b> <i>Agent orchestrator (spawn, tasks, inbox)</i>`);
14518
14644
  }
14519
14645
  const { execFile: execFile5 } = await import("child_process");
14520
- const { homedir: homedir7 } = await import("os");
14521
- const discoveryCwd = homedir7();
14646
+ const { homedir: homedir9 } = await import("os");
14647
+ const discoveryCwd = homedir9();
14522
14648
  const runnerResults = await Promise.allSettled(
14523
14649
  getAllRunners().map((runner) => {
14524
14650
  const listCmd = runner.getMcpListCommand();
@@ -15702,7 +15828,7 @@ async function sendJobsBoard(chatId, channel, page) {
15702
15828
  pageSize: 10,
15703
15829
  callbackPrefix: "job:",
15704
15830
  renderItem: (j) => ({
15705
- label: `#${j.id}: ${j.description.slice(0, 30)}`,
15831
+ label: `#${j.id}: ${(j.title ?? j.description).slice(0, 30)}`,
15706
15832
  data: `job:view:${j.id}`,
15707
15833
  style: "primary"
15708
15834
  }),
@@ -15712,7 +15838,7 @@ async function sendJobsBoard(chatId, channel, page) {
15712
15838
  for (const j of pageJobs) {
15713
15839
  const emoji = getJobStatusEmoji(j);
15714
15840
  const schedule2 = getJobScheduleText(j);
15715
- const desc = j.description.length > 24 ? j.description.slice(0, 24) + "\u2026" : j.description;
15841
+ const desc = j.title ?? (j.description.length > 24 ? j.description.slice(0, 24) + "\u2026" : j.description);
15716
15842
  lines.push(`${emoji} ${desc} \xB7 ${schedule2}`);
15717
15843
  }
15718
15844
  lines.push("");
@@ -15747,8 +15873,9 @@ async function sendJobDetail(chatId, jobId, channel) {
15747
15873
  const runs = getJobRuns(jobId, 1);
15748
15874
  const lastRunStatus = runs.length > 0 ? runs[0].status : null;
15749
15875
  const lines = [
15750
- `Job #${job.id}: ${job.description}`,
15876
+ `Job #${job.id}: ${job.title ?? job.description}`,
15751
15877
  buildSectionHeader("", 22),
15878
+ ...job.title ? [`Task: ${job.description.length > 80 ? job.description.slice(0, 77) + "\u2026" : job.description}`] : [],
15752
15879
  `Runs: ${schedule2}${tz}`,
15753
15880
  `Backend: ${backend2} | Model: ${model2}`,
15754
15881
  `Last run: ${lastRun}${lastRunStatus ? ` (${lastRunStatus})` : ""}`,
@@ -15855,7 +15982,7 @@ async function sendJobPicker(chatId, channel, action) {
15855
15982
  const actionLabel = action.charAt(0).toUpperCase() + action.slice(1);
15856
15983
  const style = action === "run" ? "success" : action === "cancel" ? "danger" : void 0;
15857
15984
  const buttons = jobs.map((j) => [{
15858
- label: `#${j.id}: ${j.description.slice(0, 30)}`,
15985
+ label: `#${j.id}: ${(j.title ?? j.description).slice(0, 30)}`,
15859
15986
  data: action === "cancel" ? `job:cancel:${j.id}` : `job:${action}:${j.id}`,
15860
15987
  ...style ? { style } : {}
15861
15988
  }]);
@@ -16464,7 +16591,8 @@ Result: ${task.result.slice(0, 500)}` : ""
16464
16591
  if (insights.length === 0) {
16465
16592
  await channel.sendText(chatId, "No new insights from recent interactions.", { parseMode: "plain" });
16466
16593
  } else {
16467
- await channel.sendText(chatId, formatNightlySummary2(insights), { parseMode: "plain" });
16594
+ const nightlyItems = insights.map((ins, i) => ({ id: i + 1, ...ins }));
16595
+ await channel.sendText(chatId, formatNightlySummary2(nightlyItems), { parseMode: "plain" });
16468
16596
  }
16469
16597
  } catch (e) {
16470
16598
  await channel.sendText(chatId, `Analysis failed: ${e}`, { parseMode: "plain" });
@@ -16510,6 +16638,164 @@ Result: ${task.result.slice(0, 500)}` : ""
16510
16638
  await channel.sendText(chatId, "Skipped \u2014 will show again next review.", { parseMode: "plain" });
16511
16639
  break;
16512
16640
  }
16641
+ case "discuss": {
16642
+ const insId = parseInt(idStr, 10);
16643
+ await channel.sendKeyboard(chatId, [
16644
+ "What would you like to do with this proposal?",
16645
+ "",
16646
+ "Why this file? \u2014 ask the AI to explain its reasoning",
16647
+ "Retarget \u2014 move this change to a different file (e.g., a skill instead of SOUL.md)",
16648
+ "Revise \u2014 ask the AI to rewrite the proposed change"
16649
+ ].join("\n"), [
16650
+ [
16651
+ { label: "Why this file?", data: `evolve:discuss-why:${insId}`, style: "primary" },
16652
+ { label: "Retarget", data: `evolve:discuss-retarget:${insId}` }
16653
+ ],
16654
+ [
16655
+ { label: "Revise the change", data: `evolve:discuss-revise:${insId}` },
16656
+ { label: "Back", data: `evolve:discuss-back:${insId}` }
16657
+ ]
16658
+ ]);
16659
+ break;
16660
+ }
16661
+ case "discuss-why": {
16662
+ const { getInsightById: gwIns } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16663
+ const { getDb: gwDb } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16664
+ const gwInsight = gwIns(gwDb(), parseInt(idStr, 10));
16665
+ if (!gwInsight) {
16666
+ await channel.sendText(chatId, "Proposal not found.", { parseMode: "plain" });
16667
+ break;
16668
+ }
16669
+ await channel.sendTyping?.(chatId);
16670
+ const whyPrompt = [
16671
+ `Explain in 2-3 sentences why you chose "${gwInsight.targetFile}" as the target file for this insight:`,
16672
+ `"${gwInsight.insight}"`,
16673
+ `Consider what other files could work (skills, context files, USER.md) and explain your reasoning.`
16674
+ ].join("\n");
16675
+ try {
16676
+ const whyResp = await askAgent(chatId, whyPrompt, { bootstrapTier: "chat", maxTurns: 1, timeoutMs: 6e4 });
16677
+ await channel.sendText(chatId, whyResp.text ?? "No response.");
16678
+ } catch (e) {
16679
+ await channel.sendText(chatId, `Error: ${e.message}`, { parseMode: "plain" });
16680
+ }
16681
+ await channel.sendKeyboard(chatId, "What next?", [
16682
+ [
16683
+ { label: "OK, Apply", data: `evolve:apply:${idStr}`, style: "success" },
16684
+ { label: "Retarget instead", data: `evolve:discuss-retarget:${idStr}` }
16685
+ ],
16686
+ [
16687
+ { label: "Reject", data: `evolve:reject:${idStr}`, style: "danger" },
16688
+ { label: "Back", data: `evolve:discuss-back:${idStr}` }
16689
+ ]
16690
+ ]);
16691
+ break;
16692
+ }
16693
+ case "discuss-retarget": {
16694
+ const { getInsightById: rtIns } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16695
+ const { getDb: rtDb } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16696
+ const rtInsight = rtIns(rtDb(), parseInt(idStr, 10));
16697
+ if (!rtInsight) {
16698
+ await channel.sendText(chatId, "Proposal not found.", { parseMode: "plain" });
16699
+ break;
16700
+ }
16701
+ const currentTarget = rtInsight.targetFile ?? "unknown";
16702
+ const targets = [
16703
+ { label: "SOUL.md", path: "identity/SOUL.md" },
16704
+ { label: "USER.md", path: "identity/USER.md" }
16705
+ ];
16706
+ const skillDirs = [
16707
+ join19(homedir6(), ".cc-claw", "workspace", "skills")
16708
+ ];
16709
+ try {
16710
+ const { readdirSync: readdirSync7, statSync: statSync9 } = await import("fs");
16711
+ for (const dir of skillDirs) {
16712
+ if (!existsSync19(dir)) continue;
16713
+ for (const entry of readdirSync7(dir)) {
16714
+ if (statSync9(join19(dir, entry)).isDirectory()) {
16715
+ targets.push({ label: `skills/${entry}`, path: `workspace/skills/${entry}/SKILL.md` });
16716
+ }
16717
+ }
16718
+ }
16719
+ } catch {
16720
+ }
16721
+ const rows = targets.filter((t) => t.path !== currentTarget).map((t) => [{ label: t.label, data: `evolve:discuss-retarget-to:${idStr}:${t.path}` }]);
16722
+ rows.push([{ label: "Cancel", data: `evolve:discuss-back:${idStr}` }]);
16723
+ await channel.sendKeyboard(chatId, `Current target: ${currentTarget}
16724
+
16725
+ Pick a different file for this change. Identity files (SOUL/USER) shape personality; skills teach specific workflows.`, rows);
16726
+ break;
16727
+ }
16728
+ case "discuss-retarget-to": {
16729
+ const retargetParts = data.split(":");
16730
+ const rtId = parseInt(retargetParts[2], 10);
16731
+ const newPath = retargetParts.slice(3).join(":");
16732
+ const { getInsightById: rt2Ins, updateInsightProposal: rt2Update } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16733
+ const { formatProposalCard: rt2Card, buildProposalKeyboard: rt2Kb } = await Promise.resolve().then(() => (init_propose(), propose_exports));
16734
+ const { getDb: rt2Db } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16735
+ const rt2Insight = rt2Ins(rt2Db(), rtId);
16736
+ if (!rt2Insight) {
16737
+ await channel.sendText(chatId, "Proposal not found.", { parseMode: "plain" });
16738
+ break;
16739
+ }
16740
+ rt2Update(rt2Db(), rtId, newPath, rt2Insight.proposedDiff, rt2Insight.proposedAction);
16741
+ const updatedIns = rt2Ins(rt2Db(), rtId);
16742
+ if (updatedIns) {
16743
+ const card = rt2Card(updatedIns);
16744
+ const kb = rt2Kb(updatedIns.id, updatedIns.category);
16745
+ await channel.sendKeyboard(chatId, `Retargeted to ${newPath}. Updated proposal:
16746
+
16747
+ ` + card, kb);
16748
+ }
16749
+ break;
16750
+ }
16751
+ case "discuss-revise": {
16752
+ const { getInsightById: rvIns } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16753
+ const { getDb: rvDb } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16754
+ const rvInsight = rvIns(rvDb(), parseInt(idStr, 10));
16755
+ if (!rvInsight) {
16756
+ await channel.sendText(chatId, "Proposal not found.", { parseMode: "plain" });
16757
+ break;
16758
+ }
16759
+ await channel.sendTyping?.(chatId);
16760
+ const revisePrompt = [
16761
+ `Revise this proposed change to be more specific and actionable:`,
16762
+ `Current insight: "${rvInsight.insight}"`,
16763
+ `Current diff: ${rvInsight.proposedDiff ?? "none"}`,
16764
+ `Target: ${rvInsight.targetFile}`,
16765
+ ``,
16766
+ `Output ONLY the revised diff lines (starting with + for additions, - for removals). No explanation.`
16767
+ ].join("\n");
16768
+ try {
16769
+ const rvResp = await askAgent(chatId, revisePrompt, { bootstrapTier: "chat", maxTurns: 1, timeoutMs: 6e4 });
16770
+ const newDiff = rvResp.text?.trim() ?? rvInsight.proposedDiff;
16771
+ if (newDiff) {
16772
+ const { updateInsightProposal: rvUpdate } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16773
+ rvUpdate(rvDb(), parseInt(idStr, 10), rvInsight.targetFile ?? "", newDiff, rvInsight.proposedAction);
16774
+ }
16775
+ const updatedRv = rvIns(rvDb(), parseInt(idStr, 10));
16776
+ if (updatedRv) {
16777
+ const { formatProposalCard: rvCard, buildProposalKeyboard: rvKb } = await Promise.resolve().then(() => (init_propose(), propose_exports));
16778
+ const card = rvCard(updatedRv);
16779
+ const kb = rvKb(updatedRv.id, updatedRv.category);
16780
+ await channel.sendKeyboard(chatId, "Revised proposal:\n\n" + card, kb);
16781
+ }
16782
+ } catch (e) {
16783
+ await channel.sendText(chatId, `Revision error: ${e.message}`, { parseMode: "plain" });
16784
+ }
16785
+ break;
16786
+ }
16787
+ case "discuss-back": {
16788
+ const { getInsightById: bkIns } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16789
+ const { formatProposalCard: bkCard, buildProposalKeyboard: bkKb } = await Promise.resolve().then(() => (init_propose(), propose_exports));
16790
+ const { getDb: bkDb } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16791
+ const bkInsight = bkIns(bkDb(), parseInt(idStr, 10));
16792
+ if (bkInsight && bkInsight.status === "pending") {
16793
+ const card = bkCard(bkInsight);
16794
+ const kb = bkKb(bkInsight.id, bkInsight.category);
16795
+ await channel.sendKeyboard(chatId, card, kb);
16796
+ }
16797
+ break;
16798
+ }
16513
16799
  case "reject": {
16514
16800
  const { updateInsightStatus: updateInsightStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
16515
16801
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
@@ -16524,7 +16810,18 @@ Result: ${task.result.slice(0, 500)}` : ""
16524
16810
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16525
16811
  const reportData = buildGrowthReportData2(getDb2(), chatId, 30);
16526
16812
  const modelData = buildModelPerformanceData2(getDb2(), chatId, 30);
16527
- let report = formatGrowthReport2(reportData, modelData);
16813
+ const metricsForReport = {
16814
+ correctionsBefore: reportData.avgCorrectionsFirstHalf,
16815
+ correctionsAfter: reportData.avgCorrectionsSecondHalf,
16816
+ praiseRatio: reportData.praiseRatio,
16817
+ insightsApplied: reportData.totalInsightsApplied,
16818
+ pendingCount: reportData.pendingCount,
16819
+ topInsight: reportData.topInsightId != null ? {
16820
+ insight: `#${reportData.topInsightId}`,
16821
+ effectiveness: reportData.topInsightEffectiveness ?? 0
16822
+ } : null
16823
+ };
16824
+ let report = formatGrowthReport2(metricsForReport, modelData);
16528
16825
  const drift = calculateDrift2(chatId);
16529
16826
  if (drift && (drift.soulDrift > 0.5 || drift.userDrift > 0.5)) {
16530
16827
  report += "\n\nSOUL.md has changed significantly since reflection started.\nTap History in /evolve to review all applied changes.";
@@ -16557,19 +16854,19 @@ Result: ${task.result.slice(0, 500)}` : ""
16557
16854
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
16558
16855
  const current = getReflectionStatus2(getDb2(), chatId);
16559
16856
  if (current === "frozen") {
16560
- const { readFileSync: readFileSync21, existsSync: existsSync45 } = await import("fs");
16857
+ const { readFileSync: readFileSync21, existsSync: existsSync47 } = await import("fs");
16561
16858
  const { join: join26 } = await import("path");
16562
16859
  const { CC_CLAW_HOME: CC_CLAW_HOME3 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
16563
16860
  const soulPath = join26(CC_CLAW_HOME3, "identity/SOUL.md");
16564
16861
  const userPath = join26(CC_CLAW_HOME3, "identity/USER.md");
16565
- const soul = existsSync45(soulPath) ? readFileSync21(soulPath, "utf-8") : "";
16566
- const user = existsSync45(userPath) ? readFileSync21(userPath, "utf-8") : "";
16862
+ const soul = existsSync47(soulPath) ? readFileSync21(soulPath, "utf-8") : "";
16863
+ const user = existsSync47(userPath) ? readFileSync21(userPath, "utf-8") : "";
16567
16864
  setReflectionStatus2(getDb2(), chatId, "active", soul, user);
16568
16865
  const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
16569
16866
  logActivity2(getDb2(), { chatId, source: "telegram", eventType: "reflection_unfrozen", summary: "Reflection enabled" });
16570
16867
  await channel.sendText(chatId, "\u2705 Self-learning enabled. Signal detection is now active.\nCreate a nightly cron job with /schedule to enable automatic analysis.", { parseMode: "plain" });
16571
16868
  } else {
16572
- setReflectionStatus2(getDb2(), chatId, "frozen", null, null);
16869
+ setReflectionStatus2(getDb2(), chatId, "frozen", void 0, void 0);
16573
16870
  const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
16574
16871
  logActivity2(getDb2(), { chatId, source: "telegram", eventType: "reflection_frozen", summary: "Reflection disabled" });
16575
16872
  await channel.sendText(chatId, "\u26D4 Self-learning disabled. No signals will be collected.", { parseMode: "plain" });
@@ -17397,19 +17694,19 @@ var init_router = __esm({
17397
17694
  });
17398
17695
 
17399
17696
  // src/skills/bootstrap.ts
17400
- import { existsSync as existsSync18 } from "fs";
17697
+ import { existsSync as existsSync20 } from "fs";
17401
17698
  import { readdir as readdir4, readFile as readFile6, writeFile as writeFile4, copyFile } from "fs/promises";
17402
17699
  import { join as join20, dirname as dirname3 } from "path";
17403
17700
  import { fileURLToPath as fileURLToPath2 } from "url";
17404
17701
  async function copyAgentManifestSkills() {
17405
- if (!existsSync18(PKG_SKILLS)) return;
17702
+ if (!existsSync20(PKG_SKILLS)) return;
17406
17703
  try {
17407
17704
  const entries = await readdir4(PKG_SKILLS, { withFileTypes: true });
17408
17705
  for (const entry of entries) {
17409
17706
  if (!entry.isFile() || !entry.name.startsWith("agent-") || !entry.name.endsWith(".md")) continue;
17410
17707
  const src = join20(PKG_SKILLS, entry.name);
17411
17708
  const dest = join20(SKILLS_PATH, entry.name);
17412
- if (existsSync18(dest)) continue;
17709
+ if (existsSync20(dest)) continue;
17413
17710
  await copyFile(src, dest);
17414
17711
  log(`[skills] Bootstrapped ${entry.name} to ${SKILLS_PATH}`);
17415
17712
  }
@@ -17420,7 +17717,7 @@ async function copyAgentManifestSkills() {
17420
17717
  async function bootstrapSkills() {
17421
17718
  await copyAgentManifestSkills();
17422
17719
  const usmDir = join20(SKILLS_PATH, USM_DIR_NAME);
17423
- if (existsSync18(usmDir)) return;
17720
+ if (existsSync20(usmDir)) return;
17424
17721
  try {
17425
17722
  const entries = await readdir4(SKILLS_PATH);
17426
17723
  const dirs = entries.filter((e) => !e.startsWith("."));
@@ -17443,7 +17740,7 @@ async function bootstrapSkills() {
17443
17740
  }
17444
17741
  async function patchUsmForCcClaw(usmDir) {
17445
17742
  const skillPath = join20(usmDir, "SKILL.md");
17446
- if (!existsSync18(skillPath)) return;
17743
+ if (!existsSync20(skillPath)) return;
17447
17744
  try {
17448
17745
  let content = await readFile6(skillPath, "utf-8");
17449
17746
  let patched = false;
@@ -17703,13 +18000,13 @@ __export(ai_skill_exports, {
17703
18000
  generateAiSkill: () => generateAiSkill,
17704
18001
  installAiSkill: () => installAiSkill
17705
18002
  });
17706
- import { existsSync as existsSync19, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7 } from "fs";
18003
+ import { existsSync as existsSync21, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7 } from "fs";
17707
18004
  import { join as join21 } from "path";
17708
- import { homedir as homedir5 } from "os";
18005
+ import { homedir as homedir7 } from "os";
17709
18006
  function generateAiSkill() {
17710
18007
  const version = VERSION;
17711
18008
  let systemState = "";
17712
- if (existsSync19(DB_PATH)) {
18009
+ if (existsSync21(DB_PATH)) {
17713
18010
  try {
17714
18011
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = (init_store5(), __toCommonJS(store_exports5));
17715
18012
  const readDb = openDatabaseReadOnly2();
@@ -18125,11 +18422,11 @@ var init_ai_skill = __esm({
18125
18422
  init_paths();
18126
18423
  init_version();
18127
18424
  BACKEND_SKILL_DIRS2 = {
18128
- "cc-claw": [join21(homedir5(), ".cc-claw", "workspace", "skills")],
18129
- claude: [join21(homedir5(), ".claude", "skills")],
18130
- gemini: [join21(homedir5(), ".gemini", "skills")],
18131
- codex: [join21(homedir5(), ".agents", "skills")],
18132
- cursor: [join21(homedir5(), ".cursor", "skills"), join21(homedir5(), ".cursor", "skills-cursor")]
18425
+ "cc-claw": [join21(homedir7(), ".cc-claw", "workspace", "skills")],
18426
+ claude: [join21(homedir7(), ".claude", "skills")],
18427
+ gemini: [join21(homedir7(), ".gemini", "skills")],
18428
+ codex: [join21(homedir7(), ".agents", "skills")],
18429
+ cursor: [join21(homedir7(), ".cursor", "skills"), join21(homedir7(), ".cursor", "skills-cursor")]
18133
18430
  };
18134
18431
  }
18135
18432
  });
@@ -18139,7 +18436,7 @@ var index_exports = {};
18139
18436
  __export(index_exports, {
18140
18437
  main: () => main
18141
18438
  });
18142
- import { mkdirSync as mkdirSync8, existsSync as existsSync20, renameSync, statSync as statSync3, readFileSync as readFileSync12 } from "fs";
18439
+ import { mkdirSync as mkdirSync8, existsSync as existsSync22, renameSync, statSync as statSync4, readFileSync as readFileSync12 } from "fs";
18143
18440
  import { join as join22 } from "path";
18144
18441
  import dotenv from "dotenv";
18145
18442
  function migrateLayout() {
@@ -18153,7 +18450,7 @@ function migrateLayout() {
18153
18450
  [join22(CC_CLAW_HOME, "cc-claw.error.log.1"), join22(LOGS_PATH, "cc-claw.error.log.1")]
18154
18451
  ];
18155
18452
  for (const [from, to] of moves) {
18156
- if (existsSync20(from) && !existsSync20(to)) {
18453
+ if (existsSync22(from) && !existsSync22(to)) {
18157
18454
  try {
18158
18455
  renameSync(from, to);
18159
18456
  } catch {
@@ -18164,7 +18461,7 @@ function migrateLayout() {
18164
18461
  function rotateLogs() {
18165
18462
  for (const file of [LOG_PATH, ERROR_LOG_PATH]) {
18166
18463
  try {
18167
- const { size } = statSync3(file);
18464
+ const { size } = statSync4(file);
18168
18465
  if (size > LOG_MAX_BYTES) {
18169
18466
  const archivePath = `${file}.1`;
18170
18467
  try {
@@ -18360,10 +18657,10 @@ var init_index = __esm({
18360
18657
  init_bootstrap2();
18361
18658
  init_health3();
18362
18659
  for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
18363
- if (!existsSync20(dir)) mkdirSync8(dir, { recursive: true });
18660
+ if (!existsSync22(dir)) mkdirSync8(dir, { recursive: true });
18364
18661
  }
18365
18662
  migrateLayout();
18366
- if (existsSync20(ENV_PATH)) {
18663
+ if (existsSync22(ENV_PATH)) {
18367
18664
  dotenv.config({ path: ENV_PATH });
18368
18665
  } else {
18369
18666
  console.error(`[cc-claw] Config not found at ${ENV_PATH} \u2014 run 'cc-claw setup' first`);
@@ -18384,12 +18681,12 @@ __export(api_client_exports, {
18384
18681
  apiPost: () => apiPost,
18385
18682
  isDaemonRunning: () => isDaemonRunning
18386
18683
  });
18387
- import { readFileSync as readFileSync13, existsSync as existsSync21 } from "fs";
18684
+ import { readFileSync as readFileSync13, existsSync as existsSync23 } from "fs";
18388
18685
  import { request as httpRequest } from "http";
18389
18686
  function getToken() {
18390
18687
  if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
18391
18688
  try {
18392
- if (existsSync21(TOKEN_PATH)) return readFileSync13(TOKEN_PATH, "utf-8").trim();
18689
+ if (existsSync23(TOKEN_PATH)) return readFileSync13(TOKEN_PATH, "utf-8").trim();
18393
18690
  } catch {
18394
18691
  }
18395
18692
  return null;
@@ -18484,9 +18781,9 @@ __export(service_exports, {
18484
18781
  serviceStatus: () => serviceStatus,
18485
18782
  uninstallService: () => uninstallService
18486
18783
  });
18487
- import { existsSync as existsSync22, mkdirSync as mkdirSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4 } from "fs";
18784
+ import { existsSync as existsSync24, mkdirSync as mkdirSync9, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4 } from "fs";
18488
18785
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
18489
- import { homedir as homedir6, platform } from "os";
18786
+ import { homedir as homedir8, platform } from "os";
18490
18787
  import { join as join23, dirname as dirname4 } from "path";
18491
18788
  function resolveExecutable2(name) {
18492
18789
  try {
@@ -18497,7 +18794,7 @@ function resolveExecutable2(name) {
18497
18794
  }
18498
18795
  function getPathDirs() {
18499
18796
  const nodeBin = dirname4(process.execPath);
18500
- const home = homedir6();
18797
+ const home = homedir8();
18501
18798
  const dirs = /* @__PURE__ */ new Set([
18502
18799
  nodeBin,
18503
18800
  join23(home, ".local", "bin"),
@@ -18515,7 +18812,7 @@ function getPathDirs() {
18515
18812
  function generatePlist() {
18516
18813
  const ccClawBin = resolveExecutable2("cc-claw");
18517
18814
  const pathDirs = getPathDirs();
18518
- const home = homedir6();
18815
+ const home = homedir8();
18519
18816
  return `<?xml version="1.0" encoding="UTF-8"?>
18520
18817
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
18521
18818
  <plist version="1.0">
@@ -18559,9 +18856,9 @@ function generatePlist() {
18559
18856
  }
18560
18857
  function installMacOS() {
18561
18858
  const agentsDir = dirname4(PLIST_PATH);
18562
- if (!existsSync22(agentsDir)) mkdirSync9(agentsDir, { recursive: true });
18563
- if (!existsSync22(LOGS_PATH)) mkdirSync9(LOGS_PATH, { recursive: true });
18564
- if (existsSync22(PLIST_PATH)) {
18859
+ if (!existsSync24(agentsDir)) mkdirSync9(agentsDir, { recursive: true });
18860
+ if (!existsSync24(LOGS_PATH)) mkdirSync9(LOGS_PATH, { recursive: true });
18861
+ if (existsSync24(PLIST_PATH)) {
18565
18862
  try {
18566
18863
  execFileSync2("launchctl", ["unload", PLIST_PATH]);
18567
18864
  } catch {
@@ -18573,7 +18870,7 @@ function installMacOS() {
18573
18870
  console.log(" Service loaded and starting.");
18574
18871
  }
18575
18872
  function uninstallMacOS() {
18576
- if (!existsSync22(PLIST_PATH)) {
18873
+ if (!existsSync24(PLIST_PATH)) {
18577
18874
  console.log(" No service found to uninstall.");
18578
18875
  return;
18579
18876
  }
@@ -18640,15 +18937,15 @@ Restart=on-failure
18640
18937
  RestartSec=10
18641
18938
  WorkingDirectory=${CC_CLAW_HOME}
18642
18939
  Environment=PATH=${pathDirs}
18643
- Environment=HOME=${homedir6()}
18940
+ Environment=HOME=${homedir8()}
18644
18941
 
18645
18942
  [Install]
18646
18943
  WantedBy=default.target
18647
18944
  `;
18648
18945
  }
18649
18946
  function installLinux() {
18650
- if (!existsSync22(SYSTEMD_DIR)) mkdirSync9(SYSTEMD_DIR, { recursive: true });
18651
- if (!existsSync22(LOGS_PATH)) mkdirSync9(LOGS_PATH, { recursive: true });
18947
+ if (!existsSync24(SYSTEMD_DIR)) mkdirSync9(SYSTEMD_DIR, { recursive: true });
18948
+ if (!existsSync24(LOGS_PATH)) mkdirSync9(LOGS_PATH, { recursive: true });
18652
18949
  writeFileSync7(UNIT_PATH, generateUnit());
18653
18950
  console.log(` Installed: ${UNIT_PATH}`);
18654
18951
  execFileSync2("systemctl", ["--user", "daemon-reload"]);
@@ -18657,7 +18954,7 @@ function installLinux() {
18657
18954
  console.log(" Service enabled and started.");
18658
18955
  }
18659
18956
  function uninstallLinux() {
18660
- if (!existsSync22(UNIT_PATH)) {
18957
+ if (!existsSync24(UNIT_PATH)) {
18661
18958
  console.log(" No service found to uninstall.");
18662
18959
  return;
18663
18960
  }
@@ -18682,7 +18979,7 @@ function statusLinux() {
18682
18979
  }
18683
18980
  }
18684
18981
  function installService() {
18685
- if (!existsSync22(join23(CC_CLAW_HOME, ".env"))) {
18982
+ if (!existsSync24(join23(CC_CLAW_HOME, ".env"))) {
18686
18983
  console.error(` Config not found at ${CC_CLAW_HOME}/.env`);
18687
18984
  console.error(" Run 'cc-claw setup' before installing the service.");
18688
18985
  process.exitCode = 1;
@@ -18711,8 +19008,8 @@ var init_service = __esm({
18711
19008
  "use strict";
18712
19009
  init_paths();
18713
19010
  PLIST_LABEL = "com.cc-claw";
18714
- PLIST_PATH = join23(homedir6(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
18715
- SYSTEMD_DIR = join23(homedir6(), ".config", "systemd", "user");
19011
+ PLIST_PATH = join23(homedir8(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
19012
+ SYSTEMD_DIR = join23(homedir8(), ".config", "systemd", "user");
18716
19013
  UNIT_PATH = join23(SYSTEMD_DIR, "cc-claw.service");
18717
19014
  }
18718
19015
  });
@@ -18910,7 +19207,7 @@ var status_exports = {};
18910
19207
  __export(status_exports, {
18911
19208
  statusCommand: () => statusCommand
18912
19209
  });
18913
- import { existsSync as existsSync23, statSync as statSync4 } from "fs";
19210
+ import { existsSync as existsSync25, statSync as statSync5 } from "fs";
18914
19211
  async function statusCommand(globalOpts, localOpts) {
18915
19212
  try {
18916
19213
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
@@ -18950,7 +19247,7 @@ async function statusCommand(globalOpts, localOpts) {
18950
19247
  const cwdRow = readDb.prepare("SELECT cwd FROM chat_cwd WHERE chat_id = ?").get(chatId);
18951
19248
  const voiceRow = readDb.prepare("SELECT enabled FROM chat_voice WHERE chat_id = ?").get(chatId);
18952
19249
  const usageRow = readDb.prepare("SELECT * FROM chat_usage WHERE chat_id = ?").get(chatId);
18953
- const dbStat = existsSync23(DB_PATH) ? statSync4(DB_PATH) : null;
19250
+ const dbStat = existsSync25(DB_PATH) ? statSync5(DB_PATH) : null;
18954
19251
  let daemonRunning = false;
18955
19252
  let daemonInfo = {};
18956
19253
  if (localOpts.deep) {
@@ -19041,12 +19338,12 @@ var doctor_exports = {};
19041
19338
  __export(doctor_exports, {
19042
19339
  doctorCommand: () => doctorCommand
19043
19340
  });
19044
- import { existsSync as existsSync24, statSync as statSync5, accessSync, constants } from "fs";
19341
+ import { existsSync as existsSync26, statSync as statSync6, accessSync, constants } from "fs";
19045
19342
  import { execFileSync as execFileSync3 } from "child_process";
19046
19343
  async function doctorCommand(globalOpts, localOpts) {
19047
19344
  const checks = [];
19048
- if (existsSync24(DB_PATH)) {
19049
- const size = statSync5(DB_PATH).size;
19345
+ if (existsSync26(DB_PATH)) {
19346
+ const size = statSync6(DB_PATH).size;
19050
19347
  checks.push({ name: "Database", status: "ok", message: `${DB_PATH} (${(size / 1024).toFixed(0)}KB)` });
19051
19348
  try {
19052
19349
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
@@ -19075,7 +19372,7 @@ async function doctorCommand(globalOpts, localOpts) {
19075
19372
  } else {
19076
19373
  checks.push({ name: "Database", status: "error", message: `Not found at ${DB_PATH}`, fix: "cc-claw setup" });
19077
19374
  }
19078
- if (existsSync24(ENV_PATH)) {
19375
+ if (existsSync26(ENV_PATH)) {
19079
19376
  checks.push({ name: "Environment", status: "ok", message: `.env loaded` });
19080
19377
  } else {
19081
19378
  checks.push({ name: "Environment", status: "error", message: "No .env found", fix: "cc-claw setup" });
@@ -19119,7 +19416,7 @@ async function doctorCommand(globalOpts, localOpts) {
19119
19416
  checks.push({ name: "Daemon", status: "warning", message: "could not probe" });
19120
19417
  }
19121
19418
  const tokenPath = `${DATA_PATH}/api-token`;
19122
- if (existsSync24(tokenPath)) {
19419
+ if (existsSync26(tokenPath)) {
19123
19420
  try {
19124
19421
  accessSync(tokenPath, constants.R_OK);
19125
19422
  checks.push({ name: "API token", status: "ok", message: "token file readable" });
@@ -19144,7 +19441,7 @@ async function doctorCommand(globalOpts, localOpts) {
19144
19441
  }
19145
19442
  } catch {
19146
19443
  }
19147
- if (existsSync24(ERROR_LOG_PATH)) {
19444
+ if (existsSync26(ERROR_LOG_PATH)) {
19148
19445
  try {
19149
19446
  const { readFileSync: readFileSync21 } = await import("fs");
19150
19447
  const logContent = readFileSync21(ERROR_LOG_PATH, "utf-8");
@@ -19270,10 +19567,10 @@ var logs_exports = {};
19270
19567
  __export(logs_exports, {
19271
19568
  logsCommand: () => logsCommand
19272
19569
  });
19273
- import { existsSync as existsSync25, readFileSync as readFileSync16, watchFile as watchFile2, unwatchFile as unwatchFile2 } from "fs";
19570
+ import { existsSync as existsSync27, readFileSync as readFileSync16, watchFile as watchFile2, unwatchFile as unwatchFile2 } from "fs";
19274
19571
  async function logsCommand(opts) {
19275
19572
  const logFile = opts.error ? ERROR_LOG_PATH : LOG_PATH;
19276
- if (!existsSync25(logFile)) {
19573
+ if (!existsSync27(logFile)) {
19277
19574
  outputError("LOG_NOT_FOUND", `Log file not found: ${logFile}`);
19278
19575
  process.exit(1);
19279
19576
  }
@@ -19325,11 +19622,11 @@ __export(gemini_exports, {
19325
19622
  geminiReorder: () => geminiReorder,
19326
19623
  geminiRotation: () => geminiRotation
19327
19624
  });
19328
- import { existsSync as existsSync26, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, readFileSync as readFileSync17, chmodSync } from "fs";
19625
+ import { existsSync as existsSync28, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, readFileSync as readFileSync17, chmodSync } from "fs";
19329
19626
  import { join as join24 } from "path";
19330
19627
  import { createInterface as createInterface5 } from "readline";
19331
19628
  function requireDb() {
19332
- if (!existsSync26(DB_PATH)) {
19629
+ if (!existsSync28(DB_PATH)) {
19333
19630
  outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
19334
19631
  process.exit(1);
19335
19632
  }
@@ -19355,7 +19652,7 @@ function resolveOAuthEmail(configHome) {
19355
19652
  if (!configHome) return null;
19356
19653
  try {
19357
19654
  const accountsPath = join24(configHome, ".gemini", "google_accounts.json");
19358
- if (!existsSync26(accountsPath)) return null;
19655
+ if (!existsSync28(accountsPath)) return null;
19359
19656
  const accounts = JSON.parse(readFileSync17(accountsPath, "utf-8"));
19360
19657
  return accounts.active || null;
19361
19658
  } catch {
@@ -19439,7 +19736,7 @@ async function geminiAddKey(globalOpts, opts) {
19439
19736
  async function geminiAddAccount(globalOpts, opts) {
19440
19737
  await requireWriteDb();
19441
19738
  const slotsDir = join24(CC_CLAW_HOME, "gemini-slots");
19442
- if (!existsSync26(slotsDir)) mkdirSync10(slotsDir, { recursive: true });
19739
+ if (!existsSync28(slotsDir)) mkdirSync10(slotsDir, { recursive: true });
19443
19740
  const { addGeminiSlot: addGeminiSlot2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
19444
19741
  const tempId = Date.now();
19445
19742
  const slotDir = join24(slotsDir, `slot-${tempId}`);
@@ -19463,7 +19760,7 @@ async function geminiAddAccount(globalOpts, opts) {
19463
19760
  } catch {
19464
19761
  }
19465
19762
  const oauthPath = join24(slotDir, ".gemini", "oauth_creds.json");
19466
- if (!existsSync26(oauthPath)) {
19763
+ if (!existsSync28(oauthPath)) {
19467
19764
  console.log(error2("\n No OAuth credentials found. Sign-in may have failed."));
19468
19765
  console.log(" The slot directory is preserved at: " + slotDir);
19469
19766
  console.log(" Re-run: cc-claw gemini add-account\n");
@@ -19577,12 +19874,12 @@ __export(backend_exports, {
19577
19874
  backendList: () => backendList,
19578
19875
  backendSet: () => backendSet
19579
19876
  });
19580
- import { existsSync as existsSync27 } from "fs";
19877
+ import { existsSync as existsSync29 } from "fs";
19581
19878
  async function backendList(globalOpts) {
19582
19879
  const { getAvailableAdapters: getAvailableAdapters2 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
19583
19880
  const chatId = resolveChatId(globalOpts);
19584
19881
  let activeBackend = null;
19585
- if (existsSync27(DB_PATH)) {
19882
+ if (existsSync29(DB_PATH)) {
19586
19883
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
19587
19884
  const readDb = openDatabaseReadOnly2();
19588
19885
  try {
@@ -19613,7 +19910,7 @@ async function backendList(globalOpts) {
19613
19910
  }
19614
19911
  async function backendGet(globalOpts) {
19615
19912
  const chatId = resolveChatId(globalOpts);
19616
- if (!existsSync27(DB_PATH)) {
19913
+ if (!existsSync29(DB_PATH)) {
19617
19914
  outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
19618
19915
  process.exit(1);
19619
19916
  }
@@ -19657,13 +19954,13 @@ __export(model_exports, {
19657
19954
  modelList: () => modelList,
19658
19955
  modelSet: () => modelSet
19659
19956
  });
19660
- import { existsSync as existsSync28 } from "fs";
19957
+ import { existsSync as existsSync30 } from "fs";
19661
19958
  async function modelList(globalOpts) {
19662
19959
  const chatId = resolveChatId(globalOpts);
19663
19960
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
19664
19961
  const { getAdapter: getAdapter2, getAllAdapters: getAllAdapters3 } = await Promise.resolve().then(() => (init_backends(), backends_exports));
19665
19962
  let backendId = "claude";
19666
- if (existsSync28(DB_PATH)) {
19963
+ if (existsSync30(DB_PATH)) {
19667
19964
  const readDb = openDatabaseReadOnly2();
19668
19965
  try {
19669
19966
  const row = readDb.prepare("SELECT backend FROM chat_backend WHERE chat_id = ?").get(chatId);
@@ -19696,7 +19993,7 @@ async function modelList(globalOpts) {
19696
19993
  }
19697
19994
  async function modelGet(globalOpts) {
19698
19995
  const chatId = resolveChatId(globalOpts);
19699
- if (!existsSync28(DB_PATH)) {
19996
+ if (!existsSync30(DB_PATH)) {
19700
19997
  outputError("DB_NOT_FOUND", "Database not found.");
19701
19998
  process.exit(1);
19702
19999
  }
@@ -19740,9 +20037,9 @@ __export(memory_exports, {
19740
20037
  memoryList: () => memoryList,
19741
20038
  memorySearch: () => memorySearch
19742
20039
  });
19743
- import { existsSync as existsSync29 } from "fs";
20040
+ import { existsSync as existsSync31 } from "fs";
19744
20041
  async function memoryList(globalOpts) {
19745
- if (!existsSync29(DB_PATH)) {
20042
+ if (!existsSync31(DB_PATH)) {
19746
20043
  outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
19747
20044
  process.exit(1);
19748
20045
  }
@@ -19766,7 +20063,7 @@ async function memoryList(globalOpts) {
19766
20063
  });
19767
20064
  }
19768
20065
  async function memorySearch(globalOpts, query) {
19769
- if (!existsSync29(DB_PATH)) {
20066
+ if (!existsSync31(DB_PATH)) {
19770
20067
  outputError("DB_NOT_FOUND", "Database not found.");
19771
20068
  process.exit(1);
19772
20069
  }
@@ -19788,7 +20085,7 @@ async function memorySearch(globalOpts, query) {
19788
20085
  });
19789
20086
  }
19790
20087
  async function memoryHistory(globalOpts, opts) {
19791
- if (!existsSync29(DB_PATH)) {
20088
+ if (!existsSync31(DB_PATH)) {
19792
20089
  outputError("DB_NOT_FOUND", "Database not found.");
19793
20090
  process.exit(1);
19794
20091
  }
@@ -19836,7 +20133,7 @@ __export(cron_exports2, {
19836
20133
  cronList: () => cronList,
19837
20134
  cronRuns: () => cronRuns
19838
20135
  });
19839
- import { existsSync as existsSync30 } from "fs";
20136
+ import { existsSync as existsSync32 } from "fs";
19840
20137
  function parseFallbacks(raw) {
19841
20138
  return raw.slice(0, 3).map((f) => {
19842
20139
  const [backend2, ...rest] = f.split(":");
@@ -19857,7 +20154,7 @@ function parseAndValidateTimeout(raw) {
19857
20154
  return val;
19858
20155
  }
19859
20156
  async function cronList(globalOpts) {
19860
- if (!existsSync30(DB_PATH)) {
20157
+ if (!existsSync32(DB_PATH)) {
19861
20158
  outputError("DB_NOT_FOUND", "Database not found.");
19862
20159
  process.exit(1);
19863
20160
  }
@@ -19876,7 +20173,7 @@ async function cronList(globalOpts) {
19876
20173
  const schedule2 = j.cron ?? (j.at_time ? `at ${j.at_time}` : j.every_ms ? `every ${j.every_ms / 1e3}s` : "?");
19877
20174
  const tz = j.timezone !== "UTC" ? ` (${j.timezone})` : "";
19878
20175
  lines.push(` ${statusDot(status)} #${j.id} [${status}] ${schedule2}${tz}`);
19879
- lines.push(` ${j.description}`);
20176
+ lines.push(` ${j.title ?? j.description}`);
19880
20177
  if (j.backend) lines.push(` Backend: ${j.backend}${j.model ? ` / ${j.model}` : ""}`);
19881
20178
  if (j.fallbacks) {
19882
20179
  try {
@@ -19895,7 +20192,7 @@ async function cronList(globalOpts) {
19895
20192
  });
19896
20193
  }
19897
20194
  async function cronHealth(globalOpts) {
19898
- if (!existsSync30(DB_PATH)) {
20195
+ if (!existsSync32(DB_PATH)) {
19899
20196
  outputError("DB_NOT_FOUND", "Database not found.");
19900
20197
  process.exit(1);
19901
20198
  }
@@ -19955,6 +20252,7 @@ async function cronCreate(globalOpts, opts) {
19955
20252
  cron: opts.cron ?? null,
19956
20253
  atTime: opts.at ?? null,
19957
20254
  everyMs,
20255
+ title: opts.title ?? null,
19958
20256
  description: opts.description,
19959
20257
  chatId,
19960
20258
  backend: opts.backend ?? null,
@@ -20009,6 +20307,10 @@ async function cronEdit(globalOpts, id, opts) {
20009
20307
  const db3 = getDb2();
20010
20308
  const updates = [];
20011
20309
  const values = [];
20310
+ if (opts.title) {
20311
+ updates.push("title = ?");
20312
+ values.push(opts.title);
20313
+ }
20012
20314
  if (opts.description) {
20013
20315
  updates.push("description = ?");
20014
20316
  values.push(opts.description);
@@ -20075,7 +20377,7 @@ async function cronEdit(globalOpts, id, opts) {
20075
20377
  }
20076
20378
  }
20077
20379
  async function cronRuns(globalOpts, jobId, opts) {
20078
- if (!existsSync30(DB_PATH)) {
20380
+ if (!existsSync32(DB_PATH)) {
20079
20381
  outputError("DB_NOT_FOUND", "Database not found.");
20080
20382
  process.exit(1);
20081
20383
  }
@@ -20122,9 +20424,9 @@ __export(agents_exports, {
20122
20424
  runnersList: () => runnersList,
20123
20425
  tasksList: () => tasksList
20124
20426
  });
20125
- import { existsSync as existsSync31 } from "fs";
20427
+ import { existsSync as existsSync33 } from "fs";
20126
20428
  async function agentsList(globalOpts) {
20127
- if (!existsSync31(DB_PATH)) {
20429
+ if (!existsSync33(DB_PATH)) {
20128
20430
  outputError("DB_NOT_FOUND", "Database not found.");
20129
20431
  process.exit(1);
20130
20432
  }
@@ -20155,7 +20457,7 @@ async function agentsList(globalOpts) {
20155
20457
  });
20156
20458
  }
20157
20459
  async function tasksList(globalOpts) {
20158
- if (!existsSync31(DB_PATH)) {
20460
+ if (!existsSync33(DB_PATH)) {
20159
20461
  outputError("DB_NOT_FOUND", "Database not found.");
20160
20462
  process.exit(1);
20161
20463
  }
@@ -20283,18 +20585,18 @@ __export(db_exports, {
20283
20585
  dbPath: () => dbPath,
20284
20586
  dbStats: () => dbStats
20285
20587
  });
20286
- import { existsSync as existsSync32, statSync as statSync6, copyFileSync as copyFileSync2, mkdirSync as mkdirSync11 } from "fs";
20588
+ import { existsSync as existsSync34, statSync as statSync7, copyFileSync as copyFileSync2, mkdirSync as mkdirSync11 } from "fs";
20287
20589
  import { dirname as dirname5 } from "path";
20288
20590
  async function dbStats(globalOpts) {
20289
- if (!existsSync32(DB_PATH)) {
20591
+ if (!existsSync34(DB_PATH)) {
20290
20592
  outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
20291
20593
  process.exit(1);
20292
20594
  }
20293
20595
  const { openDatabaseReadOnly: openDatabaseReadOnly2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
20294
20596
  const readDb = openDatabaseReadOnly2();
20295
- const mainSize = statSync6(DB_PATH).size;
20597
+ const mainSize = statSync7(DB_PATH).size;
20296
20598
  const walPath = DB_PATH + "-wal";
20297
- const walSize = existsSync32(walPath) ? statSync6(walPath).size : 0;
20599
+ const walSize = existsSync34(walPath) ? statSync7(walPath).size : 0;
20298
20600
  const tableNames = readDb.prepare(
20299
20601
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '%_fts%' ORDER BY name"
20300
20602
  ).all();
@@ -20328,7 +20630,7 @@ async function dbPath(globalOpts) {
20328
20630
  output({ path: DB_PATH }, (d) => d.path);
20329
20631
  }
20330
20632
  async function dbBackup(globalOpts, destPath) {
20331
- if (!existsSync32(DB_PATH)) {
20633
+ if (!existsSync34(DB_PATH)) {
20332
20634
  outputError("DB_NOT_FOUND", `Database not found at ${DB_PATH}`);
20333
20635
  process.exit(1);
20334
20636
  }
@@ -20337,8 +20639,8 @@ async function dbBackup(globalOpts, destPath) {
20337
20639
  mkdirSync11(dirname5(dest), { recursive: true });
20338
20640
  copyFileSync2(DB_PATH, dest);
20339
20641
  const walPath = DB_PATH + "-wal";
20340
- if (existsSync32(walPath)) copyFileSync2(walPath, dest + "-wal");
20341
- output({ path: dest, sizeBytes: statSync6(dest).size }, (d) => {
20642
+ if (existsSync34(walPath)) copyFileSync2(walPath, dest + "-wal");
20643
+ output({ path: dest, sizeBytes: statSync7(dest).size }, (d) => {
20342
20644
  const b = d;
20343
20645
  return `
20344
20646
  ${success("Backup created:")} ${b.path} (${(b.sizeBytes / 1024).toFixed(0)}KB)
@@ -20366,9 +20668,9 @@ __export(usage_exports, {
20366
20668
  usageCost: () => usageCost,
20367
20669
  usageTokens: () => usageTokens
20368
20670
  });
20369
- import { existsSync as existsSync33 } from "fs";
20671
+ import { existsSync as existsSync35 } from "fs";
20370
20672
  function ensureDb() {
20371
- if (!existsSync33(DB_PATH)) {
20673
+ if (!existsSync35(DB_PATH)) {
20372
20674
  outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
20373
20675
  process.exit(1);
20374
20676
  }
@@ -20558,9 +20860,9 @@ __export(config_exports, {
20558
20860
  configList: () => configList,
20559
20861
  configSet: () => configSet
20560
20862
  });
20561
- import { existsSync as existsSync34, readFileSync as readFileSync18 } from "fs";
20863
+ import { existsSync as existsSync36, readFileSync as readFileSync18 } from "fs";
20562
20864
  async function configList(globalOpts) {
20563
- if (!existsSync34(DB_PATH)) {
20865
+ if (!existsSync36(DB_PATH)) {
20564
20866
  outputError("DB_NOT_FOUND", "Database not found.");
20565
20867
  process.exit(1);
20566
20868
  }
@@ -20594,7 +20896,7 @@ async function configGet(globalOpts, key) {
20594
20896
  outputError("INVALID_KEY", `Unknown config key "${key}". Valid keys: ${RUNTIME_KEYS.join(", ")}`);
20595
20897
  process.exit(1);
20596
20898
  }
20597
- if (!existsSync34(DB_PATH)) {
20899
+ if (!existsSync36(DB_PATH)) {
20598
20900
  outputError("DB_NOT_FOUND", "Database not found.");
20599
20901
  process.exit(1);
20600
20902
  }
@@ -20640,7 +20942,7 @@ async function configSet(globalOpts, key, value) {
20640
20942
  }
20641
20943
  }
20642
20944
  async function configEnv(_globalOpts) {
20643
- if (!existsSync34(ENV_PATH)) {
20945
+ if (!existsSync36(ENV_PATH)) {
20644
20946
  outputError("ENV_NOT_FOUND", `No .env file at ${ENV_PATH}. Run cc-claw setup.`);
20645
20947
  process.exit(1);
20646
20948
  }
@@ -20694,9 +20996,9 @@ __export(session_exports, {
20694
20996
  sessionGet: () => sessionGet,
20695
20997
  sessionNew: () => sessionNew
20696
20998
  });
20697
- import { existsSync as existsSync35 } from "fs";
20999
+ import { existsSync as existsSync37 } from "fs";
20698
21000
  async function sessionGet(globalOpts) {
20699
- if (!existsSync35(DB_PATH)) {
21001
+ if (!existsSync37(DB_PATH)) {
20700
21002
  outputError("DB_NOT_FOUND", "Database not found.");
20701
21003
  process.exit(1);
20702
21004
  }
@@ -20757,9 +21059,9 @@ __export(permissions_exports, {
20757
21059
  verboseGet: () => verboseGet,
20758
21060
  verboseSet: () => verboseSet
20759
21061
  });
20760
- import { existsSync as existsSync36 } from "fs";
21062
+ import { existsSync as existsSync38 } from "fs";
20761
21063
  function ensureDb2() {
20762
- if (!existsSync36(DB_PATH)) {
21064
+ if (!existsSync38(DB_PATH)) {
20763
21065
  outputError("DB_NOT_FOUND", "Database not found.");
20764
21066
  process.exit(1);
20765
21067
  }
@@ -20906,9 +21208,9 @@ __export(cwd_exports, {
20906
21208
  cwdGet: () => cwdGet,
20907
21209
  cwdSet: () => cwdSet
20908
21210
  });
20909
- import { existsSync as existsSync37 } from "fs";
21211
+ import { existsSync as existsSync39 } from "fs";
20910
21212
  async function cwdGet(globalOpts) {
20911
- if (!existsSync37(DB_PATH)) {
21213
+ if (!existsSync39(DB_PATH)) {
20912
21214
  outputError("DB_NOT_FOUND", "Database not found.");
20913
21215
  process.exit(1);
20914
21216
  }
@@ -20970,9 +21272,9 @@ __export(voice_exports, {
20970
21272
  voiceGet: () => voiceGet,
20971
21273
  voiceSet: () => voiceSet
20972
21274
  });
20973
- import { existsSync as existsSync38 } from "fs";
21275
+ import { existsSync as existsSync40 } from "fs";
20974
21276
  async function voiceGet(globalOpts) {
20975
- if (!existsSync38(DB_PATH)) {
21277
+ if (!existsSync40(DB_PATH)) {
20976
21278
  outputError("DB_NOT_FOUND", "Database not found.");
20977
21279
  process.exit(1);
20978
21280
  }
@@ -21021,9 +21323,9 @@ __export(heartbeat_exports, {
21021
21323
  heartbeatGet: () => heartbeatGet,
21022
21324
  heartbeatSet: () => heartbeatSet
21023
21325
  });
21024
- import { existsSync as existsSync39 } from "fs";
21326
+ import { existsSync as existsSync41 } from "fs";
21025
21327
  async function heartbeatGet(globalOpts) {
21026
- if (!existsSync39(DB_PATH)) {
21328
+ if (!existsSync41(DB_PATH)) {
21027
21329
  outputError("DB_NOT_FOUND", "Database not found.");
21028
21330
  process.exit(1);
21029
21331
  }
@@ -21133,9 +21435,9 @@ __export(chats_exports, {
21133
21435
  chatsList: () => chatsList,
21134
21436
  chatsRemoveAlias: () => chatsRemoveAlias
21135
21437
  });
21136
- import { existsSync as existsSync40 } from "fs";
21438
+ import { existsSync as existsSync42 } from "fs";
21137
21439
  async function chatsList(_globalOpts) {
21138
- if (!existsSync40(DB_PATH)) {
21440
+ if (!existsSync42(DB_PATH)) {
21139
21441
  outputError("DB_NOT_FOUND", "Database not found.");
21140
21442
  process.exit(1);
21141
21443
  }
@@ -21263,9 +21565,9 @@ var mcps_exports = {};
21263
21565
  __export(mcps_exports, {
21264
21566
  mcpsList: () => mcpsList
21265
21567
  });
21266
- import { existsSync as existsSync41 } from "fs";
21568
+ import { existsSync as existsSync43 } from "fs";
21267
21569
  async function mcpsList(_globalOpts) {
21268
- if (!existsSync41(DB_PATH)) {
21570
+ if (!existsSync43(DB_PATH)) {
21269
21571
  outputError("DB_NOT_FOUND", "Database not found.");
21270
21572
  process.exit(1);
21271
21573
  }
@@ -21302,11 +21604,11 @@ __export(chat_exports, {
21302
21604
  chatSend: () => chatSend
21303
21605
  });
21304
21606
  import { request as httpRequest2 } from "http";
21305
- import { readFileSync as readFileSync19, existsSync as existsSync42 } from "fs";
21607
+ import { readFileSync as readFileSync19, existsSync as existsSync44 } from "fs";
21306
21608
  function getToken2() {
21307
21609
  if (process.env.CC_CLAW_API_TOKEN) return process.env.CC_CLAW_API_TOKEN;
21308
21610
  try {
21309
- if (existsSync42(TOKEN_PATH2)) return readFileSync19(TOKEN_PATH2, "utf-8").trim();
21611
+ if (existsSync44(TOKEN_PATH2)) return readFileSync19(TOKEN_PATH2, "utf-8").trim();
21310
21612
  } catch {
21311
21613
  }
21312
21614
  return null;
@@ -21746,9 +22048,9 @@ __export(evolve_exports, {
21746
22048
  evolveStatus: () => evolveStatus,
21747
22049
  evolveUndo: () => evolveUndo
21748
22050
  });
21749
- import { existsSync as existsSync43 } from "fs";
22051
+ import { existsSync as existsSync45 } from "fs";
21750
22052
  function ensureDb3() {
21751
- if (!existsSync43(DB_PATH)) {
22053
+ if (!existsSync45(DB_PATH)) {
21752
22054
  outputError("DB_NOT_FOUND", "Database not found. Run cc-claw setup first.");
21753
22055
  process.exit(1);
21754
22056
  }
@@ -22110,7 +22412,7 @@ var init_evolve = __esm({
22110
22412
 
22111
22413
  // src/setup.ts
22112
22414
  var setup_exports = {};
22113
- import { existsSync as existsSync44, writeFileSync as writeFileSync9, readFileSync as readFileSync20, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, statSync as statSync7 } from "fs";
22415
+ import { existsSync as existsSync46, writeFileSync as writeFileSync9, readFileSync as readFileSync20, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, statSync as statSync8 } from "fs";
22114
22416
  import { execFileSync as execFileSync4 } from "child_process";
22115
22417
  import { createInterface as createInterface7 } from "readline";
22116
22418
  import { join as join25 } from "path";
@@ -22188,10 +22490,10 @@ async function setup() {
22188
22490
  }
22189
22491
  console.log("");
22190
22492
  for (const dir of [CC_CLAW_HOME, DATA_PATH, LOGS_PATH, SKILLS_PATH, RUNNERS_PATH, AGENTS_PATH]) {
22191
- if (!existsSync44(dir)) mkdirSync12(dir, { recursive: true });
22493
+ if (!existsSync46(dir)) mkdirSync12(dir, { recursive: true });
22192
22494
  }
22193
22495
  const env = {};
22194
- const envSource = existsSync44(ENV_PATH) ? ENV_PATH : existsSync44(".env") ? ".env" : null;
22496
+ const envSource = existsSync46(ENV_PATH) ? ENV_PATH : existsSync46(".env") ? ".env" : null;
22195
22497
  if (envSource) {
22196
22498
  console.log(yellow(` Found existing config at ${envSource} \u2014 your values will be preserved`));
22197
22499
  console.log(yellow(" unless you enter new ones. Just press Enter to keep existing values.\n"));
@@ -22202,8 +22504,8 @@ async function setup() {
22202
22504
  }
22203
22505
  }
22204
22506
  const cwdDb = join25(process.cwd(), "cc-claw.db");
22205
- if (existsSync44(cwdDb) && !existsSync44(DB_PATH)) {
22206
- const { size } = statSync7(cwdDb);
22507
+ if (existsSync46(cwdDb) && !existsSync46(DB_PATH)) {
22508
+ const { size } = statSync8(cwdDb);
22207
22509
  console.log(yellow(` Found existing database at ${cwdDb} (${(size / 1024).toFixed(0)}KB)`));
22208
22510
  const migrate = await confirm("Copy database to ~/.cc-claw/? (preserves memories & history)", true);
22209
22511
  if (migrate) {
@@ -22622,7 +22924,7 @@ function registerCronCommands(cmd) {
22622
22924
  const { cronList: cronList2 } = await Promise.resolve().then(() => (init_cron2(), cron_exports2));
22623
22925
  await cronList2(program.opts());
22624
22926
  });
22625
- cmd.command("create").description("Create a scheduled job").requiredOption("--description <text>", "Job description").option("--prompt <text>", "Agent prompt (defaults to description)").option("--cron <expr>", "Cron expression (e.g. '0 9 * * *')").option("--at <iso8601>", "One-shot time").option("--every <interval>", "Repeat interval (e.g. 30m, 1h)").option("--backend <name>", "Backend for this job").option("--model <name>", "Model for this job").option("--thinking <level>", "Thinking level").option("--timeout <seconds>", "Job timeout in seconds (30-3600)").option("--fallback <backend:model>", "Fallback backend:model (repeatable, max 3)", (val, prev) => [...prev, val], []).option("--timezone <tz>", "IANA timezone", "UTC").option("--session-type <type>", "Session type (isolated/main)", "isolated").option("--delivery <mode>", "Delivery mode (announce/webhook/none)", "announce").option("--channel <name>", "Delivery channel").option("--target <id>", "Delivery target").option("--cwd <path>", "Working directory").action(async (opts) => {
22927
+ cmd.command("create").description("Create a scheduled job").requiredOption("--description <text>", "Job description").option("--title <text>", "Short title for job list (auto-generated if omitted)").option("--prompt <text>", "Agent prompt (defaults to description)").option("--cron <expr>", "Cron expression (e.g. '0 9 * * *')").option("--at <iso8601>", "One-shot time").option("--every <interval>", "Repeat interval (e.g. 30m, 1h)").option("--backend <name>", "Backend for this job").option("--model <name>", "Model for this job").option("--thinking <level>", "Thinking level").option("--timeout <seconds>", "Job timeout in seconds (30-3600)").option("--fallback <backend:model>", "Fallback backend:model (repeatable, max 3)", (val, prev) => [...prev, val], []).option("--timezone <tz>", "IANA timezone", "UTC").option("--session-type <type>", "Session type (isolated/main)", "isolated").option("--delivery <mode>", "Delivery mode (announce/webhook/none)", "announce").option("--channel <name>", "Delivery channel").option("--target <id>", "Delivery target").option("--cwd <path>", "Working directory").action(async (opts) => {
22626
22928
  const { cronCreate: cronCreate2 } = await Promise.resolve().then(() => (init_cron2(), cron_exports2));
22627
22929
  await cronCreate2(program.opts(), opts);
22628
22930
  });
@@ -22642,7 +22944,7 @@ function registerCronCommands(cmd) {
22642
22944
  const { cronAction: cronAction2 } = await Promise.resolve().then(() => (init_cron2(), cron_exports2));
22643
22945
  await cronAction2(program.opts(), "run", id);
22644
22946
  });
22645
- cmd.command("edit <id>").description("Edit a job (same flags as create)").option("--description <text>").option("--cron <expr>").option("--at <iso8601>").option("--every <interval>").option("--backend <name>").option("--model <name>").option("--thinking <level>").option("--timeout <seconds>", "Job timeout in seconds (30-3600)").option("--fallback <backend:model>", "Fallback backend:model (repeatable, max 3)", (val, prev) => [...prev, val], []).option("--timezone <tz>").action(async (id, opts) => {
22947
+ cmd.command("edit <id>").description("Edit a job (same flags as create)").option("--title <text>", "Short title for job list").option("--description <text>").option("--cron <expr>").option("--at <iso8601>").option("--every <interval>").option("--backend <name>").option("--model <name>").option("--thinking <level>").option("--timeout <seconds>", "Job timeout in seconds (30-3600)").option("--fallback <backend:model>", "Fallback backend:model (repeatable, max 3)", (val, prev) => [...prev, val], []).option("--timezone <tz>").action(async (id, opts) => {
22646
22948
  const { cronEdit: cronEdit2 } = await Promise.resolve().then(() => (init_cron2(), cron_exports2));
22647
22949
  await cronEdit2(program.opts(), id, opts);
22648
22950
  });