zencode-cli 0.1.0 → 0.2.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.
@@ -446,6 +446,10 @@ var init_write_file = __esm({
446
446
  content: {
447
447
  type: "string",
448
448
  description: "\u8981\u5199\u5165\u7684\u6587\u4EF6\u5185\u5BB9"
449
+ },
450
+ overwrite: {
451
+ type: "boolean",
452
+ description: "\u6587\u4EF6\u5DF2\u5B58\u5728\u65F6\u662F\u5426\u786E\u8BA4\u8986\u76D6\uFF0C\u9ED8\u8BA4 false"
449
453
  }
450
454
  },
451
455
  required: ["path", "content"]
@@ -564,7 +568,7 @@ var init_bash = __esm({
564
568
  async execute(params) {
565
569
  const command = params["command"];
566
570
  const timeout = params["timeout"] || DEFAULT_TIMEOUT;
567
- return new Promise((resolve7) => {
571
+ return new Promise((resolve8) => {
568
572
  exec(
569
573
  command,
570
574
  {
@@ -585,7 +589,7 @@ ${stderr}`;
585
589
  } else if (error && !stdout && !stderr) {
586
590
  output = `\u547D\u4EE4\u6267\u884C\u5931\u8D25\uFF1A${error.message}`;
587
591
  }
588
- resolve7({ content: output || "\uFF08\u65E0\u8F93\u51FA\uFF09" });
592
+ resolve8({ content: output || "\uFF08\u65E0\u8F93\u51FA\uFF09" });
589
593
  }
590
594
  );
591
595
  });
@@ -929,6 +933,108 @@ var init_conversation = __esm({
929
933
  }
930
934
  });
931
935
 
936
+ // src/core/auto-memo.ts
937
+ function extractExports(code) {
938
+ const names = [];
939
+ for (const m of code.matchAll(/export\s+(?:default\s+)?(?:function|class|const|let|var)\s+(\w+)/g)) {
940
+ names.push(m[1]);
941
+ }
942
+ for (const m of code.matchAll(/^(?:async\s+)?function\s+(\w+)/gm)) {
943
+ if (!names.includes(m[1])) names.push(m[1]);
944
+ }
945
+ for (const m of code.matchAll(/(?:^|\n)\s{0,4}(?:async\s+)?function\s+(\w+)/g)) {
946
+ if (!names.includes(m[1])) names.push(m[1]);
947
+ }
948
+ return [...new Set(names)].slice(0, 8).join(", ");
949
+ }
950
+ function autoMemoForTool(memoStore, toolName, params, result) {
951
+ if (!memoStore) return;
952
+ if (toolName === "write-file") {
953
+ const path8 = params["path"];
954
+ const content = params["content"] || "";
955
+ const lines = content.split("\n").length;
956
+ const exports = extractExports(content);
957
+ memoStore.write(
958
+ `file:${path8}`,
959
+ content,
960
+ "auto",
961
+ `\u65B0\u5EFA ${lines}\u884C${exports ? " | \u5BFC\u51FA: " + exports : ""}`
962
+ );
963
+ }
964
+ if (toolName === "edit-file") {
965
+ const path8 = params["path"];
966
+ const newStr = params["new_string"] || "";
967
+ const oldStr = params["old_string"] || "";
968
+ const changeLines = newStr.split("\n").length;
969
+ memoStore.write(
970
+ `file:${path8}`,
971
+ `--- \u65E7 ---
972
+ ${oldStr}
973
+ --- \u65B0 ---
974
+ ${newStr}`,
975
+ "auto",
976
+ `\u7F16\u8F91 ${changeLines}\u884C\u53D8\u66F4`
977
+ );
978
+ }
979
+ if (toolName === "read-file") {
980
+ const path8 = params["path"];
981
+ const lines = result.split("\n").length;
982
+ const exports = extractExports(result);
983
+ memoStore.write(
984
+ `file:${path8}`,
985
+ result,
986
+ "auto",
987
+ `\u5DF2\u8BFB ${lines}\u884C${exports ? " | \u5BFC\u51FA: " + exports : ""}`
988
+ );
989
+ }
990
+ }
991
+ var init_auto_memo = __esm({
992
+ "src/core/auto-memo.ts"() {
993
+ "use strict";
994
+ }
995
+ });
996
+
997
+ // src/core/read-tracker.ts
998
+ import * as fs6 from "fs";
999
+ import * as path6 from "path";
1000
+ var ReadTracker;
1001
+ var init_read_tracker = __esm({
1002
+ "src/core/read-tracker.ts"() {
1003
+ "use strict";
1004
+ ReadTracker = class {
1005
+ files = /* @__PURE__ */ new Set();
1006
+ /** 标记文件已被读取 */
1007
+ markRead(filePath) {
1008
+ this.files.add(this.normalize(filePath));
1009
+ }
1010
+ /** 标记文件已被写入(新建/重写,agent 已知内容) */
1011
+ markWritten(filePath) {
1012
+ this.files.add(this.normalize(filePath));
1013
+ }
1014
+ /** 检查文件是否已读取 */
1015
+ hasRead(filePath) {
1016
+ return this.files.has(this.normalize(filePath));
1017
+ }
1018
+ /**
1019
+ * 检查 write-file 是否会覆盖已有文件
1020
+ * @returns 警告消息(需要拦截),或 null(可以继续执行)
1021
+ */
1022
+ checkWriteOverwrite(filePath, overwrite) {
1023
+ const resolved = path6.resolve(filePath);
1024
+ if (!overwrite && fs6.existsSync(resolved)) {
1025
+ return `\u26A0 \u6587\u4EF6\u5DF2\u5B58\u5728\uFF1A${filePath}
1026
+ \u4FEE\u6539\u5DF2\u6709\u6587\u4EF6\u8BF7\u7528 read-file + edit-file\uFF08\u66F4\u7CBE\u786E\u5B89\u5168\uFF09\u3002
1027
+ \u5982\u786E\u9700\u5B8C\u6574\u91CD\u5199\uFF0C\u8BF7\u91CD\u65B0\u8C03\u7528 write-file \u5E76\u8BBE\u7F6E overwrite: true\u3002`;
1028
+ }
1029
+ return null;
1030
+ }
1031
+ normalize(filePath) {
1032
+ return filePath.replace(/\\/g, "/").replace(/^\.\//, "");
1033
+ }
1034
+ };
1035
+ }
1036
+ });
1037
+
932
1038
  // src/core/agent.ts
933
1039
  var Agent;
934
1040
  var init_agent = __esm({
@@ -936,19 +1042,24 @@ var init_agent = __esm({
936
1042
  "use strict";
937
1043
  init_permission();
938
1044
  init_conversation();
1045
+ init_auto_memo();
1046
+ init_read_tracker();
939
1047
  Agent = class {
940
1048
  conversation;
941
1049
  client;
942
1050
  registry;
943
1051
  config;
944
1052
  fixedTools;
945
- constructor(client, registry, config, systemPrompt, tools) {
1053
+ memoStore;
1054
+ readTracker = new ReadTracker();
1055
+ constructor(client, registry, config, systemPrompt, tools, memoStore) {
946
1056
  this.client = client;
947
1057
  this.registry = registry;
948
1058
  this.config = config;
949
1059
  this.conversation = new Conversation();
950
1060
  this.conversation.setSystemPrompt(systemPrompt);
951
1061
  this.fixedTools = tools;
1062
+ this.memoStore = memoStore;
952
1063
  }
953
1064
  /**
954
1065
  * 执行一轮完整的 agent 循环
@@ -978,6 +1089,26 @@ var init_agent = __esm({
978
1089
  continue;
979
1090
  }
980
1091
  try {
1092
+ if (toolName === "edit-file") {
1093
+ const editPath = params["path"];
1094
+ if (!this.readTracker.hasRead(editPath)) {
1095
+ this.conversation.addToolResult(
1096
+ toolCall.id,
1097
+ `\u26A0 \u7981\u6B62\u7F16\u8F91\u672A\u8BFB\u53D6\u7684\u6587\u4EF6\u3002\u8BF7\u5148 read-file "${editPath}" \u4E86\u89E3\u5F53\u524D\u5185\u5BB9\uFF0C\u518D edit-file\u3002`
1098
+ );
1099
+ continue;
1100
+ }
1101
+ }
1102
+ if (toolName === "write-file") {
1103
+ const warn = this.readTracker.checkWriteOverwrite(
1104
+ params["path"],
1105
+ params["overwrite"]
1106
+ );
1107
+ if (warn) {
1108
+ this.conversation.addToolResult(toolCall.id, warn);
1109
+ continue;
1110
+ }
1111
+ }
981
1112
  const permLevel = this.registry.getPermissionLevel(toolName);
982
1113
  if (permLevel === "deny") {
983
1114
  callbacks.onDenied?.(toolName);
@@ -998,6 +1129,12 @@ var init_agent = __esm({
998
1129
  }
999
1130
  const result = await this.registry.execute(toolName, params, this.config.max_tool_output);
1000
1131
  callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);
1132
+ autoMemoForTool(this.memoStore, toolName, params, result.content);
1133
+ if (toolName === "read-file") {
1134
+ this.readTracker.markRead(params["path"]);
1135
+ } else if (toolName === "write-file") {
1136
+ this.readTracker.markWritten(params["path"]);
1137
+ }
1001
1138
  this.conversation.addToolResult(toolCall.id, result.content);
1002
1139
  } catch (err) {
1003
1140
  const msg = err instanceof Error ? err.message : String(err);
@@ -1027,18 +1164,22 @@ var init_coder = __esm({
1027
1164
  "use strict";
1028
1165
  init_conversation();
1029
1166
  init_permission();
1167
+ init_auto_memo();
1168
+ init_read_tracker();
1030
1169
  Coder = class {
1031
1170
  client;
1032
1171
  registry;
1033
1172
  config;
1034
1173
  systemPrompt;
1035
1174
  tools;
1036
- constructor(client, registry, config, systemPrompt, tools) {
1175
+ memoStore;
1176
+ constructor(client, registry, config, systemPrompt, tools, memoStore) {
1037
1177
  this.client = client;
1038
1178
  this.registry = registry;
1039
1179
  this.config = config;
1040
1180
  this.systemPrompt = systemPrompt;
1041
1181
  this.tools = tools;
1182
+ this.memoStore = memoStore;
1042
1183
  }
1043
1184
  /**
1044
1185
  * 执行编码任务(短生命周期,每次新建会话)
@@ -1051,6 +1192,7 @@ var init_coder = __esm({
1051
1192
  const conversation = new Conversation();
1052
1193
  conversation.setSystemPrompt(this.systemPrompt);
1053
1194
  conversation.addUserMessage(taskMessage);
1195
+ const readTracker = new ReadTracker();
1054
1196
  let lastContent = "";
1055
1197
  while (true) {
1056
1198
  const assistantMsg = await this.client.chatStream(
@@ -1073,6 +1215,26 @@ var init_coder = __esm({
1073
1215
  continue;
1074
1216
  }
1075
1217
  try {
1218
+ if (toolName === "edit-file") {
1219
+ const editPath = params["path"];
1220
+ if (!readTracker.hasRead(editPath)) {
1221
+ conversation.addToolResult(
1222
+ toolCall.id,
1223
+ `\u26A0 \u7981\u6B62\u7F16\u8F91\u672A\u8BFB\u53D6\u7684\u6587\u4EF6\u3002\u8BF7\u5148 read-file "${editPath}" \u4E86\u89E3\u5F53\u524D\u5185\u5BB9\uFF0C\u518D edit-file\u3002`
1224
+ );
1225
+ continue;
1226
+ }
1227
+ }
1228
+ if (toolName === "write-file") {
1229
+ const warn = readTracker.checkWriteOverwrite(
1230
+ params["path"],
1231
+ params["overwrite"]
1232
+ );
1233
+ if (warn) {
1234
+ conversation.addToolResult(toolCall.id, warn);
1235
+ continue;
1236
+ }
1237
+ }
1076
1238
  const permLevel = this.registry.getPermissionLevel(toolName);
1077
1239
  if (permLevel === "deny") {
1078
1240
  callbacks.onDenied?.(toolName);
@@ -1093,6 +1255,12 @@ var init_coder = __esm({
1093
1255
  }
1094
1256
  const result = await this.registry.execute(toolName, params, this.config.max_tool_output);
1095
1257
  callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);
1258
+ autoMemoForTool(this.memoStore, toolName, params, result.content);
1259
+ if (toolName === "read-file") {
1260
+ readTracker.markRead(params["path"]);
1261
+ } else if (toolName === "write-file") {
1262
+ readTracker.markWritten(params["path"]);
1263
+ }
1096
1264
  conversation.addToolResult(toolCall.id, result.content);
1097
1265
  } catch (err) {
1098
1266
  const msg = err instanceof Error ? err.message : String(err);
@@ -1126,21 +1294,34 @@ var CODER_IDENTITY, DELEGATED_MODE, AUTONOMOUS_MODE, CONTROLLED_MODE;
1126
1294
  var init_modes = __esm({
1127
1295
  "src/core/dual-agent/modes.ts"() {
1128
1296
  "use strict";
1129
- CODER_IDENTITY = `\u4F60\u662F\u7F16\u7801\u5B50 Agent\u3002\u6309\u4EE5\u4E0B\u987A\u5E8F\u5DE5\u4F5C\uFF1A
1297
+ CODER_IDENTITY = `\u4F60\u662F\u7F16\u7801\u5B50 Agent\u3002
1130
1298
 
1131
- 1. **\u8BFB memo**\uFF1A\u5982\u679C\u4EFB\u52A1\u63D0\u5230\u4E86 memo key\uFF0C\u5148 memo read \u83B7\u53D6\u8C03\u5EA6\u8005\u8BB0\u5F55\u7684\u4E0A\u4E0B\u6587
1132
- 2. **\u7F16\u7801**\uFF1A
1133
- - \u65B0\u5EFA\u6587\u4EF6 \u2192 \u76F4\u63A5 write-file
1134
- - \u4FEE\u6539\u6587\u4EF6 \u2192 read-file \u9605\u8BFB\u8981\u6539\u7684\u6587\u4EF6 \u2192 edit-file \u4FEE\u6539
1135
- 3. **\u5199 memo**\uFF1A\u5B8C\u6210\u540E memo write \u8BB0\u5F55\u6539\u52A8\u6458\u8981\uFF08key \u5982 "done-xxx"\uFF09\uFF0C\u4FBF\u4E8E\u8C03\u5EA6\u8005\u4E86\u89E3\u8FDB\u5C55
1136
- 4. **\u56DE\u590D**\uFF1A\u4E00\u53E5\u8BDD\u8BF4\u660E\u7ED3\u679C
1299
+ ## \u5DE5\u4F5C\u6D41\u7A0B
1300
+ 1. \u67E5\u770B\u4EFB\u52A1\u672B\u5C3E\u7684 [\u5171\u4EAB\u5907\u5FD8\u5F55] \u4E86\u89E3\u5DF2\u6709\u6587\u4EF6\u548C\u51FD\u6570
1301
+ - \u6BCF\u884C\u683C\u5F0F\uFF1A[file:\u8DEF\u5F84] \u6458\u8981 | \u5BFC\u51FA: \u51FD\u6570\u540D\u5217\u8868
1302
+ - \u9700\u8981\u5B8C\u6574\u6587\u4EF6\u5185\u5BB9\u6216 diff \u8BE6\u60C5 \u2192 memo read <key>
1303
+ 2. \u7F16\u7801\uFF1A
1304
+ - \u65B0\u5EFA\u6587\u4EF6 \u2192 write-file
1305
+ - \u4FEE\u6539\u6587\u4EF6 \u2192 \u5FC5\u987B\u5148 read-file \u9605\u8BFB \u2192 \u518D edit-file \u4FEE\u6539
1306
+ - \u26A0\uFE0F \u7CFB\u7EDF\u5F3A\u5236\uFF1A\u672A read-file \u7684\u6587\u4EF6\u65E0\u6CD5 edit-file\uFF0C\u4F1A\u88AB\u62E6\u622A
1307
+ - \u5F15\u7528\u5DF2\u6709\u6587\u4EF6\u7684\u51FD\u6570\u65F6\uFF0C\u52A1\u5FC5\u4F7F\u7528 memo \u4E2D\u5217\u51FA\u7684\u51C6\u786E\u540D\u79F0
1308
+ 3. \u4E00\u53E5\u8BDD\u8BF4\u660E\u7ED3\u679C
1309
+
1310
+ \u6CE8\u610F\uFF1A\u6587\u4EF6\u64CD\u4F5C\uFF08write-file\u3001edit-file\uFF09\u4F1A\u81EA\u52A8\u8BB0\u5F55\u5230 memo\uFF0C\u4E0D\u9700\u8981\u624B\u52A8 memo write \u6587\u4EF6\u4FE1\u606F\u3002
1311
+ \u5982\u6709\u9700\u8981\uFF0C\u4ECD\u53EF memo write \u8BB0\u5F55\u975E\u6587\u4EF6\u7C7B\u4FE1\u606F\uFF08\u67B6\u6784\u51B3\u7B56\u3001\u6CE8\u610F\u4E8B\u9879\u7B49\uFF09\u3002
1312
+
1313
+ ## edit-file \u51C6\u786E\u6027\u89C4\u5219
1314
+ - old_string \u5FC5\u987B\u4ECE read-file \u8FD4\u56DE\u7684\u5185\u5BB9\u4E2D**\u7CBE\u786E\u590D\u5236**\uFF0C\u4E0D\u80FD\u51ED\u8BB0\u5FC6\u624B\u5199
1315
+ - old_string \u5305\u542B\u8DB3\u591F\u4E0A\u4E0B\u6587\u884C\uFF083-5 \u884C\uFF09\u786E\u4FDD\u552F\u4E00\u5339\u914D
1316
+ - \u7F29\u8FDB\u3001\u7A7A\u683C\u3001\u6362\u884C\u7B26\u5FC5\u987B\u5B8C\u5168\u4E00\u81F4
1317
+ - \u5982\u679C\u4E0D\u786E\u5B9A\u6587\u4EF6\u5185\u5BB9\uFF0C\u5148 read-file \u518D\u64CD\u4F5C
1137
1318
 
1138
1319
  ## \u7981\u6B62
1139
- - \u274C \u7F16\u7801\u524D\u505A\u63A2\u7D22\uFF08bash ls/dir/pwd\u3001glob\u3001grep\uFF09\u2014 \u8C03\u5EA6\u8005\u5DF2\u7ECF\u505A\u8FC7\u4E86\uFF0C\u7ED3\u679C\u5728 memo \u4E2D
1320
+ - \u274C \u7F16\u7801\u524D\u505A\u63A2\u7D22\uFF08bash ls/dir/pwd\u3001glob\u3001grep\uFF09\u2014 \u4E0A\u4E0B\u6587\u5DF2\u5728 memo \u4E2D
1140
1321
  - \u274C \u8F93\u51FA\u8BA1\u5212\u3001\u5206\u6790\u3001\u601D\u8DEF\u8BF4\u660E \u2014 \u76F4\u63A5\u52A8\u624B
1141
1322
  - \u274C \u505A\u4EFB\u52A1\u8303\u56F4\u5916\u7684\u6539\u52A8
1142
- - \u274C \u6DFB\u52A0\u672A\u8981\u6C42\u7684\u6CE8\u91CA\u3001\u6587\u6863\u3001\u9519\u8BEF\u5904\u7406
1143
- - \u274C \u8FC7\u5EA6\u5DE5\u7A0B\u5316`;
1323
+ - \u274C \u8FC7\u5EA6\u5DE5\u7A0B\u5316
1324
+ - \u274C \u51ED\u8BB0\u5FC6\u731C\u6D4B\u6587\u4EF6\u5185\u5BB9\u7528\u4E8E edit-file \u7684 old_string`;
1144
1325
  DELEGATED_MODE = {
1145
1326
  name: "delegated",
1146
1327
  description: "A\u6536\u96C6\u4E0A\u4E0B\u6587\u5E76\u59D4\u6D3E\uFF0CB\u62E5\u6709\u5B8C\u6574\u5DE5\u5177\u72EC\u7ACB\u6267\u884C",
@@ -1175,6 +1356,8 @@ var init_orchestrator = __esm({
1175
1356
  init_permission();
1176
1357
  init_coder();
1177
1358
  init_modes();
1359
+ init_auto_memo();
1360
+ init_read_tracker();
1178
1361
  SEND_TO_CODER_TOOL = {
1179
1362
  type: "function",
1180
1363
  function: {
@@ -1201,6 +1384,7 @@ var init_orchestrator = __esm({
1201
1384
  mode;
1202
1385
  baseSystemPrompt;
1203
1386
  memoStore;
1387
+ readTracker = new ReadTracker();
1204
1388
  constructor(registry, config, systemPrompt, memoStore) {
1205
1389
  this.registry = registry;
1206
1390
  this.config = config;
@@ -1246,31 +1430,29 @@ var init_orchestrator = __esm({
1246
1430
 
1247
1431
  \u534F\u4F5C\u6A21\u5F0F\uFF1A${modeInfo.name} - ${modeInfo.description}
1248
1432
 
1249
- \u4F60\u662F\u4FA6\u5BDF\u5175 + \u6307\u6325\u5B98\u3002\u4F60\u81EA\u5DF1\u4E0D\u5199\u4EE3\u7801\uFF0C\u4F60\u7684\u804C\u8D23\u662F\uFF1A\u6536\u96C6\u60C5\u62A5 \u2192 \u8BB0\u5165 memo \u2192 \u59D4\u6D3E\u7F16\u7801 Agent\u3002
1433
+ \u4F60\u662F\u4FA6\u5BDF\u5175 + \u6307\u6325\u5B98\u3002\u4F60\u81EA\u5DF1\u4E0D\u5199\u4EE3\u7801\uFF0C\u4F60\u7684\u804C\u8D23\u662F\uFF1A\u6536\u96C6\u60C5\u62A5 \u2192 \u59D4\u6D3E\u7F16\u7801 Agent\u3002
1250
1434
 
1251
1435
  ## \u6838\u5FC3\u6D41\u7A0B
1252
1436
 
1253
1437
  1. **\u8BC4\u4F30**\uFF1A\u4EFB\u52A1\u662F\u5426\u9700\u8981\u4E86\u89E3\u73B0\u6709\u4EE3\u7801\uFF1F
1254
- - \u9700\u8981\u4FEE\u6539\u73B0\u6709\u6587\u4EF6\u3001\u9700\u8981\u4E0E\u73B0\u6709\u4EE3\u7801\u98CE\u683C\u4E00\u81F4\u3001\u9700\u8981\u7406\u89E3\u4F9D\u8D56\u5173\u7CFB \u2192 \u5148\u6536\u96C6
1255
- - \u9700\u6C42\u5B8C\u5168\u81EA\u5305\u542B\u3001\u76EE\u6807\u8DEF\u5F84\u5DF2\u660E\u786E \u2192 \u8DF3\u5230\u7B2C 3 \u6B65
1438
+ - \u9700\u8981\u4FEE\u6539\u73B0\u6709\u6587\u4EF6\u3001\u9700\u8981\u7406\u89E3\u4F9D\u8D56\u5173\u7CFB \u2192 \u5148\u6536\u96C6
1439
+ - \u9700\u6C42\u81EA\u5305\u542B\u3001\u76EE\u6807\u8DEF\u5F84\u660E\u786E \u2192 \u8DF3\u5230\u7B2C 3 \u6B65
1256
1440
 
1257
1441
  2. **\u6536\u96C6\u4E0A\u4E0B\u6587**\uFF08\u9AD8\u6548\uFF0C\u4E0D\u91CD\u590D\uFF09
1258
- - \u7528 glob/grep \u5B9A\u4F4D\uFF08\u4E00\u6B21\u5C31\u591F\uFF0C\u4E0D\u8981\u540C\u4E00\u76EE\u6807\u67E5\u591A\u6B21\uFF09
1259
- - \u7528 read-file \u6216 spawn-agents \u5E76\u884C\u8BFB\u53D6\u5173\u952E\u6587\u4EF6
1260
- - **\u5FC5\u987B memo write \u8BB0\u5F55\u53D1\u73B0**\uFF0Ckey \u7528\u6709\u610F\u4E49\u7684\u540D\u79F0
1261
- \u4F8B\uFF1Amemo write key="demo-structure" value="demo/ \u4E0B\u6709 weather.html\uFF08\u5929\u6C14\u7EC4\u4EF6\u793A\u4F8B\uFF09\uFF0C\u4F7F\u7528\u7EAF HTML+CSS+JS \u5355\u6587\u4EF6\u7ED3\u6784"
1262
- - \u7CBE\u70BC\u6458\u8981\uFF0C\u4E0D\u8981\u590D\u5236\u6574\u4E2A\u6587\u4EF6\u5185\u5BB9
1442
+ - \u7528 glob/grep \u5B9A\u4F4D + read-file \u6216 spawn-agents \u5E76\u884C\u8BFB\u53D6
1443
+ - \u6587\u4EF6\u64CD\u4F5C\uFF08read-file \u7B49\uFF09\u4F1A\u81EA\u52A8\u8BB0\u5F55\u5230 memo\uFF0C\u4E0D\u9700\u8981\u624B\u52A8 memo write \u6587\u4EF6\u5185\u5BB9
1444
+ - \u4ECD\u53EF memo write \u8BB0\u5F55\u5206\u6790\u7ED3\u8BBA\u3001\u67B6\u6784\u51B3\u7B56\u7B49\u975E\u6587\u4EF6\u4FE1\u606F
1263
1445
 
1264
1446
  3. **\u59D4\u6D3E\u7F16\u7801**\uFF1Asend-to-coder
1265
- - task \u4E2D\u5199\u6E05\uFF1A\u505A\u4EC0\u4E48 + \u76EE\u6807\u8DEF\u5F84 + \u5F15\u7528 memo key
1266
- \u4F8B\uFF1Atask="\u5728 demo/newyear.html \u521B\u5EFA\u9A6C\u5E74\u6625\u8282\u795D\u798F\u7F51\u9875\u3002\u9879\u76EE\u73B0\u6709\u7ED3\u6784\u89C1 memo key 'demo-structure'\u3002\u8981\u6C42\uFF1A\u5355\u6587\u4EF6 HTML\uFF0C\u5305\u542B\u5185\u8054 CSS \u548C JS\uFF0C\u4E2D\u6587\u5185\u5BB9\u3002"
1447
+ - task \u4E2D\u5199\u6E05\uFF1A\u505A\u4EC0\u4E48 + \u76EE\u6807\u8DEF\u5F84
1448
+ - \u7F16\u7801 Agent \u4F1A\u81EA\u52A8\u770B\u5230 memo \u4E2D\u7684\u6587\u4EF6\u7D22\u5F15\uFF08\u5305\u62EC\u5DF2\u521B\u5EFA\u7684\u6587\u4EF6\u548C\u5BFC\u51FA\u7684\u51FD\u6570\u540D\uFF09
1267
1449
  - \u6BCF\u6B21\u53EA\u53D1\u4E00\u4E2A\u5177\u4F53\u6B65\u9AA4
1268
1450
 
1269
1451
  4. **\u8FED\u4EE3/\u9A8C\u8BC1**\uFF1A\u9700\u8981\u65F6\u7EE7\u7EED\u59D4\u6D3E\u6216\u7528 bash \u8FD0\u884C\u9A8C\u8BC1
1270
1452
 
1271
1453
  ## \u91CD\u8981
1272
1454
 
1273
- - memo \u662F\u4F60\u4E0E\u7F16\u7801 Agent \u7684\u5171\u4EAB\u8BB0\u5FC6\uFF0C\u662F\u534F\u4F5C\u7684\u6838\u5FC3\u6865\u6881
1455
+ - memo \u7D22\u5F15\u4F1A\u81EA\u52A8\u6CE8\u5165\u7ED9\u7F16\u7801 Agent\uFF0C\u5305\u542B\u6240\u6709\u5DF2\u64CD\u4F5C\u6587\u4EF6\u7684\u6458\u8981\u548C\u5BFC\u51FA\u51FD\u6570\u540D
1274
1456
  - \u4E0D\u8981\u91CD\u590D\u63A2\u7D22\uFF08glob \u67E5\u8FC7\u5C31\u4E0D\u8981\u518D bash ls \u540C\u4E00\u76EE\u5F55\uFF09
1275
1457
  - bash \u7528\u4E8E\u6267\u884C\u547D\u4EE4\uFF08\u6784\u5EFA\u3001\u6D4B\u8BD5\uFF09\uFF0C\u4E0D\u9700\u8981\u59D4\u6D3E
1276
1458
  - \u5B8C\u6210\u6240\u6709\u6B65\u9AA4\u540E\u7B80\u8981\u544A\u77E5\u7528\u6237\u7ED3\u679C`;
@@ -1317,6 +1499,26 @@ var init_orchestrator = __esm({
1317
1499
  this.conversation.addToolResult(toolCall.id, coderResponse);
1318
1500
  continue;
1319
1501
  }
1502
+ if (toolName === "edit-file") {
1503
+ const editPath = params["path"];
1504
+ if (!this.readTracker.hasRead(editPath)) {
1505
+ this.conversation.addToolResult(
1506
+ toolCall.id,
1507
+ `\u26A0 \u7981\u6B62\u7F16\u8F91\u672A\u8BFB\u53D6\u7684\u6587\u4EF6\u3002\u8BF7\u5148 read-file "${editPath}" \u4E86\u89E3\u5F53\u524D\u5185\u5BB9\uFF0C\u518D edit-file\u3002`
1508
+ );
1509
+ continue;
1510
+ }
1511
+ }
1512
+ if (toolName === "write-file") {
1513
+ const warn = this.readTracker.checkWriteOverwrite(
1514
+ params["path"],
1515
+ params["overwrite"]
1516
+ );
1517
+ if (warn) {
1518
+ this.conversation.addToolResult(toolCall.id, warn);
1519
+ continue;
1520
+ }
1521
+ }
1320
1522
  const permLevel = this.registry.getPermissionLevel(toolName);
1321
1523
  if (permLevel === "deny") {
1322
1524
  callbacks.onDenied?.(toolName);
@@ -1337,6 +1539,12 @@ var init_orchestrator = __esm({
1337
1539
  }
1338
1540
  const result = await this.registry.execute(toolName, params, this.config.max_tool_output);
1339
1541
  callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);
1542
+ autoMemoForTool(this.memoStore, toolName, params, result.content);
1543
+ if (toolName === "read-file") {
1544
+ this.readTracker.markRead(params["path"]);
1545
+ } else if (toolName === "write-file") {
1546
+ this.readTracker.markWritten(params["path"]);
1547
+ }
1340
1548
  this.conversation.addToolResult(toolCall.id, result.content);
1341
1549
  } catch (err) {
1342
1550
  const msg = err instanceof Error ? err.message : String(err);
@@ -1375,7 +1583,8 @@ ${index}`;
1375
1583
  this.registry,
1376
1584
  this.config,
1377
1585
  modeInfo.coderSystemPrompt,
1378
- coderTools
1586
+ coderTools,
1587
+ this.memoStore
1379
1588
  );
1380
1589
  const response = await coder.execute(taskWithMemo, {
1381
1590
  onContent: callbacks.onContent,
@@ -1410,14 +1619,19 @@ function buildCorePrompt() {
1410
1619
  \u4F60\u6709\u4EE5\u4E0B\u5DE5\u5177\u53EF\u7528\uFF0C\u8BF7\u6839\u636E\u4EFB\u52A1\u9009\u62E9\u6700\u5408\u9002\u7684\u5DE5\u5177\uFF1A
1411
1620
 
1412
1621
  - **read-file**\uFF1A\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\u3002\u4FEE\u6539\u4EE3\u7801\u524D\u5FC5\u987B\u5148\u8BFB\u53D6\u76EE\u6807\u6587\u4EF6\u3002\u652F\u6301 offset/limit \u8BFB\u53D6\u5927\u6587\u4EF6\u7684\u7279\u5B9A\u90E8\u5206\u3002
1413
- - **edit-file**\uFF1A\u901A\u8FC7\u5B57\u7B26\u4E32\u66FF\u6362\u7F16\u8F91\u6587\u4EF6\u3002\u4F18\u5148\u4F7F\u7528 edit-file \u800C\u975E write-file \u4FEE\u6539\u5DF2\u6709\u6587\u4EF6\u2014\u2014\u5B83\u66F4\u7CBE\u786E\u3001\u66F4\u5B89\u5168\u3002old_string \u5FC5\u987B\u552F\u4E00\u5339\u914D\uFF0C\u5339\u914D\u5931\u8D25\u65F6\u63D0\u4F9B\u66F4\u591A\u4E0A\u4E0B\u6587\u4F7F\u5176\u552F\u4E00\u3002
1622
+ - **edit-file**\uFF1A\u901A\u8FC7\u5B57\u7B26\u4E32\u66FF\u6362\u7F16\u8F91\u6587\u4EF6\u3002\u4F18\u5148\u4F7F\u7528 edit-file \u800C\u975E write-file \u4FEE\u6539\u5DF2\u6709\u6587\u4EF6\u2014\u2014\u5B83\u66F4\u7CBE\u786E\u3001\u66F4\u5B89\u5168\u3002
1623
+ - \u26A0\uFE0F \u7CFB\u7EDF\u5F3A\u5236\uFF1A\u672A\u7528 read-file \u8BFB\u53D6\u8FC7\u7684\u6587\u4EF6\u65E0\u6CD5 edit-file\uFF0C\u4F1A\u88AB\u62E6\u622A
1624
+ - old_string \u5FC5\u987B\u4E0E\u6587\u4EF6\u4E2D\u7684\u5185\u5BB9**\u5B8C\u5168\u4E00\u81F4**\uFF08\u5305\u62EC\u7F29\u8FDB\u3001\u7A7A\u683C\u3001\u6362\u884C\u7B26\uFF09
1625
+ - old_string \u4E0D\u552F\u4E00\u65F6\uFF0C\u5305\u542B\u66F4\u591A\u4E0A\u4E0B\u6587\u884C\uFF08\u5EFA\u8BAE 3-5 \u884C\uFF09\u4F7F\u5176\u552F\u4E00
1626
+ - \u4E0D\u8981\u51ED\u8BB0\u5FC6\u731C\u6D4B\u6587\u4EF6\u5185\u5BB9\uFF0C\u5FC5\u987B\u57FA\u4E8E read-file \u7684\u5B9E\u9645\u8FD4\u56DE\u503C
1414
1627
  - **write-file**\uFF1A\u521B\u5EFA\u65B0\u6587\u4EF6\u6216\u5B8C\u6574\u91CD\u5199\u6587\u4EF6\u3002\u4EC5\u5728\u521B\u5EFA\u65B0\u6587\u4EF6\u6216\u9700\u8981\u5927\u5E45\u91CD\u5199\u65F6\u4F7F\u7528\u3002
1415
1628
  - **glob**\uFF1A\u6309\u6A21\u5F0F\u641C\u7D22\u6587\u4EF6\u8DEF\u5F84\u3002\u7528\u4E8E\u67E5\u627E\u6587\u4EF6\u4F4D\u7F6E\uFF08\u5982 \`**/*.ts\`\u3001\`src/**/config.*\`\uFF09\u3002
1416
1629
  - **grep**\uFF1A\u5728\u6587\u4EF6\u5185\u5BB9\u4E2D\u641C\u7D22\u6B63\u5219\u8868\u8FBE\u5F0F\u3002\u7528\u4E8E\u67E5\u627E\u51FD\u6570\u5B9A\u4E49\u3001\u5F15\u7528\u3001\u7279\u5B9A\u4EE3\u7801\u6A21\u5F0F\u3002
1417
1630
  - **bash**\uFF1A\u6267\u884C shell \u547D\u4EE4\u3002\u7528\u4E8E\u8FD0\u884C\u6784\u5EFA\u3001\u6D4B\u8BD5\u3001git \u64CD\u4F5C\u7B49\u3002\u4E0D\u8981\u7528 bash \u505A\u80FD\u7528\u4E0A\u8FF0\u5DE5\u5177\u5B8C\u6210\u7684\u4E8B\uFF08\u5982\u4E0D\u8981\u7528 cat \u8BFB\u6587\u4EF6\u3001\u4E0D\u8981\u7528 sed \u7F16\u8F91\u6587\u4EF6\u3001\u4E0D\u8981\u7528 find \u641C\u7D22\u6587\u4EF6\uFF09\u3002
1418
1631
 
1419
1632
  \u5173\u952E\u89C4\u5219\uFF1A
1420
- - \u4FEE\u6539\u4EE3\u7801\u524D\u5148\u7528 read-file \u9605\u8BFB\u76F8\u5173\u6587\u4EF6\uFF0C\u7406\u89E3\u73B0\u6709\u903B\u8F91
1633
+ - **\u5148\u8BFB\u540E\u6539**\uFF1A\u4FEE\u6539\u6587\u4EF6\u524D\u5FC5\u987B read-file \u8BFB\u53D6\u8BE5\u6587\u4EF6\uFF08\u7CFB\u7EDF\u4F1A\u62E6\u622A\u672A\u8BFB\u53D6\u5C31 edit \u7684\u64CD\u4F5C\uFF09
1634
+ - edit-file \u7684 old_string \u5FC5\u987B\u4ECE read-file \u8FD4\u56DE\u7684\u5185\u5BB9\u4E2D\u7CBE\u786E\u590D\u5236\uFF0C\u4E0D\u8981\u624B\u52A8\u8F93\u5165\u6216\u51ED\u8BB0\u5FC6
1421
1635
  - \u4F18\u5148 edit-file \u7F16\u8F91\u5DF2\u6709\u6587\u4EF6\uFF0C\u800C\u975E write-file \u91CD\u5199
1422
1636
  - \u4E0D\u8981\u521B\u5EFA\u4E0D\u5FC5\u8981\u7684\u65B0\u6587\u4EF6\uFF0C\u4F18\u5148\u5728\u73B0\u6709\u6587\u4EF6\u4E2D\u4FEE\u6539
1423
1637
  - \u53EA\u505A\u5FC5\u8981\u7684\u6700\u5C0F\u6539\u52A8\uFF0C\u4E0D\u505A\u989D\u5916"\u6539\u8FDB"
@@ -1515,11 +1729,11 @@ var init_git = __esm({
1515
1729
  });
1516
1730
 
1517
1731
  // src/core/prompt/layers/project.ts
1518
- import * as fs6 from "fs/promises";
1519
- import * as path6 from "path";
1732
+ import * as fs7 from "fs/promises";
1733
+ import * as path7 from "path";
1520
1734
  async function buildProjectPrompt() {
1521
1735
  try {
1522
- const content = await fs6.readFile(path6.resolve("ZENCODE.md"), "utf-8");
1736
+ const content = await fs7.readFile(path7.resolve("ZENCODE.md"), "utf-8");
1523
1737
  return content.trim() || null;
1524
1738
  } catch {
1525
1739
  return null;
@@ -1529,8 +1743,8 @@ async function loadUserPrompts(paths) {
1529
1743
  const prompts = [];
1530
1744
  for (const p of paths) {
1531
1745
  try {
1532
- const resolved = p.startsWith("~") ? path6.join(process.env["HOME"] || process.env["USERPROFILE"] || "", p.slice(1)) : path6.resolve(p);
1533
- const content = await fs6.readFile(resolved, "utf-8");
1746
+ const resolved = p.startsWith("~") ? path7.join(process.env["HOME"] || process.env["USERPROFILE"] || "", p.slice(1)) : path7.resolve(p);
1747
+ const content = await fs7.readFile(resolved, "utf-8");
1534
1748
  if (content.trim()) {
1535
1749
  prompts.push(content.trim());
1536
1750
  }
@@ -1546,10 +1760,10 @@ var init_project = __esm({
1546
1760
  });
1547
1761
 
1548
1762
  // src/core/prompt/builder.ts
1549
- import * as fs7 from "fs";
1763
+ import * as fs8 from "fs";
1550
1764
  function isGitRepo() {
1551
1765
  try {
1552
- fs7.statSync(".git");
1766
+ fs8.statSync(".git");
1553
1767
  return true;
1554
1768
  } catch {
1555
1769
  return false;
@@ -1649,9 +1863,15 @@ var init_memo_store = __esm({
1649
1863
  MAX_CONTENT_LENGTH = 3e3;
1650
1864
  MemoStore = class {
1651
1865
  entries = /* @__PURE__ */ new Map();
1652
- write(key, content, author = "agent") {
1866
+ write(key, content, author = "agent", summary) {
1653
1867
  const trimmed = content.slice(0, MAX_CONTENT_LENGTH);
1654
- const entry = { key, content: trimmed, author, updatedAt: Date.now() };
1868
+ const entry = {
1869
+ key,
1870
+ summary: summary || content.slice(0, 80).replace(/\n/g, " "),
1871
+ content: trimmed,
1872
+ author,
1873
+ updatedAt: Date.now()
1874
+ };
1655
1875
  if (!this.entries.has(key) && this.entries.size >= MAX_ENTRIES) {
1656
1876
  let oldest = null;
1657
1877
  let oldestTime = Infinity;
@@ -1673,7 +1893,7 @@ var init_memo_store = __esm({
1673
1893
  return [...this.entries.values()].map((e) => ({
1674
1894
  key: e.key,
1675
1895
  author: e.author,
1676
- preview: e.content.slice(0, 80)
1896
+ summary: e.summary
1677
1897
  }));
1678
1898
  }
1679
1899
  delete(key) {
@@ -1683,15 +1903,13 @@ var init_memo_store = __esm({
1683
1903
  this.entries.clear();
1684
1904
  }
1685
1905
  /**
1686
- * 生成简短的备忘录索引(用于注入 Agent 系统提示词)
1687
- * 仅包含 key 列表和简短预览,占用极少 token
1906
+ * 生成备忘录索引(注入 Coder 任务中)
1907
+ * 只输出 key + summary,清爽紧凑
1908
+ * Coder 需要详情时用 memo read <key> 获取完整内容
1688
1909
  */
1689
1910
  buildIndex() {
1690
1911
  if (this.entries.size === 0) return null;
1691
- const lines = [...this.entries.values()].map(
1692
- (e) => `- ${e.key}: ${e.content.slice(0, 50)}`
1693
- );
1694
- return lines.join("\n");
1912
+ return [...this.entries.values()].map((e) => `[${e.key}] ${e.summary}`).join("\n");
1695
1913
  }
1696
1914
  };
1697
1915
  }
@@ -1703,6 +1921,8 @@ var init_sub_agent = __esm({
1703
1921
  "src/core/sub-agent.ts"() {
1704
1922
  "use strict";
1705
1923
  init_conversation();
1924
+ init_auto_memo();
1925
+ init_read_tracker();
1706
1926
  DEFAULT_TIMEOUT_MS = 12e4;
1707
1927
  SubAgent = class {
1708
1928
  client;
@@ -1739,6 +1959,7 @@ var init_sub_agent = __esm({
1739
1959
  }
1740
1960
  async execute() {
1741
1961
  const conversation = new Conversation();
1962
+ const readTracker = new ReadTracker();
1742
1963
  let systemPrompt = `\u4F60\u662F ZenCode \u5B50 Agent\u3002\u4F60\u7684\u4EFB\u52A1\uFF1A${this.task}
1743
1964
  \u5B8C\u6210\u540E\u76F4\u63A5\u8FD4\u56DE\u7ED3\u679C\uFF0C\u4E0D\u8981\u591A\u4F59\u89E3\u91CA\u3002`;
1744
1965
  if (this.memoStore) {
@@ -1781,11 +2002,37 @@ ${index}`;
1781
2002
  continue;
1782
2003
  }
1783
2004
  try {
2005
+ if (toolName === "edit-file") {
2006
+ const editPath = params["path"];
2007
+ if (!readTracker.hasRead(editPath)) {
2008
+ conversation.addToolResult(
2009
+ toolCall.id,
2010
+ `\u26A0 \u7981\u6B62\u7F16\u8F91\u672A\u8BFB\u53D6\u7684\u6587\u4EF6\u3002\u8BF7\u5148 read-file "${editPath}" \u4E86\u89E3\u5F53\u524D\u5185\u5BB9\uFF0C\u518D edit-file\u3002`
2011
+ );
2012
+ continue;
2013
+ }
2014
+ }
2015
+ if (toolName === "write-file") {
2016
+ const warn = readTracker.checkWriteOverwrite(
2017
+ params["path"],
2018
+ params["overwrite"]
2019
+ );
2020
+ if (warn) {
2021
+ conversation.addToolResult(toolCall.id, warn);
2022
+ continue;
2023
+ }
2024
+ }
1784
2025
  const result = await this.registry.execute(
1785
2026
  toolName,
1786
2027
  params,
1787
2028
  this.config.max_tool_output
1788
2029
  );
2030
+ autoMemoForTool(this.memoStore, toolName, params, result.content);
2031
+ if (toolName === "read-file") {
2032
+ readTracker.markRead(params["path"]);
2033
+ } else if (toolName === "write-file") {
2034
+ readTracker.markWritten(params["path"]);
2035
+ }
1789
2036
  conversation.addToolResult(toolCall.id, result.content);
1790
2037
  } catch (err) {
1791
2038
  const msg = err instanceof Error ? err.message : String(err);
@@ -2031,7 +2278,11 @@ function createMemoTool(store) {
2031
2278
  },
2032
2279
  content: {
2033
2280
  type: "string",
2034
- description: "write \u65F6\u5FC5\u586B\uFF1A\u8981\u5199\u5165\u7684\u5185\u5BB9\uFF08\u5EFA\u8BAE\u7B80\u6D01\u6458\u8981\uFF0C\u6700\u591A 3000 \u5B57\u7B26\uFF09"
2281
+ description: "write \u65F6\u5FC5\u586B\uFF1A\u8981\u5199\u5165\u7684\u5185\u5BB9\uFF08\u6700\u591A 3000 \u5B57\u7B26\uFF09"
2282
+ },
2283
+ summary: {
2284
+ type: "string",
2285
+ description: "write \u65F6\u53EF\u9009\uFF1A\u4E00\u884C\u6458\u8981\uFF08\u4E0D\u586B\u5219\u81EA\u52A8\u622A\u53D6 content \u524D 80 \u5B57\u7B26\uFF09"
2035
2286
  }
2036
2287
  },
2037
2288
  required: ["action"]
@@ -2043,10 +2294,11 @@ function createMemoTool(store) {
2043
2294
  case "write": {
2044
2295
  const key = params["key"];
2045
2296
  const content = params["content"];
2297
+ const summary = params["summary"];
2046
2298
  if (!key || !content) {
2047
2299
  return { content: "\u9519\u8BEF\uFF1Awrite \u9700\u8981\u63D0\u4F9B key \u548C content" };
2048
2300
  }
2049
- const entry = store.write(key, content);
2301
+ const entry = store.write(key, content, "agent", summary);
2050
2302
  return { content: `\u5DF2\u5199\u5165 memo [${entry.key}]\uFF08${entry.content.length} \u5B57\u7B26\uFF09` };
2051
2303
  }
2052
2304
  case "read": {
@@ -2067,7 +2319,7 @@ ${entry.content}` };
2067
2319
  return { content: "\u5907\u5FD8\u5F55\u4E3A\u7A7A" };
2068
2320
  }
2069
2321
  const lines = items.map(
2070
- (item) => `[${item.key}] (${item.author}) ${item.preview}`
2322
+ (item) => `[${item.key}] (${item.author}) ${item.summary}`
2071
2323
  );
2072
2324
  return { content: `\u5171 ${items.length} \u6761\u5907\u5FD8\u5F55\uFF1A
2073
2325
  ${lines.join("\n")}` };
@@ -3420,7 +3672,7 @@ function App({ config, client, agent, orchestrator, registry, todoStore, memoSto
3420
3672
  );
3421
3673
  useEffect(() => {
3422
3674
  setStructuredConfirmHandler((toolName, params) => {
3423
- return new Promise((resolve7) => {
3675
+ return new Promise((resolve8) => {
3424
3676
  const id = `confirm-${Date.now()}`;
3425
3677
  registerConfirmToolId(toolName, id);
3426
3678
  dispatch({
@@ -3431,13 +3683,13 @@ function App({ config, client, agent, orchestrator, registry, todoStore, memoSto
3431
3683
  resolve: (result) => {
3432
3684
  if (result === "always") {
3433
3685
  registry.addAutoApprove(toolName);
3434
- resolve7({ approved: true });
3686
+ resolve8({ approved: true });
3435
3687
  } else if (result === "allow") {
3436
- resolve7({ approved: true });
3688
+ resolve8({ approved: true });
3437
3689
  } else if (result === "deny") {
3438
- resolve7({ approved: false });
3690
+ resolve8({ approved: false });
3439
3691
  } else {
3440
- resolve7({ approved: false, feedback: result.feedback });
3692
+ resolve8({ approved: false, feedback: result.feedback });
3441
3693
  }
3442
3694
  }
3443
3695
  });
@@ -3707,7 +3959,7 @@ async function startTui(options) {
3707
3959
  registry.register(createTodoTool(todoStore));
3708
3960
  }
3709
3961
  registry.register(createMemoTool(memoStore));
3710
- const agent = new Agent(client, registry, config, systemPrompt);
3962
+ const agent = new Agent(client, registry, config, systemPrompt, void 0, memoStore);
3711
3963
  const orchestrator = new Orchestrator(registry, config, systemPrompt, memoStore);
3712
3964
  const { waitUntilExit } = render(
3713
3965
  /* @__PURE__ */ jsx9(
@@ -3959,13 +4211,13 @@ async function startRepl(options) {
3959
4211
  historySize: 100
3960
4212
  });
3961
4213
  setConfirmHandler(async (promptText) => {
3962
- return new Promise((resolve7) => {
4214
+ return new Promise((resolve8) => {
3963
4215
  process.stdout.write(promptText);
3964
4216
  const onData = (data) => {
3965
4217
  process.stdin.removeListener("data", onData);
3966
4218
  process.stdin.pause();
3967
4219
  const answer = data.toString().trim().toLowerCase();
3968
- resolve7(answer === "y");
4220
+ resolve8(answer === "y");
3969
4221
  };
3970
4222
  process.stdin.resume();
3971
4223
  process.stdin.once("data", onData);
@@ -4131,7 +4383,7 @@ async function runOnce(prompt, config) {
4131
4383
  };
4132
4384
  try {
4133
4385
  if (config.agent_mode === "single") {
4134
- const agent = new Agent(client, registry, config, systemPrompt);
4386
+ const agent = new Agent(client, registry, config, systemPrompt, void 0, memoStore);
4135
4387
  await agent.run(prompt, callbacks);
4136
4388
  } else {
4137
4389
  const orchestrator = new Orchestrator(registry, config, systemPrompt, memoStore);
@@ -4148,7 +4400,7 @@ async function runOnce(prompt, config) {
4148
4400
  }
4149
4401
  function createCli() {
4150
4402
  const program2 = new Command();
4151
- program2.name("zencode").description("\u6781\u7B80 CLI AI \u7F16\u7A0B\u5DE5\u5177").version("0.1.0").option("-m, --model <model>", "\u6307\u5B9A\u6A21\u578B\u540D\u79F0").option("-k, --api-key <key>", "API \u5BC6\u94A5").option("-u, --base-url <url>", "API \u57FA\u7840 URL").option("--single", "\u4F7F\u7528\u5355 Agent \u6A21\u5F0F").option("--dual", "\u4F7F\u7528\u53CC Agent \u6A21\u5F0F").option("--mode <mode>", "\u534F\u4F5C\u6A21\u5F0F (delegated/autonomous/controlled)").option("--simple", "\u4F7F\u7528\u7B80\u5355 REPL \u6A21\u5F0F\uFF08\u975E\u5168\u5C4F TUI\uFF09").argument("[prompt...]", "\u76F4\u63A5\u6267\u884C\u7684\u63D0\u793A\u8BCD\uFF08\u975E\u4EA4\u4E92\u5F0F\uFF09").action(async (promptParts, opts) => {
4403
+ program2.name("zencode").description("\u6781\u7B80 CLI AI \u7F16\u7A0B\u5DE5\u5177").version("0.2.1").option("-m, --model <model>", "\u6307\u5B9A\u6A21\u578B\u540D\u79F0").option("-k, --api-key <key>", "API \u5BC6\u94A5").option("-u, --base-url <url>", "API \u57FA\u7840 URL").option("--single", "\u4F7F\u7528\u5355 Agent \u6A21\u5F0F").option("--dual", "\u4F7F\u7528\u53CC Agent \u6A21\u5F0F").option("--mode <mode>", "\u534F\u4F5C\u6A21\u5F0F (delegated/autonomous/controlled)").option("--simple", "\u4F7F\u7528\u7B80\u5355 REPL \u6A21\u5F0F\uFF08\u975E\u5168\u5C4F TUI\uFF09").argument("[prompt...]", "\u76F4\u63A5\u6267\u884C\u7684\u63D0\u793A\u8BCD\uFF08\u975E\u4EA4\u4E92\u5F0F\uFF09").action(async (promptParts, opts) => {
4152
4404
  const config = loadConfig(opts);
4153
4405
  if (!config.api_key) {
4154
4406
  printError("\u672A\u8BBE\u7F6E API \u5BC6\u94A5\u3002\u8BF7\u901A\u8FC7\u4EE5\u4E0B\u65B9\u5F0F\u4E4B\u4E00\u8BBE\u7F6E\uFF1A");