cc-claw 0.20.0 → 0.20.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.
- package/dist/cli.js +124 -14
- 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.
|
|
36
|
+
VERSION = true ? "0.20.2" : (() => {
|
|
37
37
|
try {
|
|
38
38
|
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
|
|
39
39
|
} catch {
|
|
@@ -1774,6 +1774,12 @@ function initSchema(db3) {
|
|
|
1774
1774
|
value INTEGER NOT NULL DEFAULT 0
|
|
1775
1775
|
);
|
|
1776
1776
|
`);
|
|
1777
|
+
db3.exec(`
|
|
1778
|
+
CREATE TABLE IF NOT EXISTS chat_skill_suggestions (
|
|
1779
|
+
chat_id TEXT PRIMARY KEY,
|
|
1780
|
+
value INTEGER NOT NULL DEFAULT 1
|
|
1781
|
+
);
|
|
1782
|
+
`);
|
|
1777
1783
|
db3.exec(`
|
|
1778
1784
|
CREATE TABLE IF NOT EXISTS chat_session_log (
|
|
1779
1785
|
chat_id TEXT PRIMARY KEY,
|
|
@@ -2543,6 +2549,7 @@ __export(chat_settings_exports, {
|
|
|
2543
2549
|
getRecentBookmarks: () => getRecentBookmarks,
|
|
2544
2550
|
getSessionLogEnabled: () => getSessionLogEnabled,
|
|
2545
2551
|
getShowThinkingUi: () => getShowThinkingUi,
|
|
2552
|
+
getSkillSuggestionsEnabled: () => getSkillSuggestionsEnabled,
|
|
2546
2553
|
getSummarizer: () => getSummarizer,
|
|
2547
2554
|
getThinkingLevel: () => getThinkingLevel,
|
|
2548
2555
|
getToolsMap: () => getToolsMap,
|
|
@@ -2559,6 +2566,7 @@ __export(chat_settings_exports, {
|
|
|
2559
2566
|
setModel: () => setModel,
|
|
2560
2567
|
setSessionLogEnabled: () => setSessionLogEnabled,
|
|
2561
2568
|
setShowThinkingUi: () => setShowThinkingUi,
|
|
2569
|
+
setSkillSuggestionsEnabled: () => setSkillSuggestionsEnabled,
|
|
2562
2570
|
setSummarizer: () => setSummarizer,
|
|
2563
2571
|
setThinkingLevel: () => setThinkingLevel,
|
|
2564
2572
|
setVerboseLevel: () => setVerboseLevel,
|
|
@@ -2686,6 +2694,19 @@ function toggleShowThinkingUi(chatId) {
|
|
|
2686
2694
|
setShowThinkingUi(chatId, next);
|
|
2687
2695
|
return next;
|
|
2688
2696
|
}
|
|
2697
|
+
function getSkillSuggestionsEnabled(chatId) {
|
|
2698
|
+
const row = getDb().prepare(
|
|
2699
|
+
"SELECT value FROM chat_skill_suggestions WHERE chat_id = ?"
|
|
2700
|
+
).get(chatId);
|
|
2701
|
+
return (row?.value ?? 1) === 1;
|
|
2702
|
+
}
|
|
2703
|
+
function setSkillSuggestionsEnabled(chatId, enabled) {
|
|
2704
|
+
getDb().prepare(`
|
|
2705
|
+
INSERT INTO chat_skill_suggestions (chat_id, value)
|
|
2706
|
+
VALUES (?, ?)
|
|
2707
|
+
ON CONFLICT(chat_id) DO UPDATE SET value = ?
|
|
2708
|
+
`).run(chatId, enabled ? 1 : 0, enabled ? 1 : 0);
|
|
2709
|
+
}
|
|
2689
2710
|
function getMode(chatId) {
|
|
2690
2711
|
const row = getDb().prepare(
|
|
2691
2712
|
"SELECT mode FROM chat_mode WHERE chat_id = ?"
|
|
@@ -3897,6 +3918,7 @@ __export(store_exports5, {
|
|
|
3897
3918
|
getSessionSummaries: () => getSessionSummaries,
|
|
3898
3919
|
getSessionSummariesWithoutEmbeddings: () => getSessionSummariesWithoutEmbeddings,
|
|
3899
3920
|
getShowThinkingUi: () => getShowThinkingUi,
|
|
3921
|
+
getSkillSuggestionsEnabled: () => getSkillSuggestionsEnabled,
|
|
3900
3922
|
getSummarizer: () => getSummarizer,
|
|
3901
3923
|
getThinkingLevel: () => getThinkingLevel,
|
|
3902
3924
|
getToolsMap: () => getToolsMap,
|
|
@@ -3965,6 +3987,7 @@ __export(store_exports5, {
|
|
|
3965
3987
|
setSessionLogEnabled: () => setSessionLogEnabled,
|
|
3966
3988
|
setSessionStartedAt: () => setSessionStartedAt,
|
|
3967
3989
|
setShowThinkingUi: () => setShowThinkingUi,
|
|
3990
|
+
setSkillSuggestionsEnabled: () => setSkillSuggestionsEnabled,
|
|
3968
3991
|
setSummarizer: () => setSummarizer,
|
|
3969
3992
|
setThinkingLevel: () => setThinkingLevel,
|
|
3970
3993
|
setVerboseLevel: () => setVerboseLevel,
|
|
@@ -7102,7 +7125,7 @@ function searchContext(userMessage) {
|
|
|
7102
7125
|
}
|
|
7103
7126
|
return null;
|
|
7104
7127
|
}
|
|
7105
|
-
async function assembleBootstrapPrompt(userMessage, tier = "full", chatId, permMode, responseStyle, agentMode, sideQuestContext, planningDirective) {
|
|
7128
|
+
async function assembleBootstrapPrompt(userMessage, tier = "full", chatId, permMode, responseStyle, agentMode, sideQuestContext, planningDirective, chatContext) {
|
|
7106
7129
|
const sections = [];
|
|
7107
7130
|
if (planningDirective) {
|
|
7108
7131
|
sections.push(planningDirective);
|
|
@@ -7121,6 +7144,19 @@ async function assembleBootstrapPrompt(userMessage, tier = "full", chatId, permM
|
|
|
7121
7144
|
sections.push("[Response Style]\nYou should be detailed and thorough in your responses. Explain concepts fully and provide comprehensive answers.");
|
|
7122
7145
|
}
|
|
7123
7146
|
}
|
|
7147
|
+
if (chatId && tier !== "slim") {
|
|
7148
|
+
const parts = [`Chat ID: ${chatId}`];
|
|
7149
|
+
if (chatContext?.chatTitle) parts.push(`Group: ${chatContext.chatTitle}`);
|
|
7150
|
+
if (chatContext?.threadId) parts.push(`Forum topic thread: ${chatContext.threadId}`);
|
|
7151
|
+
try {
|
|
7152
|
+
const { getAllChatAliases: getAllChatAliases3 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
7153
|
+
const match = getAllChatAliases3().find((a) => a.chatId === chatId);
|
|
7154
|
+
if (match) parts.push(`Alias: ${match.alias}`);
|
|
7155
|
+
} catch {
|
|
7156
|
+
}
|
|
7157
|
+
sections.push(`[Current chat]
|
|
7158
|
+
${parts.join("\n")}`);
|
|
7159
|
+
}
|
|
7124
7160
|
if (tier === "full") {
|
|
7125
7161
|
const ctx = searchContext(userMessage);
|
|
7126
7162
|
if (ctx) {
|
|
@@ -13578,7 +13614,7 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
13578
13614
|
const tier = bootstrapTier ?? "full";
|
|
13579
13615
|
const effectiveAgentMode = optsAgentMode ?? getAgentMode(settingsChat);
|
|
13580
13616
|
const sideQuestCtx = settingsSourceChatId ? { parentChatId: settingsSourceChatId, actualChatId: chatId } : void 0;
|
|
13581
|
-
const fullPrompt = await assembleBootstrapPrompt(userMessage, tier, settingsChat, mode, responseStyle, effectiveAgentMode, sideQuestCtx, planningDirective);
|
|
13617
|
+
const fullPrompt = await assembleBootstrapPrompt(userMessage, tier, settingsChat, mode, responseStyle, effectiveAgentMode, sideQuestCtx, planningDirective, opts?.chatContext);
|
|
13582
13618
|
if (adapter.streamDirect) {
|
|
13583
13619
|
const resolvedModel2 = model2 ?? adapter.defaultModel;
|
|
13584
13620
|
const abortController = new AbortController();
|
|
@@ -18531,6 +18567,13 @@ Use /skills <page> to navigate (e.g. /skills 2)` : "";
|
|
|
18531
18567
|
if (safePage < totalPages) navRow.push({ label: `Page ${safePage + 1} \u2192`, data: `skills:page:${safePage + 1}` });
|
|
18532
18568
|
buttons.push(navRow);
|
|
18533
18569
|
}
|
|
18570
|
+
const { getSkillSuggestionsEnabled: getSkillSuggestionsEnabled2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
18571
|
+
const extractEnabled = getSkillSuggestionsEnabled2(chatId);
|
|
18572
|
+
buttons.push([{
|
|
18573
|
+
label: `${extractEnabled ? "\u2713" : "\u25CB"} Auto-Extract Skills`,
|
|
18574
|
+
data: "skills:toggle-extract",
|
|
18575
|
+
...extractEnabled ? { style: "primary" } : {}
|
|
18576
|
+
}]);
|
|
18534
18577
|
const header2 = totalPages > 1 ? `${skills2.length} skills (page ${safePage}/${totalPages}). Select one to invoke:` : `${skills2.length} skills available. Select one to invoke:`;
|
|
18535
18578
|
await sendOrEditKeyboard(chatId, channel, messageId, header2, buttons);
|
|
18536
18579
|
}
|
|
@@ -22535,10 +22578,12 @@ import { join as join25 } from "path";
|
|
|
22535
22578
|
import { writeFile as writeFile4, mkdir as mkdir3 } from "fs/promises";
|
|
22536
22579
|
function isSkillWorthy(signals) {
|
|
22537
22580
|
const { toolUseCount, tokenOutput, elapsedMs, userMessage } = signals;
|
|
22538
|
-
if (toolUseCount <
|
|
22581
|
+
if (toolUseCount < 8) return false;
|
|
22539
22582
|
const supplementary = [
|
|
22540
|
-
tokenOutput >=
|
|
22541
|
-
|
|
22583
|
+
tokenOutput >= 3e3,
|
|
22584
|
+
// substantial output
|
|
22585
|
+
elapsedMs >= 45e3
|
|
22586
|
+
// took real effort (45s+)
|
|
22542
22587
|
].filter(Boolean).length;
|
|
22543
22588
|
if (supplementary < 1) return false;
|
|
22544
22589
|
const words = userMessage.split(/\s+/).length;
|
|
@@ -23652,6 +23697,12 @@ Salience: ${memory2.salience.toFixed(2)} | Created: ${memory2.created_at.slice(0
|
|
|
23652
23697
|
Example: /limits ${bid} daily 500000`, { parseMode: "plain" });
|
|
23653
23698
|
}
|
|
23654
23699
|
return;
|
|
23700
|
+
} else if (data === "skills:toggle-extract") {
|
|
23701
|
+
const { getSkillSuggestionsEnabled: getSkillSuggestionsEnabled2, setSkillSuggestionsEnabled: setSkillSuggestionsEnabled2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
23702
|
+
const current = getSkillSuggestionsEnabled2(chatId);
|
|
23703
|
+
setSkillSuggestionsEnabled2(chatId, !current);
|
|
23704
|
+
const skills2 = await discoverAllSkills();
|
|
23705
|
+
await sendSkillsPage(chatId, channel, skills2, 1, messageId);
|
|
23655
23706
|
} else if (data.startsWith("skills:page:")) {
|
|
23656
23707
|
const page = parseInt(data.slice(12), 10);
|
|
23657
23708
|
const skills2 = await discoverAllSkills();
|
|
@@ -23675,12 +23726,42 @@ Example: /limits ${bid} daily 500000`, { parseMode: "plain" });
|
|
|
23675
23726
|
});
|
|
23676
23727
|
const parsed = parseExtractedSkill2(extractionResponse.text);
|
|
23677
23728
|
if (parsed) {
|
|
23678
|
-
const {
|
|
23679
|
-
|
|
23680
|
-
|
|
23681
|
-
|
|
23729
|
+
const { storePendingDraft: updateDraft } = await Promise.resolve().then(() => (init_auto_create(), auto_create_exports));
|
|
23730
|
+
updateDraft(chatId, { ...draft, name: parsed.name, content: parsed.content });
|
|
23731
|
+
const escaped = parsed.content.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
23732
|
+
const header2 = `\u{1F4CB} <b>Skill Preview: "${parsed.name}"</b>
|
|
23682
23733
|
|
|
23683
|
-
|
|
23734
|
+
`;
|
|
23735
|
+
const MAX_PREVIEW = 3500 - header2.length;
|
|
23736
|
+
if (typeof channel.sendKeyboard === "function") {
|
|
23737
|
+
if (escaped.length > MAX_PREVIEW) {
|
|
23738
|
+
await channel.sendText(chatId, `${header2}<pre>${escaped.slice(0, 3500)}</pre>
|
|
23739
|
+
|
|
23740
|
+
\u2026(truncated \u2014 full skill will be saved)`, { parseMode: "html" });
|
|
23741
|
+
await channel.sendKeyboard(
|
|
23742
|
+
chatId,
|
|
23743
|
+
`Save "${parsed.name}" as a reusable skill?`,
|
|
23744
|
+
[[
|
|
23745
|
+
{ label: "\u2705 Save Skill", data: "skill:confirm-save", style: "success" },
|
|
23746
|
+
{ label: "\u2715 Discard", data: "skill:discard" }
|
|
23747
|
+
]]
|
|
23748
|
+
);
|
|
23749
|
+
} else {
|
|
23750
|
+
await channel.sendKeyboard(
|
|
23751
|
+
chatId,
|
|
23752
|
+
`${header2}<pre>${escaped}</pre>`,
|
|
23753
|
+
[[
|
|
23754
|
+
{ label: "\u2705 Save Skill", data: "skill:confirm-save", style: "success" },
|
|
23755
|
+
{ label: "\u2715 Discard", data: "skill:discard" }
|
|
23756
|
+
]]
|
|
23757
|
+
);
|
|
23758
|
+
}
|
|
23759
|
+
} else {
|
|
23760
|
+
const { path } = await saveSkill2(parsed.name, parsed.content);
|
|
23761
|
+
clearPendingDraft2(chatId);
|
|
23762
|
+
await channel.sendText(chatId, `\u2705 Skill "${parsed.name}" saved.
|
|
23763
|
+
Path: ${path}`, { parseMode: "plain" });
|
|
23764
|
+
}
|
|
23684
23765
|
} else {
|
|
23685
23766
|
clearPendingDraft2(chatId);
|
|
23686
23767
|
await channel.sendText(chatId, "Could not extract a well-formed skill from this conversation. Try /remember to save key steps manually.", { parseMode: "plain" });
|
|
@@ -23690,10 +23771,32 @@ Use /skills to see all available skills.`, { parseMode: "plain" });
|
|
|
23690
23771
|
await channel.sendText(chatId, `Skill extraction failed: ${e.message}`, { parseMode: "plain" });
|
|
23691
23772
|
}
|
|
23692
23773
|
return;
|
|
23774
|
+
} else if (data === "skill:confirm-save") {
|
|
23775
|
+
const { getPendingDraft: getPendingDraft2, clearPendingDraft: clearPendingDraft2, saveSkill: saveSkill2 } = await Promise.resolve().then(() => (init_auto_create(), auto_create_exports));
|
|
23776
|
+
const draft = getPendingDraft2(chatId);
|
|
23777
|
+
if (!draft || !draft.name || !draft.content) {
|
|
23778
|
+
await channel.sendText(chatId, "No pending skill to save.", { parseMode: "plain" });
|
|
23779
|
+
return;
|
|
23780
|
+
}
|
|
23781
|
+
try {
|
|
23782
|
+
const { path } = await saveSkill2(draft.name, draft.content);
|
|
23783
|
+
clearPendingDraft2(chatId);
|
|
23784
|
+
if (messageId) await replaceWithText(`\u2705 Skill "${draft.name}" saved.
|
|
23785
|
+
Path: ${path}
|
|
23786
|
+
|
|
23787
|
+
Use /skills to see all available skills.`);
|
|
23788
|
+
else await channel.sendText(chatId, `\u2705 Skill "${draft.name}" saved.
|
|
23789
|
+
Path: ${path}
|
|
23790
|
+
|
|
23791
|
+
Use /skills to see all available skills.`, { parseMode: "plain" });
|
|
23792
|
+
} catch (e) {
|
|
23793
|
+
await channel.sendText(chatId, `Failed to save skill: ${e.message}`, { parseMode: "plain" });
|
|
23794
|
+
}
|
|
23795
|
+
return;
|
|
23693
23796
|
} else if (data === "skill:discard") {
|
|
23694
23797
|
const { clearPendingDraft: clearPendingDraft2 } = await Promise.resolve().then(() => (init_auto_create(), auto_create_exports));
|
|
23695
23798
|
clearPendingDraft2(chatId);
|
|
23696
|
-
|
|
23799
|
+
if (messageId) await replaceWithText("\u{1F44C} Noted.");
|
|
23697
23800
|
return;
|
|
23698
23801
|
} else if (data.startsWith("skill:")) {
|
|
23699
23802
|
const parts = data.slice(6).split(":");
|
|
@@ -24597,6 +24700,7 @@ Debating: "${question.slice(0, 100)}${question.length > 100 ? "\u2026" : ""}"`,
|
|
|
24597
24700
|
maxTurns,
|
|
24598
24701
|
agentMode: effectiveAgentMode,
|
|
24599
24702
|
...effectiveThinking ? { thinkingLevel: effectiveThinking } : {},
|
|
24703
|
+
chatContext: { chatTitle: msg.chatTitle, threadId: msg.threadId },
|
|
24600
24704
|
onThinking: liveStatus || sessionLog ? (chunk) => {
|
|
24601
24705
|
if (liveStatus) liveStatus.addThinking(chunk);
|
|
24602
24706
|
if (sessionLog) sessionLog.logThinking(chunk);
|
|
@@ -24702,7 +24806,8 @@ Debating: "${question.slice(0, 100)}${question.length > 100 ? "\u2026" : ""}"`,
|
|
|
24702
24806
|
log(`[reflection] Signal detection error: ${e}`);
|
|
24703
24807
|
}
|
|
24704
24808
|
try {
|
|
24705
|
-
|
|
24809
|
+
const { getSkillSuggestionsEnabled: getSkillSuggestionsEnabled2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
24810
|
+
if (intent === "agentic" && toolUseCount > 0 && getSkillSuggestionsEnabled2(chatId)) {
|
|
24706
24811
|
const { isSkillWorthy: isSkillWorthy2 } = await Promise.resolve().then(() => (init_auto_create(), auto_create_exports));
|
|
24707
24812
|
const signals = {
|
|
24708
24813
|
toolUseCount,
|
|
@@ -24712,6 +24817,7 @@ Debating: "${question.slice(0, 100)}${question.length > 100 ? "\u2026" : ""}"`,
|
|
|
24712
24817
|
};
|
|
24713
24818
|
if (isSkillWorthy2(signals) && typeof channel.sendKeyboard === "function") {
|
|
24714
24819
|
const { storePendingDraft: storePendingDraft2 } = await Promise.resolve().then(() => (init_auto_create(), auto_create_exports));
|
|
24820
|
+
const taskSummary = (cleanText || text).slice(0, 120) + ((cleanText || text).length > 120 ? "\u2026" : "");
|
|
24715
24821
|
storePendingDraft2(chatId, {
|
|
24716
24822
|
name: "",
|
|
24717
24823
|
content: "",
|
|
@@ -24720,7 +24826,11 @@ Debating: "${question.slice(0, 100)}${question.length > 100 ? "\u2026" : ""}"`,
|
|
|
24720
24826
|
});
|
|
24721
24827
|
await channel.sendKeyboard(
|
|
24722
24828
|
chatId,
|
|
24723
|
-
|
|
24829
|
+
`\u{1F4A1} That looked like a reusable workflow:
|
|
24830
|
+
|
|
24831
|
+
"${taskSummary}"
|
|
24832
|
+
|
|
24833
|
+
Want me to extract it as a reusable skill? (${toolUseCount} tools used, ${elapsedSec}s)`,
|
|
24724
24834
|
[[
|
|
24725
24835
|
{ label: "\u2705 Extract Skill", data: "skill:extract", style: "success" },
|
|
24726
24836
|
{ label: "\u2715 No thanks", data: "skill:discard" }
|
package/package.json
CHANGED