cc-claw 0.20.17 → 0.20.19

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 +31 -120
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -33,7 +33,7 @@ var VERSION;
33
33
  var init_version = __esm({
34
34
  "src/version.ts"() {
35
35
  "use strict";
36
- VERSION = true ? "0.20.17" : (() => {
36
+ VERSION = true ? "0.20.19" : (() => {
37
37
  try {
38
38
  return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
39
39
  } catch {
@@ -7370,11 +7370,6 @@ ${ctx}`);
7370
7370
  } catch {
7371
7371
  }
7372
7372
  }
7373
- if (tier !== "slim" && tier !== "heartbeat") {
7374
- sections.push(
7375
- "[React] Start your response with [REACT:emoji] \u2014 one emoji from the Telegram allowed set matching the message tone. Examples: \u{1F914} question, \u{1FAE1} task/request, \u{1F525} exciting, \u{1F923} funny, \u{1F622} sad, \u{1F4AF} agree, \u{1F389} celebrate, \u{1F468}\u200D\u{1F4BB} coding, \u{1F92F} mind-blown, \u{1F440} interesting, \u{1F91D} thanks, \u{1F60E} chill."
7376
- );
7377
- }
7378
7373
  if (sideQuestContext) {
7379
7374
  const { getInFlightMessage: getInFlightMessage3 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7380
7375
  const inFlightMsg = getInFlightMessage3(sideQuestContext.parentChatId);
@@ -8527,11 +8522,6 @@ function pickFallbackEmoji(userMessage) {
8527
8522
  }
8528
8523
  return "\u{1F44D}";
8529
8524
  }
8530
- function ensureReaction(responseText, userMessage) {
8531
- if (/\[REACT:.+?\]/.test(responseText)) return responseText;
8532
- const emoji = pickFallbackEmoji(userMessage);
8533
- return `[REACT:${emoji}]${responseText}`;
8534
- }
8535
8525
  function isPathAllowed(filePath, cwd) {
8536
8526
  const resolved = resolvePath(cwd ?? process.cwd(), filePath);
8537
8527
  for (const pattern of BLOCKED_PATH_PATTERNS) {
@@ -8709,7 +8699,7 @@ async function sendOrEditKeyboard(chatId, channel, messageId, text, buttons) {
8709
8699
  await channel.sendText(chatId, text, { parseMode: "plain" });
8710
8700
  return void 0;
8711
8701
  }
8712
- var TONE_PATTERNS, ALLOWED_REACTION_EMOJIS, BLOCKED_PATH_PATTERNS, CLI_INSTALL_HINTS, PERM_MODES, VERBOSE_LEVELS, HELP_CATEGORIES, USAGE_WINDOW_MAP, SKILLS_PER_PAGE, MAX_SIDE_QUESTS;
8702
+ var TONE_PATTERNS, BLOCKED_PATH_PATTERNS, CLI_INSTALL_HINTS, PERM_MODES, VERBOSE_LEVELS, HELP_CATEGORIES, USAGE_WINDOW_MAP, SKILLS_PER_PAGE, MAX_SIDE_QUESTS;
8713
8703
  var init_helpers = __esm({
8714
8704
  "src/router/helpers.ts"() {
8715
8705
  "use strict";
@@ -8744,77 +8734,6 @@ var init_helpers = __esm({
8744
8734
  // Chill / casual greeting
8745
8735
  { pattern: /^(hey|hi|hello|sup|yo|what'?s up|howdy)\b/i, emoji: "\u{1F60E}" }
8746
8736
  ];
8747
- ALLOWED_REACTION_EMOJIS = /* @__PURE__ */ new Set([
8748
- "\u{1F44D}",
8749
- "\u{1F44E}",
8750
- "\u2764",
8751
- "\u{1F525}",
8752
- "\u{1F970}",
8753
- "\u{1F44F}",
8754
- "\u{1F601}",
8755
- "\u{1F914}",
8756
- "\u{1F92F}",
8757
- "\u{1F631}",
8758
- "\u{1F92C}",
8759
- "\u{1F622}",
8760
- "\u{1F389}",
8761
- "\u{1F929}",
8762
- "\u{1F92E}",
8763
- "\u{1F4A9}",
8764
- "\u{1F64F}",
8765
- "\u{1F44C}",
8766
- "\u{1F54A}\uFE0F",
8767
- "\u{1F921}",
8768
- "\u{1F971}",
8769
- "\u{1F974}",
8770
- "\u{1F60D}",
8771
- "\u{1F433}",
8772
- "\u{1F31A}",
8773
- "\u{1F32D}",
8774
- "\u{1F4AF}",
8775
- "\u{1F923}",
8776
- "\u26A1",
8777
- "\u{1F34C}",
8778
- "\u{1F3C6}",
8779
- "\u{1F494}",
8780
- "\u{1F928}",
8781
- "\u{1F610}",
8782
- "\u{1F353}",
8783
- "\u{1F37E}",
8784
- "\u{1F48B}",
8785
- "\u{1F595}",
8786
- "\u{1F608}",
8787
- "\u{1F634}",
8788
- "\u{1F62D}",
8789
- "\u{1F913}",
8790
- "\u{1F47B}",
8791
- "\u{1F468}\u200D\u{1F4BB}",
8792
- "\u{1F440}",
8793
- "\u{1F383}",
8794
- "\u{1F648}",
8795
- "\u{1F607}",
8796
- "\u{1F628}",
8797
- "\u{1F91D}",
8798
- "\u{1F917}",
8799
- "\u{1FAE1}",
8800
- "\u{1F385}",
8801
- "\u{1F384}",
8802
- "\u2603\uFE0F",
8803
- "\u{1F485}",
8804
- "\u{1F92A}",
8805
- "\u{1F5FF}",
8806
- "\u{1F192}",
8807
- "\u{1F498}",
8808
- "\u{1F649}",
8809
- "\u{1F984}",
8810
- "\u{1F618}",
8811
- "\u{1F48A}",
8812
- "\u{1F64A}",
8813
- "\u{1F60E}",
8814
- "\u{1F47E}",
8815
- "\u{1F937}",
8816
- "\u{1F621}"
8817
- ]);
8818
8737
  BLOCKED_PATH_PATTERNS = [
8819
8738
  /\/\.ssh\//,
8820
8739
  /\/\.gnupg\//,
@@ -15863,14 +15782,17 @@ async function classifyWithLlm(text) {
15863
15782
  return null;
15864
15783
  }
15865
15784
  async function classifyWithOllama(text) {
15866
- const ollamaService = await Promise.resolve().then(() => (init_service(), service_exports));
15785
+ const ollamaStore = await Promise.resolve().then(() => (init_store6(), store_exports6));
15867
15786
  const ollamaClient = await Promise.resolve().then(() => (init_client(), client_exports));
15868
- const servers = ollamaService.listServers();
15787
+ const servers = ollamaStore.listServers();
15869
15788
  const onlineServer = servers.find((s) => s.status === "online");
15870
15789
  if (!onlineServer) return null;
15871
- const models = ollamaService.listModels(onlineServer.name);
15872
- if (models.length === 0) return null;
15873
- const sorted = [...models].sort(
15790
+ const allModels = ollamaStore.listModels(onlineServer.id);
15791
+ const chatModels = allModels.filter(
15792
+ (m) => !/embed|nomic|e5|bge/i.test(m.name)
15793
+ );
15794
+ if (chatModels.length === 0) return null;
15795
+ const sorted = [...chatModels].sort(
15874
15796
  (a, b) => (a.sizeBytes ?? Infinity) - (b.sizeBytes ?? Infinity)
15875
15797
  );
15876
15798
  const model2 = sorted[0].name;
@@ -16035,8 +15957,8 @@ var init_classify = __esm({
16035
15957
  // "what is", "what version", "what does"
16036
15958
  /^(?:which|where|when|why|who)\s+/i,
16037
15959
  // "which file", "where is", "when did"
16038
- /^(?:how\s+(?:do|does|can|did|many|much|long|often|come))\s+/i,
16039
- // "how do I", "how many"
15960
+ /^(?:how\s+(?:do|does|can|did|many|much|long|often|come|are|is|was|were|about))\s+/i,
15961
+ // "how do I", "how many", "how are you"
16040
15962
  /^(?:show|tell|list|explain|describe|summarize|display)\s+(?:me\s+)?/i,
16041
15963
  /^(?:do you|can you|could you|are you|is there|are there)\s+(?:know|have|see|find|show|tell|check|list|explain|describe)\s+/i,
16042
15964
  /^(?:give\s+me|get\s+me)\s+(?:the|a|my|an|current|latest)\s+/i,
@@ -18093,13 +18015,11 @@ var init_image_gen = __esm({
18093
18015
  // src/router/response.ts
18094
18016
  var response_exports = {};
18095
18017
  __export(response_exports, {
18096
- ensureReaction: () => ensureReaction,
18097
18018
  handleResponseExhaustion: () => handleResponseExhaustion,
18098
18019
  makeToolActionCallback: () => makeToolActionCallback,
18099
18020
  pendingFallbackMessages: () => pendingFallbackMessages,
18100
18021
  processFileSends: () => processFileSends2,
18101
18022
  processImageGenerations: () => processImageGenerations,
18102
- processReaction: () => processReaction,
18103
18023
  sendResponse: () => sendResponse
18104
18024
  });
18105
18025
  import { readFile as readFile3 } from "fs/promises";
@@ -18165,25 +18085,8 @@ async function processImageGenerations(chatId, channel, text) {
18165
18085
  }
18166
18086
  return text.replace(pattern, "").trim();
18167
18087
  }
18168
- async function processReaction(chatId, channel, text, messageId) {
18169
- const reactPatternGlobal = /\[\s*REACT:\s*(.+?)\s*\]/g;
18170
- if (!reactPatternGlobal.test(text)) return text;
18171
- let reacted = false;
18172
- reactPatternGlobal.lastIndex = 0;
18173
- let match;
18174
- while ((match = reactPatternGlobal.exec(text)) !== null) {
18175
- const emoji = match[1].trim();
18176
- if (!reacted && messageId && typeof channel.reactToMessage === "function" && ALLOWED_REACTION_EMOJIS.has(emoji)) {
18177
- channel.reactToMessage(chatId, messageId, emoji).catch((err) => {
18178
- log(`[reaction] Failed for chat=${chatId}: ${err}`);
18179
- });
18180
- reacted = true;
18181
- }
18182
- }
18183
- return text.replace(/\[\s*REACT:\s*(.+?)\s*\]/g, "").trim();
18184
- }
18185
18088
  async function sendResponse(chatId, channel, text, messageId, replyToMessageId) {
18186
- text = await processReaction(chatId, channel, text, messageId);
18089
+ text = text.replace(/\[\s*REACT:\s*(.+?)\s*\]/g, "").trim();
18187
18090
  const { cleanText: afterUpdates, updates } = extractUserUpdates(text);
18188
18091
  for (const { key, value } of updates) {
18189
18092
  if (typeof channel.sendKeyboard === "function") {
@@ -18620,8 +18523,7 @@ async function handleVoice(msg, channel) {
18620
18523
  if (vLiveStatus) await vLiveStatus.finalize(Date.now() - sigT0);
18621
18524
  if (response.usage) addUsage(chatId, response.usage.input, response.usage.output, response.usage.cacheRead, vModel, void 0, response.usage.contextSize);
18622
18525
  if (await handleResponseExhaustion(response.text, chatId, msg, channel)) return;
18623
- const voiceResponse = ensureReaction(response.text, transcript);
18624
- await sendResponse(chatId, channel, voiceResponse, msg.messageId);
18526
+ await sendResponse(chatId, channel, response.text, msg.messageId);
18625
18527
  } catch (err) {
18626
18528
  error("[router] Voice error:", err);
18627
18529
  await channel.sendText(chatId, `Voice processing error: ${errorMessage(err)}`, { parseMode: "plain" });
@@ -18703,8 +18605,7 @@ Acknowledge receipt. Do NOT analyze the video unless they ask you to.`;
18703
18605
  if (vidLiveStatus) await vidLiveStatus.finalize(Date.now() - vidT0);
18704
18606
  if (response2.usage) addUsage(chatId, response2.usage.input, response2.usage.output, response2.usage.cacheRead, vidModel, void 0, response2.usage.contextSize);
18705
18607
  if (await handleResponseExhaustion(response2.text, chatId, msg, channel)) return;
18706
- const vidResponse = ensureReaction(response2.text, caption || "video");
18707
- await sendResponse(chatId, channel, vidResponse, msg.messageId);
18608
+ await sendResponse(chatId, channel, response2.text, msg.messageId);
18708
18609
  return;
18709
18610
  }
18710
18611
  if (!fileName) {
@@ -18777,8 +18678,7 @@ ${content}
18777
18678
  if (mLiveStatus) await mLiveStatus.finalize(Date.now() - mT0);
18778
18679
  if (response.usage) addUsage(chatId, response.usage.input, response.usage.output, response.usage.cacheRead, mediaModel, void 0, response.usage.contextSize);
18779
18680
  if (await handleResponseExhaustion(response.text, chatId, msg, channel)) return;
18780
- const mediaResponse = ensureReaction(response.text, caption || "file");
18781
- await sendResponse(chatId, channel, mediaResponse, msg.messageId);
18681
+ await sendResponse(chatId, channel, response.text, msg.messageId);
18782
18682
  } catch (err) {
18783
18683
  error("[router] Media error:", err);
18784
18684
  const errStr = errorMessage(err);
@@ -24521,7 +24421,9 @@ ${PERM_MODES[chosen]}`,
24521
24421
  return;
24522
24422
  }
24523
24423
  removePendingPlan(chatId);
24524
- await replaceWithText("\u2705 Approved. Executing...");
24424
+ await replaceWithText(`\u{1F50D} ${plan.plan}
24425
+
24426
+ \u2705 Approved. Executing...`);
24525
24427
  bypassBusyCheck.add(chatId);
24526
24428
  const { handleMessage: handleMessage2 } = await Promise.resolve().then(() => (init_router2(), router_exports));
24527
24429
  const overrideMsg = `[SYSTEM: Planning mode disabled. Execution APPROVED. Please execute the plan.]
@@ -24539,7 +24441,9 @@ ${plan.originalMessage}`;
24539
24441
  }
24540
24442
  removePendingPlan(chatId);
24541
24443
  setRejectionMode(chatId);
24542
- await channel.sendText(chatId, "\u270F\uFE0F Plan rejected. Send your feedback and I'll revise the plan.", { parseMode: "plain" });
24444
+ await replaceWithText(`\u{1F50D} ${plan.plan}
24445
+
24446
+ \u274C Rejected \u2014 send feedback to revise.`);
24543
24447
  return;
24544
24448
  } else if (data === "exec:yolo") {
24545
24449
  const plan = getPendingPlan(chatId);
@@ -24549,7 +24453,9 @@ ${plan.originalMessage}`;
24549
24453
  }
24550
24454
  removePendingPlan(chatId);
24551
24455
  setExecMode(chatId, "yolo");
24552
- await channel.sendText(chatId, "\u26A1 Switched to YOLO mode. Executing without approval gate...", { parseMode: "plain" });
24456
+ await replaceWithText(`\u{1F50D} ${plan.plan}
24457
+
24458
+ \u26A1 YOLO mode. Executing...`);
24553
24459
  bypassBusyCheck.add(chatId);
24554
24460
  const { handleMessage: handleMessage2 } = await Promise.resolve().then(() => (init_router2(), router_exports));
24555
24461
  const overrideMsg = `[SYSTEM: Planning mode disabled. YOLO mode enabled. Proceed immediately without asking for approval.]
@@ -26283,6 +26189,12 @@ async function handleText(msg, channel) {
26283
26189
  await channel.sendText(chatId, "Got it, I'll remember that.", { parseMode: "plain" });
26284
26190
  return;
26285
26191
  }
26192
+ if (msg.messageId && typeof channel.reactToMessage === "function") {
26193
+ const ackEmoji = pickFallbackEmoji(text);
26194
+ channel.reactToMessage(chatId, msg.messageId, ackEmoji).catch(() => {
26195
+ });
26196
+ }
26197
+ await channel.sendTyping?.(chatId);
26286
26198
  const model2 = resolveModel(chatId);
26287
26199
  let autoRouted = false;
26288
26200
  let effectiveModel = model2;
@@ -26701,7 +26613,6 @@ Debating: "${question.slice(0, 100)}${question.length > 100 ? "\u2026" : ""}"`,
26701
26613
  if (activeSideQuests.has(chatId) && responseText && !responseText.startsWith("(No response")) {
26702
26614
  responseText = "\u{1F4CB} <b>Main task</b>\n\n" + responseText;
26703
26615
  }
26704
- responseText = ensureReaction(responseText, cleanText || text);
26705
26616
  await sendResponse(chatId, channel, responseText, msg.messageId);
26706
26617
  try {
26707
26618
  const adapter2 = getAdapterForChat(chatId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-claw",
3
- "version": "0.20.17",
3
+ "version": "0.20.19",
4
4
  "description": "CC-Claw: Personal AI assistant on Telegram — multi-backend (Claude, Gemini, Codex, Cursor), sub-agent orchestration, MCP management",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",