@skillsmith/core 0.9.0 → 0.11.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 (404) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts +23 -0
  4. package/dist/src/analysis/tree-sitter/pythonIncremental.d.ts.map +1 -1
  5. package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js +137 -0
  6. package/dist/src/analysis/tree-sitter/pythonIncremental.hardening.test.js.map +1 -1
  7. package/dist/src/analysis/tree-sitter/pythonIncremental.js +83 -10
  8. package/dist/src/analysis/tree-sitter/pythonIncremental.js.map +1 -1
  9. package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js +6 -1
  10. package/dist/src/analysis/tree-sitter/queryExtractionMatchesOrExceedsRegex.test.js.map +1 -1
  11. package/dist/src/api/client.d.ts.map +1 -1
  12. package/dist/src/api/client.js +6 -0
  13. package/dist/src/api/client.js.map +1 -1
  14. package/dist/src/api/client.test.d.ts +9 -0
  15. package/dist/src/api/client.test.d.ts.map +1 -0
  16. package/dist/src/api/client.test.js +81 -0
  17. package/dist/src/api/client.test.js.map +1 -0
  18. package/dist/src/config/audit-notify-state.d.ts +46 -0
  19. package/dist/src/config/audit-notify-state.d.ts.map +1 -0
  20. package/dist/src/config/audit-notify-state.js +55 -0
  21. package/dist/src/config/audit-notify-state.js.map +1 -0
  22. package/dist/src/config/audit-notify-state.test.d.ts +9 -0
  23. package/dist/src/config/audit-notify-state.test.d.ts.map +1 -0
  24. package/dist/src/config/audit-notify-state.test.js +63 -0
  25. package/dist/src/config/audit-notify-state.test.js.map +1 -0
  26. package/dist/src/config/index.d.ts +10 -0
  27. package/dist/src/config/index.d.ts.map +1 -1
  28. package/dist/src/config/index.js.map +1 -1
  29. package/dist/src/exports/services.d.ts +3 -1
  30. package/dist/src/exports/services.d.ts.map +1 -1
  31. package/dist/src/exports/services.js +9 -1
  32. package/dist/src/exports/services.js.map +1 -1
  33. package/dist/src/index.d.ts +6 -3
  34. package/dist/src/index.d.ts.map +1 -1
  35. package/dist/src/index.js +11 -2
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/install/agent-config-merge.json-array.d.ts +29 -0
  38. package/dist/src/install/agent-config-merge.json-array.d.ts.map +1 -0
  39. package/dist/src/install/agent-config-merge.json-array.js +100 -0
  40. package/dist/src/install/agent-config-merge.json-array.js.map +1 -0
  41. package/dist/src/install/agent-config-merge.json.d.ts +37 -0
  42. package/dist/src/install/agent-config-merge.json.d.ts.map +1 -0
  43. package/dist/src/install/agent-config-merge.json.js +134 -0
  44. package/dist/src/install/agent-config-merge.json.js.map +1 -0
  45. package/dist/src/install/agent-config-merge.toml-block.d.ts +48 -0
  46. package/dist/src/install/agent-config-merge.toml-block.d.ts.map +1 -0
  47. package/dist/src/install/agent-config-merge.toml-block.js +107 -0
  48. package/dist/src/install/agent-config-merge.toml-block.js.map +1 -0
  49. package/dist/src/install/agent-config-merge.types.d.ts +87 -0
  50. package/dist/src/install/agent-config-merge.types.d.ts.map +1 -0
  51. package/dist/src/install/agent-config-merge.types.js +83 -0
  52. package/dist/src/install/agent-config-merge.types.js.map +1 -0
  53. package/dist/src/install/agent-config-merge.yaml.d.ts +46 -0
  54. package/dist/src/install/agent-config-merge.yaml.d.ts.map +1 -0
  55. package/dist/src/install/agent-config-merge.yaml.js +133 -0
  56. package/dist/src/install/agent-config-merge.yaml.js.map +1 -0
  57. package/dist/src/install/agent-config-merge.yaml.test.d.ts +2 -0
  58. package/dist/src/install/agent-config-merge.yaml.test.d.ts.map +1 -0
  59. package/dist/src/install/agent-config-merge.yaml.test.js +210 -0
  60. package/dist/src/install/agent-config-merge.yaml.test.js.map +1 -0
  61. package/dist/src/install/agent-harness-targets.d.ts +98 -0
  62. package/dist/src/install/agent-harness-targets.d.ts.map +1 -0
  63. package/dist/src/install/agent-harness-targets.js +154 -0
  64. package/dist/src/install/agent-harness-targets.js.map +1 -0
  65. package/dist/src/install/agent-home-relocate.d.ts +29 -0
  66. package/dist/src/install/agent-home-relocate.d.ts.map +1 -0
  67. package/dist/src/install/agent-home-relocate.js +38 -0
  68. package/dist/src/install/agent-home-relocate.js.map +1 -0
  69. package/dist/src/install/agent-manifest-path-guard.d.ts +55 -0
  70. package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -0
  71. package/dist/src/install/agent-manifest-path-guard.js +109 -0
  72. package/dist/src/install/agent-manifest-path-guard.js.map +1 -0
  73. package/dist/src/install/agent-manifest-path-guard.test.d.ts +2 -0
  74. package/dist/src/install/agent-manifest-path-guard.test.d.ts.map +1 -0
  75. package/dist/src/install/agent-manifest-path-guard.test.js +72 -0
  76. package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -0
  77. package/dist/src/install/agent-manifest.d.ts +58 -0
  78. package/dist/src/install/agent-manifest.d.ts.map +1 -0
  79. package/dist/src/install/agent-manifest.js +103 -0
  80. package/dist/src/install/agent-manifest.js.map +1 -0
  81. package/dist/src/install/agent-pack-installer.d.ts +39 -0
  82. package/dist/src/install/agent-pack-installer.d.ts.map +1 -0
  83. package/dist/src/install/agent-pack-installer.entry.d.ts +55 -0
  84. package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -0
  85. package/dist/src/install/agent-pack-installer.entry.js +90 -0
  86. package/dist/src/install/agent-pack-installer.entry.js.map +1 -0
  87. package/dist/src/install/agent-pack-installer.fs-helpers.d.ts +33 -0
  88. package/dist/src/install/agent-pack-installer.fs-helpers.d.ts.map +1 -0
  89. package/dist/src/install/agent-pack-installer.fs-helpers.js +59 -0
  90. package/dist/src/install/agent-pack-installer.fs-helpers.js.map +1 -0
  91. package/dist/src/install/agent-pack-installer.harness.d.ts +66 -0
  92. package/dist/src/install/agent-pack-installer.harness.d.ts.map +1 -0
  93. package/dist/src/install/agent-pack-installer.harness.js +310 -0
  94. package/dist/src/install/agent-pack-installer.harness.js.map +1 -0
  95. package/dist/src/install/agent-pack-installer.js +221 -0
  96. package/dist/src/install/agent-pack-installer.js.map +1 -0
  97. package/dist/src/install/agent-pack-installer.preserve.test.d.ts +11 -0
  98. package/dist/src/install/agent-pack-installer.preserve.test.d.ts.map +1 -0
  99. package/dist/src/install/agent-pack-installer.preserve.test.js +72 -0
  100. package/dist/src/install/agent-pack-installer.preserve.test.js.map +1 -0
  101. package/dist/src/install/agent-pack-installer.test.d.ts +2 -0
  102. package/dist/src/install/agent-pack-installer.test.d.ts.map +1 -0
  103. package/dist/src/install/agent-pack-installer.test.js +350 -0
  104. package/dist/src/install/agent-pack-installer.test.js.map +1 -0
  105. package/dist/src/install/agent-pack-installer.types.d.ts +51 -0
  106. package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -0
  107. package/dist/src/install/agent-pack-installer.types.js +16 -0
  108. package/dist/src/install/agent-pack-installer.types.js.map +1 -0
  109. package/dist/src/install/agent-pack-uninstaller.d.ts +43 -0
  110. package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -0
  111. package/dist/src/install/agent-pack-uninstaller.js +113 -0
  112. package/dist/src/install/agent-pack-uninstaller.js.map +1 -0
  113. package/dist/src/install/agent-pack-uninstaller.test.d.ts +2 -0
  114. package/dist/src/install/agent-pack-uninstaller.test.d.ts.map +1 -0
  115. package/dist/src/install/agent-pack-uninstaller.test.js +212 -0
  116. package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -0
  117. package/dist/src/install/index.d.ts +7 -0
  118. package/dist/src/install/index.d.ts.map +1 -1
  119. package/dist/src/install/index.js +7 -0
  120. package/dist/src/install/index.js.map +1 -1
  121. package/dist/src/install/paths.d.ts +1 -1
  122. package/dist/src/install/paths.d.ts.map +1 -1
  123. package/dist/src/install/paths.js +4 -0
  124. package/dist/src/install/paths.js.map +1 -1
  125. package/dist/src/install/paths.test.js +15 -0
  126. package/dist/src/install/paths.test.js.map +1 -1
  127. package/dist/src/journal/hash.d.ts +13 -0
  128. package/dist/src/journal/hash.d.ts.map +1 -0
  129. package/dist/src/journal/hash.js +16 -0
  130. package/dist/src/journal/hash.js.map +1 -0
  131. package/dist/src/journal/index.d.ts +15 -0
  132. package/dist/src/journal/index.d.ts.map +1 -0
  133. package/dist/src/journal/index.js +15 -0
  134. package/dist/src/journal/index.js.map +1 -0
  135. package/dist/src/journal/journal.test.d.ts +16 -0
  136. package/dist/src/journal/journal.test.d.ts.map +1 -0
  137. package/dist/src/journal/journal.test.js +171 -0
  138. package/dist/src/journal/journal.test.js.map +1 -0
  139. package/dist/src/journal/path.d.ts +44 -0
  140. package/dist/src/journal/path.d.ts.map +1 -0
  141. package/dist/src/journal/path.js +61 -0
  142. package/dist/src/journal/path.js.map +1 -0
  143. package/dist/src/journal/reader.d.ts +38 -0
  144. package/dist/src/journal/reader.d.ts.map +1 -0
  145. package/dist/src/journal/reader.js +93 -0
  146. package/dist/src/journal/reader.js.map +1 -0
  147. package/dist/src/journal/types.d.ts +87 -0
  148. package/dist/src/journal/types.d.ts.map +1 -0
  149. package/dist/src/journal/types.js +21 -0
  150. package/dist/src/journal/types.js.map +1 -0
  151. package/dist/src/journal/writer.d.ts +52 -0
  152. package/dist/src/journal/writer.d.ts.map +1 -0
  153. package/dist/src/journal/writer.js +125 -0
  154. package/dist/src/journal/writer.js.map +1 -0
  155. package/dist/src/logging/context.d.ts +58 -0
  156. package/dist/src/logging/context.d.ts.map +1 -0
  157. package/dist/src/logging/context.js +62 -0
  158. package/dist/src/logging/context.js.map +1 -0
  159. package/dist/src/logging/context.test.d.ts +14 -0
  160. package/dist/src/logging/context.test.d.ts.map +1 -0
  161. package/dist/src/logging/context.test.js +88 -0
  162. package/dist/src/logging/context.test.js.map +1 -0
  163. package/dist/src/logging/index.d.ts +13 -0
  164. package/dist/src/logging/index.d.ts.map +1 -0
  165. package/dist/src/logging/index.js +12 -0
  166. package/dist/src/logging/index.js.map +1 -0
  167. package/dist/src/logging/logger.d.ts +71 -0
  168. package/dist/src/logging/logger.d.ts.map +1 -0
  169. package/dist/src/logging/logger.js +264 -0
  170. package/dist/src/logging/logger.js.map +1 -0
  171. package/dist/src/logging/logger.test.d.ts +9 -0
  172. package/dist/src/logging/logger.test.d.ts.map +1 -0
  173. package/dist/src/logging/logger.test.js +320 -0
  174. package/dist/src/logging/logger.test.js.map +1 -0
  175. package/dist/src/logging/redact.d.ts +35 -0
  176. package/dist/src/logging/redact.d.ts.map +1 -0
  177. package/dist/src/logging/redact.js +152 -0
  178. package/dist/src/logging/redact.js.map +1 -0
  179. package/dist/src/logging/redact.test.d.ts +8 -0
  180. package/dist/src/logging/redact.test.d.ts.map +1 -0
  181. package/dist/src/logging/redact.test.js +330 -0
  182. package/dist/src/logging/redact.test.js.map +1 -0
  183. package/dist/src/logging/rotation.d.ts +75 -0
  184. package/dist/src/logging/rotation.d.ts.map +1 -0
  185. package/dist/src/logging/rotation.js +284 -0
  186. package/dist/src/logging/rotation.js.map +1 -0
  187. package/dist/src/logging/rotation.test.d.ts +11 -0
  188. package/dist/src/logging/rotation.test.d.ts.map +1 -0
  189. package/dist/src/logging/rotation.test.js +132 -0
  190. package/dist/src/logging/rotation.test.js.map +1 -0
  191. package/dist/src/logging/types.d.ts +69 -0
  192. package/dist/src/logging/types.d.ts.map +1 -0
  193. package/dist/src/logging/types.js +9 -0
  194. package/dist/src/logging/types.js.map +1 -0
  195. package/dist/src/paywall-triggers/index.d.ts +13 -0
  196. package/dist/src/paywall-triggers/index.d.ts.map +1 -0
  197. package/dist/src/paywall-triggers/index.js +13 -0
  198. package/dist/src/paywall-triggers/index.js.map +1 -0
  199. package/dist/src/paywall-triggers/path.d.ts +47 -0
  200. package/dist/src/paywall-triggers/path.d.ts.map +1 -0
  201. package/dist/src/paywall-triggers/path.js +73 -0
  202. package/dist/src/paywall-triggers/path.js.map +1 -0
  203. package/dist/src/paywall-triggers/store.d.ts +75 -0
  204. package/dist/src/paywall-triggers/store.d.ts.map +1 -0
  205. package/dist/src/paywall-triggers/store.js +122 -0
  206. package/dist/src/paywall-triggers/store.js.map +1 -0
  207. package/dist/src/paywall-triggers/store.test.d.ts +2 -0
  208. package/dist/src/paywall-triggers/store.test.d.ts.map +1 -0
  209. package/dist/src/paywall-triggers/store.test.js +121 -0
  210. package/dist/src/paywall-triggers/store.test.js.map +1 -0
  211. package/dist/src/paywall-triggers/types.d.ts +24 -0
  212. package/dist/src/paywall-triggers/types.d.ts.map +1 -0
  213. package/dist/src/paywall-triggers/types.js +13 -0
  214. package/dist/src/paywall-triggers/types.js.map +1 -0
  215. package/dist/src/security/index.d.ts +2 -0
  216. package/dist/src/security/index.d.ts.map +1 -1
  217. package/dist/src/security/index.js +4 -0
  218. package/dist/src/security/index.js.map +1 -1
  219. package/dist/src/security/scanner/SecurityScanner.compound.d.ts +13 -0
  220. package/dist/src/security/scanner/SecurityScanner.compound.d.ts.map +1 -0
  221. package/dist/src/security/scanner/SecurityScanner.compound.js +127 -0
  222. package/dist/src/security/scanner/SecurityScanner.compound.js.map +1 -0
  223. package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
  224. package/dist/src/security/scanner/SecurityScanner.hostile-update.d.ts +46 -0
  225. package/dist/src/security/scanner/SecurityScanner.hostile-update.d.ts.map +1 -0
  226. package/dist/src/security/scanner/SecurityScanner.hostile-update.js +209 -0
  227. package/dist/src/security/scanner/SecurityScanner.hostile-update.js.map +1 -0
  228. package/dist/src/security/scanner/SecurityScanner.js +10 -1
  229. package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
  230. package/dist/src/security/scanner/SecurityScanner.pii.d.ts +23 -0
  231. package/dist/src/security/scanner/SecurityScanner.pii.d.ts.map +1 -0
  232. package/dist/src/security/scanner/SecurityScanner.pii.js +152 -0
  233. package/dist/src/security/scanner/SecurityScanner.pii.js.map +1 -0
  234. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts +5 -12
  235. package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
  236. package/dist/src/security/scanner/SecurityScanner.scanners.js +63 -137
  237. package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
  238. package/dist/src/security/scanner/index.d.ts +2 -1
  239. package/dist/src/security/scanner/index.d.ts.map +1 -1
  240. package/dist/src/security/scanner/index.js +2 -0
  241. package/dist/src/security/scanner/index.js.map +1 -1
  242. package/dist/src/security/scanner/patterns.d.ts +2 -0
  243. package/dist/src/security/scanner/patterns.d.ts.map +1 -1
  244. package/dist/src/security/scanner/patterns.js +79 -11
  245. package/dist/src/security/scanner/patterns.js.map +1 -1
  246. package/dist/src/security/scanner/types.d.ts +23 -0
  247. package/dist/src/security/scanner/types.d.ts.map +1 -1
  248. package/dist/src/services/agent-pack/agent-pack.test.d.ts +18 -0
  249. package/dist/src/services/agent-pack/agent-pack.test.d.ts.map +1 -0
  250. package/dist/src/services/agent-pack/agent-pack.test.js +344 -0
  251. package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -0
  252. package/dist/src/services/agent-pack/hooks.d.ts +29 -0
  253. package/dist/src/services/agent-pack/hooks.d.ts.map +1 -0
  254. package/dist/src/services/agent-pack/hooks.js +139 -0
  255. package/dist/src/services/agent-pack/hooks.js.map +1 -0
  256. package/dist/src/services/agent-pack/index.d.ts +26 -0
  257. package/dist/src/services/agent-pack/index.d.ts.map +1 -0
  258. package/dist/src/services/agent-pack/index.js +109 -0
  259. package/dist/src/services/agent-pack/index.js.map +1 -0
  260. package/dist/src/services/agent-pack/prompt-source.d.ts +47 -0
  261. package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -0
  262. package/dist/src/services/agent-pack/prompt-source.js +182 -0
  263. package/dist/src/services/agent-pack/prompt-source.js.map +1 -0
  264. package/dist/src/services/agent-pack/shims.d.ts +40 -0
  265. package/dist/src/services/agent-pack/shims.d.ts.map +1 -0
  266. package/dist/src/services/agent-pack/shims.js +96 -0
  267. package/dist/src/services/agent-pack/shims.js.map +1 -0
  268. package/dist/src/services/agent-pack/skill-md.d.ts +35 -0
  269. package/dist/src/services/agent-pack/skill-md.d.ts.map +1 -0
  270. package/dist/src/services/agent-pack/skill-md.js +89 -0
  271. package/dist/src/services/agent-pack/skill-md.js.map +1 -0
  272. package/dist/src/services/agent-pack/types.d.ts +118 -0
  273. package/dist/src/services/agent-pack/types.d.ts.map +1 -0
  274. package/dist/src/services/agent-pack/types.js +61 -0
  275. package/dist/src/services/agent-pack/types.js.map +1 -0
  276. package/dist/src/services/agent-tool-profile.d.ts +59 -0
  277. package/dist/src/services/agent-tool-profile.d.ts.map +1 -0
  278. package/dist/src/services/agent-tool-profile.js +76 -0
  279. package/dist/src/services/agent-tool-profile.js.map +1 -0
  280. package/dist/src/services/agent-tool-profile.test.d.ts +2 -0
  281. package/dist/src/services/agent-tool-profile.test.d.ts.map +1 -0
  282. package/dist/src/services/agent-tool-profile.test.js +28 -0
  283. package/dist/src/services/agent-tool-profile.test.js.map +1 -0
  284. package/dist/src/services/bundled-sibling-scan.d.ts +111 -0
  285. package/dist/src/services/bundled-sibling-scan.d.ts.map +1 -0
  286. package/dist/src/services/bundled-sibling-scan.js +170 -0
  287. package/dist/src/services/bundled-sibling-scan.js.map +1 -0
  288. package/dist/src/services/skill-installation.io.d.ts +16 -5
  289. package/dist/src/services/skill-installation.io.d.ts.map +1 -1
  290. package/dist/src/services/skill-installation.io.js +63 -22
  291. package/dist/src/services/skill-installation.io.js.map +1 -1
  292. package/dist/src/services/skill-installation.policy.d.ts +96 -0
  293. package/dist/src/services/skill-installation.policy.d.ts.map +1 -0
  294. package/dist/src/services/skill-installation.policy.js +144 -0
  295. package/dist/src/services/skill-installation.policy.js.map +1 -0
  296. package/dist/src/services/skill-installation.service.d.ts.map +1 -1
  297. package/dist/src/services/skill-installation.service.js +9 -3
  298. package/dist/src/services/skill-installation.service.js.map +1 -1
  299. package/dist/src/sources/index.d.ts +1 -0
  300. package/dist/src/sources/index.d.ts.map +1 -1
  301. package/dist/src/sources/index.js +4 -0
  302. package/dist/src/sources/index.js.map +1 -1
  303. package/dist/src/sync/access-token.d.ts +27 -0
  304. package/dist/src/sync/access-token.d.ts.map +1 -0
  305. package/dist/src/sync/access-token.js +40 -0
  306. package/dist/src/sync/access-token.js.map +1 -0
  307. package/dist/src/sync/audit-notify-client.d.ts +83 -0
  308. package/dist/src/sync/audit-notify-client.d.ts.map +1 -0
  309. package/dist/src/sync/audit-notify-client.js +126 -0
  310. package/dist/src/sync/audit-notify-client.js.map +1 -0
  311. package/dist/src/sync/audit-notify-client.test.d.ts +14 -0
  312. package/dist/src/sync/audit-notify-client.test.d.ts.map +1 -0
  313. package/dist/src/sync/audit-notify-client.test.js +133 -0
  314. package/dist/src/sync/audit-notify-client.test.js.map +1 -0
  315. package/dist/src/sync/index.d.ts +2 -1
  316. package/dist/src/sync/index.d.ts.map +1 -1
  317. package/dist/src/sync/index.js +3 -1
  318. package/dist/src/sync/index.js.map +1 -1
  319. package/dist/src/sync/inventory-client.d.ts +16 -0
  320. package/dist/src/sync/inventory-client.d.ts.map +1 -1
  321. package/dist/src/sync/inventory-client.js +59 -16
  322. package/dist/src/sync/inventory-client.js.map +1 -1
  323. package/dist/src/sync/inventory-client.test.js +67 -1
  324. package/dist/src/sync/inventory-client.test.js.map +1 -1
  325. package/dist/src/sync/inventory-collector.d.ts.map +1 -1
  326. package/dist/src/sync/inventory-collector.js +32 -5
  327. package/dist/src/sync/inventory-collector.js.map +1 -1
  328. package/dist/src/sync/inventory-collector.test.js +50 -1
  329. package/dist/src/sync/inventory-collector.test.js.map +1 -1
  330. package/dist/src/sync/inventory-types.d.ts +9 -0
  331. package/dist/src/sync/inventory-types.d.ts.map +1 -1
  332. package/dist/src/sync/inventory-types.js +3 -0
  333. package/dist/src/sync/inventory-types.js.map +1 -1
  334. package/dist/src/telemetry/agent-marker.d.ts +137 -0
  335. package/dist/src/telemetry/agent-marker.d.ts.map +1 -0
  336. package/dist/src/telemetry/agent-marker.js +242 -0
  337. package/dist/src/telemetry/agent-marker.js.map +1 -0
  338. package/dist/src/telemetry/agent-marker.test.d.ts +13 -0
  339. package/dist/src/telemetry/agent-marker.test.d.ts.map +1 -0
  340. package/dist/src/telemetry/agent-marker.test.js +202 -0
  341. package/dist/src/telemetry/agent-marker.test.js.map +1 -0
  342. package/dist/src/telemetry/index.d.ts +2 -1
  343. package/dist/src/telemetry/index.d.ts.map +1 -1
  344. package/dist/src/telemetry/index.js +6 -1
  345. package/dist/src/telemetry/index.js.map +1 -1
  346. package/dist/src/telemetry/posthog.d.ts +25 -0
  347. package/dist/src/telemetry/posthog.d.ts.map +1 -1
  348. package/dist/src/telemetry/posthog.js +10 -1
  349. package/dist/src/telemetry/posthog.js.map +1 -1
  350. package/dist/src/telemetry/wrap.bench.js +5 -0
  351. package/dist/src/telemetry/wrap.bench.js.map +1 -1
  352. package/dist/src/telemetry/wrap.correlation.test.d.ts +20 -0
  353. package/dist/src/telemetry/wrap.correlation.test.d.ts.map +1 -0
  354. package/dist/src/telemetry/wrap.correlation.test.js +174 -0
  355. package/dist/src/telemetry/wrap.correlation.test.js.map +1 -0
  356. package/dist/src/telemetry/wrap.d.ts +28 -7
  357. package/dist/src/telemetry/wrap.d.ts.map +1 -1
  358. package/dist/src/telemetry/wrap.gate.test.d.ts +22 -0
  359. package/dist/src/telemetry/wrap.gate.test.d.ts.map +1 -0
  360. package/dist/src/telemetry/wrap.gate.test.js +202 -0
  361. package/dist/src/telemetry/wrap.gate.test.js.map +1 -0
  362. package/dist/src/telemetry/wrap.js +196 -52
  363. package/dist/src/telemetry/wrap.js.map +1 -1
  364. package/dist/src/telemetry/wrap.marker.test.d.ts +16 -0
  365. package/dist/src/telemetry/wrap.marker.test.d.ts.map +1 -0
  366. package/dist/src/telemetry/wrap.marker.test.js +190 -0
  367. package/dist/src/telemetry/wrap.marker.test.js.map +1 -0
  368. package/dist/src/telemetry/wrap.test.js +14 -0
  369. package/dist/src/telemetry/wrap.test.js.map +1 -1
  370. package/dist/src/types.d.ts +6 -0
  371. package/dist/src/types.d.ts.map +1 -1
  372. package/dist/tests/SecurityScanner.exec.test.js +60 -0
  373. package/dist/tests/SecurityScanner.exec.test.js.map +1 -1
  374. package/dist/tests/security/ContinuousSecurity.test.js +10 -4
  375. package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
  376. package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts +2 -0
  377. package/dist/tests/security/SecurityScanner.chmod-evasion.test.d.ts.map +1 -0
  378. package/dist/tests/security/SecurityScanner.chmod-evasion.test.js +126 -0
  379. package/dist/tests/security/SecurityScanner.chmod-evasion.test.js.map +1 -0
  380. package/dist/tests/security/chmod-compound.test.d.ts +2 -0
  381. package/dist/tests/security/chmod-compound.test.d.ts.map +1 -0
  382. package/dist/tests/security/chmod-compound.test.js +188 -0
  383. package/dist/tests/security/chmod-compound.test.js.map +1 -0
  384. package/dist/tests/security/pii-detection.test.js +24 -0
  385. package/dist/tests/security/pii-detection.test.js.map +1 -1
  386. package/dist/tests/security/scanner-regression-guard.test.d.ts +23 -7
  387. package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -1
  388. package/dist/tests/security/scanner-regression-guard.test.js +206 -12
  389. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
  390. package/dist/tests/security/sensitive-path-fp.test.d.ts +2 -0
  391. package/dist/tests/security/sensitive-path-fp.test.d.ts.map +1 -0
  392. package/dist/tests/security/sensitive-path-fp.test.js +142 -0
  393. package/dist/tests/security/sensitive-path-fp.test.js.map +1 -0
  394. package/dist/tests/services/bundled-sibling-scan.test.d.ts +2 -0
  395. package/dist/tests/services/bundled-sibling-scan.test.d.ts.map +1 -0
  396. package/dist/tests/services/bundled-sibling-scan.test.js +139 -0
  397. package/dist/tests/services/bundled-sibling-scan.test.js.map +1 -0
  398. package/dist/tests/unit/services/skill-installation.io.test.js +166 -0
  399. package/dist/tests/unit/services/skill-installation.io.test.js.map +1 -1
  400. package/dist/tests/unit/services/skill-installation.policy.test.d.ts +8 -0
  401. package/dist/tests/unit/services/skill-installation.policy.test.d.ts.map +1 -0
  402. package/dist/tests/unit/services/skill-installation.policy.test.js +151 -0
  403. package/dist/tests/unit/services/skill-installation.policy.test.js.map +1 -0
  404. package/package.json +28 -3
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-pack-installer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-pack-installer.test.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,350 @@
1
+ /**
2
+ * @fileoverview Tests for `installAgentPack` (SMI-5456 Wave 1 Step 5).
3
+ * @module @skillsmith/core/install/agent-pack-installer.test
4
+ *
5
+ * Covers the P-5 "Harness MCP config files" + "Dual-path pack copies"
6
+ * invariants named in
7
+ * docs/internal/implementation/smi-5456-skillsmith-agent-wave1.md:
8
+ * - install to a temp HOME: dual-path byte-identical
9
+ * - shims only for detected harnesses
10
+ * - hooks +x (incl. Codex SessionStart TOML wiring, Step-6 corrected)
11
+ * - MCP config JSON/YAML/TOML merge results correct
12
+ * - double-install idempotency (no duplicate backups/manifest entries)
13
+ * - preserve-existing (non-interactive refusal path)
14
+ * The uninstall exact-reversal + manifest-path-guard suites live in
15
+ * `agent-pack-uninstaller.test.ts` (split at the 500-line gate).
16
+ */
17
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from 'node:fs';
18
+ import { tmpdir } from 'node:os';
19
+ import { join } from 'node:path';
20
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
21
+ import { installAgentPack } from './agent-pack-installer.js';
22
+ import { AGENT_INSTALL_DIR_ENV_VAR, getAgentInstallBackupsDir, getAgentManifestPath, } from './agent-manifest.js';
23
+ import { CLIENT_NATIVE_PATHS } from './paths.js';
24
+ import { relocateUnderHome } from './agent-home-relocate.js';
25
+ let homeDir;
26
+ let manifestDir;
27
+ let prevInstallDirEnv;
28
+ function skillPath(client) {
29
+ return join(relocateUnderHome(CLIENT_NATIVE_PATHS[client], homeDir), 'skillsmith-agent', 'SKILL.md');
30
+ }
31
+ beforeEach(() => {
32
+ homeDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-home-'));
33
+ manifestDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-manifest-'));
34
+ prevInstallDirEnv = process.env[AGENT_INSTALL_DIR_ENV_VAR];
35
+ process.env[AGENT_INSTALL_DIR_ENV_VAR] = manifestDir;
36
+ });
37
+ afterEach(() => {
38
+ rmSync(homeDir, { recursive: true, force: true });
39
+ rmSync(manifestDir, { recursive: true, force: true });
40
+ if (prevInstallDirEnv !== undefined)
41
+ process.env[AGENT_INSTALL_DIR_ENV_VAR] = prevInstallDirEnv;
42
+ else
43
+ delete process.env[AGENT_INSTALL_DIR_ENV_VAR];
44
+ });
45
+ describe('installAgentPack — dual-path + shim + hook + MCP', () => {
46
+ it('writes byte-identical SKILL.md to both claude-code and agents skill paths', () => {
47
+ installAgentPack({ homeDir });
48
+ const claudePath = skillPath('claude-code');
49
+ const agentsPath = skillPath('agents');
50
+ expect(existsSync(claudePath)).toBe(true);
51
+ expect(existsSync(agentsPath)).toBe(true);
52
+ expect(readFileSync(claudePath, 'utf-8')).toBe(readFileSync(agentsPath, 'utf-8'));
53
+ });
54
+ it('writes the claude-code shim unconditionally; copilot/opencode shims only when detected', () => {
55
+ const result = installAgentPack({ homeDir });
56
+ const claudeShim = join(homeDir, '.claude', 'agents', 'skillsmith-agent.md');
57
+ const copilotShim = join(homeDir, '.copilot', 'agents', 'skillsmith-agent.agent.md');
58
+ expect(existsSync(claudeShim)).toBe(true);
59
+ expect(existsSync(copilotShim)).toBe(false);
60
+ const claudeReport = result.harnessReports.find((r) => r.harness === 'claude-code');
61
+ const copilotReport = result.harnessReports.find((r) => r.harness === 'copilot');
62
+ expect(claudeReport?.shimWritten).toBe(true);
63
+ expect(copilotReport?.detected).toBe(false);
64
+ expect(copilotReport?.shimWritten).toBe(false);
65
+ });
66
+ it('detects copilot and writes its shim + skill pack when ~/.copilot/skills is present', () => {
67
+ mkdirSync(join(homeDir, '.copilot', 'skills'), { recursive: true });
68
+ const result = installAgentPack({ homeDir });
69
+ const copilotShim = join(homeDir, '.copilot', 'agents', 'skillsmith-agent.agent.md');
70
+ expect(existsSync(copilotShim)).toBe(true);
71
+ const copilotReport = result.harnessReports.find((r) => r.harness === 'copilot');
72
+ expect(copilotReport?.detected).toBe(true);
73
+ expect(copilotReport?.shimWritten).toBe(true);
74
+ });
75
+ it('installs claude-code + cursor hook scripts with the executable bit set', () => {
76
+ mkdirSync(join(homeDir, '.cursor', 'skills'), { recursive: true });
77
+ installAgentPack({ homeDir });
78
+ for (const dir of ['.claude', '.cursor']) {
79
+ const startPath = join(homeDir, dir, 'hooks', 'session-start.sh');
80
+ const endPath = join(homeDir, dir, 'hooks', 'session-end.sh');
81
+ expect(existsSync(startPath)).toBe(true);
82
+ expect((statSync(startPath).mode & 0o111) !== 0).toBe(true);
83
+ expect((statSync(endPath).mode & 0o111) !== 0).toBe(true);
84
+ }
85
+ });
86
+ it('does not install cursor hooks when cursor is not detected', () => {
87
+ installAgentPack({ homeDir });
88
+ expect(existsSync(join(homeDir, '.cursor', 'hooks', 'session-start.sh'))).toBe(false);
89
+ });
90
+ it('merges the skillsmith MCP entry into claude-code settings.json with SKILLSMITH_TOOL_PROFILE=agent', () => {
91
+ const result = installAgentPack({ homeDir });
92
+ const settingsPath = join(homeDir, '.claude', 'settings.json');
93
+ const doc = JSON.parse(readFileSync(settingsPath, 'utf-8'));
94
+ expect(doc.mcpServers.skillsmith.env.SKILLSMITH_TOOL_PROFILE).toBe('agent');
95
+ const report = result.harnessReports.find((r) => r.harness === 'claude-code');
96
+ expect(report?.mcpConfig?.status).toBe('created');
97
+ });
98
+ it('merges the codex MCP + agents entries as marker-delimited TOML blocks when codex is detected', () => {
99
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
100
+ const result = installAgentPack({ homeDir });
101
+ const configPath = join(homeDir, '.codex', 'config.toml');
102
+ const content = readFileSync(configPath, 'utf-8');
103
+ expect(content).toContain('# >>> skillsmith:mcp_servers.skillsmith >>>');
104
+ expect(content).toContain('# >>> skillsmith:agents.skillsmith-agent >>>');
105
+ const report = result.harnessReports.find((r) => r.harness === 'codex');
106
+ expect(report?.detected).toBe(true);
107
+ expect(report?.shimWritten).toBe(true);
108
+ expect(report?.mcpConfig?.status).toBe('created');
109
+ });
110
+ // Step-6 correction (2026-07-01): Codex hook wiring is now implemented —
111
+ // the inline `[[hooks.SessionStart]]` array-of-tables shape was verified
112
+ // against developers.openai.com/codex/hooks.
113
+ it('wires the codex SessionStart hook as a marker-delimited [[hooks.SessionStart]] TOML block', () => {
114
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
115
+ const result = installAgentPack({ homeDir });
116
+ const configPath = join(homeDir, '.codex', 'config.toml');
117
+ const content = readFileSync(configPath, 'utf-8');
118
+ const startScript = join(homeDir, '.codex', 'hooks', 'session-start.sh');
119
+ expect(content).toContain('# >>> skillsmith:hooks.SessionStart >>>');
120
+ expect(content).toContain('[[hooks.SessionStart]]');
121
+ expect(content).toContain('[[hooks.SessionStart.hooks]]');
122
+ expect(content).toContain('type = "command"');
123
+ expect(content).toContain(JSON.stringify(startScript));
124
+ const report = result.harnessReports.find((r) => r.harness === 'codex');
125
+ expect(report?.hooksInstalled).toBe(true);
126
+ expect(report?.hookConfig.some((w) => w.status === 'created')).toBe(true);
127
+ });
128
+ it('does NOT wire any codex SessionEnd/Stop cleanup (no SessionEnd event; Stop is per-turn)', () => {
129
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
130
+ const result = installAgentPack({ homeDir });
131
+ const configPath = join(homeDir, '.codex', 'config.toml');
132
+ const content = readFileSync(configPath, 'utf-8');
133
+ expect(content).not.toContain('SessionEnd');
134
+ expect(content).not.toContain('hooks.Stop');
135
+ expect(content).not.toContain('session-end.sh');
136
+ // session-end.sh is still INSTALLED (inert, manifest-tracked) so the
137
+ // script tree stays uniform across hook-capable harnesses.
138
+ const endScript = join(homeDir, '.codex', 'hooks', 'session-end.sh');
139
+ expect(existsSync(endScript)).toBe(true);
140
+ expect((statSync(endScript).mode & 0o111) !== 0).toBe(true);
141
+ const report = result.harnessReports.find((r) => r.harness === 'codex');
142
+ expect(report?.notes.some((n) => n.includes('no SessionEnd event'))).toBe(true);
143
+ });
144
+ it('refuses codex hook wiring (conflict) when the user defined [hooks.SessionStart] as a plain table', () => {
145
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
146
+ const configPath = join(homeDir, '.codex', 'config.toml');
147
+ // Single-bracket TABLE — appending our [[...]] array entry would make
148
+ // the file invalid TOML, so this must be a non-destructive refusal.
149
+ const preExisting = '[hooks.SessionStart]\nsomething = "user-defined"\n';
150
+ writeFileSync(configPath, preExisting);
151
+ const result = installAgentPack({ homeDir });
152
+ const content = readFileSync(configPath, 'utf-8');
153
+ expect(content).toContain('something = "user-defined"');
154
+ expect(content).not.toContain('# >>> skillsmith:hooks.SessionStart >>>');
155
+ const report = result.harnessReports.find((r) => r.harness === 'codex');
156
+ expect(report?.hookConfig.some((w) => w.status === 'conflict')).toBe(true);
157
+ expect(report?.notes.some((n) => n.includes('plain TOML table'))).toBe(true);
158
+ });
159
+ // Governance follow-up (2026-07-01): `mergeTomlBlock` ignores `force` for a
160
+ // bare foreign table header (see `void force` in
161
+ // `agent-config-merge.toml-block.ts`) — must hold with force: true too.
162
+ it('refuses codex hook wiring (conflict) even with force: true, since appending would be invalid TOML', () => {
163
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
164
+ const configPath = join(homeDir, '.codex', 'config.toml');
165
+ const preExisting = '[hooks.SessionStart]\nsomething = "user-defined"\n';
166
+ writeFileSync(configPath, preExisting);
167
+ const result = installAgentPack({ homeDir, force: true });
168
+ const content = readFileSync(configPath, 'utf-8');
169
+ // Unrelated blocks (agents shim, mcp_servers) still merge under
170
+ // force: true — only the hooks.SessionStart table conflict is refused.
171
+ expect(content).toContain('something = "user-defined"');
172
+ expect(content).not.toContain('# >>> skillsmith:hooks.SessionStart >>>');
173
+ const report = result.harnessReports.find((r) => r.harness === 'codex');
174
+ expect(report?.hookConfig.some((w) => w.status === 'conflict')).toBe(true);
175
+ expect(report?.notes.some((n) => n.includes('plain TOML table'))).toBe(true);
176
+ });
177
+ it("appends alongside a user's own [[hooks.SessionStart]] array entry (valid TOML coexistence)", () => {
178
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
179
+ const configPath = join(homeDir, '.codex', 'config.toml');
180
+ const userHook = [
181
+ '[[hooks.SessionStart]]',
182
+ '',
183
+ '[[hooks.SessionStart.hooks]]',
184
+ 'type = "command"',
185
+ 'command = "/usr/local/bin/my-own-hook.sh"',
186
+ '',
187
+ ].join('\n');
188
+ writeFileSync(configPath, userHook);
189
+ installAgentPack({ homeDir });
190
+ const content = readFileSync(configPath, 'utf-8');
191
+ // Both hooks present: the user's untouched, ours marker-delimited.
192
+ expect(content).toContain('/usr/local/bin/my-own-hook.sh');
193
+ expect(content).toContain('# >>> skillsmith:hooks.SessionStart >>>');
194
+ expect(content.split('[[hooks.SessionStart]]').length - 1).toBe(2);
195
+ });
196
+ // Step-6 corrections (2026-07-01): opencode agent dir is `agents/`
197
+ // (plural, opencode.ai/docs/agents/) and its MCP entry uses OpenCode's own
198
+ // schema (type local|remote, command ARRAY, `environment` not `env`).
199
+ it('writes the opencode shim to agents/ (plural) and an OpenCode-schema MCP entry when detected', () => {
200
+ mkdirSync(join(homeDir, '.config', 'opencode', 'skills'), { recursive: true });
201
+ const result = installAgentPack({ homeDir });
202
+ const shimPath = join(homeDir, '.config', 'opencode', 'agents', 'skillsmith-agent.md');
203
+ expect(existsSync(shimPath)).toBe(true);
204
+ expect(existsSync(join(homeDir, '.config', 'opencode', 'agent', 'skillsmith-agent.md'))).toBe(false);
205
+ const configPath = join(homeDir, '.config', 'opencode', 'opencode.json');
206
+ const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
207
+ expect(doc.mcp.skillsmith.type).toBe('local');
208
+ expect(Array.isArray(doc.mcp.skillsmith.command)).toBe(true);
209
+ expect(doc.mcp.skillsmith.command).toContain('@skillsmith/mcp-server');
210
+ expect(doc.mcp.skillsmith.environment.SKILLSMITH_TOOL_PROFILE).toBe('agent');
211
+ expect(doc.mcp.skillsmith.env).toBeUndefined();
212
+ expect(doc.mcp.skillsmith.args).toBeUndefined();
213
+ const report = result.harnessReports.find((r) => r.harness === 'opencode');
214
+ expect(report?.detected).toBe(true);
215
+ expect(report?.shimWritten).toBe(true);
216
+ expect(report?.mcpConfig?.status).toBe('created');
217
+ });
218
+ it('recognizes a prior-install OpenCode-schema entry as OURS and updates it without --force', () => {
219
+ mkdirSync(join(homeDir, '.config', 'opencode', 'skills'), { recursive: true });
220
+ const configPath = join(homeDir, '.config', 'opencode', 'opencode.json');
221
+ // Simulates an entry a PREVIOUS sklx version wrote: same OpenCode schema,
222
+ // same package, but stale field content. Without the command-array /
223
+ // `environment` checks in looksLikeOurMcpEntry, this would be
224
+ // misclassified as foreign and refuse to update.
225
+ writeFileSync(configPath, JSON.stringify({
226
+ mcp: {
227
+ skillsmith: {
228
+ type: 'local',
229
+ command: ['npx', '-y', '@skillsmith/mcp-server@0.0.1'],
230
+ environment: { SKILLSMITH_TOOL_PROFILE: 'agent', STALE_VAR: 'x' },
231
+ },
232
+ },
233
+ }, null, 2));
234
+ const result = installAgentPack({ homeDir });
235
+ const report = result.harnessReports.find((r) => r.harness === 'opencode');
236
+ expect(report?.mcpConfig?.status).toBe('updated');
237
+ const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
238
+ expect(doc.mcp.skillsmith.command).toContain('@skillsmith/mcp-server');
239
+ expect(doc.mcp.skillsmith.environment.STALE_VAR).toBeUndefined();
240
+ });
241
+ it('writes the copilot MCP entry to mcp-config.json (Step-6 corrected filename)', () => {
242
+ mkdirSync(join(homeDir, '.copilot', 'skills'), { recursive: true });
243
+ const result = installAgentPack({ homeDir });
244
+ const configPath = join(homeDir, '.copilot', 'mcp-config.json');
245
+ expect(existsSync(configPath)).toBe(true);
246
+ expect(existsSync(join(homeDir, '.copilot', 'mcp.json'))).toBe(false);
247
+ const doc = JSON.parse(readFileSync(configPath, 'utf-8'));
248
+ expect(doc.mcpServers.skillsmith.env.SKILLSMITH_TOOL_PROFILE).toBe('agent');
249
+ const report = result.harnessReports.find((r) => r.harness === 'copilot');
250
+ expect(report?.mcpConfig?.status).toBe('created');
251
+ });
252
+ // Governance follow-up (2026-07-01): hermes is the ONLY detected harness
253
+ // whose MCP config is YAML (`agent-config-merge.yaml.ts`) — before this
254
+ // test, nothing in the installer suite ever created `~/.hermes`, so the
255
+ // YAML merge path had zero coverage end-to-end through `installAgentPack`.
256
+ it('merges the skillsmith MCP entry into hermes config.yaml (YAML format) when hermes is detected', () => {
257
+ mkdirSync(join(homeDir, '.hermes', 'skills'), { recursive: true });
258
+ const result = installAgentPack({ homeDir });
259
+ const configPath = join(homeDir, '.hermes', 'config.yaml');
260
+ const content = readFileSync(configPath, 'utf-8');
261
+ expect(content).toContain('mcp_servers:');
262
+ expect(content).toContain('skillsmith:');
263
+ expect(content).toContain('SKILLSMITH_TOOL_PROFILE');
264
+ const report = result.harnessReports.find((r) => r.harness === 'hermes');
265
+ expect(report?.detected).toBe(true);
266
+ expect(report?.skillPackWritten).toBe(true);
267
+ expect(report?.mcpConfig?.status).toBe('created');
268
+ });
269
+ it('hermes YAML merge preserves pre-existing comments and unrelated keys', () => {
270
+ mkdirSync(join(homeDir, '.hermes', 'skills'), { recursive: true });
271
+ const configPath = join(homeDir, '.hermes', 'config.yaml');
272
+ writeFileSync(configPath, ['# my hermes config', 'some_setting: true # inline note', ''].join('\n'));
273
+ installAgentPack({ homeDir });
274
+ const content = readFileSync(configPath, 'utf-8');
275
+ expect(content).toContain('# my hermes config');
276
+ expect(content).toContain('some_setting: true');
277
+ expect(content).toContain('# inline note');
278
+ expect(content).toContain('mcp_servers:');
279
+ });
280
+ });
281
+ describe('installAgentPack — double-install idempotency', () => {
282
+ it('produces identical manifest entry count and zero additional backups on a second install', () => {
283
+ mkdirSync(join(homeDir, '.cursor', 'skills'), { recursive: true });
284
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
285
+ installAgentPack({ homeDir });
286
+ const manifestAfterFirst = JSON.parse(readFileSync(getAgentManifestPath(), 'utf-8'));
287
+ const backupsDir = getAgentInstallBackupsDir();
288
+ const backupCountAfterFirst = existsSync(backupsDir) ? readdirSync(backupsDir).length : 0;
289
+ installAgentPack({ homeDir });
290
+ const manifestAfterSecond = JSON.parse(readFileSync(getAgentManifestPath(), 'utf-8'));
291
+ const backupCountAfterSecond = existsSync(backupsDir) ? readdirSync(backupsDir).length : 0;
292
+ expect(manifestAfterSecond.entries.length).toBe(manifestAfterFirst.entries.length);
293
+ expect(backupCountAfterSecond).toBe(backupCountAfterFirst);
294
+ });
295
+ // Governance regression test (2026-07-01): the marker-delimited Codex TOML
296
+ // block must be updated in place on re-install, never appended as a SECOND
297
+ // block — a naive "no match found → append" fallback would duplicate the
298
+ // `[mcp_servers.skillsmith]` / `[agents.skillsmith-agent]` tables on every
299
+ // subsequent install.
300
+ it('does not duplicate the codex TOML marker blocks on a second install', () => {
301
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
302
+ installAgentPack({ homeDir });
303
+ installAgentPack({ homeDir });
304
+ const configPath = join(homeDir, '.codex', 'config.toml');
305
+ const content = readFileSync(configPath, 'utf-8');
306
+ const countOccurrences = (needle) => content.split(needle).length - 1;
307
+ expect(countOccurrences('# >>> skillsmith:mcp_servers.skillsmith >>>')).toBe(1);
308
+ expect(countOccurrences('# >>> skillsmith:agents.skillsmith-agent >>>')).toBe(1);
309
+ expect(countOccurrences('# >>> skillsmith:hooks.SessionStart >>>')).toBe(1);
310
+ expect(countOccurrences('[mcp_servers.skillsmith]')).toBe(1);
311
+ expect(countOccurrences('[[hooks.SessionStart]]')).toBe(1);
312
+ });
313
+ it('reports the codex hook wiring as "unchanged" on the second install', () => {
314
+ mkdirSync(join(homeDir, '.codex'), { recursive: true });
315
+ installAgentPack({ homeDir });
316
+ const second = installAgentPack({ homeDir });
317
+ const report = second.harnessReports.find((r) => r.harness === 'codex');
318
+ expect(report?.hookConfig.some((w) => w.status === 'unchanged')).toBe(true);
319
+ });
320
+ it('reports mcpConfig status "unchanged" on the second install', () => {
321
+ installAgentPack({ homeDir });
322
+ const second = installAgentPack({ homeDir });
323
+ const report = second.harnessReports.find((r) => r.harness === 'claude-code');
324
+ expect(report?.mcpConfig?.status).toBe('unchanged');
325
+ });
326
+ // Governance regression test (2026-07-01) for the commit-message-claimed
327
+ // fix: "duplicate backups when hooks+MCP share a config file". Within a
328
+ // SINGLE install run, claude-code's settings.json is merged into THREE
329
+ // times (SessionStart hook, SessionEnd hook, MCP registration) — without
330
+ // `alreadyBackedUpPaths` sharing across those calls, the second and third
331
+ // merges would each independently "back up" content THIS SAME RUN already
332
+ // wrote, producing 3 backup files for one genuine pre-install state instead
333
+ // of 1, and (per `agent-manifest.ts`'s `dedupeEntriesByPath` last-non-null-
334
+ // wins rule) the manifest would end up pointing `uninstall` at the WRONG,
335
+ // polluted backup rather than the true pre-install content.
336
+ it('writes exactly ONE backup file for settings.json even though 3 separate merges touch it in one run', () => {
337
+ mkdirSync(join(homeDir, '.claude'), { recursive: true });
338
+ const settingsPath = join(homeDir, '.claude', 'settings.json');
339
+ writeFileSync(settingsPath, JSON.stringify({ preExisting: true }, null, 2));
340
+ installAgentPack({ homeDir });
341
+ const backupsDir = getAgentInstallBackupsDir();
342
+ const backupFiles = readdirSync(backupsDir).filter((f) => f.includes('settings.json'));
343
+ expect(backupFiles).toHaveLength(1);
344
+ const backupContent = JSON.parse(readFileSync(join(backupsDir, backupFiles[0]), 'utf-8'));
345
+ // The ONE backup that exists must be the GENUINE pre-install content —
346
+ // not an intermediate state polluted by an earlier merge THIS run.
347
+ expect(backupContent).toEqual({ preExisting: true });
348
+ });
349
+ });
350
+ //# sourceMappingURL=agent-pack-installer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-pack-installer.test.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Report + options types for `installAgentPack` / `uninstallAgentPack`
3
+ * (SMI-5456 Wave 1 Step 5).
4
+ *
5
+ * @module @skillsmith/core/install/agent-pack-installer.types
6
+ */
7
+ import type { MergeResult } from './agent-config-merge.types.js';
8
+ /** Support tier from PRD §3.1 / Decision 5. */
9
+ export type SupportTier = 1 | 2 | 3;
10
+ export declare const HARNESS_SUPPORT_TIER: Readonly<Record<string, SupportTier>>;
11
+ export interface HarnessInstallReport {
12
+ harness: string;
13
+ tier: SupportTier;
14
+ detected: boolean;
15
+ skillPackWritten: boolean;
16
+ shimWritten: boolean;
17
+ hooksInstalled: boolean;
18
+ mcpConfig: MergeResult | null;
19
+ hookConfig: MergeResult[];
20
+ notes: string[];
21
+ }
22
+ export interface AgentInstallOptions {
23
+ /** Override HOME for tests. Defaults to `os.homedir()`. */
24
+ homeDir?: string;
25
+ /** Overwrite a foreign (non-Skillsmith) MCP/hook config entry instead of refusing. Default false. */
26
+ force?: boolean;
27
+ }
28
+ export interface AgentInstallResult {
29
+ installedAt: string;
30
+ manifestPath: string;
31
+ harnessReports: HarnessInstallReport[];
32
+ }
33
+ export interface AgentUninstallOptions {
34
+ homeDir?: string;
35
+ }
36
+ export interface AgentUninstallResult {
37
+ /** Paths that were deleted (installer-created files) or restored from backup (installer-modified files). */
38
+ removed: string[];
39
+ restored: string[];
40
+ /** Manifest entries that referenced a path already missing on disk (no-op, not an error). */
41
+ alreadyGone: string[];
42
+ /**
43
+ * Manifest entries whose `path` or `backupPath` did not match a known
44
+ * installer target (see `agent-manifest-path-guard.ts`) — skipped
45
+ * entirely, neither deleted nor restored. Non-empty only for a corrupted
46
+ * or hand-tampered manifest; empty on every normal install/uninstall
47
+ * cycle.
48
+ */
49
+ rejected: string[];
50
+ }
51
+ //# sourceMappingURL=agent-pack-installer.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-pack-installer.types.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAEhE,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAEnC,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAQtE,CAAA;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,OAAO,CAAA;IACpB,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qGAAqG;IACrG,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,oBAAoB,EAAE,CAAA;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,4GAA4G;IAC5G,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,6FAA6F;IAC7F,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Report + options types for `installAgentPack` / `uninstallAgentPack`
3
+ * (SMI-5456 Wave 1 Step 5).
4
+ *
5
+ * @module @skillsmith/core/install/agent-pack-installer.types
6
+ */
7
+ export const HARNESS_SUPPORT_TIER = {
8
+ 'claude-code': 1,
9
+ cursor: 1,
10
+ codex: 1,
11
+ copilot: 1,
12
+ opencode: 2,
13
+ hermes: 2,
14
+ windsurf: 3,
15
+ };
16
+ //# sourceMappingURL=agent-pack-installer.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-pack-installer.types.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,CAAC,MAAM,oBAAoB,GAA0C;IACzE,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;CACZ,CAAA"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * `sklx agent uninstall` core orchestration (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Reverses EXACTLY what `installAgentPack` wrote by replaying the manifest
5
+ * it saved — never by re-deriving "what the generator would currently
6
+ * produce" (which could have drifted across a version bump between install
7
+ * and uninstall). Per manifest entry:
8
+ * - `backupPath !== null` (a shared config file we merged a key into):
9
+ * restore the file to the FULL pre-merge content captured in the
10
+ * backup — this removes exactly our `skillsmith` key/hook entry while
11
+ * leaving every other key in the file untouched, because the backup was
12
+ * taken of the whole file immediately before the merge.
13
+ * - `backupPath === null` (a file we created outright — skill pack copy,
14
+ * shim, hook script): delete it. There is nothing to restore to.
15
+ * - A path already missing on disk (user deleted it manually) is a no-op,
16
+ * not an error.
17
+ *
18
+ * SECURITY (governance follow-up, 2026-07-01): before touching the
19
+ * filesystem, every entry's `path` is checked against
20
+ * {@link isAllowedManifestEntryPath} (must structurally match one of the
21
+ * installer's known per-harness target locations) and, when `backupPath` is
22
+ * set, {@link isAllowedManifestBackupPath} (must resolve under this run's
23
+ * manifest backups directory). The manifest is an ordinary user-writable
24
+ * JSON file, not a signed record — a corrupted or tampered manifest must
25
+ * never become an arbitrary-file-delete/overwrite primitive. An entry
26
+ * failing either check is skipped entirely (added to `result.rejected`,
27
+ * counted toward neither `removed` nor `restored`) rather than acted on.
28
+ *
29
+ * After removing all installer-created files, now-empty directories we
30
+ * likely created (the parents of removed paths) are cleaned up bottom-up —
31
+ * a non-empty directory is left alone (`rmdirSync` only removes empty ones).
32
+ *
33
+ * Known limitation: a hook script's original executable bit is not
34
+ * separately tracked, so restoring a backup writes default file
35
+ * permissions. This only matters for the vanishingly rare case of a
36
+ * pre-existing FOREIGN executable file that happened to already occupy our
37
+ * namespaced hook-script path — documented, not defended against.
38
+ *
39
+ * @module @skillsmith/core/install/agent-pack-uninstaller
40
+ */
41
+ import type { AgentUninstallOptions, AgentUninstallResult } from './agent-pack-installer.types.js';
42
+ export declare function uninstallAgentPack(_opts?: AgentUninstallOptions): AgentUninstallResult;
43
+ //# sourceMappingURL=agent-pack-uninstaller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-pack-uninstaller.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-uninstaller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAUH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAElG,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,qBAA0B,GAAG,oBAAoB,CAkD1F"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * `sklx agent uninstall` core orchestration (SMI-5456 Wave 1 Step 5).
3
+ *
4
+ * Reverses EXACTLY what `installAgentPack` wrote by replaying the manifest
5
+ * it saved — never by re-deriving "what the generator would currently
6
+ * produce" (which could have drifted across a version bump between install
7
+ * and uninstall). Per manifest entry:
8
+ * - `backupPath !== null` (a shared config file we merged a key into):
9
+ * restore the file to the FULL pre-merge content captured in the
10
+ * backup — this removes exactly our `skillsmith` key/hook entry while
11
+ * leaving every other key in the file untouched, because the backup was
12
+ * taken of the whole file immediately before the merge.
13
+ * - `backupPath === null` (a file we created outright — skill pack copy,
14
+ * shim, hook script): delete it. There is nothing to restore to.
15
+ * - A path already missing on disk (user deleted it manually) is a no-op,
16
+ * not an error.
17
+ *
18
+ * SECURITY (governance follow-up, 2026-07-01): before touching the
19
+ * filesystem, every entry's `path` is checked against
20
+ * {@link isAllowedManifestEntryPath} (must structurally match one of the
21
+ * installer's known per-harness target locations) and, when `backupPath` is
22
+ * set, {@link isAllowedManifestBackupPath} (must resolve under this run's
23
+ * manifest backups directory). The manifest is an ordinary user-writable
24
+ * JSON file, not a signed record — a corrupted or tampered manifest must
25
+ * never become an arbitrary-file-delete/overwrite primitive. An entry
26
+ * failing either check is skipped entirely (added to `result.rejected`,
27
+ * counted toward neither `removed` nor `restored`) rather than acted on.
28
+ *
29
+ * After removing all installer-created files, now-empty directories we
30
+ * likely created (the parents of removed paths) are cleaned up bottom-up —
31
+ * a non-empty directory is left alone (`rmdirSync` only removes empty ones).
32
+ *
33
+ * Known limitation: a hook script's original executable bit is not
34
+ * separately tracked, so restoring a backup writes default file
35
+ * permissions. This only matters for the vanishingly rare case of a
36
+ * pre-existing FOREIGN executable file that happened to already occupy our
37
+ * namespaced hook-script path — documented, not defended against.
38
+ *
39
+ * @module @skillsmith/core/install/agent-pack-uninstaller
40
+ */
41
+ import { dirname } from 'node:path';
42
+ import { existsSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'node:fs';
43
+ import { loadAgentManifest, saveAgentManifest } from './agent-manifest.js';
44
+ import { isAllowedManifestBackupPath, isAllowedManifestEntryPath, } from './agent-manifest-path-guard.js';
45
+ export function uninstallAgentPack(_opts = {}) {
46
+ const manifest = loadAgentManifest();
47
+ const removed = [];
48
+ const restored = [];
49
+ const alreadyGone = [];
50
+ const rejected = [];
51
+ const touchedDirs = new Set();
52
+ for (const entry of manifest.entries) {
53
+ if (!isAllowedManifestEntryPath(entry.path)) {
54
+ rejected.push(entry.path);
55
+ continue;
56
+ }
57
+ if (entry.backupPath && !isAllowedManifestBackupPath(entry.backupPath)) {
58
+ // A validated destination path but an untrusted backup SOURCE — never
59
+ // restore from it (that would be an attacker-controlled read into a
60
+ // safe write target) and never fall through to delete either (the
61
+ // entry's true install-time shape can't be determined). Skip it whole.
62
+ rejected.push(entry.path);
63
+ continue;
64
+ }
65
+ if (!existsSync(entry.path)) {
66
+ alreadyGone.push(entry.path);
67
+ continue;
68
+ }
69
+ touchedDirs.add(dirname(entry.path));
70
+ if (entry.backupPath && existsSync(entry.backupPath)) {
71
+ const content = readFileSync(entry.backupPath, 'utf-8');
72
+ writeFileSync(entry.path, content, 'utf-8');
73
+ restored.push(entry.path);
74
+ }
75
+ else {
76
+ unlinkSync(entry.path);
77
+ removed.push(entry.path);
78
+ }
79
+ }
80
+ cleanupEmptyDirs(touchedDirs);
81
+ // Uninstall clears the manifest — a subsequent install starts fresh
82
+ // (P-5 idempotency: install → uninstall → install produces the same
83
+ // filesystem state as a first-ever install, not accumulated entries).
84
+ saveAgentManifest({
85
+ schemaVersion: 1,
86
+ installedAt: new Date(0).toISOString(),
87
+ packSchemaVersion: 0,
88
+ entries: [],
89
+ });
90
+ return { removed, restored, alreadyGone, rejected };
91
+ }
92
+ /** Remove now-empty directories, deepest first, stopping at the first non-empty one per branch. */
93
+ function cleanupEmptyDirs(dirs) {
94
+ const sorted = [...dirs].sort((a, b) => b.length - a.length);
95
+ for (const dir of sorted) {
96
+ let current = dir;
97
+ // Walk upward while each level is empty; stop at the first non-empty
98
+ // (or missing/root) directory. Bounded by path length, never infinite.
99
+ for (let i = 0; i < 32; i++) {
100
+ try {
101
+ rmdirSync(current);
102
+ }
103
+ catch {
104
+ break; // non-empty, missing, or permission-denied — stop this branch.
105
+ }
106
+ const parent = dirname(current);
107
+ if (parent === current)
108
+ break;
109
+ current = parent;
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=agent-pack-uninstaller.js.map