@soleri/core 9.2.0 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/data/flows/build.flow.yaml +8 -9
  2. package/data/flows/deliver.flow.yaml +9 -10
  3. package/data/flows/design.flow.yaml +3 -4
  4. package/data/flows/enhance.flow.yaml +5 -6
  5. package/data/flows/explore.flow.yaml +3 -4
  6. package/data/flows/fix.flow.yaml +5 -6
  7. package/data/flows/plan.flow.yaml +4 -5
  8. package/data/flows/review.flow.yaml +3 -4
  9. package/dist/curator/curator.d.ts.map +1 -1
  10. package/dist/curator/curator.js +98 -22
  11. package/dist/curator/curator.js.map +1 -1
  12. package/dist/engine/bin/soleri-engine.js.map +1 -1
  13. package/dist/engine/module-manifest.d.ts +2 -0
  14. package/dist/engine/module-manifest.d.ts.map +1 -1
  15. package/dist/engine/module-manifest.js +136 -1
  16. package/dist/engine/module-manifest.js.map +1 -1
  17. package/dist/engine/register-engine.d.ts.map +1 -1
  18. package/dist/engine/register-engine.js +25 -1
  19. package/dist/engine/register-engine.js.map +1 -1
  20. package/dist/flows/gate-evaluator.js.map +1 -1
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/operator/operator-profile.d.ts.map +1 -1
  26. package/dist/operator/operator-profile.js +11 -5
  27. package/dist/operator/operator-profile.js.map +1 -1
  28. package/dist/operator/operator-signals.d.ts.map +1 -1
  29. package/dist/operator/operator-signals.js.map +1 -1
  30. package/dist/planning/evidence-collector.js.map +1 -1
  31. package/dist/planning/gap-passes.d.ts.map +1 -1
  32. package/dist/planning/gap-passes.js +23 -6
  33. package/dist/planning/gap-passes.js.map +1 -1
  34. package/dist/planning/gap-patterns.d.ts.map +1 -1
  35. package/dist/planning/gap-patterns.js +57 -11
  36. package/dist/planning/gap-patterns.js.map +1 -1
  37. package/dist/planning/github-projection.d.ts.map +1 -1
  38. package/dist/planning/github-projection.js +39 -20
  39. package/dist/planning/github-projection.js.map +1 -1
  40. package/dist/planning/impact-analyzer.d.ts.map +1 -1
  41. package/dist/planning/impact-analyzer.js +20 -18
  42. package/dist/planning/impact-analyzer.js.map +1 -1
  43. package/dist/planning/plan-lifecycle.d.ts.map +1 -1
  44. package/dist/planning/plan-lifecycle.js +22 -9
  45. package/dist/planning/plan-lifecycle.js.map +1 -1
  46. package/dist/planning/planner.d.ts.map +1 -1
  47. package/dist/planning/planner.js +60 -17
  48. package/dist/planning/planner.js.map +1 -1
  49. package/dist/planning/rationalization-detector.d.ts.map +1 -1
  50. package/dist/planning/rationalization-detector.js.map +1 -1
  51. package/dist/planning/reconciliation-engine.d.ts.map +1 -1
  52. package/dist/planning/reconciliation-engine.js.map +1 -1
  53. package/dist/planning/task-complexity-assessor.d.ts +42 -0
  54. package/dist/planning/task-complexity-assessor.d.ts.map +1 -0
  55. package/dist/planning/task-complexity-assessor.js +132 -0
  56. package/dist/planning/task-complexity-assessor.js.map +1 -0
  57. package/dist/planning/task-verifier.d.ts.map +1 -1
  58. package/dist/planning/task-verifier.js +14 -6
  59. package/dist/planning/task-verifier.js.map +1 -1
  60. package/dist/runtime/admin-ops.d.ts.map +1 -1
  61. package/dist/runtime/admin-ops.js +18 -0
  62. package/dist/runtime/admin-ops.js.map +1 -1
  63. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  64. package/dist/runtime/admin-setup-ops.js +2 -1
  65. package/dist/runtime/admin-setup-ops.js.map +1 -1
  66. package/dist/runtime/branching-ops.d.ts +12 -0
  67. package/dist/runtime/branching-ops.d.ts.map +1 -0
  68. package/dist/runtime/branching-ops.js +100 -0
  69. package/dist/runtime/branching-ops.js.map +1 -0
  70. package/dist/runtime/context-health.d.ts.map +1 -1
  71. package/dist/runtime/context-health.js.map +1 -1
  72. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  73. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  74. package/dist/runtime/facades/branching-facade.js +8 -0
  75. package/dist/runtime/facades/branching-facade.js.map +1 -0
  76. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -1
  77. package/dist/runtime/facades/chat-service-ops.js +3 -1
  78. package/dist/runtime/facades/chat-service-ops.js.map +1 -1
  79. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -1
  80. package/dist/runtime/facades/chat-transport-ops.js.map +1 -1
  81. package/dist/runtime/facades/index.d.ts.map +1 -1
  82. package/dist/runtime/facades/index.js +42 -0
  83. package/dist/runtime/facades/index.js.map +1 -1
  84. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  85. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  86. package/dist/runtime/facades/intake-facade.js +11 -0
  87. package/dist/runtime/facades/intake-facade.js.map +1 -0
  88. package/dist/runtime/facades/links-facade.d.ts +9 -0
  89. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  90. package/dist/runtime/facades/links-facade.js +10 -0
  91. package/dist/runtime/facades/links-facade.js.map +1 -0
  92. package/dist/runtime/facades/operator-facade.d.ts.map +1 -1
  93. package/dist/runtime/facades/operator-facade.js.map +1 -1
  94. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  95. package/dist/runtime/facades/plan-facade.js +4 -1
  96. package/dist/runtime/facades/plan-facade.js.map +1 -1
  97. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  98. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  99. package/dist/runtime/facades/tier-facade.js +8 -0
  100. package/dist/runtime/facades/tier-facade.js.map +1 -0
  101. package/dist/runtime/facades/vault-facade.d.ts +9 -1
  102. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  103. package/dist/runtime/facades/vault-facade.js +44 -187
  104. package/dist/runtime/facades/vault-facade.js.map +1 -1
  105. package/dist/runtime/github-integration.d.ts.map +1 -1
  106. package/dist/runtime/github-integration.js +11 -4
  107. package/dist/runtime/github-integration.js.map +1 -1
  108. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  109. package/dist/runtime/orchestrate-ops.js +75 -42
  110. package/dist/runtime/orchestrate-ops.js.map +1 -1
  111. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  112. package/dist/runtime/planning-extra-ops.js.map +1 -1
  113. package/dist/runtime/runtime.d.ts.map +1 -1
  114. package/dist/runtime/runtime.js +3 -1
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/runtime/session-briefing.d.ts.map +1 -1
  117. package/dist/runtime/session-briefing.js +5 -1
  118. package/dist/runtime/session-briefing.js.map +1 -1
  119. package/dist/runtime/tier-ops.d.ts +13 -0
  120. package/dist/runtime/tier-ops.d.ts.map +1 -0
  121. package/dist/runtime/tier-ops.js +110 -0
  122. package/dist/runtime/tier-ops.js.map +1 -0
  123. package/dist/skills/sync-skills.d.ts.map +1 -1
  124. package/dist/skills/sync-skills.js +1 -1
  125. package/dist/skills/sync-skills.js.map +1 -1
  126. package/dist/vault/linking.d.ts.map +1 -1
  127. package/dist/vault/linking.js +41 -5
  128. package/dist/vault/linking.js.map +1 -1
  129. package/dist/vault/vault-entries.d.ts.map +1 -1
  130. package/dist/vault/vault-entries.js +68 -26
  131. package/dist/vault/vault-entries.js.map +1 -1
  132. package/dist/vault/vault-maintenance.d.ts.map +1 -1
  133. package/dist/vault/vault-maintenance.js +6 -2
  134. package/dist/vault/vault-maintenance.js.map +1 -1
  135. package/dist/vault/vault-markdown-sync.d.ts.map +1 -1
  136. package/dist/vault/vault-markdown-sync.js.map +1 -1
  137. package/dist/vault/vault-memories.d.ts.map +1 -1
  138. package/dist/vault/vault-memories.js +3 -1
  139. package/dist/vault/vault-memories.js.map +1 -1
  140. package/dist/vault/vault-schema.js +36 -10
  141. package/dist/vault/vault-schema.js.map +1 -1
  142. package/dist/vault/vault.d.ts.map +1 -1
  143. package/dist/vault/vault.js +5 -1
  144. package/dist/vault/vault.js.map +1 -1
  145. package/package.json +7 -7
  146. package/src/agency/agency-manager.test.ts +60 -40
  147. package/src/agency/default-rules.test.ts +17 -9
  148. package/src/capabilities/registry.test.ts +2 -12
  149. package/src/chat/agent-loop.test.ts +33 -43
  150. package/src/chat/mcp-bridge.test.ts +7 -2
  151. package/src/claudemd/inject.test.ts +2 -12
  152. package/src/context/context-engine.test.ts +96 -51
  153. package/src/control/intent-router.test.ts +3 -3
  154. package/src/curator/classifier.test.ts +14 -8
  155. package/src/curator/contradiction-detector.test.ts +30 -5
  156. package/src/curator/curator.ts +278 -56
  157. package/src/curator/duplicate-detector.test.ts +77 -15
  158. package/src/curator/quality-gate.test.ts +71 -31
  159. package/src/curator/tag-manager.test.ts +12 -4
  160. package/src/domain-packs/knowledge-installer.test.ts +2 -10
  161. package/src/domain-packs/token-resolver.test.ts +1 -3
  162. package/src/domain-packs/types.test.ts +16 -2
  163. package/src/enforcement/registry.test.ts +2 -8
  164. package/src/engine/bin/soleri-engine.ts +3 -1
  165. package/src/engine/module-manifest.test.ts +48 -4
  166. package/src/engine/module-manifest.ts +138 -1
  167. package/src/engine/register-engine.test.ts +6 -1
  168. package/src/engine/register-engine.ts +26 -3
  169. package/src/errors/classify.test.ts +6 -2
  170. package/src/errors/retry.test.ts +1 -4
  171. package/src/facades/facade-factory.test.ts +110 -64
  172. package/src/flows/epilogue.test.ts +16 -10
  173. package/src/flows/gate-evaluator.test.ts +12 -6
  174. package/src/flows/gate-evaluator.ts +1 -3
  175. package/src/governance/governance.test.ts +137 -21
  176. package/src/health/health-registry.test.ts +8 -1
  177. package/src/index.ts +8 -0
  178. package/src/intake/content-classifier.test.ts +121 -51
  179. package/src/intake/dedup-gate.test.ts +38 -22
  180. package/src/intake/intake-pipeline.test.ts +5 -3
  181. package/src/intake/text-ingester.test.ts +26 -20
  182. package/src/llm/key-pool.test.ts +1 -3
  183. package/src/llm/llm-client.test.ts +1 -4
  184. package/src/llm/oauth-discovery.test.ts +16 -16
  185. package/src/llm/utils.test.ts +62 -18
  186. package/src/logging/logger.test.ts +4 -1
  187. package/src/loop/loop-manager.test.ts +2 -6
  188. package/src/migrations/migration-runner.edge-cases.test.ts +2 -7
  189. package/src/operator/operator-profile-extended.test.ts +15 -5
  190. package/src/operator/operator-profile.test.ts +26 -8
  191. package/src/operator/operator-profile.ts +38 -22
  192. package/src/operator/operator-signals-extended.test.ts +35 -23
  193. package/src/operator/operator-signals.test.ts +6 -10
  194. package/src/operator/operator-signals.ts +2 -1
  195. package/src/operator/prompts/hook-precompact-operator-dispatch.md +10 -6
  196. package/src/operator/prompts/subagent-soft-signal-extractor.md +5 -0
  197. package/src/operator/prompts/subagent-synthesis-cognition.md +19 -10
  198. package/src/operator/prompts/subagent-synthesis-communication.md +13 -7
  199. package/src/operator/prompts/subagent-synthesis-technical.md +19 -9
  200. package/src/operator/prompts/subagent-synthesis-trust.md +27 -21
  201. package/src/persona/defaults.test.ts +1 -5
  202. package/src/planning/evidence-collector.test.ts +147 -38
  203. package/src/planning/evidence-collector.ts +1 -4
  204. package/src/planning/gap-analysis-alternatives.test.ts +41 -11
  205. package/src/planning/gap-passes.test.ts +215 -33
  206. package/src/planning/gap-passes.ts +115 -46
  207. package/src/planning/gap-patterns.test.ts +87 -13
  208. package/src/planning/gap-patterns.ts +114 -31
  209. package/src/planning/github-projection.test.ts +6 -1
  210. package/src/planning/github-projection.ts +41 -20
  211. package/src/planning/impact-analyzer.test.ts +10 -23
  212. package/src/planning/impact-analyzer.ts +33 -46
  213. package/src/planning/plan-lifecycle.test.ts +103 -36
  214. package/src/planning/plan-lifecycle.ts +49 -18
  215. package/src/planning/planner.test.ts +12 -2
  216. package/src/planning/planner.ts +198 -58
  217. package/src/planning/rationalization-detector.test.ts +5 -20
  218. package/src/planning/rationalization-detector.ts +14 -16
  219. package/src/planning/reconciliation-engine.test.ts +20 -3
  220. package/src/planning/reconciliation-engine.ts +1 -2
  221. package/src/planning/task-complexity-assessor.test.ts +298 -0
  222. package/src/planning/task-complexity-assessor.ts +183 -0
  223. package/src/planning/task-verifier.test.ts +59 -27
  224. package/src/planning/task-verifier.ts +15 -9
  225. package/src/playbooks/playbook-executor.test.ts +1 -3
  226. package/src/plugins/plugin-loader.test.ts +19 -14
  227. package/src/plugins/plugin-registry.test.ts +45 -33
  228. package/src/project/project-registry.test.ts +23 -12
  229. package/src/prompts/template-manager.test.ts +4 -1
  230. package/src/queue/job-queue.test.ts +10 -14
  231. package/src/runtime/admin-extra-ops.test.ts +5 -19
  232. package/src/runtime/admin-ops.test.ts +22 -1
  233. package/src/runtime/admin-ops.ts +19 -0
  234. package/src/runtime/admin-setup-ops.test.ts +3 -4
  235. package/src/runtime/admin-setup-ops.ts +9 -2
  236. package/src/runtime/archive-ops.test.ts +4 -1
  237. package/src/runtime/branching-ops.test.ts +144 -0
  238. package/src/runtime/branching-ops.ts +107 -0
  239. package/src/runtime/capture-ops.test.ts +7 -21
  240. package/src/runtime/chain-ops.test.ts +16 -6
  241. package/src/runtime/claude-md-helpers.test.ts +1 -3
  242. package/src/runtime/context-health.test.ts +1 -3
  243. package/src/runtime/context-health.ts +1 -3
  244. package/src/runtime/curator-extra-ops.test.ts +3 -1
  245. package/src/runtime/domain-ops.test.ts +46 -36
  246. package/src/runtime/facades/admin-facade.test.ts +1 -4
  247. package/src/runtime/facades/archive-facade.test.ts +21 -7
  248. package/src/runtime/facades/brain-facade.test.ts +176 -72
  249. package/src/runtime/facades/branching-facade.test.ts +43 -0
  250. package/src/runtime/facades/branching-facade.ts +11 -0
  251. package/src/runtime/facades/chat-facade.test.ts +81 -28
  252. package/src/runtime/facades/chat-service-ops.test.ts +178 -73
  253. package/src/runtime/facades/chat-service-ops.ts +3 -1
  254. package/src/runtime/facades/chat-session-ops.test.ts +25 -10
  255. package/src/runtime/facades/chat-transport-ops.test.ts +101 -34
  256. package/src/runtime/facades/chat-transport-ops.ts +0 -1
  257. package/src/runtime/facades/context-facade.test.ts +19 -4
  258. package/src/runtime/facades/control-facade.test.ts +3 -3
  259. package/src/runtime/facades/index.ts +42 -0
  260. package/src/runtime/facades/intake-facade.test.ts +215 -0
  261. package/src/runtime/facades/intake-facade.ts +14 -0
  262. package/src/runtime/facades/links-facade.test.ts +203 -0
  263. package/src/runtime/facades/links-facade.ts +13 -0
  264. package/src/runtime/facades/loop-facade.test.ts +22 -5
  265. package/src/runtime/facades/memory-facade.test.ts +19 -5
  266. package/src/runtime/facades/operator-facade.test.ts +17 -4
  267. package/src/runtime/facades/operator-facade.ts +11 -3
  268. package/src/runtime/facades/orchestrate-facade.test.ts +7 -1
  269. package/src/runtime/facades/plan-facade.test.ts +29 -12
  270. package/src/runtime/facades/plan-facade.ts +7 -2
  271. package/src/runtime/facades/tier-facade.test.ts +47 -0
  272. package/src/runtime/facades/tier-facade.ts +11 -0
  273. package/src/runtime/facades/vault-facade.test.ts +174 -242
  274. package/src/runtime/facades/vault-facade.ts +55 -199
  275. package/src/runtime/github-integration.ts +11 -8
  276. package/src/runtime/grading-ops.test.ts +39 -8
  277. package/src/runtime/intake-ops.test.ts +69 -16
  278. package/src/runtime/loop-ops.test.ts +16 -6
  279. package/src/runtime/memory-cross-project-ops.test.ts +25 -14
  280. package/src/runtime/orchestrate-ops.test.ts +204 -0
  281. package/src/runtime/orchestrate-ops.ts +103 -65
  282. package/src/runtime/pack-ops.test.ts +23 -6
  283. package/src/runtime/planning-extra-ops.test.ts +17 -7
  284. package/src/runtime/planning-extra-ops.ts +3 -1
  285. package/src/runtime/playbook-ops.test.ts +26 -3
  286. package/src/runtime/plugin-ops.test.ts +83 -25
  287. package/src/runtime/project-ops.test.ts +26 -6
  288. package/src/runtime/runtime.ts +3 -1
  289. package/src/runtime/session-briefing.test.ts +183 -54
  290. package/src/runtime/session-briefing.ts +8 -2
  291. package/src/runtime/sync-ops.test.ts +3 -12
  292. package/src/runtime/telemetry-ops.test.ts +31 -6
  293. package/src/runtime/tier-ops.test.ts +159 -0
  294. package/src/runtime/tier-ops.ts +119 -0
  295. package/src/runtime/vault-extra-ops.test.ts +32 -8
  296. package/src/runtime/vault-sharing-ops.test.ts +1 -4
  297. package/src/skills/sync-skills.ts +2 -12
  298. package/src/transport/ws-server.test.ts +7 -4
  299. package/src/vault/__tests__/vault-characterization.test.ts +492 -81
  300. package/src/vault/linking.test.ts +50 -17
  301. package/src/vault/linking.ts +48 -7
  302. package/src/vault/obsidian-sync.test.ts +6 -3
  303. package/src/vault/scope-detector.test.ts +1 -3
  304. package/src/vault/vault-branching.test.ts +9 -7
  305. package/src/vault/vault-entries.ts +209 -65
  306. package/src/vault/vault-maintenance.ts +7 -12
  307. package/src/vault/vault-manager.test.ts +10 -10
  308. package/src/vault/vault-markdown-sync.ts +4 -1
  309. package/src/vault/vault-memories.ts +7 -7
  310. package/src/vault/vault-scaling.test.ts +5 -5
  311. package/src/vault/vault-schema.ts +72 -15
  312. package/src/vault/vault.ts +55 -9
  313. package/src/brain/strength-scorer.ts +0 -404
  314. package/src/engine/index.ts +0 -21
  315. package/src/persona/index.ts +0 -9
  316. package/src/vault/vault-interfaces.ts +0 -56
@@ -6,10 +6,11 @@
6
6
  */
7
7
 
8
8
  import { describe, it, expect, beforeEach, vi } from 'vitest';
9
- import { createVaultFacadeOps } from './vault-facade.js';
9
+ import { createVaultFacadeOps, deprecateOps } from './vault-facade.js';
10
10
  import { captureOps, executeOp } from '../../engine/test-helpers.js';
11
11
  import type { CapturedOp } from '../../engine/test-helpers.js';
12
12
  import type { AgentRuntime } from '../types.js';
13
+ import { resetDeprecationWarnings } from '../deprecation.js';
13
14
 
14
15
  // ─── Mock factories ──────────────────────────────────────────────────
15
16
 
@@ -34,7 +35,9 @@ function makeMockVault() {
34
35
  getRecent: vi.fn().mockReturnValue([]),
35
36
  exportAll: vi.fn().mockReturnValue({ entries: [] }),
36
37
  getAgeReport: vi.fn().mockReturnValue({ buckets: [], oldestTimestamp: null }),
37
- getDb: vi.fn().mockReturnValue({ prepare: vi.fn().mockReturnValue({ all: vi.fn().mockReturnValue([]) }) }),
38
+ getDb: vi
39
+ .fn()
40
+ .mockReturnValue({ prepare: vi.fn().mockReturnValue({ all: vi.fn().mockReturnValue([]) }) }),
38
41
  searchMemories: vi.fn().mockReturnValue([]),
39
42
  isAutoLinkEnabled: vi.fn().mockReturnValue(false),
40
43
  setTemporal: vi.fn().mockReturnValue(true),
@@ -52,17 +55,14 @@ function makeMockVault() {
52
55
 
53
56
  function makeMockBrain() {
54
57
  return {
55
- intelligentSearch: vi.fn().mockResolvedValue([
56
- { id: 'e1', title: 'Result 1', score: 0.9 },
57
- ]),
58
- scanSearch: vi.fn().mockResolvedValue([
59
- { id: 'e1', title: 'Result 1', score: 0.8 },
60
- ]),
61
- loadEntries: vi.fn().mockReturnValue([
62
- { id: 'e1', title: 'Full entry', type: 'pattern' },
63
- ]),
58
+ intelligentSearch: vi.fn().mockResolvedValue([{ id: 'e1', title: 'Result 1', score: 0.9 }]),
59
+ scanSearch: vi.fn().mockResolvedValue([{ id: 'e1', title: 'Result 1', score: 0.8 }]),
60
+ loadEntries: vi.fn().mockReturnValue([{ id: 'e1', title: 'Full entry', type: 'pattern' }]),
64
61
  enrichAndCapture: vi.fn().mockReturnValue({
65
- captured: true, id: 'cap-1', autoTags: ['auto'], duplicate: null,
62
+ captured: true,
63
+ id: 'cap-1',
64
+ autoTags: ['auto'],
65
+ duplicate: null,
66
66
  }),
67
67
  recordFeedback: vi.fn(),
68
68
  };
@@ -72,17 +72,11 @@ function makeMockVaultManager() {
72
72
  return {
73
73
  open: vi.fn(),
74
74
  disconnect: vi.fn().mockReturnValue(true),
75
- listTiers: vi.fn().mockReturnValue([
76
- { tier: 'agent', connected: true, entries: 25 },
77
- ]),
78
- search: vi.fn().mockReturnValue([
79
- { id: 'e1', tier: 'agent', score: 0.9 },
80
- ]),
75
+ listTiers: vi.fn().mockReturnValue([{ tier: 'agent', connected: true, entries: 25 }]),
76
+ search: vi.fn().mockReturnValue([{ id: 'e1', tier: 'agent', score: 0.9 }]),
81
77
  connect: vi.fn(),
82
78
  disconnectNamed: vi.fn().mockReturnValue(true),
83
- listConnected: vi.fn().mockReturnValue([
84
- { name: 'team-shared', priority: 0.5 },
85
- ]),
79
+ listConnected: vi.fn().mockReturnValue([{ name: 'team-shared', priority: 0.5 }]),
86
80
  };
87
81
  }
88
82
 
@@ -175,16 +169,17 @@ describe('vault-facade', () => {
175
169
  it('registers ops from all groups', () => {
176
170
  // The facade includes inline ops + satellite ops from 5 modules.
177
171
  // We check the inline ops explicitly, satellite ops just need to exist.
178
- expect(ops.size).toBeGreaterThan(30);
172
+ expect(ops.size).toBeGreaterThan(20);
179
173
  });
180
174
 
181
175
  it('includes core inline op names', () => {
182
176
  const coreOps = [
183
- 'search', 'load_entries', 'vault_stats', 'list_all', 'export',
184
- 'capture_enriched', 'vault_connect', 'vault_disconnect', 'vault_tiers',
185
- 'vault_search_all', 'vault_connect_source', 'vault_disconnect_source',
186
- 'vault_list_sources', 'vault_branch', 'vault_branch_add',
187
- 'vault_branch_list', 'vault_merge_branch', 'vault_delete_branch',
177
+ 'search',
178
+ 'load_entries',
179
+ 'vault_stats',
180
+ 'list_all',
181
+ 'export',
182
+ 'capture_enriched',
188
183
  ];
189
184
  for (const name of coreOps) {
190
185
  expect(ops.has(name), `missing op: ${name}`).toBe(true);
@@ -193,10 +188,10 @@ describe('vault-facade', () => {
193
188
 
194
189
  it('includes satellite ops', () => {
195
190
  // Spot-check a few ops from each satellite module
196
- expect(ops.has('vault_get')).toBe(true); // vault-extra-ops
191
+ expect(ops.has('vault_get')).toBe(true); // vault-extra-ops
197
192
  expect(ops.has('capture_knowledge')).toBe(true); // capture-ops
198
193
  expect(ops.has('search_intelligent')).toBe(true); // capture-ops
199
- expect(ops.has('link_entries')).toBe(true); // vault-linking-ops
194
+ // link_entries moved to vault-linking-facade
200
195
  });
201
196
 
202
197
  // ─── Auth levels ─────────────────────────────────────────────────
@@ -208,18 +203,6 @@ describe('vault-facade', () => {
208
203
  expect(ops.get('list_all')!.auth).toBe('read');
209
204
  expect(ops.get('export')!.auth).toBe('read');
210
205
  expect(ops.get('capture_enriched')!.auth).toBe('write');
211
- expect(ops.get('vault_connect')!.auth).toBe('admin');
212
- expect(ops.get('vault_disconnect')!.auth).toBe('admin');
213
- expect(ops.get('vault_tiers')!.auth).toBe('read');
214
- expect(ops.get('vault_search_all')!.auth).toBe('read');
215
- expect(ops.get('vault_connect_source')!.auth).toBe('admin');
216
- expect(ops.get('vault_disconnect_source')!.auth).toBe('admin');
217
- expect(ops.get('vault_list_sources')!.auth).toBe('read');
218
- expect(ops.get('vault_branch')!.auth).toBe('write');
219
- expect(ops.get('vault_branch_add')!.auth).toBe('write');
220
- expect(ops.get('vault_branch_list')!.auth).toBe('read');
221
- expect(ops.get('vault_merge_branch')!.auth).toBe('admin');
222
- expect(ops.get('vault_delete_branch')!.auth).toBe('admin');
223
206
  });
224
207
 
225
208
  // ─── search ────────────────────────────────────────────────────────
@@ -230,32 +213,47 @@ describe('vault-facade', () => {
230
213
  expect(result.success).toBe(true);
231
214
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
232
215
  expect(brain.intelligentSearch).toHaveBeenCalledWith('tokens', {
233
- domain: undefined, type: undefined, severity: undefined,
234
- tags: undefined, limit: 10,
216
+ domain: undefined,
217
+ type: undefined,
218
+ severity: undefined,
219
+ tags: undefined,
220
+ limit: 10,
235
221
  });
236
222
  });
237
223
 
238
224
  it('uses scan mode when specified', async () => {
239
225
  const result = await executeOp(ops, 'search', {
240
- query: 'tokens', mode: 'scan',
226
+ query: 'tokens',
227
+ mode: 'scan',
241
228
  });
242
229
  expect(result.success).toBe(true);
243
230
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
244
- expect(brain.scanSearch).toHaveBeenCalledWith('tokens', expect.objectContaining({
245
- limit: 10,
246
- }));
231
+ expect(brain.scanSearch).toHaveBeenCalledWith(
232
+ 'tokens',
233
+ expect.objectContaining({
234
+ limit: 10,
235
+ }),
236
+ );
247
237
  expect(brain.intelligentSearch).not.toHaveBeenCalled();
248
238
  });
249
239
 
250
240
  it('passes all filter params', async () => {
251
241
  await executeOp(ops, 'search', {
252
- query: 'test', domain: 'design', type: 'pattern',
253
- severity: 'critical', tags: ['a11y'], limit: 5, mode: 'full',
242
+ query: 'test',
243
+ domain: 'design',
244
+ type: 'pattern',
245
+ severity: 'critical',
246
+ tags: ['a11y'],
247
+ limit: 5,
248
+ mode: 'full',
254
249
  });
255
250
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
256
251
  expect(brain.intelligentSearch).toHaveBeenCalledWith('test', {
257
- domain: 'design', type: 'pattern', severity: 'critical',
258
- tags: ['a11y'], limit: 5,
252
+ domain: 'design',
253
+ type: 'pattern',
254
+ severity: 'critical',
255
+ tags: ['a11y'],
256
+ limit: 5,
259
257
  });
260
258
  });
261
259
  });
@@ -315,20 +313,26 @@ describe('vault-facade', () => {
315
313
  it('uses default pagination', async () => {
316
314
  await executeOp(ops, 'list_all', {});
317
315
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
318
- expect(vault.list).toHaveBeenCalledWith(
319
- expect.objectContaining({ limit: 20, offset: 0 }),
320
- );
316
+ expect(vault.list).toHaveBeenCalledWith(expect.objectContaining({ limit: 20, offset: 0 }));
321
317
  });
322
318
 
323
319
  it('passes all filter params', async () => {
324
320
  await executeOp(ops, 'list_all', {
325
- domain: 'design', type: 'pattern', severity: 'warning',
326
- tags: ['a11y'], limit: 5, offset: 10,
321
+ domain: 'design',
322
+ type: 'pattern',
323
+ severity: 'warning',
324
+ tags: ['a11y'],
325
+ limit: 5,
326
+ offset: 10,
327
327
  });
328
328
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
329
329
  expect(vault.list).toHaveBeenCalledWith({
330
- domain: 'design', type: 'pattern', severity: 'warning',
331
- tags: ['a11y'], limit: 5, offset: 10,
330
+ domain: 'design',
331
+ type: 'pattern',
332
+ severity: 'warning',
333
+ tags: ['a11y'],
334
+ limit: 5,
335
+ offset: 10,
332
336
  });
333
337
  });
334
338
  });
@@ -359,8 +363,11 @@ describe('vault-facade', () => {
359
363
  describe('capture_enriched', () => {
360
364
  it('captures with LLM enrichment when successful', async () => {
361
365
  const result = await executeOp(ops, 'capture_enriched', {
362
- title: 'Semantic tokens', description: 'Always use semantic tokens',
363
- type: 'pattern', domain: 'design', tags: ['tokens'],
366
+ title: 'Semantic tokens',
367
+ description: 'Always use semantic tokens',
368
+ type: 'pattern',
369
+ domain: 'design',
370
+ tags: ['tokens'],
364
371
  });
365
372
  expect(result.success).toBe(true);
366
373
  const data = result.data as { captured: boolean; enriched: boolean; entryId: string };
@@ -370,10 +377,13 @@ describe('vault-facade', () => {
370
377
 
371
378
  it('falls back to basic capture when enrichment fails', async () => {
372
379
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
373
- brain.enrichAndCapture.mockImplementation(() => { throw new Error('LLM unavailable'); });
380
+ brain.enrichAndCapture.mockImplementation(() => {
381
+ throw new Error('LLM unavailable');
382
+ });
374
383
 
375
384
  const result = await executeOp(ops, 'capture_enriched', {
376
- title: 'Test entry', description: 'A test pattern to avoid problems',
385
+ title: 'Test entry',
386
+ description: 'A test pattern to avoid problems',
377
387
  });
378
388
  expect(result.success).toBe(true);
379
389
  const data = result.data as { captured: boolean; enriched: boolean };
@@ -383,34 +393,37 @@ describe('vault-facade', () => {
383
393
 
384
394
  it('infers anti-pattern type from description keywords', async () => {
385
395
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
386
- brain.enrichAndCapture.mockImplementation(() => { throw new Error('LLM down'); });
396
+ brain.enrichAndCapture.mockImplementation(() => {
397
+ throw new Error('LLM down');
398
+ });
387
399
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
388
400
 
389
401
  await executeOp(ops, 'capture_enriched', {
390
402
  title: 'Avoid inline styles',
391
403
  description: "Don't use inline styles in components",
392
404
  });
393
- expect(vault.add).toHaveBeenCalledWith(
394
- expect.objectContaining({ type: 'anti-pattern' }),
395
- );
405
+ expect(vault.add).toHaveBeenCalledWith(expect.objectContaining({ type: 'anti-pattern' }));
396
406
  });
397
407
 
398
408
  it('infers critical severity from keywords', async () => {
399
409
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
400
- brain.enrichAndCapture.mockImplementation(() => { throw new Error('fail'); });
410
+ brain.enrichAndCapture.mockImplementation(() => {
411
+ throw new Error('fail');
412
+ });
401
413
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
402
414
 
403
415
  await executeOp(ops, 'capture_enriched', {
404
- title: 'Security check', description: 'This is a critical security requirement',
416
+ title: 'Security check',
417
+ description: 'This is a critical security requirement',
405
418
  });
406
- expect(vault.add).toHaveBeenCalledWith(
407
- expect.objectContaining({ severity: 'critical' }),
408
- );
419
+ expect(vault.add).toHaveBeenCalledWith(expect.objectContaining({ severity: 'critical' }));
409
420
  });
410
421
 
411
422
  it('auto-generates tags from title when none provided', async () => {
412
423
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
413
- brain.enrichAndCapture.mockImplementation(() => { throw new Error('fail'); });
424
+ brain.enrichAndCapture.mockImplementation(() => {
425
+ throw new Error('fail');
426
+ });
414
427
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
415
428
 
416
429
  await executeOp(ops, 'capture_enriched', {
@@ -426,12 +439,17 @@ describe('vault-facade', () => {
426
439
 
427
440
  it('returns error on total failure', async () => {
428
441
  const brain = runtime.brain as ReturnType<typeof makeMockBrain>;
429
- brain.enrichAndCapture.mockImplementation(() => { throw new Error('fail'); });
442
+ brain.enrichAndCapture.mockImplementation(() => {
443
+ throw new Error('fail');
444
+ });
430
445
  const vault = runtime.vault as ReturnType<typeof makeMockVault>;
431
- vault.add.mockImplementation(() => { throw new Error('DB error'); });
446
+ vault.add.mockImplementation(() => {
447
+ throw new Error('DB error');
448
+ });
432
449
 
433
450
  const result = await executeOp(ops, 'capture_enriched', {
434
- title: 'Test', description: 'Test',
451
+ title: 'Test',
452
+ description: 'Test',
435
453
  });
436
454
  expect(result.success).toBe(true);
437
455
  const data = result.data as { error: string };
@@ -439,193 +457,107 @@ describe('vault-facade', () => {
439
457
  });
440
458
  });
441
459
 
442
- // ─── Multi-vault ops ──────────────────────────────────────────────
443
-
444
- describe('vault_connect', () => {
445
- it('connects a vault tier', async () => {
446
- const result = await executeOp(ops, 'vault_connect', {
447
- tier: 'project', path: '/tmp/project.db',
448
- });
449
- expect(result.success).toBe(true);
450
- const data = result.data as { connected: boolean; tier: string; path: string };
451
- expect(data.connected).toBe(true);
452
- expect(data.tier).toBe('project');
453
- expect(data.path).toBe('/tmp/project.db');
454
- });
455
- });
456
-
457
- describe('vault_disconnect', () => {
458
- it('disconnects a vault tier', async () => {
459
- const result = await executeOp(ops, 'vault_disconnect', { tier: 'team' });
460
- expect(result.success).toBe(true);
461
- const data = result.data as { disconnected: boolean; tier: string };
462
- expect(data.disconnected).toBe(true);
463
- expect(data.tier).toBe('team');
464
- });
465
- });
466
-
467
- describe('vault_tiers', () => {
468
- it('lists vault tiers', async () => {
469
- const result = await executeOp(ops, 'vault_tiers', {});
470
- expect(result.success).toBe(true);
471
- const data = result.data as { tiers: Array<{ tier: string }> };
472
- expect(data.tiers).toHaveLength(1);
473
- expect(data.tiers[0].tier).toBe('agent');
474
- });
475
- });
460
+ // ─── Obsidian ops ──────────────────────────────────────────────────
461
+ // ObsidianSync is instantiated inside the handler, so we test param passing
462
+ // and that the handler doesn't throw. Full ObsidianSync tests are elsewhere.
476
463
 
477
- describe('vault_search_all', () => {
478
- it('searches across all tiers', async () => {
479
- const result = await executeOp(ops, 'vault_search_all', { query: 'tokens' });
480
- expect(result.success).toBe(true);
481
- const data = result.data as { results: unknown[]; count: number };
482
- expect(data.count).toBe(1);
483
- const vm = runtime.vaultManager as ReturnType<typeof makeMockVaultManager>;
484
- expect(vm.search).toHaveBeenCalledWith('tokens', 20);
485
- });
464
+ // ─── Backward-compat stubs ──────────────────────────────────────────
486
465
 
487
- it('passes custom limit', async () => {
488
- await executeOp(ops, 'vault_search_all', { query: 'test', limit: 5 });
489
- const vm = runtime.vaultManager as ReturnType<typeof makeMockVaultManager>;
490
- expect(vm.search).toHaveBeenCalledWith('test', 5);
466
+ describe('backward-compat deprecated stubs', () => {
467
+ beforeEach(() => {
468
+ resetDeprecationWarnings();
491
469
  });
492
- });
493
-
494
- // ─── Named vault connections ───────────────────────────────────────
495
470
 
496
- describe('vault_connect_source', () => {
497
- it('connects with default priority', async () => {
498
- const result = await executeOp(ops, 'vault_connect_source', {
499
- name: 'team-kb', path: '/tmp/team.db',
500
- });
501
- expect(result.success).toBe(true);
502
- const data = result.data as { connected: boolean; priority: number };
503
- expect(data.connected).toBe(true);
504
- expect(data.priority).toBe(0.5);
471
+ it('includes moved ops from all new facades', () => {
472
+ // Spot-check one op from each moved facade
473
+ const movedOps = [
474
+ 'vault_archive', // archive
475
+ 'vault_git_push', // sync
476
+ 'vault_submit_review', // review
477
+ 'link_entries', // links
478
+ 'vault_branch', // branching
479
+ 'vault_connect', // tier
480
+ ];
481
+ for (const name of movedOps) {
482
+ expect(ops.has(name), `missing compat stub: ${name}`).toBe(true);
483
+ }
505
484
  });
506
485
 
507
- it('connects with custom priority', async () => {
508
- const result = await executeOp(ops, 'vault_connect_source', {
509
- name: 'primary', path: '/tmp/p.db', priority: 1.5,
510
- });
511
- expect(result.success).toBe(true);
512
- const vm = runtime.vaultManager as ReturnType<typeof makeMockVaultManager>;
513
- expect(vm.connect).toHaveBeenCalledWith('primary', '/tmp/p.db', 1.5);
514
- });
515
- });
486
+ it('logs deprecation warning and forwards to real handler', async () => {
487
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
516
488
 
517
- describe('vault_disconnect_source', () => {
518
- it('disconnects a named source', async () => {
519
- const result = await executeOp(ops, 'vault_disconnect_source', {
520
- name: 'team-kb',
489
+ // vault_archive is from archive-facade — call it via vault facade compat
490
+ const result = await executeOp(ops, 'vault_archive', {
491
+ olderThanDays: 90,
521
492
  });
522
493
  expect(result.success).toBe(true);
523
- const data = result.data as { disconnected: boolean; name: string };
524
- expect(data.disconnected).toBe(true);
525
- expect(data.name).toBe('team-kb');
526
- });
527
- });
528
494
 
529
- describe('vault_list_sources', () => {
530
- it('lists connected sources', async () => {
531
- const result = await executeOp(ops, 'vault_list_sources', {});
532
- expect(result.success).toBe(true);
533
- const data = result.data as { sources: Array<{ name: string }> };
534
- expect(data.sources).toHaveLength(1);
535
- expect(data.sources[0].name).toBe('team-shared');
536
- });
537
- });
495
+ // Verify deprecation warning was logged
496
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('[DEPRECATED]'));
497
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('vault_archive'));
498
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('archive'));
538
499
 
539
- // ─── Branching ────────────────────────────────────────────────────
540
-
541
- describe('vault_branch', () => {
542
- it('creates a branch', async () => {
543
- const result = await executeOp(ops, 'vault_branch', { name: 'experiment' });
544
- expect(result.success).toBe(true);
545
- const data = result.data as { created: boolean; name: string };
546
- expect(data.created).toBe(true);
547
- expect(data.name).toBe('experiment');
548
- });
549
-
550
- it('returns error on duplicate branch', async () => {
551
- const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
552
- vb.branch.mockImplementation(() => { throw new Error('Branch already exists'); });
553
- const result = await executeOp(ops, 'vault_branch', { name: 'dup' });
554
- expect(result.success).toBe(true);
555
- const data = result.data as { error: string };
556
- expect(data.error).toBe('Branch already exists');
557
- });
558
- });
500
+ // Verify the real handler was invoked
501
+ const vault = runtime.vault as ReturnType<typeof makeMockVault>;
502
+ expect(vault.archive).toHaveBeenCalled();
559
503
 
560
- describe('vault_branch_add', () => {
561
- it('adds an operation to a branch', async () => {
562
- const result = await executeOp(ops, 'vault_branch_add', {
563
- branchName: 'exp', entryId: 'e1', action: 'add',
564
- entryData: { id: 'e1', title: 'New', type: 'pattern', domain: 'test' },
565
- });
566
- expect(result.success).toBe(true);
567
- const data = result.data as { added: boolean; action: string };
568
- expect(data.added).toBe(true);
569
- expect(data.action).toBe('add');
504
+ warnSpy.mockRestore();
570
505
  });
571
506
 
572
- it('returns error on invalid branch', async () => {
573
- const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
574
- vb.addOperation.mockImplementation(() => { throw new Error('Branch not found'); });
575
- const result = await executeOp(ops, 'vault_branch_add', {
576
- branchName: 'missing', entryId: 'e1', action: 'remove',
577
- });
578
- expect(result.success).toBe(true);
579
- expect((result.data as { error: string }).error).toBe('Branch not found');
580
- });
581
- });
507
+ it('only logs deprecation warning once per op', async () => {
508
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
582
509
 
583
- describe('vault_branch_list', () => {
584
- it('lists all branches', async () => {
585
- const result = await executeOp(ops, 'vault_branch_list', {});
586
- expect(result.success).toBe(true);
587
- const data = result.data as { branches: Array<{ name: string }> };
588
- expect(data.branches).toHaveLength(1);
589
- expect(data.branches[0].name).toBe('experiment');
590
- });
591
- });
510
+ await executeOp(ops, 'vault_archive', { olderThanDays: 30 });
511
+ await executeOp(ops, 'vault_archive', { olderThanDays: 60 });
592
512
 
593
- describe('vault_merge_branch', () => {
594
- it('merges a branch', async () => {
595
- const result = await executeOp(ops, 'vault_merge_branch', {
596
- branchName: 'experiment',
597
- });
598
- expect(result.success).toBe(true);
599
- const data = result.data as { merged: boolean; applied: number };
600
- expect(data.merged).toBe(true);
601
- expect(data.applied).toBe(3);
602
- });
513
+ // deprecationWarning deduplicates by op name
514
+ const archiveWarnings = warnSpy.mock.calls.filter(
515
+ (call) => typeof call[0] === 'string' && call[0].includes('vault_archive'),
516
+ );
517
+ expect(archiveWarnings).toHaveLength(1);
603
518
 
604
- it('returns error on merge failure', async () => {
605
- const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
606
- vb.merge.mockImplementation(() => { throw new Error('Conflict detected'); });
607
- const result = await executeOp(ops, 'vault_merge_branch', {
608
- branchName: 'conflict',
609
- });
610
- expect(result.success).toBe(true);
611
- expect((result.data as { error: string }).error).toBe('Conflict detected');
519
+ warnSpy.mockRestore();
612
520
  });
613
521
  });
614
522
 
615
- describe('vault_delete_branch', () => {
616
- it('deletes a branch', async () => {
617
- const result = await executeOp(ops, 'vault_delete_branch', {
618
- branchName: 'experiment',
619
- });
620
- expect(result.success).toBe(true);
621
- const data = result.data as { deleted: boolean; branchName: string };
622
- expect(data.deleted).toBe(true);
623
- expect(data.branchName).toBe('experiment');
523
+ // ─── deprecateOps utility ───────────────────────────────────────────
524
+
525
+ describe('deprecateOps', () => {
526
+ beforeEach(() => {
527
+ resetDeprecationWarnings();
528
+ });
529
+
530
+ it('preserves op metadata (name, description, auth, schema)', () => {
531
+ const original = [
532
+ {
533
+ name: 'test_op',
534
+ description: 'A test op',
535
+ auth: 'write' as const,
536
+ handler: async () => ({ ok: true }),
537
+ },
538
+ ];
539
+ const wrapped = deprecateOps(original, 'new-facade');
540
+ expect(wrapped).toHaveLength(1);
541
+ expect(wrapped[0].name).toBe('test_op');
542
+ expect(wrapped[0].description).toBe('A test op');
543
+ expect(wrapped[0].auth).toBe('write');
544
+ });
545
+
546
+ it('wraps handler to log warning and return original result', async () => {
547
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
548
+ const original = [
549
+ {
550
+ name: 'moved_op',
551
+ description: 'Moved',
552
+ auth: 'read' as const,
553
+ handler: async () => ({ value: 42 }),
554
+ },
555
+ ];
556
+ const wrapped = deprecateOps(original, 'target-facade');
557
+ const result = await wrapped[0].handler({});
558
+ expect(result).toEqual({ value: 42 });
559
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('target-facade'));
560
+ warnSpy.mockRestore();
624
561
  });
625
562
  });
626
-
627
- // ─── Obsidian ops ──────────────────────────────────────────────────
628
- // ObsidianSync is instantiated inside the handler, so we test param passing
629
- // and that the handler doesn't throw. Full ObsidianSync tests are elsewhere.
630
-
631
563
  });