@soleri/core 9.2.0 → 9.3.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 (298) 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.map +1 -1
  14. package/dist/engine/module-manifest.js +21 -1
  15. package/dist/engine/module-manifest.js.map +1 -1
  16. package/dist/engine/register-engine.d.ts.map +1 -1
  17. package/dist/engine/register-engine.js +25 -1
  18. package/dist/engine/register-engine.js.map +1 -1
  19. package/dist/flows/gate-evaluator.js.map +1 -1
  20. package/dist/operator/operator-profile.d.ts.map +1 -1
  21. package/dist/operator/operator-profile.js +11 -5
  22. package/dist/operator/operator-profile.js.map +1 -1
  23. package/dist/operator/operator-signals.d.ts.map +1 -1
  24. package/dist/operator/operator-signals.js.map +1 -1
  25. package/dist/planning/evidence-collector.js.map +1 -1
  26. package/dist/planning/gap-passes.d.ts.map +1 -1
  27. package/dist/planning/gap-passes.js +23 -6
  28. package/dist/planning/gap-passes.js.map +1 -1
  29. package/dist/planning/gap-patterns.d.ts.map +1 -1
  30. package/dist/planning/gap-patterns.js +57 -11
  31. package/dist/planning/gap-patterns.js.map +1 -1
  32. package/dist/planning/github-projection.d.ts.map +1 -1
  33. package/dist/planning/github-projection.js +39 -20
  34. package/dist/planning/github-projection.js.map +1 -1
  35. package/dist/planning/impact-analyzer.d.ts.map +1 -1
  36. package/dist/planning/impact-analyzer.js +20 -18
  37. package/dist/planning/impact-analyzer.js.map +1 -1
  38. package/dist/planning/plan-lifecycle.d.ts.map +1 -1
  39. package/dist/planning/plan-lifecycle.js +22 -9
  40. package/dist/planning/plan-lifecycle.js.map +1 -1
  41. package/dist/planning/planner.d.ts.map +1 -1
  42. package/dist/planning/planner.js +60 -17
  43. package/dist/planning/planner.js.map +1 -1
  44. package/dist/planning/rationalization-detector.d.ts.map +1 -1
  45. package/dist/planning/rationalization-detector.js.map +1 -1
  46. package/dist/planning/reconciliation-engine.d.ts.map +1 -1
  47. package/dist/planning/reconciliation-engine.js.map +1 -1
  48. package/dist/planning/task-verifier.d.ts.map +1 -1
  49. package/dist/planning/task-verifier.js +14 -6
  50. package/dist/planning/task-verifier.js.map +1 -1
  51. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  52. package/dist/runtime/admin-setup-ops.js +2 -1
  53. package/dist/runtime/admin-setup-ops.js.map +1 -1
  54. package/dist/runtime/branching-ops.d.ts +12 -0
  55. package/dist/runtime/branching-ops.d.ts.map +1 -0
  56. package/dist/runtime/branching-ops.js +100 -0
  57. package/dist/runtime/branching-ops.js.map +1 -0
  58. package/dist/runtime/context-health.d.ts.map +1 -1
  59. package/dist/runtime/context-health.js.map +1 -1
  60. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  61. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  62. package/dist/runtime/facades/branching-facade.js +8 -0
  63. package/dist/runtime/facades/branching-facade.js.map +1 -0
  64. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -1
  65. package/dist/runtime/facades/chat-service-ops.js +3 -1
  66. package/dist/runtime/facades/chat-service-ops.js.map +1 -1
  67. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -1
  68. package/dist/runtime/facades/chat-transport-ops.js.map +1 -1
  69. package/dist/runtime/facades/index.d.ts.map +1 -1
  70. package/dist/runtime/facades/index.js +42 -0
  71. package/dist/runtime/facades/index.js.map +1 -1
  72. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  73. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  74. package/dist/runtime/facades/intake-facade.js +11 -0
  75. package/dist/runtime/facades/intake-facade.js.map +1 -0
  76. package/dist/runtime/facades/links-facade.d.ts +9 -0
  77. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  78. package/dist/runtime/facades/links-facade.js +10 -0
  79. package/dist/runtime/facades/links-facade.js.map +1 -0
  80. package/dist/runtime/facades/operator-facade.d.ts.map +1 -1
  81. package/dist/runtime/facades/operator-facade.js.map +1 -1
  82. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  83. package/dist/runtime/facades/plan-facade.js +4 -1
  84. package/dist/runtime/facades/plan-facade.js.map +1 -1
  85. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  86. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  87. package/dist/runtime/facades/tier-facade.js +8 -0
  88. package/dist/runtime/facades/tier-facade.js.map +1 -0
  89. package/dist/runtime/facades/vault-facade.d.ts +9 -1
  90. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  91. package/dist/runtime/facades/vault-facade.js +44 -187
  92. package/dist/runtime/facades/vault-facade.js.map +1 -1
  93. package/dist/runtime/github-integration.d.ts.map +1 -1
  94. package/dist/runtime/github-integration.js +11 -4
  95. package/dist/runtime/github-integration.js.map +1 -1
  96. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  97. package/dist/runtime/orchestrate-ops.js +32 -10
  98. package/dist/runtime/orchestrate-ops.js.map +1 -1
  99. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  100. package/dist/runtime/planning-extra-ops.js.map +1 -1
  101. package/dist/runtime/runtime.d.ts.map +1 -1
  102. package/dist/runtime/runtime.js +3 -1
  103. package/dist/runtime/runtime.js.map +1 -1
  104. package/dist/runtime/session-briefing.d.ts.map +1 -1
  105. package/dist/runtime/session-briefing.js +5 -1
  106. package/dist/runtime/session-briefing.js.map +1 -1
  107. package/dist/runtime/tier-ops.d.ts +13 -0
  108. package/dist/runtime/tier-ops.d.ts.map +1 -0
  109. package/dist/runtime/tier-ops.js +110 -0
  110. package/dist/runtime/tier-ops.js.map +1 -0
  111. package/dist/skills/sync-skills.d.ts.map +1 -1
  112. package/dist/skills/sync-skills.js +1 -1
  113. package/dist/skills/sync-skills.js.map +1 -1
  114. package/dist/vault/linking.d.ts.map +1 -1
  115. package/dist/vault/linking.js +41 -5
  116. package/dist/vault/linking.js.map +1 -1
  117. package/dist/vault/vault-entries.d.ts.map +1 -1
  118. package/dist/vault/vault-entries.js +68 -26
  119. package/dist/vault/vault-entries.js.map +1 -1
  120. package/dist/vault/vault-maintenance.d.ts.map +1 -1
  121. package/dist/vault/vault-maintenance.js +6 -2
  122. package/dist/vault/vault-maintenance.js.map +1 -1
  123. package/dist/vault/vault-markdown-sync.d.ts.map +1 -1
  124. package/dist/vault/vault-markdown-sync.js.map +1 -1
  125. package/dist/vault/vault-memories.d.ts.map +1 -1
  126. package/dist/vault/vault-memories.js +3 -1
  127. package/dist/vault/vault-memories.js.map +1 -1
  128. package/dist/vault/vault-schema.js +36 -10
  129. package/dist/vault/vault-schema.js.map +1 -1
  130. package/dist/vault/vault.d.ts.map +1 -1
  131. package/dist/vault/vault.js +5 -1
  132. package/dist/vault/vault.js.map +1 -1
  133. package/package.json +7 -7
  134. package/src/agency/agency-manager.test.ts +60 -40
  135. package/src/agency/default-rules.test.ts +17 -9
  136. package/src/capabilities/registry.test.ts +2 -12
  137. package/src/chat/agent-loop.test.ts +33 -43
  138. package/src/chat/mcp-bridge.test.ts +7 -2
  139. package/src/claudemd/inject.test.ts +2 -12
  140. package/src/context/context-engine.test.ts +96 -51
  141. package/src/control/intent-router.test.ts +3 -3
  142. package/src/curator/classifier.test.ts +14 -8
  143. package/src/curator/contradiction-detector.test.ts +30 -5
  144. package/src/curator/curator.ts +278 -56
  145. package/src/curator/duplicate-detector.test.ts +77 -15
  146. package/src/curator/quality-gate.test.ts +71 -31
  147. package/src/curator/tag-manager.test.ts +12 -4
  148. package/src/domain-packs/knowledge-installer.test.ts +2 -10
  149. package/src/domain-packs/token-resolver.test.ts +1 -3
  150. package/src/domain-packs/types.test.ts +16 -2
  151. package/src/enforcement/registry.test.ts +2 -8
  152. package/src/engine/bin/soleri-engine.ts +3 -1
  153. package/src/engine/module-manifest.test.ts +5 -4
  154. package/src/engine/module-manifest.ts +21 -1
  155. package/src/engine/register-engine.test.ts +6 -1
  156. package/src/engine/register-engine.ts +26 -3
  157. package/src/errors/classify.test.ts +6 -2
  158. package/src/errors/retry.test.ts +1 -4
  159. package/src/facades/facade-factory.test.ts +110 -64
  160. package/src/flows/epilogue.test.ts +16 -10
  161. package/src/flows/gate-evaluator.test.ts +12 -6
  162. package/src/flows/gate-evaluator.ts +1 -3
  163. package/src/governance/governance.test.ts +137 -21
  164. package/src/health/health-registry.test.ts +8 -1
  165. package/src/intake/content-classifier.test.ts +121 -51
  166. package/src/intake/dedup-gate.test.ts +38 -22
  167. package/src/intake/intake-pipeline.test.ts +5 -3
  168. package/src/intake/text-ingester.test.ts +26 -20
  169. package/src/llm/key-pool.test.ts +1 -3
  170. package/src/llm/llm-client.test.ts +1 -4
  171. package/src/llm/oauth-discovery.test.ts +16 -16
  172. package/src/llm/utils.test.ts +62 -18
  173. package/src/logging/logger.test.ts +4 -1
  174. package/src/loop/loop-manager.test.ts +2 -6
  175. package/src/migrations/migration-runner.edge-cases.test.ts +2 -7
  176. package/src/operator/operator-profile-extended.test.ts +15 -5
  177. package/src/operator/operator-profile.test.ts +26 -8
  178. package/src/operator/operator-profile.ts +38 -22
  179. package/src/operator/operator-signals-extended.test.ts +35 -23
  180. package/src/operator/operator-signals.test.ts +6 -10
  181. package/src/operator/operator-signals.ts +2 -1
  182. package/src/operator/prompts/hook-precompact-operator-dispatch.md +10 -6
  183. package/src/operator/prompts/subagent-soft-signal-extractor.md +5 -0
  184. package/src/operator/prompts/subagent-synthesis-cognition.md +19 -10
  185. package/src/operator/prompts/subagent-synthesis-communication.md +13 -7
  186. package/src/operator/prompts/subagent-synthesis-technical.md +19 -9
  187. package/src/operator/prompts/subagent-synthesis-trust.md +27 -21
  188. package/src/persona/defaults.test.ts +1 -5
  189. package/src/planning/evidence-collector.test.ts +147 -38
  190. package/src/planning/evidence-collector.ts +1 -4
  191. package/src/planning/gap-analysis-alternatives.test.ts +41 -11
  192. package/src/planning/gap-passes.test.ts +215 -33
  193. package/src/planning/gap-passes.ts +115 -46
  194. package/src/planning/gap-patterns.test.ts +87 -13
  195. package/src/planning/gap-patterns.ts +114 -31
  196. package/src/planning/github-projection.test.ts +6 -1
  197. package/src/planning/github-projection.ts +41 -20
  198. package/src/planning/impact-analyzer.test.ts +10 -23
  199. package/src/planning/impact-analyzer.ts +33 -46
  200. package/src/planning/plan-lifecycle.test.ts +103 -36
  201. package/src/planning/plan-lifecycle.ts +49 -18
  202. package/src/planning/planner.test.ts +12 -2
  203. package/src/planning/planner.ts +198 -58
  204. package/src/planning/rationalization-detector.test.ts +5 -20
  205. package/src/planning/rationalization-detector.ts +14 -16
  206. package/src/planning/reconciliation-engine.test.ts +20 -3
  207. package/src/planning/reconciliation-engine.ts +1 -2
  208. package/src/planning/task-verifier.test.ts +59 -27
  209. package/src/planning/task-verifier.ts +15 -9
  210. package/src/playbooks/playbook-executor.test.ts +1 -3
  211. package/src/plugins/plugin-loader.test.ts +19 -14
  212. package/src/plugins/plugin-registry.test.ts +45 -33
  213. package/src/project/project-registry.test.ts +23 -12
  214. package/src/prompts/template-manager.test.ts +4 -1
  215. package/src/queue/job-queue.test.ts +10 -14
  216. package/src/runtime/admin-extra-ops.test.ts +5 -19
  217. package/src/runtime/admin-ops.test.ts +1 -3
  218. package/src/runtime/admin-setup-ops.test.ts +3 -4
  219. package/src/runtime/admin-setup-ops.ts +9 -2
  220. package/src/runtime/archive-ops.test.ts +4 -1
  221. package/src/runtime/branching-ops.test.ts +144 -0
  222. package/src/runtime/branching-ops.ts +107 -0
  223. package/src/runtime/capture-ops.test.ts +7 -21
  224. package/src/runtime/chain-ops.test.ts +16 -6
  225. package/src/runtime/claude-md-helpers.test.ts +1 -3
  226. package/src/runtime/context-health.test.ts +1 -3
  227. package/src/runtime/context-health.ts +1 -3
  228. package/src/runtime/curator-extra-ops.test.ts +3 -1
  229. package/src/runtime/domain-ops.test.ts +46 -36
  230. package/src/runtime/facades/admin-facade.test.ts +1 -4
  231. package/src/runtime/facades/archive-facade.test.ts +21 -7
  232. package/src/runtime/facades/brain-facade.test.ts +176 -72
  233. package/src/runtime/facades/branching-facade.test.ts +43 -0
  234. package/src/runtime/facades/branching-facade.ts +11 -0
  235. package/src/runtime/facades/chat-facade.test.ts +81 -28
  236. package/src/runtime/facades/chat-service-ops.test.ts +178 -73
  237. package/src/runtime/facades/chat-service-ops.ts +3 -1
  238. package/src/runtime/facades/chat-session-ops.test.ts +25 -10
  239. package/src/runtime/facades/chat-transport-ops.test.ts +101 -34
  240. package/src/runtime/facades/chat-transport-ops.ts +0 -1
  241. package/src/runtime/facades/context-facade.test.ts +19 -4
  242. package/src/runtime/facades/control-facade.test.ts +3 -3
  243. package/src/runtime/facades/index.ts +42 -0
  244. package/src/runtime/facades/intake-facade.test.ts +215 -0
  245. package/src/runtime/facades/intake-facade.ts +14 -0
  246. package/src/runtime/facades/links-facade.test.ts +203 -0
  247. package/src/runtime/facades/links-facade.ts +13 -0
  248. package/src/runtime/facades/loop-facade.test.ts +22 -5
  249. package/src/runtime/facades/memory-facade.test.ts +19 -5
  250. package/src/runtime/facades/operator-facade.test.ts +17 -4
  251. package/src/runtime/facades/operator-facade.ts +11 -3
  252. package/src/runtime/facades/orchestrate-facade.test.ts +7 -1
  253. package/src/runtime/facades/plan-facade.test.ts +29 -12
  254. package/src/runtime/facades/plan-facade.ts +7 -2
  255. package/src/runtime/facades/tier-facade.test.ts +47 -0
  256. package/src/runtime/facades/tier-facade.ts +11 -0
  257. package/src/runtime/facades/vault-facade.test.ts +174 -242
  258. package/src/runtime/facades/vault-facade.ts +55 -199
  259. package/src/runtime/github-integration.ts +11 -8
  260. package/src/runtime/grading-ops.test.ts +39 -8
  261. package/src/runtime/intake-ops.test.ts +69 -16
  262. package/src/runtime/loop-ops.test.ts +16 -6
  263. package/src/runtime/memory-cross-project-ops.test.ts +25 -14
  264. package/src/runtime/orchestrate-ops.ts +54 -27
  265. package/src/runtime/pack-ops.test.ts +23 -6
  266. package/src/runtime/planning-extra-ops.test.ts +17 -7
  267. package/src/runtime/planning-extra-ops.ts +3 -1
  268. package/src/runtime/playbook-ops.test.ts +26 -3
  269. package/src/runtime/plugin-ops.test.ts +83 -25
  270. package/src/runtime/project-ops.test.ts +26 -6
  271. package/src/runtime/runtime.ts +3 -1
  272. package/src/runtime/session-briefing.test.ts +183 -54
  273. package/src/runtime/session-briefing.ts +8 -2
  274. package/src/runtime/sync-ops.test.ts +3 -12
  275. package/src/runtime/telemetry-ops.test.ts +31 -6
  276. package/src/runtime/tier-ops.test.ts +159 -0
  277. package/src/runtime/tier-ops.ts +119 -0
  278. package/src/runtime/vault-extra-ops.test.ts +32 -8
  279. package/src/runtime/vault-sharing-ops.test.ts +1 -4
  280. package/src/skills/sync-skills.ts +2 -12
  281. package/src/transport/ws-server.test.ts +7 -4
  282. package/src/vault/__tests__/vault-characterization.test.ts +492 -81
  283. package/src/vault/linking.test.ts +50 -17
  284. package/src/vault/linking.ts +48 -7
  285. package/src/vault/obsidian-sync.test.ts +6 -3
  286. package/src/vault/scope-detector.test.ts +1 -3
  287. package/src/vault/vault-branching.test.ts +9 -7
  288. package/src/vault/vault-entries.ts +209 -65
  289. package/src/vault/vault-maintenance.ts +7 -12
  290. package/src/vault/vault-manager.test.ts +10 -10
  291. package/src/vault/vault-markdown-sync.ts +4 -1
  292. package/src/vault/vault-memories.ts +7 -7
  293. package/src/vault/vault-schema.ts +72 -15
  294. package/src/vault/vault.ts +55 -9
  295. package/src/brain/strength-scorer.ts +0 -404
  296. package/src/engine/index.ts +0 -21
  297. package/src/persona/index.ts +0 -9
  298. package/src/vault/vault-interfaces.ts +0 -56
@@ -73,9 +73,7 @@ describe('runAgentLoop', () => {
73
73
 
74
74
  describe('basic flow', () => {
75
75
  test('returns text on end_turn', async () => {
76
- fetchMock.mockResolvedValueOnce(
77
- anthropicResponse([{ type: 'text', text: 'Hello!' }]),
78
- );
76
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'Hello!' }]));
79
77
 
80
78
  const result = await runAgentLoop(makeMessages('hi'), makeConfig());
81
79
  expect(result.text).toBe('Hello!');
@@ -87,9 +85,7 @@ describe('runAgentLoop', () => {
87
85
  });
88
86
 
89
87
  test('accumulates newMessages', async () => {
90
- fetchMock.mockResolvedValueOnce(
91
- anthropicResponse([{ type: 'text', text: 'reply' }]),
92
- );
88
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'reply' }]));
93
89
 
94
90
  const result = await runAgentLoop(makeMessages('q'), makeConfig());
95
91
  expect(result.newMessages.length).toBeGreaterThanOrEqual(1);
@@ -111,20 +107,24 @@ describe('runAgentLoop', () => {
111
107
  ),
112
108
  );
113
109
  // Second call: LLM returns final text
114
- fetchMock.mockResolvedValueOnce(
115
- anthropicResponse([{ type: 'text', text: 'Found it!' }]),
116
- );
110
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'Found it!' }]));
117
111
 
118
112
  const executorResults: string[] = [];
119
- const executor = async (name: string, _input: Record<string, unknown>): Promise<ToolResult> => {
113
+ const executor = async (
114
+ name: string,
115
+ _input: Record<string, unknown>,
116
+ ): Promise<ToolResult> => {
120
117
  executorResults.push(name);
121
118
  return { output: `result for ${name}`, isError: false };
122
119
  };
123
120
 
124
- const result = await runAgentLoop(makeMessages('search'), makeConfig({
125
- tools: [{ name: 'search', description: 'Search', inputSchema: { type: 'object' } }],
126
- executor,
127
- }));
121
+ const result = await runAgentLoop(
122
+ makeMessages('search'),
123
+ makeConfig({
124
+ tools: [{ name: 'search', description: 'Search', inputSchema: { type: 'object' } }],
125
+ executor,
126
+ }),
127
+ );
128
128
 
129
129
  expect(result.iterations).toBe(2);
130
130
  expect(result.toolCalls).toBe(1);
@@ -139,16 +139,16 @@ describe('runAgentLoop', () => {
139
139
  'tool_use',
140
140
  ),
141
141
  );
142
- fetchMock.mockResolvedValueOnce(
143
- anthropicResponse([{ type: 'text', text: 'Done' }]),
144
- );
142
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'Done' }]));
145
143
 
146
144
  const errors: string[] = [];
147
145
  const result = await runAgentLoop(
148
146
  makeMessages('go'),
149
147
  makeConfig({
150
148
  tools: [{ name: 'broken', description: 'Broken', inputSchema: { type: 'object' } }],
151
- executor: async () => { throw new Error('tool failed'); },
149
+ executor: async () => {
150
+ throw new Error('tool failed');
151
+ },
152
152
  }),
153
153
  {
154
154
  onError: (err, ctx) => errors.push(`${ctx}: ${err.message}`),
@@ -254,9 +254,7 @@ describe('runAgentLoop', () => {
254
254
 
255
255
  describe('callbacks', () => {
256
256
  test('fires onIteration for each loop', async () => {
257
- fetchMock.mockResolvedValueOnce(
258
- anthropicResponse([{ type: 'text', text: 'ok' }]),
259
- );
257
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'ok' }]));
260
258
 
261
259
  const iterations: number[] = [];
262
260
  await runAgentLoop(makeMessages('hi'), makeConfig(), {
@@ -273,9 +271,7 @@ describe('runAgentLoop', () => {
273
271
  'tool_use',
274
272
  ),
275
273
  );
276
- fetchMock.mockResolvedValueOnce(
277
- anthropicResponse([{ type: 'text', text: 'done' }]),
278
- );
274
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'done' }]));
279
275
 
280
276
  const toolUses: string[] = [];
281
277
  const toolResults: string[] = [];
@@ -304,9 +300,9 @@ describe('runAgentLoop', () => {
304
300
  test('throws on non-retryable API error', async () => {
305
301
  fetchMock.mockResolvedValueOnce(anthropicError(400, 'bad request'));
306
302
 
307
- await expect(
308
- runAgentLoop(makeMessages('hi'), makeConfig()),
309
- ).rejects.toThrow('Anthropic API error 400');
303
+ await expect(runAgentLoop(makeMessages('hi'), makeConfig())).rejects.toThrow(
304
+ 'Anthropic API error 400',
305
+ );
310
306
  });
311
307
 
312
308
  test('fires onError callback before throwing', async () => {
@@ -326,9 +322,7 @@ describe('runAgentLoop', () => {
326
322
 
327
323
  describe('message sanitization', () => {
328
324
  test('strips leading assistant messages', async () => {
329
- fetchMock.mockResolvedValueOnce(
330
- anthropicResponse([{ type: 'text', text: 'ok' }]),
331
- );
325
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'ok' }]));
332
326
 
333
327
  const messages: ChatMessage[] = [
334
328
  { role: 'assistant', content: 'orphan', timestamp: Date.now() },
@@ -344,9 +338,7 @@ describe('runAgentLoop', () => {
344
338
  });
345
339
 
346
340
  test('skips standalone tool messages', async () => {
347
- fetchMock.mockResolvedValueOnce(
348
- anthropicResponse([{ type: 'text', text: 'ok' }]),
349
- );
341
+ fetchMock.mockResolvedValueOnce(anthropicResponse([{ type: 'text', text: 'ok' }]));
350
342
 
351
343
  const messages: ChatMessage[] = [
352
344
  { role: 'user', content: 'hello', timestamp: Date.now() },
@@ -365,18 +357,16 @@ describe('runAgentLoop', () => {
365
357
  describe('usage accumulation', () => {
366
358
  test('sums usage across iterations', async () => {
367
359
  fetchMock.mockResolvedValueOnce(
368
- anthropicResponse(
369
- [{ type: 'tool_use', id: 'tu_1', name: 'x', input: {} }],
370
- 'tool_use',
371
- { input_tokens: 100, output_tokens: 50 },
372
- ),
360
+ anthropicResponse([{ type: 'tool_use', id: 'tu_1', name: 'x', input: {} }], 'tool_use', {
361
+ input_tokens: 100,
362
+ output_tokens: 50,
363
+ }),
373
364
  );
374
365
  fetchMock.mockResolvedValueOnce(
375
- anthropicResponse(
376
- [{ type: 'text', text: 'done' }],
377
- 'end_turn',
378
- { input_tokens: 150, output_tokens: 30 },
379
- ),
366
+ anthropicResponse([{ type: 'text', text: 'done' }], 'end_turn', {
367
+ input_tokens: 150,
368
+ output_tokens: 30,
369
+ }),
380
370
  );
381
371
 
382
372
  const result = await runAgentLoop(
@@ -108,7 +108,9 @@ describe('McpToolBridge', () => {
108
108
  test('catches handler errors', async () => {
109
109
  bridge.register({
110
110
  ...makeTool('broken'),
111
- handler: async () => { throw new Error('kaboom'); },
111
+ handler: async () => {
112
+ throw new Error('kaboom');
113
+ },
112
114
  });
113
115
  const result = await bridge.execute('broken', {});
114
116
  expect(result.isError).toBe(true);
@@ -119,7 +121,10 @@ describe('McpToolBridge', () => {
119
121
  let received: Record<string, unknown> = {};
120
122
  bridge.register({
121
123
  ...makeTool('capture'),
122
- handler: async (input) => { received = input; return 'ok'; },
124
+ handler: async (input) => {
125
+ received = input;
126
+ return 'ok';
127
+ },
123
128
  });
124
129
  await bridge.execute('capture', { foo: 'bar' });
125
130
  expect(received).toEqual({ foo: 'bar' });
@@ -2,18 +2,8 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { join } from 'node:path';
3
3
  import { mkdtempSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { tmpdir } from 'node:os';
5
- import {
6
- injectCLAUDEmd,
7
- removeCLAUDEmd,
8
- hasCLAUDEmdBlock,
9
- extractUserZone,
10
- } from './inject.js';
11
- import {
12
- OPEN_MARKER,
13
- CLOSE_MARKER,
14
- USER_ZONE_OPEN,
15
- USER_ZONE_CLOSE,
16
- } from './compose.js';
5
+ import { injectCLAUDEmd, removeCLAUDEmd, hasCLAUDEmdBlock, extractUserZone } from './inject.js';
6
+ import { OPEN_MARKER, CLOSE_MARKER, USER_ZONE_OPEN, USER_ZONE_CLOSE } from './compose.js';
17
7
 
18
8
  function block(content: string): string {
19
9
  return `${OPEN_MARKER}\n${content}\n${CLOSE_MARKER}`;
@@ -31,7 +31,13 @@ function createMockIntelligence(overrides?: Partial<BrainIntelligence>): BrainIn
31
31
  } as unknown as BrainIntelligence;
32
32
  }
33
33
 
34
- function makeVaultResult(id: string, title: string, score: number, domain: string, tags: string[] = []) {
34
+ function makeVaultResult(
35
+ id: string,
36
+ title: string,
37
+ score: number,
38
+ domain: string,
39
+ tags: string[] = [],
40
+ ) {
35
41
  return {
36
42
  entry: { id, title, domain, tags, type: 'pattern', severity: 'suggestion', description: '' },
37
43
  score,
@@ -120,7 +126,9 @@ describe('ContextEngine', () => {
120
126
  });
121
127
 
122
128
  it('extracts kebab-case patterns but filters stop words', () => {
123
- const result = engine.extractEntities('Use the token-migration pattern, not built-in or real-time');
129
+ const result = engine.extractEntities(
130
+ 'Use the token-migration pattern, not built-in or real-time',
131
+ );
124
132
  const patterns = result.byType.pattern ?? [];
125
133
  expect(patterns.some((p) => p.value === 'token-migration')).toBe(true);
126
134
  expect(patterns.some((p) => p.value === 'real-time')).toBe(false);
@@ -170,9 +178,11 @@ describe('ContextEngine', () => {
170
178
 
171
179
  describe('retrieveKnowledge', () => {
172
180
  it('returns vault results with enriched scores', async () => {
173
- const mockSearch = vi.fn().mockReturnValue([
174
- makeVaultResult('v1', 'Button pattern', 10, 'design', ['button', 'component']),
175
- ]);
181
+ const mockSearch = vi
182
+ .fn()
183
+ .mockReturnValue([
184
+ makeVaultResult('v1', 'Button pattern', 10, 'design', ['button', 'component']),
185
+ ]);
176
186
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
177
187
  engine = new ContextEngine(vault, brain, intelligence);
178
188
 
@@ -186,10 +196,12 @@ describe('ContextEngine', () => {
186
196
  });
187
197
 
188
198
  it('returns brain recommendations normalized to 0-1', async () => {
189
- const mockRecommend = vi.fn().mockReturnValue([
190
- makeBrainRecommendation('semantic-tokens', 'design', 80),
191
- ]);
192
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
199
+ const mockRecommend = vi
200
+ .fn()
201
+ .mockReturnValue([makeBrainRecommendation('semantic-tokens', 'design', 80)]);
202
+ intelligence = createMockIntelligence({
203
+ recommend: mockRecommend,
204
+ } as unknown as Partial<BrainIntelligence>);
193
205
  engine = new ContextEngine(vault, brain, intelligence);
194
206
 
195
207
  const result = await engine.retrieveKnowledge('design tokens');
@@ -200,14 +212,16 @@ describe('ContextEngine', () => {
200
212
  });
201
213
 
202
214
  it('combines vault and brain results sorted by score descending', async () => {
203
- const mockSearch = vi.fn().mockReturnValue([
204
- makeVaultResult('v1', 'Low relevance', 2, 'general'),
205
- ]);
206
- const mockRecommend = vi.fn().mockReturnValue([
207
- makeBrainRecommendation('high-relevance', 'design', 95),
208
- ]);
215
+ const mockSearch = vi
216
+ .fn()
217
+ .mockReturnValue([makeVaultResult('v1', 'Low relevance', 2, 'general')]);
218
+ const mockRecommend = vi
219
+ .fn()
220
+ .mockReturnValue([makeBrainRecommendation('high-relevance', 'design', 95)]);
209
221
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
210
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
222
+ intelligence = createMockIntelligence({
223
+ recommend: mockRecommend,
224
+ } as unknown as Partial<BrainIntelligence>);
211
225
  engine = new ContextEngine(vault, brain, intelligence);
212
226
 
213
227
  const result = await engine.retrieveKnowledge('test query');
@@ -216,9 +230,9 @@ describe('ContextEngine', () => {
216
230
  });
217
231
 
218
232
  it('filters items below minScoreThreshold', async () => {
219
- const mockSearch = vi.fn().mockReturnValue([
220
- makeVaultResult('v1', 'Irrelevant entry', 1, 'misc'),
221
- ]);
233
+ const mockSearch = vi
234
+ .fn()
235
+ .mockReturnValue([makeVaultResult('v1', 'Irrelevant entry', 1, 'misc')]);
222
236
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
223
237
  engine = new ContextEngine(vault, brain, intelligence, { minScoreThreshold: 0.99 });
224
238
 
@@ -241,12 +255,17 @@ describe('ContextEngine', () => {
241
255
  engine = new ContextEngine(vault, brain, intelligence);
242
256
 
243
257
  await engine.retrieveKnowledge('test', 'security');
244
- expect(mockSearch).toHaveBeenCalledWith('test', expect.objectContaining({ domain: 'security' }));
258
+ expect(mockSearch).toHaveBeenCalledWith(
259
+ 'test',
260
+ expect.objectContaining({ domain: 'security' }),
261
+ );
245
262
  });
246
263
 
247
264
  it('passes domain to brain recommendations', async () => {
248
265
  const mockRecommend = vi.fn().mockReturnValue([]);
249
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
266
+ intelligence = createMockIntelligence({
267
+ recommend: mockRecommend,
268
+ } as unknown as Partial<BrainIntelligence>);
250
269
  engine = new ContextEngine(vault, brain, intelligence);
251
270
 
252
271
  await engine.retrieveKnowledge('test', 'design');
@@ -254,7 +273,9 @@ describe('ContextEngine', () => {
254
273
  });
255
274
 
256
275
  it('gracefully handles vault search throwing', async () => {
257
- const mockSearch = vi.fn().mockImplementation(() => { throw new Error('DB error'); });
276
+ const mockSearch = vi.fn().mockImplementation(() => {
277
+ throw new Error('DB error');
278
+ });
258
279
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
259
280
  engine = new ContextEngine(vault, brain, intelligence);
260
281
 
@@ -264,8 +285,12 @@ describe('ContextEngine', () => {
264
285
  });
265
286
 
266
287
  it('gracefully handles brain recommend throwing', async () => {
267
- const mockRecommend = vi.fn().mockImplementation(() => { throw new Error('Brain error'); });
268
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
288
+ const mockRecommend = vi.fn().mockImplementation(() => {
289
+ throw new Error('Brain error');
290
+ });
291
+ intelligence = createMockIntelligence({
292
+ recommend: mockRecommend,
293
+ } as unknown as Partial<BrainIntelligence>);
269
294
  engine = new ContextEngine(vault, brain, intelligence);
270
295
 
271
296
  const result = await engine.retrieveKnowledge('test');
@@ -283,7 +308,9 @@ describe('ContextEngine', () => {
283
308
 
284
309
  it('respects brainRecommendLimit config', async () => {
285
310
  const mockRecommend = vi.fn().mockReturnValue([]);
286
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
311
+ intelligence = createMockIntelligence({
312
+ recommend: mockRecommend,
313
+ } as unknown as Partial<BrainIntelligence>);
287
314
  engine = new ContextEngine(vault, brain, intelligence, { brainRecommendLimit: 2 });
288
315
 
289
316
  await engine.retrieveKnowledge('test');
@@ -312,7 +339,9 @@ describe('ContextEngine', () => {
312
339
  });
313
340
 
314
341
  it('confidence is between 0 and 1', async () => {
315
- const result = await engine.analyze('Create React TypeScript component in src/app.tsx for security');
342
+ const result = await engine.analyze(
343
+ 'Create React TypeScript component in src/app.tsx for security',
344
+ );
316
345
  expect(result.confidence).toBeGreaterThanOrEqual(0);
317
346
  expect(result.confidence).toBeLessThanOrEqual(1);
318
347
  });
@@ -324,13 +353,17 @@ describe('ContextEngine', () => {
324
353
  });
325
354
 
326
355
  it('assigns higher confidence when entities and knowledge are present', async () => {
327
- const mockSearch = vi.fn().mockReturnValue([
328
- makeVaultResult('v1', 'Unit test best practices', 10, 'testing', ['testing']),
329
- ]);
356
+ const mockSearch = vi
357
+ .fn()
358
+ .mockReturnValue([
359
+ makeVaultResult('v1', 'Unit test best practices', 10, 'testing', ['testing']),
360
+ ]);
330
361
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
331
362
  engine = new ContextEngine(vault, brain, intelligence);
332
363
 
333
- const result = await engine.analyze('Create unit tests for the search() function in src/vault.ts with TypeScript');
364
+ const result = await engine.analyze(
365
+ 'Create unit tests for the search() function in src/vault.ts with TypeScript',
366
+ );
334
367
  expect(result.confidence).toBeGreaterThan(0.4);
335
368
  });
336
369
 
@@ -341,9 +374,9 @@ describe('ContextEngine', () => {
341
374
  });
342
375
 
343
376
  it('detects domains from knowledge items', async () => {
344
- const mockSearch = vi.fn().mockReturnValue([
345
- makeVaultResult('v1', 'Perf guide', 10, 'performance', ['performance']),
346
- ]);
377
+ const mockSearch = vi
378
+ .fn()
379
+ .mockReturnValue([makeVaultResult('v1', 'Perf guide', 10, 'performance', ['performance'])]);
347
380
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
348
381
  engine = new ContextEngine(vault, brain, intelligence);
349
382
 
@@ -352,9 +385,9 @@ describe('ContextEngine', () => {
352
385
  });
353
386
 
354
387
  it('deduplicates domains from entities and knowledge', async () => {
355
- const mockSearch = vi.fn().mockReturnValue([
356
- makeVaultResult('v1', 'A11y rules', 10, 'accessibility', ['a11y']),
357
- ]);
388
+ const mockSearch = vi
389
+ .fn()
390
+ .mockReturnValue([makeVaultResult('v1', 'A11y rules', 10, 'accessibility', ['a11y'])]);
358
391
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
359
392
  engine = new ContextEngine(vault, brain, intelligence);
360
393
 
@@ -393,27 +426,35 @@ describe('ContextEngine', () => {
393
426
 
394
427
  it('more entities increase confidence up to a cap', async () => {
395
428
  const few = await engine.analyze('fix it');
396
- const many = await engine.analyze('fix the React TypeScript component in src/app.tsx for accessibility and deploy');
429
+ const many = await engine.analyze(
430
+ 'fix the React TypeScript component in src/app.tsx for accessibility and deploy',
431
+ );
397
432
  expect(many.confidence).toBeGreaterThan(few.confidence);
398
433
  });
399
434
 
400
435
  it('source diversity bonus applies when multiple sources return results', async () => {
401
- const mockSearch = vi.fn().mockReturnValue([
402
- makeVaultResult('v1', 'Pattern one', 10, 'design', ['design']),
403
- ]);
404
- const mockRecommend = vi.fn().mockReturnValue([
405
- makeBrainRecommendation('some-pattern', 'design', 70),
406
- ]);
436
+ const mockSearch = vi
437
+ .fn()
438
+ .mockReturnValue([makeVaultResult('v1', 'Pattern one', 10, 'design', ['design'])]);
439
+ const mockRecommend = vi
440
+ .fn()
441
+ .mockReturnValue([makeBrainRecommendation('some-pattern', 'design', 70)]);
407
442
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
408
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
443
+ intelligence = createMockIntelligence({
444
+ recommend: mockRecommend,
445
+ } as unknown as Partial<BrainIntelligence>);
409
446
  const multiEngine = new ContextEngine(vault, brain, intelligence);
410
447
 
411
- const vaultOnlySearch = vi.fn().mockReturnValue([
412
- makeVaultResult('v1', 'Pattern one', 10, 'design', ['design']),
413
- ]);
448
+ const vaultOnlySearch = vi
449
+ .fn()
450
+ .mockReturnValue([makeVaultResult('v1', 'Pattern one', 10, 'design', ['design'])]);
414
451
  const emptyRecommend = vi.fn().mockReturnValue([]);
415
- const vaultOnlyVault = createMockVault({ search: vaultOnlySearch } as unknown as Partial<Vault>);
416
- const emptyIntel = createMockIntelligence({ recommend: emptyRecommend } as unknown as Partial<BrainIntelligence>);
452
+ const vaultOnlyVault = createMockVault({
453
+ search: vaultOnlySearch,
454
+ } as unknown as Partial<Vault>);
455
+ const emptyIntel = createMockIntelligence({
456
+ recommend: emptyRecommend,
457
+ } as unknown as Partial<BrainIntelligence>);
417
458
  const singleEngine = new ContextEngine(vaultOnlyVault, brain, emptyIntel);
418
459
 
419
460
  const multi = await multiEngine.analyze('design patterns');
@@ -428,7 +469,9 @@ describe('ContextEngine', () => {
428
469
  expect(low.confidence).toBeLessThan(0.45);
429
470
 
430
471
  // Construct a scenario with enough signals for medium (action + 6 entities = 0.2 + 0.4 cap = 0.6)
431
- const medium = await engine.analyze('create a React TypeScript component in src/app.tsx for security');
472
+ const medium = await engine.analyze(
473
+ 'create a React TypeScript component in src/app.tsx for security',
474
+ );
432
475
  expect(medium.confidence).toBeGreaterThanOrEqual(0.45);
433
476
  expect(['medium', 'high']).toContain(medium.confidenceLevel);
434
477
  });
@@ -450,7 +493,9 @@ describe('ContextEngine', () => {
450
493
  const mockSearch = vi.fn().mockReturnValue([]);
451
494
  const mockRecommend = vi.fn().mockReturnValue([]);
452
495
  vault = createMockVault({ search: mockSearch } as unknown as Partial<Vault>);
453
- intelligence = createMockIntelligence({ recommend: mockRecommend } as unknown as Partial<BrainIntelligence>);
496
+ intelligence = createMockIntelligence({
497
+ recommend: mockRecommend,
498
+ } as unknown as Partial<BrainIntelligence>);
454
499
  engine = new ContextEngine(vault, brain, intelligence, { vaultSearchLimit: 5 });
455
500
 
456
501
  await engine.retrieveKnowledge('test');
@@ -230,9 +230,9 @@ describe('IntentRouter', () => {
230
230
  });
231
231
 
232
232
  it('throws for unknown mode', () => {
233
- expect(() =>
234
- router.updateModeRules('NOPE-MODE' as OperationalMode, ['x']),
235
- ).toThrow(/Unknown mode/);
233
+ expect(() => router.updateModeRules('NOPE-MODE' as OperationalMode, ['x'])).toThrow(
234
+ /Unknown mode/,
235
+ );
236
236
  });
237
237
  });
238
238
 
@@ -32,12 +32,14 @@ describe('classifyEntry', () => {
32
32
  });
33
33
 
34
34
  it('classifies entry with valid LLM response', async () => {
35
- const llm = mockLLM(JSON.stringify({
36
- domain: 'security',
37
- severity: 'critical',
38
- tags: ['auth', 'jwt', 'security'],
39
- confidence: 0.9,
40
- }));
35
+ const llm = mockLLM(
36
+ JSON.stringify({
37
+ domain: 'security',
38
+ severity: 'critical',
39
+ tags: ['auth', 'jwt', 'security'],
40
+ confidence: 0.9,
41
+ }),
42
+ );
41
43
 
42
44
  const result = await classifyEntry(makeEntry({ title: 'Use JWT securely' }), llm);
43
45
  expect(result.classified).toBe(true);
@@ -75,7 +77,9 @@ describe('classifyEntry', () => {
75
77
  });
76
78
 
77
79
  it('passes entry fields to LLM prompt', async () => {
78
- const llm = mockLLM(JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }));
80
+ const llm = mockLLM(
81
+ JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }),
82
+ );
79
83
  const entry = makeEntry({
80
84
  title: 'Specific Title',
81
85
  type: 'anti-pattern',
@@ -93,7 +97,9 @@ describe('classifyEntry', () => {
93
97
  });
94
98
 
95
99
  it('uses empty tags placeholder when entry has no tags', async () => {
96
- const llm = mockLLM(JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }));
100
+ const llm = mockLLM(
101
+ JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }),
102
+ );
97
103
  const entry = makeEntry({ tags: [] });
98
104
 
99
105
  await classifyEntry(entry, llm);
@@ -111,8 +111,18 @@ describe('contradiction-detector', () => {
111
111
 
112
112
  it('falls back to all patterns when searchFn returns empty', () => {
113
113
  const entries = [
114
- makeEntry({ id: 'p1', type: 'pattern', title: 'Use inline styles', description: 'Inline.' }),
115
- makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
114
+ makeEntry({
115
+ id: 'p1',
116
+ type: 'pattern',
117
+ title: 'Use inline styles',
118
+ description: 'Inline.',
119
+ }),
120
+ makeEntry({
121
+ id: 'ap1',
122
+ type: 'anti-pattern',
123
+ title: 'Avoid inline styles',
124
+ description: 'No inline.',
125
+ }),
116
126
  ];
117
127
 
118
128
  const searchFn = vi.fn().mockReturnValue([]);
@@ -125,8 +135,18 @@ describe('contradiction-detector', () => {
125
135
 
126
136
  it('falls back to all patterns when searchFn throws', () => {
127
137
  const entries = [
128
- makeEntry({ id: 'p1', type: 'pattern', title: 'Use inline styles', description: 'Inline.' }),
129
- makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
138
+ makeEntry({
139
+ id: 'p1',
140
+ type: 'pattern',
141
+ title: 'Use inline styles',
142
+ description: 'Inline.',
143
+ }),
144
+ makeEntry({
145
+ id: 'ap1',
146
+ type: 'anti-pattern',
147
+ title: 'Avoid inline styles',
148
+ description: 'No inline.',
149
+ }),
130
150
  ];
131
151
 
132
152
  const searchFn = vi.fn().mockImplementation(() => {
@@ -170,7 +190,12 @@ describe('contradiction-detector', () => {
170
190
  it('ignores entries that are neither pattern nor anti-pattern', () => {
171
191
  const entries = [
172
192
  makeEntry({ id: 'r1', type: 'rule', title: 'Use inline styles', description: 'Inline.' }),
173
- makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'Avoid inline styles', description: 'No inline.' }),
193
+ makeEntry({
194
+ id: 'ap1',
195
+ type: 'anti-pattern',
196
+ title: 'Avoid inline styles',
197
+ description: 'No inline.',
198
+ }),
174
199
  ];
175
200
  // Rules should not be compared against anti-patterns
176
201
  const results = findContradictions(entries, 0.1);