@skillsmith/core 0.12.0 → 0.12.2

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 (290) hide show
  1. package/CHANGELOG.md +166 -1
  2. package/README.md +7 -8
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/api/client.d.ts +5 -3
  5. package/dist/src/api/client.d.ts.map +1 -1
  6. package/dist/src/api/client.js +23 -33
  7. package/dist/src/api/client.js.map +1 -1
  8. package/dist/src/api/client.registry-sync.d.ts +28 -0
  9. package/dist/src/api/client.registry-sync.d.ts.map +1 -0
  10. package/dist/src/api/client.registry-sync.js +36 -0
  11. package/dist/src/api/client.registry-sync.js.map +1 -0
  12. package/dist/src/api/client.test.js +185 -0
  13. package/dist/src/api/client.test.js.map +1 -1
  14. package/dist/src/api/client.toSkill.d.ts +16 -0
  15. package/dist/src/api/client.toSkill.d.ts.map +1 -0
  16. package/dist/src/api/client.toSkill.js +46 -0
  17. package/dist/src/api/client.toSkill.js.map +1 -0
  18. package/dist/src/api/client.types.d.ts +22 -0
  19. package/dist/src/api/client.types.d.ts.map +1 -1
  20. package/dist/src/api/index.d.ts +1 -1
  21. package/dist/src/api/index.d.ts.map +1 -1
  22. package/dist/src/api/index.js.map +1 -1
  23. package/dist/src/api/schemas.d.ts +28 -0
  24. package/dist/src/api/schemas.d.ts.map +1 -1
  25. package/dist/src/api/schemas.js +13 -0
  26. package/dist/src/api/schemas.js.map +1 -1
  27. package/dist/src/audit/remote-audit.d.ts +85 -0
  28. package/dist/src/audit/remote-audit.d.ts.map +1 -1
  29. package/dist/src/audit/remote-audit.js +126 -3
  30. package/dist/src/audit/remote-audit.js.map +1 -1
  31. package/dist/src/audit/remote-audit.test.js +217 -1
  32. package/dist/src/audit/remote-audit.test.js.map +1 -1
  33. package/dist/src/config/index.d.ts +1 -0
  34. package/dist/src/config/index.d.ts.map +1 -1
  35. package/dist/src/config/index.js.map +1 -1
  36. package/dist/src/config/token-credentials.d.ts +20 -0
  37. package/dist/src/config/token-credentials.d.ts.map +1 -1
  38. package/dist/src/config/token-credentials.js +59 -0
  39. package/dist/src/config/token-credentials.js.map +1 -1
  40. package/dist/src/config/token-credentials.test.d.ts +3 -0
  41. package/dist/src/config/token-credentials.test.d.ts.map +1 -1
  42. package/dist/src/config/token-credentials.test.js +68 -0
  43. package/dist/src/config/token-credentials.test.js.map +1 -1
  44. package/dist/src/db/migration-runner.d.ts.map +1 -1
  45. package/dist/src/db/migration-runner.js +6 -0
  46. package/dist/src/db/migration-runner.js.map +1 -1
  47. package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts +36 -0
  48. package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts.map +1 -0
  49. package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js +38 -0
  50. package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js.map +1 -0
  51. package/dist/src/db/schema.d.ts +1 -1
  52. package/dist/src/db/schema.d.ts.map +1 -1
  53. package/dist/src/db/schema.js +3 -1
  54. package/dist/src/db/schema.js.map +1 -1
  55. package/dist/src/exports/services.d.ts +3 -7
  56. package/dist/src/exports/services.d.ts.map +1 -1
  57. package/dist/src/exports/services.install.d.ts +18 -0
  58. package/dist/src/exports/services.install.d.ts.map +1 -0
  59. package/dist/src/exports/services.install.js +62 -0
  60. package/dist/src/exports/services.install.js.map +1 -0
  61. package/dist/src/exports/services.js +12 -32
  62. package/dist/src/exports/services.js.map +1 -1
  63. package/dist/src/exports/types.d.ts +1 -1
  64. package/dist/src/exports/types.d.ts.map +1 -1
  65. package/dist/src/index.d.ts +6 -6
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/index.js +8 -5
  68. package/dist/src/index.js.map +1 -1
  69. package/dist/src/install/agent-config-merge.json.d.ts +5 -4
  70. package/dist/src/install/agent-config-merge.json.d.ts.map +1 -1
  71. package/dist/src/install/agent-config-merge.json.js +10 -9
  72. package/dist/src/install/agent-config-merge.json.js.map +1 -1
  73. package/dist/src/install/agent-config-merge.types.d.ts +11 -1
  74. package/dist/src/install/agent-config-merge.types.d.ts.map +1 -1
  75. package/dist/src/install/agent-config-merge.types.js.map +1 -1
  76. package/dist/src/install/agent-harness-targets.d.ts +30 -2
  77. package/dist/src/install/agent-harness-targets.d.ts.map +1 -1
  78. package/dist/src/install/agent-harness-targets.js +17 -0
  79. package/dist/src/install/agent-harness-targets.js.map +1 -1
  80. package/dist/src/install/agent-manifest-path-guard.d.ts +28 -3
  81. package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -1
  82. package/dist/src/install/agent-manifest-path-guard.js +59 -3
  83. package/dist/src/install/agent-manifest-path-guard.js.map +1 -1
  84. package/dist/src/install/agent-manifest-path-guard.test.js +27 -1
  85. package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -1
  86. package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts +74 -0
  87. package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts.map +1 -0
  88. package/dist/src/install/agent-pack-installer.antigravity-mcp.js +106 -0
  89. package/dist/src/install/agent-pack-installer.antigravity-mcp.js.map +1 -0
  90. package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts +2 -0
  91. package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts.map +1 -0
  92. package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js +157 -0
  93. package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js.map +1 -0
  94. package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts +53 -0
  95. package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts.map +1 -0
  96. package/dist/src/install/agent-pack-installer.cursor-mcp.js +207 -0
  97. package/dist/src/install/agent-pack-installer.cursor-mcp.js.map +1 -0
  98. package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts +2 -0
  99. package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts.map +1 -0
  100. package/dist/src/install/agent-pack-installer.cursor-mcp.test.js +285 -0
  101. package/dist/src/install/agent-pack-installer.cursor-mcp.test.js.map +1 -0
  102. package/dist/src/install/agent-pack-installer.d.ts +8 -0
  103. package/dist/src/install/agent-pack-installer.d.ts.map +1 -1
  104. package/dist/src/install/agent-pack-installer.entry.d.ts +120 -3
  105. package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -1
  106. package/dist/src/install/agent-pack-installer.entry.js +166 -3
  107. package/dist/src/install/agent-pack-installer.entry.js.map +1 -1
  108. package/dist/src/install/agent-pack-installer.js +97 -3
  109. package/dist/src/install/agent-pack-installer.js.map +1 -1
  110. package/dist/src/install/agent-pack-installer.types.d.ts +27 -0
  111. package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -1
  112. package/dist/src/install/agent-pack-installer.types.js +6 -0
  113. package/dist/src/install/agent-pack-installer.types.js.map +1 -1
  114. package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts +2 -0
  115. package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts.map +1 -0
  116. package/dist/src/install/agent-pack-installer.workspace-scope.test.js +148 -0
  117. package/dist/src/install/agent-pack-installer.workspace-scope.test.js.map +1 -0
  118. package/dist/src/install/agent-pack-uninstaller.d.ts +18 -7
  119. package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -1
  120. package/dist/src/install/agent-pack-uninstaller.js +59 -9
  121. package/dist/src/install/agent-pack-uninstaller.js.map +1 -1
  122. package/dist/src/install/agent-pack-uninstaller.test.js +74 -1
  123. package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -1
  124. package/dist/src/install/fan-out.d.ts.map +1 -1
  125. package/dist/src/install/fan-out.js +6 -0
  126. package/dist/src/install/fan-out.js.map +1 -1
  127. package/dist/src/install/index.d.ts +2 -0
  128. package/dist/src/install/index.d.ts.map +1 -1
  129. package/dist/src/install/index.js +2 -0
  130. package/dist/src/install/index.js.map +1 -1
  131. package/dist/src/install/workspace-scope.d.ts +207 -0
  132. package/dist/src/install/workspace-scope.d.ts.map +1 -0
  133. package/dist/src/install/workspace-scope.js +275 -0
  134. package/dist/src/install/workspace-scope.js.map +1 -0
  135. package/dist/src/install/workspace-scope.test.d.ts +2 -0
  136. package/dist/src/install/workspace-scope.test.d.ts.map +1 -0
  137. package/dist/src/install/workspace-scope.test.js +378 -0
  138. package/dist/src/install/workspace-scope.test.js.map +1 -0
  139. package/dist/src/security/__tests__/pathValidation.test.js +30 -1
  140. package/dist/src/security/__tests__/pathValidation.test.js.map +1 -1
  141. package/dist/src/services/SubagentGenerator.client-profiles.d.ts +258 -0
  142. package/dist/src/services/SubagentGenerator.client-profiles.d.ts.map +1 -0
  143. package/dist/src/services/SubagentGenerator.client-profiles.js +260 -0
  144. package/dist/src/services/SubagentGenerator.client-profiles.js.map +1 -0
  145. package/dist/src/services/SubagentGenerator.d.ts +19 -41
  146. package/dist/src/services/SubagentGenerator.d.ts.map +1 -1
  147. package/dist/src/services/SubagentGenerator.helpers.d.ts +64 -0
  148. package/dist/src/services/SubagentGenerator.helpers.d.ts.map +1 -0
  149. package/dist/src/services/SubagentGenerator.helpers.js +228 -0
  150. package/dist/src/services/SubagentGenerator.helpers.js.map +1 -0
  151. package/dist/src/services/SubagentGenerator.js +66 -208
  152. package/dist/src/services/SubagentGenerator.js.map +1 -1
  153. package/dist/src/services/SubagentGenerator.types.d.ts +45 -0
  154. package/dist/src/services/SubagentGenerator.types.d.ts.map +1 -0
  155. package/dist/src/services/SubagentGenerator.types.js +14 -0
  156. package/dist/src/services/SubagentGenerator.types.js.map +1 -0
  157. package/dist/src/services/TransformationService.d.ts +18 -61
  158. package/dist/src/services/TransformationService.d.ts.map +1 -1
  159. package/dist/src/services/TransformationService.js +29 -17
  160. package/dist/src/services/TransformationService.js.map +1 -1
  161. package/dist/src/services/TransformationService.types.d.ts +74 -0
  162. package/dist/src/services/TransformationService.types.d.ts.map +1 -0
  163. package/dist/src/services/TransformationService.types.js +8 -0
  164. package/dist/src/services/TransformationService.types.js.map +1 -0
  165. package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts +5 -0
  166. package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts.map +1 -0
  167. package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js +72 -0
  168. package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js.map +1 -0
  169. package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts +2 -0
  170. package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts.map +1 -0
  171. package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js +61 -0
  172. package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js.map +1 -0
  173. package/dist/src/services/__tests__/SubagentGenerator.test.js +155 -0
  174. package/dist/src/services/__tests__/SubagentGenerator.test.js.map +1 -1
  175. package/dist/src/services/__tests__/TransformationService.test.js +48 -0
  176. package/dist/src/services/__tests__/TransformationService.test.js.map +1 -1
  177. package/dist/src/services/agent-pack/agent-pack.test.js +1 -0
  178. package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -1
  179. package/dist/src/services/agent-pack/prompt-source.d.ts +1 -1
  180. package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -1
  181. package/dist/src/services/agent-pack/prompt-source.js +10 -3
  182. package/dist/src/services/agent-pack/prompt-source.js.map +1 -1
  183. package/dist/src/services/agent-pack/types.d.ts +26 -2
  184. package/dist/src/services/agent-pack/types.d.ts.map +1 -1
  185. package/dist/src/services/agent-pack/types.js +13 -0
  186. package/dist/src/services/agent-pack/types.js.map +1 -1
  187. package/dist/src/services/agent-tool-profile.d.ts.map +1 -1
  188. package/dist/src/services/agent-tool-profile.js +7 -0
  189. package/dist/src/services/agent-tool-profile.js.map +1 -1
  190. package/dist/src/services/agent-tool-profile.test.js +2 -2
  191. package/dist/src/services/skill-content-comparison.d.ts +71 -0
  192. package/dist/src/services/skill-content-comparison.d.ts.map +1 -0
  193. package/dist/src/services/skill-content-comparison.js +90 -0
  194. package/dist/src/services/skill-content-comparison.js.map +1 -0
  195. package/dist/src/services/skill-content-comparison.test.d.ts +6 -0
  196. package/dist/src/services/skill-content-comparison.test.d.ts.map +1 -0
  197. package/dist/src/services/skill-content-comparison.test.js +83 -0
  198. package/dist/src/services/skill-content-comparison.test.js.map +1 -0
  199. package/dist/src/services/skill-identity-classification.d.ts +202 -0
  200. package/dist/src/services/skill-identity-classification.d.ts.map +1 -0
  201. package/dist/src/services/skill-identity-classification.js +295 -0
  202. package/dist/src/services/skill-identity-classification.js.map +1 -0
  203. package/dist/src/services/skill-identity-classification.test.d.ts +6 -0
  204. package/dist/src/services/skill-identity-classification.test.d.ts.map +1 -0
  205. package/dist/src/services/skill-identity-classification.test.js +314 -0
  206. package/dist/src/services/skill-identity-classification.test.js.map +1 -0
  207. package/dist/src/services/skill-installation.content.d.ts.map +1 -1
  208. package/dist/src/services/skill-installation.content.js +6 -1
  209. package/dist/src/services/skill-installation.content.js.map +1 -1
  210. package/dist/src/services/skill-installation.helpers.d.ts +8 -15
  211. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
  212. package/dist/src/services/skill-installation.helpers.js +11 -105
  213. package/dist/src/services/skill-installation.helpers.js.map +1 -1
  214. package/dist/src/services/skill-installation.helpers.test.js +106 -1
  215. package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
  216. package/dist/src/services/skill-installation.service.js +1 -1
  217. package/dist/src/services/skill-installation.service.js.map +1 -1
  218. package/dist/src/services/skill-installation.types.d.ts +33 -0
  219. package/dist/src/services/skill-installation.types.d.ts.map +1 -1
  220. package/dist/src/services/skill-installation.types.js.map +1 -1
  221. package/dist/src/services/skill-installation.uninstall.d.ts +84 -0
  222. package/dist/src/services/skill-installation.uninstall.d.ts.map +1 -0
  223. package/dist/src/services/skill-installation.uninstall.js +252 -0
  224. package/dist/src/services/skill-installation.uninstall.js.map +1 -0
  225. package/dist/src/services/skill-manifest.d.ts +41 -0
  226. package/dist/src/services/skill-manifest.d.ts.map +1 -1
  227. package/dist/src/services/skill-manifest.js +93 -0
  228. package/dist/src/services/skill-manifest.js.map +1 -1
  229. package/dist/src/services/skill-manifest.test.js +27 -0
  230. package/dist/src/services/skill-manifest.test.js.map +1 -1
  231. package/dist/src/sync/SyncEngine.d.ts.map +1 -1
  232. package/dist/src/sync/SyncEngine.js +69 -77
  233. package/dist/src/sync/SyncEngine.js.map +1 -1
  234. package/dist/src/telemetry/agent-marker.d.ts +8 -0
  235. package/dist/src/telemetry/agent-marker.d.ts.map +1 -1
  236. package/dist/src/telemetry/agent-marker.js +7 -0
  237. package/dist/src/telemetry/agent-marker.js.map +1 -1
  238. package/dist/src/telemetry/agent-marker.test.js +7 -1
  239. package/dist/src/telemetry/agent-marker.test.js.map +1 -1
  240. package/dist/src/telemetry/index.d.ts +1 -1
  241. package/dist/src/telemetry/index.d.ts.map +1 -1
  242. package/dist/src/telemetry/index.js +1 -1
  243. package/dist/src/telemetry/index.js.map +1 -1
  244. package/dist/src/telemetry/wrap.d.ts +6 -0
  245. package/dist/src/telemetry/wrap.d.ts.map +1 -1
  246. package/dist/src/telemetry/wrap.js +65 -10
  247. package/dist/src/telemetry/wrap.js.map +1 -1
  248. package/dist/src/telemetry/wrap.test.js +81 -1
  249. package/dist/src/telemetry/wrap.test.js.map +1 -1
  250. package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts +26 -0
  251. package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts.map +1 -0
  252. package/dist/src/telemetry/wrap.tool-call-sink.test.js +162 -0
  253. package/dist/src/telemetry/wrap.tool-call-sink.test.js.map +1 -0
  254. package/dist/src/types/skill.d.ts +9 -1
  255. package/dist/src/types/skill.d.ts.map +1 -1
  256. package/dist/src/utils/index.d.ts +1 -1
  257. package/dist/src/utils/index.d.ts.map +1 -1
  258. package/dist/src/utils/index.js +1 -1
  259. package/dist/src/utils/index.js.map +1 -1
  260. package/dist/src/utils/version-check.d.ts +61 -0
  261. package/dist/src/utils/version-check.d.ts.map +1 -1
  262. package/dist/src/utils/version-check.js +78 -1
  263. package/dist/src/utils/version-check.js.map +1 -1
  264. package/dist/src/utils/version-check.test.js +130 -1
  265. package/dist/src/utils/version-check.test.js.map +1 -1
  266. package/dist/tests/db/migration-runner-race.test.js +19 -9
  267. package/dist/tests/db/migration-runner-race.test.js.map +1 -1
  268. package/dist/tests/install/fan-out.test.js +27 -0
  269. package/dist/tests/install/fan-out.test.js.map +1 -1
  270. package/dist/tests/skill-scanner/allowlist.test.js +7 -1
  271. package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
  272. package/dist/tests/sync/SyncEngine.abort.test.js +15 -11
  273. package/dist/tests/sync/SyncEngine.abort.test.js.map +1 -1
  274. package/dist/tests/sync/SyncEngine.status.test.js +1 -1
  275. package/dist/tests/sync/SyncEngine.status.test.js.map +1 -1
  276. package/dist/tests/sync/SyncEngine.test.d.ts +11 -2
  277. package/dist/tests/sync/SyncEngine.test.d.ts.map +1 -1
  278. package/dist/tests/sync/SyncEngine.test.js +164 -13
  279. package/dist/tests/sync/SyncEngine.test.js.map +1 -1
  280. package/dist/tests/unit/migrations/migration-v18.test.d.ts +16 -0
  281. package/dist/tests/unit/migrations/migration-v18.test.d.ts.map +1 -0
  282. package/dist/tests/unit/migrations/migration-v18.test.js +192 -0
  283. package/dist/tests/unit/migrations/migration-v18.test.js.map +1 -0
  284. package/dist/tests/unit/services/skill-installation.content.test.js +65 -1
  285. package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
  286. package/dist/tests/unit/services/skill-installation.service.test.js +9 -8
  287. package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
  288. package/dist/tests/unit/sync-engine.source-aware.test.js +5 -5
  289. package/dist/tests/unit/sync-engine.source-aware.test.js.map +1 -1
  290. package/package.json +3 -3
@@ -44,26 +44,36 @@ export function createMockSkill(id, updatedAt = new Date().toISOString()) {
44
44
  };
45
45
  }
46
46
  /**
47
- * Create a mock API client with customizable behavior
47
+ * Create a mock API client with customizable behavior.
48
+ *
49
+ * SyncEngine fetches via `syncRegistry()` (the Team/Enterprise bulk
50
+ * registry-enumeration endpoint, SMI-6197) rather than the old 8-broad-query
51
+ * abuse of `search()` — this mock paginates the same `skills` fixture array
52
+ * against `syncRegistry`'s `{ limit, offset, since }` signature. It does NOT
53
+ * filter by `since` itself (SyncEngine's own client-side
54
+ * `updated_at > lastSyncAt` filter is what's under test in the differential
55
+ * sync tests below) — `since` forwarding is asserted separately via the mock's
56
+ * call arguments.
48
57
  */
49
58
  export function createMockApiClient(config = {}) {
50
- const { offline = false, healthStatus = 'healthy', skills = [], throwOnSearch } = config;
51
- const searchMock = vi.fn().mockImplementation(async ({ limit = 100, offset = 0 }) => {
52
- if (throwOnSearch) {
53
- throw throwOnSearch;
59
+ const { offline = false, healthStatus = 'healthy', skills = [], throwOnFetch } = config;
60
+ const syncRegistryMock = vi
61
+ .fn()
62
+ .mockImplementation(async ({ limit = 100, offset = 0, since } = {}) => {
63
+ if (throwOnFetch) {
64
+ throw throwOnFetch;
54
65
  }
55
66
  const pageSkills = skills.slice(offset, offset + limit);
56
67
  return {
57
68
  data: pageSkills,
58
- total: skills.length,
59
- limit,
60
- offset,
69
+ meta: { limit, offset, since: since ?? null },
61
70
  };
62
71
  });
63
72
  return {
64
73
  isOffline: vi.fn().mockReturnValue(offline),
65
74
  checkHealth: vi.fn().mockResolvedValue({ status: healthStatus }),
66
- search: searchMock,
75
+ search: vi.fn(),
76
+ syncRegistry: syncRegistryMock,
67
77
  getSkill: vi.fn(),
68
78
  getHealthStatus: vi.fn(),
69
79
  };
@@ -238,10 +248,151 @@ describe('SyncEngine', () => {
238
248
  expect(result.success).toBe(true);
239
249
  expect(result.skillsAdded).toBe(150);
240
250
  expect(result.totalProcessed).toBe(150);
241
- // SyncEngine uses 8 different search queries to cover more skills
242
- // Each query paginates through results: 8 queries × 2 pages (100 + 50) = 16 calls
243
- // Skills are deduplicated across queries
244
- expect(apiClient.search).toHaveBeenCalledTimes(16);
251
+ // SyncEngine now scans registry-sync's single id-ordered enumeration:
252
+ // 2 pages (100 + 50) instead of the old 8-query × 2-page = 16 calls.
253
+ expect(apiClient.syncRegistry).toHaveBeenCalledTimes(2);
254
+ });
255
+ });
256
+ describe('sync - since forwarding', () => {
257
+ it('omits `since` when force=true, even with a lastSyncAt on record', async () => {
258
+ const lastSyncAt = new Date(Date.now() - 60 * 60 * 1000).toISOString();
259
+ syncConfigRepo.setLastSync(lastSyncAt, 0);
260
+ const apiClient = createMockApiClient({ skills: [createMockSkill('test/skill-1')] });
261
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, createMockSkillVersionRepo());
262
+ await engine.sync({ force: true });
263
+ const syncRegistryMock = apiClient.syncRegistry;
264
+ expect(syncRegistryMock).toHaveBeenCalledWith(expect.objectContaining({ since: undefined }));
265
+ });
266
+ it('forwards lastSyncAt as `since` on a non-forced sync', async () => {
267
+ const lastSyncAt = new Date(Date.now() - 60 * 60 * 1000).toISOString();
268
+ syncConfigRepo.setLastSync(lastSyncAt, 0);
269
+ const apiClient = createMockApiClient({ skills: [createMockSkill('test/skill-1')] });
270
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, createMockSkillVersionRepo());
271
+ await engine.sync();
272
+ const syncRegistryMock = apiClient.syncRegistry;
273
+ expect(syncRegistryMock).toHaveBeenCalledWith(expect.objectContaining({ since: lastSyncAt }));
274
+ });
275
+ it('omits `since` on a non-forced sync with no lastSyncAt on record', async () => {
276
+ const apiClient = createMockApiClient({ skills: [createMockSkill('test/skill-1')] });
277
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, createMockSkillVersionRepo());
278
+ await engine.sync();
279
+ const syncRegistryMock = apiClient.syncRegistry;
280
+ expect(syncRegistryMock).toHaveBeenCalledWith(expect.objectContaining({ since: undefined }));
281
+ });
282
+ });
283
+ // ===========================================================================
284
+ // SMI-6343 Wave 2: real content_hash recording (never a metadata proxy)
285
+ // ===========================================================================
286
+ describe('recordVersion — real content hash, never a metadata proxy', () => {
287
+ it('records the registry real content_hash on create, not a metadata proxy', async () => {
288
+ const skillVersionRepo = createMockSkillVersionRepo();
289
+ const skill = {
290
+ ...createMockSkill('test/hash-on-create'),
291
+ content_hash: 'realsha256contenthash1',
292
+ };
293
+ const apiClient = createMockApiClient({ skills: [skill] });
294
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
295
+ const result = await engine.sync();
296
+ expect(result.success).toBe(true);
297
+ expect(skillVersionRepo.recordVersion).toHaveBeenCalledWith('test/hash-on-create', 'realsha256contenthash1');
298
+ });
299
+ it('records the registry real content_hash on update, not a metadata proxy', async () => {
300
+ skillRepo.create({
301
+ id: 'test/hash-on-update',
302
+ name: 'Old Name',
303
+ trustTier: 'community',
304
+ tags: ['old'],
305
+ });
306
+ const skillVersionRepo = createMockSkillVersionRepo();
307
+ const skill = {
308
+ ...createMockSkill('test/hash-on-update', new Date(Date.now() + 1000).toISOString()),
309
+ content_hash: 'realsha256contenthash2',
310
+ };
311
+ const apiClient = createMockApiClient({ skills: [skill] });
312
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
313
+ const result = await engine.sync();
314
+ expect(result.success).toBe(true);
315
+ expect(result.skillsUpdated).toBe(1);
316
+ expect(skillVersionRepo.recordVersion).toHaveBeenCalledWith('test/hash-on-update', 'realsha256contenthash2');
317
+ });
318
+ it('skips recordVersion entirely when the registry provides no content_hash (create path)', async () => {
319
+ const skillVersionRepo = createMockSkillVersionRepo();
320
+ // createMockSkill() does not set content_hash.
321
+ const apiClient = createMockApiClient({ skills: [createMockSkill('test/no-hash-create')] });
322
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
323
+ const result = await engine.sync();
324
+ expect(result.success).toBe(true);
325
+ expect(result.skillsAdded).toBe(1);
326
+ expect(skillVersionRepo.recordVersion).not.toHaveBeenCalled();
327
+ });
328
+ it('skips recordVersion entirely when the registry provides no content_hash (update path)', async () => {
329
+ skillRepo.create({
330
+ id: 'test/no-hash-update',
331
+ name: 'Old Name',
332
+ trustTier: 'community',
333
+ tags: ['old'],
334
+ });
335
+ const skillVersionRepo = createMockSkillVersionRepo();
336
+ const skill = createMockSkill('test/no-hash-update', new Date(Date.now() + 1000).toISOString());
337
+ const apiClient = createMockApiClient({ skills: [skill] });
338
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
339
+ const result = await engine.sync();
340
+ expect(result.success).toBe(true);
341
+ expect(result.skillsUpdated).toBe(1);
342
+ expect(skillVersionRepo.recordVersion).not.toHaveBeenCalled();
343
+ });
344
+ it('records the registry content_hash for an UNCHANGED skill (adversarial-review regression)', async () => {
345
+ // The bug this guards: recordVersion() originally lived only inside
346
+ // the branch where existing.updatedAt !== skill.updated_at, so a
347
+ // skill whose metadata hasn't changed since last sync would never
348
+ // regain a skill_versions row after migration v18's purge —
349
+ // contradicting the migration's own "fully rebuilds on the next
350
+ // registry sync" claim for the common case where most of the catalog
351
+ // doesn't change every sync.
352
+ const timestamp = new Date().toISOString();
353
+ skillRepo.create({
354
+ id: 'test/unchanged-hash',
355
+ name: 'Skill test/unchanged-hash',
356
+ trustTier: 'community',
357
+ tags: ['test'],
358
+ });
359
+ db.prepare('UPDATE skills SET updated_at = ? WHERE id = ?').run(timestamp, 'test/unchanged-hash');
360
+ const skillVersionRepo = createMockSkillVersionRepo();
361
+ const skill = {
362
+ ...createMockSkill('test/unchanged-hash', timestamp),
363
+ content_hash: 'realsha256contenthash-unchanged',
364
+ };
365
+ const apiClient = createMockApiClient({ skills: [skill] });
366
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
367
+ const result = await engine.sync();
368
+ expect(result.success).toBe(true);
369
+ expect(result.skillsUnchanged).toBe(1);
370
+ expect(result.skillsUpdated).toBe(0);
371
+ expect(skillVersionRepo.recordVersion).toHaveBeenCalledWith('test/unchanged-hash', 'realsha256contenthash-unchanged');
372
+ });
373
+ it('does not record a version for a locally-imported skill even when unchanged', async () => {
374
+ // SMI-4665's local-import skip must still be honored — the fix above
375
+ // widens WHEN recordVersion runs, but must not reach past the
376
+ // pre-existing `existing.source === 'local'` early-continue.
377
+ const timestamp = new Date().toISOString();
378
+ skillRepo.create({
379
+ id: 'test/local-unchanged',
380
+ name: 'Local Skill',
381
+ trustTier: 'community',
382
+ tags: ['test'],
383
+ source: 'local',
384
+ });
385
+ db.prepare('UPDATE skills SET updated_at = ? WHERE id = ?').run(timestamp, 'test/local-unchanged');
386
+ const skillVersionRepo = createMockSkillVersionRepo();
387
+ const skill = {
388
+ ...createMockSkill('test/local-unchanged', timestamp),
389
+ content_hash: 'realsha256contenthash-local',
390
+ };
391
+ const apiClient = createMockApiClient({ skills: [skill] });
392
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
393
+ const result = await engine.sync();
394
+ expect(result.success).toBe(true);
395
+ expect(skillVersionRepo.recordVersion).not.toHaveBeenCalled();
245
396
  });
246
397
  });
247
398
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SyncEngine.test.js","sourceRoot":"","sources":["../../../tests/sync/SyncEngine.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SyncEngine.test.js","sourceRoot":"","sources":["../../../tests/sync/SyncEngine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Tests for migration v18 — purge proxy-hash skill_versions history
3
+ * @see SMI-6343 Wave 2 — repair the content-hash comparison
4
+ *
5
+ * Coverage:
6
+ * - MIGRATIONS registers v18 with the documented SQL.
7
+ * - SCHEMA_VERSION is at least 18.
8
+ * - MIGRATION_V18_SQL empties skill_versions of any pre-existing (proxy-hash
9
+ * era) rows.
10
+ * - A v17 fixture DB upgrades to v18 cleanly via runMigrations, purging a
11
+ * legacy row planted before the upgrade.
12
+ * - A post-migration registry sync (SyncEngine) repopulates skill_versions
13
+ * with a real SKILL.md content hash — never a metadata proxy.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=migration-v18.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-v18.test.d.ts","sourceRoot":"","sources":["../../../../tests/unit/migrations/migration-v18.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * @fileoverview Tests for migration v18 — purge proxy-hash skill_versions history
3
+ * @see SMI-6343 Wave 2 — repair the content-hash comparison
4
+ *
5
+ * Coverage:
6
+ * - MIGRATIONS registers v18 with the documented SQL.
7
+ * - SCHEMA_VERSION is at least 18.
8
+ * - MIGRATION_V18_SQL empties skill_versions of any pre-existing (proxy-hash
9
+ * era) rows.
10
+ * - A v17 fixture DB upgrades to v18 cleanly via runMigrations, purging a
11
+ * legacy row planted before the upgrade.
12
+ * - A post-migration registry sync (SyncEngine) repopulates skill_versions
13
+ * with a real SKILL.md content hash — never a metadata proxy.
14
+ */
15
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
16
+ import { createTestDatabase, closeDatabase } from '../../helpers/database.js';
17
+ import { getSchemaVersion, SCHEMA_VERSION, runMigrations, MIGRATIONS, createDatabaseAsync, initializeSchema, SCHEMA_SQL, } from '../../../src/db/schema.js';
18
+ import { MIGRATION_V18_SQL } from '../../../src/db/migrations/v18-skill-versions-real-content-hash.js';
19
+ import { SyncEngine } from '../../../src/sync/SyncEngine.js';
20
+ import { SkillRepository } from '../../../src/repositories/SkillRepository.js';
21
+ import { SyncConfigRepository } from '../../../src/repositories/SyncConfigRepository.js';
22
+ import { SyncHistoryRepository } from '../../../src/repositories/SyncHistoryRepository.js';
23
+ import { SkillVersionRepository } from '../../../src/repositories/SkillVersionRepository.js';
24
+ // The BARE factory (creates no tables) — needed to build a pristine fixture DB
25
+ // whose schema_version table starts empty.
26
+ import { createDatabaseAsync as createBareDatabaseAsync } from '../../../src/db/createDatabase.js';
27
+ /**
28
+ * Build a fixture DB stamped at exactly `targetVersion` by running the base
29
+ * schema then every migration up to (and including) `targetVersion`. Mirrors
30
+ * the pattern in migration-v17.test.ts's fixtureAtVersion().
31
+ */
32
+ async function fixtureAtVersion(targetVersion) {
33
+ const db = (await createBareDatabaseAsync(':memory:'));
34
+ db.exec(SCHEMA_SQL);
35
+ for (const migration of MIGRATIONS) {
36
+ if (migration.version === 1 || migration.version > targetVersion)
37
+ continue;
38
+ try {
39
+ if (migration.apply) {
40
+ migration.apply(db);
41
+ }
42
+ else if (migration.sql !== undefined) {
43
+ db.exec(migration.sql);
44
+ }
45
+ }
46
+ catch (error) {
47
+ const msg = error instanceof Error ? error.message : String(error);
48
+ if (!msg.includes('duplicate column'))
49
+ throw error;
50
+ }
51
+ db.prepare('INSERT OR IGNORE INTO schema_version (version) VALUES (?)').run(migration.version);
52
+ }
53
+ return db;
54
+ }
55
+ function countSkillVersions(db) {
56
+ return db.prepare('SELECT COUNT(*) as c FROM skill_versions').get().c;
57
+ }
58
+ function buildMockApiClient(skills) {
59
+ return {
60
+ isOffline: vi.fn().mockReturnValue(false),
61
+ checkHealth: vi.fn().mockResolvedValue({ status: 'healthy' }),
62
+ syncRegistry: vi.fn().mockResolvedValue({ data: skills, meta: {} }),
63
+ search: vi.fn(),
64
+ getSkill: vi.fn(),
65
+ getHealthStatus: vi.fn(),
66
+ };
67
+ }
68
+ describe('Migration v18: purge proxy-hash skill_versions history', () => {
69
+ let db;
70
+ beforeEach(async () => {
71
+ db = await createTestDatabase();
72
+ });
73
+ afterEach(() => {
74
+ closeDatabase(db);
75
+ });
76
+ it('SCHEMA_VERSION is at least 18', () => {
77
+ expect(SCHEMA_VERSION).toBeGreaterThanOrEqual(18);
78
+ });
79
+ it('MIGRATIONS registers v18 with the expected SQL', () => {
80
+ const v18 = MIGRATIONS.find((m) => m.version === 18);
81
+ expect(v18).toBeDefined();
82
+ expect(v18?.sql).toBe(MIGRATION_V18_SQL);
83
+ expect(v18?.description).toContain('SMI-6343');
84
+ });
85
+ it('MIGRATION_V18_SQL empties skill_versions of pre-existing (proxy-hash) rows', () => {
86
+ db.prepare(`INSERT INTO skill_versions (skill_id, content_hash) VALUES (?, ?)`).run('legacy/skill', 'deadbeef-proxy-hash');
87
+ expect(countSkillVersions(db)).toBe(1);
88
+ db.exec(MIGRATION_V18_SQL);
89
+ expect(countSkillVersions(db)).toBe(0);
90
+ });
91
+ it('is idempotent — running it again on an already-empty table is a no-op', () => {
92
+ db.exec(MIGRATION_V18_SQL);
93
+ expect(countSkillVersions(db)).toBe(0);
94
+ expect(() => db.exec(MIGRATION_V18_SQL)).not.toThrow();
95
+ expect(countSkillVersions(db)).toBe(0);
96
+ });
97
+ it('a v17 fixture DB upgrades to v18 cleanly, purging a legacy proxy-hash row planted before the upgrade', async () => {
98
+ const v17 = await fixtureAtVersion(17);
99
+ expect(getSchemaVersion(v17)).toBe(17);
100
+ // Plant a legacy (pre-fix) proxy-hash row, as a real pre-migration DB would have.
101
+ v17
102
+ .prepare(`INSERT INTO skill_versions (skill_id, content_hash) VALUES (?, ?)`)
103
+ .run('legacy/proxy-hash-skill', 'legacy-proxy-hash-value');
104
+ expect(countSkillVersions(v17)).toBe(1);
105
+ const ran = runMigrations(v17);
106
+ expect(ran).toBeGreaterThanOrEqual(1);
107
+ expect(getSchemaVersion(v17)).toBe(SCHEMA_VERSION);
108
+ expect(countSkillVersions(v17)).toBe(0);
109
+ closeDatabase(v17);
110
+ });
111
+ it('post-migration registry sync repopulates skill_versions with a real content hash, never a metadata proxy', async () => {
112
+ db.exec(MIGRATION_V18_SQL);
113
+ expect(countSkillVersions(db)).toBe(0);
114
+ const skillRepo = new SkillRepository(db);
115
+ const syncConfigRepo = new SyncConfigRepository(db);
116
+ const syncHistoryRepo = new SyncHistoryRepository(db);
117
+ const skillVersionRepo = new SkillVersionRepository(db);
118
+ const realContentHash = 'a'.repeat(64); // shape of a real sha256 hex digest
119
+ const skill = {
120
+ id: 'community/real-hash-skill',
121
+ name: 'Real Hash Skill',
122
+ description: 'test skill',
123
+ author: 'test-author',
124
+ repo_url: 'https://github.com/test/real-hash-skill',
125
+ quality_score: 0.8,
126
+ trust_tier: 'community',
127
+ tags: [],
128
+ content_hash: realContentHash,
129
+ updated_at: new Date().toISOString(),
130
+ };
131
+ const apiClient = buildMockApiClient([skill]);
132
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
133
+ const result = await engine.sync();
134
+ expect(result.success).toBe(true);
135
+ expect(result.skillsAdded).toBe(1);
136
+ const latest = await skillVersionRepo.getLatestVersion('community/real-hash-skill');
137
+ expect(latest).not.toBeNull();
138
+ expect(latest?.content_hash).toBe(realContentHash);
139
+ // Never a metadata-proxy hash: the proxy was
140
+ // sha256(JSON.stringify({id, name, description, updated_at})) — a
141
+ // completely different value from the registry's real content_hash.
142
+ const metadataProxyShape = JSON.stringify({
143
+ id: skill.id,
144
+ name: skill.name,
145
+ description: skill.description ?? null,
146
+ updated_at: skill.updated_at ?? null,
147
+ });
148
+ expect(latest?.content_hash).not.toBe(metadataProxyShape);
149
+ });
150
+ it('post-migration registry sync skips recordVersion entirely when the registry provides no content hash', async () => {
151
+ db.exec(MIGRATION_V18_SQL);
152
+ const skillRepo = new SkillRepository(db);
153
+ const syncConfigRepo = new SyncConfigRepository(db);
154
+ const syncHistoryRepo = new SyncHistoryRepository(db);
155
+ const skillVersionRepo = new SkillVersionRepository(db);
156
+ const skill = {
157
+ id: 'community/no-hash-skill',
158
+ name: 'No Hash Skill',
159
+ description: 'test skill',
160
+ author: 'test-author',
161
+ repo_url: 'https://github.com/test/no-hash-skill',
162
+ quality_score: 0.8,
163
+ trust_tier: 'community',
164
+ tags: [],
165
+ // content_hash intentionally omitted
166
+ updated_at: new Date().toISOString(),
167
+ };
168
+ const apiClient = buildMockApiClient([skill]);
169
+ const engine = new SyncEngine(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
170
+ const result = await engine.sync();
171
+ expect(result.success).toBe(true);
172
+ expect(result.skillsAdded).toBe(1);
173
+ // No row was recorded — a missing hash is honestly "unknown", never a
174
+ // proxy fabrication.
175
+ const latest = await skillVersionRepo.getLatestVersion('community/no-hash-skill');
176
+ expect(latest).toBeNull();
177
+ });
178
+ it('H1: the skills table itself is unaffected by v18 (only skill_versions is touched)', () => {
179
+ db.prepare("INSERT INTO skills (id, name, trust_tier, source) VALUES ('keep-1', 'keep', 'community', 'registry')").run();
180
+ db.exec(MIGRATION_V18_SQL);
181
+ const row = db.prepare('SELECT id FROM skills WHERE id = ?').get('keep-1');
182
+ expect(row?.id).toBe('keep-1');
183
+ });
184
+ it('fresh-install convergence: a brand-new DB has an empty skill_versions table at the current schema version', async () => {
185
+ const fresh = await createDatabaseAsync(':memory:');
186
+ initializeSchema(fresh);
187
+ expect(getSchemaVersion(fresh)).toBe(SCHEMA_VERSION);
188
+ expect(countSkillVersions(fresh)).toBe(0);
189
+ closeDatabase(fresh);
190
+ });
191
+ });
192
+ //# sourceMappingURL=migration-v18.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-v18.test.js","sourceRoot":"","sources":["../../../../tests/unit/migrations/migration-v18.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAiB,MAAM,2BAA2B,CAAA;AAC5F,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oEAAoE,CAAA;AACtG,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,8CAA8C,CAAA;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAA;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,qDAAqD,CAAA;AAE5F,+EAA+E;AAC/E,2CAA2C;AAC3C,OAAO,EAAE,mBAAmB,IAAI,uBAAuB,EAAE,MAAM,mCAAmC,CAAA;AAElG;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAAC,aAAqB;IACnD,MAAM,EAAE,GAAG,CAAC,MAAM,uBAAuB,CAAC,UAAU,CAAC,CAAa,CAAA;IAClE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACnB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,GAAG,aAAa;YAAE,SAAQ;QAC1E,IAAI,CAAC;YACH,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBACpB,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACrB,CAAC;iBAAM,IAAI,SAAS,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBACvC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAClE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAAE,MAAM,KAAK,CAAA;QACpD,CAAC;QACD,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAChG,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAY;IACtC,OAAQ,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAA;AAC1F,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAyB;IACnD,OAAO;QACL,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;QACzC,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC7D,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACnE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;QACf,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;QACjB,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE;KACS,CAAA;AACrC,CAAC;AAED,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACtE,IAAI,EAAY,CAAA;IAEhB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,GAAG,MAAM,kBAAkB,EAAE,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,CAAC,EAAE,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,cAAc,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,CAAA;QACpD,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;QACzB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACxC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,EAAE,CAAC,OAAO,CAAC,mEAAmE,CAAC,CAAC,GAAG,CACjF,cAAc,EACd,qBAAqB,CACtB,CAAA;QACD,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEtC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAE1B,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC1B,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACtC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;QACtD,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sGAAsG,EAAE,KAAK,IAAI,EAAE;QACpH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAA;QACtC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAEtC,kFAAkF;QAClF,GAAG;aACA,OAAO,CAAC,mEAAmE,CAAC;aAC5E,GAAG,CAAC,yBAAyB,EAAE,yBAAyB,CAAC,CAAA;QAC5D,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEvC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAClD,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEvC,aAAa,CAAC,GAAG,CAAC,CAAA;IACpB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0GAA0G,EAAE,KAAK,IAAI,EAAE;QACxH,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC1B,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEtC,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,CAAA;QACzC,MAAM,cAAc,GAAG,IAAI,oBAAoB,CAAC,EAAE,CAAC,CAAA;QACnD,MAAM,eAAe,GAAG,IAAI,qBAAqB,CAAC,EAAE,CAAC,CAAA;QACrD,MAAM,gBAAgB,GAAG,IAAI,sBAAsB,CAAC,EAAE,CAAC,CAAA;QAEvD,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,CAAC,oCAAoC;QAC3E,MAAM,KAAK,GAAoB;YAC7B,EAAE,EAAE,2BAA2B;YAC/B,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,yCAAyC;YACnD,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,WAAW;YACvB,IAAI,EAAE,EAAE;YACR,YAAY,EAAE,eAAe;YAC7B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAA;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,IAAI,UAAU,CAC3B,SAAS,EACT,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,CACjB,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAElC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,2BAA2B,CAAC,CAAA;QACnF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;QAC7B,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAElD,6CAA6C;QAC7C,kEAAkE;QAClE,oEAAoE;QACpE,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC;YACxC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;SACrC,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sGAAsG,EAAE,KAAK,IAAI,EAAE;QACpH,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAE1B,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,CAAA;QACzC,MAAM,cAAc,GAAG,IAAI,oBAAoB,CAAC,EAAE,CAAC,CAAA;QACnD,MAAM,eAAe,GAAG,IAAI,qBAAqB,CAAC,EAAE,CAAC,CAAA;QACrD,MAAM,gBAAgB,GAAG,IAAI,sBAAsB,CAAC,EAAE,CAAC,CAAA;QAEvD,MAAM,KAAK,GAAoB;YAC7B,EAAE,EAAE,yBAAyB;YAC7B,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,uCAAuC;YACjD,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,WAAW;YACvB,IAAI,EAAE,EAAE;YACR,qCAAqC;YACrC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAA;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,IAAI,UAAU,CAC3B,SAAS,EACT,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,CACjB,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAElC,sEAAsE;QACtE,qBAAqB;QACrB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAA;QACjF,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC3B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QAC3F,EAAE,CAAC,OAAO,CACR,sGAAsG,CACvG,CAAC,GAAG,EAAE,CAAA;QAEP,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAE1B,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAE5D,CAAA;QACb,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2GAA2G,EAAE,KAAK,IAAI,EAAE;QACzH,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,CAAA;QACnD,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACvB,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACpD,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,aAAa,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -40,7 +40,7 @@ async function createTmpDirs() {
40
40
  async function cleanupTmpDirs() {
41
41
  await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => { });
42
42
  }
43
- function createService(db) {
43
+ function createService(db, client, companionBaseDir) {
44
44
  const skillRepo = new SkillRepository(db);
45
45
  const skillDependencyRepo = new SkillDependencyRepository(db);
46
46
  return new SkillInstallationService({
@@ -49,8 +49,26 @@ function createService(db) {
49
49
  skillDependencyRepo,
50
50
  skillsDir,
51
51
  manifestPath,
52
+ ...(client !== undefined && { client }),
53
+ ...(companionBaseDir !== undefined && { companionBaseDir }),
52
54
  });
53
55
  }
56
+ // SMI-6276 pr-reviewer finding: content substantial enough to trigger BOTH
57
+ // quickTransformCheck (>=3 heavy-tool-pattern mentions) and
58
+ // generateSubagent()'s own gate (lineCount >= 300) deterministically, so a
59
+ // companion subagent is always generated regardless of analysis heuristics.
60
+ const HEAVY_TOOL_USAGE_SKILL_MD = `---
61
+ name: heavy-tool-skill
62
+ description: A skill that runs npm, git, and docker commands extensively for testing client-aware subagent generation
63
+ ---
64
+
65
+ # Heavy Tool Skill
66
+
67
+ This skill runs \`npm install\`, \`git commit\`, and \`docker build\` as part of
68
+ its normal operation, plus assorted Bash( invocations elsewhere in this file.
69
+
70
+ ${Array.from({ length: 300 }, (_, i) => `Padding line ${i} to exceed the subagent-generation line-count threshold.`).join('\n')}
71
+ `;
54
72
  describe('SMI-5905 Wave 1: installFromContent()', () => {
55
73
  let db;
56
74
  beforeEach(async () => {
@@ -286,5 +304,51 @@ describe('SMI-5905 Wave 1: installFromContent()', () => {
286
304
  expect(result.errorCode).toBe('SCAN_REJECTED');
287
305
  await expect(fs.access(path.join(skillsDir, 'acme-tool'))).rejects.toThrow();
288
306
  });
307
+ // SMI-6276 pr-reviewer finding (round 1): installFromContent() had `client`
308
+ // in scope (used elsewhere for the manifest key + tips) but never forwarded
309
+ // it into applyOptimization(), silently generating Claude-shaped subagent
310
+ // content regardless of the real target client. This proves the fix by
311
+ // installing the SAME heavy-tool-usage content under two different clients
312
+ // and asserting the written companion-subagent files actually differ in
313
+ // client-specific ways -- before the fix, both would be byte-identical
314
+ // (both Claude-shaped) despite requesting different clients.
315
+ it('threads the target client through to subagent generation — AntiGravity gets its own tool vocabulary, not Claude-shaped output', async () => {
316
+ const claudeService = createService(db, 'claude-code');
317
+ const claudeResult = await claudeService.installFromContent({
318
+ skillId: 'acme/heavy-tool-skill',
319
+ version: '1.0.0',
320
+ content: { 'SKILL.md': HEAVY_TOOL_USAGE_SKILL_MD },
321
+ });
322
+ expect(claudeResult.success).toBe(true);
323
+ expect(claudeResult.optimization?.subagentGenerated).toBe(true);
324
+ const claudeSubagentPath = claudeResult.optimization?.subagentPath;
325
+ expect(claudeSubagentPath).toBeTruthy();
326
+ const claudeSubagentContent = await fs.readFile(claudeSubagentPath, 'utf-8');
327
+ // Claude-code gets the pre-existing Claude-shaped frontmatter.
328
+ expect(claudeSubagentContent).toMatch(/^model: (haiku|sonnet|opus)$/m);
329
+ expect(claudeSubagentContent).toMatch(/^tools: [A-Za-z]/m);
330
+ await cleanupTmpDirs();
331
+ await createTmpDirs();
332
+ db.close();
333
+ db = await createTestDatabase();
334
+ // AntiGravity's companion-agent path is workspace-relative (directory-
335
+ // package mode) and requires an explicit companionBaseDir — tmpDir
336
+ // stands in for "the calling client's real project" here.
337
+ const antigravityService = createService(db, 'antigravity', tmpDir);
338
+ const antigravityResult = await antigravityService.installFromContent({
339
+ skillId: 'acme/heavy-tool-skill',
340
+ version: '1.0.0',
341
+ content: { 'SKILL.md': HEAVY_TOOL_USAGE_SKILL_MD },
342
+ });
343
+ expect(antigravityResult.success).toBe(true);
344
+ expect(antigravityResult.optimization?.subagentGenerated).toBe(true);
345
+ const antigravitySubagentPath = antigravityResult.optimization?.subagentPath;
346
+ expect(antigravitySubagentPath).toBeTruthy();
347
+ const antigravitySubagentContent = await fs.readFile(antigravitySubagentPath, 'utf-8');
348
+ // AntiGravity gets its own mapped tool vocabulary as a YAML array, and no
349
+ // Claude model field — the exact divergence this fix makes possible.
350
+ expect(antigravitySubagentContent).not.toMatch(/^model: (haiku|sonnet|opus)$/m);
351
+ expect(antigravitySubagentContent).not.toMatch(/^tools: [A-Za-z]/m);
352
+ });
289
353
  });
290
354
  //# sourceMappingURL=skill-installation.content.test.js.map