aws-runtime-bridge 1.9.32 → 1.9.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +35 -1
  2. package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
  3. package/dist/adapter/AcodeSdkAdapter.js +417 -40
  4. package/dist/adapter/ClaudeSdkAdapter.d.ts +6 -0
  5. package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -1
  6. package/dist/adapter/ClaudeSdkAdapter.js +23 -1
  7. package/dist/adapter/idle-poll-loop.d.ts +2 -1
  8. package/dist/adapter/idle-poll-loop.d.ts.map +1 -1
  9. package/dist/adapter/types.d.ts +65 -3
  10. package/dist/adapter/types.d.ts.map +1 -1
  11. package/dist/adapter/types.js +5 -4
  12. package/dist/index.js +4 -0
  13. package/dist/routes/acode-todos.d.ts +11 -0
  14. package/dist/routes/acode-todos.d.ts.map +1 -0
  15. package/dist/routes/acode-todos.js +75 -0
  16. package/dist/routes/memory.d.ts +1 -1
  17. package/dist/routes/memory.d.ts.map +1 -1
  18. package/dist/routes/memory.js +3 -3
  19. package/dist/routes/pty.d.ts.map +1 -1
  20. package/dist/routes/pty.js +9 -0
  21. package/dist/routes/sub-agents.d.ts +14 -0
  22. package/dist/routes/sub-agents.d.ts.map +1 -0
  23. package/dist/routes/sub-agents.js +253 -0
  24. package/dist/routes/terminal.d.ts +9 -1
  25. package/dist/routes/terminal.d.ts.map +1 -1
  26. package/dist/routes/terminal.js +207 -22
  27. package/dist/services/agent-event-store.d.ts +1 -0
  28. package/dist/services/agent-event-store.d.ts.map +1 -1
  29. package/dist/services/event-delta-pusher.js +4 -4
  30. package/dist/services/session-output.d.ts +3 -0
  31. package/dist/services/session-output.d.ts.map +1 -1
  32. package/dist/services/session-output.js +38 -2
  33. package/dist/services/sub-agent-manager-instance.d.ts +4 -0
  34. package/dist/services/sub-agent-manager-instance.d.ts.map +1 -0
  35. package/dist/services/sub-agent-manager-instance.js +12 -0
  36. package/dist/services/workspace-files.d.ts +1 -0
  37. package/dist/services/workspace-files.d.ts.map +1 -1
  38. package/dist/services/workspace-files.js +57 -1
  39. package/package/acode/dist/ask-user-question-tool.d.ts +47 -0
  40. package/package/acode/dist/ask-user-question-tool.d.ts.map +1 -0
  41. package/package/acode/dist/ask-user-question-tool.js +233 -0
  42. package/package/acode/dist/built-in-file-tools.d.ts +2 -0
  43. package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
  44. package/package/acode/dist/compaction.d.ts +206 -0
  45. package/package/acode/dist/compaction.d.ts.map +1 -0
  46. package/package/acode/dist/compaction.js +664 -0
  47. package/package/acode/dist/config.d.ts +6 -1
  48. package/package/acode/dist/config.d.ts.map +1 -1
  49. package/package/acode/dist/config.js +27 -2
  50. package/package/acode/dist/index.d.ts +4 -0
  51. package/package/acode/dist/index.d.ts.map +1 -1
  52. package/package/acode/dist/index.js +4 -0
  53. package/package/acode/dist/runtime.d.ts +137 -0
  54. package/package/acode/dist/runtime.d.ts.map +1 -1
  55. package/package/acode/dist/runtime.js +974 -172
  56. package/package/acode/dist/skill-tool.d.ts +30 -0
  57. package/package/acode/dist/skill-tool.d.ts.map +1 -0
  58. package/package/acode/dist/skill-tool.js +174 -0
  59. package/package/acode/dist/sub-agent-manager.d.ts +169 -0
  60. package/package/acode/dist/sub-agent-manager.d.ts.map +1 -0
  61. package/package/acode/dist/sub-agent-manager.js +535 -0
  62. package/package/acode/dist/sub-agent-store.d.ts +33 -0
  63. package/package/acode/dist/sub-agent-store.d.ts.map +1 -0
  64. package/package/acode/dist/sub-agent-store.js +109 -0
  65. package/package/acode/dist/sub-agent-tools.d.ts +72 -0
  66. package/package/acode/dist/sub-agent-tools.d.ts.map +1 -0
  67. package/package/acode/dist/sub-agent-tools.js +429 -0
  68. package/package/acode/dist/sub-agent-types.d.ts +81 -0
  69. package/package/acode/dist/sub-agent-types.d.ts.map +1 -0
  70. package/package/acode/dist/sub-agent-types.js +8 -0
  71. package/package/acode/dist/todo-store.d.ts +42 -0
  72. package/package/acode/dist/todo-store.d.ts.map +1 -0
  73. package/package/acode/dist/todo-store.js +68 -0
  74. package/package/acode/dist/todo-tool.d.ts +6 -0
  75. package/package/acode/dist/todo-tool.d.ts.map +1 -0
  76. package/package/acode/dist/todo-tool.js +138 -0
  77. package/package/acode/dist/types.d.ts +22 -1
  78. package/package/acode/dist/types.d.ts.map +1 -1
  79. package/package/acode/package.json +13 -2
  80. package/package/aws-client-agent-mcp/dist/context-manager.test.js +0 -2
  81. package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +1 -1
  82. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +83 -45
  83. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
  84. package/package/aws-client-agent-mcp/dist/mcp-server.js +451 -325
  85. package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
  86. package/package/aws-client-agent-mcp/dist/mcp-server.test.js +259 -241
  87. package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
  88. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +1 -19
  89. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
  90. package/package/aws-client-agent-mcp/dist/mcp-tools.js +2 -69
  91. package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
  92. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +17 -19
  93. package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -1
  94. package/package/aws-client-agent-mcp/dist/memory-store.js +62 -99
  95. package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -1
  96. package/package/aws-client-agent-mcp/dist/memory-store.test.js +207 -125
  97. package/package/aws-client-agent-mcp/dist/memory-store.test.js.map +1 -1
  98. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +3 -4
  99. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +1 -1
  100. package/package/aws-client-agent-mcp/dist/memory-tools.js +28 -33
  101. package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -1
  102. package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +27 -9
  103. package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +1 -1
  104. package/package/aws-client-agent-mcp/dist/message-buffer.js +100 -23
  105. package/package/aws-client-agent-mcp/dist/message-buffer.js.map +1 -1
  106. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +1 -3
  107. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +1 -1
  108. package/package/aws-client-agent-mcp/dist/server-memory-store.js +7 -11
  109. package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +1 -1
  110. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +1 -1
  111. package/package/aws-client-agent-mcp/dist/status-reporter.js +8 -5
  112. package/package/aws-client-agent-mcp/dist/status-reporter.js.map +1 -1
  113. package/package/aws-client-agent-mcp/dist/status-reporter.test.js +93 -0
  114. package/package/aws-client-agent-mcp/dist/status-reporter.test.js.map +1 -1
  115. package/package/aws-client-agent-mcp/dist/types.d.ts +3 -25
  116. package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
  117. package/package.json +17 -7
  118. package/dist/adapter/AcodeSdkAdapter.test.d.ts +0 -2
  119. package/dist/adapter/AcodeSdkAdapter.test.d.ts.map +0 -1
  120. package/dist/adapter/AcodeSdkAdapter.test.js +0 -2000
  121. package/dist/adapter/AdapterRegistry.test.d.ts +0 -5
  122. package/dist/adapter/AdapterRegistry.test.d.ts.map +0 -1
  123. package/dist/adapter/AdapterRegistry.test.js +0 -118
  124. package/dist/adapter/ClaudeSdkAdapter.test.d.ts +0 -2
  125. package/dist/adapter/ClaudeSdkAdapter.test.d.ts.map +0 -1
  126. package/dist/adapter/ClaudeSdkAdapter.test.js +0 -311
  127. package/dist/adapter/CodexSdkAdapter.test.d.ts +0 -2
  128. package/dist/adapter/CodexSdkAdapter.test.d.ts.map +0 -1
  129. package/dist/adapter/CodexSdkAdapter.test.js +0 -270
  130. package/dist/adapter/OpencodeSdkAdapter.test.d.ts +0 -2
  131. package/dist/adapter/OpencodeSdkAdapter.test.d.ts.map +0 -1
  132. package/dist/adapter/OpencodeSdkAdapter.test.js +0 -158
  133. package/dist/adapter/acode-tool-names.test.d.ts +0 -2
  134. package/dist/adapter/acode-tool-names.test.d.ts.map +0 -1
  135. package/dist/adapter/acode-tool-names.test.js +0 -28
  136. package/dist/adapter/adapter.test.d.ts +0 -5
  137. package/dist/adapter/adapter.test.d.ts.map +0 -1
  138. package/dist/adapter/adapter.test.js +0 -180
  139. package/dist/adapter/idle-poll-loop.test.d.ts +0 -2
  140. package/dist/adapter/idle-poll-loop.test.d.ts.map +0 -1
  141. package/dist/adapter/idle-poll-loop.test.js +0 -85
  142. package/dist/adapter/types.test.d.ts +0 -2
  143. package/dist/adapter/types.test.d.ts.map +0 -1
  144. package/dist/adapter/types.test.js +0 -50
  145. package/dist/adapters/cc-switch/mcp-acode.test.d.ts +0 -2
  146. package/dist/adapters/cc-switch/mcp-acode.test.d.ts.map +0 -1
  147. package/dist/adapters/cc-switch/mcp-acode.test.js +0 -80
  148. package/dist/adapters/cc-switch/mcp-claudecode.test.d.ts +0 -2
  149. package/dist/adapters/cc-switch/mcp-claudecode.test.d.ts.map +0 -1
  150. package/dist/adapters/cc-switch/mcp-claudecode.test.js +0 -75
  151. package/dist/adapters/cc-switch/mcp-codex.test.d.ts +0 -2
  152. package/dist/adapters/cc-switch/mcp-codex.test.d.ts.map +0 -1
  153. package/dist/adapters/cc-switch/mcp-codex.test.js +0 -126
  154. package/dist/adapters/cc-switch/mcp-opencode.test.d.ts +0 -2
  155. package/dist/adapters/cc-switch/mcp-opencode.test.d.ts.map +0 -1
  156. package/dist/adapters/cc-switch/mcp-opencode.test.js +0 -62
  157. package/dist/adapters/cc-switch/skill-directory.test.d.ts +0 -2
  158. package/dist/adapters/cc-switch/skill-directory.test.d.ts.map +0 -1
  159. package/dist/adapters/cc-switch/skill-directory.test.js +0 -74
  160. package/dist/config.test.d.ts +0 -2
  161. package/dist/config.test.d.ts.map +0 -1
  162. package/dist/config.test.js +0 -107
  163. package/dist/routes/ai-sources.test.d.ts +0 -2
  164. package/dist/routes/ai-sources.test.d.ts.map +0 -1
  165. package/dist/routes/ai-sources.test.js +0 -169
  166. package/dist/routes/file-browser.test.d.ts +0 -5
  167. package/dist/routes/file-browser.test.d.ts.map +0 -1
  168. package/dist/routes/file-browser.test.js +0 -155
  169. package/dist/routes/git.test.d.ts +0 -2
  170. package/dist/routes/git.test.d.ts.map +0 -1
  171. package/dist/routes/git.test.js +0 -330
  172. package/dist/routes/instance.test.d.ts +0 -5
  173. package/dist/routes/instance.test.d.ts.map +0 -1
  174. package/dist/routes/instance.test.js +0 -389
  175. package/dist/routes/mcp.test.d.ts +0 -5
  176. package/dist/routes/mcp.test.d.ts.map +0 -1
  177. package/dist/routes/mcp.test.js +0 -92
  178. package/dist/routes/memory-route-wiring.test.d.ts +0 -2
  179. package/dist/routes/memory-route-wiring.test.d.ts.map +0 -1
  180. package/dist/routes/memory-route-wiring.test.js +0 -15
  181. package/dist/routes/memory.test.d.ts +0 -2
  182. package/dist/routes/memory.test.d.ts.map +0 -1
  183. package/dist/routes/memory.test.js +0 -177
  184. package/dist/routes/properties.test.d.ts +0 -5
  185. package/dist/routes/properties.test.d.ts.map +0 -1
  186. package/dist/routes/properties.test.js +0 -72
  187. package/dist/routes/pty.test.d.ts +0 -2
  188. package/dist/routes/pty.test.d.ts.map +0 -1
  189. package/dist/routes/pty.test.js +0 -82
  190. package/dist/routes/runtime-binding.test.d.ts +0 -2
  191. package/dist/routes/runtime-binding.test.d.ts.map +0 -1
  192. package/dist/routes/runtime-binding.test.js +0 -32
  193. package/dist/routes/sessions.test.d.ts +0 -5
  194. package/dist/routes/sessions.test.d.ts.map +0 -1
  195. package/dist/routes/sessions.test.js +0 -86
  196. package/dist/routes/skills.test.d.ts +0 -5
  197. package/dist/routes/skills.test.d.ts.map +0 -1
  198. package/dist/routes/skills.test.js +0 -50
  199. package/dist/routes/system-metrics.test.d.ts +0 -2
  200. package/dist/routes/system-metrics.test.d.ts.map +0 -1
  201. package/dist/routes/system-metrics.test.js +0 -16
  202. package/dist/routes/terminal.stop-options.test.d.ts +0 -2
  203. package/dist/routes/terminal.stop-options.test.d.ts.map +0 -1
  204. package/dist/routes/terminal.stop-options.test.js +0 -39
  205. package/dist/routes/terminal.test.d.ts +0 -2
  206. package/dist/routes/terminal.test.d.ts.map +0 -1
  207. package/dist/routes/terminal.test.js +0 -746
  208. package/dist/routes/yml.test.d.ts +0 -5
  209. package/dist/routes/yml.test.d.ts.map +0 -1
  210. package/dist/routes/yml.test.js +0 -58
  211. package/dist/services/ai-source-apply.test.d.ts +0 -2
  212. package/dist/services/ai-source-apply.test.d.ts.map +0 -1
  213. package/dist/services/ai-source-apply.test.js +0 -138
  214. package/dist/services/auto-register.test.d.ts +0 -2
  215. package/dist/services/auto-register.test.d.ts.map +0 -1
  216. package/dist/services/auto-register.test.js +0 -184
  217. package/dist/services/aws-client-agent-mcp.test.d.ts +0 -2
  218. package/dist/services/aws-client-agent-mcp.test.d.ts.map +0 -1
  219. package/dist/services/aws-client-agent-mcp.test.js +0 -242
  220. package/dist/services/bridge-package-publish-hooks.test.d.ts +0 -2
  221. package/dist/services/bridge-package-publish-hooks.test.d.ts.map +0 -1
  222. package/dist/services/bridge-package-publish-hooks.test.js +0 -136
  223. package/dist/services/cc-switch-discovery.test.d.ts +0 -2
  224. package/dist/services/cc-switch-discovery.test.d.ts.map +0 -1
  225. package/dist/services/cc-switch-discovery.test.js +0 -56
  226. package/dist/services/cli-commands.test.d.ts +0 -2
  227. package/dist/services/cli-commands.test.d.ts.map +0 -1
  228. package/dist/services/cli-commands.test.js +0 -230
  229. package/dist/services/instance-init-service.test.d.ts +0 -2
  230. package/dist/services/instance-init-service.test.d.ts.map +0 -1
  231. package/dist/services/instance-init-service.test.js +0 -140
  232. package/dist/services/instance-state.test.d.ts +0 -2
  233. package/dist/services/instance-state.test.d.ts.map +0 -1
  234. package/dist/services/instance-state.test.js +0 -245
  235. package/dist/services/mcp-launch-binding-queue.test.d.ts +0 -2
  236. package/dist/services/mcp-launch-binding-queue.test.d.ts.map +0 -1
  237. package/dist/services/mcp-launch-binding-queue.test.js +0 -181
  238. package/dist/services/runtime-binding.test.d.ts +0 -2
  239. package/dist/services/runtime-binding.test.d.ts.map +0 -1
  240. package/dist/services/runtime-binding.test.js +0 -78
  241. package/dist/services/runtime-lifecycle-policy.test.d.ts +0 -2
  242. package/dist/services/runtime-lifecycle-policy.test.d.ts.map +0 -1
  243. package/dist/services/runtime-lifecycle-policy.test.js +0 -41
  244. package/dist/services/session-output.test.d.ts +0 -5
  245. package/dist/services/session-output.test.d.ts.map +0 -1
  246. package/dist/services/session-output.test.js +0 -177
  247. package/dist/services/startup-config-wizard.test.d.ts +0 -2
  248. package/dist/services/startup-config-wizard.test.d.ts.map +0 -1
  249. package/dist/services/startup-config-wizard.test.js +0 -184
  250. package/dist/services/terminal-persistence.test.d.ts +0 -5
  251. package/dist/services/terminal-persistence.test.d.ts.map +0 -1
  252. package/dist/services/terminal-persistence.test.js +0 -159
  253. package/dist/services/tool-installer.test.d.ts +0 -2
  254. package/dist/services/tool-installer.test.d.ts.map +0 -1
  255. package/dist/services/tool-installer.test.js +0 -225
  256. package/dist/services/workspace-files.test.d.ts +0 -2
  257. package/dist/services/workspace-files.test.d.ts.map +0 -1
  258. package/dist/services/workspace-files.test.js +0 -648
  259. package/dist/services/workspace-watch.test.d.ts +0 -2
  260. package/dist/services/workspace-watch.test.d.ts.map +0 -1
  261. package/dist/services/workspace-watch.test.js +0 -38
  262. package/dist/utils/file-utils.test.d.ts +0 -2
  263. package/dist/utils/file-utils.test.d.ts.map +0 -1
  264. package/dist/utils/file-utils.test.js +0 -244
  265. package/dist/utils/logger.test.d.ts +0 -2
  266. package/dist/utils/logger.test.d.ts.map +0 -1
  267. package/dist/utils/logger.test.js +0 -93
  268. package/dist/utils/sdk-package-loader.test.d.ts +0 -2
  269. package/dist/utils/sdk-package-loader.test.d.ts.map +0 -1
  270. package/dist/utils/sdk-package-loader.test.js +0 -84
  271. package/dist/utils/validation.test.d.ts +0 -2
  272. package/dist/utils/validation.test.d.ts.map +0 -1
  273. package/dist/utils/validation.test.js +0 -88
  274. package/dist/utils/yaml-utils.test.d.ts +0 -2
  275. package/dist/utils/yaml-utils.test.d.ts.map +0 -1
  276. package/dist/utils/yaml-utils.test.js +0 -363
@@ -1,12 +1,12 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { describe, it } from "node:test";
6
6
  import { AgentClient } from "./agent-client.js";
7
7
  import { McpServer } from "./mcp-server.js";
8
8
  import { MCP_TOOLS } from "./mcp-tools.js";
9
- import { MemoryCapacityError, MemoryStore, } from "./memory-store.js";
9
+ import { MemoryStore, } from "./memory-store.js";
10
10
  import { MessageBuffer } from "./message-buffer.js";
11
11
  function createServerWithUnread(unreadMessages, overrides = {}) {
12
12
  const server = new McpServer();
@@ -150,52 +150,40 @@ describe("McpServer unread backlog hydration", () => {
150
150
  });
151
151
  });
152
152
  it("poll_message should keep blocking through empty polls until messages arrive", async () => {
153
- const previousBlockWait = process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS;
154
- process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS = "20";
155
- try {
156
- const directMessage = {
157
- msgId: "dm-delayed-1",
158
- senderId: "agent-delayed",
159
- senderName: "Agent Delayed",
160
- content: "delayed dm",
161
- requireReply: false,
162
- timestamp: new Date().toISOString(),
163
- };
164
- const fetchOptions = [];
165
- let fetchCount = 0;
166
- const server = createServerWithUnread({ directMessages: [], groupMessages: [] }, {
167
- fetchUnreadMessages: async (options) => {
168
- fetchOptions.push(options ?? {});
169
- fetchCount += 1;
170
- if (fetchCount <= 1) {
171
- return { directMessages: [], groupMessages: [] };
172
- }
173
- return { directMessages: [directMessage], groupMessages: [] };
174
- },
175
- });
176
- const handleToolCall = getHandleToolCall(server);
177
- const result = await handleToolCall.call(server, "poll_message", {});
178
- assert.deepEqual(result, {
179
- directMessages: [directMessage],
180
- groupMessages: [],
181
- fromBuffer: true,
182
- systemMessages: [],
183
- });
184
- assert.equal(fetchOptions.length, 2);
185
- assert.equal(fetchOptions[0].blockIfEmpty, false);
186
- assert.equal(fetchOptions[0].includePipelineTasks, false);
187
- assert.equal(fetchOptions[1].blockIfEmpty, true);
188
- assert.ok(typeof fetchOptions[1].blockTimeoutMs === "number");
189
- assert.equal(fetchOptions[1].blockTimeoutMs, 20);
190
- }
191
- finally {
192
- if (previousBlockWait === undefined) {
193
- delete process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS;
194
- }
195
- else {
196
- process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS = previousBlockWait;
197
- }
198
- }
153
+ const directMessage = {
154
+ msgId: "dm-delayed-1",
155
+ senderId: "agent-delayed",
156
+ senderName: "Agent Delayed",
157
+ content: "delayed dm",
158
+ requireReply: false,
159
+ timestamp: new Date().toISOString(),
160
+ };
161
+ const fetchOptions = [];
162
+ const server = createServerWithUnread({ directMessages: [], groupMessages: [] }, {
163
+ fetchUnreadMessages: async (options) => {
164
+ fetchOptions.push(options ?? {});
165
+ return { directMessages: [], groupMessages: [] };
166
+ },
167
+ });
168
+ // Simulate a WebSocket message arriving after hydration returns empty.
169
+ // poll_message must keep blocking on the local buffer until the message arrives.
170
+ const buffer = Reflect.get(server, "messageBuffer");
171
+ setTimeout(() => {
172
+ buffer.push(directMessage);
173
+ }, 50);
174
+ const handleToolCall = getHandleToolCall(server);
175
+ const result = await handleToolCall.call(server, "poll_message", {});
176
+ assert.deepEqual(result, {
177
+ directMessages: [directMessage],
178
+ groupMessages: [],
179
+ fromBuffer: true,
180
+ systemMessages: [],
181
+ });
182
+ // fetchUnreadMessages should only be called once (the initial non-blocking hydrate).
183
+ // The message must arrive via the local buffer (WebSocket push), not a second blocking fetch.
184
+ assert.equal(fetchOptions.length, 1);
185
+ assert.equal(fetchOptions[0].blockIfEmpty, false);
186
+ assert.equal(fetchOptions[0].includePipelineTasks, false);
199
187
  });
200
188
  it("poll_message should handle hydration error gracefully and receive WebSocket messages", async () => {
201
189
  const directMessage = {
@@ -210,10 +198,7 @@ describe("McpServer unread backlog hydration", () => {
210
198
  const server = createServerWithUnread({ directMessages: [], groupMessages: [] }, {
211
199
  fetchUnreadMessages: async () => {
212
200
  fetchCount += 1;
213
- if (fetchCount === 2) {
214
- throw new Error("MCP tool poll_message timed out after 120000ms");
215
- }
216
- return { directMessages: [], groupMessages: [] };
201
+ throw new Error("MCP tool poll_message timed out after 120000ms");
217
202
  },
218
203
  });
219
204
  // Simulate WebSocket message arriving after hydration fails
@@ -229,7 +214,10 @@ describe("McpServer unread backlog hydration", () => {
229
214
  fromBuffer: true,
230
215
  systemMessages: [],
231
216
  });
232
- assert.equal(fetchCount, 2);
217
+ // fetchUnreadMessages should only be called once (the initial hydrate, which throws).
218
+ // hydrateUnreadMessagesFromServer catches the error, and poll_message falls back to
219
+ // blocking on the local buffer until the WebSocket message arrives.
220
+ assert.equal(fetchCount, 1);
233
221
  });
234
222
  it("get_message should still hydrate unread group messages after profile push is received", async () => {
235
223
  const groupMessage = {
@@ -519,54 +507,13 @@ describe("McpServer unread backlog hydration", () => {
519
507
  }, 50);
520
508
  const handleToolCall = getHandleToolCall(server);
521
509
  const result = (await handleToolCall.call(server, "poll_message", {}));
522
- assert.equal(fetchCalls, 2);
510
+ // Only the initial non-blocking hydrate should call fetchUnreadMessages.
511
+ // The message must arrive via the local buffer (WebSocket push).
512
+ assert.equal(fetchCalls, 1);
523
513
  assert.deepEqual(result.directMessages, [delayedMessage]);
524
514
  assert.deepEqual(result.groupMessages, []);
525
515
  assert.equal(result.fromBuffer, true);
526
516
  });
527
- it("poll_message should clamp block wait below HTTP request timeout", async () => {
528
- const previousBlockWait = process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS;
529
- process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS = "120000";
530
- try {
531
- const delayedMessage = {
532
- msgId: "dm-after-clamped-poll",
533
- senderId: "agent-later",
534
- senderName: "Later Agent",
535
- receiverId: "agent-self",
536
- content: "arrived after clamped backend poll",
537
- requireReply: false,
538
- timestamp: new Date().toISOString(),
539
- };
540
- const fetchOptions = [];
541
- const server = createServerWithUnread({
542
- directMessages: [],
543
- groupMessages: [],
544
- }, {
545
- fetchUnreadMessages: async (options) => {
546
- fetchOptions.push(options ?? {});
547
- return fetchOptions.length === 1
548
- ? { directMessages: [], groupMessages: [] }
549
- : fetchOptions.length === 2
550
- ? { directMessages: [delayedMessage], groupMessages: [] }
551
- : { directMessages: [], groupMessages: [] };
552
- },
553
- });
554
- const handleToolCall = getHandleToolCall(server);
555
- const result = (await handleToolCall.call(server, "poll_message", {}));
556
- assert.deepEqual(result.directMessages, [delayedMessage]);
557
- assert.equal(fetchOptions[0].blockIfEmpty, false);
558
- assert.equal(fetchOptions[1].blockIfEmpty, true);
559
- assert.equal(fetchOptions[1].blockTimeoutMs, 120000);
560
- }
561
- finally {
562
- if (previousBlockWait === undefined) {
563
- delete process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS;
564
- }
565
- else {
566
- process.env.AWS_POLL_MESSAGE_BLOCK_WAIT_MS = previousBlockWait;
567
- }
568
- }
569
- });
570
517
  it("poll_message should restore waiting status when task notification is returned", async () => {
571
518
  const statusEvents = [];
572
519
  const server = createServerWithUnread({
@@ -768,7 +715,6 @@ describe("McpServer memory tools", () => {
768
715
  assert.ok(toolNames.includes("search_memory"));
769
716
  assert.ok(toolNames.includes("list_memories"));
770
717
  assert.ok(toolNames.includes("get_memory_stats"));
771
- assert.ok(toolNames.includes("archive_recently_memory"));
772
718
  // Memory 近期记忆过期与回忆工具 (v1.11.0)
773
719
  assert.ok(toolNames.includes("memory_recurrence"));
774
720
  assert.ok(toolNames.includes("memory_recurrence_complete"));
@@ -777,7 +723,7 @@ describe("McpServer memory tools", () => {
777
723
  await withMemoryServer(async (server) => {
778
724
  const handleToolCall = getHandleToolCall(server);
779
725
  const created = await handleToolCall.call(server, "create_memory", {
780
- memory_type: "memory",
726
+ memory_type: "project_memory",
781
727
  uri: "Core://Agent/Profile/",
782
728
  content: "prefers concise backend summaries",
783
729
  });
@@ -785,12 +731,12 @@ describe("McpServer memory tools", () => {
785
731
  assert.equal(created.content, undefined);
786
732
  const read = await handleToolCall.call(server, "read_memory", {
787
733
  uri: "core://Agent/Profile",
788
- memory_type: "memory",
734
+ memory_type: "project_memory",
789
735
  });
790
736
  assert.equal(read.content, "prefers concise backend summaries");
791
737
  const updated = await handleToolCall.call(server, "update_memory", {
792
738
  uri: "core://Agent/Profile",
793
- memory_type: "memory",
739
+ memory_type: "project_memory",
794
740
  old_string: "concise",
795
741
  new_string: "structured",
796
742
  append: "\nuses MCP memory tools",
@@ -799,7 +745,7 @@ describe("McpServer memory tools", () => {
799
745
  assert.equal(updated.version, 2);
800
746
  const readUpdated = await handleToolCall.call(server, "read_memory", {
801
747
  uri: "core://Agent/Profile",
802
- memory_type: "memory",
748
+ memory_type: "project_memory",
803
749
  });
804
750
  assert.match(readUpdated.content, /structured backend/);
805
751
  assert.match(readUpdated.content, /MCP memory tools/);
@@ -810,7 +756,7 @@ describe("McpServer memory tools", () => {
810
756
  assert.equal(searchResult.results.length, 1);
811
757
  const deleted = await handleToolCall.call(server, "delete_memory", {
812
758
  uri: "core://Agent/Profile",
813
- memory_type: "memory",
759
+ memory_type: "project_memory",
814
760
  });
815
761
  assert.deepEqual(deleted, { deleted: true });
816
762
  });
@@ -819,25 +765,25 @@ describe("McpServer memory tools", () => {
819
765
  await withMemoryServer(async (server) => {
820
766
  const handleToolCall = getHandleToolCall(server);
821
767
  await handleToolCall.call(server, "create_memory", {
822
- memory_type: "task_list",
768
+ memory_type: "recently_memory",
823
769
  uri: "task://todo/current",
824
770
  content: "finish memory endpoint tests",
825
771
  });
826
772
  await handleToolCall.call(server, "create_memory", {
827
- memory_type: "recently_memory",
773
+ memory_type: "agent_memory",
828
774
  uri: "recent://discussion/memory-tools",
829
775
  content: "memory tools should stay local for now",
830
776
  });
831
777
  const taskList = await handleToolCall.call(server, "list_memories", {
832
- memory_type: "task_list",
778
+ memory_type: "recently_memory",
833
779
  });
834
780
  assert.equal(taskList.length, 1);
835
781
  const recentList = await handleToolCall.call(server, "list_memories", {
836
- memory_type: "recently_memory",
782
+ memory_type: "agent_memory",
837
783
  });
838
784
  assert.equal(recentList.length, 1);
839
785
  await assert.rejects(() => handleToolCall.call(server, "list_memories", {
840
- memory_type: "memory",
786
+ memory_type: "project_memory",
841
787
  }), /Invalid memory_type/);
842
788
  });
843
789
  });
@@ -846,76 +792,42 @@ describe("McpServer memory tools", () => {
846
792
  const firstHandleToolCall = getHandleToolCall(firstServer);
847
793
  const secondHandleToolCall = getHandleToolCall(secondServer);
848
794
  await firstHandleToolCall.call(firstServer, "create_memory", {
849
- memory_type: "memory",
795
+ memory_type: "project_memory",
850
796
  uri: "core://role/shared-profile",
851
797
  content: "shared role knowledge",
852
798
  });
853
799
  await firstHandleToolCall.call(firstServer, "create_memory", {
854
- memory_type: "recently_memory",
800
+ memory_type: "agent_memory",
855
801
  uri: "recent://instance/private-context",
856
802
  content: "agent one private context",
857
803
  });
858
804
  const roleMemory = await secondHandleToolCall.call(secondServer, "read_memory", {
859
805
  uri: "core://role/shared-profile",
860
- memory_type: "memory",
806
+ memory_type: "project_memory",
861
807
  });
862
808
  const recentMemory = await secondHandleToolCall.call(secondServer, "read_memory", {
863
809
  uri: "recent://instance/private-context",
864
- memory_type: "recently_memory",
810
+ memory_type: "agent_memory",
865
811
  });
866
812
  assert.equal(roleMemory.content, "shared role knowledge");
867
813
  assert.equal(recentMemory, null);
868
814
  });
869
815
  });
870
- it("supports task-list removal and recent-memory archive semantics", async () => {
871
- await withMemoryServer(async (server) => {
872
- const handleToolCall = getHandleToolCall(server);
873
- await handleToolCall.call(server, "create_memory", {
874
- memory_type: "task_list",
875
- uri: "task://todo/remove-me",
876
- content: "temporary task",
877
- });
878
- await handleToolCall.call(server, "create_memory", {
879
- memory_type: "recently_memory",
880
- uri: "recent://note/archive-me",
881
- content: "hot context",
882
- });
883
- const deleted = await handleToolCall.call(server, "delete_memory", {
884
- uri: "task://todo/remove-me",
885
- memory_type: "task_list",
886
- });
887
- assert.deepEqual(deleted, { deleted: true });
888
- const archived = await handleToolCall.call(server, "archive_recently_memory", {
889
- uri: "recent://note/archive-me",
890
- });
891
- assert.equal(archived.memory_type, "memory");
892
- const archivedInRoleScope = await handleToolCall.call(server, "read_memory", {
893
- uri: "recent://note/archive-me",
894
- memory_type: "memory",
895
- });
896
- const removedFromInstanceScope = await handleToolCall.call(server, "read_memory", {
897
- uri: "recent://note/archive-me",
898
- memory_type: "recently_memory",
899
- });
900
- assert.equal(archivedInRoleScope.content, "hot context");
901
- assert.equal(removedFromInstanceScope, null);
902
- });
903
- });
904
816
  it("returns memory stats through MCP dispatch", async () => {
905
817
  await withMemoryServer(async (server) => {
906
818
  const handleToolCall = getHandleToolCall(server);
907
819
  await handleToolCall.call(server, "create_memory", {
908
- memory_type: "task_list",
820
+ memory_type: "recently_memory",
909
821
  uri: "task://todo/stats",
910
822
  content: "temporary task",
911
823
  });
912
824
  await handleToolCall.call(server, "create_memory", {
913
- memory_type: "recently_memory",
825
+ memory_type: "agent_memory",
914
826
  uri: "recent://note/stats",
915
827
  content: "hot context",
916
828
  });
917
829
  await handleToolCall.call(server, "create_memory", {
918
- memory_type: "memory",
830
+ memory_type: "project_memory",
919
831
  uri: "core://agent/profile",
920
832
  content: "long-term profile",
921
833
  });
@@ -929,15 +841,15 @@ describe("McpServer memory tools", () => {
929
841
  exceeded: false,
930
842
  hardExceeded: false,
931
843
  });
932
- assert.equal(typedStats.by_type.task_list.count, 1);
933
- assert.equal(typedStats.by_type.task_list.domainCount, 1);
934
- assert.equal(typedStats.by_type.task_list.by_domain.task?.count, 1);
935
844
  assert.equal(typedStats.by_type.recently_memory.count, 1);
936
845
  assert.equal(typedStats.by_type.recently_memory.domainCount, 1);
937
- assert.equal(typedStats.by_type.recently_memory.by_domain.recent?.count, 1);
938
- assert.equal(typedStats.by_type.memory.count, 1);
939
- assert.equal(typedStats.by_type.memory.domainCount, 1);
940
- assert.equal(typedStats.by_type.memory.by_domain.core?.count, 1);
846
+ assert.equal(typedStats.by_type.recently_memory.by_domain.task?.count, 1);
847
+ assert.equal(typedStats.by_type.agent_memory.count, 1);
848
+ assert.equal(typedStats.by_type.agent_memory.domainCount, 1);
849
+ assert.equal(typedStats.by_type.agent_memory.by_domain.recent?.count, 1);
850
+ assert.equal(typedStats.by_type.project_memory.count, 1);
851
+ assert.equal(typedStats.by_type.project_memory.domainCount, 1);
852
+ assert.equal(typedStats.by_type.project_memory.by_domain.core?.count, 1);
941
853
  });
942
854
  });
943
855
  it("reports combined memory stats after long-term memory changes", async () => {
@@ -946,32 +858,13 @@ describe("McpServer memory tools", () => {
946
858
  const reportedStats = [];
947
859
  attachMemoryStatsReporter(server, reportedStats);
948
860
  await handleToolCall.call(server, "create_memory", {
949
- memory_type: "memory",
861
+ memory_type: "project_memory",
950
862
  uri: "project://test-aws/permanent-memory-check",
951
863
  content: "dashboard should see this permanent memory count",
952
864
  });
953
865
  assert.equal(reportedStats.length, 1);
954
- assert.equal(reportedStats[0]?.by_type.memory.count, 1);
955
- assert.equal(reportedStats[0]?.by_type.memory.by_domain.project?.count, 1);
956
- });
957
- });
958
- it("reports combined memory stats after archiving recent memory", async () => {
959
- await withMemoryServer(async (server) => {
960
- const handleToolCall = getHandleToolCall(server);
961
- const reportedStats = [];
962
- attachMemoryStatsReporter(server, reportedStats);
963
- await handleToolCall.call(server, "create_memory", {
964
- memory_type: "recently_memory",
965
- uri: "project://test-aws/hot-note",
966
- content: "hot note that will become permanent",
967
- });
968
- await handleToolCall.call(server, "archive_recently_memory", {
969
- uri: "project://test-aws/hot-note",
970
- });
971
- const latestStats = reportedStats.at(-1);
972
- assert.equal(latestStats?.by_type.recently_memory.count, 0);
973
- assert.equal(latestStats?.by_type.memory.count, 1);
974
- assert.equal(latestStats?.by_type.memory.by_domain.project?.count, 1);
866
+ assert.equal(reportedStats[0]?.by_type.project_memory.count, 1);
867
+ assert.equal(reportedStats[0]?.by_type.project_memory.by_domain.project?.count, 1);
975
868
  });
976
869
  });
977
870
  it("reports existing combined memory stats after auto registration", async () => {
@@ -979,7 +872,7 @@ describe("McpServer memory tools", () => {
979
872
  const reportedStats = [];
980
873
  const roleMemoryStore = Reflect.get(server, "roleMemoryStore");
981
874
  await roleMemoryStore.createMemory({
982
- memory_type: "memory",
875
+ memory_type: "project_memory",
983
876
  uri: "project://test-aws/existing-permanent-memory",
984
877
  content: "existing role memory should be visible on dashboard startup",
985
878
  });
@@ -999,75 +892,55 @@ describe("McpServer memory tools", () => {
999
892
  const autoRegister = Reflect.get(server, "autoRegister");
1000
893
  await autoRegister.call(server);
1001
894
  assert.equal(reportedStats.length, 1);
1002
- assert.equal(reportedStats[0]?.by_type.memory.count, 1);
1003
- assert.equal(reportedStats[0]?.by_type.memory.by_domain.project?.count, 1);
895
+ assert.equal(reportedStats[0]?.by_type.project_memory.count, 1);
896
+ assert.equal(reportedStats[0]?.by_type.project_memory.by_domain.project?.count, 1);
1004
897
  });
1005
898
  });
1006
899
  it("returns memory stats for one requested memory type", async () => {
1007
900
  await withMemoryServer(async (server) => {
1008
901
  const handleToolCall = getHandleToolCall(server);
1009
902
  await handleToolCall.call(server, "create_memory", {
1010
- memory_type: "task_list",
903
+ memory_type: "recently_memory",
1011
904
  uri: "task://todo/stats",
1012
905
  content: "temporary task",
1013
906
  });
1014
907
  await handleToolCall.call(server, "create_memory", {
1015
- memory_type: "recently_memory",
908
+ memory_type: "agent_memory",
1016
909
  uri: "recent://note/stats",
1017
910
  content: "hot context",
1018
911
  });
1019
912
  await handleToolCall.call(server, "create_memory", {
1020
- memory_type: "memory",
913
+ memory_type: "project_memory",
1021
914
  uri: "core://agent/profile",
1022
915
  content: "long-term profile",
1023
916
  });
1024
917
  const stats = (await handleToolCall.call(server, "get_memory_stats", {
1025
- memory_type: "recently_memory",
918
+ memory_type: "agent_memory",
1026
919
  }));
1027
- assert.equal(stats.memory_type, "recently_memory");
920
+ assert.equal(stats.memory_type, "agent_memory");
1028
921
  assert.equal(stats.total, 1);
1029
- assert.deepEqual(Object.keys(stats.by_type), ["recently_memory"]);
1030
- assert.equal(stats.by_type.recently_memory?.domainCount, 1);
1031
- assert.equal(stats.by_type.recently_memory?.by_domain.recent?.count, 1);
1032
- const memoryStats = (await handleToolCall.call(server, "get_memory_stats", { memory_type: "memory" }));
1033
- assert.equal(memoryStats.memory_type, "memory");
922
+ assert.deepEqual(Object.keys(stats.by_type), ["agent_memory"]);
923
+ assert.equal(stats.by_type.agent_memory?.domainCount, 1);
924
+ assert.equal(stats.by_type.agent_memory?.by_domain.recent?.count, 1);
925
+ const memoryStats = (await handleToolCall.call(server, "get_memory_stats", { memory_type: "project_memory" }));
926
+ assert.equal(memoryStats.memory_type, "project_memory");
1034
927
  assert.equal(memoryStats.total, 1);
1035
- assert.deepEqual(Object.keys(memoryStats.by_type), ["memory"]);
1036
- assert.equal(memoryStats.by_type.memory?.domainCount, 1);
1037
- assert.equal(memoryStats.by_type.memory?.by_domain.core?.count, 1);
1038
- });
1039
- });
1040
- it("keeps structured details on memory capacity errors", async () => {
1041
- await withMemoryServer(async (server) => {
1042
- const handleToolCall = getHandleToolCall(server);
1043
- for (let index = 0; index < 64; index += 1) {
1044
- await handleToolCall.call(server, "create_memory", {
1045
- memory_type: "recently_memory",
1046
- uri: `recent://capacity/${index}`,
1047
- content: `recent ${index}`,
1048
- });
1049
- }
1050
- await assert.rejects(async () => {
1051
- await handleToolCall.call(server, "create_memory", {
1052
- memory_type: "recently_memory",
1053
- uri: "recent://capacity/overflow",
1054
- content: "overflow",
1055
- });
1056
- }, (error) => {
1057
- assert.ok(error instanceof MemoryCapacityError);
1058
- assert.equal(error.details.code, "MEMORY_TYPE_LIMIT_REACHED");
1059
- assert.equal(error.details.memory_type, "recently_memory");
1060
- assert.equal(error.details.domain, "recent");
1061
- assert.equal(error.details.current, 64);
1062
- assert.equal(error.details.limit, 64);
1063
- assert.ok(error.details.recommended_actions.includes("archive_recently_memory({ uri })"));
1064
- return true;
1065
- });
928
+ assert.deepEqual(Object.keys(memoryStats.by_type), ["project_memory"]);
929
+ assert.equal(memoryStats.by_type.project_memory?.domainCount, 1);
930
+ assert.equal(memoryStats.by_type.project_memory?.by_domain.core?.count, 1);
1066
931
  });
1067
932
  });
1068
933
  it("poll_message injects a cleanup notice when listable memory exceeds soft limits", async () => {
1069
934
  await withMemoryServer(async (server) => {
1070
935
  const handleToolCall = getHandleToolCall(server);
936
+ const directMessage = {
937
+ msgId: "dm-trigger-cleanup",
938
+ senderId: "agent-trigger",
939
+ senderName: "Trigger Agent",
940
+ content: "trigger cleanup notice",
941
+ requireReply: false,
942
+ timestamp: new Date().toISOString(),
943
+ };
1071
944
  Reflect.set(server, "agentClient", {
1072
945
  fetchUnreadMessages: async () => ({
1073
946
  directMessages: [],
@@ -1078,21 +951,29 @@ describe("McpServer memory tools", () => {
1078
951
  });
1079
952
  for (let index = 0; index < 33; index += 1) {
1080
953
  await handleToolCall.call(server, "create_memory", {
1081
- memory_type: "recently_memory",
954
+ memory_type: "agent_memory",
1082
955
  uri: `recent://cleanup/${index}`,
1083
956
  content: `recent ${index}`,
1084
957
  });
1085
958
  }
959
+ // poll_message blocks until a real message arrives; cleanup notice is prepended.
960
+ const buffer = Reflect.get(server, "messageBuffer");
961
+ setTimeout(() => {
962
+ buffer.push(directMessage);
963
+ }, 50);
1086
964
  const result = (await handleToolCall.call(server, "poll_message", {}));
1087
965
  assert.equal(result.groupMessages.length, 0);
1088
- assert.equal(result.directMessages.length, 1);
966
+ // cleanup notice prepended before the real message
967
+ assert.equal(result.directMessages.length, 2);
1089
968
  assert.match(result.directMessages[0]?.msgId, /^memory-cleanup-/);
1090
969
  assert.equal(result.directMessages[0]?.senderId, "MCP-System");
1091
970
  assert.equal(result.directMessages[0]?.receiverId, "agent-self");
1092
971
  assert.match(result.directMessages[0]?.content ?? "", /本地 memory 已超过建议容量/);
1093
- assert.match(result.directMessages[0]?.content ?? "", /recently_memory\/recent 类型下当前 33 条 memory/);
972
+ assert.match(result.directMessages[0]?.content ?? "", /agent_memory\/recent 类型下当前 33 条 memory/);
1094
973
  assert.match(result.directMessages[0]?.content ?? "", /get_memory_stats/);
1095
974
  assert.match(result.directMessages[0]?.prompt ?? "", /无需持久化/);
975
+ // real message follows the cleanup notice
976
+ assert.equal(result.directMessages[1]?.msgId, directMessage.msgId);
1096
977
  });
1097
978
  });
1098
979
  it("poll_message should claim backend tasks before returning a cleanup notice", async () => {
@@ -1121,7 +1002,7 @@ describe("McpServer memory tools", () => {
1121
1002
  });
1122
1003
  for (let index = 0; index < 33; index += 1) {
1123
1004
  await handleToolCall.call(server, "create_memory", {
1124
- memory_type: "recently_memory",
1005
+ memory_type: "agent_memory",
1125
1006
  uri: `recent://cleanup-claim/${index}`,
1126
1007
  content: `recent ${index}`,
1127
1008
  });
@@ -1149,7 +1030,7 @@ describe("McpServer memory tools", () => {
1149
1030
  });
1150
1031
  for (let index = 0; index < 33; index += 1) {
1151
1032
  await handleToolCall.call(server, "create_memory", {
1152
- memory_type: "recently_memory",
1033
+ memory_type: "agent_memory",
1153
1034
  uri: `recent://cleanup-get/${index}`,
1154
1035
  content: `recent ${index}`,
1155
1036
  });
@@ -1162,7 +1043,7 @@ describe("McpServer memory tools", () => {
1162
1043
  assert.equal(result.directMessages[0]?.senderId, "MCP-System");
1163
1044
  assert.equal(result.directMessages[0]?.receiverId, "agent-self");
1164
1045
  assert.match(result.directMessages[0]?.content ?? "", /本地 memory 已超过建议容量/);
1165
- assert.match(result.directMessages[0]?.content ?? "", /recently_memory\/recent 类型下当前 33 条 memory/);
1046
+ assert.match(result.directMessages[0]?.content ?? "", /agent_memory\/recent 类型下当前 33 条 memory/);
1166
1047
  assert.match(result.directMessages[0]?.prompt ?? "", /无需持久化/);
1167
1048
  });
1168
1049
  });
@@ -1170,7 +1051,7 @@ describe("McpServer memory tools", () => {
1170
1051
  await withMemoryServer(async (server) => {
1171
1052
  const handleToolCall = getHandleToolCall(server);
1172
1053
  await handleToolCall.call(server, "create_memory", {
1173
- memory_type: "memory",
1054
+ memory_type: "project_memory",
1174
1055
  uri: "core://agent/incomplete-update",
1175
1056
  content: "original",
1176
1057
  });
@@ -1196,7 +1077,7 @@ describe("McpServer memory tools", () => {
1196
1077
  });
1197
1078
  const handleToolCall = getHandleToolCall(server);
1198
1079
  await handleToolCall.call(server, "create_memory", {
1199
- memory_type: "memory",
1080
+ memory_type: "project_memory",
1200
1081
  uri: "core://agent/private",
1201
1082
  content: "secret local memory content",
1202
1083
  });
@@ -1212,7 +1093,7 @@ describe("McpServer memory tools", () => {
1212
1093
  });
1213
1094
  assert.deepEqual(reported[0], {
1214
1095
  name: "create_memory",
1215
- args: { uri: "core://agent/private", memory_type: "memory" },
1096
+ args: { uri: "core://agent/private", memory_type: "project_memory" },
1216
1097
  });
1217
1098
  assert.deepEqual(reported[1], {
1218
1099
  name: "update_memory",
@@ -1268,12 +1149,12 @@ describe("McpServer memory tools", () => {
1268
1149
  await withMemoryServer(async (server) => {
1269
1150
  const handleToolCall = getHandleToolCall(server);
1270
1151
  await handleToolCall.call(server, "create_memory", {
1271
- memory_type: "memory",
1152
+ memory_type: "project_memory",
1272
1153
  uri: "core://agent/duplicate",
1273
1154
  content: "first",
1274
1155
  });
1275
1156
  await assert.rejects(() => handleToolCall.call(server, "create_memory", {
1276
- memory_type: "memory",
1157
+ memory_type: "project_memory",
1277
1158
  uri: "core://agent/duplicate",
1278
1159
  content: "second",
1279
1160
  }), /Memory already exists/);
@@ -1287,7 +1168,7 @@ describe("McpServer memory tools", () => {
1287
1168
  await withMemoryServer(async (server) => {
1288
1169
  const handleToolCall = getHandleToolCall(server);
1289
1170
  await handleToolCall.call(server, "create_memory", {
1290
- memory_type: "memory",
1171
+ memory_type: "project_memory",
1291
1172
  uri: "core://agent/noop",
1292
1173
  content: "original",
1293
1174
  });
@@ -1301,7 +1182,7 @@ describe("McpServer memory tools", () => {
1301
1182
  await withMemoryServer(async (server) => {
1302
1183
  const handleToolCall = getHandleToolCall(server);
1303
1184
  await assert.rejects(() => handleToolCall.call(server, "create_memory", {
1304
- memory_type: "memory",
1185
+ memory_type: "project_memory",
1305
1186
  uri: "core://agent/missing-bound-file",
1306
1187
  content: "memory with non-existent bound file",
1307
1188
  bound_files: ["./non-existent-file.ts"],
@@ -1312,13 +1193,13 @@ describe("McpServer memory tools", () => {
1312
1193
  await withMemoryServer(async (server) => {
1313
1194
  const handleToolCall = getHandleToolCall(server);
1314
1195
  await handleToolCall.call(server, "create_memory", {
1315
- memory_type: "memory",
1196
+ memory_type: "project_memory",
1316
1197
  uri: "core://agent/update-with-missing-bound-file",
1317
1198
  content: "original content",
1318
1199
  });
1319
1200
  await assert.rejects(() => handleToolCall.call(server, "update_memory", {
1320
1201
  uri: "core://agent/update-with-missing-bound-file",
1321
- memory_type: "memory",
1202
+ memory_type: "project_memory",
1322
1203
  old_string: "original",
1323
1204
  new_string: "updated",
1324
1205
  bound_files: ["./non-existent-file.ts"],
@@ -1335,7 +1216,7 @@ describe("McpServer memory tools", () => {
1335
1216
  await withMemoryServer(async (server) => {
1336
1217
  const handleToolCall = getHandleToolCall(server);
1337
1218
  const created = await handleToolCall.call(server, "create_memory", {
1338
- memory_type: "memory",
1219
+ memory_type: "project_memory",
1339
1220
  uri: "core://agent/valid-bound-file",
1340
1221
  content: "memory with valid bound file",
1341
1222
  bound_files: ["./existing-file.ts"],
@@ -1364,7 +1245,7 @@ describe("McpServer memory tools", () => {
1364
1245
  await withMemoryServer(async (server) => {
1365
1246
  const handleToolCall = getHandleToolCall(server);
1366
1247
  await assert.rejects(() => handleToolCall.call(server, "create_memory", {
1367
- memory_type: "memory",
1248
+ memory_type: "project_memory",
1368
1249
  uri: "core://agent/mixed-bound-file",
1369
1250
  content: "memory with mixed bound files",
1370
1251
  bound_files: ["./existing-file.ts", "./non-existent-file.ts"],
@@ -1385,14 +1266,14 @@ describe("McpServer memory tools", () => {
1385
1266
  await withMemoryServer(async (server) => {
1386
1267
  const handleToolCall = getHandleToolCall(server);
1387
1268
  await handleToolCall.call(server, "create_memory", {
1388
- memory_type: "memory",
1269
+ memory_type: "project_memory",
1389
1270
  uri: "core://agent/update-without-bound-files",
1390
1271
  content: "original content",
1391
1272
  });
1392
1273
  // Update without bound_files should succeed even if existing bound files are invalid
1393
1274
  const updated = await handleToolCall.call(server, "update_memory", {
1394
1275
  uri: "core://agent/update-without-bound-files",
1395
- memory_type: "memory",
1276
+ memory_type: "project_memory",
1396
1277
  old_string: "original",
1397
1278
  new_string: "updated",
1398
1279
  });
@@ -1882,4 +1763,141 @@ describe("AgentClient group room aggregation", () => {
1882
1763
  assert.equal(result.count, 2);
1883
1764
  });
1884
1765
  });
1766
+ describe("McpServer todo reminder on poll_message", () => {
1767
+ // 使用唯一 agentId 避免污染开发者真实 todo 文件;每次测试写入并清理
1768
+ const testAgentId = `test-todo-reminder-${process.pid}-${Date.now()}`;
1769
+ const todoDir = path.join(os.homedir(), ".acode", "todos");
1770
+ const todoPath = path.join(todoDir, `${testAgentId}.json`);
1771
+ async function writeTodoFile(todos) {
1772
+ await mkdir(todoDir, { recursive: true });
1773
+ await writeFile(todoPath, JSON.stringify({
1774
+ agentId: testAgentId,
1775
+ updatedAt: new Date().toISOString(),
1776
+ background: "test background",
1777
+ todos,
1778
+ }), "utf-8");
1779
+ }
1780
+ async function cleanupTodoFile() {
1781
+ try {
1782
+ await rm(todoPath, { force: true });
1783
+ }
1784
+ catch {
1785
+ // 忽略清理失败
1786
+ }
1787
+ }
1788
+ function createServerForTodo() {
1789
+ return createServerWithUnread({ directMessages: [], groupMessages: [] }, {
1790
+ getState: () => ({ agentId: testAgentId }),
1791
+ });
1792
+ }
1793
+ function makeDirectMessage(msgId) {
1794
+ return {
1795
+ msgId,
1796
+ senderId: "agent-wake",
1797
+ senderName: "Wake Agent",
1798
+ content: `wake message ${msgId}`,
1799
+ requireReply: false,
1800
+ timestamp: new Date().toISOString(),
1801
+ };
1802
+ }
1803
+ it("injects todo reminder when incomplete todos exist", async () => {
1804
+ await writeTodoFile([
1805
+ { content: "任务A", status: "pending", priority: "high" },
1806
+ { content: "任务B", status: "completed", priority: "low" },
1807
+ ]);
1808
+ try {
1809
+ const server = createServerForTodo();
1810
+ const handleToolCall = getHandleToolCall(server);
1811
+ const result = (await handleToolCall.call(server, "poll_message", {}));
1812
+ assert.equal(result.directMessages.length, 1);
1813
+ const notice = result.directMessages[0];
1814
+ assert.equal(notice.senderId, "MCP-System");
1815
+ assert.equal(notice.senderName, "系统");
1816
+ assert.match(notice.content, /Todo 列表存在 1 项未完成/);
1817
+ }
1818
+ finally {
1819
+ await cleanupTodoFile();
1820
+ }
1821
+ });
1822
+ it("does not inject todo reminder when all todos are completed", async () => {
1823
+ await writeTodoFile([
1824
+ { content: "任务A", status: "completed", priority: "high" },
1825
+ ]);
1826
+ try {
1827
+ const server = createServerForTodo();
1828
+ const buffer = Reflect.get(server, "messageBuffer");
1829
+ const wake = makeDirectMessage("wake-completed");
1830
+ setTimeout(() => buffer.push(wake), 50);
1831
+ const handleToolCall = getHandleToolCall(server);
1832
+ const result = (await handleToolCall.call(server, "poll_message", {}));
1833
+ // 全完成时不应注入 todo 通知,仅返回 push 的唤醒消息
1834
+ assert.equal(result.directMessages.length, 1);
1835
+ assert.equal(result.directMessages[0].msgId, "wake-completed");
1836
+ }
1837
+ finally {
1838
+ await cleanupTodoFile();
1839
+ }
1840
+ });
1841
+ it("does not repeat todo reminder when fingerprint unchanged", async () => {
1842
+ await writeTodoFile([
1843
+ { content: "任务A", status: "pending", priority: "high" },
1844
+ ]);
1845
+ try {
1846
+ const server = createServerForTodo();
1847
+ const handleToolCall = getHandleToolCall(server);
1848
+ // 第一次:应返回 todo 通知
1849
+ const result1 = (await handleToolCall.call(server, "poll_message", {}));
1850
+ assert.equal(result1.directMessages.length, 1);
1851
+ assert.match(result1.directMessages[0].content, /Todo 列表存在/);
1852
+ // 第二次:指纹未变,应进入阻塞等待。push 一条消息让 poll 返回
1853
+ const buffer = Reflect.get(server, "messageBuffer");
1854
+ const wake = makeDirectMessage("wake-unchanged");
1855
+ setTimeout(() => buffer.push(wake), 50);
1856
+ const result2 = (await handleToolCall.call(server, "poll_message", {}));
1857
+ // 第二次不应再注入 todo 通知,仅返回 push 的唤醒消息
1858
+ assert.equal(result2.directMessages.length, 1);
1859
+ assert.equal(result2.directMessages[0].msgId, "wake-unchanged");
1860
+ }
1861
+ finally {
1862
+ await cleanupTodoFile();
1863
+ }
1864
+ });
1865
+ it("re-injects todo reminder when todos change after being notified", async () => {
1866
+ await writeTodoFile([
1867
+ { content: "任务A", status: "pending", priority: "high" },
1868
+ ]);
1869
+ try {
1870
+ const server = createServerForTodo();
1871
+ const handleToolCall = getHandleToolCall(server);
1872
+ // 第一次:返回 todo 通知(1 项未完成)
1873
+ const result1 = (await handleToolCall.call(server, "poll_message", {}));
1874
+ assert.match(result1.directMessages[0].content, /Todo 列表存在 1 项未完成/);
1875
+ // 修改 todo:新增一项未完成(指纹变化)
1876
+ await writeTodoFile([
1877
+ { content: "任务A", status: "pending", priority: "high" },
1878
+ { content: "任务B", status: "in_progress", priority: "medium" },
1879
+ ]);
1880
+ // 第二次:指纹变化,应再次返回 todo 通知(2 项未完成)
1881
+ const result2 = (await handleToolCall.call(server, "poll_message", {}));
1882
+ assert.equal(result2.directMessages.length, 1);
1883
+ assert.match(result2.directMessages[0].content, /Todo 列表存在 2 项未完成/);
1884
+ }
1885
+ finally {
1886
+ await cleanupTodoFile();
1887
+ }
1888
+ });
1889
+ it("does not inject todo reminder when todo file is absent", async () => {
1890
+ // 确保文件不存在
1891
+ await cleanupTodoFile();
1892
+ const server = createServerForTodo();
1893
+ const buffer = Reflect.get(server, "messageBuffer");
1894
+ const wake = makeDirectMessage("wake-no-file");
1895
+ setTimeout(() => buffer.push(wake), 50);
1896
+ const handleToolCall = getHandleToolCall(server);
1897
+ const result = (await handleToolCall.call(server, "poll_message", {}));
1898
+ // 无 todo 文件不应注入通知,仅返回 push 的唤醒消息
1899
+ assert.equal(result.directMessages.length, 1);
1900
+ assert.equal(result.directMessages[0].msgId, "wake-no-file");
1901
+ });
1902
+ });
1885
1903
  //# sourceMappingURL=mcp-server.test.js.map