@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
@@ -11,8 +11,12 @@ import {
11
11
  import type { PlanTask, TaskEvidence, TaskDeliverable, ReviewEvidence } from './planner-types.js';
12
12
 
13
13
  const makeTask = (overrides: Partial<PlanTask> = {}): PlanTask => ({
14
- id: 'task-1', title: 'Test task', description: 'Do something',
15
- status: 'pending', updatedAt: 0, ...overrides,
14
+ id: 'task-1',
15
+ title: 'Test task',
16
+ description: 'Do something',
17
+ status: 'pending',
18
+ updatedAt: 0,
19
+ ...overrides,
16
20
  });
17
21
 
18
22
  describe('task-verifier', () => {
@@ -21,7 +25,11 @@ describe('task-verifier', () => {
21
25
  const existing: TaskEvidence[] = [
22
26
  { criterion: 'cr1', content: 'result', type: 'description', submittedAt: 100 },
23
27
  ];
24
- const result = createEvidence(existing, { criterion: 'cr2', content: 'output', type: 'command_output' });
28
+ const result = createEvidence(existing, {
29
+ criterion: 'cr2',
30
+ content: 'output',
31
+ type: 'command_output',
32
+ });
25
33
  expect(result).toHaveLength(2);
26
34
  expect(result[1].criterion).toBe('cr2');
27
35
  expect(result[1].submittedAt).toBeGreaterThan(0);
@@ -66,22 +74,50 @@ describe('task-verifier', () => {
66
74
  it('returns verified=true when task has approved review', () => {
67
75
  const task = makeTask({ status: 'completed' });
68
76
  const reviews: ReviewEvidence[] = [
69
- { planId: 'p1', taskId: 'task-1', reviewer: 'r', outcome: 'approved', comments: '', reviewedAt: 0 },
77
+ {
78
+ planId: 'p1',
79
+ taskId: 'task-1',
80
+ reviewer: 'r',
81
+ outcome: 'approved',
82
+ comments: '',
83
+ reviewedAt: 0,
84
+ },
70
85
  ];
71
86
  expect(verifyTaskLogic(task, reviews).verified).toBe(true);
72
87
  });
73
88
  it('returns verified=false when task has rejected review', () => {
74
89
  const task = makeTask({ status: 'completed' });
75
90
  const reviews: ReviewEvidence[] = [
76
- { planId: 'p1', taskId: 'task-1', reviewer: 'r', outcome: 'rejected', comments: '', reviewedAt: 0 },
91
+ {
92
+ planId: 'p1',
93
+ taskId: 'task-1',
94
+ reviewer: 'r',
95
+ outcome: 'rejected',
96
+ comments: '',
97
+ reviewedAt: 0,
98
+ },
77
99
  ];
78
100
  expect(verifyTaskLogic(task, reviews).verified).toBe(false);
79
101
  });
80
102
  it('uses latest review outcome', () => {
81
103
  const task = makeTask({ status: 'completed' });
82
104
  const reviews: ReviewEvidence[] = [
83
- { planId: 'p1', taskId: 'task-1', reviewer: 'r', outcome: 'rejected', comments: '', reviewedAt: 0 },
84
- { planId: 'p1', taskId: 'task-1', reviewer: 'r', outcome: 'approved', comments: '', reviewedAt: 1 },
105
+ {
106
+ planId: 'p1',
107
+ taskId: 'task-1',
108
+ reviewer: 'r',
109
+ outcome: 'rejected',
110
+ comments: '',
111
+ reviewedAt: 0,
112
+ },
113
+ {
114
+ planId: 'p1',
115
+ taskId: 'task-1',
116
+ reviewer: 'r',
117
+ outcome: 'approved',
118
+ comments: '',
119
+ reviewedAt: 1,
120
+ },
85
121
  ];
86
122
  expect(verifyTaskLogic(task, reviews).verified).toBe(true);
87
123
  });
@@ -110,9 +146,13 @@ describe('task-verifier', () => {
110
146
  expect(result.issues[0].issue).toContain('pending');
111
147
  });
112
148
  it('flags missing evidence for completed tasks with acceptance criteria', () => {
113
- const tasks: PlanTask[] = [makeTask({
114
- status: 'completed', acceptanceCriteria: ['cr1'], evidence: [],
115
- })];
149
+ const tasks: PlanTask[] = [
150
+ makeTask({
151
+ status: 'completed',
152
+ acceptanceCriteria: ['cr1'],
153
+ evidence: [],
154
+ }),
155
+ ];
116
156
  const result = verifyPlanLogic('plan-1', tasks);
117
157
  expect(result.issues[0].issue).toContain('Missing evidence');
118
158
  });
@@ -138,35 +178,27 @@ describe('task-verifier', () => {
138
178
  expect(result.staleCount).toBe(0);
139
179
  });
140
180
  it('marks file deliverables as stale when file does not exist', () => {
141
- const deliverables: TaskDeliverable[] = [
142
- { type: 'file', path: '/nonexistent/path/file.ts' },
143
- ];
181
+ const deliverables: TaskDeliverable[] = [{ type: 'file', path: '/nonexistent/path/file.ts' }];
144
182
  const result = verifyDeliverablesLogic(deliverables);
145
183
  expect(result.verified).toBe(false);
146
184
  expect(result.staleCount).toBe(1);
147
185
  expect(result.deliverables[0].stale).toBe(true);
148
186
  });
149
187
  it('marks vault_entry deliverables as stale when vault returns null', () => {
150
- const deliverables: TaskDeliverable[] = [
151
- { type: 'vault_entry', path: 'entry-123' },
152
- ];
188
+ const deliverables: TaskDeliverable[] = [{ type: 'vault_entry', path: 'entry-123' }];
153
189
  const vault = { get: () => null };
154
190
  const result = verifyDeliverablesLogic(deliverables, vault);
155
191
  expect(result.staleCount).toBe(1);
156
192
  });
157
193
  it('marks vault_entry deliverables as valid when vault returns non-null', () => {
158
- const deliverables: TaskDeliverable[] = [
159
- { type: 'vault_entry', path: 'entry-123' },
160
- ];
194
+ const deliverables: TaskDeliverable[] = [{ type: 'vault_entry', path: 'entry-123' }];
161
195
  const vault = { get: () => ({ id: 'entry-123' }) };
162
196
  const result = verifyDeliverablesLogic(deliverables, vault);
163
197
  expect(result.verified).toBe(true);
164
198
  expect(result.staleCount).toBe(0);
165
199
  });
166
200
  it('skips url deliverables (no verification)', () => {
167
- const deliverables: TaskDeliverable[] = [
168
- { type: 'url', path: 'https://example.com' },
169
- ];
201
+ const deliverables: TaskDeliverable[] = [{ type: 'url', path: 'https://example.com' }];
170
202
  const result = verifyDeliverablesLogic(deliverables);
171
203
  expect(result.verified).toBe(true);
172
204
  });
@@ -214,17 +246,17 @@ describe('task-verifier', () => {
214
246
  expect(prompt).toContain('2. No regressions');
215
247
  });
216
248
  it('omits criteria section when empty', () => {
217
- const prompt = buildSpecReviewPrompt(
218
- { title: 'T', description: 'd' },
219
- 'Objective',
220
- );
249
+ const prompt = buildSpecReviewPrompt({ title: 'T', description: 'd' }, 'Objective');
221
250
  expect(prompt).not.toContain('Acceptance Criteria');
222
251
  });
223
252
  });
224
253
 
225
254
  describe('buildQualityReviewPrompt', () => {
226
255
  it('includes task info and quality checklist', () => {
227
- const prompt = buildQualityReviewPrompt({ title: 'Refactor X', description: 'Clean up code' });
256
+ const prompt = buildQualityReviewPrompt({
257
+ title: 'Refactor X',
258
+ description: 'Clean up code',
259
+ });
228
260
  expect(prompt).toContain('Refactor X');
229
261
  expect(prompt).toContain('Clean up code');
230
262
  expect(prompt).toContain('Code Quality Review');
@@ -268,14 +268,18 @@ export function buildSpecReviewPrompt(
268
268
  ? `\n\nAcceptance Criteria:\n${task.acceptanceCriteria.map((c, i) => `${i + 1}. ${c}`).join('\n')}`
269
269
  : '';
270
270
  return [
271
- `# Spec Compliance Review`, ``, `## Task: ${task.title}`,
271
+ `# Spec Compliance Review`,
272
+ ``,
273
+ `## Task: ${task.title}`,
272
274
  `**Description:** ${task.description}`,
273
- `**Plan Objective:** ${planObjective}${criteria}`, ``,
275
+ `**Plan Objective:** ${planObjective}${criteria}`,
276
+ ``,
274
277
  `## Review Checklist`,
275
278
  `1. Does the implementation match the task description?`,
276
279
  `2. Are all acceptance criteria satisfied?`,
277
280
  `3. Does it align with the plan's overall objective?`,
278
- `4. Are there any spec deviations?`, ``,
281
+ `4. Are there any spec deviations?`,
282
+ ``,
279
283
  `Provide: outcome (approved/rejected/needs_changes) and detailed comments.`,
280
284
  ].join('\n');
281
285
  }
@@ -284,12 +288,13 @@ export function buildSpecReviewPrompt(
284
288
  * Generate a code quality review prompt for a task.
285
289
  * Pure function — no persistence side-effects.
286
290
  */
287
- export function buildQualityReviewPrompt(
288
- task: Pick<PlanTask, 'title' | 'description'>,
289
- ): string {
291
+ export function buildQualityReviewPrompt(task: Pick<PlanTask, 'title' | 'description'>): string {
290
292
  return [
291
- `# Code Quality Review`, ``, `## Task: ${task.title}`,
292
- `**Description:** ${task.description}`, ``,
293
+ `# Code Quality Review`,
294
+ ``,
295
+ `## Task: ${task.title}`,
296
+ `**Description:** ${task.description}`,
297
+ ``,
293
298
  `## Quality Checklist`,
294
299
  `1. **Correctness** — Does it work as intended?`,
295
300
  `2. **Security** — No injection, XSS, or OWASP top 10 vulnerabilities?`,
@@ -297,7 +302,8 @@ export function buildQualityReviewPrompt(
297
302
  `4. **Maintainability** — Clear naming, appropriate abstractions, documented intent?`,
298
303
  `5. **Testing** — Adequate test coverage for the changes?`,
299
304
  `6. **Error Handling** — Graceful degradation, no swallowed errors?`,
300
- `7. **Conventions** — Follows project coding standards?`, ``,
305
+ `7. **Conventions** — Follows project coding standards?`,
306
+ ``,
301
307
  `Provide: outcome (approved/rejected/needs_changes) and detailed comments.`,
302
308
  ].join('\n');
303
309
  }
@@ -19,9 +19,7 @@ function makePlaybook(overrides: Partial<PlaybookDefinition> = {}): PlaybookDefi
19
19
  tags: [],
20
20
  matchIntents: ['BUILD'],
21
21
  matchKeywords: [],
22
- gates: [
23
- { phase: 'completion', requirement: 'Tests pass', checkType: 'test-pass' },
24
- ],
22
+ gates: [{ phase: 'completion', requirement: 'Tests pass', checkType: 'test-pass' }],
25
23
  taskTemplates: [],
26
24
  toolInjections: ['search_intelligent'],
27
25
  verificationCriteria: ['All tests pass'],
@@ -13,7 +13,10 @@ import type { LoadedPlugin, PluginManifest } from './types.js';
13
13
  let testDirs: string[] = [];
14
14
 
15
15
  function makeTempDir(): string {
16
- const dir = join(tmpdir(), `soleri-loader-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
16
+ const dir = join(
17
+ tmpdir(),
18
+ `soleri-loader-test-${Date.now()}-${Math.random().toString(36).slice(2)}`,
19
+ );
17
20
  mkdirSync(dir, { recursive: true });
18
21
  testDirs.push(dir);
19
22
  return dir;
@@ -26,13 +29,15 @@ function writePlugin(parentDir: string, id: string, manifest: Record<string, unk
26
29
  return dir;
27
30
  }
28
31
 
29
- function makeLoaded(overrides: Partial<LoadedPlugin & { manifest: Partial<PluginManifest> }> = {}): LoadedPlugin {
32
+ function makeLoaded(
33
+ overrides: Partial<LoadedPlugin & { manifest: Partial<PluginManifest> }> = {},
34
+ ): LoadedPlugin {
30
35
  return {
31
36
  manifest: pluginManifestSchema.parse({
32
37
  id: 'test-plugin',
33
38
  name: 'Test',
34
39
  version: '1.0.0',
35
- ...(overrides.manifest),
40
+ ...overrides.manifest,
36
41
  }),
37
42
  directory: overrides.directory ?? '/tmp/test',
38
43
  provenance: overrides.provenance ?? 'global',
@@ -41,7 +46,11 @@ function makeLoaded(overrides: Partial<LoadedPlugin & { manifest: Partial<Plugin
41
46
 
42
47
  afterEach(() => {
43
48
  for (const dir of testDirs) {
44
- try { rmSync(dir, { recursive: true, force: true }); } catch { /* noop */ }
49
+ try {
50
+ rmSync(dir, { recursive: true, force: true });
51
+ } catch {
52
+ /* noop */
53
+ }
45
54
  }
46
55
  testDirs = [];
47
56
  });
@@ -62,11 +71,11 @@ describe('loadPlugins — colocated', () => {
62
71
  const result = loadPlugins('test-agent', undefined, [dir1, dir2]);
63
72
 
64
73
  expect(result.loaded).toHaveLength(2);
65
- const ids = result.loaded.map(p => p.manifest.id);
74
+ const ids = result.loaded.map((p) => p.manifest.id);
66
75
  expect(ids).toContain('alpha');
67
76
  expect(ids).toContain('beta');
68
77
  // First occurrence wins
69
- expect(result.loaded.find(p => p.manifest.id === 'alpha')!.manifest.name).toBe('Alpha');
78
+ expect(result.loaded.find((p) => p.manifest.id === 'alpha')!.manifest.name).toBe('Alpha');
70
79
  });
71
80
 
72
81
  it('skips files (non-directories) inside plugin dir', () => {
@@ -154,18 +163,14 @@ describe('validateDependencies — colocated', () => {
154
163
  });
155
164
 
156
165
  it('detects multiple missing dependencies', () => {
157
- const plugins = [
158
- makeLoaded({ manifest: { id: 'lonely', dependencies: ['dep-a', 'dep-b'] } }),
159
- ];
166
+ const plugins = [makeLoaded({ manifest: { id: 'lonely', dependencies: ['dep-a', 'dep-b'] } })];
160
167
  const errors = validateDependencies(plugins);
161
168
  expect(errors).toHaveLength(2);
162
- expect(errors.map(e => e.missingDep)).toEqual(['dep-a', 'dep-b']);
169
+ expect(errors.map((e) => e.missingDep)).toEqual(['dep-a', 'dep-b']);
163
170
  });
164
171
 
165
172
  it('handles plugins with no dependencies', () => {
166
- const plugins = [
167
- makeLoaded({ manifest: { id: 'standalone' } }),
168
- ];
173
+ const plugins = [makeLoaded({ manifest: { id: 'standalone' } })];
169
174
  expect(validateDependencies(plugins)).toEqual([]);
170
175
  });
171
176
  });
@@ -181,7 +186,7 @@ describe('sortByDependencies — colocated', () => {
181
186
  const a = makeLoaded({ manifest: { id: 'a' } });
182
187
 
183
188
  const sorted = sortByDependencies([c, b, a]);
184
- const ids = sorted.map(p => p.manifest.id);
189
+ const ids = sorted.map((p) => p.manifest.id);
185
190
 
186
191
  expect(ids.indexOf('a')).toBeLessThan(ids.indexOf('b'));
187
192
  expect(ids.indexOf('b')).toBeLessThan(ids.indexOf('c'));
@@ -73,14 +73,16 @@ describe('PluginRegistry — colocated', () => {
73
73
  it('builds static facades from manifest when no index.js exists', async () => {
74
74
  const loaded = makeLoaded({
75
75
  manifest: makeManifest({
76
- facades: [{
77
- name: 'my_facade',
78
- description: 'Test facade',
79
- ops: [
80
- { name: 'do_thing', description: 'Does a thing', auth: 'read' },
81
- { name: 'admin_thing', description: 'Admin action', auth: 'admin' },
82
- ],
83
- }],
76
+ facades: [
77
+ {
78
+ name: 'my_facade',
79
+ description: 'Test facade',
80
+ ops: [
81
+ { name: 'do_thing', description: 'Does a thing', auth: 'read' },
82
+ { name: 'admin_thing', description: 'Admin action', auth: 'admin' },
83
+ ],
84
+ },
85
+ ],
84
86
  }),
85
87
  });
86
88
 
@@ -98,11 +100,13 @@ describe('PluginRegistry — colocated', () => {
98
100
  it('static facade ops return error message when called', async () => {
99
101
  const loaded = makeLoaded({
100
102
  manifest: makeManifest({
101
- facades: [{
102
- name: 'f',
103
- description: '',
104
- ops: [{ name: 'op1', description: '', auth: 'read' }],
105
- }],
103
+ facades: [
104
+ {
105
+ name: 'f',
106
+ description: '',
107
+ ops: [{ name: 'op1', description: '', auth: 'read' }],
108
+ },
109
+ ],
106
110
  }),
107
111
  });
108
112
 
@@ -126,9 +130,9 @@ describe('PluginRegistry — colocated', () => {
126
130
  });
127
131
 
128
132
  it('throws for unregistered plugin', async () => {
129
- await expect(
130
- registry.activate('ghost', makeContext(makeLoaded())),
131
- ).rejects.toThrow('not registered');
133
+ await expect(registry.activate('ghost', makeContext(makeLoaded()))).rejects.toThrow(
134
+ 'not registered',
135
+ );
132
136
  });
133
137
 
134
138
  it('sets error status when index.js fails to load', async () => {
@@ -152,11 +156,13 @@ describe('PluginRegistry — colocated', () => {
152
156
  it('deactivates an active plugin and clears facades', async () => {
153
157
  const loaded = makeLoaded({
154
158
  manifest: makeManifest({
155
- facades: [{
156
- name: 'f',
157
- description: '',
158
- ops: [{ name: 'op', description: '', auth: 'read' }],
159
- }],
159
+ facades: [
160
+ {
161
+ name: 'f',
162
+ description: '',
163
+ ops: [{ name: 'op', description: '', auth: 'read' }],
164
+ },
165
+ ],
160
166
  }),
161
167
  });
162
168
 
@@ -203,11 +209,13 @@ describe('PluginRegistry — colocated', () => {
203
209
  const active = makeLoaded({
204
210
  manifest: makeManifest({
205
211
  id: 'active-one',
206
- facades: [{
207
- name: 'af',
208
- description: '',
209
- ops: [{ name: 'aop', description: '', auth: 'read' }],
210
- }],
212
+ facades: [
213
+ {
214
+ name: 'af',
215
+ description: '',
216
+ ops: [{ name: 'aop', description: '', auth: 'read' }],
217
+ },
218
+ ],
211
219
  }),
212
220
  });
213
221
  const inactive = makeLoaded({ manifest: makeManifest({ id: 'inactive-one' }) });
@@ -227,10 +235,14 @@ describe('PluginRegistry — colocated', () => {
227
235
  id: 'multi',
228
236
  facades: [
229
237
  { name: 'f1', description: '', ops: [{ name: 'a', description: '', auth: 'read' }] },
230
- { name: 'f2', description: '', ops: [
231
- { name: 'b', description: '', auth: 'write' },
232
- { name: 'c', description: '', auth: 'admin' },
233
- ]},
238
+ {
239
+ name: 'f2',
240
+ description: '',
241
+ ops: [
242
+ { name: 'b', description: '', auth: 'write' },
243
+ { name: 'c', description: '', auth: 'admin' },
244
+ ],
245
+ },
234
246
  ],
235
247
  }),
236
248
  });
@@ -240,7 +252,7 @@ describe('PluginRegistry — colocated', () => {
240
252
 
241
253
  const ops = registry.getActiveOps();
242
254
  expect(ops).toHaveLength(3);
243
- expect(ops.map(o => o.name)).toEqual(['a', 'b', 'c']);
255
+ expect(ops.map((o) => o.name)).toEqual(['a', 'b', 'c']);
244
256
  });
245
257
 
246
258
  it('returns empty when no active plugins', () => {
@@ -265,8 +277,8 @@ describe('PluginRegistry — colocated', () => {
265
277
 
266
278
  const list = registry.list();
267
279
  expect(list).toHaveLength(2);
268
- expect(list.find(p => p.id === 'a')!.status).toBe('active');
269
- expect(list.find(p => p.id === 'b')!.status).toBe('registered');
280
+ expect(list.find((p) => p.id === 'a')!.status).toBe('active');
281
+ expect(list.find((p) => p.id === 'b')!.status).toBe('registered');
270
282
  });
271
283
  });
272
284
  });
@@ -33,9 +33,7 @@ function createMockProvider(): PersistenceProvider {
33
33
  // Check for duplicate
34
34
  const existing = store.project_links.find(
35
35
  (r) =>
36
- r.source_project_id === p[0] &&
37
- r.target_project_id === p[1] &&
38
- r.link_type === p[2],
36
+ r.source_project_id === p[0] && r.target_project_id === p[1] && r.link_type === p[2],
39
37
  );
40
38
  if (existing) return { changes: 0, lastInsertRowid: existing.id as number };
41
39
  autoIncrementId++;
@@ -97,7 +95,11 @@ function createMockProvider(): PersistenceProvider {
97
95
  return { changes: before - store.project_rules.length, lastInsertRowid: 0 };
98
96
  }
99
97
 
100
- if (sql.startsWith('DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type')) {
98
+ if (
99
+ sql.startsWith(
100
+ 'DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type',
101
+ )
102
+ ) {
101
103
  const before = store.project_links.length;
102
104
  store.project_links = store.project_links.filter(
103
105
  (r) =>
@@ -106,16 +108,23 @@ function createMockProvider(): PersistenceProvider {
106
108
  return { changes: before - store.project_links.length, lastInsertRowid: 0 };
107
109
  }
108
110
 
109
- if (sql.startsWith('DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ?')) {
111
+ if (
112
+ sql.startsWith(
113
+ 'DELETE FROM project_links WHERE source_project_id = ? AND target_project_id = ?',
114
+ )
115
+ ) {
110
116
  const before = store.project_links.length;
111
117
  store.project_links = store.project_links.filter(
112
- (r) =>
113
- !(r.source_project_id === p[0] && r.target_project_id === p[1]),
118
+ (r) => !(r.source_project_id === p[0] && r.target_project_id === p[1]),
114
119
  );
115
120
  return { changes: before - store.project_links.length, lastInsertRowid: 0 };
116
121
  }
117
122
 
118
- if (sql.startsWith('DELETE FROM project_links WHERE source_project_id = ? OR target_project_id = ?')) {
123
+ if (
124
+ sql.startsWith(
125
+ 'DELETE FROM project_links WHERE source_project_id = ? OR target_project_id = ?',
126
+ )
127
+ ) {
119
128
  const before = store.project_links.length;
120
129
  store.project_links = store.project_links.filter(
121
130
  (r) => r.source_project_id !== p[0] && r.target_project_id !== p[1],
@@ -141,12 +150,14 @@ function createMockProvider(): PersistenceProvider {
141
150
  if (sql.includes('FROM registered_projects WHERE path')) {
142
151
  return store.registered_projects.find((r) => r.path === p[0]) as T | undefined;
143
152
  }
144
- if (sql.includes('FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type')) {
153
+ if (
154
+ sql.includes(
155
+ 'FROM project_links WHERE source_project_id = ? AND target_project_id = ? AND link_type',
156
+ )
157
+ ) {
145
158
  return store.project_links.find(
146
159
  (r) =>
147
- r.source_project_id === p[0] &&
148
- r.target_project_id === p[1] &&
149
- r.link_type === p[2],
160
+ r.source_project_id === p[0] && r.target_project_id === p[1] && r.link_type === p[2],
150
161
  ) as T | undefined;
151
162
  }
152
163
 
@@ -8,7 +8,10 @@ describe('TemplateManager', () => {
8
8
  let tempDir: string;
9
9
 
10
10
  beforeEach(() => {
11
- tempDir = join(tmpdir(), `tmpl-mgr-colocated-${Date.now()}-${Math.random().toString(36).slice(2)}`);
11
+ tempDir = join(
12
+ tmpdir(),
13
+ `tmpl-mgr-colocated-${Date.now()}-${Math.random().toString(36).slice(2)}`,
14
+ );
12
15
  mkdirSync(tempDir, { recursive: true });
13
16
  });
14
17
 
@@ -57,7 +57,11 @@ function createMockProvider(): PersistenceProvider {
57
57
  row.completed_at = new Date().toISOString();
58
58
  }
59
59
  }
60
- if (sql.includes('UPDATE') && sql.includes("status = 'pending'") && sql.includes('retry_count')) {
60
+ if (
61
+ sql.includes('UPDATE') &&
62
+ sql.includes("status = 'pending'") &&
63
+ sql.includes('retry_count')
64
+ ) {
61
65
  const id = p[0] as string;
62
66
  const row = rows.get(id);
63
67
  if (row) {
@@ -144,15 +148,7 @@ describe('JobQueue', () => {
144
148
  queue.enqueue('groom');
145
149
  expect(provider.run).toHaveBeenCalledWith(
146
150
  expect.stringContaining('INSERT INTO job_queue'),
147
- expect.arrayContaining([
148
- expect.any(String),
149
- 'groom',
150
- null,
151
- '{}',
152
- '[]',
153
- null,
154
- 3,
155
- ]),
151
+ expect.arrayContaining([expect.any(String), 'groom', null, '{}', '[]', null, 3]),
156
152
  );
157
153
  });
158
154
 
@@ -219,10 +215,10 @@ describe('JobQueue', () => {
219
215
  const id = queue.enqueue('groom');
220
216
  queue.dequeue();
221
217
  queue.complete(id);
222
- expect(provider.run).toHaveBeenCalledWith(
223
- expect.stringContaining("status = 'completed'"),
224
- [null, id],
225
- );
218
+ expect(provider.run).toHaveBeenCalledWith(expect.stringContaining("status = 'completed'"), [
219
+ null,
220
+ id,
221
+ ]);
226
222
  });
227
223
  });
228
224
 
@@ -67,9 +67,7 @@ function createMockRuntime(): AgentRuntime {
67
67
  overall: 'healthy',
68
68
  subsystems: { vault: { status: 'healthy' }, brain: { status: 'healthy' } },
69
69
  })),
70
- get: vi.fn((name: string) =>
71
- name === 'vault' ? { status: 'healthy', failures: 0 } : null,
72
- ),
70
+ get: vi.fn((name: string) => (name === 'vault' ? { status: 'healthy', failures: 0 } : null)),
73
71
  },
74
72
  flags: {
75
73
  getAll: vi.fn(() => ({
@@ -396,10 +394,7 @@ describe('createAdminExtraOps', () => {
396
394
 
397
395
  describe('admin_hot_reload', () => {
398
396
  it('reloads brain, vault FTS, and templates', async () => {
399
- const result = (await findOp(ops, 'admin_hot_reload').handler({})) as Record<
400
- string,
401
- unknown
402
- >;
397
+ const result = (await findOp(ops, 'admin_hot_reload').handler({})) as Record<string, unknown>;
403
398
  expect((result.reloaded as string[]).length).toBe(3);
404
399
  expect(result.brainTerms).toBe(500);
405
400
  expect(result.templateCount).toBe(2);
@@ -409,10 +404,7 @@ describe('createAdminExtraOps', () => {
409
404
  vi.mocked(runtime.vault.rebuildFtsIndex).mockImplementation(() => {
410
405
  throw new Error('fail');
411
406
  });
412
- const result = (await findOp(ops, 'admin_hot_reload').handler({})) as Record<
413
- string,
414
- unknown
415
- >;
407
+ const result = (await findOp(ops, 'admin_hot_reload').handler({})) as Record<string, unknown>;
416
408
  expect(result.reloaded).not.toContain('vault_fts');
417
409
  });
418
410
  });
@@ -455,10 +447,7 @@ describe('createAdminExtraOps', () => {
455
447
 
456
448
  describe('admin_list_flags', () => {
457
449
  it('returns all feature flags', async () => {
458
- const result = (await findOp(ops, 'admin_list_flags').handler({})) as Record<
459
- string,
460
- unknown
461
- >;
450
+ const result = (await findOp(ops, 'admin_list_flags').handler({})) as Record<string, unknown>;
462
451
  expect(result).toHaveProperty('auth-enforcement');
463
452
  });
464
453
  });
@@ -516,10 +505,7 @@ describe('createAdminExtraOps', () => {
516
505
 
517
506
  describe('admin_setup_run', () => {
518
507
  it('runs setup actions', async () => {
519
- const result = (await findOp(ops, 'admin_setup_run').handler({})) as Record<
520
- string,
521
- unknown
522
- >;
508
+ const result = (await findOp(ops, 'admin_setup_run').handler({})) as Record<string, unknown>;
523
509
  expect(result.setup).toBe(true);
524
510
  expect((result.actions as string[]).length).toBeGreaterThan(0);
525
511
  });
@@ -135,9 +135,7 @@ describe('createAdminOps', () => {
135
135
 
136
136
  it('returns verbose format when verbose=true', async () => {
137
137
  const op = findOp(ops, 'admin_tool_list');
138
- const allOps = [
139
- { name: 'admin_health', description: 'Health check', auth: 'read' },
140
- ];
138
+ const allOps = [{ name: 'admin_health', description: 'Health check', auth: 'read' }];
141
139
  const result = (await op.handler({
142
140
  _allOps: allOps,
143
141
  verbose: true,
@@ -42,9 +42,7 @@ vi.mock('./claude-md-helpers.js', () => ({
42
42
  }));
43
43
 
44
44
  vi.mock('../skills/sync-skills.js', () => ({
45
- discoverSkills: vi.fn(() => [
46
- { name: 'skill-1', path: '/mock/skills/skill-1' },
47
- ]),
45
+ discoverSkills: vi.fn(() => [{ name: 'skill-1', path: '/mock/skills/skill-1' }]),
48
46
  syncSkillsToClaudeCode: vi.fn(() => ({
49
47
  installed: ['skill-1'],
50
48
  updated: [],
@@ -158,7 +156,8 @@ describe('createAdminSetupOps', () => {
158
156
  });
159
157
 
160
158
  it('updates existing agent sections', async () => {
161
- mockFs['/some/project/CLAUDE.md'] = '# Project\n<!-- agent:test-agent -->\nOld\n<!-- /agent:test-agent -->';
159
+ mockFs['/some/project/CLAUDE.md'] =
160
+ '# Project\n<!-- agent:test-agent -->\nOld\n<!-- /agent:test-agent -->';
162
161
  const { hasSections } = await import('./claude-md-helpers.js');
163
162
  vi.mocked(hasSections).mockReturnValueOnce(true);
164
163
  const result = (await findOp(ops, 'admin_inject_claude_md').handler({