@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
@@ -25,7 +25,15 @@ const mockAuthManager = {
25
25
  };
26
26
 
27
27
  vi.mock('../../chat/auth-manager.js', () => ({
28
- ChatAuthManager: vi.fn().mockImplementation(() => mockAuthManager),
28
+ ChatAuthManager: class {
29
+ enabled = mockAuthManager.enabled;
30
+ authenticatedCount = mockAuthManager.authenticatedCount;
31
+ isAuthenticated = mockAuthManager.isAuthenticated;
32
+ isLockedOut = mockAuthManager.isLockedOut;
33
+ authenticate = mockAuthManager.authenticate;
34
+ revoke = mockAuthManager.revoke;
35
+ listAuthenticated = mockAuthManager.listAuthenticated;
36
+ },
29
37
  }));
30
38
 
31
39
  const mockBridge = {
@@ -36,13 +44,18 @@ const mockBridge = {
36
44
  };
37
45
 
38
46
  vi.mock('../../chat/mcp-bridge.js', () => ({
39
- McpToolBridge: vi.fn().mockImplementation(() => mockBridge),
47
+ McpToolBridge: class {
48
+ size = mockBridge.size;
49
+ register = mockBridge.register;
50
+ listTools = mockBridge.listTools;
51
+ execute = mockBridge.execute;
52
+ },
40
53
  }));
41
54
 
42
55
  vi.mock('../../chat/output-compressor.js', () => ({
43
- createOutputCompressor: vi.fn().mockReturnValue(
44
- (_name: string, output: string, _max?: number) => output.slice(0, 10),
45
- ),
56
+ createOutputCompressor: vi
57
+ .fn()
58
+ .mockReturnValue((_name: string, output: string, _max?: number) => output.slice(0, 10)),
46
59
  }));
47
60
 
48
61
  vi.mock('../../chat/voice.js', () => ({
@@ -63,7 +76,14 @@ const mockQueue = {
63
76
  };
64
77
 
65
78
  vi.mock('../../chat/queue.js', () => ({
66
- MessageQueue: vi.fn().mockImplementation(() => mockQueue),
79
+ MessageQueue: class {
80
+ inboxCount = mockQueue.inboxCount;
81
+ outboxCount = mockQueue.outboxCount;
82
+ readInbox = mockQueue.readInbox;
83
+ formatInbox = mockQueue.formatInbox;
84
+ sendResponse = mockQueue.sendResponse;
85
+ drainOutbox = mockQueue.drainOutbox;
86
+ },
67
87
  }));
68
88
 
69
89
  // Needed via chat-state imports
@@ -95,12 +115,22 @@ describe('chat-transport-ops', () => {
95
115
  const names = ops.map((o) => o.name);
96
116
  expect(names).toEqual([
97
117
  'chat_chunk_response',
98
- 'chat_auth_init', 'chat_auth_check', 'chat_auth_authenticate',
99
- 'chat_auth_revoke', 'chat_auth_status',
100
- 'chat_bridge_init', 'chat_bridge_register', 'chat_bridge_list', 'chat_bridge_execute',
118
+ 'chat_auth_init',
119
+ 'chat_auth_check',
120
+ 'chat_auth_authenticate',
121
+ 'chat_auth_revoke',
122
+ 'chat_auth_status',
123
+ 'chat_bridge_init',
124
+ 'chat_bridge_register',
125
+ 'chat_bridge_list',
126
+ 'chat_bridge_execute',
101
127
  'chat_compress_output',
102
- 'chat_voice_transcribe', 'chat_voice_synthesize',
103
- 'chat_queue_init', 'chat_queue_inbox', 'chat_queue_reply', 'chat_queue_drain',
128
+ 'chat_voice_transcribe',
129
+ 'chat_voice_synthesize',
130
+ 'chat_queue_init',
131
+ 'chat_queue_inbox',
132
+ 'chat_queue_reply',
133
+ 'chat_queue_drain',
104
134
  ]);
105
135
  });
106
136
 
@@ -109,7 +139,10 @@ describe('chat-transport-ops', () => {
109
139
  describe('chat_chunk_response', () => {
110
140
  it('chunks text and returns result', async () => {
111
141
  const op = findOp(ops, 'chat_chunk_response');
112
- const result = (await op.handler({ text: 'hello world' })) as { chunks: string[]; count: number };
142
+ const result = (await op.handler({ text: 'hello world' })) as {
143
+ chunks: string[];
144
+ count: number;
145
+ };
113
146
  expect(result.chunks).toEqual(['chunk1', 'chunk2']);
114
147
  expect(result.count).toBe(2);
115
148
  });
@@ -130,7 +163,10 @@ describe('chat-transport-ops', () => {
130
163
 
131
164
  describe('chat_auth_check', () => {
132
165
  it('checks authentication status', async () => {
133
- const result = await findOp(ops, 'chat_auth_check').handler({ userId: 'u1', storagePath: '/tmp/auth.json' });
166
+ const result = await findOp(ops, 'chat_auth_check').handler({
167
+ userId: 'u1',
168
+ storagePath: '/tmp/auth.json',
169
+ });
134
170
  expect(result).toEqual({ userId: 'u1', authenticated: true, lockedOut: false });
135
171
  });
136
172
  });
@@ -138,7 +174,9 @@ describe('chat-transport-ops', () => {
138
174
  describe('chat_auth_authenticate', () => {
139
175
  it('authenticates user with passphrase', async () => {
140
176
  const result = await findOp(ops, 'chat_auth_authenticate').handler({
141
- userId: 'u1', passphrase: 'secret', storagePath: '/tmp/auth.json',
177
+ userId: 'u1',
178
+ passphrase: 'secret',
179
+ storagePath: '/tmp/auth.json',
142
180
  });
143
181
  expect(result).toEqual({ userId: 'u1', success: true, lockedOut: false });
144
182
  expect(mockAuthManager.authenticate).toHaveBeenCalledWith('u1', 'secret');
@@ -147,16 +185,22 @@ describe('chat-transport-ops', () => {
147
185
 
148
186
  describe('chat_auth_revoke', () => {
149
187
  it('revokes authentication', async () => {
150
- const result = await findOp(ops, 'chat_auth_revoke').handler({ userId: 'u1', storagePath: '/tmp/auth.json' });
188
+ const result = await findOp(ops, 'chat_auth_revoke').handler({
189
+ userId: 'u1',
190
+ storagePath: '/tmp/auth.json',
191
+ });
151
192
  expect(result).toEqual({ revoked: true, userId: 'u1' });
152
193
  });
153
194
  });
154
195
 
155
196
  describe('chat_auth_status', () => {
156
197
  it('returns auth status', async () => {
157
- const result = await findOp(ops, 'chat_auth_status').handler({ storagePath: '/tmp/auth.json' });
198
+ const result = await findOp(ops, 'chat_auth_status').handler({
199
+ storagePath: '/tmp/auth.json',
200
+ });
158
201
  expect(result).toEqual({
159
- enabled: true, authenticatedCount: 1,
202
+ enabled: true,
203
+ authenticatedCount: 1,
160
204
  authenticatedUsers: [{ userId: 'u1', authenticatedAt: 1000 }],
161
205
  });
162
206
  });
@@ -174,7 +218,9 @@ describe('chat-transport-ops', () => {
174
218
  describe('chat_bridge_register', () => {
175
219
  it('registers a tool', async () => {
176
220
  const result = await findOp(ops, 'chat_bridge_register').handler({
177
- name: 'my-tool', description: 'A tool', inputSchema: { type: 'object' },
221
+ name: 'my-tool',
222
+ description: 'A tool',
223
+ inputSchema: { type: 'object' },
178
224
  });
179
225
  expect(result).toEqual({ registered: true, name: 'my-tool', totalTools: 1 });
180
226
  });
@@ -187,27 +233,34 @@ describe('chat-transport-ops', () => {
187
233
 
188
234
  it('returns tools after init', async () => {
189
235
  await findOp(ops, 'chat_bridge_init').handler({});
190
- expect(await findOp(ops, 'chat_bridge_list').handler({})).toEqual({ tools: [{ name: 'tool1' }], count: 1 });
236
+ expect(await findOp(ops, 'chat_bridge_list').handler({})).toEqual({
237
+ tools: [{ name: 'tool1' }],
238
+ count: 1,
239
+ });
191
240
  });
192
241
  });
193
242
 
194
243
  describe('chat_bridge_execute', () => {
195
244
  it('returns error when not initialized', async () => {
196
- expect(await findOp(ops, 'chat_bridge_execute').handler({ name: 'tool1' }))
197
- .toEqual({ output: 'Bridge not initialized', isError: true });
245
+ expect(await findOp(ops, 'chat_bridge_execute').handler({ name: 'tool1' })).toEqual({
246
+ output: 'Bridge not initialized',
247
+ isError: true,
248
+ });
198
249
  });
199
250
 
200
251
  it('executes tool after init', async () => {
201
252
  await findOp(ops, 'chat_bridge_init').handler({});
202
- expect(await findOp(ops, 'chat_bridge_execute').handler({ name: 'tool1', input: { a: 1 } }))
203
- .toEqual({ output: 'result' });
253
+ expect(
254
+ await findOp(ops, 'chat_bridge_execute').handler({ name: 'tool1', input: { a: 1 } }),
255
+ ).toEqual({ output: 'result' });
204
256
  });
205
257
  });
206
258
 
207
259
  describe('chat_compress_output', () => {
208
260
  it('compresses output', async () => {
209
261
  const result = (await findOp(ops, 'chat_compress_output').handler({
210
- toolName: 'test', output: 'long output text here',
262
+ toolName: 'test',
263
+ output: 'long output text here',
211
264
  })) as { compressed: string; originalLength: number; compressedLength: number };
212
265
  expect(result.originalLength).toBe(21);
213
266
  expect(result.compressedLength).toBe(10);
@@ -219,7 +272,8 @@ describe('chat-transport-ops', () => {
219
272
  describe('chat_voice_transcribe', () => {
220
273
  it('transcribes audio', async () => {
221
274
  const result = await findOp(ops, 'chat_voice_transcribe').handler({
222
- audioBase64: Buffer.from('test').toString('base64'), openaiApiKey: 'key-123',
275
+ audioBase64: Buffer.from('test').toString('base64'),
276
+ openaiApiKey: 'key-123',
223
277
  });
224
278
  expect(result).toEqual({ text: 'hello world', language: 'en' });
225
279
  });
@@ -228,7 +282,8 @@ describe('chat-transport-ops', () => {
228
282
  describe('chat_voice_synthesize', () => {
229
283
  it('synthesizes speech', async () => {
230
284
  const result = (await findOp(ops, 'chat_voice_synthesize').handler({
231
- text: 'hello', openaiApiKey: 'key-123',
285
+ text: 'hello',
286
+ openaiApiKey: 'key-123',
232
287
  })) as Record<string, unknown>;
233
288
  expect(result.success).toBe(true);
234
289
  expect(result.audioBase64).toBeDefined();
@@ -239,14 +294,19 @@ describe('chat-transport-ops', () => {
239
294
 
240
295
  describe('chat_queue_init', () => {
241
296
  it('initializes queue', async () => {
242
- expect(await findOp(ops, 'chat_queue_init').handler({ queueDir: '/tmp/queue' }))
243
- .toEqual({ initialized: true, inbox: 2, outbox: 1 });
297
+ expect(await findOp(ops, 'chat_queue_init').handler({ queueDir: '/tmp/queue' })).toEqual({
298
+ initialized: true,
299
+ inbox: 2,
300
+ outbox: 1,
301
+ });
244
302
  });
245
303
  });
246
304
 
247
305
  describe('chat_queue_inbox', () => {
248
306
  it('reads inbox', async () => {
249
- const result = (await findOp(ops, 'chat_queue_inbox').handler({ queueDir: '/tmp/queue' })) as Record<string, unknown>;
307
+ const result = (await findOp(ops, 'chat_queue_inbox').handler({
308
+ queueDir: '/tmp/queue',
309
+ })) as Record<string, unknown>;
250
310
  expect(result.count).toBe(1);
251
311
  expect(result.formatted).toBe('formatted');
252
312
  });
@@ -254,16 +314,23 @@ describe('chat-transport-ops', () => {
254
314
 
255
315
  describe('chat_queue_reply', () => {
256
316
  it('sends reply', async () => {
257
- expect(await findOp(ops, 'chat_queue_reply').handler({
258
- messageId: 'm1', chatId: 'chat-1', text: 'response', queueDir: '/tmp/queue',
259
- })).toEqual({ sent: true, response: { id: 'r1' } });
317
+ expect(
318
+ await findOp(ops, 'chat_queue_reply').handler({
319
+ messageId: 'm1',
320
+ chatId: 'chat-1',
321
+ text: 'response',
322
+ queueDir: '/tmp/queue',
323
+ }),
324
+ ).toEqual({ sent: true, response: { id: 'r1' } });
260
325
  });
261
326
  });
262
327
 
263
328
  describe('chat_queue_drain', () => {
264
329
  it('drains outbox', async () => {
265
- expect(await findOp(ops, 'chat_queue_drain').handler({ queueDir: '/tmp/queue' }))
266
- .toEqual({ responses: [{ id: 'r1' }], count: 1 });
330
+ expect(await findOp(ops, 'chat_queue_drain').handler({ queueDir: '/tmp/queue' })).toEqual({
331
+ responses: [{ id: 'r1' }],
332
+ count: 1,
333
+ });
267
334
  });
268
335
  });
269
336
  });
@@ -375,6 +375,5 @@ export function createChatTransportOps(state: ChatState): OpDefinition[] {
375
375
  return { responses, count: responses.length };
376
376
  },
377
377
  },
378
-
379
378
  ];
380
379
  }
@@ -21,7 +21,14 @@ function makeMockContextEngine() {
21
21
  total: 1,
22
22
  }),
23
23
  analyze: vi.fn().mockReturnValue({
24
- entities: { files: ['src/app.ts'], functions: [], domains: ['general'], actions: ['build'], technologies: [], patterns: [] },
24
+ entities: {
25
+ files: ['src/app.ts'],
26
+ functions: [],
27
+ domains: ['general'],
28
+ actions: ['build'],
29
+ technologies: [],
30
+ patterns: [],
31
+ },
25
32
  knowledge: { items: [], total: 0 },
26
33
  confidence: 0.7,
27
34
  detectedDomains: ['general'],
@@ -47,7 +54,11 @@ describe('context-facade', () => {
47
54
  it('registers all 3 ops', () => {
48
55
  expect(ops.size).toBe(3);
49
56
  expect([...ops.keys()]).toEqual(
50
- expect.arrayContaining(['context_extract_entities', 'context_retrieve_knowledge', 'context_analyze']),
57
+ expect.arrayContaining([
58
+ 'context_extract_entities',
59
+ 'context_retrieve_knowledge',
60
+ 'context_analyze',
61
+ ]),
51
62
  );
52
63
  });
53
64
 
@@ -74,7 +85,9 @@ describe('context-facade', () => {
74
85
  // ─── context_retrieve_knowledge ────────────────────────────────
75
86
 
76
87
  it('context_retrieve_knowledge calls engine with prompt', async () => {
77
- const result = await executeOp(ops, 'context_retrieve_knowledge', { prompt: 'contrast patterns' });
88
+ const result = await executeOp(ops, 'context_retrieve_knowledge', {
89
+ prompt: 'contrast patterns',
90
+ });
78
91
  expect(result.success).toBe(true);
79
92
  expect(mockEngine.retrieveKnowledge).toHaveBeenCalledWith('contrast patterns', undefined);
80
93
  });
@@ -100,7 +113,9 @@ describe('context-facade', () => {
100
113
  });
101
114
 
102
115
  it('context_analyze propagates engine errors', async () => {
103
- mockEngine.analyze.mockImplementation(() => { throw new Error('Engine failure'); });
116
+ mockEngine.analyze.mockImplementation(() => {
117
+ throw new Error('Engine failure');
118
+ });
104
119
  const result = await executeOp(ops, 'context_analyze', { prompt: 'fail' });
105
120
  expect(result.success).toBe(false);
106
121
  expect(result.error).toContain('Engine failure');
@@ -402,9 +402,9 @@ describe('createControlFacadeOps', () => {
402
402
 
403
403
  describe('routing_feedback', () => {
404
404
  it('records feedback', async () => {
405
- vi.mocked(runtime.intentRouter.recordRoutingFeedback).mockReturnValue(
406
- { recorded: true } as never,
407
- );
405
+ vi.mocked(runtime.intentRouter.recordRoutingFeedback).mockReturnValue({
406
+ recorded: true,
407
+ } as never);
408
408
 
409
409
  const result = await findOp(ops, 'routing_feedback').handler({
410
410
  initialIntent: 'BUILD',
@@ -20,6 +20,13 @@ import { createContextFacadeOps } from './context-facade.js';
20
20
  import { createAgencyFacadeOps } from './agency-facade.js';
21
21
  import { createChatFacadeOps } from './chat-facade.js';
22
22
  import { createOperatorFacadeOps } from './operator-facade.js';
23
+ import { createArchiveFacadeOps } from './archive-facade.js';
24
+ import { createSyncFacadeOps } from './sync-facade.js';
25
+ import { createReviewFacadeOps } from './review-facade.js';
26
+ import { createIntakeFacadeOps } from './intake-facade.js';
27
+ import { createLinksFacadeOps } from './links-facade.js';
28
+ import { createBranchingFacadeOps } from './branching-facade.js';
29
+ import { createTierFacadeOps } from './tier-facade.js';
23
30
 
24
31
  export function createSemanticFacades(runtime: AgentRuntime, agentId: string): FacadeConfig[] {
25
32
  const facades: FacadeConfig[] = [
@@ -91,6 +98,41 @@ export function createSemanticFacades(runtime: AgentRuntime, agentId: string): F
91
98
  description: 'Operator profile — personality learning, signals, adaptation.',
92
99
  ops: createOperatorFacadeOps(runtime),
93
100
  },
101
+ {
102
+ name: `${agentId}_archive`,
103
+ description: 'Archival, lifecycle, and knowledge maintenance.',
104
+ ops: createArchiveFacadeOps(runtime),
105
+ },
106
+ {
107
+ name: `${agentId}_sync`,
108
+ description: 'Git, Obsidian, and pack sync operations.',
109
+ ops: createSyncFacadeOps(runtime),
110
+ },
111
+ {
112
+ name: `${agentId}_review`,
113
+ description: 'Knowledge review workflow.',
114
+ ops: createReviewFacadeOps(runtime),
115
+ },
116
+ {
117
+ name: `${agentId}_intake`,
118
+ description: 'Content ingestion — books, URLs, text, batch import.',
119
+ ops: createIntakeFacadeOps(runtime),
120
+ },
121
+ {
122
+ name: `${agentId}_links`,
123
+ description: 'Entry linking — create, traverse, suggest, orphan detection.',
124
+ ops: createLinksFacadeOps(runtime),
125
+ },
126
+ {
127
+ name: `${agentId}_branching`,
128
+ description: 'Vault branching — create, list, merge, delete branches.',
129
+ ops: createBranchingFacadeOps(runtime),
130
+ },
131
+ {
132
+ name: `${agentId}_tier`,
133
+ description: 'Multi-vault tiers — connect, disconnect, search across sources.',
134
+ ops: createTierFacadeOps(runtime),
135
+ },
94
136
  ];
95
137
 
96
138
  return facades;
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Colocated contract tests for intake-facade.ts.
3
+ * Verifies that createIntakeFacadeOps correctly delegates to createIntakeOps
4
+ * via the AgentRuntime. Detailed handler tests live in intake-ops.test.ts.
5
+ */
6
+
7
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
8
+ import { createIntakeFacadeOps } from './intake-facade.js';
9
+ import { captureOps, executeOp } from '../../engine/test-helpers.js';
10
+ import type { CapturedOp } from '../../engine/test-helpers.js';
11
+ import type { AgentRuntime } from '../types.js';
12
+
13
+ // ─── Mock factories ──────────────────────────────────────────────────
14
+
15
+ function makeMockIntakePipeline() {
16
+ return {
17
+ ingestBook: vi.fn().mockResolvedValue({ jobId: 'j1', chunks: 5 }),
18
+ processChunks: vi.fn().mockResolvedValue({ processed: 3, stored: 2 }),
19
+ getJob: vi.fn().mockReturnValue({ id: 'j1', status: 'active' }),
20
+ getChunks: vi.fn().mockReturnValue([{ id: 'c1' }, { id: 'c2' }]),
21
+ listJobs: vi.fn().mockReturnValue([{ id: 'j1' }, { id: 'j2' }]),
22
+ preview: vi.fn().mockResolvedValue({ items: [{ text: 'sample' }] }),
23
+ };
24
+ }
25
+
26
+ function makeMockTextIngester() {
27
+ return {
28
+ ingestUrl: vi.fn().mockResolvedValue({ ingested: 3, duplicates: 1 }),
29
+ ingestText: vi.fn().mockResolvedValue({ ingested: 2, duplicates: 0 }),
30
+ ingestBatch: vi.fn().mockResolvedValue({ total: 4, ingested: 3, duplicates: 1 }),
31
+ };
32
+ }
33
+
34
+ function makeRuntime(overrides: Partial<Record<string, unknown>> = {}): AgentRuntime {
35
+ return {
36
+ intakePipeline: makeMockIntakePipeline(),
37
+ textIngester: makeMockTextIngester(),
38
+ ...overrides,
39
+ } as unknown as AgentRuntime;
40
+ }
41
+
42
+ // ─── Tests ────────────────────────────────────────────────────────────
43
+
44
+ describe('intake-facade', () => {
45
+ let runtime: AgentRuntime;
46
+ let ops: Map<string, CapturedOp>;
47
+
48
+ beforeEach(() => {
49
+ runtime = makeRuntime();
50
+ ops = captureOps(createIntakeFacadeOps(runtime));
51
+ });
52
+
53
+ // ─── Registration ─────────────────────────────────────────────────
54
+
55
+ it('returns exactly 7 ops', () => {
56
+ expect(ops.size).toBe(7);
57
+ });
58
+
59
+ it('includes all expected op names', () => {
60
+ const expected = [
61
+ 'intake_ingest_book',
62
+ 'intake_process',
63
+ 'intake_status',
64
+ 'intake_preview',
65
+ 'ingest_url',
66
+ 'ingest_text',
67
+ 'ingest_batch',
68
+ ];
69
+ for (const name of expected) {
70
+ expect(ops.has(name), `missing op: ${name}`).toBe(true);
71
+ }
72
+ });
73
+
74
+ // ─── Auth levels ─────────────────────────────────────────────────
75
+
76
+ it('has correct auth levels', () => {
77
+ expect(ops.get('intake_ingest_book')!.auth).toBe('write');
78
+ expect(ops.get('intake_process')!.auth).toBe('write');
79
+ expect(ops.get('intake_status')!.auth).toBe('read');
80
+ expect(ops.get('intake_preview')!.auth).toBe('read');
81
+ expect(ops.get('ingest_url')!.auth).toBe('write');
82
+ expect(ops.get('ingest_text')!.auth).toBe('write');
83
+ expect(ops.get('ingest_batch')!.auth).toBe('write');
84
+ });
85
+
86
+ // ─── Delegation ─────────────────────────────────────────────────
87
+
88
+ describe('intake_ingest_book', () => {
89
+ it('delegates to pipeline.ingestBook', async () => {
90
+ const result = await executeOp(ops, 'intake_ingest_book', {
91
+ pdfPath: '/book.pdf',
92
+ title: 'My Book',
93
+ domain: 'design',
94
+ });
95
+ expect(result.success).toBe(true);
96
+ const pipeline = runtime.intakePipeline as ReturnType<typeof makeMockIntakePipeline>;
97
+ expect(pipeline.ingestBook).toHaveBeenCalled();
98
+ });
99
+ });
100
+
101
+ describe('intake_process', () => {
102
+ it('delegates to pipeline.processChunks', async () => {
103
+ const result = await executeOp(ops, 'intake_process', { jobId: 'j1' });
104
+ expect(result.success).toBe(true);
105
+ const pipeline = runtime.intakePipeline as ReturnType<typeof makeMockIntakePipeline>;
106
+ expect(pipeline.processChunks).toHaveBeenCalledWith('j1', undefined);
107
+ });
108
+ });
109
+
110
+ describe('intake_status', () => {
111
+ it('returns job and chunks when jobId provided', async () => {
112
+ const result = await executeOp(ops, 'intake_status', { jobId: 'j1' });
113
+ expect(result.success).toBe(true);
114
+ const data = result.data as { job: { id: string }; chunks: unknown[] };
115
+ expect(data.job.id).toBe('j1');
116
+ expect(data.chunks).toHaveLength(2);
117
+ });
118
+
119
+ it('lists all jobs when no jobId', async () => {
120
+ const result = await executeOp(ops, 'intake_status', {});
121
+ expect(result.success).toBe(true);
122
+ const data = result.data as { jobs: unknown[] };
123
+ expect(data.jobs).toHaveLength(2);
124
+ });
125
+ });
126
+
127
+ describe('intake_preview', () => {
128
+ it('delegates to pipeline.preview', async () => {
129
+ const result = await executeOp(ops, 'intake_preview', {
130
+ pdfPath: '/x.pdf',
131
+ title: 'T',
132
+ domain: 'd',
133
+ pageStart: 1,
134
+ pageEnd: 10,
135
+ });
136
+ expect(result.success).toBe(true);
137
+ const pipeline = runtime.intakePipeline as ReturnType<typeof makeMockIntakePipeline>;
138
+ expect(pipeline.preview).toHaveBeenCalledWith(
139
+ { pdfPath: '/x.pdf', title: 'T', domain: 'd' },
140
+ 1,
141
+ 10,
142
+ );
143
+ });
144
+ });
145
+
146
+ describe('ingest_url', () => {
147
+ it('delegates to textIngester.ingestUrl', async () => {
148
+ const result = await executeOp(ops, 'ingest_url', {
149
+ url: 'https://example.com',
150
+ domain: 'test',
151
+ tags: ['t1'],
152
+ });
153
+ expect(result.success).toBe(true);
154
+ const ingester = runtime.textIngester as ReturnType<typeof makeMockTextIngester>;
155
+ expect(ingester.ingestUrl).toHaveBeenCalledWith('https://example.com', {
156
+ domain: 'test',
157
+ tags: ['t1'],
158
+ });
159
+ });
160
+ });
161
+
162
+ describe('ingest_text', () => {
163
+ it('delegates to textIngester.ingestText', async () => {
164
+ const result = await executeOp(ops, 'ingest_text', {
165
+ text: 'content',
166
+ title: 'My Notes',
167
+ sourceType: 'transcript',
168
+ });
169
+ expect(result.success).toBe(true);
170
+ const ingester = runtime.textIngester as ReturnType<typeof makeMockTextIngester>;
171
+ expect(ingester.ingestText).toHaveBeenCalled();
172
+ });
173
+ });
174
+
175
+ describe('ingest_batch', () => {
176
+ it('delegates to textIngester.ingestBatch', async () => {
177
+ const result = await executeOp(ops, 'ingest_batch', {
178
+ items: [{ text: 'a', title: 'A' }],
179
+ });
180
+ expect(result.success).toBe(true);
181
+ const ingester = runtime.textIngester as ReturnType<typeof makeMockTextIngester>;
182
+ expect(ingester.ingestBatch).toHaveBeenCalled();
183
+ });
184
+ });
185
+
186
+ // ─── Graceful degradation ──────────────────────────────────────────
187
+
188
+ describe('when pipeline is null', () => {
189
+ it('intake ops return error', async () => {
190
+ const rt = makeRuntime({ intakePipeline: null });
191
+ const nullOps = captureOps(createIntakeFacadeOps(rt));
192
+ const result = await executeOp(nullOps, 'intake_ingest_book', {
193
+ pdfPath: '/x.pdf',
194
+ title: 'T',
195
+ domain: 'd',
196
+ });
197
+ expect(result.success).toBe(true);
198
+ const data = result.data as { error: string };
199
+ expect(data.error).toBe('Intake pipeline not configured');
200
+ });
201
+ });
202
+
203
+ describe('when textIngester is null', () => {
204
+ it('ingest ops return error', async () => {
205
+ const rt = makeRuntime({ textIngester: null });
206
+ const nullOps = captureOps(createIntakeFacadeOps(rt));
207
+ const result = await executeOp(nullOps, 'ingest_url', {
208
+ url: 'https://example.com',
209
+ });
210
+ expect(result.success).toBe(true);
211
+ const data = result.data as { error: string };
212
+ expect(data.error).toContain('Text ingester not configured');
213
+ });
214
+ });
215
+ });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Intake facade — content ingestion ops.
3
+ * intake_ingest_book, intake_process, intake_status, intake_preview,
4
+ * ingest_url, ingest_text, ingest_batch.
5
+ */
6
+
7
+ import type { OpDefinition } from '../../facades/types.js';
8
+ import type { AgentRuntime } from '../types.js';
9
+ import { createIntakeOps } from '../intake-ops.js';
10
+
11
+ export function createIntakeFacadeOps(runtime: AgentRuntime): OpDefinition[] {
12
+ const { intakePipeline, textIngester } = runtime;
13
+ return createIntakeOps(intakePipeline, textIngester);
14
+ }