@vellumai/assistant 0.5.16 → 0.6.0

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 (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -0,0 +1,534 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory Graph — CLI inspection tool for testing
3
+ //
4
+ // Usage (from assistant/):
5
+ // bun run src/memory/graph/inspect.ts --stats
6
+ // bun run src/memory/graph/inspect.ts --context-load
7
+ // bun run src/memory/graph/inspect.ts --query "what does the user think about X"
8
+ // bun run src/memory/graph/inspect.ts --node <id>
9
+ // bun run src/memory/graph/inspect.ts --turn "user said this"
10
+ // bun run src/memory/graph/inspect.ts --bootstrap [--limit N] [--dry-run]
11
+ // bun run src/memory/graph/inspect.ts --bootstrap-journal
12
+ // bun run src/memory/graph/inspect.ts --decay
13
+ // ---------------------------------------------------------------------------
14
+
15
+ import { getConfig } from "../../config/loader.js";
16
+ import { initializeDb } from "../db-init.js";
17
+ import { initQdrantClient } from "../qdrant-client.js";
18
+ import {
19
+ countNodes,
20
+ getEdgesForNode,
21
+ getNode,
22
+ getTriggersForNode,
23
+ queryNodes,
24
+ } from "./store.js";
25
+ import type { ScoredNode } from "./types.js";
26
+
27
+ // Initialize DB and Qdrant before anything else
28
+ initializeDb();
29
+ const config = getConfig();
30
+ try {
31
+ initQdrantClient({
32
+ url: config.memory.qdrant.url ?? "http://127.0.0.1:6333",
33
+ collection: config.memory.qdrant.collection,
34
+ vectorSize: config.memory.qdrant.vectorSize,
35
+ onDisk: config.memory.qdrant.onDisk ?? true,
36
+ quantization: config.memory.qdrant.quantization ?? "none",
37
+ });
38
+ } catch {
39
+ // Qdrant may already be initialized
40
+ }
41
+
42
+ const args = process.argv.slice(2);
43
+
44
+ async function main() {
45
+ if (args.includes("--stats")) {
46
+ await showStats();
47
+ } else if (args.includes("--list")) {
48
+ showList();
49
+ } else if (args.includes("--context-load")) {
50
+ await showContextLoad();
51
+ } else if (args.includes("--query")) {
52
+ const idx = args.indexOf("--query");
53
+ const query = args[idx + 1];
54
+ if (!query) {
55
+ console.error("Usage: --query <search text>");
56
+ process.exit(1);
57
+ }
58
+ await showQuery(query);
59
+ } else if (args.includes("--node")) {
60
+ const idx = args.indexOf("--node");
61
+ const nodeId = args[idx + 1];
62
+ if (!nodeId) {
63
+ console.error("Usage: --node <node-id>");
64
+ process.exit(1);
65
+ }
66
+ showNode(nodeId);
67
+ } else if (args.includes("--turn")) {
68
+ const idx = args.indexOf("--turn");
69
+ const userMsg = args[idx + 1];
70
+ if (!userMsg) {
71
+ console.error('Usage: --turn "user message"');
72
+ process.exit(1);
73
+ }
74
+ await showTurn(userMsg);
75
+ } else if (args.includes("--bootstrap")) {
76
+ await runBootstrap();
77
+ } else if (args.includes("--bootstrap-journal")) {
78
+ await runJournalBootstrap();
79
+ } else if (args.includes("--consolidate")) {
80
+ await runConsolidate();
81
+ } else if (args.includes("--pattern-scan")) {
82
+ await runPatterns();
83
+ } else if (args.includes("--narrative")) {
84
+ await runNarrative();
85
+ } else if (args.includes("--decay")) {
86
+ runDecay();
87
+ } else {
88
+ console.log(`Memory Graph Inspector
89
+
90
+ Commands:
91
+ --stats Show graph statistics
92
+ --list [--type X] List all nodes (optionally filter by type)
93
+ --context-load Simulate conversation start retrieval
94
+ --query "text" Search graph nodes by content
95
+ --node <id> Show a specific node and its connections
96
+ --turn "user msg" Simulate mid-conversation injection
97
+ --consolidate Run consolidation (merge dupes, fade old)
98
+ --pattern-scan Detect recurring patterns
99
+ --narrative Refine narrative arcs
100
+ --bootstrap [--limit N] [--dry-run] Re-extract from history
101
+ --bootstrap-journal Extract from journal files
102
+ --decay Run a decay tick
103
+ `);
104
+ }
105
+ }
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // Commands
109
+ // ---------------------------------------------------------------------------
110
+
111
+ function showList() {
112
+ const scopeId = "default";
113
+ const typeIdx = args.indexOf("--type");
114
+ const typeFilter = typeIdx >= 0 ? args[typeIdx + 1] : undefined;
115
+
116
+ const allNodes = queryNodes({
117
+ scopeId,
118
+ fidelityNot: ["gone"],
119
+ limit: 100000,
120
+ });
121
+ const filtered = typeFilter
122
+ ? allNodes.filter((n) => n.type === typeFilter)
123
+ : allNodes;
124
+
125
+ // Sort by created desc (newest first)
126
+ filtered.sort((a, b) => b.created - a.created);
127
+
128
+ console.log(
129
+ `\n Nodes${typeFilter ? ` (type: ${typeFilter})` : ""}: ${filtered.length}\n`,
130
+ );
131
+ for (const node of filtered) {
132
+ const age = relativeAge(node.created);
133
+ const preview =
134
+ node.content.length > 90 ? node.content.slice(0, 90) + "…" : node.content;
135
+ console.log(
136
+ ` ${node.id} [${node.type}] (${age}, sig=${node.significance.toFixed(2)}) ${preview}`,
137
+ );
138
+ }
139
+ console.log();
140
+ }
141
+
142
+ function relativeAge(epochMs: number): string {
143
+ const elapsed = Date.now() - epochMs;
144
+ const mins = Math.floor(elapsed / 60_000);
145
+ if (mins < 60) return `${mins}m ago`;
146
+ const hours = Math.floor(mins / 60);
147
+ if (hours < 24) return `${hours}h ago`;
148
+ const days = Math.floor(hours / 24);
149
+ if (days <= 90) return `${days}d ago`;
150
+ const months = Math.floor(days / 30);
151
+ return `${months}mo ago`;
152
+ }
153
+
154
+ async function showStats() {
155
+ const scopeId = "default";
156
+ const total = countNodes(scopeId);
157
+ const allNodes = queryNodes({
158
+ scopeId,
159
+ fidelityNot: ["gone"],
160
+ limit: 100000,
161
+ });
162
+
163
+ const byType = new Map<string, number>();
164
+ const byFidelity = new Map<string, number>();
165
+ let totalEdges = 0;
166
+ let totalTriggers = 0;
167
+
168
+ for (const node of allNodes) {
169
+ byType.set(node.type, (byType.get(node.type) ?? 0) + 1);
170
+ byFidelity.set(node.fidelity, (byFidelity.get(node.fidelity) ?? 0) + 1);
171
+ totalEdges += getEdgesForNode(node.id).length;
172
+ totalTriggers += getTriggersForNode(node.id).length;
173
+ }
174
+
175
+ // Edges are counted twice (once per endpoint), so halve
176
+ totalEdges = Math.floor(totalEdges / 2);
177
+
178
+ console.log(`\n Memory Graph Stats (scope: ${scopeId})`);
179
+ console.log(` ${"─".repeat(40)}`);
180
+ console.log(` Total nodes: ${total}`);
181
+ console.log(` Total edges: ${totalEdges}`);
182
+ console.log(` Total triggers: ${totalTriggers}`);
183
+ console.log(`\n By type:`);
184
+ for (const [type, count] of [...byType.entries()].sort(
185
+ (a, b) => b[1] - a[1],
186
+ )) {
187
+ console.log(` ${type}: ${count}`);
188
+ }
189
+ console.log(`\n By fidelity:`);
190
+ for (const [fidelity, count] of [...byFidelity.entries()].sort()) {
191
+ console.log(` ${fidelity}: ${count}`);
192
+ }
193
+
194
+ // Sample content
195
+ if (allNodes.length > 0) {
196
+ console.log(`\n Sample nodes (top 5 by significance):`);
197
+ const top = [...allNodes]
198
+ .sort((a, b) => b.significance - a.significance)
199
+ .slice(0, 5);
200
+ for (const node of top) {
201
+ const preview =
202
+ node.content.length > 100
203
+ ? node.content.slice(0, 100) + "…"
204
+ : node.content;
205
+ console.log(
206
+ ` ${node.id} [${node.type}] (sig=${node.significance.toFixed(2)}) ${preview}`,
207
+ );
208
+ }
209
+ }
210
+ console.log();
211
+ }
212
+
213
+ async function showContextLoad() {
214
+ const { loadContextMemory } = await import("./retriever.js");
215
+
216
+ console.log("\n Simulating context load (conversation start)...\n");
217
+
218
+ const result = await loadContextMemory({
219
+ scopeId: "default",
220
+ recentSummaries: [], // No recent summaries for standalone test
221
+ config,
222
+ });
223
+
224
+ console.log(
225
+ ` Retrieved ${result.nodes.length} nodes in ${result.latencyMs}ms`,
226
+ );
227
+ console.log(` Triggered: ${result.triggeredNodes.length} triggers fired`);
228
+
229
+ // Show assembled context
230
+ const { assembleContextBlock } = await import("./injection.js");
231
+ const block = assembleContextBlock(result.nodes, {
232
+ serendipityNodes: result.serendipityNodes,
233
+ });
234
+
235
+ if (block) {
236
+ console.log(`\n --- Assembled Context Block ---\n`);
237
+ console.log(block);
238
+ console.log(`\n --- End Context Block ---\n`);
239
+ } else {
240
+ console.log(" (no context to inject)");
241
+ }
242
+
243
+ printScoredNodes(result.nodes);
244
+ }
245
+
246
+ async function showQuery(query: string) {
247
+ const { embedWithRetry } = await import("../embed.js");
248
+ const { searchGraphNodes } = await import("./graph-search.js");
249
+ const { getNodesByIds } = await import("./store.js");
250
+
251
+ console.log(`\n Searching: "${query}"\n`);
252
+
253
+ try {
254
+ const embedding = await embedWithRetry(config, [query]);
255
+ const vector = embedding.vectors[0];
256
+ if (!vector) {
257
+ console.error(" Failed to embed query");
258
+ return;
259
+ }
260
+
261
+ const results = await searchGraphNodes(vector, 20, ["default"]);
262
+ if (results.length === 0) {
263
+ console.log(" No results found.");
264
+ return;
265
+ }
266
+
267
+ const nodes = getNodesByIds(results.map((r) => r.nodeId));
268
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
269
+
270
+ console.log(` Found ${results.length} results:\n`);
271
+ for (const r of results) {
272
+ const node = nodeMap.get(r.nodeId);
273
+ if (!node) continue;
274
+ const preview =
275
+ node.content.length > 120
276
+ ? node.content.slice(0, 120) + "…"
277
+ : node.content;
278
+ console.log(
279
+ ` ${r.nodeId} [${r.score.toFixed(3)}] (${node.type}, sig=${node.significance.toFixed(2)}) ${preview}`,
280
+ );
281
+ }
282
+ } catch (err) {
283
+ console.error(
284
+ ` Error: ${err instanceof Error ? err.message : String(err)}`,
285
+ );
286
+ }
287
+ console.log();
288
+ }
289
+
290
+ function showNode(nodeId: string) {
291
+ const node = getNode(nodeId);
292
+ if (!node) {
293
+ console.error(` Node not found: ${nodeId}`);
294
+ return;
295
+ }
296
+
297
+ console.log(`\n Node: ${node.id}`);
298
+ console.log(` ${"─".repeat(50)}`);
299
+ console.log(` Type: ${node.type}`);
300
+ console.log(` Fidelity: ${node.fidelity}`);
301
+ console.log(` Confidence: ${node.confidence.toFixed(2)}`);
302
+ console.log(` Significance: ${node.significance.toFixed(2)}`);
303
+ console.log(` Stability: ${node.stability.toFixed(1)}`);
304
+ console.log(` Reinforcements: ${node.reinforcementCount}`);
305
+ console.log(` Source: ${node.sourceType}`);
306
+ console.log(` Created: ${new Date(node.created).toISOString()}`);
307
+ console.log(
308
+ ` Event date: ${node.eventDate != null ? new Date(node.eventDate).toISOString() : "none"}`,
309
+ );
310
+ console.log(
311
+ ` Emotional: valence=${node.emotionalCharge.valence.toFixed(2)} intensity=${node.emotionalCharge.intensity.toFixed(2)} curve=${node.emotionalCharge.decayCurve}`,
312
+ );
313
+ if (node.narrativeRole)
314
+ console.log(` Narrative role: ${node.narrativeRole}`);
315
+ if (node.partOfStory) console.log(` Part of story: ${node.partOfStory}`);
316
+ console.log(` Source conversations: ${node.sourceConversations.length}`);
317
+ console.log(`\n Content:\n ${node.content}\n`);
318
+
319
+ // Edges
320
+ const edges = getEdgesForNode(node.id);
321
+ if (edges.length > 0) {
322
+ console.log(` Edges (${edges.length}):`);
323
+ for (const edge of edges) {
324
+ const otherId =
325
+ edge.sourceNodeId === node.id ? edge.targetNodeId : edge.sourceNodeId;
326
+ const direction = edge.sourceNodeId === node.id ? "→" : "←";
327
+ const other = getNode(otherId);
328
+ const preview = other
329
+ ? other.content.length > 60
330
+ ? other.content.slice(0, 60) + "…"
331
+ : other.content
332
+ : "(deleted)";
333
+ console.log(
334
+ ` ${direction} [${edge.relationship}] (w=${edge.weight.toFixed(2)}) ${preview}`,
335
+ );
336
+ }
337
+ }
338
+
339
+ // Triggers
340
+ const triggers = getTriggersForNode(node.id);
341
+ if (triggers.length > 0) {
342
+ console.log(`\n Triggers (${triggers.length}):`);
343
+ for (const t of triggers) {
344
+ const detail =
345
+ t.type === "temporal"
346
+ ? t.schedule
347
+ : t.type === "semantic"
348
+ ? t.condition
349
+ : t.eventDate
350
+ ? new Date(t.eventDate).toISOString()
351
+ : "?";
352
+ console.log(
353
+ ` [${t.type}] ${detail} ${t.recurring ? "(recurring)" : ""} ${t.consumed ? "(consumed)" : ""}`,
354
+ );
355
+ }
356
+ }
357
+ console.log();
358
+ }
359
+
360
+ async function showTurn(userMessage: string) {
361
+ const { retrieveForTurn } = await import("./retriever.js");
362
+ const { InContextTracker } = await import("./injection.js");
363
+ const { assembleInjectionBlock } = await import("./injection.js");
364
+
365
+ const tracker = new InContextTracker();
366
+
367
+ console.log(`\n Simulating per-turn retrieval for: "${userMessage}"\n`);
368
+
369
+ const result = await retrieveForTurn({
370
+ assistantLastMessage: "",
371
+ userLastMessage: userMessage,
372
+ scopeId: "default",
373
+ config,
374
+ tracker,
375
+ });
376
+
377
+ console.log(
378
+ ` Found ${result.nodes.length} new nodes in ${result.latencyMs}ms`,
379
+ );
380
+ console.log(` Triggered: ${result.triggeredNodes.length} semantic triggers`);
381
+
382
+ if (result.nodes.length > 0) {
383
+ const block = assembleInjectionBlock(result.nodes);
384
+ console.log(`\n Injection: ${block}\n`);
385
+ printScoredNodes(result.nodes);
386
+ } else {
387
+ console.log(" (nothing to inject)\n");
388
+ }
389
+ }
390
+
391
+ async function runBootstrap() {
392
+ const { bootstrapFromHistory, resetBootstrapCheckpoint } =
393
+ await import("./bootstrap.js");
394
+
395
+ const limitIdx = args.indexOf("--limit");
396
+ const limit = limitIdx >= 0 ? parseInt(args[limitIdx + 1], 10) : undefined;
397
+ const dryRun = args.includes("--dry-run");
398
+
399
+ if (args.includes("--reset")) {
400
+ resetBootstrapCheckpoint();
401
+ console.log(" Bootstrap checkpoint reset.\n");
402
+ }
403
+
404
+ console.log(
405
+ `\n Starting bootstrap${dryRun ? " (dry run)" : ""}${limit ? ` (limit: ${limit})` : ""}...\n`,
406
+ );
407
+
408
+ const result = await bootstrapFromHistory({ limit, dryRun });
409
+
410
+ console.log(` Bootstrap complete:`);
411
+ console.log(` Conversations processed: ${result.conversationsProcessed}`);
412
+ console.log(` Conversations skipped: ${result.conversationsSkipped}`);
413
+ console.log(` Nodes created: ${result.totalNodesCreated}`);
414
+ console.log(` Nodes updated: ${result.totalNodesUpdated}`);
415
+ console.log(` Nodes reinforced: ${result.totalNodesReinforced}`);
416
+ console.log(` Edges created: ${result.totalEdgesCreated}`);
417
+ console.log(` Triggers created: ${result.totalTriggersCreated}`);
418
+ console.log(` Errors: ${result.errors.length}`);
419
+ console.log(` Elapsed: ${(result.elapsedMs / 1000).toFixed(1)}s`);
420
+
421
+ if (result.errors.length > 0) {
422
+ console.log(`\n Errors:`);
423
+ for (const e of result.errors.slice(0, 10)) {
424
+ console.log(` ${e.conversationId}: ${e.error}`);
425
+ }
426
+ if (result.errors.length > 10) {
427
+ console.log(` ... and ${result.errors.length - 10} more`);
428
+ }
429
+ }
430
+ console.log();
431
+ }
432
+
433
+ async function runJournalBootstrap() {
434
+ const { bootstrapFromJournal } = await import("./bootstrap.js");
435
+
436
+ console.log("\n Extracting from journal files...\n");
437
+ const result = await bootstrapFromJournal();
438
+ console.log(` Journal entries extracted: ${result.extracted}`);
439
+ console.log(` Errors: ${result.errors}`);
440
+ console.log();
441
+ }
442
+
443
+ async function runConsolidate() {
444
+ const { runConsolidation } = await import("./consolidation.js");
445
+ console.log("\n Running consolidation...\n");
446
+ const result = await runConsolidation("default", config);
447
+ console.log(
448
+ ` Consolidation complete (${(result.latencyMs / 1000).toFixed(1)}s):`,
449
+ );
450
+ console.log(` Nodes updated: ${result.totalUpdated}`);
451
+ console.log(` Nodes deleted (merged): ${result.totalDeleted}`);
452
+ console.log(` Merge edges created: ${result.totalMergeEdges}`);
453
+ console.log(`\n By partition:`);
454
+ for (const [name, p] of Object.entries(result.partitions)) {
455
+ console.log(
456
+ ` ${name}: ${p.nodesUpdated} updated, ${p.nodesDeleted} deleted, ${p.mergeEdgesCreated} merged`,
457
+ );
458
+ }
459
+ console.log();
460
+ }
461
+
462
+ async function runPatterns() {
463
+ const { runPatternScan } = await import("./pattern-scan.js");
464
+ console.log("\n Running pattern scan...\n");
465
+ const result = await runPatternScan("default", config);
466
+ console.log(
467
+ ` Pattern scan complete (${(result.latencyMs / 1000).toFixed(1)}s):`,
468
+ );
469
+ console.log(` Patterns detected: ${result.patternsDetected}`);
470
+ console.log(` Edges created: ${result.edgesCreated}`);
471
+ console.log();
472
+ }
473
+
474
+ async function runNarrative() {
475
+ const { runNarrativeRefinement } = await import("./narrative.js");
476
+ console.log("\n Running narrative refinement...\n");
477
+ const result = await runNarrativeRefinement("default", config);
478
+ console.log(
479
+ ` Narrative refinement complete (${(result.latencyMs / 1000).toFixed(1)}s):`,
480
+ );
481
+ console.log(` Nodes updated: ${result.nodesUpdated}`);
482
+ console.log(` Arcs identified: ${result.arcsIdentified}`);
483
+ if (result.arcs.length > 0) {
484
+ console.log(`\n Story arcs:`);
485
+ for (const arc of result.arcs) {
486
+ console.log(
487
+ ` "${arc.name}" (${arc.nodeCount} nodes): ${arc.description}`,
488
+ );
489
+ }
490
+ }
491
+ console.log();
492
+ }
493
+
494
+ function runDecay() {
495
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
496
+ const { runDecayTick } = require("./decay.js") as typeof import("./decay.js");
497
+ console.log("\n Running decay tick...\n");
498
+ const result = runDecayTick("default");
499
+ console.log(` Nodes processed: ${result.nodesProcessed}`);
500
+ console.log(` Emotional decays: ${result.emotionalDecays}`);
501
+ console.log(` Fidelity downgrades: ${result.fidelityDowngrades}`);
502
+ console.log();
503
+ }
504
+
505
+ // ---------------------------------------------------------------------------
506
+ // Helpers
507
+ // ---------------------------------------------------------------------------
508
+
509
+ function printScoredNodes(nodes: ScoredNode[]) {
510
+ if (nodes.length === 0) return;
511
+ console.log(` Scored nodes:`);
512
+ for (const s of nodes) {
513
+ const b = s.scoreBreakdown;
514
+ const preview =
515
+ s.node.content.length > 80
516
+ ? s.node.content.slice(0, 80) + "…"
517
+ : s.node.content;
518
+ console.log(
519
+ ` ${s.node.id} [${s.score.toFixed(3)}] sem=${b.semanticSimilarity.toFixed(2)} sig=${b.effectiveSignificance.toFixed(2)} emo=${b.emotionalIntensity.toFixed(2)} tmp=${b.temporalBoost.toFixed(2)} rec=${b.recencyBoost.toFixed(2)} trg=${b.triggerBoost.toFixed(2)} act=${b.activationBoost.toFixed(2)}`,
520
+ );
521
+ console.log(` (${s.node.type}) ${preview}`);
522
+ }
523
+ }
524
+
525
+ // ---------------------------------------------------------------------------
526
+ // Run
527
+ // ---------------------------------------------------------------------------
528
+
529
+ main()
530
+ .then(() => process.exit(0))
531
+ .catch((err) => {
532
+ console.error("Fatal:", err);
533
+ process.exit(1);
534
+ });