@skillsmith/core 0.4.16 → 0.5.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 (285) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +57 -2
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/api/client.d.ts +21 -21
  5. package/dist/src/api/client.d.ts.map +1 -1
  6. package/dist/src/api/client.events.d.ts +39 -0
  7. package/dist/src/api/client.events.d.ts.map +1 -0
  8. package/dist/src/api/client.events.js +77 -0
  9. package/dist/src/api/client.events.js.map +1 -0
  10. package/dist/src/api/client.js +39 -33
  11. package/dist/src/api/client.js.map +1 -1
  12. package/dist/src/api/event-batcher.d.ts +81 -0
  13. package/dist/src/api/event-batcher.d.ts.map +1 -0
  14. package/dist/src/api/event-batcher.js +191 -0
  15. package/dist/src/api/event-batcher.js.map +1 -0
  16. package/dist/src/api/index.d.ts +1 -0
  17. package/dist/src/api/index.d.ts.map +1 -1
  18. package/dist/src/api/index.js +2 -0
  19. package/dist/src/api/index.js.map +1 -1
  20. package/dist/src/api/schemas.d.ts +62 -4
  21. package/dist/src/api/schemas.d.ts.map +1 -1
  22. package/dist/src/api/schemas.js +45 -0
  23. package/dist/src/api/schemas.js.map +1 -1
  24. package/dist/src/db/migration-runner.d.ts +44 -0
  25. package/dist/src/db/migration-runner.d.ts.map +1 -0
  26. package/dist/src/db/migration-runner.js +175 -0
  27. package/dist/src/db/migration-runner.js.map +1 -0
  28. package/dist/src/db/migration.d.ts.map +1 -1
  29. package/dist/src/db/migration.js +2 -1
  30. package/dist/src/db/migration.js.map +1 -1
  31. package/dist/src/db/migrations/v12-risk-score-history.d.ts +10 -0
  32. package/dist/src/db/migrations/v12-risk-score-history.d.ts.map +1 -0
  33. package/dist/src/db/migrations/v12-risk-score-history.js +25 -0
  34. package/dist/src/db/migrations/v12-risk-score-history.js.map +1 -0
  35. package/dist/src/db/migrations/v13-team-tables.d.ts +11 -0
  36. package/dist/src/db/migrations/v13-team-tables.d.ts.map +1 -0
  37. package/dist/src/db/migrations/v13-team-tables.js +14 -0
  38. package/dist/src/db/migrations/v13-team-tables.js.map +1 -0
  39. package/dist/src/db/schema-sql.d.ts +16 -0
  40. package/dist/src/db/schema-sql.d.ts.map +1 -0
  41. package/dist/src/db/schema-sql.js +161 -0
  42. package/dist/src/db/schema-sql.js.map +1 -0
  43. package/dist/src/db/schema.d.ts +7 -32
  44. package/dist/src/db/schema.d.ts.map +1 -1
  45. package/dist/src/db/schema.js +14 -298
  46. package/dist/src/db/schema.js.map +1 -1
  47. package/dist/src/embeddings/hnsw-store.d.ts +1 -1
  48. package/dist/src/embeddings/hnsw-store.d.ts.map +1 -1
  49. package/dist/src/embeddings/hnsw-store.js +4 -34
  50. package/dist/src/embeddings/hnsw-store.js.map +1 -1
  51. package/dist/src/embeddings/hnsw-store.types.d.ts +18 -0
  52. package/dist/src/embeddings/hnsw-store.types.d.ts.map +1 -1
  53. package/dist/src/embeddings/hnsw-store.types.js.map +1 -1
  54. package/dist/src/exports/repositories.d.ts +1 -0
  55. package/dist/src/exports/repositories.d.ts.map +1 -1
  56. package/dist/src/exports/repositories.js +4 -0
  57. package/dist/src/exports/repositories.js.map +1 -1
  58. package/dist/src/exports/services.d.ts +4 -0
  59. package/dist/src/exports/services.d.ts.map +1 -1
  60. package/dist/src/exports/services.js +7 -0
  61. package/dist/src/exports/services.js.map +1 -1
  62. package/dist/src/index.d.ts +1 -1
  63. package/dist/src/index.js +1 -1
  64. package/dist/src/learning/PatternStore.d.ts.map +1 -1
  65. package/dist/src/learning/PatternStore.js +2 -9
  66. package/dist/src/learning/PatternStore.js.map +1 -1
  67. package/dist/src/repositories/RiskScoreHistoryRepository.d.ts +37 -0
  68. package/dist/src/repositories/RiskScoreHistoryRepository.d.ts.map +1 -0
  69. package/dist/src/repositories/RiskScoreHistoryRepository.js +66 -0
  70. package/dist/src/repositories/RiskScoreHistoryRepository.js.map +1 -0
  71. package/dist/src/routing/SONARouter.d.ts.map +1 -1
  72. package/dist/src/routing/SONARouter.js +4 -15
  73. package/dist/src/routing/SONARouter.js.map +1 -1
  74. package/dist/src/scoring/index.d.ts +1 -0
  75. package/dist/src/scoring/index.d.ts.map +1 -1
  76. package/dist/src/scoring/index.js +1 -0
  77. package/dist/src/scoring/index.js.map +1 -1
  78. package/dist/src/scoring/quality-score.d.ts +49 -0
  79. package/dist/src/scoring/quality-score.d.ts.map +1 -0
  80. package/dist/src/scoring/quality-score.js +73 -0
  81. package/dist/src/scoring/quality-score.js.map +1 -0
  82. package/dist/src/scripts/__tests__/scan-imported-skills.test.js +10 -0
  83. package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
  84. package/dist/src/scripts/validation/types.d.ts +2 -2
  85. package/dist/src/security/index.d.ts +2 -0
  86. package/dist/src/security/index.d.ts.map +1 -1
  87. package/dist/src/security/index.js +2 -0
  88. package/dist/src/security/index.js.map +1 -1
  89. package/dist/src/security/risk-trend.d.ts +21 -0
  90. package/dist/src/security/risk-trend.d.ts.map +1 -0
  91. package/dist/src/security/risk-trend.js +81 -0
  92. package/dist/src/security/risk-trend.js.map +1 -0
  93. package/dist/src/security/scanner/SecurityScanner.d.ts +6 -2
  94. package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
  95. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts +24 -2
  96. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
  97. package/dist/src/security/scanner/SecurityScanner.helpers.js +111 -9
  98. package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
  99. package/dist/src/security/scanner/SecurityScanner.js +64 -71
  100. package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
  101. package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts +15 -0
  102. package/dist/src/security/scanner/SecurityScanner.ssrf.d.ts.map +1 -0
  103. package/dist/src/security/scanner/SecurityScanner.ssrf.js +76 -0
  104. package/dist/src/security/scanner/SecurityScanner.ssrf.js.map +1 -0
  105. package/dist/src/security/scanner/index.d.ts +1 -1
  106. package/dist/src/security/scanner/index.d.ts.map +1 -1
  107. package/dist/src/security/scanner/index.js +1 -1
  108. package/dist/src/security/scanner/index.js.map +1 -1
  109. package/dist/src/security/scanner/patterns.d.ts +12 -0
  110. package/dist/src/security/scanner/patterns.d.ts.map +1 -1
  111. package/dist/src/security/scanner/patterns.js +57 -0
  112. package/dist/src/security/scanner/patterns.js.map +1 -1
  113. package/dist/src/security/scanner/types.d.ts +3 -1
  114. package/dist/src/security/scanner/types.d.ts.map +1 -1
  115. package/dist/src/security/scanner/weights.d.ts.map +1 -1
  116. package/dist/src/security/scanner/weights.js +2 -0
  117. package/dist/src/security/scanner/weights.js.map +1 -1
  118. package/dist/src/services/skill-config-schema.d.ts +36 -0
  119. package/dist/src/services/skill-config-schema.d.ts.map +1 -0
  120. package/dist/src/services/skill-config-schema.js +76 -0
  121. package/dist/src/services/skill-config-schema.js.map +1 -0
  122. package/dist/src/services/skill-installation.feedback.d.ts +24 -0
  123. package/dist/src/services/skill-installation.feedback.d.ts.map +1 -0
  124. package/dist/src/services/skill-installation.feedback.js +37 -0
  125. package/dist/src/services/skill-installation.feedback.js.map +1 -0
  126. package/dist/src/services/skill-installation.helpers.d.ts +88 -0
  127. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -0
  128. package/dist/src/services/skill-installation.helpers.js +377 -0
  129. package/dist/src/services/skill-installation.helpers.js.map +1 -0
  130. package/dist/src/services/skill-installation.service.d.ts +37 -0
  131. package/dist/src/services/skill-installation.service.d.ts.map +1 -0
  132. package/dist/src/services/skill-installation.service.js +432 -0
  133. package/dist/src/services/skill-installation.service.js.map +1 -0
  134. package/dist/src/services/skill-installation.types.d.ts +166 -0
  135. package/dist/src/services/skill-installation.types.d.ts.map +1 -0
  136. package/dist/src/services/skill-installation.types.js +38 -0
  137. package/dist/src/services/skill-installation.types.js.map +1 -0
  138. package/dist/src/services/skill-manifest.d.ts +20 -0
  139. package/dist/src/services/skill-manifest.d.ts.map +1 -0
  140. package/dist/src/services/skill-manifest.js +84 -0
  141. package/dist/src/services/skill-manifest.js.map +1 -0
  142. package/dist/src/session/SessionManager.helpers.d.ts +1 -27
  143. package/dist/src/session/SessionManager.helpers.d.ts.map +1 -1
  144. package/dist/src/session/SessionManager.helpers.js +0 -64
  145. package/dist/src/session/SessionManager.helpers.js.map +1 -1
  146. package/dist/src/session/SessionManager.memory.d.ts +12 -11
  147. package/dist/src/session/SessionManager.memory.d.ts.map +1 -1
  148. package/dist/src/session/SessionManager.memory.js +23 -115
  149. package/dist/src/session/SessionManager.memory.js.map +1 -1
  150. package/dist/src/session/SessionManager.types.d.ts +0 -37
  151. package/dist/src/session/SessionManager.types.d.ts.map +1 -1
  152. package/dist/src/session/SessionManager.types.js.map +1 -1
  153. package/dist/src/session/SessionRecovery.js +4 -4
  154. package/dist/src/session/SessionRecovery.js.map +1 -1
  155. package/dist/src/testing/MultiLLMProvider.d.ts.map +1 -1
  156. package/dist/src/testing/MultiLLMProvider.js +5 -19
  157. package/dist/src/testing/MultiLLMProvider.js.map +1 -1
  158. package/dist/src/types.d.ts +2 -0
  159. package/dist/src/types.d.ts.map +1 -1
  160. package/dist/tests/SecurityScanner.ai-defence.test.d.ts +6 -0
  161. package/dist/tests/SecurityScanner.ai-defence.test.d.ts.map +1 -0
  162. package/dist/tests/SecurityScanner.ai-defence.test.js +221 -0
  163. package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -0
  164. package/dist/tests/SecurityScanner.performance.test.d.ts +6 -0
  165. package/dist/tests/SecurityScanner.performance.test.d.ts.map +1 -0
  166. package/dist/tests/SecurityScanner.performance.test.js +132 -0
  167. package/dist/tests/SecurityScanner.performance.test.js.map +1 -0
  168. package/dist/tests/SecurityScanner.scoring.test.d.ts +6 -0
  169. package/dist/tests/SecurityScanner.scoring.test.d.ts.map +1 -0
  170. package/dist/tests/SecurityScanner.scoring.test.js +197 -0
  171. package/dist/tests/SecurityScanner.scoring.test.js.map +1 -0
  172. package/dist/tests/SecurityScanner.test.d.ts +2 -2
  173. package/dist/tests/SecurityScanner.test.js +2 -520
  174. package/dist/tests/SecurityScanner.test.js.map +1 -1
  175. package/dist/tests/SkillMatcher.test.js +5 -5
  176. package/dist/tests/SkillMatcher.test.js.map +1 -1
  177. package/dist/tests/billing/StripeClient.test.d.ts +18 -0
  178. package/dist/tests/billing/StripeClient.test.d.ts.map +1 -0
  179. package/dist/tests/billing/StripeClient.test.js +566 -0
  180. package/dist/tests/billing/StripeClient.test.js.map +1 -0
  181. package/dist/tests/billing/StripeWebhookHandler.test.d.ts +16 -0
  182. package/dist/tests/billing/StripeWebhookHandler.test.d.ts.map +1 -0
  183. package/dist/tests/billing/StripeWebhookHandler.test.js +240 -0
  184. package/dist/tests/billing/StripeWebhookHandler.test.js.map +1 -0
  185. package/dist/tests/billing/stripe-helpers.test.d.ts +7 -0
  186. package/dist/tests/billing/stripe-helpers.test.d.ts.map +1 -0
  187. package/dist/tests/billing/stripe-helpers.test.js +91 -0
  188. package/dist/tests/billing/stripe-helpers.test.js.map +1 -0
  189. package/dist/tests/billing/webhook-handlers.test.d.ts +16 -0
  190. package/dist/tests/billing/webhook-handlers.test.d.ts.map +1 -0
  191. package/dist/tests/billing/webhook-handlers.test.js +519 -0
  192. package/dist/tests/billing/webhook-handlers.test.js.map +1 -0
  193. package/dist/tests/db/migration.test.d.ts +11 -0
  194. package/dist/tests/db/migration.test.d.ts.map +1 -0
  195. package/dist/tests/db/migration.test.js +265 -0
  196. package/dist/tests/db/migration.test.js.map +1 -0
  197. package/dist/tests/db/schema-migrations.test.js +8 -6
  198. package/dist/tests/db/schema-migrations.test.js.map +1 -1
  199. package/dist/tests/integration/events-batch-contract.test.d.ts +12 -0
  200. package/dist/tests/integration/events-batch-contract.test.d.ts.map +1 -0
  201. package/dist/tests/integration/events-batch-contract.test.js +69 -0
  202. package/dist/tests/integration/events-batch-contract.test.js.map +1 -0
  203. package/dist/tests/scoring/quality-score.test.d.ts +7 -0
  204. package/dist/tests/scoring/quality-score.test.d.ts.map +1 -0
  205. package/dist/tests/scoring/quality-score.test.js +78 -0
  206. package/dist/tests/scoring/quality-score.test.js.map +1 -0
  207. package/dist/tests/security/ContinuousSecurity.false-positives.test.d.ts +6 -0
  208. package/dist/tests/security/ContinuousSecurity.false-positives.test.d.ts.map +1 -0
  209. package/dist/tests/security/ContinuousSecurity.false-positives.test.js +89 -0
  210. package/dist/tests/security/ContinuousSecurity.false-positives.test.js.map +1 -0
  211. package/dist/tests/security/ContinuousSecurity.performance.test.d.ts +6 -0
  212. package/dist/tests/security/ContinuousSecurity.performance.test.d.ts.map +1 -0
  213. package/dist/tests/security/ContinuousSecurity.performance.test.js +177 -0
  214. package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -0
  215. package/dist/tests/security/ContinuousSecurity.reporting.test.d.ts +6 -0
  216. package/dist/tests/security/ContinuousSecurity.reporting.test.d.ts.map +1 -0
  217. package/dist/tests/security/ContinuousSecurity.reporting.test.js +106 -0
  218. package/dist/tests/security/ContinuousSecurity.reporting.test.js.map +1 -0
  219. package/dist/tests/security/ContinuousSecurity.test.d.ts +9 -2
  220. package/dist/tests/security/ContinuousSecurity.test.d.ts.map +1 -1
  221. package/dist/tests/security/ContinuousSecurity.test.js +9 -336
  222. package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
  223. package/dist/tests/security/pii-detection.test.d.ts +7 -0
  224. package/dist/tests/security/pii-detection.test.d.ts.map +1 -0
  225. package/dist/tests/security/pii-detection.test.js +91 -0
  226. package/dist/tests/security/pii-detection.test.js.map +1 -0
  227. package/dist/tests/security/risk-trend.test.d.ts +6 -0
  228. package/dist/tests/security/risk-trend.test.d.ts.map +1 -0
  229. package/dist/tests/security/risk-trend.test.js +68 -0
  230. package/dist/tests/security/risk-trend.test.js.map +1 -0
  231. package/dist/tests/security/scanner-regression-guard.test.d.ts +12 -0
  232. package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -0
  233. package/dist/tests/security/scanner-regression-guard.test.js +111 -0
  234. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -0
  235. package/dist/tests/security.test.js +200 -0
  236. package/dist/tests/security.test.js.map +1 -1
  237. package/dist/tests/services/aidefence-feedback.test.d.ts +6 -0
  238. package/dist/tests/services/aidefence-feedback.test.d.ts.map +1 -0
  239. package/dist/tests/services/aidefence-feedback.test.js +115 -0
  240. package/dist/tests/services/aidefence-feedback.test.js.map +1 -0
  241. package/dist/tests/services/dep-quarantine-check.test.d.ts +5 -0
  242. package/dist/tests/services/dep-quarantine-check.test.d.ts.map +1 -0
  243. package/dist/tests/services/dep-quarantine-check.test.js +92 -0
  244. package/dist/tests/services/dep-quarantine-check.test.js.map +1 -0
  245. package/dist/tests/services/skill-config-schema.test.d.ts +5 -0
  246. package/dist/tests/services/skill-config-schema.test.d.ts.map +1 -0
  247. package/dist/tests/services/skill-config-schema.test.js +98 -0
  248. package/dist/tests/services/skill-config-schema.test.js.map +1 -0
  249. package/dist/tests/session/SessionManager.helpers.test.js +1 -9
  250. package/dist/tests/session/SessionManager.helpers.test.js.map +1 -1
  251. package/dist/tests/session/SessionManager.memory.test.d.ts +3 -4
  252. package/dist/tests/session/SessionManager.memory.test.d.ts.map +1 -1
  253. package/dist/tests/session/SessionManager.memory.test.js +41 -123
  254. package/dist/tests/session/SessionManager.memory.test.js.map +1 -1
  255. package/dist/tests/sync/BackgroundSyncService.test.d.ts +13 -0
  256. package/dist/tests/sync/BackgroundSyncService.test.d.ts.map +1 -0
  257. package/dist/tests/sync/BackgroundSyncService.test.js +259 -0
  258. package/dist/tests/sync/BackgroundSyncService.test.js.map +1 -0
  259. package/dist/tests/testkit.d.ts +14 -0
  260. package/dist/tests/testkit.d.ts.map +1 -0
  261. package/dist/tests/testkit.js +14 -0
  262. package/dist/tests/testkit.js.map +1 -0
  263. package/dist/tests/unit/api-client-events.test.d.ts +10 -0
  264. package/dist/tests/unit/api-client-events.test.d.ts.map +1 -0
  265. package/dist/tests/unit/api-client-events.test.js +73 -0
  266. package/dist/tests/unit/api-client-events.test.js.map +1 -0
  267. package/dist/tests/unit/event-batcher.test.d.ts +13 -0
  268. package/dist/tests/unit/event-batcher.test.d.ts.map +1 -0
  269. package/dist/tests/unit/event-batcher.test.js +155 -0
  270. package/dist/tests/unit/event-batcher.test.js.map +1 -0
  271. package/dist/tests/unit/migrations/v10-dependencies.test.js +3 -3
  272. package/dist/tests/unit/migrations/v10-dependencies.test.js.map +1 -1
  273. package/dist/tests/unit/services/skill-installation-extended.test.d.ts +8 -0
  274. package/dist/tests/unit/services/skill-installation-extended.test.d.ts.map +1 -0
  275. package/dist/tests/unit/services/skill-installation-extended.test.js +423 -0
  276. package/dist/tests/unit/services/skill-installation-extended.test.js.map +1 -0
  277. package/dist/tests/unit/services/skill-installation.service.test.d.ts +8 -0
  278. package/dist/tests/unit/services/skill-installation.service.test.d.ts.map +1 -0
  279. package/dist/tests/unit/services/skill-installation.service.test.js +342 -0
  280. package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -0
  281. package/package.json +22 -10
  282. package/dist/vitest.config.d.ts +0 -3
  283. package/dist/vitest.config.d.ts.map +0 -1
  284. package/dist/vitest.config.js +0 -13
  285. package/dist/vitest.config.js.map +0 -1
@@ -0,0 +1,259 @@
1
+ /**
2
+ * SMI-3416: BackgroundSyncService Tests
3
+ *
4
+ * Tests for session-based automatic sync service:
5
+ * - Start/stop lifecycle
6
+ * - Sync-on-start behavior
7
+ * - Periodic check and sync triggering
8
+ * - Concurrent sync prevention
9
+ * - Manual sync
10
+ * - Error handling and callbacks
11
+ */
12
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
13
+ import { BackgroundSyncService, createBackgroundSyncService, } from '../../src/sync/BackgroundSyncService.js';
14
+ /** Flush microtask queue so fire-and-forget promises resolve */
15
+ function flushPromises() {
16
+ return new Promise((resolve) => setImmediate(resolve));
17
+ }
18
+ // ============================================================================
19
+ // Mock Factories
20
+ // ============================================================================
21
+ function createMockSyncResult(overrides) {
22
+ return {
23
+ success: true,
24
+ skillsAdded: 2,
25
+ skillsUpdated: 1,
26
+ skillsUnchanged: 10,
27
+ totalProcessed: 13,
28
+ durationMs: 150,
29
+ errors: [],
30
+ dryRun: false,
31
+ ...overrides,
32
+ };
33
+ }
34
+ function createMockSyncEngine(result) {
35
+ return {
36
+ sync: vi.fn().mockResolvedValue(result ?? createMockSyncResult()),
37
+ };
38
+ }
39
+ function createMockConfigRepo(overrides) {
40
+ const enabled = overrides?.enabled ?? true;
41
+ const lastSyncAt = overrides?.lastSyncAt ?? '2026-03-16T00:00:00Z';
42
+ const isSyncDue = overrides?.isSyncDue ?? false;
43
+ return {
44
+ getConfig: vi.fn().mockReturnValue({
45
+ enabled,
46
+ frequency: 'daily',
47
+ intervalMs: 86400000,
48
+ lastSyncAt,
49
+ }),
50
+ isSyncDue: vi.fn().mockReturnValue(isSyncDue),
51
+ };
52
+ }
53
+ // ============================================================================
54
+ // Tests
55
+ // ============================================================================
56
+ describe('BackgroundSyncService', () => {
57
+ beforeEach(() => {
58
+ vi.useFakeTimers();
59
+ });
60
+ afterEach(() => {
61
+ vi.useRealTimers();
62
+ });
63
+ describe('start/stop lifecycle', () => {
64
+ it('should start and report isStarted', () => {
65
+ const service = new BackgroundSyncService(createMockSyncEngine(), createMockConfigRepo(), {
66
+ syncOnStart: false,
67
+ });
68
+ service.start();
69
+ expect(service.isServiceStarted()).toBe(true);
70
+ service.stop();
71
+ expect(service.isServiceStarted()).toBe(false);
72
+ });
73
+ it('should not start if auto-sync is disabled', () => {
74
+ const service = new BackgroundSyncService(createMockSyncEngine(), createMockConfigRepo({ enabled: false }), { syncOnStart: false });
75
+ service.start();
76
+ expect(service.isServiceStarted()).toBe(false);
77
+ });
78
+ it('should ignore duplicate start calls', () => {
79
+ const service = new BackgroundSyncService(createMockSyncEngine(), createMockConfigRepo(), {
80
+ syncOnStart: false,
81
+ });
82
+ service.start();
83
+ service.start(); // should not throw
84
+ expect(service.isServiceStarted()).toBe(true);
85
+ service.stop();
86
+ });
87
+ });
88
+ describe('sync-on-start', () => {
89
+ // These tests use real timers since triggerSync is fire-and-forget
90
+ // and fake timers interfere with promise resolution
91
+ beforeEach(() => {
92
+ vi.useRealTimers();
93
+ });
94
+ afterEach(() => {
95
+ vi.useFakeTimers();
96
+ });
97
+ it('should trigger sync immediately if due on start', async () => {
98
+ const engine = createMockSyncEngine();
99
+ const service = new BackgroundSyncService(engine, createMockConfigRepo({ isSyncDue: true }), {
100
+ syncOnStart: true,
101
+ });
102
+ service.start();
103
+ await flushPromises();
104
+ expect(engine.sync).toHaveBeenCalledOnce();
105
+ service.stop();
106
+ });
107
+ it('should not trigger sync on start if not due', async () => {
108
+ const engine = createMockSyncEngine();
109
+ const service = new BackgroundSyncService(engine, createMockConfigRepo({ isSyncDue: false }), { syncOnStart: true });
110
+ service.start();
111
+ await flushPromises();
112
+ expect(engine.sync).not.toHaveBeenCalled();
113
+ service.stop();
114
+ });
115
+ it('should recognize never-synced as sync-due via shouldSyncNow', () => {
116
+ // When lastSyncAt is null, shouldSyncNow returns true immediately
117
+ // (without checking isSyncDue). Verified via manualSync integration test.
118
+ const engine = createMockSyncEngine();
119
+ const service = new BackgroundSyncService(engine, createMockConfigRepo({ lastSyncAt: null }), { syncOnStart: false } // Don't auto-fire; test manualSync instead
120
+ );
121
+ // manualSync directly calls sync, confirming the engine integration
122
+ const syncPromise = service.manualSync();
123
+ expect(engine.sync).toHaveBeenCalledOnce();
124
+ return syncPromise;
125
+ });
126
+ });
127
+ describe('periodic checks', () => {
128
+ it('should check and sync on interval', async () => {
129
+ const engine = createMockSyncEngine();
130
+ const configRepo = createMockConfigRepo({ isSyncDue: false });
131
+ const service = new BackgroundSyncService(engine, configRepo, {
132
+ syncOnStart: false,
133
+ checkIntervalMs: 1000,
134
+ });
135
+ service.start();
136
+ // First interval — not due
137
+ await vi.advanceTimersByTimeAsync(1000);
138
+ expect(engine.sync).not.toHaveBeenCalled();
139
+ configRepo.isSyncDue.mockReturnValue(true);
140
+ await vi.advanceTimersByTimeAsync(1000);
141
+ expect(engine.sync).toHaveBeenCalledOnce();
142
+ service.stop();
143
+ });
144
+ it('should not sync after stop', async () => {
145
+ const engine = createMockSyncEngine();
146
+ const service = new BackgroundSyncService(engine, createMockConfigRepo({ isSyncDue: true }), {
147
+ syncOnStart: false,
148
+ checkIntervalMs: 1000,
149
+ });
150
+ service.start();
151
+ service.stop();
152
+ await vi.advanceTimersByTimeAsync(5000);
153
+ expect(engine.sync).not.toHaveBeenCalled();
154
+ });
155
+ });
156
+ describe('callbacks', () => {
157
+ beforeEach(() => {
158
+ vi.useRealTimers();
159
+ });
160
+ afterEach(() => {
161
+ vi.useFakeTimers();
162
+ });
163
+ it('should call onSyncComplete on success', async () => {
164
+ const onComplete = vi.fn();
165
+ const result = createMockSyncResult();
166
+ const service = new BackgroundSyncService(createMockSyncEngine(result), createMockConfigRepo({ isSyncDue: true }), { syncOnStart: true, onSyncComplete: onComplete });
167
+ service.start();
168
+ await flushPromises();
169
+ expect(onComplete).toHaveBeenCalledWith(result);
170
+ service.stop();
171
+ });
172
+ it('should call onSyncError on failure', async () => {
173
+ const onError = vi.fn();
174
+ const engine = {
175
+ sync: vi.fn().mockRejectedValue(new Error('Network timeout')),
176
+ };
177
+ const service = new BackgroundSyncService(engine, createMockConfigRepo({ isSyncDue: true }), {
178
+ syncOnStart: true,
179
+ onSyncError: onError,
180
+ });
181
+ service.start();
182
+ await flushPromises();
183
+ expect(onError).toHaveBeenCalledWith(expect.objectContaining({ message: 'Network timeout' }));
184
+ service.stop();
185
+ });
186
+ });
187
+ describe('manualSync', () => {
188
+ it('should execute sync and return result', async () => {
189
+ const result = createMockSyncResult();
190
+ const service = new BackgroundSyncService(createMockSyncEngine(result), createMockConfigRepo(), { syncOnStart: false });
191
+ const syncResult = await service.manualSync();
192
+ expect(syncResult).toEqual(result);
193
+ });
194
+ it('should throw if sync already in progress', async () => {
195
+ let resolveSync;
196
+ const engine = {
197
+ sync: vi.fn().mockReturnValue(new Promise((resolve) => {
198
+ resolveSync = () => resolve(createMockSyncResult());
199
+ })),
200
+ };
201
+ const service = new BackgroundSyncService(engine, createMockConfigRepo(), {
202
+ syncOnStart: false,
203
+ });
204
+ const firstSync = service.manualSync();
205
+ await expect(service.manualSync()).rejects.toThrow('Sync already in progress');
206
+ resolveSync();
207
+ await firstSync;
208
+ });
209
+ it('should propagate sync errors', async () => {
210
+ const engine = {
211
+ sync: vi.fn().mockRejectedValue(new Error('DB locked')),
212
+ };
213
+ const service = new BackgroundSyncService(engine, createMockConfigRepo(), {
214
+ syncOnStart: false,
215
+ });
216
+ await expect(service.manualSync()).rejects.toThrow('DB locked');
217
+ });
218
+ });
219
+ describe('state tracking', () => {
220
+ it('should track checksPerformed and syncsTriggered', async () => {
221
+ const service = new BackgroundSyncService(createMockSyncEngine(), createMockConfigRepo({ isSyncDue: true }), { syncOnStart: false, checkIntervalMs: 100 });
222
+ service.start();
223
+ await vi.advanceTimersByTimeAsync(100);
224
+ const state = service.getState();
225
+ expect(state.checksPerformed).toBe(1);
226
+ expect(state.syncsTriggered).toBe(1);
227
+ service.stop();
228
+ });
229
+ it('should track lastResult after successful sync', async () => {
230
+ const result = createMockSyncResult({ skillsAdded: 5 });
231
+ const service = new BackgroundSyncService(createMockSyncEngine(result), createMockConfigRepo(), { syncOnStart: false });
232
+ await service.manualSync();
233
+ const state = service.getState();
234
+ expect(state.lastResult).toEqual(result);
235
+ expect(state.lastError).toBeNull();
236
+ });
237
+ it('should track lastError after failed sync', async () => {
238
+ const engine = {
239
+ sync: vi.fn().mockRejectedValue(new Error('fail')),
240
+ };
241
+ const service = new BackgroundSyncService(engine, createMockConfigRepo(), {
242
+ syncOnStart: false,
243
+ });
244
+ await service.manualSync().catch(() => { });
245
+ const state = service.getState();
246
+ expect(state.lastError?.message).toBe('fail');
247
+ });
248
+ });
249
+ describe('createBackgroundSyncService factory', () => {
250
+ it('should create and start service', () => {
251
+ const service = createBackgroundSyncService(createMockSyncEngine(), createMockConfigRepo(), {
252
+ syncOnStart: false,
253
+ });
254
+ expect(service.isServiceStarted()).toBe(true);
255
+ service.stop();
256
+ });
257
+ });
258
+ });
259
+ //# sourceMappingURL=BackgroundSyncService.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackgroundSyncService.test.js","sourceRoot":"","sources":["../../../tests/sync/BackgroundSyncService.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Test helper re-exports for cross-package test use
3
+ * @module @skillsmith/core/testkit
4
+ * @see SMI-3218
5
+ *
6
+ * Re-exports database test helpers so sibling packages (CLI, mcp-server)
7
+ * can import via `@skillsmith/core/testkit` instead of relative paths.
8
+ *
9
+ * Boundary: This subpath is for database test setup (createTestDatabase,
10
+ * closeDatabase). For MultiLLMProvider test utilities, use
11
+ * `@skillsmith/core/testing`.
12
+ */
13
+ export { createTestDatabase, closeDatabase } from './helpers/database.js';
14
+ //# sourceMappingURL=testkit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testkit.d.ts","sourceRoot":"","sources":["../../tests/testkit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Test helper re-exports for cross-package test use
3
+ * @module @skillsmith/core/testkit
4
+ * @see SMI-3218
5
+ *
6
+ * Re-exports database test helpers so sibling packages (CLI, mcp-server)
7
+ * can import via `@skillsmith/core/testkit` instead of relative paths.
8
+ *
9
+ * Boundary: This subpath is for database test setup (createTestDatabase,
10
+ * closeDatabase). For MultiLLMProvider test utilities, use
11
+ * `@skillsmith/core/testing`.
12
+ */
13
+ export { createTestDatabase, closeDatabase } from './helpers/database.js';
14
+ //# sourceMappingURL=testkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testkit.js","sourceRoot":"","sources":["../../tests/testkit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SMI-4119: SkillsmithApiClient event-batching integration tests.
3
+ *
4
+ * Verifies:
5
+ * - `recordEvent()` enqueues without an immediate POST.
6
+ * - `flushEvents()` drains the queue and issues a single POST with
7
+ * `X-Skillsmith-Batched: true` and `{ events: [...] }` body.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=api-client-events.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client-events.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/api-client-events.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * SMI-4119: SkillsmithApiClient event-batching integration tests.
3
+ *
4
+ * Verifies:
5
+ * - `recordEvent()` enqueues without an immediate POST.
6
+ * - `flushEvents()` drains the queue and issues a single POST with
7
+ * `X-Skillsmith-Batched: true` and `{ events: [...] }` body.
8
+ */
9
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
10
+ import { SkillsmithApiClient } from '../../src/api/client.js';
11
+ describe('SMI-4119: SkillsmithApiClient event batching', () => {
12
+ const originalFetch = globalThis.fetch;
13
+ let fetchMock;
14
+ // SMI-4119: Track clients so we can dispose the batcher after each test.
15
+ // Without dispose() the batcher keeps `beforeExit` / `SIGINT` / `SIGTERM`
16
+ // listeners on `process`, leaking across tests and triggering
17
+ // MaxListenersExceededWarning in long Vitest runs.
18
+ const clients = [];
19
+ beforeEach(() => {
20
+ fetchMock = vi
21
+ .fn()
22
+ .mockResolvedValue(new Response('', { status: 200, headers: { 'Content-Type': 'text/plain' } }));
23
+ globalThis.fetch = fetchMock;
24
+ });
25
+ afterEach(async () => {
26
+ for (const c of clients.splice(0)) {
27
+ try {
28
+ await c.flushEvents();
29
+ }
30
+ catch {
31
+ /* noop */
32
+ }
33
+ c.disposeEventBatcher();
34
+ }
35
+ globalThis.fetch = originalFetch;
36
+ vi.restoreAllMocks();
37
+ });
38
+ const mkEvent = (anonId) => ({
39
+ event: 'skill_view',
40
+ anonymous_id: anonId,
41
+ });
42
+ it('recordEvent does not POST immediately', async () => {
43
+ const client = new SkillsmithApiClient({ baseUrl: 'https://test.invalid' });
44
+ clients.push(client);
45
+ const res = await client.recordEvent(mkEvent('aaaaaaaaaaaaaaaa'));
46
+ expect(res).toEqual({ ok: true });
47
+ expect(fetchMock).not.toHaveBeenCalled();
48
+ });
49
+ it('flushEvents drains queued events via a single POST with X-Skillsmith-Batched', async () => {
50
+ const client = new SkillsmithApiClient({ baseUrl: 'https://test.invalid' });
51
+ clients.push(client);
52
+ await client.recordEvent(mkEvent('aaaaaaaaaaaaaaaa'));
53
+ await client.recordEvent(mkEvent('bbbbbbbbbbbbbbbb'));
54
+ await client.flushEvents();
55
+ expect(fetchMock).toHaveBeenCalledTimes(1);
56
+ const [url, init] = fetchMock.mock.calls[0];
57
+ expect(url).toBe('https://test.invalid/events');
58
+ expect(init.method).toBe('POST');
59
+ const headers = init.headers;
60
+ expect(headers['X-Skillsmith-Batched']).toBe('true');
61
+ const body = JSON.parse(String(init.body));
62
+ expect(body.events).toHaveLength(2);
63
+ expect(body.events[0].anonymous_id).toBe('aaaaaaaaaaaaaaaa');
64
+ });
65
+ it('offlineMode short-circuits recordEvent (no enqueue, no POST)', async () => {
66
+ const client = new SkillsmithApiClient({ baseUrl: 'https://test.invalid', offlineMode: true });
67
+ const res = await client.recordEvent(mkEvent('aaaaaaaaaaaaaaaa'));
68
+ expect(res).toEqual({ ok: true });
69
+ await client.flushEvents();
70
+ expect(fetchMock).not.toHaveBeenCalled();
71
+ });
72
+ });
73
+ //# sourceMappingURL=api-client-events.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client-events.test.js","sourceRoot":"","sources":["../../../tests/unit/api-client-events.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SMI-4119: EventBatcher unit tests.
3
+ *
4
+ * Covers:
5
+ * - size flush : 20 events → 1 POST (single flush)
6
+ * - time flush : wait elapses → flush
7
+ * - exit drain : `beforeExit` triggers flush
8
+ * - failure : first POST fails, retry succeeds
9
+ * - double-fail : two consecutive failures drop silently (no throw)
10
+ * - ordering : batch is delivered in enqueue order
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=event-batcher.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-batcher.test.d.ts","sourceRoot":"","sources":["../../../tests/unit/event-batcher.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * SMI-4119: EventBatcher unit tests.
3
+ *
4
+ * Covers:
5
+ * - size flush : 20 events → 1 POST (single flush)
6
+ * - time flush : wait elapses → flush
7
+ * - exit drain : `beforeExit` triggers flush
8
+ * - failure : first POST fails, retry succeeds
9
+ * - double-fail : two consecutive failures drop silently (no throw)
10
+ * - ordering : batch is delivered in enqueue order
11
+ */
12
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
13
+ import { EventBatcher } from '../../src/api/event-batcher.js';
14
+ const makeEvent = (anonId, skillId) => ({
15
+ event: 'skill_view',
16
+ anonymous_id: anonId,
17
+ skill_id: skillId,
18
+ });
19
+ describe('SMI-4119: EventBatcher', () => {
20
+ beforeEach(() => {
21
+ vi.useFakeTimers();
22
+ });
23
+ afterEach(() => {
24
+ vi.useRealTimers();
25
+ vi.restoreAllMocks();
26
+ });
27
+ it('flushes a single batch when queue reaches maxBatchSize', async () => {
28
+ const flushFn = vi
29
+ .fn()
30
+ .mockResolvedValue(undefined);
31
+ const batcher = new EventBatcher(flushFn, {
32
+ maxBatchSize: 20,
33
+ maxWaitMs: 10_000,
34
+ registerExitHandlers: false,
35
+ });
36
+ for (let i = 0; i < 20; i++)
37
+ batcher.enqueue(makeEvent(`a${i}`));
38
+ // Size-trigger schedules microtask flush; let it run.
39
+ await vi.runAllTimersAsync();
40
+ expect(flushFn).toHaveBeenCalledTimes(1);
41
+ expect(flushFn.mock.calls[0][0]).toHaveLength(20);
42
+ batcher.dispose();
43
+ });
44
+ it('flushes on wall-clock timeout even with < maxBatchSize events', async () => {
45
+ const flushFn = vi
46
+ .fn()
47
+ .mockResolvedValue(undefined);
48
+ const batcher = new EventBatcher(flushFn, {
49
+ maxBatchSize: 20,
50
+ maxWaitMs: 10_000,
51
+ registerExitHandlers: false,
52
+ });
53
+ batcher.enqueue(makeEvent('only-one'));
54
+ expect(flushFn).not.toHaveBeenCalled();
55
+ await vi.advanceTimersByTimeAsync(10_000);
56
+ expect(flushFn).toHaveBeenCalledTimes(1);
57
+ expect(flushFn.mock.calls[0][0]).toHaveLength(1);
58
+ batcher.dispose();
59
+ });
60
+ it('preserves enqueue order in the delivered batch', async () => {
61
+ const flushFn = vi
62
+ .fn()
63
+ .mockResolvedValue(undefined);
64
+ const batcher = new EventBatcher(flushFn, {
65
+ maxBatchSize: 5,
66
+ maxWaitMs: 10_000,
67
+ registerExitHandlers: false,
68
+ });
69
+ const ids = [
70
+ 'aaaaaaaaaaaaaaaa',
71
+ 'bbbbbbbbbbbbbbbb',
72
+ 'cccccccccccccccc',
73
+ 'dddddddddddddddd',
74
+ 'eeeeeeeeeeeeeeee',
75
+ ];
76
+ for (const id of ids)
77
+ batcher.enqueue(makeEvent(id));
78
+ await vi.runAllTimersAsync();
79
+ expect(flushFn).toHaveBeenCalledTimes(1);
80
+ expect(flushFn.mock.calls[0][0].map((e) => e.anonymous_id)).toEqual(ids);
81
+ batcher.dispose();
82
+ });
83
+ it('retries once after 2s when first flush fails, then succeeds', async () => {
84
+ const flushFn = vi
85
+ .fn()
86
+ .mockRejectedValueOnce(new Error('network down'))
87
+ .mockResolvedValueOnce(undefined);
88
+ const batcher = new EventBatcher(flushFn, {
89
+ maxBatchSize: 2,
90
+ maxWaitMs: 10_000,
91
+ retryDelayMs: 2_000,
92
+ registerExitHandlers: false,
93
+ });
94
+ batcher.enqueue(makeEvent('a1a1a1a1a1a1a1a1'));
95
+ batcher.enqueue(makeEvent('b2b2b2b2b2b2b2b2'));
96
+ await vi.advanceTimersByTimeAsync(0);
97
+ await vi.advanceTimersByTimeAsync(2_000);
98
+ await vi.runAllTimersAsync();
99
+ expect(flushFn).toHaveBeenCalledTimes(2);
100
+ batcher.dispose();
101
+ });
102
+ it('drops the batch silently after two consecutive failures', async () => {
103
+ const flushFn = vi
104
+ .fn()
105
+ .mockRejectedValue(new Error('network down'));
106
+ const batcher = new EventBatcher(flushFn, {
107
+ maxBatchSize: 1,
108
+ maxWaitMs: 10_000,
109
+ retryDelayMs: 500,
110
+ registerExitHandlers: false,
111
+ });
112
+ batcher.enqueue(makeEvent('a1a1a1a1a1a1a1a1'));
113
+ // Let the initial flush, retry delay, and second attempt all resolve.
114
+ await vi.runAllTimersAsync();
115
+ expect(flushFn).toHaveBeenCalledTimes(2);
116
+ // No unhandled rejections — batcher swallowed both failures.
117
+ batcher.dispose();
118
+ });
119
+ it('drains queued events when flush() is invoked (exit-drain surrogate)', async () => {
120
+ const flushFn = vi
121
+ .fn()
122
+ .mockResolvedValue(undefined);
123
+ const batcher = new EventBatcher(flushFn, {
124
+ maxBatchSize: 20,
125
+ maxWaitMs: 10_000,
126
+ registerExitHandlers: false,
127
+ });
128
+ batcher.enqueue(makeEvent('x1x1x1x1x1x1x1x1'));
129
+ batcher.enqueue(makeEvent('y2y2y2y2y2y2y2y2'));
130
+ expect(flushFn).not.toHaveBeenCalled();
131
+ await batcher.flush();
132
+ expect(flushFn).toHaveBeenCalledTimes(1);
133
+ expect(flushFn.mock.calls[0][0]).toHaveLength(2);
134
+ batcher.dispose();
135
+ });
136
+ it('triggers flush on the real `beforeExit` process event', async () => {
137
+ const flushFn = vi
138
+ .fn()
139
+ .mockResolvedValue(undefined);
140
+ const batcher = new EventBatcher(flushFn, {
141
+ maxBatchSize: 20,
142
+ maxWaitMs: 10_000,
143
+ drainTimeoutMs: 1_000,
144
+ registerExitHandlers: true,
145
+ });
146
+ batcher.enqueue(makeEvent('z1z1z1z1z1z1z1z1'));
147
+ process.emit('beforeExit', 0);
148
+ // Let the drain promise and its race timeout flush.
149
+ await vi.runAllTimersAsync();
150
+ await Promise.resolve();
151
+ expect(flushFn).toHaveBeenCalledTimes(1);
152
+ batcher.dispose();
153
+ });
154
+ });
155
+ //# sourceMappingURL=event-batcher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-batcher.test.js","sourceRoot":"","sources":["../../../tests/unit/event-batcher.test.ts"],"names":[],"mappings":"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"}
@@ -59,9 +59,9 @@ describe('Migration v10: skill_dependencies table', () => {
59
59
  // Running the SQL again should not throw (IF NOT EXISTS).
60
60
  expect(() => db.exec(MIGRATION_V10_SQL)).not.toThrow();
61
61
  });
62
- it('bumps schema version to 10', () => {
63
- expect(getSchemaVersion(db)).toBe(10);
64
- expect(SCHEMA_VERSION).toBe(10);
62
+ it('schema version is at least 10 after migration', () => {
63
+ expect(getSchemaVersion(db)).toBeGreaterThanOrEqual(10);
64
+ expect(SCHEMA_VERSION).toBeGreaterThanOrEqual(10);
65
65
  });
66
66
  it('unique index prevents duplicate (skill_id, dep_type, dep_target, dep_source)', () => {
67
67
  const insert = db.prepare(`
@@ -1 +1 @@
1
- {"version":3,"file":"v10-dependencies.test.js","sourceRoot":"","sources":["../../../../tests/unit/migrations/v10-dependencies.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"v10-dependencies.test.js","sourceRoot":"","sources":["../../../../tests/unit/migrations/v10-dependencies.test.ts"],"names":[],"mappings":"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"}