@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
@@ -59,9 +59,7 @@ class LinkingMockDB implements PersistenceProvider {
59
59
  }
60
60
  if (sql.includes('DELETE FROM vault_links')) {
61
61
  const before = this.links.length;
62
- this.links = this.links.filter(
63
- (l) => !(l.source_id === p[0] && l.target_id === p[1]),
64
- );
62
+ this.links = this.links.filter((l) => !(l.source_id === p[0] && l.target_id === p[1]));
65
63
  return { changes: before - this.links.length, lastInsertRowid: 0 };
66
64
  }
67
65
  return { changes: 0, lastInsertRowid: 0 };
@@ -71,9 +69,7 @@ class LinkingMockDB implements PersistenceProvider {
71
69
  const p = params ?? [];
72
70
  if (sql.includes('COUNT(*)')) {
73
71
  const id = p[0] as string;
74
- const count = this.links.filter(
75
- (l) => l.source_id === id || l.target_id === id,
76
- ).length;
72
+ const count = this.links.filter((l) => l.source_id === id || l.target_id === id).length;
77
73
  return { count } as T;
78
74
  }
79
75
  if (sql.includes('FROM entries WHERE id')) {
@@ -83,7 +79,12 @@ class LinkingMockDB implements PersistenceProvider {
83
79
  if (sql.includes('title, description, type, tags')) {
84
80
  const entry = this.entries.find((e) => e.id === p[0]);
85
81
  if (!entry) return undefined;
86
- return { title: entry.title, description: entry.description, type: entry.type, tags: entry.tags } as T;
82
+ return {
83
+ title: entry.title,
84
+ description: entry.description,
85
+ type: entry.type,
86
+ tags: entry.tags,
87
+ } as T;
87
88
  }
88
89
  return undefined;
89
90
  }
@@ -99,9 +100,7 @@ class LinkingMockDB implements PersistenceProvider {
99
100
  if (sql.includes('source_id IN')) {
100
101
  const half = p.length / 2;
101
102
  const ids = new Set(p.slice(0, half) as string[]);
102
- return this.links.filter(
103
- (l) => ids.has(l.source_id) || ids.has(l.target_id),
104
- ) as T[];
103
+ return this.links.filter((l) => ids.has(l.source_id) || ids.has(l.target_id)) as T[];
105
104
  }
106
105
  if (sql.includes('NOT IN')) {
107
106
  const limit = p[0] as number;
@@ -125,8 +124,12 @@ class LinkingMockDB implements PersistenceProvider {
125
124
  return [];
126
125
  }
127
126
 
128
- transaction<T>(fn: () => T): T { return fn(); }
129
- ftsSearch<T>(): T[] { return []; }
127
+ transaction<T>(fn: () => T): T {
128
+ return fn();
129
+ }
130
+ ftsSearch<T>(): T[] {
131
+ return [];
132
+ }
130
133
  ftsRebuild(): void {}
131
134
  close(): void {}
132
135
  }
@@ -200,7 +203,9 @@ describe('LinkManager', () => {
200
203
  // ── traverse ────────────────────────────────────────────────────────
201
204
 
202
205
  it('returns empty for entry with no links', () => {
203
- db.seedEntries([{ id: 'solo', title: 'Solo', type: 'pattern', domain: 'd', description: '', tags: '' }]);
206
+ db.seedEntries([
207
+ { id: 'solo', title: 'Solo', type: 'pattern', domain: 'd', description: '', tags: '' },
208
+ ]);
204
209
  expect(mgr.traverse('solo')).toEqual([]);
205
210
  });
206
211
 
@@ -293,8 +298,22 @@ describe('LinkManager', () => {
293
298
 
294
299
  it('suggests links based on FTS matches', () => {
295
300
  db.seedEntries([
296
- { id: 'e1', title: 'Accessibility Pattern', type: 'pattern', domain: 'a11y', description: 'Screen reader support', tags: '' },
297
- { id: 'e2', title: 'ARIA Rules', type: 'rule', domain: 'a11y', description: 'Always use ARIA labels', tags: '' },
301
+ {
302
+ id: 'e1',
303
+ title: 'Accessibility Pattern',
304
+ type: 'pattern',
305
+ domain: 'a11y',
306
+ description: 'Screen reader support',
307
+ tags: '',
308
+ },
309
+ {
310
+ id: 'e2',
311
+ title: 'ARIA Rules',
312
+ type: 'rule',
313
+ domain: 'a11y',
314
+ description: 'Always use ARIA labels',
315
+ tags: '',
316
+ },
298
317
  ]);
299
318
  const suggestions = mgr.suggestLinks('e1', 5);
300
319
  // e2 should be suggested (e1 is filtered as self)
@@ -329,8 +348,22 @@ describe('LinkManager', () => {
329
348
 
330
349
  it('dry run populates preview array', () => {
331
350
  db.seedEntries([
332
- { id: 'orphan', title: 'Orphan', type: 'pattern', domain: 'd', description: 'test content', tags: '' },
333
- { id: 'target', title: 'Target', type: 'rule', domain: 'd', description: 'test content', tags: '' },
351
+ {
352
+ id: 'orphan',
353
+ title: 'Orphan',
354
+ type: 'pattern',
355
+ domain: 'd',
356
+ description: 'test content',
357
+ tags: '',
358
+ },
359
+ {
360
+ id: 'target',
361
+ title: 'Target',
362
+ type: 'rule',
363
+ domain: 'd',
364
+ description: 'test content',
365
+ tags: '',
366
+ },
334
367
  ]);
335
368
  // Link target so orphan is the only orphan
336
369
  mgr.addLink('target', 'target', 'supports'); // self-link to exclude from orphans
@@ -21,9 +21,35 @@ import type {
21
21
 
22
22
  // ── Stop words for keyword extraction ─────────────────────────────────
23
23
  const STOP_WORDS = new Set([
24
- 'the', 'and', 'for', 'with', 'from', 'this', 'that', 'are', 'was', 'not',
25
- 'but', 'have', 'has', 'use', 'can', 'will', 'all', 'each', 'than', 'its',
26
- 'more', 'when', 'into', 'also', 'any', 'may', 'only', 'should', 'which',
24
+ 'the',
25
+ 'and',
26
+ 'for',
27
+ 'with',
28
+ 'from',
29
+ 'this',
30
+ 'that',
31
+ 'are',
32
+ 'was',
33
+ 'not',
34
+ 'but',
35
+ 'have',
36
+ 'has',
37
+ 'use',
38
+ 'can',
39
+ 'will',
40
+ 'all',
41
+ 'each',
42
+ 'than',
43
+ 'its',
44
+ 'more',
45
+ 'when',
46
+ 'into',
47
+ 'also',
48
+ 'any',
49
+ 'may',
50
+ 'only',
51
+ 'should',
52
+ 'which',
27
53
  ]);
28
54
 
29
55
  export class LinkManager {
@@ -165,7 +191,12 @@ export class LinkManager {
165
191
  nextFrontier.push(neighborId);
166
192
  const entry = this.getEntryMeta(neighborId);
167
193
  if (!entry) return;
168
- result.push({ ...entry, linkType: link.linkType, linkDirection: direction, linkNote: link.note });
194
+ result.push({
195
+ ...entry,
196
+ linkType: link.linkType,
197
+ linkDirection: direction,
198
+ linkNote: link.note,
199
+ });
169
200
  }
170
201
 
171
202
  // ── Bulk Queries ────────────────────────────────────────────────────
@@ -239,7 +270,11 @@ export class LinkManager {
239
270
  ): Array<{ id: string; title: string; type: string; domain: string; rank: number }> {
240
271
  const queryTerms = keywords.join(' OR ');
241
272
  return this.provider.all<{
242
- id: string; title: string; type: string; domain: string; rank: number;
273
+ id: string;
274
+ title: string;
275
+ type: string;
276
+ domain: string;
277
+ rank: number;
243
278
  }>(
244
279
  `SELECT e.id, e.title, e.type, e.domain, rank
245
280
  FROM entries_fts fts
@@ -285,7 +320,8 @@ export class LinkManager {
285
320
  const orphans = this.getOrphans(10000);
286
321
  let processed = 0;
287
322
  let linksCreated = 0;
288
- const preview: Array<{ sourceId: string; targetId: string; linkType: string; score: number }> = [];
323
+ const preview: Array<{ sourceId: string; targetId: string; linkType: string; score: number }> =
324
+ [];
289
325
 
290
326
  for (let i = 0; i < orphans.length; i += batchSize) {
291
327
  const batch = orphans.slice(i, i + batchSize);
@@ -317,7 +353,12 @@ export class LinkManager {
317
353
  const qualifying = suggestions.filter((s) => s.score >= threshold).slice(0, maxLinks);
318
354
  for (const s of qualifying) {
319
355
  if (dryRun) {
320
- preview.push({ sourceId: entryId, targetId: s.entryId, linkType: s.suggestedType, score: s.score });
356
+ preview.push({
357
+ sourceId: entryId,
358
+ targetId: s.entryId,
359
+ linkType: s.suggestedType,
360
+ score: s.score,
361
+ });
321
362
  } else {
322
363
  this.addLink(entryId, s.entryId, s.suggestedType);
323
364
  }
@@ -278,9 +278,12 @@ describe('ObsidianSync', () => {
278
278
  const sync = new ObsidianSync({ vault: mockVault });
279
279
  const result = sync.import(obsidianDir);
280
280
  expect(result.updated).toBe(1);
281
- expect(mockVault.update).toHaveBeenCalledWith('existing', expect.objectContaining({
282
- title: 'Updated Title',
283
- }));
281
+ expect(mockVault.update).toHaveBeenCalledWith(
282
+ 'existing',
283
+ expect.objectContaining({
284
+ title: 'Updated Title',
285
+ }),
286
+ );
284
287
  });
285
288
 
286
289
  it('skips files without title or description', () => {
@@ -90,9 +90,7 @@ describe('detectScope', () => {
90
90
  });
91
91
 
92
92
  it('detects agent tier for home directory paths', () => {
93
- const result = detectScope(
94
- makeInput({ description: 'Config lives in ~/dotfiles/zshrc' }),
95
- );
93
+ const result = detectScope(makeInput({ description: 'Config lives in ~/dotfiles/zshrc' }));
96
94
  expect(result.tier).toBe('agent');
97
95
  });
98
96
 
@@ -98,7 +98,9 @@ class BranchingMockDB implements PersistenceProvider {
98
98
  return fn();
99
99
  }
100
100
 
101
- ftsSearch<T>(): T[] { return []; }
101
+ ftsSearch<T>(): T[] {
102
+ return [];
103
+ }
102
104
  ftsRebuild(): void {}
103
105
  close(): void {}
104
106
 
@@ -135,7 +137,7 @@ describe('VaultBranching', () => {
135
137
 
136
138
  it('throws when creating duplicate active branch', () => {
137
139
  branching.branch('feature-x');
138
- expect(() => branching.branch('feature-x')).toThrow("already exists");
140
+ expect(() => branching.branch('feature-x')).toThrow('already exists');
139
141
  });
140
142
 
141
143
  // ── addOperation ────────────────────────────────────────────────────
@@ -159,14 +161,14 @@ describe('VaultBranching', () => {
159
161
 
160
162
  it('throws when adding to non-existent branch', () => {
161
163
  expect(() => branching.addOperation('missing', 'e1', 'add', makeEntry('e1'))).toThrow(
162
- "does not exist",
164
+ 'does not exist',
163
165
  );
164
166
  });
165
167
 
166
168
  it('throws when add/modify has no entry data', () => {
167
169
  branching.branch('b1');
168
- expect(() => branching.addOperation('b1', 'e1', 'add')).toThrow("Entry data required");
169
- expect(() => branching.addOperation('b1', 'e1', 'modify')).toThrow("Entry data required");
170
+ expect(() => branching.addOperation('b1', 'e1', 'add')).toThrow('Entry data required');
171
+ expect(() => branching.addOperation('b1', 'e1', 'modify')).toThrow('Entry data required');
170
172
  });
171
173
 
172
174
  // ── listEntries ─────────────────────────────────────────────────────
@@ -226,13 +228,13 @@ describe('VaultBranching', () => {
226
228
  });
227
229
 
228
230
  it('throws when merging non-existent branch', () => {
229
- expect(() => branching.merge('missing')).toThrow("does not exist");
231
+ expect(() => branching.merge('missing')).toThrow('does not exist');
230
232
  });
231
233
 
232
234
  it('throws when merging already-merged branch', () => {
233
235
  branching.branch('b1');
234
236
  branching.merge('b1');
235
- expect(() => branching.merge('b1')).toThrow("already merged");
237
+ expect(() => branching.merge('b1')).toThrow('already merged');
236
238
  });
237
239
 
238
240
  // ── deleteBranch ────────────────────────────────────────────────────