cc-claw 0.11.0 → 0.11.1
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 +138 -13
- 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.
|
|
75
|
+
VERSION = true ? "0.11.1" : (() => {
|
|
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
|
}
|
|
@@ -12680,16 +12686,20 @@ function pct(ratio) {
|
|
|
12680
12686
|
return `${Math.round(ratio * 100)}%`;
|
|
12681
12687
|
}
|
|
12682
12688
|
function formatProposalCard(params) {
|
|
12683
|
-
const { category, insight, why, targetFile, confidence } = params;
|
|
12689
|
+
const { category, insight, why, targetFile, confidence, proposedAction, proposedDiff } = params;
|
|
12684
12690
|
const header2 = `[${category}] ${insight}`;
|
|
12685
|
-
const whyLine = `Why: ${why}
|
|
12691
|
+
const whyLine = why ? `Why: ${why}` : null;
|
|
12686
12692
|
const confidencePct = pct(confidence);
|
|
12687
12693
|
const showTarget = category !== "codebase" && targetFile && targetFile !== "codebase";
|
|
12688
12694
|
const targetLine = showTarget ? `Target: ${targetFile} | Confidence: ${confidencePct}` : `Confidence: ${confidencePct}`;
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
|
|
12695
|
+
const lines = [header2, ""];
|
|
12696
|
+
if (whyLine) lines.push(whyLine);
|
|
12697
|
+
lines.push(targetLine);
|
|
12698
|
+
if (proposedDiff) {
|
|
12699
|
+
const actionLabel = proposedAction ? ` (${proposedAction})` : "";
|
|
12700
|
+
lines.push("", `Proposed change${actionLabel}:`, "```diff", proposedDiff, "```");
|
|
12701
|
+
}
|
|
12702
|
+
return lines.join("\n");
|
|
12693
12703
|
}
|
|
12694
12704
|
function formatNightlySummary(insights) {
|
|
12695
12705
|
const count = insights.length;
|
|
@@ -12734,7 +12744,7 @@ function buildProposalKeyboard(insightId, category) {
|
|
|
12734
12744
|
return [
|
|
12735
12745
|
[
|
|
12736
12746
|
{ label: "Show Diff", data: `evolve:diff:${insightId}`, style: "primary" },
|
|
12737
|
-
{ label: "
|
|
12747
|
+
{ label: "Discuss", data: `evolve:discuss:${insightId}` },
|
|
12738
12748
|
{ label: "Reject", data: `evolve:reject:${insightId}`, style: "danger" }
|
|
12739
12749
|
]
|
|
12740
12750
|
];
|
|
@@ -12742,7 +12752,7 @@ function buildProposalKeyboard(insightId, category) {
|
|
|
12742
12752
|
return [
|
|
12743
12753
|
[
|
|
12744
12754
|
{ label: "Apply", data: `evolve:apply:${insightId}`, style: "success" },
|
|
12745
|
-
{ label: "
|
|
12755
|
+
{ label: "Discuss", data: `evolve:discuss:${insightId}` },
|
|
12746
12756
|
{ label: "Reject", data: `evolve:reject:${insightId}`, style: "danger" }
|
|
12747
12757
|
]
|
|
12748
12758
|
];
|
|
@@ -14901,6 +14911,26 @@ async function handleText(msg, channel) {
|
|
|
14901
14911
|
await handleWizardText(chatId, text, channel);
|
|
14902
14912
|
return;
|
|
14903
14913
|
}
|
|
14914
|
+
const discussingInsightId = activeProposalDiscussion.get(chatId);
|
|
14915
|
+
if (discussingInsightId !== void 0) {
|
|
14916
|
+
if (text.toLowerCase() === "done") {
|
|
14917
|
+
activeProposalDiscussion.delete(chatId);
|
|
14918
|
+
const { getInsightById: getInsightById2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
14919
|
+
const { formatProposalCard: formatProposalCard2, buildProposalKeyboard: buildProposalKeyboard2 } = await Promise.resolve().then(() => (init_propose(), propose_exports));
|
|
14920
|
+
const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
14921
|
+
const insight = getInsightById2(getDb2(), discussingInsightId);
|
|
14922
|
+
if (insight && insight.status === "pending") {
|
|
14923
|
+
const card = formatProposalCard2(insight);
|
|
14924
|
+
const kb = buildProposalKeyboard2(insight.id, insight.category);
|
|
14925
|
+
await channel.sendKeyboard(chatId, "Discussion complete. Updated proposal:\n\n" + card, kb);
|
|
14926
|
+
} else {
|
|
14927
|
+
await channel.sendText(chatId, "Discussion ended.", { parseMode: "plain" });
|
|
14928
|
+
}
|
|
14929
|
+
return;
|
|
14930
|
+
}
|
|
14931
|
+
await handleProposalDiscussion(chatId, discussingInsightId, text, channel);
|
|
14932
|
+
return;
|
|
14933
|
+
}
|
|
14904
14934
|
const rememberMatch = text.match(/^remember\s+(?:that\s+)?(.+)/i);
|
|
14905
14935
|
if (rememberMatch) {
|
|
14906
14936
|
const content = rememberMatch[1];
|
|
@@ -15128,6 +15158,65 @@ After installing, restart the service: cc-claw service restart`;
|
|
|
15128
15158
|
}
|
|
15129
15159
|
return `Error: ${msg}`;
|
|
15130
15160
|
}
|
|
15161
|
+
async function handleProposalDiscussion(chatId, insightId, userQuestion, channel) {
|
|
15162
|
+
const { getInsightById: getInsightById2, updateInsightProposal: updateInsightProposal2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
15163
|
+
const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
15164
|
+
const insight = getInsightById2(getDb2(), insightId);
|
|
15165
|
+
if (!insight) {
|
|
15166
|
+
activeProposalDiscussion.delete(chatId);
|
|
15167
|
+
await channel.sendText(chatId, "Proposal not found. Discussion ended.", { parseMode: "plain" });
|
|
15168
|
+
return;
|
|
15169
|
+
}
|
|
15170
|
+
const prompt = [
|
|
15171
|
+
`You are reviewing a self-learning proposal with the user. They want to discuss it before deciding whether to apply, modify, or reject it.`,
|
|
15172
|
+
``,
|
|
15173
|
+
`Current proposal:`,
|
|
15174
|
+
`- Category: ${insight.category}`,
|
|
15175
|
+
`- Insight: ${insight.insight}`,
|
|
15176
|
+
`- Why: ${insight.why ?? "not specified"}`,
|
|
15177
|
+
`- Target file: ${insight.targetFile ?? "not specified"}`,
|
|
15178
|
+
`- Proposed action: ${insight.proposedAction ?? "not specified"}`,
|
|
15179
|
+
`- Proposed diff: ${insight.proposedDiff ?? "none"}`,
|
|
15180
|
+
`- Confidence: ${Math.round(insight.confidence * 100)}%`,
|
|
15181
|
+
``,
|
|
15182
|
+
`The user asks: "${userQuestion}"`,
|
|
15183
|
+
``,
|
|
15184
|
+
`Answer their question honestly. If they suggest retargeting to a different file or modifying the proposal, agree if it makes sense and output one of these markers:`,
|
|
15185
|
+
`- [RETARGET:filepath] \u2014 to change the target file (e.g., [RETARGET:skills/newsroom/SKILL.md])`,
|
|
15186
|
+
`- [REVISE_DIFF:new diff text] \u2014 to update the proposed change`,
|
|
15187
|
+
`- [REVISE_ACTION:action] \u2014 to change the action type (append/replace/etc.)`,
|
|
15188
|
+
``,
|
|
15189
|
+
`Only output markers when the user explicitly asks for a change. Otherwise just discuss.`,
|
|
15190
|
+
`Keep responses concise \u2014 this is a quick review conversation, not an essay.`
|
|
15191
|
+
].join("\n");
|
|
15192
|
+
try {
|
|
15193
|
+
await channel.sendTyping?.(chatId);
|
|
15194
|
+
const response = await askAgent(chatId, prompt, {
|
|
15195
|
+
bootstrapTier: "chat",
|
|
15196
|
+
maxTurns: 1,
|
|
15197
|
+
timeoutMs: 6e4
|
|
15198
|
+
});
|
|
15199
|
+
const responseText = response.text ?? "";
|
|
15200
|
+
const retargetMatch = responseText.match(/\[RETARGET:([^\]]+)\]/);
|
|
15201
|
+
const reviseDiffMatch = responseText.match(/\[REVISE_DIFF:([^\]]+)\]/);
|
|
15202
|
+
const reviseActionMatch = responseText.match(/\[REVISE_ACTION:([^\]]+)\]/);
|
|
15203
|
+
if (retargetMatch || reviseDiffMatch || reviseActionMatch) {
|
|
15204
|
+
const newTarget = retargetMatch?.[1]?.trim() ?? insight.targetFile ?? "";
|
|
15205
|
+
const newDiff = reviseDiffMatch?.[1]?.trim() ?? insight.proposedDiff ?? null;
|
|
15206
|
+
const newAction = reviseActionMatch?.[1]?.trim() ?? insight.proposedAction ?? null;
|
|
15207
|
+
updateInsightProposal2(getDb2(), insightId, newTarget, newDiff, newAction);
|
|
15208
|
+
}
|
|
15209
|
+
const cleanText = responseText.replace(/\[RETARGET:[^\]]+\]/g, "").replace(/\[REVISE_DIFF:[^\]]+\]/g, "").replace(/\[REVISE_ACTION:[^\]]+\]/g, "").trim();
|
|
15210
|
+
if (cleanText) {
|
|
15211
|
+
await channel.sendText(chatId, cleanText);
|
|
15212
|
+
}
|
|
15213
|
+
await channel.sendKeyboard(chatId, "Continue discussing, or type 'done' to finish.", [
|
|
15214
|
+
[{ label: "Done \u2014 show updated proposal", data: `evolve:discuss-done:${insightId}` }]
|
|
15215
|
+
]);
|
|
15216
|
+
} catch (err) {
|
|
15217
|
+
await channel.sendText(chatId, `Discussion error: ${err.message}`, { parseMode: "plain" });
|
|
15218
|
+
}
|
|
15219
|
+
}
|
|
15131
15220
|
async function handleSideQuest(parentChatId, msg, channel) {
|
|
15132
15221
|
const sqId = `sq:${parentChatId}:${randomUUID3()}`;
|
|
15133
15222
|
const active = activeSideQuests.get(parentChatId) ?? /* @__PURE__ */ new Set();
|
|
@@ -16464,7 +16553,8 @@ Result: ${task.result.slice(0, 500)}` : ""
|
|
|
16464
16553
|
if (insights.length === 0) {
|
|
16465
16554
|
await channel.sendText(chatId, "No new insights from recent interactions.", { parseMode: "plain" });
|
|
16466
16555
|
} else {
|
|
16467
|
-
|
|
16556
|
+
const nightlyItems = insights.map((ins, i) => ({ id: i + 1, ...ins }));
|
|
16557
|
+
await channel.sendText(chatId, formatNightlySummary2(nightlyItems), { parseMode: "plain" });
|
|
16468
16558
|
}
|
|
16469
16559
|
} catch (e) {
|
|
16470
16560
|
await channel.sendText(chatId, `Analysis failed: ${e}`, { parseMode: "plain" });
|
|
@@ -16510,6 +16600,29 @@ Result: ${task.result.slice(0, 500)}` : ""
|
|
|
16510
16600
|
await channel.sendText(chatId, "Skipped \u2014 will show again next review.", { parseMode: "plain" });
|
|
16511
16601
|
break;
|
|
16512
16602
|
}
|
|
16603
|
+
case "discuss": {
|
|
16604
|
+
const insId = parseInt(idStr, 10);
|
|
16605
|
+
activeProposalDiscussion.set(chatId, insId);
|
|
16606
|
+
await channel.sendKeyboard(chatId, `Discussing proposal #${insId}. Send your questions \u2014 type "done" when finished.`, [
|
|
16607
|
+
[{ label: "Done", data: `evolve:discuss-done:${insId}` }]
|
|
16608
|
+
]);
|
|
16609
|
+
break;
|
|
16610
|
+
}
|
|
16611
|
+
case "discuss-done": {
|
|
16612
|
+
activeProposalDiscussion.delete(chatId);
|
|
16613
|
+
const { getInsightById: getIns } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
16614
|
+
const { formatProposalCard: fmtCard, buildProposalKeyboard: buildKb } = await Promise.resolve().then(() => (init_propose(), propose_exports));
|
|
16615
|
+
const { getDb: getDatabase } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
16616
|
+
const ins = getIns(getDatabase(), parseInt(idStr, 10));
|
|
16617
|
+
if (ins && ins.status === "pending") {
|
|
16618
|
+
const card = fmtCard(ins);
|
|
16619
|
+
const kb = buildKb(ins.id, ins.category);
|
|
16620
|
+
await channel.sendKeyboard(chatId, "Updated proposal:\n\n" + card, kb);
|
|
16621
|
+
} else {
|
|
16622
|
+
await channel.sendText(chatId, "Discussion ended.", { parseMode: "plain" });
|
|
16623
|
+
}
|
|
16624
|
+
break;
|
|
16625
|
+
}
|
|
16513
16626
|
case "reject": {
|
|
16514
16627
|
const { updateInsightStatus: updateInsightStatus2 } = await Promise.resolve().then(() => (init_store4(), store_exports4));
|
|
16515
16628
|
const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
@@ -16524,7 +16637,18 @@ Result: ${task.result.slice(0, 500)}` : ""
|
|
|
16524
16637
|
const { getDb: getDb2 } = await Promise.resolve().then(() => (init_store5(), store_exports5));
|
|
16525
16638
|
const reportData = buildGrowthReportData2(getDb2(), chatId, 30);
|
|
16526
16639
|
const modelData = buildModelPerformanceData2(getDb2(), chatId, 30);
|
|
16527
|
-
|
|
16640
|
+
const metricsForReport = {
|
|
16641
|
+
correctionsBefore: reportData.avgCorrectionsFirstHalf,
|
|
16642
|
+
correctionsAfter: reportData.avgCorrectionsSecondHalf,
|
|
16643
|
+
praiseRatio: reportData.praiseRatio,
|
|
16644
|
+
insightsApplied: reportData.totalInsightsApplied,
|
|
16645
|
+
pendingCount: reportData.pendingCount,
|
|
16646
|
+
topInsight: reportData.topInsightId != null ? {
|
|
16647
|
+
insight: `#${reportData.topInsightId}`,
|
|
16648
|
+
effectiveness: reportData.topInsightEffectiveness ?? 0
|
|
16649
|
+
} : null
|
|
16650
|
+
};
|
|
16651
|
+
let report = formatGrowthReport2(metricsForReport, modelData);
|
|
16528
16652
|
const drift = calculateDrift2(chatId);
|
|
16529
16653
|
if (drift && (drift.soulDrift > 0.5 || drift.userDrift > 0.5)) {
|
|
16530
16654
|
report += "\n\nSOUL.md has changed significantly since reflection started.\nTap History in /evolve to review all applied changes.";
|
|
@@ -16569,7 +16693,7 @@ Result: ${task.result.slice(0, 500)}` : ""
|
|
|
16569
16693
|
logActivity2(getDb2(), { chatId, source: "telegram", eventType: "reflection_unfrozen", summary: "Reflection enabled" });
|
|
16570
16694
|
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
16695
|
} else {
|
|
16572
|
-
setReflectionStatus2(getDb2(), chatId, "frozen",
|
|
16696
|
+
setReflectionStatus2(getDb2(), chatId, "frozen", void 0, void 0);
|
|
16573
16697
|
const { logActivity: logActivity2 } = await Promise.resolve().then(() => (init_store3(), store_exports3));
|
|
16574
16698
|
logActivity2(getDb2(), { chatId, source: "telegram", eventType: "reflection_frozen", summary: "Reflection disabled" });
|
|
16575
16699
|
await channel.sendText(chatId, "\u26D4 Self-learning disabled. No signals will be collected.", { parseMode: "plain" });
|
|
@@ -17157,7 +17281,7 @@ Use /skills <page> to navigate (e.g. /skills 2)` : "";
|
|
|
17157
17281
|
const header2 = totalPages > 1 ? `${skills2.length} skills (page ${safePage}/${totalPages}). Select one to invoke:` : `${skills2.length} skills available. Select one to invoke:`;
|
|
17158
17282
|
await channel.sendKeyboard(chatId, header2, buttons);
|
|
17159
17283
|
}
|
|
17160
|
-
var PERM_MODES, VERBOSE_LEVELS, HELP_CATEGORIES, USAGE_WINDOW_MAP, MEDIA_INCOMING_PATH, TONE_PATTERNS, pendingInterrupts, bypassBusyCheck, activeSideQuests, MAX_SIDE_QUESTS, pendingFallbackMessages, dashboardClawWarnings, pendingSummaryUndo, pendingNewchatUndo, CLI_INSTALL_HINTS, BLOCKED_PATH_PATTERNS2, ALLOWED_REACTION_EMOJIS, SKILLS_PER_PAGE;
|
|
17284
|
+
var PERM_MODES, VERBOSE_LEVELS, HELP_CATEGORIES, USAGE_WINDOW_MAP, MEDIA_INCOMING_PATH, TONE_PATTERNS, pendingInterrupts, bypassBusyCheck, activeSideQuests, MAX_SIDE_QUESTS, activeProposalDiscussion, pendingFallbackMessages, dashboardClawWarnings, pendingSummaryUndo, pendingNewchatUndo, CLI_INSTALL_HINTS, BLOCKED_PATH_PATTERNS2, ALLOWED_REACTION_EMOJIS, SKILLS_PER_PAGE;
|
|
17161
17285
|
var init_router = __esm({
|
|
17162
17286
|
"src/router.ts"() {
|
|
17163
17287
|
"use strict";
|
|
@@ -17298,6 +17422,7 @@ var init_router = __esm({
|
|
|
17298
17422
|
bypassBusyCheck = /* @__PURE__ */ new Set();
|
|
17299
17423
|
activeSideQuests = /* @__PURE__ */ new Map();
|
|
17300
17424
|
MAX_SIDE_QUESTS = 2;
|
|
17425
|
+
activeProposalDiscussion = /* @__PURE__ */ new Map();
|
|
17301
17426
|
pendingFallbackMessages = /* @__PURE__ */ new Map();
|
|
17302
17427
|
dashboardClawWarnings = /* @__PURE__ */ new Map();
|
|
17303
17428
|
pendingSummaryUndo = /* @__PURE__ */ new Map();
|
package/package.json
CHANGED