@vellumai/assistant 0.8.7-dev.202606052232.2ddc989 → 0.8.8

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 (262) hide show
  1. package/bun.lock +2 -2
  2. package/docs/plugins.md +832 -0
  3. package/examples/plugins/echo/README.md +60 -61
  4. package/examples/plugins/echo/package.json +2 -1
  5. package/examples/plugins/echo/register.ts +143 -0
  6. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -7
  7. package/openapi.yaml +5 -15
  8. package/package.json +2 -2
  9. package/src/__tests__/agent-loop-exit-reason.test.ts +56 -3
  10. package/src/__tests__/anthropic-provider.test.ts +1 -1
  11. package/src/__tests__/app-control-flow.test.ts +1 -1
  12. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  13. package/src/__tests__/approval-routes-http.test.ts +1 -4
  14. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  15. package/src/__tests__/channel-approvals.test.ts +1 -1
  16. package/src/__tests__/circuit-breaker-pipeline.test.ts +405 -0
  17. package/src/__tests__/compaction-pipeline.test.ts +210 -0
  18. package/src/__tests__/compaction-timeout-recovery.test.ts +251 -0
  19. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
  20. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
  21. package/src/__tests__/conversation-agent-loop-overflow.test.ts +7 -3
  22. package/src/__tests__/conversation-agent-loop.test.ts +39 -42
  23. package/src/__tests__/conversation-clean-command.test.ts +2 -5
  24. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -4
  25. package/src/__tests__/conversation-runtime-assembly.test.ts +71 -140
  26. package/src/__tests__/conversation-runtime-workspace.test.ts +27 -108
  27. package/src/__tests__/conversation-starter-routes.test.ts +6 -14
  28. package/src/__tests__/conversation-workspace-cache-state.test.ts +16 -17
  29. package/src/__tests__/conversation-workspace-injection.test.ts +1 -61
  30. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -7
  31. package/src/__tests__/db-acp-history.test.ts +0 -101
  32. package/src/__tests__/dynamic-page-surface.test.ts +0 -31
  33. package/src/__tests__/file-write-tool.test.ts +0 -63
  34. package/src/__tests__/gateway-only-guard.test.ts +2 -12
  35. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  36. package/src/__tests__/guardian-routing-invariants.test.ts +4 -2
  37. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  38. package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -1
  39. package/src/__tests__/heartbeat-service.test.ts +0 -1
  40. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  41. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  42. package/src/__tests__/injector-background-turn.test.ts +1 -1
  43. package/src/__tests__/injector-chain.test.ts +6 -34
  44. package/src/__tests__/injector-disk-pressure.test.ts +34 -77
  45. package/src/__tests__/injector-document-comments.test.ts +1 -1
  46. package/src/__tests__/list-messages-hidden-metadata.test.ts +0 -38
  47. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  48. package/src/__tests__/{overflow-reduction-loop.test.ts → overflow-reduce-pipeline.test.ts} +284 -64
  49. package/src/__tests__/pipeline-runner.test.ts +554 -0
  50. package/src/__tests__/plugin-api-shim.test.ts +6 -3
  51. package/src/__tests__/plugin-bootstrap.test.ts +23 -12
  52. package/src/__tests__/plugin-registry.test.ts +49 -3
  53. package/src/__tests__/plugin-types.test.ts +70 -0
  54. package/src/__tests__/reaction-persistence.test.ts +1 -1
  55. package/src/__tests__/send-endpoint-busy.test.ts +1 -4
  56. package/src/__tests__/skill-feature-flags-integration.test.ts +0 -33
  57. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  58. package/src/__tests__/subagent-fork-notifications.test.ts +3 -1
  59. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  60. package/src/__tests__/subagent-manager-notify.test.ts +3 -1
  61. package/src/__tests__/subagent-notify-parent.test.ts +3 -1
  62. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  63. package/src/__tests__/user-plugin-loader.test.ts +286 -54
  64. package/src/acp/__tests__/client-handler.test.ts +0 -40
  65. package/src/acp/__tests__/prepare-agent-env.test.ts +0 -137
  66. package/src/acp/__tests__/session-manager-persistence.test.ts +28 -95
  67. package/src/acp/agent-process.ts +1 -61
  68. package/src/acp/client-handler.ts +0 -31
  69. package/src/acp/prepare-agent-env.ts +29 -83
  70. package/src/acp/resolve-agent.test.ts +7 -320
  71. package/src/acp/resolve-agent.ts +18 -182
  72. package/src/acp/session-manager.ts +73 -495
  73. package/src/acp/types.ts +0 -8
  74. package/src/agent/compaction-circuit.ts +102 -60
  75. package/src/agent/loop.ts +59 -32
  76. package/src/api/responses/conversation-message.ts +1 -7
  77. package/src/approvals/guardian-request-resolvers.ts +1 -1
  78. package/src/background-wake/next-wake.ts +0 -1
  79. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  80. package/src/config/acp-defaults.test.ts +0 -10
  81. package/src/config/acp-defaults.ts +0 -6
  82. package/src/config/bundled-skills/acp/SKILL.md +31 -83
  83. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  84. package/src/config/bundled-skills/app-builder/SKILL.md +381 -224
  85. package/src/config/bundled-skills/app-builder/TOOLS.json +0 -29
  86. package/src/config/bundled-skills/document-editor/SKILL.md +23 -28
  87. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  88. package/src/config/bundled-tool-registry.ts +0 -2
  89. package/src/config/feature-flag-registry.json +5 -14
  90. package/src/config/schemas/heartbeat.ts +0 -9
  91. package/src/context/strip-injections.ts +2 -8
  92. package/src/context/window-manager.ts +1 -2
  93. package/src/daemon/conversation-agent-loop-handlers.ts +11 -0
  94. package/src/daemon/conversation-agent-loop.ts +279 -62
  95. package/src/daemon/conversation-runtime-assembly.ts +69 -106
  96. package/src/daemon/conversation-store.ts +90 -9
  97. package/src/daemon/conversation-workspace.ts +0 -17
  98. package/src/daemon/conversation.ts +6 -0
  99. package/src/daemon/external-plugins-bootstrap.ts +11 -11
  100. package/src/daemon/handlers/conversations.ts +1 -3
  101. package/src/daemon/handlers/skills.ts +1 -4
  102. package/src/daemon/lifecycle.ts +0 -21
  103. package/src/daemon/server.ts +0 -2
  104. package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -3
  105. package/src/heartbeat/heartbeat-run-store.ts +1 -23
  106. package/src/heartbeat/heartbeat-service.ts +0 -26
  107. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  108. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  109. package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -15
  110. package/src/ipc/skill-routes/memory.ts +2 -4
  111. package/src/memory/conversation-starter-checkpoints.ts +0 -1
  112. package/src/memory/db-init.ts +0 -2
  113. package/src/memory/job-handlers/conversation-starters.ts +2 -13
  114. package/src/memory/jobs-worker.ts +1 -1
  115. package/src/memory/migrations/index.ts +0 -1
  116. package/src/memory/schema/acp.ts +0 -4
  117. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  118. package/src/memory/v2/consolidation-job.ts +4 -13
  119. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/assign.test.ts +4 -4
  120. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/live-integration.test.ts +4 -4
  121. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/maintain-job.test.ts +5 -5
  122. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/orchestrate.test.ts +3 -3
  123. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/reconcile.test.ts +2 -2
  124. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/render-injection.test.ts +1 -1
  125. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/router.test.ts +3 -3
  126. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selection-log-store.test.ts +8 -8
  127. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selector.test.ts +3 -3
  128. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/shadow-plugin.test.ts +12 -12
  129. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/assign.ts +5 -5
  130. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/capabilities.ts +2 -2
  131. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/maintain-job.ts +8 -8
  132. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/page-content.ts +2 -2
  133. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/provider-blocks.ts +1 -1
  134. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/reconcile.ts +3 -3
  135. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/render-injection.ts +1 -1
  136. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/router.ts +3 -3
  137. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selection-log-store.ts +4 -4
  138. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selector.ts +4 -4
  139. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/shadow-plugin.ts +90 -28
  140. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/tree.ts +1 -1
  141. package/src/plugin-api/index.ts +5 -0
  142. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
  143. package/src/plugins/defaults/{memory-v3-shadow → circuit-breaker}/package.json +2 -2
  144. package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
  145. package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
  146. package/src/plugins/defaults/compaction/package.json +1 -1
  147. package/src/plugins/defaults/compaction/register.ts +19 -8
  148. package/src/plugins/defaults/compaction/terminal.ts +73 -0
  149. package/src/plugins/defaults/index.ts +5 -3
  150. package/src/plugins/defaults/{memory-retrieval/injectors.ts → injectors/register.ts} +7 -45
  151. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +7 -11
  152. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  153. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +126 -0
  154. package/src/plugins/defaults/overflow-reduce/package.json +15 -0
  155. package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
  156. package/src/plugins/external-api.ts +2 -2
  157. package/src/plugins/pipeline.ts +293 -6
  158. package/src/plugins/registry.ts +37 -9
  159. package/src/plugins/types.ts +336 -32
  160. package/src/plugins/user-loader.ts +127 -30
  161. package/src/proactive-artifact/aux-message-injector.ts +1 -1
  162. package/src/proactive-artifact/job.test.ts +1 -1
  163. package/src/prompts/__tests__/system-prompt.test.ts +0 -6
  164. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +2 -4
  165. package/src/runtime/__tests__/agent-wake.test.ts +5 -5
  166. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  167. package/src/runtime/agent-wake.ts +3 -0
  168. package/src/runtime/assistant-event-hub.ts +1 -1
  169. package/src/runtime/channel-approvals.ts +1 -1
  170. package/src/runtime/interactive-ui.ts +1 -1
  171. package/src/runtime/routes/__tests__/acp-routes.test.ts +55 -283
  172. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  173. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +4 -5
  174. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -4
  175. package/src/runtime/routes/acp-routes.test.ts +25 -89
  176. package/src/runtime/routes/acp-routes.ts +29 -81
  177. package/src/runtime/routes/approval-routes.ts +1 -1
  178. package/src/runtime/routes/browser-routes.ts +1 -1
  179. package/src/runtime/routes/browser-tabs-routes.ts +10 -6
  180. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  181. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  182. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  183. package/src/runtime/routes/conversation-routes.ts +2 -15
  184. package/src/runtime/routes/conversation-starter-routes.ts +7 -13
  185. package/src/runtime/routes/conversations-import-routes.ts +7 -24
  186. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  187. package/src/runtime/routes/host-cu-routes.ts +1 -1
  188. package/src/runtime/routes/identity-routes.ts +3 -18
  189. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  190. package/src/runtime/routes/memory-v3-routes.ts +6 -16
  191. package/src/runtime/routes/playground/helpers.ts +1 -1
  192. package/src/runtime/routes/surface-conversation-resolver.ts +3 -4
  193. package/src/runtime/routes/work-items-routes.ts +4 -2
  194. package/src/runtime/services/conversation-serializer.ts +1 -1
  195. package/src/signals/cancel.ts +4 -2
  196. package/src/subagent/manager.ts +5 -17
  197. package/src/tools/acp/list-agents.test.ts +1 -7
  198. package/src/tools/acp/spawn.test.ts +55 -158
  199. package/src/tools/acp/spawn.ts +72 -47
  200. package/src/tools/acp/steer.test.ts +8 -105
  201. package/src/tools/acp/steer.ts +17 -48
  202. package/src/tools/apps/executors.ts +8 -13
  203. package/src/tools/filesystem/write.ts +0 -34
  204. package/src/tools/subagent/spawn.ts +4 -2
  205. package/src/tools/ui-surface/definitions.ts +4 -25
  206. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +5 -4
  207. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +45 -69
  208. package/examples/plugins/echo/hooks/post-tool-use.ts +0 -18
  209. package/examples/plugins/echo/hooks/stop.ts +0 -16
  210. package/examples/plugins/echo/hooks/user-prompt-submit.ts +0 -18
  211. package/examples/plugins/echo/src/emit.ts +0 -19
  212. package/src/__tests__/compaction-circuit.test.ts +0 -258
  213. package/src/__tests__/compaction-direct.test.ts +0 -132
  214. package/src/__tests__/conversations-import-system-filter.test.ts +0 -101
  215. package/src/acp/__tests__/agent-process.test.ts +0 -161
  216. package/src/acp/__tests__/helpers/acp-history-db.ts +0 -82
  217. package/src/acp/__tests__/helpers/exec-file-stub.ts +0 -101
  218. package/src/acp/__tests__/session-manager-resume.test.ts +0 -736
  219. package/src/acp/auto-install.test.ts +0 -196
  220. package/src/acp/auto-install.ts +0 -177
  221. package/src/acp/feature-gate.test.ts +0 -48
  222. package/src/acp/feature-gate.ts +0 -34
  223. package/src/acp/resume-hint.ts +0 -25
  224. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +0 -48
  225. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +0 -57
  226. package/src/config/bundled-skills/app-builder/references/SLIDES.md +0 -38
  227. package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -62
  228. package/src/daemon/conversation-registry.ts +0 -159
  229. package/src/daemon/overflow-reduction-loop.ts +0 -230
  230. package/src/memory/migrations/272-acp-session-history-cwd.ts +0 -36
  231. package/src/plugins/defaults/compaction/compact.ts +0 -59
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +0 -14
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +0 -19
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +0 -75
  235. package/src/plugins/defaults/memory-v3-shadow/register.ts +0 -26
  236. package/src/tools/acp/context.ts +0 -20
  237. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/capabilities.test.ts +0 -0
  238. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/core.test.ts +0 -0
  239. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/eval-turns.json +0 -0
  240. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/live-turns.json +0 -0
  241. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/health.test.ts +0 -0
  242. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/needle.test.ts +0 -0
  243. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/provider-blocks.test.ts +0 -0
  244. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/snapshot.test.ts +0 -0
  245. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/tree.test.ts +0 -0
  246. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/types.test.ts +0 -0
  247. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-eviction.test.ts +0 -0
  248. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-skeleton.test.ts +0 -0
  249. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/core.ts +0 -0
  250. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/README.md +0 -0
  251. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/assignments.json +0 -0
  252. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/core.json +0 -0
  253. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-x.md +0 -0
  254. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-y.md +0 -0
  255. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-b/topic-z.md +0 -0
  256. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/health.ts +0 -0
  257. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/llm-retry.ts +0 -0
  258. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/needle.ts +0 -0
  259. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/orchestrate.ts +0 -0
  260. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/snapshot.ts +0 -0
  261. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/types.ts +0 -0
  262. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/working-set.ts +0 -0
@@ -25,7 +25,6 @@ import { stripCommentLines } from "../util/strip-comment-lines.js";
25
25
  import {
26
26
  completeHeartbeatRun,
27
27
  countCompletedHeartbeatRuns,
28
- countCompletedRunsToday,
29
28
  countRecentConsecutiveRuns,
30
29
  insertPendingHeartbeatRun,
31
30
  markStaleRunningAsError,
@@ -188,13 +187,6 @@ export class HeartbeatService {
188
187
  );
189
188
  }
190
189
 
191
- /** Whether the daily run cap has been reached. */
192
- get isDailyCapReached(): boolean {
193
- const config = getConfig().heartbeat;
194
- if (config.maxDailyRuns == null) return false;
195
- return countCompletedRunsToday() >= config.maxDailyRuns;
196
- }
197
-
198
190
  async runManagedWakeIfDue(
199
191
  options: ManagedWakeHeartbeatRunOptions = {},
200
192
  ): Promise<ManagedWakeHeartbeatRunResult> {
@@ -559,24 +551,6 @@ export class HeartbeatService {
559
551
  return false;
560
552
  }
561
553
 
562
- // Daily run cap — stop burning tokens when the daily budget is exhausted.
563
- // Force runs bypass the cap.
564
- if (
565
- !force &&
566
- config.maxDailyRuns != null &&
567
- countCompletedRunsToday() >= config.maxDailyRuns
568
- ) {
569
- log.debug(
570
- { maxDailyRuns: config.maxDailyRuns },
571
- "Daily run cap reached, skipping",
572
- );
573
- if (runId) skipHeartbeatRun(runId, "max_daily_runs");
574
- if (!this.cronMode) {
575
- this.scheduleNextRun(config.intervalMs);
576
- }
577
- return false;
578
- }
579
-
580
554
  // Overlap prevention
581
555
  if (this.activeRun) {
582
556
  log.debug("Previous heartbeat run still active, skipping");
@@ -55,7 +55,7 @@ mock.module("../../browser/operations.js", () => ({
55
55
  },
56
56
  }));
57
57
 
58
- mock.module("../../daemon/conversation-registry.js", () => ({
58
+ mock.module("../../daemon/conversation-store.js", () => ({
59
59
  findConversation: (conversationId: string) => {
60
60
  mockFindConversationCalls.push(conversationId);
61
61
  return mockConversation ?? undefined;
@@ -32,9 +32,9 @@ let mockSurfaceResult: InteractiveUiResult = {
32
32
  let mockSurfaceThrows: Error | null = null;
33
33
 
34
34
  // Re-export the real module and override only findConversation.
35
- const realRegistry = await import("../../daemon/conversation-registry.js");
36
- mock.module("../../daemon/conversation-registry.js", () => ({
37
- ...realRegistry,
35
+ const realStore = await import("../../daemon/conversation-store.js");
36
+ mock.module("../../daemon/conversation-store.js", () => ({
37
+ ...realStore,
38
38
  findConversation: (_conversationId: string) => mockConversation ?? undefined,
39
39
  }));
40
40
 
@@ -137,21 +137,6 @@ describe("host.memory.addMessage", () => {
137
137
  }),
138
138
  ).rejects.toThrow();
139
139
  });
140
-
141
- test("rejects the non-renderable system role", async () => {
142
- // GIVEN the messages store is UI-facing (ConversationMessage), so only
143
- // renderable turns may be persisted via this facet
144
- // WHEN a skill attempts to add a system row
145
- // THEN the route rejects it instead of persisting agent-context scaffolding
146
- await expect(
147
- memoryAddMessageRoute.handler({
148
- conversationId: "c",
149
- role: "system",
150
- content: "agent-context scaffolding",
151
- }),
152
- ).rejects.toThrow();
153
- expect(addMessageSpy).not.toHaveBeenCalled();
154
- });
155
140
  });
156
141
 
157
142
  describe("host.memory.wakeAgentForOpportunity", () => {
@@ -17,9 +17,7 @@ import type { SkillIpcRoute } from "../skill-ipc-types.js";
17
17
 
18
18
  /**
19
19
  * IPC params for `addMessage()`. `role` is constrained to the
20
- * renderable conversation roles (`user`/`assistant`): the messages store
21
- * is UI-facing (`ConversationMessage`), so agent-context `system` rows are
22
- * not accepted here. `metadata` is a free-form record (validated
20
+ * `MessageRole` union. `metadata` is a free-form record (validated
23
21
  * downstream by `messageMetadataSchema` with a warn-and-store fallback).
24
22
  * `skipIndexing` and `clientMessageId` mirror `AddMessageOptions`.
25
23
  *
@@ -30,7 +28,7 @@ import type { SkillIpcRoute } from "../skill-ipc-types.js";
30
28
  */
31
29
  const MemoryAddMessageParams = z.object({
32
30
  conversationId: z.string().min(1),
33
- role: z.enum(["user", "assistant"]),
31
+ role: z.enum(["user", "assistant", "system"]),
34
32
  content: z.string(),
35
33
  metadata: z.record(z.string(), z.unknown()).optional(),
36
34
  skipIndexing: z.boolean().optional(),
@@ -15,7 +15,6 @@ import { memoryCheckpoints } from "./schema.js";
15
15
  export const CK_ITEM_COUNT = "conversation_starters:item_count_at_last_gen";
16
16
  export const CK_BATCH = "conversation_starters:generation_batch";
17
17
  export const CK_LAST_GEN_AT = "conversation_starters:last_gen_at";
18
- export const CK_LAST_ATTEMPT_AT = "conversation_starters:last_attempt_at";
19
18
 
20
19
  export function checkpointKey(base: string, scopeId: string): string {
21
20
  return `${base}:${scopeId}`;
@@ -41,7 +41,6 @@ import {
41
41
  migrate230AcpSessionHistory,
42
42
  migrate231RepairMemoryGraphEventDates,
43
43
  migrateA2ATasks,
44
- migrateAcpSessionHistoryCwd,
45
44
  migrateActivationState,
46
45
  migrateActivationStateFkCascade,
47
46
  migrateAddConversationInferenceProfile,
@@ -479,7 +478,6 @@ export function initializeDb(): void {
479
478
  migrateScheduleSourceConversation,
480
479
  migrateMessagesRoleCreatedAtIndex,
481
480
  createAuthFallbackEventsTable,
482
- migrateAcpSessionHistoryCwd,
483
481
  ];
484
482
 
485
483
  // Run each migration step, catching and logging individual failures so one
@@ -22,7 +22,6 @@ import {
22
22
  checkpointKey,
23
23
  CK_BATCH,
24
24
  CK_ITEM_COUNT,
25
- CK_LAST_ATTEMPT_AT,
26
25
  CK_LAST_GEN_AT,
27
26
  countActiveMemoryNodes,
28
27
  getCheckpointValue,
@@ -337,7 +336,6 @@ Bad → Good (incomplete phrase → complete):
337
336
  config: {
338
337
  callSite: "conversationStarters" as const,
339
338
  max_tokens: 2048,
340
- temperature: 0.7,
341
339
  tool_choice: {
342
340
  type: "tool" as const,
343
341
  name: "store_conversation_starters",
@@ -397,27 +395,18 @@ export async function generateConversationStartersJob(
397
395
  const db = getDb();
398
396
  const now = Date.now();
399
397
 
400
- // Record attempt time so the route handler's cooldown prevents rapid retries
401
- // even when generation produces 0 valid starters.
402
- upsertCheckpoint(
403
- checkpointKey(CK_LAST_ATTEMPT_AT, scopeId),
404
- String(now),
405
- now,
406
- );
407
-
408
398
  const starters = await generateStarters(scopeId);
409
399
  if (starters.length === 0) {
410
400
  log.info({ scopeId }, "No conversation starters generated");
411
401
 
412
- // Sync the item count checkpoint so `checkpointAhead` clears, but do NOT
413
- // update `CK_LAST_GEN_AT` — the stale TTL should trigger a retry on the
414
- // next GET rather than blocking retries for the full TTL window.
402
+ // Sync checkpoints so both `staleByAge` and `checkpointAhead` clear.
415
403
  const totalActive = countActiveMemoryNodes(scopeId);
416
404
  upsertCheckpoint(
417
405
  checkpointKey(CK_ITEM_COUNT, scopeId),
418
406
  String(totalActive),
419
407
  now,
420
408
  );
409
+ upsertCheckpoint(checkpointKey(CK_LAST_GEN_AT, scopeId), String(now), now);
421
410
  return;
422
411
  }
423
412
 
@@ -8,7 +8,6 @@ import {
8
8
  diskPressureBackgroundSkipLogFields,
9
9
  shouldLogDiskPressureBackgroundSkip,
10
10
  } from "../daemon/disk-pressure-background-gate.js";
11
- import { maintainJob as memoryV3MaintainJob } from "../plugins/defaults/memory-v3-shadow/maintain-job.js";
12
11
  import { getLogger } from "../util/logger.js";
13
12
  import { getWorkspaceDir } from "../util/platform.js";
14
13
  import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
@@ -88,6 +87,7 @@ import {
88
87
  memoryV2ConsolidateJob,
89
88
  } from "./v2/consolidation-job.js";
90
89
  import { memoryV2SweepJob } from "./v2/sweep-job.js";
90
+ import { maintainJob as memoryV3MaintainJob } from "./v3/maintain-job.js";
91
91
 
92
92
  const log = getLogger("memory-jobs-worker");
93
93
 
@@ -259,7 +259,6 @@ export { migrateScheduleScriptTimeout } from "./269-schedule-script-timeout.js";
259
259
  export { migrateMessagesRoleCreatedAtIndex } from "./270-messages-role-created-at-index.js";
260
260
  export { migrateScheduleSourceConversation } from "./270-schedule-source-conversation.js";
261
261
  export { createAuthFallbackEventsTable } from "./271-create-auth-fallback-events.js";
262
- export { migrateAcpSessionHistoryCwd } from "./272-acp-session-history-cwd.js";
263
262
  export {
264
263
  MIGRATION_REGISTRY,
265
264
  type MigrationRegistryEntry,
@@ -20,10 +20,6 @@ export const acpSessionHistory = sqliteTable(
20
20
  stopReason: text("stop_reason"),
21
21
  error: text("error"),
22
22
  eventLogJson: text("event_log_json").notNull().default("[]"),
23
- // Working directory the agent process was spawned with. Required to
24
- // resume a persisted session; null for rows written before migration
25
- // 272 (those sessions are not resumable).
26
- cwd: text("cwd"),
27
23
  },
28
24
  (table) => [
29
25
  index("idx_acp_session_history_started_at").on(table.startedAt),
@@ -121,7 +121,7 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
121
121
 
122
122
  let renderedHealth = "";
123
123
  let computeThrows = false;
124
- mock.module("../../../plugins/defaults/memory-v3-shadow/health.js", () => ({
124
+ mock.module("../../v3/health.js", () => ({
125
125
  computeV3Health: () => {
126
126
  if (computeThrows) throw new Error("simulated health compute failure");
127
127
  return {};
@@ -129,12 +129,12 @@ mock.module("../../../plugins/defaults/memory-v3-shadow/health.js", () => ({
129
129
  renderV3Health: () => renderedHealth,
130
130
  }));
131
131
 
132
- mock.module("../../../plugins/defaults/memory-v3-shadow/tree.js", () => ({
132
+ mock.module("../../v3/tree.js", () => ({
133
133
  loadLeafTree: async () => ({ leaves: new Map(), byPage: new Map() }),
134
134
  resolveDataDir: () => "/tmp/v3-data-stub",
135
135
  }));
136
136
 
137
- mock.module("../../../plugins/defaults/memory-v3-shadow/core.js", () => ({
137
+ mock.module("../../v3/core.js", () => ({
138
138
  loadCore: async () => new Set<string>(),
139
139
  }));
140
140
 
@@ -63,19 +63,6 @@ import { dirname, join } from "node:path";
63
63
 
64
64
  import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
65
65
  import type { AssistantConfig } from "../../config/types.js";
66
- import { loadCore } from "../../plugins/defaults/memory-v3-shadow/core.js";
67
- import {
68
- computeV3Health,
69
- renderV3Health,
70
- } from "../../plugins/defaults/memory-v3-shadow/health.js";
71
- import {
72
- loadLeafTree,
73
- resolveDataDir,
74
- } from "../../plugins/defaults/memory-v3-shadow/tree.js";
75
- import type {
76
- LeafPath,
77
- Slug,
78
- } from "../../plugins/defaults/memory-v3-shadow/types.js";
79
66
  import { runBackgroundJob } from "../../runtime/background-job-runner.js";
80
67
  import { getLogger } from "../../util/logger.js";
81
68
  import { getWorkspaceDir } from "../../util/platform.js";
@@ -87,6 +74,10 @@ import {
87
74
  type MemoryJobType,
88
75
  } from "../jobs-store.js";
89
76
  import { getPageIndex } from "../v2/page-index.js";
77
+ import { loadCore } from "../v3/core.js";
78
+ import { computeV3Health, renderV3Health } from "../v3/health.js";
79
+ import { loadLeafTree, resolveDataDir } from "../v3/tree.js";
80
+ import type { LeafPath, Slug } from "../v3/types.js";
90
81
  import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./constants.js";
91
82
  import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
92
83
 
@@ -8,15 +8,15 @@ import { tmpdir } from "node:os";
8
8
  import { join } from "node:path";
9
9
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
10
10
 
11
- import { readPage, writePage } from "../../../../memory/v2/page-store.js";
12
- import type { ConceptPageFrontmatter } from "../../../../memory/v2/types.js";
13
11
  import type {
14
12
  Message,
15
13
  Provider,
16
14
  ProviderResponse,
17
15
  SendMessageOptions,
18
16
  ToolUseContent,
19
- } from "../../../../providers/types.js";
17
+ } from "../../../providers/types.js";
18
+ import { readPage, writePage } from "../../v2/page-store.js";
19
+ import type { ConceptPageFrontmatter } from "../../v2/types.js";
20
20
  import type { LeafNode, LeafTree } from "../types.js";
21
21
 
22
22
  // Stub the provider layer before importing `assign.js` so its static import
@@ -24,7 +24,7 @@ import type { LeafNode, LeafTree } from "../types.js";
24
24
  // aren't built in a fresh worktree) never loads. The classifier is
25
25
  // provider-injectable, so every test passes its own stub provider — the real
26
26
  // `getConfiguredProvider` is never exercised here.
27
- mock.module("../../../../providers/provider-send-message.js", () => ({
27
+ mock.module("../../../providers/provider-send-message.js", () => ({
28
28
  getConfiguredProvider: async () => null,
29
29
  extractToolUse: (response: ProviderResponse) =>
30
30
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
@@ -25,13 +25,13 @@
25
25
 
26
26
  import { beforeEach, describe, expect, mock, test } from "bun:test";
27
27
 
28
- import { stripAllMemoryInjections } from "../../../../memory/graph/conversation-graph-memory.js";
29
28
  import type {
30
29
  ContentBlock,
31
30
  Message,
32
31
  Provider,
33
32
  ProviderResponse,
34
- } from "../../../../providers/types.js";
33
+ } from "../../../providers/types.js";
34
+ import { stripAllMemoryInjections } from "../../graph/conversation-graph-memory.js";
35
35
  import type { NeedleIndex } from "../needle.js";
36
36
  import type {
37
37
  LeafNode,
@@ -49,13 +49,13 @@ import liveTurns from "./fixtures/live-turns.json" with { type: "json" };
49
49
 
50
50
  let providerStub: Provider | null = null;
51
51
 
52
- mock.module("../../../../providers/provider-send-message.js", () => ({
52
+ mock.module("../../../providers/provider-send-message.js", () => ({
53
53
  getConfiguredProvider: async () => providerStub,
54
54
  extractToolUse: (response: ProviderResponse) =>
55
55
  response.content.find((b) => b.type === "tool_use"),
56
56
  }));
57
57
 
58
- mock.module("../../../../util/logger.js", () => ({
58
+ mock.module("../../../util/logger.js", () => ({
59
59
  getLogger: () =>
60
60
  new Proxy({} as Record<string, unknown>, {
61
61
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -3,11 +3,11 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
5
5
 
6
- import { setOverridesForTesting } from "../../../../__tests__/feature-flag-test-helpers.js";
7
- import type { AssistantConfig } from "../../../../config/types.js";
8
- import type { MemoryJob } from "../../../../memory/jobs-store.js";
9
- import { readPage, writePage } from "../../../../memory/v2/page-store.js";
10
- import type { ConceptPage } from "../../../../memory/v2/types.js";
6
+ import { setOverridesForTesting } from "../../../__tests__/feature-flag-test-helpers.js";
7
+ import type { AssistantConfig } from "../../../config/types.js";
8
+ import type { MemoryJob } from "../../jobs-store.js";
9
+ import { readPage, writePage } from "../../v2/page-store.js";
10
+ import type { ConceptPage } from "../../v2/types.js";
11
11
  import type { AssignPageResult, AssignPagesOptions } from "../assign.js";
12
12
  import {
13
13
  type ClassifyCandidate,
@@ -17,7 +17,7 @@ import type {
17
17
  Message,
18
18
  Provider,
19
19
  ProviderResponse,
20
- } from "../../../../providers/types.js";
20
+ } from "../../../providers/types.js";
21
21
  import type { NeedleIndex } from "../needle.js";
22
22
  import type {
23
23
  LeafNode,
@@ -35,13 +35,13 @@ import evalTurns from "./fixtures/eval-turns.json" with { type: "json" };
35
35
 
36
36
  let providerStub: Provider | null = null;
37
37
 
38
- mock.module("../../../../providers/provider-send-message.js", () => ({
38
+ mock.module("../../../providers/provider-send-message.js", () => ({
39
39
  getConfiguredProvider: async () => providerStub,
40
40
  extractToolUse: (response: ProviderResponse) =>
41
41
  response.content.find((b) => b.type === "tool_use"),
42
42
  }));
43
43
 
44
- mock.module("../../../../util/logger.js", () => ({
44
+ mock.module("../../../util/logger.js", () => ({
45
45
  getLogger: () =>
46
46
  new Proxy({} as Record<string, unknown>, {
47
47
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -3,8 +3,8 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
5
5
 
6
- import { readPage, writePage } from "../../../../memory/v2/page-store.js";
7
- import type { Provider } from "../../../../providers/types.js";
6
+ import type { Provider } from "../../../providers/types.js";
7
+ import { readPage, writePage } from "../../v2/page-store.js";
8
8
  import { type LeafRef, reconcileTree } from "../reconcile.js";
9
9
 
10
10
  /**
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
- import { wrapMemoryBlock } from "../../../../memory/memory-marker.js";
3
+ import { wrapMemoryBlock } from "../../memory-marker.js";
4
4
  import { renderMemoryBlock } from "../render-injection.js";
5
5
  import { Slug } from "../types.js";
6
6
 
@@ -25,7 +25,7 @@ import type {
25
25
  ProviderResponse,
26
26
  SendMessageOptions,
27
27
  ToolUseContent,
28
- } from "../../../../providers/types.js";
28
+ } from "../../../providers/types.js";
29
29
  import type { LeafNode, LeafPath, LeafTree, TurnContext } from "../types.js";
30
30
 
31
31
  // ---------------------------------------------------------------------------
@@ -41,13 +41,13 @@ interface ProviderCall {
41
41
  }
42
42
  const providerCalls: ProviderCall[] = [];
43
43
 
44
- mock.module("../../../../providers/provider-send-message.js", () => ({
44
+ mock.module("../../../providers/provider-send-message.js", () => ({
45
45
  getConfiguredProvider: async () => providerStub,
46
46
  extractToolUse: (response: ProviderResponse) =>
47
47
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
48
48
  }));
49
49
 
50
- mock.module("../../../../util/logger.js", () => ({
50
+ mock.module("../../../util/logger.js", () => ({
51
51
  getLogger: () =>
52
52
  new Proxy({} as Record<string, unknown>, {
53
53
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -20,14 +20,14 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
20
20
 
21
21
  import { drizzle } from "drizzle-orm/bun-sqlite";
22
22
 
23
- import { migrateAddMemoryV3Selections } from "../../../../memory/migrations/268-add-memory-v3-selections.js";
24
- import * as schema from "../../../../memory/schema.js";
23
+ import { migrateAddMemoryV3Selections } from "../../migrations/268-add-memory-v3-selections.js";
24
+ import * as schema from "../../schema.js";
25
25
 
26
26
  const realFlags = {
27
- ...(await import("../../../../config/assistant-feature-flags.js")),
27
+ ...(await import("../../../config/assistant-feature-flags.js")),
28
28
  };
29
- const realLoader = { ...(await import("../../../../config/loader.js")) };
30
- const realDb = { ...(await import("../../../../memory/db-connection.js")) };
29
+ const realLoader = { ...(await import("../../../config/loader.js")) };
30
+ const realDb = { ...(await import("../../db-connection.js")) };
31
31
  const realPageContent = { ...(await import("../page-content.js")) };
32
32
 
33
33
  let storeMockActive = false;
@@ -64,7 +64,7 @@ function seed(
64
64
  }
65
65
  }
66
66
 
67
- mock.module("../../../../config/assistant-feature-flags.js", () => ({
67
+ mock.module("../../../config/assistant-feature-flags.js", () => ({
68
68
  ...realFlags,
69
69
  isAssistantFeatureFlagEnabled: (key: string, config: unknown) =>
70
70
  storeMockActive
@@ -81,12 +81,12 @@ mock.module("../../../../config/assistant-feature-flags.js", () => ({
81
81
  ),
82
82
  }));
83
83
 
84
- mock.module("../../../../config/loader.js", () => ({
84
+ mock.module("../../../config/loader.js", () => ({
85
85
  ...realLoader,
86
86
  getConfig: () => (storeMockActive ? {} : realLoader.getConfig()),
87
87
  }));
88
88
 
89
- mock.module("../../../../memory/db-connection.js", () => ({
89
+ mock.module("../../db-connection.js", () => ({
90
90
  ...realDb,
91
91
  getDb: () => (storeMockActive ? testDb : realDb.getDb()),
92
92
  getSqliteFrom: (db: unknown) =>
@@ -26,7 +26,7 @@ import type {
26
26
  ProviderResponse,
27
27
  SendMessageOptions,
28
28
  ToolUseContent,
29
- } from "../../../../providers/types.js";
29
+ } from "../../../providers/types.js";
30
30
  import type {
31
31
  LeafNode,
32
32
  LeafPath,
@@ -48,13 +48,13 @@ interface ProviderCall {
48
48
  }
49
49
  const providerCalls: ProviderCall[] = [];
50
50
 
51
- mock.module("../../../../providers/provider-send-message.js", () => ({
51
+ mock.module("../../../providers/provider-send-message.js", () => ({
52
52
  getConfiguredProvider: async () => providerStub,
53
53
  extractToolUse: (response: ProviderResponse) =>
54
54
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
55
55
  }));
56
56
 
57
- mock.module("../../../../util/logger.js", () => ({
57
+ mock.module("../../../util/logger.js", () => ({
58
58
  getLogger: () =>
59
59
  new Proxy({} as Record<string, unknown>, {
60
60
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -22,8 +22,8 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
22
22
 
23
23
  import { drizzle } from "drizzle-orm/bun-sqlite";
24
24
 
25
- import { migrateAddMemoryV3Selections } from "../../../../memory/migrations/268-add-memory-v3-selections.js";
26
- import * as schema from "../../../../memory/schema.js";
25
+ import { migrateAddMemoryV3Selections } from "../../migrations/268-add-memory-v3-selections.js";
26
+ import * as schema from "../../schema.js";
27
27
  import type { LeafTree, SelectionSource } from "../types.js";
28
28
 
29
29
  // `mock.module` is process-global and, in Bun, neither `mock.restore()` nor a
@@ -41,10 +41,10 @@ const realTree = { ...(await import("../tree.js")) };
41
41
  const realCore = { ...(await import("../core.js")) };
42
42
  const realNeedle = { ...(await import("../needle.js")) };
43
43
  const realOrchestrate = { ...(await import("../orchestrate.js")) };
44
- const realPlatform = { ...(await import("../../../../util/platform.js")) };
45
- const realPageStore = { ...(await import("../../../../memory/v2/page-store.js")) };
44
+ const realPlatform = { ...(await import("../../../util/platform.js")) };
45
+ const realPageStore = { ...(await import("../../v2/page-store.js")) };
46
46
  const realConversationCrud = {
47
- ...(await import("../../../../memory/conversation-crud.js")),
47
+ ...(await import("../../conversation-crud.js")),
48
48
  };
49
49
 
50
50
  let shadowMockActive = false;
@@ -95,7 +95,7 @@ const FAKE_TREE = {
95
95
 
96
96
  // ─── module mocks (installed before the plugin import) ──────────────────────
97
97
 
98
- mock.module("../../../../config/assistant-feature-flags.js", () => ({
98
+ mock.module("../../../config/assistant-feature-flags.js", () => ({
99
99
  isAssistantFeatureFlagEnabled: (key: string) =>
100
100
  key === "memory-v3-live"
101
101
  ? liveEnabled
@@ -104,7 +104,7 @@ mock.module("../../../../config/assistant-feature-flags.js", () => ({
104
104
  : false,
105
105
  }));
106
106
 
107
- mock.module("../../../../config/loader.js", () => ({
107
+ mock.module("../../../config/loader.js", () => ({
108
108
  getConfig: () => ({
109
109
  memory: {
110
110
  v3: {
@@ -119,12 +119,12 @@ mock.module("../../../../config/loader.js", () => ({
119
119
  // (e.g. `getMessageById` via page-content.ts) stays present — replacing the
120
120
  // whole module with a bare `{ getMessages }` made those consumers fail to load.
121
121
  // Only `getMessages` is overridden, since that's the one the plugin reads.
122
- mock.module("../../../../memory/conversation-crud.js", () => ({
122
+ mock.module("../../conversation-crud.js", () => ({
123
123
  ...realConversationCrud,
124
124
  getMessages: () => messages.map((m, i) => ({ ...m, id: `m${i}` })),
125
125
  }));
126
126
 
127
- mock.module("../../../../memory/db-connection.js", () => ({
127
+ mock.module("../../db-connection.js", () => ({
128
128
  getDb: () => testDb,
129
129
  getSqliteFrom: () => testSqlite,
130
130
  }));
@@ -136,7 +136,7 @@ mock.module("../v2/page-index.js", () => ({
136
136
  // `pageContent` (live mode) reads the full page via `readPage`/`renderPageContent`.
137
137
  // Stub them to return a deterministic body per slug so the rendered `<memory>`
138
138
  // block is assertable without touching the filesystem.
139
- mock.module("../../../../memory/v2/page-store.js", () => ({
139
+ mock.module("../../v2/page-store.js", () => ({
140
140
  ...realPageStore,
141
141
  readPage: async (workspaceDir: string, slug: string) =>
142
142
  shadowMockActive
@@ -150,7 +150,7 @@ mock.module("../../../../memory/v2/page-store.js", () => ({
150
150
  ),
151
151
  }));
152
152
 
153
- mock.module("../../../../util/platform.js", () => ({
153
+ mock.module("../../../util/platform.js", () => ({
154
154
  ...realPlatform,
155
155
  getWorkspaceDir: () =>
156
156
  shadowMockActive
@@ -209,8 +209,8 @@ const {
209
209
  runShadowObservation,
210
210
  resetShadowLanesForTests,
211
211
  invalidateLanes,
212
+ memoryV3Injector,
212
213
  } = await import("../shadow-plugin.js");
213
- const { memoryV3Injector } = await import("../injector.js");
214
214
 
215
215
  // The module stubs above stay installed for the rest of the process (Bun can't
216
216
  // reliably uninstall them), but `shadowMockActive` gates their fake behavior to
@@ -18,15 +18,15 @@
18
18
  * omitted, resolves the `memoryV3RouteL1` callsite provider.
19
19
  */
20
20
 
21
- import { listPages, readPage, writePage } from "../../../memory/v2/page-store.js";
22
- import type { ConceptPage } from "../../../memory/v2/types.js";
23
21
  import {
24
22
  extractToolUse,
25
23
  getConfiguredProvider,
26
24
  userMessage,
27
- } from "../../../providers/provider-send-message.js";
28
- import type { Provider, ToolDefinition } from "../../../providers/types.js";
29
- import { getLogger } from "../../../util/logger.js";
25
+ } from "../../providers/provider-send-message.js";
26
+ import type { Provider, ToolDefinition } from "../../providers/types.js";
27
+ import { getLogger } from "../../util/logger.js";
28
+ import { listPages, readPage, writePage } from "../v2/page-store.js";
29
+ import type { ConceptPage } from "../v2/types.js";
30
30
  import type { LeafPath, LeafTree, Slug } from "./types.js";
31
31
 
32
32
  const log = getLogger("memory-v3-assign");
@@ -28,8 +28,8 @@
28
28
  import {
29
29
  getCliCommandCapability,
30
30
  isCliCommandSlug,
31
- } from "../../../memory/v2/cli-command-store.js";
32
- import { getSkillCapability, isSkillSlug } from "../../../memory/v2/skill-store.js";
31
+ } from "../v2/cli-command-store.js";
32
+ import { getSkillCapability, isSkillSlug } from "../v2/skill-store.js";
33
33
  import type { LeafNode, LeafPath, LeafTree, Slug } from "./types.js";
34
34
 
35
35
  /** Path of the always-on synthetic leaf that owns skill + CLI capability rows. */