@skillsmith/core 0.8.2 → 0.10.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 (347) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/api/client.d.ts.map +1 -1
  4. package/dist/src/api/client.js +6 -0
  5. package/dist/src/api/client.js.map +1 -1
  6. package/dist/src/api/client.test.d.ts +9 -0
  7. package/dist/src/api/client.test.d.ts.map +1 -0
  8. package/dist/src/api/client.test.js +81 -0
  9. package/dist/src/api/client.test.js.map +1 -0
  10. package/dist/src/config/device-identity.d.ts +113 -0
  11. package/dist/src/config/device-identity.d.ts.map +1 -0
  12. package/dist/src/config/device-identity.js +171 -0
  13. package/dist/src/config/device-identity.js.map +1 -0
  14. package/dist/src/config/device-identity.test.d.ts +10 -0
  15. package/dist/src/config/device-identity.test.d.ts.map +1 -0
  16. package/dist/src/config/device-identity.test.js +213 -0
  17. package/dist/src/config/device-identity.test.js.map +1 -0
  18. package/dist/src/config/index.d.ts +9 -0
  19. package/dist/src/config/index.d.ts.map +1 -1
  20. package/dist/src/config/index.js.map +1 -1
  21. package/dist/src/exports/services.d.ts +3 -1
  22. package/dist/src/exports/services.d.ts.map +1 -1
  23. package/dist/src/exports/services.js +11 -1
  24. package/dist/src/exports/services.js.map +1 -1
  25. package/dist/src/index.d.ts +4 -3
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/index.js +7 -2
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/install/agent-config-merge.json-array.d.ts +29 -0
  30. package/dist/src/install/agent-config-merge.json-array.d.ts.map +1 -0
  31. package/dist/src/install/agent-config-merge.json-array.js +100 -0
  32. package/dist/src/install/agent-config-merge.json-array.js.map +1 -0
  33. package/dist/src/install/agent-config-merge.json.d.ts +37 -0
  34. package/dist/src/install/agent-config-merge.json.d.ts.map +1 -0
  35. package/dist/src/install/agent-config-merge.json.js +134 -0
  36. package/dist/src/install/agent-config-merge.json.js.map +1 -0
  37. package/dist/src/install/agent-config-merge.toml-block.d.ts +48 -0
  38. package/dist/src/install/agent-config-merge.toml-block.d.ts.map +1 -0
  39. package/dist/src/install/agent-config-merge.toml-block.js +107 -0
  40. package/dist/src/install/agent-config-merge.toml-block.js.map +1 -0
  41. package/dist/src/install/agent-config-merge.types.d.ts +87 -0
  42. package/dist/src/install/agent-config-merge.types.d.ts.map +1 -0
  43. package/dist/src/install/agent-config-merge.types.js +83 -0
  44. package/dist/src/install/agent-config-merge.types.js.map +1 -0
  45. package/dist/src/install/agent-config-merge.yaml.d.ts +46 -0
  46. package/dist/src/install/agent-config-merge.yaml.d.ts.map +1 -0
  47. package/dist/src/install/agent-config-merge.yaml.js +133 -0
  48. package/dist/src/install/agent-config-merge.yaml.js.map +1 -0
  49. package/dist/src/install/agent-config-merge.yaml.test.d.ts +2 -0
  50. package/dist/src/install/agent-config-merge.yaml.test.d.ts.map +1 -0
  51. package/dist/src/install/agent-config-merge.yaml.test.js +210 -0
  52. package/dist/src/install/agent-config-merge.yaml.test.js.map +1 -0
  53. package/dist/src/install/agent-harness-targets.d.ts +98 -0
  54. package/dist/src/install/agent-harness-targets.d.ts.map +1 -0
  55. package/dist/src/install/agent-harness-targets.js +154 -0
  56. package/dist/src/install/agent-harness-targets.js.map +1 -0
  57. package/dist/src/install/agent-home-relocate.d.ts +29 -0
  58. package/dist/src/install/agent-home-relocate.d.ts.map +1 -0
  59. package/dist/src/install/agent-home-relocate.js +38 -0
  60. package/dist/src/install/agent-home-relocate.js.map +1 -0
  61. package/dist/src/install/agent-manifest-path-guard.d.ts +55 -0
  62. package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -0
  63. package/dist/src/install/agent-manifest-path-guard.js +109 -0
  64. package/dist/src/install/agent-manifest-path-guard.js.map +1 -0
  65. package/dist/src/install/agent-manifest-path-guard.test.d.ts +2 -0
  66. package/dist/src/install/agent-manifest-path-guard.test.d.ts.map +1 -0
  67. package/dist/src/install/agent-manifest-path-guard.test.js +72 -0
  68. package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -0
  69. package/dist/src/install/agent-manifest.d.ts +58 -0
  70. package/dist/src/install/agent-manifest.d.ts.map +1 -0
  71. package/dist/src/install/agent-manifest.js +103 -0
  72. package/dist/src/install/agent-manifest.js.map +1 -0
  73. package/dist/src/install/agent-pack-installer.d.ts +39 -0
  74. package/dist/src/install/agent-pack-installer.d.ts.map +1 -0
  75. package/dist/src/install/agent-pack-installer.entry.d.ts +55 -0
  76. package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -0
  77. package/dist/src/install/agent-pack-installer.entry.js +90 -0
  78. package/dist/src/install/agent-pack-installer.entry.js.map +1 -0
  79. package/dist/src/install/agent-pack-installer.fs-helpers.d.ts +33 -0
  80. package/dist/src/install/agent-pack-installer.fs-helpers.d.ts.map +1 -0
  81. package/dist/src/install/agent-pack-installer.fs-helpers.js +59 -0
  82. package/dist/src/install/agent-pack-installer.fs-helpers.js.map +1 -0
  83. package/dist/src/install/agent-pack-installer.harness.d.ts +66 -0
  84. package/dist/src/install/agent-pack-installer.harness.d.ts.map +1 -0
  85. package/dist/src/install/agent-pack-installer.harness.js +310 -0
  86. package/dist/src/install/agent-pack-installer.harness.js.map +1 -0
  87. package/dist/src/install/agent-pack-installer.js +221 -0
  88. package/dist/src/install/agent-pack-installer.js.map +1 -0
  89. package/dist/src/install/agent-pack-installer.preserve.test.d.ts +11 -0
  90. package/dist/src/install/agent-pack-installer.preserve.test.d.ts.map +1 -0
  91. package/dist/src/install/agent-pack-installer.preserve.test.js +72 -0
  92. package/dist/src/install/agent-pack-installer.preserve.test.js.map +1 -0
  93. package/dist/src/install/agent-pack-installer.test.d.ts +2 -0
  94. package/dist/src/install/agent-pack-installer.test.d.ts.map +1 -0
  95. package/dist/src/install/agent-pack-installer.test.js +350 -0
  96. package/dist/src/install/agent-pack-installer.test.js.map +1 -0
  97. package/dist/src/install/agent-pack-installer.types.d.ts +51 -0
  98. package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -0
  99. package/dist/src/install/agent-pack-installer.types.js +16 -0
  100. package/dist/src/install/agent-pack-installer.types.js.map +1 -0
  101. package/dist/src/install/agent-pack-uninstaller.d.ts +43 -0
  102. package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -0
  103. package/dist/src/install/agent-pack-uninstaller.js +113 -0
  104. package/dist/src/install/agent-pack-uninstaller.js.map +1 -0
  105. package/dist/src/install/agent-pack-uninstaller.test.d.ts +2 -0
  106. package/dist/src/install/agent-pack-uninstaller.test.d.ts.map +1 -0
  107. package/dist/src/install/agent-pack-uninstaller.test.js +212 -0
  108. package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -0
  109. package/dist/src/install/index.d.ts +8 -1
  110. package/dist/src/install/index.d.ts.map +1 -1
  111. package/dist/src/install/index.js +8 -1
  112. package/dist/src/install/index.js.map +1 -1
  113. package/dist/src/install/paths.d.ts +17 -1
  114. package/dist/src/install/paths.d.ts.map +1 -1
  115. package/dist/src/install/paths.js +26 -0
  116. package/dist/src/install/paths.js.map +1 -1
  117. package/dist/src/install/paths.test.d.ts +2 -0
  118. package/dist/src/install/paths.test.d.ts.map +1 -0
  119. package/dist/src/install/paths.test.js +76 -0
  120. package/dist/src/install/paths.test.js.map +1 -0
  121. package/dist/src/journal/hash.d.ts +13 -0
  122. package/dist/src/journal/hash.d.ts.map +1 -0
  123. package/dist/src/journal/hash.js +16 -0
  124. package/dist/src/journal/hash.js.map +1 -0
  125. package/dist/src/journal/index.d.ts +15 -0
  126. package/dist/src/journal/index.d.ts.map +1 -0
  127. package/dist/src/journal/index.js +15 -0
  128. package/dist/src/journal/index.js.map +1 -0
  129. package/dist/src/journal/journal.test.d.ts +16 -0
  130. package/dist/src/journal/journal.test.d.ts.map +1 -0
  131. package/dist/src/journal/journal.test.js +171 -0
  132. package/dist/src/journal/journal.test.js.map +1 -0
  133. package/dist/src/journal/path.d.ts +44 -0
  134. package/dist/src/journal/path.d.ts.map +1 -0
  135. package/dist/src/journal/path.js +61 -0
  136. package/dist/src/journal/path.js.map +1 -0
  137. package/dist/src/journal/reader.d.ts +38 -0
  138. package/dist/src/journal/reader.d.ts.map +1 -0
  139. package/dist/src/journal/reader.js +93 -0
  140. package/dist/src/journal/reader.js.map +1 -0
  141. package/dist/src/journal/types.d.ts +87 -0
  142. package/dist/src/journal/types.d.ts.map +1 -0
  143. package/dist/src/journal/types.js +21 -0
  144. package/dist/src/journal/types.js.map +1 -0
  145. package/dist/src/journal/writer.d.ts +52 -0
  146. package/dist/src/journal/writer.d.ts.map +1 -0
  147. package/dist/src/journal/writer.js +125 -0
  148. package/dist/src/journal/writer.js.map +1 -0
  149. package/dist/src/paywall-triggers/index.d.ts +13 -0
  150. package/dist/src/paywall-triggers/index.d.ts.map +1 -0
  151. package/dist/src/paywall-triggers/index.js +13 -0
  152. package/dist/src/paywall-triggers/index.js.map +1 -0
  153. package/dist/src/paywall-triggers/path.d.ts +47 -0
  154. package/dist/src/paywall-triggers/path.d.ts.map +1 -0
  155. package/dist/src/paywall-triggers/path.js +73 -0
  156. package/dist/src/paywall-triggers/path.js.map +1 -0
  157. package/dist/src/paywall-triggers/store.d.ts +75 -0
  158. package/dist/src/paywall-triggers/store.d.ts.map +1 -0
  159. package/dist/src/paywall-triggers/store.js +122 -0
  160. package/dist/src/paywall-triggers/store.js.map +1 -0
  161. package/dist/src/paywall-triggers/store.test.d.ts +2 -0
  162. package/dist/src/paywall-triggers/store.test.d.ts.map +1 -0
  163. package/dist/src/paywall-triggers/store.test.js +121 -0
  164. package/dist/src/paywall-triggers/store.test.js.map +1 -0
  165. package/dist/src/paywall-triggers/types.d.ts +24 -0
  166. package/dist/src/paywall-triggers/types.d.ts.map +1 -0
  167. package/dist/src/paywall-triggers/types.js +13 -0
  168. package/dist/src/paywall-triggers/types.js.map +1 -0
  169. package/dist/src/security/scanner/SecurityScanner.compound.d.ts +13 -0
  170. package/dist/src/security/scanner/SecurityScanner.compound.d.ts.map +1 -0
  171. package/dist/src/security/scanner/SecurityScanner.compound.js +127 -0
  172. package/dist/src/security/scanner/SecurityScanner.compound.js.map +1 -0
  173. package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
  174. package/dist/src/security/scanner/SecurityScanner.js +10 -1
  175. package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
  176. package/dist/src/security/scanner/SecurityScanner.pii.d.ts +23 -0
  177. package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -0
  178. package/dist/src/security/scanner/SecurityScanner.pii.js +152 -0
  179. package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -0
  180. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts +5 -2
  181. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
  182. package/dist/src/security/scanner/SecurityScanner.scanners.js +63 -70
  183. package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
  184. package/dist/src/security/scanner/patterns.d.ts +2 -0
  185. package/dist/src/security/scanner/patterns.d.ts.map +1 -1
  186. package/dist/src/security/scanner/patterns.js +79 -11
  187. package/dist/src/security/scanner/patterns.js.map +1 -1
  188. package/dist/src/security/scanner/types.d.ts +2 -0
  189. package/dist/src/security/scanner/types.d.ts.map +1 -1
  190. package/dist/src/services/agent-pack/agent-pack.test.d.ts +18 -0
  191. package/dist/src/services/agent-pack/agent-pack.test.d.ts.map +1 -0
  192. package/dist/src/services/agent-pack/agent-pack.test.js +344 -0
  193. package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -0
  194. package/dist/src/services/agent-pack/hooks.d.ts +29 -0
  195. package/dist/src/services/agent-pack/hooks.d.ts.map +1 -0
  196. package/dist/src/services/agent-pack/hooks.js +139 -0
  197. package/dist/src/services/agent-pack/hooks.js.map +1 -0
  198. package/dist/src/services/agent-pack/index.d.ts +26 -0
  199. package/dist/src/services/agent-pack/index.d.ts.map +1 -0
  200. package/dist/src/services/agent-pack/index.js +109 -0
  201. package/dist/src/services/agent-pack/index.js.map +1 -0
  202. package/dist/src/services/agent-pack/prompt-source.d.ts +47 -0
  203. package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -0
  204. package/dist/src/services/agent-pack/prompt-source.js +182 -0
  205. package/dist/src/services/agent-pack/prompt-source.js.map +1 -0
  206. package/dist/src/services/agent-pack/shims.d.ts +40 -0
  207. package/dist/src/services/agent-pack/shims.d.ts.map +1 -0
  208. package/dist/src/services/agent-pack/shims.js +96 -0
  209. package/dist/src/services/agent-pack/shims.js.map +1 -0
  210. package/dist/src/services/agent-pack/skill-md.d.ts +35 -0
  211. package/dist/src/services/agent-pack/skill-md.d.ts.map +1 -0
  212. package/dist/src/services/agent-pack/skill-md.js +89 -0
  213. package/dist/src/services/agent-pack/skill-md.js.map +1 -0
  214. package/dist/src/services/agent-pack/types.d.ts +118 -0
  215. package/dist/src/services/agent-pack/types.d.ts.map +1 -0
  216. package/dist/src/services/agent-pack/types.js +61 -0
  217. package/dist/src/services/agent-pack/types.js.map +1 -0
  218. package/dist/src/services/agent-tool-profile.d.ts +59 -0
  219. package/dist/src/services/agent-tool-profile.d.ts.map +1 -0
  220. package/dist/src/services/agent-tool-profile.js +76 -0
  221. package/dist/src/services/agent-tool-profile.js.map +1 -0
  222. package/dist/src/services/agent-tool-profile.test.d.ts +2 -0
  223. package/dist/src/services/agent-tool-profile.test.d.ts.map +1 -0
  224. package/dist/src/services/agent-tool-profile.test.js +28 -0
  225. package/dist/src/services/agent-tool-profile.test.js.map +1 -0
  226. package/dist/src/services/bundled-sibling-scan.d.ts +111 -0
  227. package/dist/src/services/bundled-sibling-scan.d.ts.map +1 -0
  228. package/dist/src/services/bundled-sibling-scan.js +170 -0
  229. package/dist/src/services/bundled-sibling-scan.js.map +1 -0
  230. package/dist/src/services/skill-installation.io.d.ts +16 -5
  231. package/dist/src/services/skill-installation.io.d.ts.map +1 -1
  232. package/dist/src/services/skill-installation.io.js +44 -20
  233. package/dist/src/services/skill-installation.io.js.map +1 -1
  234. package/dist/src/services/skill-installation.policy.d.ts +96 -0
  235. package/dist/src/services/skill-installation.policy.d.ts.map +1 -0
  236. package/dist/src/services/skill-installation.policy.js +144 -0
  237. package/dist/src/services/skill-installation.policy.js.map +1 -0
  238. package/dist/src/services/skill-installation.service.d.ts.map +1 -1
  239. package/dist/src/services/skill-installation.service.js +9 -3
  240. package/dist/src/services/skill-installation.service.js.map +1 -1
  241. package/dist/src/sources/index.d.ts +1 -0
  242. package/dist/src/sources/index.d.ts.map +1 -1
  243. package/dist/src/sources/index.js +4 -0
  244. package/dist/src/sources/index.js.map +1 -1
  245. package/dist/src/sync/index.d.ts +6 -0
  246. package/dist/src/sync/index.d.ts.map +1 -1
  247. package/dist/src/sync/index.js +8 -0
  248. package/dist/src/sync/index.js.map +1 -1
  249. package/dist/src/sync/inventory-builder.d.ts +21 -0
  250. package/dist/src/sync/inventory-builder.d.ts.map +1 -0
  251. package/dist/src/sync/inventory-builder.js +26 -0
  252. package/dist/src/sync/inventory-builder.js.map +1 -0
  253. package/dist/src/sync/inventory-client.d.ts +80 -0
  254. package/dist/src/sync/inventory-client.d.ts.map +1 -0
  255. package/dist/src/sync/inventory-client.js +204 -0
  256. package/dist/src/sync/inventory-client.js.map +1 -0
  257. package/dist/src/sync/inventory-client.test.d.ts +14 -0
  258. package/dist/src/sync/inventory-client.test.d.ts.map +1 -0
  259. package/dist/src/sync/inventory-client.test.js +212 -0
  260. package/dist/src/sync/inventory-client.test.js.map +1 -0
  261. package/dist/src/sync/inventory-collector.d.ts +35 -0
  262. package/dist/src/sync/inventory-collector.d.ts.map +1 -0
  263. package/dist/src/sync/inventory-collector.js +176 -0
  264. package/dist/src/sync/inventory-collector.js.map +1 -0
  265. package/dist/src/sync/inventory-collector.test.d.ts +14 -0
  266. package/dist/src/sync/inventory-collector.test.d.ts.map +1 -0
  267. package/dist/src/sync/inventory-collector.test.js +156 -0
  268. package/dist/src/sync/inventory-collector.test.js.map +1 -0
  269. package/dist/src/sync/inventory-device.d.ts +36 -0
  270. package/dist/src/sync/inventory-device.d.ts.map +1 -0
  271. package/dist/src/sync/inventory-device.js +58 -0
  272. package/dist/src/sync/inventory-device.js.map +1 -0
  273. package/dist/src/sync/inventory-push.d.ts +45 -0
  274. package/dist/src/sync/inventory-push.d.ts.map +1 -0
  275. package/dist/src/sync/inventory-push.js +62 -0
  276. package/dist/src/sync/inventory-push.js.map +1 -0
  277. package/dist/src/sync/inventory-push.test.d.ts +16 -0
  278. package/dist/src/sync/inventory-push.test.d.ts.map +1 -0
  279. package/dist/src/sync/inventory-push.test.js +104 -0
  280. package/dist/src/sync/inventory-push.test.js.map +1 -0
  281. package/dist/src/sync/inventory-types.d.ts +110 -0
  282. package/dist/src/sync/inventory-types.d.ts.map +1 -0
  283. package/dist/src/sync/inventory-types.js +45 -0
  284. package/dist/src/sync/inventory-types.js.map +1 -0
  285. package/dist/src/telemetry/agent-marker.d.ts +137 -0
  286. package/dist/src/telemetry/agent-marker.d.ts.map +1 -0
  287. package/dist/src/telemetry/agent-marker.js +242 -0
  288. package/dist/src/telemetry/agent-marker.js.map +1 -0
  289. package/dist/src/telemetry/agent-marker.test.d.ts +13 -0
  290. package/dist/src/telemetry/agent-marker.test.d.ts.map +1 -0
  291. package/dist/src/telemetry/agent-marker.test.js +202 -0
  292. package/dist/src/telemetry/agent-marker.test.js.map +1 -0
  293. package/dist/src/telemetry/index.d.ts +2 -1
  294. package/dist/src/telemetry/index.d.ts.map +1 -1
  295. package/dist/src/telemetry/index.js +6 -1
  296. package/dist/src/telemetry/index.js.map +1 -1
  297. package/dist/src/telemetry/posthog.d.ts +10 -0
  298. package/dist/src/telemetry/posthog.d.ts.map +1 -1
  299. package/dist/src/telemetry/posthog.js +5 -1
  300. package/dist/src/telemetry/posthog.js.map +1 -1
  301. package/dist/src/telemetry/wrap.d.ts +28 -7
  302. package/dist/src/telemetry/wrap.d.ts.map +1 -1
  303. package/dist/src/telemetry/wrap.gate.test.d.ts +22 -0
  304. package/dist/src/telemetry/wrap.gate.test.d.ts.map +1 -0
  305. package/dist/src/telemetry/wrap.gate.test.js +197 -0
  306. package/dist/src/telemetry/wrap.gate.test.js.map +1 -0
  307. package/dist/src/telemetry/wrap.js +111 -26
  308. package/dist/src/telemetry/wrap.js.map +1 -1
  309. package/dist/src/telemetry/wrap.marker.test.d.ts +16 -0
  310. package/dist/src/telemetry/wrap.marker.test.d.ts.map +1 -0
  311. package/dist/src/telemetry/wrap.marker.test.js +185 -0
  312. package/dist/src/telemetry/wrap.marker.test.js.map +1 -0
  313. package/dist/src/telemetry/wrap.test.js +4 -0
  314. package/dist/src/telemetry/wrap.test.js.map +1 -1
  315. package/dist/tests/SecurityScanner.exec.test.js +60 -0
  316. package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
  317. package/dist/tests/security/ContinuousSecurity.test.js +10 -4
  318. package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
  319. package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts +2 -0
  320. package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts.map +1 -0
  321. package/dist/tests/security/SecurityScanner.chmod-evasion.test.js +126 -0
  322. package/dist/tests/security/SecurityScanner.chmod-evasion.test.js.map +1 -0
  323. package/dist/tests/security/chmod-compound.test.d.ts +2 -0
  324. package/dist/tests/security/chmod-compound.test.d.ts.map +1 -0
  325. package/dist/tests/security/chmod-compound.test.js +188 -0
  326. package/dist/tests/security/chmod-compound.test.js.map +1 -0
  327. package/dist/tests/security/pii-detection.test.js +131 -0
  328. package/dist/tests/security/pii-detection.test.js.map +1 -1
  329. package/dist/tests/security/scanner-regression-guard.test.d.ts +23 -7
  330. package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
  331. package/dist/tests/security/scanner-regression-guard.test.js +27 -11
  332. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
  333. package/dist/tests/security/sensitive-path-fp.test.d.ts +2 -0
  334. package/dist/tests/security/sensitive-path-fp.test.d.ts.map +1 -0
  335. package/dist/tests/security/sensitive-path-fp.test.js +142 -0
  336. package/dist/tests/security/sensitive-path-fp.test.js.map +1 -0
  337. package/dist/tests/services/bundled-sibling-scan.test.d.ts +2 -0
  338. package/dist/tests/services/bundled-sibling-scan.test.d.ts.map +1 -0
  339. package/dist/tests/services/bundled-sibling-scan.test.js +139 -0
  340. package/dist/tests/services/bundled-sibling-scan.test.js.map +1 -0
  341. package/dist/tests/unit/services/skill-installation.io.test.js +166 -0
  342. package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
  343. package/dist/tests/unit/services/skill-installation.policy.test.d.ts +8 -0
  344. package/dist/tests/unit/services/skill-installation.policy.test.d.ts.map +1 -0
  345. package/dist/tests/unit/services/skill-installation.policy.test.js +151 -0
  346. package/dist/tests/unit/services/skill-installation.policy.test.js.map +1 -0
  347. package/package.json +23 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.json-array.js","sourceRoot":"","sources":["../../../src/install/agent-config-merge.json-array.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * JSON config-merge helper for `sklx agent install` (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Targets the `mcpServers`/`mcp`-shaped config files four of the seven
5
+ * harnesses use (claude-code, cursor, copilot, windsurf; also opencode's
6
+ * best-effort `mcp` key — see `agent-harness-targets.ts`). Backup-first,
7
+ * idempotent, preserve-and-prompt semantics per the plan's P-5 "Harness MCP
8
+ * config files" invariant: "Installer merges keys it owns, never whole-file
9
+ * writes; detects foreign `skillsmith` entries and prompts."
10
+ *
11
+ * Survey of existing config-write patterns (plan-mandated, "convention check
12
+ * before novelty"): `grep -rn "mcp.json\|mcp_config\|claude.json"
13
+ * packages/cli/src/ packages/core/src/` turned up
14
+ * `mcp-server.template.snippets.ts` (SMI-4580, docs-only — renders snippet
15
+ * TEXT for a human to paste, never writes a file) and
16
+ * `skill-installation.policy.ts` (classifies `.mcp.json` as a scan target,
17
+ * never writes one). Neither is a merge-writer to follow structurally, so
18
+ * this module's shape instead mirrors the nearest write-path precedent in
19
+ * the codebase: `config/index.ts`'s `saveConfig()` (mkdir 0700 + writeFile
20
+ * 0600, read-merge-write, JSON.stringify(..., null, 2)).
21
+ *
22
+ * @module @skillsmith/core/install/agent-config-merge.json
23
+ */
24
+ import { type MergeOptions, type MergeResult } from './agent-config-merge.types.js';
25
+ /**
26
+ * Merge a `skillsmith` MCP server entry into a JSON config file at
27
+ * `opts.path`, under `opts.keyPath` (e.g. `['mcpServers']`).
28
+ *
29
+ * Never performs a whole-file write of unrelated keys — the file is parsed,
30
+ * exactly one nested key (`skillsmith`) is set at `[...keyPath, 'skillsmith']`,
31
+ * and the WHOLE document (all other keys untouched) is re-serialized. A
32
+ * missing file is treated as `{}` (created fresh).
33
+ */
34
+ export declare function mergeJsonMcpEntry(opts: MergeOptions & {
35
+ keyPath: readonly string[];
36
+ }): MergeResult;
37
+ //# sourceMappingURL=agent-config-merge.json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.json.d.ts","sourceRoot":"","sources":["../../../src/install/agent-config-merge.json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAA;AAuCtC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,GAAG;IAAE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAClD,WAAW,CAuEb"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * JSON config-merge helper for `sklx agent install` (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Targets the `mcpServers`/`mcp`-shaped config files four of the seven
5
+ * harnesses use (claude-code, cursor, copilot, windsurf; also opencode's
6
+ * best-effort `mcp` key — see `agent-harness-targets.ts`). Backup-first,
7
+ * idempotent, preserve-and-prompt semantics per the plan's P-5 "Harness MCP
8
+ * config files" invariant: "Installer merges keys it owns, never whole-file
9
+ * writes; detects foreign `skillsmith` entries and prompts."
10
+ *
11
+ * Survey of existing config-write patterns (plan-mandated, "convention check
12
+ * before novelty"): `grep -rn "mcp.json\|mcp_config\|claude.json"
13
+ * packages/cli/src/ packages/core/src/` turned up
14
+ * `mcp-server.template.snippets.ts` (SMI-4580, docs-only — renders snippet
15
+ * TEXT for a human to paste, never writes a file) and
16
+ * `skill-installation.policy.ts` (classifies `.mcp.json` as a scan target,
17
+ * never writes one). Neither is a merge-writer to follow structurally, so
18
+ * this module's shape instead mirrors the nearest write-path precedent in
19
+ * the codebase: `config/index.ts`'s `saveConfig()` (mkdir 0700 + writeFile
20
+ * 0600, read-merge-write, JSON.stringify(..., null, 2)).
21
+ *
22
+ * @module @skillsmith/core/install/agent-config-merge.json
23
+ */
24
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
25
+ import { dirname, join } from 'node:path';
26
+ import { deepEqualJson, looksLikeOurMcpEntry, markBackedUp, shouldBackup, } from './agent-config-merge.types.js';
27
+ /** Read + set a nested key path on a JSON object, creating intermediate objects. */
28
+ function getAtPath(root, keyPath) {
29
+ let cur = root;
30
+ for (const key of keyPath) {
31
+ if (!cur || typeof cur !== 'object' || Array.isArray(cur))
32
+ return undefined;
33
+ cur = cur[key];
34
+ }
35
+ return cur;
36
+ }
37
+ function setAtPath(root, keyPath, value) {
38
+ let cur = root;
39
+ for (let i = 0; i < keyPath.length - 1; i++) {
40
+ const key = keyPath[i];
41
+ const next = cur[key];
42
+ if (!next || typeof next !== 'object' || Array.isArray(next)) {
43
+ cur[key] = {};
44
+ }
45
+ cur = cur[key];
46
+ }
47
+ const lastKey = keyPath[keyPath.length - 1];
48
+ if (lastKey !== undefined)
49
+ cur[lastKey] = value;
50
+ }
51
+ function writeBackup(sourcePath, backupDir) {
52
+ mkdirSync(backupDir, { recursive: true, mode: 0o700 });
53
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
54
+ const baseName = sourcePath.split('/').pop() ?? 'config';
55
+ const backupPath = join(backupDir, `${stamp}-${baseName}.bak`);
56
+ writeFileSync(backupPath, readFileSync(sourcePath, 'utf-8'), { mode: 0o600 });
57
+ return backupPath;
58
+ }
59
+ /**
60
+ * Merge a `skillsmith` MCP server entry into a JSON config file at
61
+ * `opts.path`, under `opts.keyPath` (e.g. `['mcpServers']`).
62
+ *
63
+ * Never performs a whole-file write of unrelated keys — the file is parsed,
64
+ * exactly one nested key (`skillsmith`) is set at `[...keyPath, 'skillsmith']`,
65
+ * and the WHOLE document (all other keys untouched) is re-serialized. A
66
+ * missing file is treated as `{}` (created fresh).
67
+ */
68
+ export function mergeJsonMcpEntry(opts) {
69
+ const { path, keyPath, entryValue, backupDir, force = false, alreadyBackedUpPaths } = opts;
70
+ let doc = {};
71
+ let existed = false;
72
+ if (existsSync(path)) {
73
+ existed = true;
74
+ let raw;
75
+ try {
76
+ raw = readFileSync(path, 'utf-8');
77
+ }
78
+ catch (e) {
79
+ return { status: 'error', path, backupPath: null, errorMessage: e.message };
80
+ }
81
+ try {
82
+ const parsed = raw.trim().length === 0 ? {} : JSON.parse(raw);
83
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
84
+ return { status: 'error', path, backupPath: null, errorMessage: 'not a JSON object' };
85
+ }
86
+ doc = parsed;
87
+ }
88
+ catch (e) {
89
+ return { status: 'error', path, backupPath: null, errorMessage: e.message };
90
+ }
91
+ }
92
+ const container = getAtPath(doc, keyPath);
93
+ const existingEntry = container && typeof container === 'object' && !Array.isArray(container)
94
+ ? container.skillsmith
95
+ : undefined;
96
+ if (existingEntry !== undefined) {
97
+ if (deepEqualJson(existingEntry, entryValue)) {
98
+ return { status: 'unchanged', path, backupPath: null };
99
+ }
100
+ if (!looksLikeOurMcpEntry(existingEntry) && !force) {
101
+ // Non-interactive refusal (P-5 preserve-existing): never clobber a
102
+ // foreign entry silently, never block on a prompt in a scripted
103
+ // install — surface a 'conflict' the CLI report + --force flag address.
104
+ return { status: 'conflict', path, backupPath: null };
105
+ }
106
+ // Recognizable as ours (or force=true): back up (once per install run),
107
+ // then overwrite. Marking `alreadyBackedUpPaths` UNCONDITIONALLY (not
108
+ // only when a backup was actually written) is what prevents a LATER
109
+ // merge into this same path this run from treating content THIS merge
110
+ // just wrote as pre-install state needing its own backup — see
111
+ // `agent-pack-installer.test.ts` "double-install idempotency" /
112
+ // "preserve-existing" suites.
113
+ const backupPath = existed && shouldBackup(path, alreadyBackedUpPaths) ? writeBackup(path, backupDir) : null;
114
+ markBackedUp(path, alreadyBackedUpPaths);
115
+ setAtPath(doc, keyPath, { ...container, skillsmith: entryValue });
116
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
117
+ writeFileSync(path, JSON.stringify(doc, null, 2) + '\n', { mode: 0o600 });
118
+ return { status: 'updated', path, backupPath };
119
+ }
120
+ // No existing entry — safe create. Still back up the FILE (not the
121
+ // skillsmith key, which didn't exist) so a foreign file with unrelated
122
+ // content the user cares about is always one restore away — unless an
123
+ // earlier merge THIS RUN already captured the pre-install state.
124
+ const backupPath = existed && shouldBackup(path, alreadyBackedUpPaths) ? writeBackup(path, backupDir) : null;
125
+ markBackedUp(path, alreadyBackedUpPaths);
126
+ const currentContainer = container && typeof container === 'object' && !Array.isArray(container)
127
+ ? container
128
+ : {};
129
+ setAtPath(doc, keyPath, { ...currentContainer, skillsmith: entryValue });
130
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
131
+ writeFileSync(path, JSON.stringify(doc, null, 2) + '\n', { mode: 0o600 });
132
+ return { status: 'created', path, backupPath };
133
+ }
134
+ //# sourceMappingURL=agent-config-merge.json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.json.js","sourceRoot":"","sources":["../../../src/install/agent-config-merge.json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Marker-delimited TOML block merge for Codex (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Codex's config lives entirely in `~/.codex/config.toml` — MCP server
5
+ * registration (`[mcp_servers.skillsmith]`), the named-agent shim
6
+ * (`[agents.skillsmith-agent]`, already rendered as TOML text by
7
+ * `renderCodexToml` in the — locked for this step — agent-pack generator),
8
+ * and hook wiring all share this one file. The repo has no confirmed real
9
+ * TOML dependency (`smol-toml` appears only under root `overrides`, pinning
10
+ * a transitive tool dependency, not a direct `dependencies`/`devDependencies`
11
+ * entry of `@skillsmith/core` or `@skillsmith/cli`) — adding one is a
12
+ * lockfile-risk change out of scope for this step. Per the task brief's
13
+ * explicit fallback for "no [format] dep": generate the block textually with
14
+ * a clearly-delimited managed section, exactly mirroring how
15
+ * `renderCodexToml` (shims.ts, locked) already emits raw TOML text via
16
+ * `JSON.stringify`-quoted strings rather than a library. This keeps every
17
+ * OTHER line of the user's `config.toml` — their own tables, comments,
18
+ * formatting — completely untouched; only the text between our markers is
19
+ * ever rewritten.
20
+ *
21
+ * Ownership model: text between `# >>> skillsmith:<markerId> >>>` and
22
+ * `# <<< skillsmith:<markerId> <<<` is unambiguously ours (idempotent
23
+ * update-in-place). A bare occurrence of the target table header OUTSIDE any
24
+ * marker block (`foreignHeaderPattern`) is a hand-written foreign entry —
25
+ * `force` does NOT override this case: appending a second `[table]` header
26
+ * with the same name risks producing invalid/ambiguous TOML without a real
27
+ * parser to detect and merge it, so this always returns `'conflict'` for a
28
+ * genuinely foreign, non-delimited entry regardless of `force`.
29
+ *
30
+ * @module @skillsmith/core/install/agent-config-merge.toml-block
31
+ */
32
+ import { type MergeResult } from './agent-config-merge.types.js';
33
+ export interface TomlBlockMergeOptions {
34
+ path: string;
35
+ /** Stable id for the marker comment, e.g. `'mcp_servers.skillsmith'`. */
36
+ markerId: string;
37
+ /** Raw TOML text to install between the markers (no marker lines, no leading/trailing blank lines required). */
38
+ blockContent: string;
39
+ /** Matches a bare (non-delimited) occurrence of the same table header, e.g. `/^\[mcp_servers\.skillsmith\]/m`. */
40
+ foreignHeaderPattern: RegExp;
41
+ backupDir: string;
42
+ force?: boolean;
43
+ /** See `MergeOptions.alreadyBackedUpPaths` — Codex merges TWO blocks (MCP + agents shim) into the same `config.toml` per install run. */
44
+ alreadyBackedUpPaths?: Set<string>;
45
+ }
46
+ /** Merge a marker-delimited TOML block into `opts.path`. See module header for the full ownership contract. */
47
+ export declare function mergeTomlBlock(opts: TomlBlockMergeOptions): MergeResult;
48
+ //# sourceMappingURL=agent-config-merge.toml-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.toml-block.d.ts","sourceRoot":"","sources":["../../../src/install/agent-config-merge.toml-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAKH,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAE5F,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAA;IAChB,gHAAgH;IAChH,YAAY,EAAE,MAAM,CAAA;IACpB,kHAAkH;IAClH,oBAAoB,EAAE,MAAM,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,yIAAyI;IACzI,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACnC;AAkBD,+GAA+G;AAC/G,wBAAgB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,WAAW,CAmEvE"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Marker-delimited TOML block merge for Codex (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Codex's config lives entirely in `~/.codex/config.toml` — MCP server
5
+ * registration (`[mcp_servers.skillsmith]`), the named-agent shim
6
+ * (`[agents.skillsmith-agent]`, already rendered as TOML text by
7
+ * `renderCodexToml` in the — locked for this step — agent-pack generator),
8
+ * and hook wiring all share this one file. The repo has no confirmed real
9
+ * TOML dependency (`smol-toml` appears only under root `overrides`, pinning
10
+ * a transitive tool dependency, not a direct `dependencies`/`devDependencies`
11
+ * entry of `@skillsmith/core` or `@skillsmith/cli`) — adding one is a
12
+ * lockfile-risk change out of scope for this step. Per the task brief's
13
+ * explicit fallback for "no [format] dep": generate the block textually with
14
+ * a clearly-delimited managed section, exactly mirroring how
15
+ * `renderCodexToml` (shims.ts, locked) already emits raw TOML text via
16
+ * `JSON.stringify`-quoted strings rather than a library. This keeps every
17
+ * OTHER line of the user's `config.toml` — their own tables, comments,
18
+ * formatting — completely untouched; only the text between our markers is
19
+ * ever rewritten.
20
+ *
21
+ * Ownership model: text between `# >>> skillsmith:<markerId> >>>` and
22
+ * `# <<< skillsmith:<markerId> <<<` is unambiguously ours (idempotent
23
+ * update-in-place). A bare occurrence of the target table header OUTSIDE any
24
+ * marker block (`foreignHeaderPattern`) is a hand-written foreign entry —
25
+ * `force` does NOT override this case: appending a second `[table]` header
26
+ * with the same name risks producing invalid/ambiguous TOML without a real
27
+ * parser to detect and merge it, so this always returns `'conflict'` for a
28
+ * genuinely foreign, non-delimited entry regardless of `force`.
29
+ *
30
+ * @module @skillsmith/core/install/agent-config-merge.toml-block
31
+ */
32
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
33
+ import { dirname, join } from 'node:path';
34
+ import { markBackedUp, shouldBackup } from './agent-config-merge.types.js';
35
+ function markerStart(markerId) {
36
+ return `# >>> skillsmith:${markerId} >>>`;
37
+ }
38
+ function markerEnd(markerId) {
39
+ return `# <<< skillsmith:${markerId} <<<`;
40
+ }
41
+ function writeBackup(sourcePath, backupDir) {
42
+ mkdirSync(backupDir, { recursive: true, mode: 0o700 });
43
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
44
+ const baseName = sourcePath.split('/').pop() ?? 'config';
45
+ const backupPath = join(backupDir, `${stamp}-${baseName}.bak`);
46
+ writeFileSync(backupPath, readFileSync(sourcePath, 'utf-8'), { mode: 0o600 });
47
+ return backupPath;
48
+ }
49
+ /** Merge a marker-delimited TOML block into `opts.path`. See module header for the full ownership contract. */
50
+ export function mergeTomlBlock(opts) {
51
+ const { path, markerId, blockContent, foreignHeaderPattern, backupDir, force = false, alreadyBackedUpPaths, } = opts;
52
+ const start = markerStart(markerId);
53
+ const end = markerEnd(markerId);
54
+ const trimmedBlock = blockContent.trim();
55
+ const existed = existsSync(path);
56
+ let raw = '';
57
+ if (existed) {
58
+ try {
59
+ raw = readFileSync(path, 'utf-8');
60
+ }
61
+ catch (e) {
62
+ return { status: 'error', path, backupPath: null, errorMessage: e.message };
63
+ }
64
+ }
65
+ const blockRegex = new RegExp(`${escapeRegExp(start)}\\n([\\s\\S]*?)\\n${escapeRegExp(end)}`);
66
+ const match = raw.match(blockRegex);
67
+ if (match) {
68
+ const existingBlock = (match[1] ?? '').trim();
69
+ if (existingBlock === trimmedBlock) {
70
+ return { status: 'unchanged', path, backupPath: null };
71
+ }
72
+ const backupPath = shouldBackup(path, alreadyBackedUpPaths)
73
+ ? writeBackup(path, backupDir)
74
+ : null;
75
+ markBackedUp(path, alreadyBackedUpPaths);
76
+ const replacement = `${start}\n${trimmedBlock}\n${end}`;
77
+ const updated = raw.replace(blockRegex, replacement);
78
+ writeFileSync(path, updated, { mode: 0o600 });
79
+ return { status: 'updated', path, backupPath };
80
+ }
81
+ // No marker block found. A bare same-name table header outside any marker
82
+ // is a foreign hand-written entry — never safely mergeable without a real
83
+ // TOML parser (see module header). `force` does not override this case.
84
+ if (foreignHeaderPattern.test(raw)) {
85
+ void force;
86
+ return { status: 'conflict', path, backupPath: null };
87
+ }
88
+ const backupPath = existed && shouldBackup(path, alreadyBackedUpPaths) ? writeBackup(path, backupDir) : null;
89
+ markBackedUp(path, alreadyBackedUpPaths);
90
+ const separator = raw.length > 0 && !raw.endsWith('\n\n') ? (raw.endsWith('\n') ? '\n' : '\n\n') : '';
91
+ const appended = `${raw}${separator}${start}\n${trimmedBlock}\n${end}\n`;
92
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
93
+ writeFileSync(path, appended, { mode: 0o600 });
94
+ // Always 'created', never `existed ? 'updated' : 'created'`: OUR block
95
+ // didn't exist before this write regardless of whether the surrounding
96
+ // FILE pre-existed (a foreign file with unrelated content, or — within
97
+ // one install run — a file another block already created moments ago,
98
+ // e.g. Codex's agents-shim block creating config.toml before the
99
+ // mcp_servers block merges into it). 'updated' is reserved for replacing
100
+ // OUR OWN previously-installed block with different content (the `match`
101
+ // branch above).
102
+ return { status: 'created', path, backupPath };
103
+ }
104
+ function escapeRegExp(s) {
105
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
106
+ }
107
+ //# sourceMappingURL=agent-config-merge.toml-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.toml-block.js","sourceRoot":"","sources":["../../../src/install/agent-config-merge.toml-block.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Shared result/option types for the agent-install config-merge helpers
3
+ * (SMI-5456 Wave 1 Step 5). One shape reused by the JSON, YAML, and
4
+ * TOML-block merge implementations so the installer orchestrator branches on
5
+ * a single result contract regardless of which harness's config format it
6
+ * just merged into.
7
+ *
8
+ * @module @skillsmith/core/install/agent-config-merge.types
9
+ */
10
+ /**
11
+ * Outcome of a single merge attempt.
12
+ *
13
+ * created - the file (or the whole key path) did not exist; created fresh.
14
+ * updated - an entry recognizable as OURS existed with different content
15
+ * (e.g. a version bump); backed up the file, then overwrote.
16
+ * unchanged - an entry recognizable as OURS already matched exactly —
17
+ * idempotent no-op, no backup written (P-5 double-install test).
18
+ * conflict - an entry existed that does NOT look like ours; left
19
+ * untouched unless `force` was passed.
20
+ * error - the file could not be read/parsed/written; left untouched.
21
+ */
22
+ export type MergeStatus = 'created' | 'updated' | 'unchanged' | 'conflict' | 'error';
23
+ export interface MergeResult {
24
+ status: MergeStatus;
25
+ path: string;
26
+ /** Absolute path to the pre-write backup, or null when no backup was needed. */
27
+ backupPath: string | null;
28
+ /** Present only when status is 'error'. */
29
+ errorMessage?: string;
30
+ }
31
+ export interface MergeOptions {
32
+ path: string;
33
+ /** The value to install under the `skillsmith` key. */
34
+ entryValue: Record<string, unknown>;
35
+ /** Directory backups are written into. Caller ensures it exists. */
36
+ backupDir: string;
37
+ /**
38
+ * When an existing entry does not look like ours, overwrite it anyway.
39
+ * Defaults to false — the non-interactive refusal path (P-5 preserve-
40
+ * existing test): no prompt, no silent clobber, just a `'conflict'` result
41
+ * the caller surfaces in the per-harness report.
42
+ */
43
+ force?: boolean;
44
+ /**
45
+ * Paths already backed up during THIS `installAgentPack` run (shared
46
+ * across every merge call in the run — `HarnessInstallCtx.backedUpPaths`).
47
+ * Some harnesses (claude-code) merge into the SAME file more than once per
48
+ * run (SessionStart hook, SessionEnd hook, then MCP registration, all in
49
+ * `~/.claude/settings.json`) — without this, the second and third merges
50
+ * would each "back up" a state that WE ourselves just wrote earlier in the
51
+ * same run, producing redundant, meaningless backups. A path is only ever
52
+ * backed up once per run, capturing genuine pre-install content.
53
+ */
54
+ alreadyBackedUpPaths?: Set<string>;
55
+ }
56
+ /**
57
+ * Decide whether a merge should take a backup of `path` right now: only if
58
+ * it hasn't already been backed up earlier in this same install run. Callers
59
+ * that DO write a backup must call {@link markBackedUp} immediately after.
60
+ */
61
+ export declare function shouldBackup(path: string, alreadyBackedUpPaths: Set<string> | undefined): boolean;
62
+ /** Record that `path` has now been backed up for the remainder of this install run. */
63
+ export declare function markBackedUp(path: string, alreadyBackedUpPaths: Set<string> | undefined): void;
64
+ /**
65
+ * Heuristic ownership check shared by every format-specific merge helper:
66
+ * does an existing entry look like a Skillsmith MCP server registration we
67
+ * (a prior `sklx agent install` run) wrote, as opposed to a user's own
68
+ * hand-written `skillsmith`-named entry pointing somewhere else entirely?
69
+ *
70
+ * There is no injected marker field in the entry value itself (that would
71
+ * pollute a config another tool's strict-schema client might read) — instead
72
+ * this checks for the structural fingerprint our own entries always carry,
73
+ * across BOTH entry conventions the installer writes:
74
+ * - mcpServers convention (claude-code/cursor/copilot/windsurf/hermes):
75
+ * an `args` array mentioning `@skillsmith/mcp-server`, or an
76
+ * `env.SKILLSMITH_TOOL_PROFILE` key.
77
+ * - OpenCode convention (`buildOpenCodeMcpEntryValue`): a `command` ARRAY
78
+ * mentioning `@skillsmith/mcp-server`, or an
79
+ * `environment.SKILLSMITH_TOOL_PROFILE` key. Without these two checks, a
80
+ * re-install after any entry-value change would misclassify our own
81
+ * prior OpenCode entry as foreign and refuse to update it.
82
+ * Any one is a strong, low-false-positive signal.
83
+ */
84
+ export declare function looksLikeOurMcpEntry(value: unknown): boolean;
85
+ /** Deep structural equality for plain JSON-shaped values (objects/arrays/primitives). */
86
+ export declare function deepEqualJson(a: unknown, b: unknown): boolean;
87
+ //# sourceMappingURL=agent-config-merge.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.types.d.ts","sourceRoot":"","sources":["../../../src/install/agent-config-merge.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAA;AAEpF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,gFAAgF;IAChF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACnC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,OAAO,CAEjG;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,IAAI,CAE9F;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAa5D;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAkB7D"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Shared result/option types for the agent-install config-merge helpers
3
+ * (SMI-5456 Wave 1 Step 5). One shape reused by the JSON, YAML, and
4
+ * TOML-block merge implementations so the installer orchestrator branches on
5
+ * a single result contract regardless of which harness's config format it
6
+ * just merged into.
7
+ *
8
+ * @module @skillsmith/core/install/agent-config-merge.types
9
+ */
10
+ /**
11
+ * Decide whether a merge should take a backup of `path` right now: only if
12
+ * it hasn't already been backed up earlier in this same install run. Callers
13
+ * that DO write a backup must call {@link markBackedUp} immediately after.
14
+ */
15
+ export function shouldBackup(path, alreadyBackedUpPaths) {
16
+ return !alreadyBackedUpPaths?.has(path);
17
+ }
18
+ /** Record that `path` has now been backed up for the remainder of this install run. */
19
+ export function markBackedUp(path, alreadyBackedUpPaths) {
20
+ alreadyBackedUpPaths?.add(path);
21
+ }
22
+ /**
23
+ * Heuristic ownership check shared by every format-specific merge helper:
24
+ * does an existing entry look like a Skillsmith MCP server registration we
25
+ * (a prior `sklx agent install` run) wrote, as opposed to a user's own
26
+ * hand-written `skillsmith`-named entry pointing somewhere else entirely?
27
+ *
28
+ * There is no injected marker field in the entry value itself (that would
29
+ * pollute a config another tool's strict-schema client might read) — instead
30
+ * this checks for the structural fingerprint our own entries always carry,
31
+ * across BOTH entry conventions the installer writes:
32
+ * - mcpServers convention (claude-code/cursor/copilot/windsurf/hermes):
33
+ * an `args` array mentioning `@skillsmith/mcp-server`, or an
34
+ * `env.SKILLSMITH_TOOL_PROFILE` key.
35
+ * - OpenCode convention (`buildOpenCodeMcpEntryValue`): a `command` ARRAY
36
+ * mentioning `@skillsmith/mcp-server`, or an
37
+ * `environment.SKILLSMITH_TOOL_PROFILE` key. Without these two checks, a
38
+ * re-install after any entry-value change would misclassify our own
39
+ * prior OpenCode entry as foreign and refuse to update it.
40
+ * Any one is a strong, low-false-positive signal.
41
+ */
42
+ export function looksLikeOurMcpEntry(value) {
43
+ if (!value || typeof value !== 'object')
44
+ return false;
45
+ const v = value;
46
+ const mentionsOurPackage = (arr) => Array.isArray(arr) &&
47
+ arr.some((a) => typeof a === 'string' && a.includes('@skillsmith/mcp-server'));
48
+ if (mentionsOurPackage(v.args))
49
+ return true;
50
+ if (mentionsOurPackage(v.command))
51
+ return true;
52
+ const hasProfileKey = (obj) => !!obj && typeof obj === 'object' && 'SKILLSMITH_TOOL_PROFILE' in obj;
53
+ if (hasProfileKey(v.env))
54
+ return true;
55
+ if (hasProfileKey(v.environment))
56
+ return true;
57
+ return false;
58
+ }
59
+ /** Deep structural equality for plain JSON-shaped values (objects/arrays/primitives). */
60
+ export function deepEqualJson(a, b) {
61
+ if (a === b)
62
+ return true;
63
+ if (typeof a !== typeof b)
64
+ return false;
65
+ if (a === null || b === null)
66
+ return a === b;
67
+ if (Array.isArray(a) || Array.isArray(b)) {
68
+ if (!Array.isArray(a) || !Array.isArray(b))
69
+ return false;
70
+ if (a.length !== b.length)
71
+ return false;
72
+ return a.every((v, i) => deepEqualJson(v, b[i]));
73
+ }
74
+ if (typeof a === 'object' && typeof b === 'object') {
75
+ const aKeys = Object.keys(a).sort();
76
+ const bKeys = Object.keys(b).sort();
77
+ if (aKeys.length !== bKeys.length || aKeys.some((k, i) => k !== bKeys[i]))
78
+ return false;
79
+ return aKeys.every((k) => deepEqualJson(a[k], b[k]));
80
+ }
81
+ return false;
82
+ }
83
+ //# sourceMappingURL=agent-config-merge.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.types.js","sourceRoot":"","sources":["../../../src/install/agent-config-merge.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * YAML config-merge helper for Hermes (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Hermes is the one target harness whose MCP config is YAML
5
+ * (`~/.hermes/config.yaml`, key `mcp_servers:` — spike report §(b),
6
+ * well-verified against three independent official doc pages). The repo
7
+ * already carries a real `yaml` dependency (`packages/core/package.json` /
8
+ * root `package.json`, `"yaml": "^2.8.3"` — also already used by
9
+ * `packages/core/src/services/agent-pack/agent-pack.test.ts`), so this uses
10
+ * the library's structured Document API (`parseDocument`/`Document#setIn`)
11
+ * rather than the textual delimited-block scheme the task brief allowed as a
12
+ * fallback for "no YAML dep" — that fallback does not apply here since the
13
+ * dependency exists.
14
+ *
15
+ * GOVERNANCE FIX (SMI-5456 code review, 2026-07-01): this module originally
16
+ * used the library's plain `parse`/`stringify` functions. Those DISCARD
17
+ * every comment in the source file on round-trip (verified: `# top comment`
18
+ * + `# a server` + a trailing inline `# inline comment` all vanish after a
19
+ * `parse` → mutate → `stringify` cycle) — a straightforward
20
+ * preserve-user-content violation for anyone who annotates their own
21
+ * `~/.hermes/config.yaml`. `yaml`'s `Document`/`parseDocument`/`setIn` API
22
+ * operates on the CST and round-trips comments, anchors, and key ordering
23
+ * untouched, only rewriting the one path this module actually sets — see the
24
+ * in-container verification in the SMI-5456 code review report. One
25
+ * documented gap remains: a source file whose root is YAML-null (`~`/`null`,
26
+ * or a fully empty document) with a comment attached to that null node loses
27
+ * that specific comment when the null root is replaced with a fresh mapping
28
+ * (there is no collection node for `setIn` to attach into) — an edge case for
29
+ * a config file that carries no actual config, accepted rather than adding a
30
+ * bespoke CST-splicing path for it.
31
+ *
32
+ * @module @skillsmith/core/install/agent-config-merge.yaml
33
+ */
34
+ import { type MergeOptions, type MergeResult } from './agent-config-merge.types.js';
35
+ /**
36
+ * Merge a `skillsmith` entry into `mcp_servers:` of a YAML config file.
37
+ * Same created/updated/unchanged/conflict/error contract as
38
+ * {@link import('./agent-config-merge.json.js').mergeJsonMcpEntry}. Uses the
39
+ * `yaml` package's `Document` (CST-backed) API so every comment, anchor, and
40
+ * unrelated key in the user's file survives the merge byte-for-byte except
41
+ * for the one path this function actually sets — see module header.
42
+ */
43
+ export declare function mergeYamlMcpEntry(opts: MergeOptions & {
44
+ mcpServersKey: string;
45
+ }): MergeResult;
46
+ //# sourceMappingURL=agent-config-merge.yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-config-merge.yaml.d.ts","sourceRoot":"","sources":["../../../src/install/agent-config-merge.yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAOH,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAA;AAwBtC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAqE7F"}