chatccc 0.2.196 → 0.2.198
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/agent-prompts/cursor_specific.md +13 -13
- package/bin/cccagent.mjs +17 -17
- package/config.sample.json +27 -27
- package/package.json +2 -1
- package/src/__tests__/agent-reload-config-rpc.test.ts +99 -0
- package/src/__tests__/builtin-chat-session.test.ts +277 -181
- package/src/__tests__/builtin-cli-json.test.ts +39 -39
- package/src/__tests__/builtin-config.test.ts +33 -33
- package/src/__tests__/builtin-context.test.ts +163 -163
- package/src/__tests__/builtin-file-tools.test.ts +224 -196
- package/src/__tests__/builtin-session-select.test.ts +116 -116
- package/src/__tests__/builtin-sigint.test.ts +56 -56
- package/src/__tests__/cards.test.ts +109 -109
- package/src/__tests__/ccc-adapter.test.ts +114 -113
- package/src/__tests__/chatgpt-subscription-rpc.test.ts +89 -89
- package/src/__tests__/chatgpt-subscription.test.ts +135 -135
- package/src/__tests__/chrome-devtools-guard.test.ts +165 -165
- package/src/__tests__/claude-raw-stream-log.test.ts +87 -0
- package/src/__tests__/codex-raw-stream-log.test.ts +163 -0
- package/src/__tests__/config-reload.test.ts +10 -10
- package/src/__tests__/config-sample.test.ts +18 -18
- package/src/__tests__/cursor-adapter.test.ts +167 -113
- package/src/__tests__/feishu-avatar.test.ts +40 -40
- package/src/__tests__/jsonl-stream.test.ts +79 -0
- package/src/__tests__/orchestrator.test.ts +181 -154
- package/src/__tests__/raw-stream-log.test.ts +106 -106
- package/src/__tests__/session.test.ts +40 -40
- package/src/__tests__/sim-platform.test.ts +12 -12
- package/src/__tests__/web-ui.test.ts +209 -209
- package/src/adapters/ccc-adapter.ts +121 -119
- package/src/adapters/claude-adapter.ts +603 -566
- package/src/adapters/codex-adapter.ts +65 -52
- package/src/adapters/cursor-adapter.ts +269 -276
- package/src/adapters/jsonl-stream.ts +157 -0
- package/src/adapters/raw-stream-log.ts +124 -124
- package/src/agent-reload-config-rpc.ts +34 -0
- package/src/builtin/cli.ts +473 -461
- package/src/builtin/context.ts +323 -323
- package/src/builtin/file-tools.ts +1072 -915
- package/src/builtin/index.ts +404 -353
- package/src/builtin/session-select.ts +48 -48
- package/src/builtin/sigint.ts +50 -50
- package/src/cards.ts +195 -195
- package/src/chatgpt-subscription-rpc.ts +27 -27
- package/src/chatgpt-subscription.ts +299 -299
- package/src/chrome-devtools-guard.ts +318 -318
- package/src/config.ts +125 -125
- package/src/feishu-api.ts +49 -49
- package/src/index.ts +8 -13
- package/src/orchestrator.ts +166 -145
- package/src/runtime-reload.ts +34 -0
- package/src/session.ts +141 -141
- package/src/web-ui.ts +205 -205
package/src/orchestrator.ts
CHANGED
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
PROJECT_ROOT,
|
|
23
23
|
anthropicConfigDisplay,
|
|
24
24
|
config,
|
|
25
|
-
fileLog,
|
|
26
|
-
getAllEffortsForTool,
|
|
27
|
-
getAllModelsForTool,
|
|
28
|
-
getDefaultEffortForTool,
|
|
29
|
-
getDefaultCwd,
|
|
25
|
+
fileLog,
|
|
26
|
+
getAllEffortsForTool,
|
|
27
|
+
getAllModelsForTool,
|
|
28
|
+
getDefaultEffortForTool,
|
|
29
|
+
getDefaultCwd,
|
|
30
30
|
setDefaultCwd,
|
|
31
31
|
getRecentDirs,
|
|
32
32
|
addRecentDir,
|
|
@@ -34,13 +34,12 @@ import {
|
|
|
34
34
|
sessionPrefixForTool,
|
|
35
35
|
toolDisplayName,
|
|
36
36
|
ts,
|
|
37
|
-
reloadConfigFromDisk,
|
|
38
37
|
type AgentTool,
|
|
39
38
|
} from "./config.ts";
|
|
40
39
|
import {
|
|
41
|
-
buildHelpCard,
|
|
42
|
-
buildEffortCard,
|
|
43
|
-
buildModelCard,
|
|
40
|
+
buildHelpCard,
|
|
41
|
+
buildEffortCard,
|
|
42
|
+
buildModelCard,
|
|
44
43
|
buildStatusCard,
|
|
45
44
|
buildCdContent,
|
|
46
45
|
buildCdCard,
|
|
@@ -55,21 +54,21 @@ import {
|
|
|
55
54
|
runGitCommand,
|
|
56
55
|
} from "./git-command.ts";
|
|
57
56
|
import {
|
|
58
|
-
clearSessionModelOverride,
|
|
59
|
-
clearSessionEffortOverride,
|
|
57
|
+
clearSessionModelOverride,
|
|
58
|
+
clearSessionEffortOverride,
|
|
60
59
|
getSessionStatus,
|
|
61
60
|
getAllSessionsStatus,
|
|
62
61
|
initClaudeSession,
|
|
63
62
|
lastMsgTimestamps,
|
|
64
63
|
resumeAndPrompt,
|
|
65
64
|
sessionInfoMap,
|
|
66
|
-
setSessionModelOverride,
|
|
67
|
-
setSessionEffortOverride,
|
|
65
|
+
setSessionModelOverride,
|
|
66
|
+
setSessionEffortOverride,
|
|
68
67
|
switchChatBinding,
|
|
69
68
|
recordSessionRegistry,
|
|
70
69
|
getAdapterForTool,
|
|
71
|
-
getEffectiveModelForTool,
|
|
72
|
-
getEffectiveEffortForTool,
|
|
70
|
+
getEffectiveModelForTool,
|
|
71
|
+
getEffectiveEffortForTool,
|
|
73
72
|
stopSession,
|
|
74
73
|
loadSessionRegistryForBinding,
|
|
75
74
|
removeSessionRegistryRecord,
|
|
@@ -91,6 +90,7 @@ import { getChatGptSubscriptionStatus, type ChatGptSubscriptionResult } from "./
|
|
|
91
90
|
import { delegateAgentTask } from "./agent-delegate-task.ts";
|
|
92
91
|
import { applySharedPrefix } from "./shared-prefix.ts";
|
|
93
92
|
import { cwdDisplayName, sessionChatName } from "./session-name.ts";
|
|
93
|
+
import { reloadRuntimeConfig } from "./runtime-reload.ts";
|
|
94
94
|
export { type PlatformAdapter } from "./platform-adapter.ts";
|
|
95
95
|
import type { ChatAvatarUsageHints, PlatformAdapter } from "./platform-adapter.ts";
|
|
96
96
|
import type { CodexUsageSummary } from "./feishu-api.ts";
|
|
@@ -548,6 +548,27 @@ export async function handleCommand(
|
|
|
548
548
|
recordChatPlatform(chatId, platform);
|
|
549
549
|
await cleanupNonWechatP2pBinding(platform, chatId, chatType, tid);
|
|
550
550
|
|
|
551
|
+
if (isCommandText && textLower === "/reload") {
|
|
552
|
+
logTrace(tid, "BRANCH", { cmd: "/reload" });
|
|
553
|
+
try {
|
|
554
|
+
const result = await reloadRuntimeConfig("chat-command");
|
|
555
|
+
await platform.sendText(
|
|
556
|
+
chatId,
|
|
557
|
+
[
|
|
558
|
+
"配置已重新加载。",
|
|
559
|
+
`默认 Agent: ${toolDisplayName(result.defaultAgent)}`,
|
|
560
|
+
`配置文件: ${result.configPath}`,
|
|
561
|
+
"后续新会话会使用最新配置;正在生成的会话不会被中断。",
|
|
562
|
+
].join("\n"),
|
|
563
|
+
).catch(() => {});
|
|
564
|
+
logTrace(tid, "DONE", { outcome: "reload", defaultAgent: result.defaultAgent });
|
|
565
|
+
} catch (err) {
|
|
566
|
+
await platform.sendText(chatId, `配置重载失败:${(err as Error).message}`).catch(() => {});
|
|
567
|
+
logTrace(tid, "DONE", { outcome: "reload_fail", error: (err as Error).message });
|
|
568
|
+
}
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
|
|
551
572
|
if (isCommandText && textLower === "/restart") {
|
|
552
573
|
logTrace(tid, "BRANCH", { cmd: "/restart" });
|
|
553
574
|
await platform.sendText(chatId, "重启中...请几秒后发消息唤醒我").catch(() => {});
|
|
@@ -742,7 +763,7 @@ export async function handleCommand(
|
|
|
742
763
|
const toolArg = text.slice(5).trim().toLowerCase();
|
|
743
764
|
const tool = toolArg || resolveDefaultAgentTool();
|
|
744
765
|
logTrace(tid, "BRANCH", { cmd: "/new", tool });
|
|
745
|
-
const validTools = ["claude", "cursor", "codex", "ccc"];
|
|
766
|
+
const validTools = ["claude", "cursor", "codex", "ccc"];
|
|
746
767
|
if (!validTools.includes(tool)) {
|
|
747
768
|
logTrace(tid, "DONE", { outcome: "new_invalid_tool", tool });
|
|
748
769
|
await platform.sendCard(
|
|
@@ -1534,96 +1555,96 @@ export async function handleCommand(
|
|
|
1534
1555
|
}
|
|
1535
1556
|
|
|
1536
1557
|
// /git <args>:在「当前会话工作目录」执行 git 命令
|
|
1537
|
-
if (isCommandText && textLower === "/effort clear") {
|
|
1538
|
-
logTrace(tid, "BRANCH", { cmd: "/effort clear", sessionId, tool: descriptionTool });
|
|
1539
|
-
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1540
|
-
const toolLabel = toolDisplayName(descriptionTool);
|
|
1541
|
-
if (efforts.length === 0) {
|
|
1542
|
-
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1543
|
-
await (platform.kind === "wechat"
|
|
1544
|
-
? platform.sendText(chatId, msg)
|
|
1545
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1546
|
-
).catch(() => {});
|
|
1547
|
-
logTrace(tid, "DONE", { outcome: "effort_unsupported", tool: descriptionTool });
|
|
1548
|
-
return;
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
clearSessionEffortOverride(sessionId);
|
|
1552
|
-
const defaultEffort = getDefaultEffortForTool(descriptionTool as AgentTool);
|
|
1553
|
-
const msg = `已清除当前 ${toolLabel} 会话的 effort 覆盖,恢复使用: \`${defaultEffort || "(未指定)"}\``;
|
|
1554
|
-
await (platform.kind === "wechat"
|
|
1555
|
-
? platform.sendText(chatId, msg)
|
|
1556
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "green")
|
|
1557
|
-
).catch(() => {});
|
|
1558
|
-
logTrace(tid, "DONE", { outcome: "effort_cleared", sessionId, tool: descriptionTool });
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
if (isCommandText && textLower.startsWith("/effort ")) {
|
|
1563
|
-
const effortArg = text.slice(8).trim();
|
|
1564
|
-
if (!effortArg) return;
|
|
1565
|
-
logTrace(tid, "BRANCH", { cmd: "/effort", arg: effortArg, sessionId, tool: descriptionTool });
|
|
1566
|
-
|
|
1567
|
-
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1568
|
-
const toolLabel = toolDisplayName(descriptionTool);
|
|
1569
|
-
if (efforts.length === 0) {
|
|
1570
|
-
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1571
|
-
await (platform.kind === "wechat"
|
|
1572
|
-
? platform.sendText(chatId, msg)
|
|
1573
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1574
|
-
).catch(() => {});
|
|
1575
|
-
logTrace(tid, "DONE", { outcome: "effort_unsupported", tool: descriptionTool });
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
const target = findModelMatch(effortArg, efforts);
|
|
1580
|
-
if (!target) {
|
|
1581
|
-
const msg = `未找到匹配 "${effortArg}" 的 effort。当前 ${toolLabel} 可选 effort:\n${efforts.map(e => ` \`${e}\``).join("\n")}`;
|
|
1582
|
-
await (platform.kind === "wechat"
|
|
1583
|
-
? platform.sendText(chatId, msg)
|
|
1584
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1585
|
-
).catch(() => {});
|
|
1586
|
-
logTrace(tid, "DONE", { outcome: "effort_not_found", arg: effortArg, tool: descriptionTool });
|
|
1587
|
-
return;
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
setSessionEffortOverride(sessionId, target);
|
|
1591
|
-
const msg = `已切换当前 ${toolLabel} 会话 effort 为: \`${target}\``;
|
|
1592
|
-
await (platform.kind === "wechat"
|
|
1593
|
-
? platform.sendText(chatId, msg)
|
|
1594
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "green")
|
|
1595
|
-
).catch(() => {});
|
|
1596
|
-
logTrace(tid, "DONE", { outcome: "effort_switched", arg: effortArg, target, sessionId, tool: descriptionTool });
|
|
1597
|
-
return;
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
if (isCommandText && textLower === "/effort") {
|
|
1601
|
-
logTrace(tid, "BRANCH", { cmd: "/effort", sessionId, tool: descriptionTool });
|
|
1602
|
-
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1603
|
-
const currentEffort = getEffectiveEffortForTool(descriptionTool, sessionId);
|
|
1604
|
-
const toolLabel = toolDisplayName(descriptionTool);
|
|
1605
|
-
|
|
1606
|
-
if (efforts.length === 0) {
|
|
1607
|
-
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1608
|
-
await (platform.kind === "wechat"
|
|
1609
|
-
? platform.sendText(chatId, msg)
|
|
1610
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1611
|
-
).catch(() => {});
|
|
1612
|
-
} else if (platform.kind === "wechat") {
|
|
1613
|
-
const lines = [currentEffort ? `当前 effort (${toolLabel}): ${currentEffort}` : `当前 effort (${toolLabel}): 未指定`];
|
|
1614
|
-
lines.push("", "可切换 effort:");
|
|
1615
|
-
for (const e of efforts) lines.push(` ${e}`);
|
|
1616
|
-
lines.push("", "输入 /effort <effort> 切换 effort");
|
|
1617
|
-
await platform.sendText(chatId, lines.join("\n")).catch(() => {});
|
|
1618
|
-
} else {
|
|
1619
|
-
const card = buildEffortCard(currentEffort, efforts, descriptionTool);
|
|
1620
|
-
await platform.sendRawCard(chatId, card);
|
|
1621
|
-
}
|
|
1622
|
-
logTrace(tid, "DONE", { outcome: "effort_query", tool: descriptionTool });
|
|
1623
|
-
return;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
if (isCommandText && (textLower.startsWith("/git ") || textLower === "/git")) {
|
|
1558
|
+
if (isCommandText && textLower === "/effort clear") {
|
|
1559
|
+
logTrace(tid, "BRANCH", { cmd: "/effort clear", sessionId, tool: descriptionTool });
|
|
1560
|
+
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1561
|
+
const toolLabel = toolDisplayName(descriptionTool);
|
|
1562
|
+
if (efforts.length === 0) {
|
|
1563
|
+
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1564
|
+
await (platform.kind === "wechat"
|
|
1565
|
+
? platform.sendText(chatId, msg)
|
|
1566
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1567
|
+
).catch(() => {});
|
|
1568
|
+
logTrace(tid, "DONE", { outcome: "effort_unsupported", tool: descriptionTool });
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
clearSessionEffortOverride(sessionId);
|
|
1573
|
+
const defaultEffort = getDefaultEffortForTool(descriptionTool as AgentTool);
|
|
1574
|
+
const msg = `已清除当前 ${toolLabel} 会话的 effort 覆盖,恢复使用: \`${defaultEffort || "(未指定)"}\``;
|
|
1575
|
+
await (platform.kind === "wechat"
|
|
1576
|
+
? platform.sendText(chatId, msg)
|
|
1577
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "green")
|
|
1578
|
+
).catch(() => {});
|
|
1579
|
+
logTrace(tid, "DONE", { outcome: "effort_cleared", sessionId, tool: descriptionTool });
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
if (isCommandText && textLower.startsWith("/effort ")) {
|
|
1584
|
+
const effortArg = text.slice(8).trim();
|
|
1585
|
+
if (!effortArg) return;
|
|
1586
|
+
logTrace(tid, "BRANCH", { cmd: "/effort", arg: effortArg, sessionId, tool: descriptionTool });
|
|
1587
|
+
|
|
1588
|
+
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1589
|
+
const toolLabel = toolDisplayName(descriptionTool);
|
|
1590
|
+
if (efforts.length === 0) {
|
|
1591
|
+
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1592
|
+
await (platform.kind === "wechat"
|
|
1593
|
+
? platform.sendText(chatId, msg)
|
|
1594
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1595
|
+
).catch(() => {});
|
|
1596
|
+
logTrace(tid, "DONE", { outcome: "effort_unsupported", tool: descriptionTool });
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
const target = findModelMatch(effortArg, efforts);
|
|
1601
|
+
if (!target) {
|
|
1602
|
+
const msg = `未找到匹配 "${effortArg}" 的 effort。当前 ${toolLabel} 可选 effort:\n${efforts.map(e => ` \`${e}\``).join("\n")}`;
|
|
1603
|
+
await (platform.kind === "wechat"
|
|
1604
|
+
? platform.sendText(chatId, msg)
|
|
1605
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1606
|
+
).catch(() => {});
|
|
1607
|
+
logTrace(tid, "DONE", { outcome: "effort_not_found", arg: effortArg, tool: descriptionTool });
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
setSessionEffortOverride(sessionId, target);
|
|
1612
|
+
const msg = `已切换当前 ${toolLabel} 会话 effort 为: \`${target}\``;
|
|
1613
|
+
await (platform.kind === "wechat"
|
|
1614
|
+
? platform.sendText(chatId, msg)
|
|
1615
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "green")
|
|
1616
|
+
).catch(() => {});
|
|
1617
|
+
logTrace(tid, "DONE", { outcome: "effort_switched", arg: effortArg, target, sessionId, tool: descriptionTool });
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
if (isCommandText && textLower === "/effort") {
|
|
1622
|
+
logTrace(tid, "BRANCH", { cmd: "/effort", sessionId, tool: descriptionTool });
|
|
1623
|
+
const efforts = getAllEffortsForTool(descriptionTool as AgentTool);
|
|
1624
|
+
const currentEffort = getEffectiveEffortForTool(descriptionTool, sessionId);
|
|
1625
|
+
const toolLabel = toolDisplayName(descriptionTool);
|
|
1626
|
+
|
|
1627
|
+
if (efforts.length === 0) {
|
|
1628
|
+
const msg = `当前 ${toolLabel} 不支持 effort 切换。`;
|
|
1629
|
+
await (platform.kind === "wechat"
|
|
1630
|
+
? platform.sendText(chatId, msg)
|
|
1631
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1632
|
+
).catch(() => {});
|
|
1633
|
+
} else if (platform.kind === "wechat") {
|
|
1634
|
+
const lines = [currentEffort ? `当前 effort (${toolLabel}): ${currentEffort}` : `当前 effort (${toolLabel}): 未指定`];
|
|
1635
|
+
lines.push("", "可切换 effort:");
|
|
1636
|
+
for (const e of efforts) lines.push(` ${e}`);
|
|
1637
|
+
lines.push("", "输入 /effort <effort> 切换 effort");
|
|
1638
|
+
await platform.sendText(chatId, lines.join("\n")).catch(() => {});
|
|
1639
|
+
} else {
|
|
1640
|
+
const card = buildEffortCard(currentEffort, efforts, descriptionTool);
|
|
1641
|
+
await platform.sendRawCard(chatId, card);
|
|
1642
|
+
}
|
|
1643
|
+
logTrace(tid, "DONE", { outcome: "effort_query", tool: descriptionTool });
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
if (isCommandText && (textLower.startsWith("/git ") || textLower === "/git")) {
|
|
1627
1648
|
const args = text === "/git" ? "" : text.slice(5).trim();
|
|
1628
1649
|
logTrace(tid, "BRANCH", { cmd: "/git", args: args || "(none)" });
|
|
1629
1650
|
if (!args) {
|
|
@@ -1781,45 +1802,45 @@ export async function handleCommand(
|
|
|
1781
1802
|
}
|
|
1782
1803
|
|
|
1783
1804
|
// 无会话上下文 → /sessions 仍是有效指令,不触发飞书私聊自动建群。
|
|
1784
|
-
if (isCommandText && textLower === "/effort") {
|
|
1785
|
-
const defaultTool = resolveDefaultAgentTool();
|
|
1786
|
-
const efforts = getAllEffortsForTool(defaultTool);
|
|
1787
|
-
const currentEffort = getDefaultEffortForTool(defaultTool);
|
|
1788
|
-
const toolLabel = toolDisplayName(defaultTool);
|
|
1789
|
-
|
|
1790
|
-
if (efforts.length === 0) {
|
|
1791
|
-
const msg = `当前默认 agent (${toolLabel}) 不支持 effort 切换。`;
|
|
1792
|
-
await (platform.kind === "wechat"
|
|
1793
|
-
? platform.sendText(chatId, msg)
|
|
1794
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1795
|
-
).catch(() => {});
|
|
1796
|
-
} else if (platform.kind === "wechat") {
|
|
1797
|
-
const lines = [currentEffort ? `当前默认 effort (${toolLabel}): ${currentEffort}` : `当前默认 effort (${toolLabel}): 未指定`];
|
|
1798
|
-
lines.push("", "可切换 effort:");
|
|
1799
|
-
for (const e of efforts) lines.push(` ${e}`);
|
|
1800
|
-
lines.push("", "在会话中输入 /effort <effort> 切换 effort");
|
|
1801
|
-
await platform.sendText(chatId, lines.join("\n")).catch(() => {});
|
|
1802
|
-
} else {
|
|
1803
|
-
const card = buildEffortCard(currentEffort, efforts, defaultTool);
|
|
1804
|
-
await platform.sendRawCard(chatId, card);
|
|
1805
|
-
}
|
|
1806
|
-
logTrace(tid, "DONE", { outcome: "effort_query", defaultTool });
|
|
1807
|
-
return;
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
if (isCommandText && textLower.startsWith("/effort ")) {
|
|
1811
|
-
const defaultTool = resolveDefaultAgentTool();
|
|
1812
|
-
const toolLabel = toolDisplayName(defaultTool);
|
|
1813
|
-
const msg = `当前没有绑定会话。请先进入 Claude/Codex 会话,再输入 /effort <effort> 切换当前会话的 effort。当前默认 agent: ${toolLabel}`;
|
|
1814
|
-
await (platform.kind === "wechat"
|
|
1815
|
-
? platform.sendText(chatId, msg)
|
|
1816
|
-
: platform.sendCard(chatId, "Effort 切换", msg, "yellow")
|
|
1817
|
-
).catch(() => {});
|
|
1818
|
-
logTrace(tid, "DONE", { outcome: "effort_no_session", defaultTool });
|
|
1819
|
-
return;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
if (isCommandText && textLower === "/sessions") {
|
|
1805
|
+
if (isCommandText && textLower === "/effort") {
|
|
1806
|
+
const defaultTool = resolveDefaultAgentTool();
|
|
1807
|
+
const efforts = getAllEffortsForTool(defaultTool);
|
|
1808
|
+
const currentEffort = getDefaultEffortForTool(defaultTool);
|
|
1809
|
+
const toolLabel = toolDisplayName(defaultTool);
|
|
1810
|
+
|
|
1811
|
+
if (efforts.length === 0) {
|
|
1812
|
+
const msg = `当前默认 agent (${toolLabel}) 不支持 effort 切换。`;
|
|
1813
|
+
await (platform.kind === "wechat"
|
|
1814
|
+
? platform.sendText(chatId, msg)
|
|
1815
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "red")
|
|
1816
|
+
).catch(() => {});
|
|
1817
|
+
} else if (platform.kind === "wechat") {
|
|
1818
|
+
const lines = [currentEffort ? `当前默认 effort (${toolLabel}): ${currentEffort}` : `当前默认 effort (${toolLabel}): 未指定`];
|
|
1819
|
+
lines.push("", "可切换 effort:");
|
|
1820
|
+
for (const e of efforts) lines.push(` ${e}`);
|
|
1821
|
+
lines.push("", "在会话中输入 /effort <effort> 切换 effort");
|
|
1822
|
+
await platform.sendText(chatId, lines.join("\n")).catch(() => {});
|
|
1823
|
+
} else {
|
|
1824
|
+
const card = buildEffortCard(currentEffort, efforts, defaultTool);
|
|
1825
|
+
await platform.sendRawCard(chatId, card);
|
|
1826
|
+
}
|
|
1827
|
+
logTrace(tid, "DONE", { outcome: "effort_query", defaultTool });
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
if (isCommandText && textLower.startsWith("/effort ")) {
|
|
1832
|
+
const defaultTool = resolveDefaultAgentTool();
|
|
1833
|
+
const toolLabel = toolDisplayName(defaultTool);
|
|
1834
|
+
const msg = `当前没有绑定会话。请先进入 Claude/Codex 会话,再输入 /effort <effort> 切换当前会话的 effort。当前默认 agent: ${toolLabel}`;
|
|
1835
|
+
await (platform.kind === "wechat"
|
|
1836
|
+
? platform.sendText(chatId, msg)
|
|
1837
|
+
: platform.sendCard(chatId, "Effort 切换", msg, "yellow")
|
|
1838
|
+
).catch(() => {});
|
|
1839
|
+
logTrace(tid, "DONE", { outcome: "effort_no_session", defaultTool });
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
if (isCommandText && textLower === "/sessions") {
|
|
1823
1844
|
logTrace(tid, "BRANCH", { cmd: "/sessions", scope: "global" });
|
|
1824
1845
|
const allSessions = await getAllSessionsStatus();
|
|
1825
1846
|
const now = Date.now();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
APP_ID,
|
|
3
|
+
CONFIG_FILE,
|
|
4
|
+
maskAppId,
|
|
5
|
+
reloadConfigFromDisk,
|
|
6
|
+
resolveDefaultAgentTool,
|
|
7
|
+
type AgentTool,
|
|
8
|
+
} from "./config.ts";
|
|
9
|
+
import { appendStartupTrace } from "./shared.ts";
|
|
10
|
+
import { clearAdapterCache } from "./session.ts";
|
|
11
|
+
import { startChromeDevtoolsGuard } from "./chrome-devtools-guard.ts";
|
|
12
|
+
|
|
13
|
+
export interface RuntimeReloadResult {
|
|
14
|
+
configPath: string;
|
|
15
|
+
defaultAgent: AgentTool;
|
|
16
|
+
reloadedAt: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function reloadRuntimeConfig(source: string): RuntimeReloadResult {
|
|
20
|
+
reloadConfigFromDisk();
|
|
21
|
+
clearAdapterCache();
|
|
22
|
+
startChromeDevtoolsGuard();
|
|
23
|
+
|
|
24
|
+
const result: RuntimeReloadResult = {
|
|
25
|
+
configPath: CONFIG_FILE,
|
|
26
|
+
defaultAgent: resolveDefaultAgentTool(),
|
|
27
|
+
reloadedAt: new Date().toISOString(),
|
|
28
|
+
};
|
|
29
|
+
appendStartupTrace(`${source}: config reloaded`, {
|
|
30
|
+
appIdMask: maskAppId(APP_ID),
|
|
31
|
+
defaultAgent: result.defaultAgent,
|
|
32
|
+
});
|
|
33
|
+
return result;
|
|
34
|
+
}
|