cc-claw 0.7.0 → 0.7.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 +53 -18
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -55,7 +55,7 @@ var VERSION;
55
55
  var init_version = __esm({
56
56
  "src/version.ts"() {
57
57
  "use strict";
58
- VERSION = true ? "0.7.0" : (() => {
58
+ VERSION = true ? "0.7.2" : (() => {
59
59
  try {
60
60
  return JSON.parse(readFileSync(join2(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
61
61
  } catch {
@@ -3919,6 +3919,16 @@ var init_loader = __esm({
3919
3919
  });
3920
3920
 
3921
3921
  // src/memory/session-log.ts
3922
+ var session_log_exports = {};
3923
+ __export(session_log_exports, {
3924
+ appendToLog: () => appendToLog,
3925
+ clearLog: () => clearLog,
3926
+ getCachedLog: () => getCachedLog,
3927
+ getLastMessageTimestamp: () => getLastMessageTimestamp,
3928
+ getLog: () => getLog,
3929
+ getLoggedChatIds: () => getLoggedChatIds,
3930
+ getMessagePairCount: () => getMessagePairCount
3931
+ });
3922
3932
  function appendToLog(chatId, userMessage, assistantResponse, backend2, model2, sessionId) {
3923
3933
  const now = Date.now();
3924
3934
  appendMessageLog(chatId, "user", userMessage, backend2 ?? null, model2 ?? null, sessionId ?? null);
@@ -3962,6 +3972,9 @@ function getLastMessageTimestamp(chatId) {
3962
3972
  const last = rows[rows.length - 1];
3963
3973
  return (/* @__PURE__ */ new Date(last.created_at + (last.created_at.includes("Z") ? "" : "Z"))).getTime();
3964
3974
  }
3975
+ function getCachedLog(chatId) {
3976
+ return cache.get(chatId) ?? [];
3977
+ }
3965
3978
  function getLoggedChatIds() {
3966
3979
  return getUnsummarizedChatIds();
3967
3980
  }
@@ -8179,6 +8192,7 @@ var init_telegram2 = __esm({
8179
8192
  { command: "backend", description: "Switch AI backend (Claude/Gemini/Codex)" },
8180
8193
  { command: "claude", description: "Switch to Claude backend" },
8181
8194
  { command: "gemini", description: "Switch to Gemini backend" },
8195
+ { command: "gemini_accounts", description: "Manage Gemini credentials & rotation" },
8182
8196
  { command: "codex", description: "Switch to Codex backend" },
8183
8197
  { command: "model", description: "Switch model for active backend" },
8184
8198
  { command: "summarizer", description: "Configure session summarization model" },
@@ -10645,7 +10659,7 @@ async function handleCommand(msg, channel) {
10645
10659
  case "help":
10646
10660
  await channel.sendText(
10647
10661
  chatId,
10648
- "Hey! I'm CC-Claw \u2014 your personal AI assistant on Telegram.\n\nI use AI coding CLIs (Claude, Gemini, Codex) as my brain. Just send me a message to get started.\n\nCommands:\n/backend [name] - Switch AI backend (or /claude /gemini /codex)\n/model - Switch model for active backend\n/gemini slot - Select Gemini credential (account/key)\n/summarizer - Configure session summarization model\n/status - Show session, model, backend, and usage\n/cost - Show estimated API cost (use /cost all for all-time)\n/usage - Show usage per backend with limits\n/limits - Configure usage limits per backend\n/newchat - Start a fresh conversation\n/summarize - Save session to memory (without resetting)\n/summarize all - Summarize all pending sessions (pre-restart)\n/cwd <path> - Set working directory\n/cwd - Show current working directory\n/memory - List stored memories\n/remember <text> - Save a memory\n/forget <keyword> - Remove a memory\n/voice - Toggle voice responses\n/voice_config - Configure voice provider and voice\n/imagine <prompt> - Generate an image (or /image)\n/cron <description> - Schedule a task (or /schedule)\n/cron - List scheduled jobs (or /jobs)\n/cron cancel <id> - Cancel a job\n/cron pause <id> - Pause a job\n/cron resume <id> - Resume a job\n/cron run <id> - Trigger a job now\n/cron runs [id] - View run history\n/cron edit <id> - Edit a job\n/cron health - Scheduler health\n/skills - List skills from all backends\n/skill-install <url> - Install a skill from GitHub\n/setup-profile - Set up your user profile\n/chats - List authorized chats and aliases\n/heartbeat - Proactive awareness (on/off/interval/hours)\n/history - List recent session summaries\n/stop - Cancel the current running task\n/tools - Configure which tools the agent can use\n/permissions - Switch permission mode (yolo/safe/plan)\n/verbose - Tool visibility (off/normal/verbose)\n/model_signature - Toggle model+thinking signature on responses\n/intent <msg> - Test intent classifier (chat vs agentic)\n/agents - List active sub-agents\n/agents mode [auto|native|claw] - Set agent mode (native vs orchestrated)\n/agents history - Native sub-agent activity (24h)\n/tasks - Show task board for current orchestration\n/stopagent <id> - Cancel a specific sub-agent\n/stopall - Cancel all sub-agents in this chat\n/runners - List registered CLI runners\n/mcps - List registered MCP servers\n/help - Show this message",
10662
+ "Hey! I'm CC-Claw \u2014 your personal AI assistant on Telegram.\n\nI use AI coding CLIs (Claude, Gemini, Codex) as my brain. Just send me a message to get started.\n\nCommands:\n/backend [name] - Switch AI backend (or /claude /gemini /codex)\n/model - Switch model for active backend\n/gemini_accounts - Manage Gemini credentials & rotation\n/summarizer - Configure session summarization model\n/status - Show session, model, backend, and usage\n/cost - Show estimated API cost (use /cost all for all-time)\n/usage - Show usage per backend with limits\n/limits - Configure usage limits per backend\n/newchat - Start a fresh conversation\n/summarize - Save session to memory (without resetting)\n/summarize all - Summarize all pending sessions (pre-restart)\n/cwd <path> - Set working directory\n/cwd - Show current working directory\n/memory - List stored memories\n/remember <text> - Save a memory\n/forget <keyword> - Remove a memory\n/voice - Toggle voice responses\n/voice_config - Configure voice provider and voice\n/imagine <prompt> - Generate an image (or /image)\n/cron <description> - Schedule a task (or /schedule)\n/cron - List scheduled jobs (or /jobs)\n/cron cancel <id> - Cancel a job\n/cron pause <id> - Pause a job\n/cron resume <id> - Resume a job\n/cron run <id> - Trigger a job now\n/cron runs [id] - View run history\n/cron edit <id> - Edit a job\n/cron health - Scheduler health\n/skills - List skills from all backends\n/skill-install <url> - Install a skill from GitHub\n/setup-profile - Set up your user profile\n/chats - List authorized chats and aliases\n/heartbeat - Proactive awareness (on/off/interval/hours)\n/history - List recent session summaries\n/stop - Cancel the current running task\n/tools - Configure which tools the agent can use\n/permissions - Switch permission mode (yolo/safe/plan)\n/verbose - Tool visibility (off/normal/verbose)\n/model_signature - Toggle model+thinking signature on responses\n/intent <msg> - Test intent classifier (chat vs agentic)\n/agents - List active sub-agents\n/agents mode [auto|native|claw] - Set agent mode (native vs orchestrated)\n/agents history - Native sub-agent activity (24h)\n/tasks - Show task board for current orchestration\n/stopagent <id> - Cancel a specific sub-agent\n/stopall - Cancel all sub-agents in this chat\n/runners - List registered CLI runners\n/mcps - List registered MCP servers\n/help - Show this message",
10649
10663
  "plain"
10650
10664
  );
10651
10665
  break;
@@ -12648,7 +12662,7 @@ async function doBackendSwitch(chatId, backendId, channel) {
12648
12662
  }
12649
12663
  if (summarized) {
12650
12664
  await channel.sendText(chatId, "\u{1F4BE} Context saved \u2014 session summarized to memory.", "plain");
12651
- } else if (pairCount > 0 && bridge) {
12665
+ } else if (bridge) {
12652
12666
  await channel.sendText(chatId, "\u{1F4AC} Context preserved.", "plain");
12653
12667
  }
12654
12668
  clearSession(chatId);
@@ -14072,22 +14086,16 @@ async function main() {
14072
14086
  initDatabase();
14073
14087
  pruneMessageLog(30, 2e3);
14074
14088
  bootstrapBuiltinMcps(getDb());
14075
- const SUMMARIZE_TIMEOUT_MS2 = 3e4;
14076
- try {
14077
- let timer;
14078
- const timeoutPromise = new Promise((_, reject) => {
14079
- timer = setTimeout(() => reject(new Error("timeout")), SUMMARIZE_TIMEOUT_MS2);
14089
+ let pendingSummarizeNotify = null;
14090
+ const { getLoggedChatIds: getLoggedChatIds2 } = await Promise.resolve().then(() => (init_session_log(), session_log_exports));
14091
+ const pendingCount = getLoggedChatIds2().length;
14092
+ if (pendingCount > 0) {
14093
+ summarizeAllPending().then(() => {
14094
+ log(`[cc-claw] Background summarization complete (${pendingCount} session(s))`);
14095
+ if (pendingSummarizeNotify) pendingSummarizeNotify();
14096
+ }).catch((err) => {
14097
+ log(`[cc-claw] Background summarization failed: ${err}`);
14080
14098
  });
14081
- try {
14082
- await Promise.race([
14083
- summarizeAllPending(),
14084
- timeoutPromise
14085
- ]);
14086
- } finally {
14087
- clearTimeout(timer);
14088
- }
14089
- } catch {
14090
- log("[cc-claw] Session summarization skipped (timeout or backend unavailable)");
14091
14099
  }
14092
14100
  setBootTime();
14093
14101
  log("[cc-claw] Database initialized (sessions preserved for resume)");
@@ -14100,6 +14108,17 @@ async function main() {
14100
14108
  }
14101
14109
  await channelRegistry.startAll(handleMessage);
14102
14110
  log("[cc-claw] Channels started");
14111
+ if (pendingCount > 0) {
14112
+ const primaryChatId = (process.env.ALLOWED_CHAT_ID ?? "").split(",")[0]?.trim();
14113
+ pendingSummarizeNotify = () => {
14114
+ if (primaryChatId) {
14115
+ for (const ch of channelRegistry.list()) {
14116
+ ch.sendText(primaryChatId, "\u{1F504} Restarted \u2014 your conversations were summarized and saved.", "plain").catch(() => {
14117
+ });
14118
+ }
14119
+ }
14120
+ };
14121
+ }
14103
14122
  const telegramChannel = channelRegistry.get("telegram");
14104
14123
  if (telegramChannel && typeof telegramChannel.onCallback === "function") {
14105
14124
  telegramChannel.onCallback(handleCallback);
@@ -15266,6 +15285,22 @@ async function geminiAddKey(globalOpts, opts) {
15266
15285
  outputError("EMPTY_KEY", "No key provided.");
15267
15286
  process.exit(1);
15268
15287
  }
15288
+ console.log(" Validating API key...");
15289
+ try {
15290
+ const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(key.trim())}`);
15291
+ if (!res.ok) {
15292
+ const body = await res.text().catch(() => "");
15293
+ if (res.status === 400 || res.status === 403) {
15294
+ outputError("INVALID_KEY", `API key is invalid or unauthorized (HTTP ${res.status}).`);
15295
+ process.exit(1);
15296
+ }
15297
+ console.log(warning(` Warning: validation returned HTTP ${res.status} \u2014 saving anyway. ${body.slice(0, 100)}`));
15298
+ } else {
15299
+ console.log(success(" \u2713 API key is valid."));
15300
+ }
15301
+ } catch (err) {
15302
+ console.log(warning(` Warning: could not validate key (network error) \u2014 saving anyway.`));
15303
+ }
15269
15304
  const { addGeminiSlot: addGeminiSlot2 } = await Promise.resolve().then(() => (init_store4(), store_exports3));
15270
15305
  const id = addGeminiSlot2({
15271
15306
  slotType: "api_key",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-claw",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "CC-Claw: Personal AI assistant on Telegram — multi-backend (Claude, Gemini, Codex), sub-agent orchestration, MCP management",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",