@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,35 @@
1
+ /**
2
+ * SMI-883 / SMI-5615: Sensitive-data redaction, ported VERBATIM from the dead
3
+ * `packages/mcp-server/src/logger.ts` (lines 11-107) into the shared
4
+ * `@skillsmith/core` logging module. Same regex patterns, same behavior,
5
+ * same test coverage (see `redact.test.ts`) — this is tested, working code
6
+ * relocated, not rewritten.
7
+ */
8
+ export declare function stripAnsi(text: string): string;
9
+ /**
10
+ * SMI-883: Redact sensitive data from text before logging
11
+ * Exported for testing purposes
12
+ */
13
+ export declare function redactSensitiveData(text: string): string;
14
+ /**
15
+ * SMI-883: Recursively redact sensitive data from objects
16
+ * Exported for testing purposes
17
+ *
18
+ * SMI-5615 Mode-B diff-audit NEW-2: `seen` guards against circular
19
+ * references. The original (dead) `mcp-server/src/logger.ts` version this was
20
+ * ported from had no cycle guard — harmless there since it was never called
21
+ * in production, but this module IS the production write path now, so a
22
+ * circular `details`/`err` object (e.g. a thrown object with a `cause` cycle)
23
+ * must degrade to `'[Circular]'` rather than stack-overflowing, which would
24
+ * otherwise abort the whole record (including the redacted `msg` and
25
+ * `correlationId`) and fall through to the raw-message console fallback.
26
+ *
27
+ * `seen` tracks only the CURRENT recursion path (ancestors), not every object
28
+ * visited overall — each object is removed again once its own subtree
29
+ * finishes (the `finally` below). This is deliberate: the same object
30
+ * appearing twice at sibling positions (a shared, non-cyclic reference — a
31
+ * DAG, not a cycle) must redact normally both times, not get falsely flagged
32
+ * `'[Circular]'` just because it was visited once already elsewhere.
33
+ */
34
+ export declare function redactSensitiveObject(obj: unknown, seen?: WeakSet<object>): unknown;
35
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/logging/redact.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9C;AAmED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,OAAO,CAAC,MAAM,CAAiB,GACpC,OAAO,CAgBT"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * SMI-883 / SMI-5615: Sensitive-data redaction, ported VERBATIM from the dead
3
+ * `packages/mcp-server/src/logger.ts` (lines 11-107) into the shared
4
+ * `@skillsmith/core` logging module. Same regex patterns, same behavior,
5
+ * same test coverage (see `redact.test.ts`) — this is tested, working code
6
+ * relocated, not rewritten.
7
+ */
8
+ /**
9
+ * Strips ANSI/SGR escape sequences (`\x1b[...m` — the `chalk`-style color
10
+ * codes CLI call sites wrap error text in). SMI-5615 Mode-B diff-audit
11
+ * (Wave 2 pass): the disk-persisted record must not embed raw escape codes
12
+ * as log noise, AND a secret sitting immediately after an escape code's
13
+ * trailing letter (e.g. `\x1b[31msk_live_...`) can defeat
14
+ * `redactSensitiveData`'s leading `\b` word-boundary check — the `m`→`s`
15
+ * transition is word-to-word, not a boundary. Stripping ANSI BEFORE redacting
16
+ * closes that gap. Only applied on the DISK-persisted path (`logger.ts`'s
17
+ * `buildRecord`/`normalizeError`) — deliberately NOT applied to the
18
+ * console-mirrored path, which must keep chalk's colors for CLI terminal UX.
19
+ * Covers chalk's actual output (SGR codes only); not a full ANSI/VT100 strip.
20
+ */
21
+ // \x1b is the intentional ESC byte an SGR sequence always starts with; this
22
+ // is the same pattern the widely-used `strip-ansi` npm package uses (also
23
+ // eslint-disabled there).
24
+ // eslint-disable-next-line no-control-regex
25
+ const ANSI_SGR_PATTERN = /\x1b\[[0-9;]*m/g;
26
+ export function stripAnsi(text) {
27
+ if (!text)
28
+ return text;
29
+ return text.replace(ANSI_SGR_PATTERN, '');
30
+ }
31
+ /**
32
+ * SMI-883: Sensitive data patterns to redact before logging
33
+ * Prevents API keys, tokens, passwords, and secrets from being written to disk
34
+ */
35
+ const SENSITIVE_PATTERNS = [
36
+ // GitHub tokens
37
+ { pattern: /\b(ghp_[a-zA-Z0-9]{36})\b/g, replacement: 'ghp_[REDACTED]' },
38
+ { pattern: /\b(github_pat_[a-zA-Z0-9_]{22,})\b/g, replacement: 'github_pat_[REDACTED]' },
39
+ { pattern: /\b(gho_[a-zA-Z0-9]{36})\b/g, replacement: 'gho_[REDACTED]' },
40
+ { pattern: /\b(ghs_[a-zA-Z0-9]{36})\b/g, replacement: 'ghs_[REDACTED]' },
41
+ { pattern: /\b(ghu_[a-zA-Z0-9]{36})\b/g, replacement: 'ghu_[REDACTED]' },
42
+ { pattern: /\b(ghr_[a-zA-Z0-9]{36})\b/g, replacement: 'ghr_[REDACTED]' },
43
+ // Linear API keys
44
+ { pattern: /\b(lin_api_[a-zA-Z0-9]{32,})\b/g, replacement: 'lin_api_[REDACTED]' },
45
+ // Stripe keys
46
+ { pattern: /\b(sk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_live_[REDACTED]' },
47
+ { pattern: /\b(sk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_test_[REDACTED]' },
48
+ { pattern: /\b(pk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_live_[REDACTED]' },
49
+ { pattern: /\b(pk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_test_[REDACTED]' },
50
+ // OpenAI API keys
51
+ { pattern: /\b(sk-[a-zA-Z0-9]{48,})\b/g, replacement: 'sk-[REDACTED]' },
52
+ // Anthropic API keys
53
+ { pattern: /\b(sk-ant-[a-zA-Z0-9-]{32,})\b/g, replacement: 'sk-ant-[REDACTED]' },
54
+ // AWS keys
55
+ { pattern: /\b(AKIA[A-Z0-9]{16})\b/g, replacement: 'AKIA[REDACTED]' },
56
+ // Slack tokens
57
+ { pattern: /\b(xox[boaprs]-[a-zA-Z0-9-]{10,})\b/g, replacement: 'xox*-[REDACTED]' },
58
+ // npm tokens
59
+ { pattern: /\b(npm_[a-zA-Z0-9]{36})\b/g, replacement: 'npm_[REDACTED]' },
60
+ // Bearer tokens
61
+ { pattern: /\bBearer\s+([a-zA-Z0-9_\-.]{20,})/gi, replacement: 'Bearer [REDACTED]' },
62
+ // Basic auth
63
+ { pattern: /\bBasic\s+([a-zA-Z0-9+/=]{20,})/gi, replacement: 'Basic [REDACTED]' },
64
+ // JWT tokens
65
+ {
66
+ pattern: /\beyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]+\b/g,
67
+ replacement: '[JWT_REDACTED]',
68
+ },
69
+ // Generic API key patterns
70
+ {
71
+ pattern: /\b(api[_-]?key|apikey)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
72
+ replacement: 'api_key=[REDACTED]',
73
+ },
74
+ {
75
+ pattern: /\b(token|auth[_-]?token)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
76
+ replacement: 'token=[REDACTED]',
77
+ },
78
+ {
79
+ pattern: /\b(password|passwd|pwd)\s*[=:]\s*["']?([^"'\s]{4,})["']?/gi,
80
+ replacement: 'password=[REDACTED]',
81
+ },
82
+ {
83
+ pattern: /\b(secret|client[_-]?secret)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
84
+ replacement: 'secret=[REDACTED]',
85
+ },
86
+ // Connection strings with passwords
87
+ { pattern: /(:\/\/[^:]+:)([^@]+)(@)/gi, replacement: '$1[REDACTED]$3' },
88
+ // Private keys
89
+ {
90
+ pattern: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----/gi,
91
+ replacement: '-----[PRIVATE KEY REDACTED]-----',
92
+ },
93
+ ];
94
+ /**
95
+ * SMI-883: Redact sensitive data from text before logging
96
+ * Exported for testing purposes
97
+ */
98
+ export function redactSensitiveData(text) {
99
+ if (!text)
100
+ return text;
101
+ let redacted = text;
102
+ for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
103
+ // Reset lastIndex for global regex patterns to ensure all matches are found
104
+ pattern.lastIndex = 0;
105
+ redacted = redacted.replace(pattern, replacement);
106
+ }
107
+ return redacted;
108
+ }
109
+ /**
110
+ * SMI-883: Recursively redact sensitive data from objects
111
+ * Exported for testing purposes
112
+ *
113
+ * SMI-5615 Mode-B diff-audit NEW-2: `seen` guards against circular
114
+ * references. The original (dead) `mcp-server/src/logger.ts` version this was
115
+ * ported from had no cycle guard — harmless there since it was never called
116
+ * in production, but this module IS the production write path now, so a
117
+ * circular `details`/`err` object (e.g. a thrown object with a `cause` cycle)
118
+ * must degrade to `'[Circular]'` rather than stack-overflowing, which would
119
+ * otherwise abort the whole record (including the redacted `msg` and
120
+ * `correlationId`) and fall through to the raw-message console fallback.
121
+ *
122
+ * `seen` tracks only the CURRENT recursion path (ancestors), not every object
123
+ * visited overall — each object is removed again once its own subtree
124
+ * finishes (the `finally` below). This is deliberate: the same object
125
+ * appearing twice at sibling positions (a shared, non-cyclic reference — a
126
+ * DAG, not a cycle) must redact normally both times, not get falsely flagged
127
+ * `'[Circular]'` just because it was visited once already elsewhere.
128
+ */
129
+ export function redactSensitiveObject(obj, seen = new WeakSet()) {
130
+ if (obj === null || obj === undefined)
131
+ return obj;
132
+ if (typeof obj === 'string')
133
+ return redactSensitiveData(obj);
134
+ if (typeof obj !== 'object')
135
+ return obj;
136
+ if (seen.has(obj))
137
+ return '[Circular]';
138
+ seen.add(obj);
139
+ try {
140
+ if (Array.isArray(obj))
141
+ return obj.map((item) => redactSensitiveObject(item, seen));
142
+ const result = {};
143
+ for (const [key, value] of Object.entries(obj)) {
144
+ result[key] = redactSensitiveObject(value, seen);
145
+ }
146
+ return result;
147
+ }
148
+ finally {
149
+ seen.delete(obj);
150
+ }
151
+ }
152
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/logging/redact.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,4EAA4E;AAC5E,0EAA0E;AAC1E,0BAA0B;AAC1B,4CAA4C;AAC5C,MAAM,gBAAgB,GAAG,iBAAiB,CAAA;AAE1C,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,kBAAkB,GAAoD;IAC1E,gBAAgB;IAChB,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,EAAE,OAAO,EAAE,qCAAqC,EAAE,WAAW,EAAE,uBAAuB,EAAE;IACxF,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,kBAAkB;IAClB,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,cAAc;IACd,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjF,kBAAkB;IAClB,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,eAAe,EAAE;IACvE,qBAAqB;IACrB,EAAE,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,mBAAmB,EAAE;IAChF,WAAW;IACX,EAAE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACrE,eAAe;IACf,EAAE,OAAO,EAAE,sCAAsC,EAAE,WAAW,EAAE,iBAAiB,EAAE;IACnF,aAAa;IACb,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACxE,gBAAgB;IAChB,EAAE,OAAO,EAAE,qCAAqC,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACpF,aAAa;IACb,EAAE,OAAO,EAAE,mCAAmC,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACjF,aAAa;IACb;QACE,OAAO,EAAE,2DAA2D;QACpE,WAAW,EAAE,gBAAgB;KAC9B;IACD,2BAA2B;IAC3B;QACE,OAAO,EAAE,iEAAiE;QAC1E,WAAW,EAAE,oBAAoB;KAClC;IACD;QACE,OAAO,EAAE,mEAAmE;QAC5E,WAAW,EAAE,kBAAkB;KAChC;IACD;QACE,OAAO,EAAE,4DAA4D;QACrE,WAAW,EAAE,qBAAqB;KACnC;IACD;QACE,OAAO,EAAE,uEAAuE;QAChF,WAAW,EAAE,mBAAmB;KACjC;IACD,oCAAoC;IACpC,EAAE,OAAO,EAAE,2BAA2B,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACvE,eAAe;IACf;QACE,OAAO,EACL,0FAA0F;QAC5F,WAAW,EAAE,kCAAkC;KAChD;CACF,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,IAAI,QAAQ,GAAG,IAAI,CAAA;IACnB,KAAK,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,kBAAkB,EAAE,CAAC;QAC1D,4EAA4E;QAC5E,OAAO,CAAC,SAAS,GAAG,CAAC,CAAA;QACrB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAY,EACZ,OAAwB,IAAI,OAAO,EAAE;IAErC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IACjD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAA;IAC5D,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IACvC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAA;IACtC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;QACnF,MAAM,MAAM,GAA4B,EAAE,CAAA;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAClD,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * SMI-883 / SMI-5615: Tests for logger sensitive data redaction, ported from
3
+ * `packages/mcp-server/tests/unit/logger.test.ts` — same coverage, new
4
+ * location (`@skillsmith/core`'s `logging/redact.ts`).
5
+ * Ensures API keys, tokens, passwords, and secrets are never written to disk.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=redact.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.test.d.ts","sourceRoot":"","sources":["../../../src/logging/redact.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * SMI-883 / SMI-5615: Tests for logger sensitive data redaction, ported from
3
+ * `packages/mcp-server/tests/unit/logger.test.ts` — same coverage, new
4
+ * location (`@skillsmith/core`'s `logging/redact.ts`).
5
+ * Ensures API keys, tokens, passwords, and secrets are never written to disk.
6
+ */
7
+ import { describe, it, expect } from 'vitest';
8
+ import { redactSensitiveData, redactSensitiveObject, stripAnsi } from './redact.js';
9
+ describe('SMI-883: Logger Sensitive Data Redaction', () => {
10
+ describe('redactSensitiveData', () => {
11
+ describe('GitHub tokens', () => {
12
+ it('should redact classic personal access tokens (ghp_)', () => {
13
+ const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
14
+ const result = redactSensitiveData(input);
15
+ expect(result).toBe('Token: ghp_[REDACTED]');
16
+ expect(result).not.toContain('1234567890');
17
+ });
18
+ it('should redact fine-grained personal access tokens (github_pat_)', () => {
19
+ const input = 'Using github_pat_abcdefghijklmnopqrstuvwx12345';
20
+ const result = redactSensitiveData(input);
21
+ expect(result).toBe('Using github_pat_[REDACTED]');
22
+ });
23
+ it('should redact OAuth tokens (gho_)', () => {
24
+ const input = 'OAuth: gho_1234567890abcdefghijklmnopqrstuvwxyz';
25
+ const result = redactSensitiveData(input);
26
+ expect(result).toBe('OAuth: gho_[REDACTED]');
27
+ });
28
+ it('should redact server-to-server tokens (ghs_)', () => {
29
+ const input = 'Server: ghs_1234567890abcdefghijklmnopqrstuvwxyz';
30
+ const result = redactSensitiveData(input);
31
+ expect(result).toBe('Server: ghs_[REDACTED]');
32
+ });
33
+ it('should redact user-to-server tokens (ghu_)', () => {
34
+ const input = 'User: ghu_1234567890abcdefghijklmnopqrstuvwxyz';
35
+ const result = redactSensitiveData(input);
36
+ expect(result).toBe('User: ghu_[REDACTED]');
37
+ });
38
+ it('should redact refresh tokens (ghr_)', () => {
39
+ const input = 'Refresh: ghr_1234567890abcdefghijklmnopqrstuvwxyz';
40
+ const result = redactSensitiveData(input);
41
+ expect(result).toBe('Refresh: ghr_[REDACTED]');
42
+ });
43
+ });
44
+ describe('Linear API keys', () => {
45
+ it('should redact Linear API keys (lin_api_)', () => {
46
+ const input = 'LINEAR_API_KEY=lin_api_abcdefghijklmnopqrstuvwxyz123456';
47
+ const result = redactSensitiveData(input);
48
+ expect(result).toContain('lin_api_[REDACTED]');
49
+ expect(result).not.toContain('abcdefghij');
50
+ });
51
+ });
52
+ describe('Stripe keys', () => {
53
+ it('should redact live secret keys (sk_live_)', () => {
54
+ const input = 'STRIPE_KEY=sk_live_abcdefghijklmnopqrstuvwx';
55
+ const result = redactSensitiveData(input);
56
+ expect(result).toContain('sk_live_[REDACTED]');
57
+ });
58
+ it('should redact test secret keys (sk_test_)', () => {
59
+ const input = 'STRIPE_KEY=sk_test_abcdefghijklmnopqrstuvwx';
60
+ const result = redactSensitiveData(input);
61
+ expect(result).toContain('sk_test_[REDACTED]');
62
+ });
63
+ it('should redact live publishable keys (pk_live_)', () => {
64
+ const input = 'STRIPE_PK=pk_live_abcdefghijklmnopqrstuvwx';
65
+ const result = redactSensitiveData(input);
66
+ expect(result).toContain('pk_live_[REDACTED]');
67
+ });
68
+ it('should redact test publishable keys (pk_test_)', () => {
69
+ const input = 'STRIPE_PK=pk_test_abcdefghijklmnopqrstuvwx';
70
+ const result = redactSensitiveData(input);
71
+ expect(result).toContain('pk_test_[REDACTED]');
72
+ });
73
+ });
74
+ describe('OpenAI API keys', () => {
75
+ it('should redact OpenAI API keys (sk-)', () => {
76
+ const input = 'OPENAI_API_KEY=sk-abcdefghijklmnopqrstuvwxyz1234567890abcdefghijkl';
77
+ const result = redactSensitiveData(input);
78
+ expect(result).toContain('sk-[REDACTED]');
79
+ expect(result).not.toContain('abcdefghij');
80
+ });
81
+ });
82
+ describe('Anthropic API keys', () => {
83
+ it('should redact Anthropic API keys (sk-ant-)', () => {
84
+ const input = 'ANTHROPIC_API_KEY=sk-ant-api03-abcdefghijklmnopqrstuvwxyz12';
85
+ const result = redactSensitiveData(input);
86
+ expect(result).toContain('sk-ant-[REDACTED]');
87
+ });
88
+ });
89
+ describe('AWS keys', () => {
90
+ it('should redact AWS access key IDs (AKIA)', () => {
91
+ const input = 'AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE';
92
+ const result = redactSensitiveData(input);
93
+ expect(result).toContain('AKIA[REDACTED]');
94
+ expect(result).not.toContain('IOSFODNN7EXAMPLE');
95
+ });
96
+ });
97
+ describe('Slack tokens', () => {
98
+ it('should redact bot tokens (xoxb-)', () => {
99
+ const input = 'SLACK_TOKEN=xoxb-123456789012-1234567890123-abcdefghijklmnop';
100
+ const result = redactSensitiveData(input);
101
+ expect(result).toContain('xox*-[REDACTED]');
102
+ });
103
+ it('should redact user tokens (xoxp-)', () => {
104
+ const input = 'SLACK_TOKEN=xoxp-123456789012-1234567890123-abcdefghijklmnop';
105
+ const result = redactSensitiveData(input);
106
+ expect(result).toContain('xox*-[REDACTED]');
107
+ });
108
+ });
109
+ describe('npm tokens', () => {
110
+ it('should redact npm tokens (npm_)', () => {
111
+ const input = 'NPM_TOKEN=npm_abcdefghijklmnopqrstuvwxyz1234567890';
112
+ const result = redactSensitiveData(input);
113
+ expect(result).toContain('npm_[REDACTED]');
114
+ });
115
+ });
116
+ describe('Bearer and Basic auth', () => {
117
+ it('should redact Bearer tokens', () => {
118
+ const input = 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9';
119
+ const result = redactSensitiveData(input);
120
+ expect(result).toContain('Bearer [REDACTED]');
121
+ });
122
+ it('should redact Basic auth credentials', () => {
123
+ const input = 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQxMjM0NTY=';
124
+ const result = redactSensitiveData(input);
125
+ expect(result).toContain('Basic [REDACTED]');
126
+ });
127
+ });
128
+ describe('JWT tokens', () => {
129
+ it('should redact JWT tokens', () => {
130
+ const input = 'Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
131
+ const result = redactSensitiveData(input);
132
+ expect(result).toContain('[JWT_REDACTED]');
133
+ expect(result).not.toContain('eyJzdWI');
134
+ });
135
+ });
136
+ describe('Generic patterns', () => {
137
+ it('should redact api_key assignments', () => {
138
+ const input = 'config.api_key = "my_secret_api_key_12345"';
139
+ const result = redactSensitiveData(input);
140
+ expect(result).toContain('api_key=[REDACTED]');
141
+ });
142
+ it('should redact password assignments', () => {
143
+ const input = 'password: "supersecret123"';
144
+ const result = redactSensitiveData(input);
145
+ expect(result).toContain('password=[REDACTED]');
146
+ });
147
+ it('should redact secret assignments', () => {
148
+ const input = 'client_secret = "abcdefghijklmnop"';
149
+ const result = redactSensitiveData(input);
150
+ expect(result).toContain('secret=[REDACTED]');
151
+ });
152
+ it('should redact token assignments', () => {
153
+ const input = 'auth_token: "my_auth_token_value"';
154
+ const result = redactSensitiveData(input);
155
+ expect(result).toContain('token=[REDACTED]');
156
+ });
157
+ });
158
+ describe('Connection strings', () => {
159
+ it('should redact passwords in connection strings', () => {
160
+ const input = 'postgresql://user:mysecretpassword@localhost:5432/db';
161
+ const result = redactSensitiveData(input);
162
+ expect(result).toBe('postgresql://user:[REDACTED]@localhost:5432/db');
163
+ expect(result).not.toContain('mysecretpassword');
164
+ });
165
+ it('should redact passwords in MongoDB connection strings', () => {
166
+ const input = 'mongodb://admin:p4ssw0rd123@cluster.mongodb.net/mydb';
167
+ const result = redactSensitiveData(input);
168
+ expect(result).toContain('[REDACTED]@cluster');
169
+ expect(result).not.toContain('p4ssw0rd123');
170
+ });
171
+ });
172
+ describe('Private keys', () => {
173
+ it('should redact RSA private keys', () => {
174
+ const input = `-----BEGIN RSA PRIVATE KEY-----
175
+ MIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWyF8PbnGy
176
+ -----END RSA PRIVATE KEY-----`;
177
+ const result = redactSensitiveData(input);
178
+ expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
179
+ expect(result).not.toContain('MIIEpAIBAAKCAQEA');
180
+ });
181
+ it('should redact generic private keys', () => {
182
+ const input = `-----BEGIN PRIVATE KEY-----
183
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEA
184
+ -----END PRIVATE KEY-----`;
185
+ const result = redactSensitiveData(input);
186
+ expect(result).toBe('-----[PRIVATE KEY REDACTED]-----');
187
+ });
188
+ });
189
+ describe('Edge cases', () => {
190
+ it('should handle empty strings', () => {
191
+ expect(redactSensitiveData('')).toBe('');
192
+ });
193
+ it('should handle null-ish values', () => {
194
+ expect(redactSensitiveData(null)).toBe(null);
195
+ expect(redactSensitiveData(undefined)).toBe(undefined);
196
+ });
197
+ it('should handle text with no sensitive data', () => {
198
+ const input = 'This is a normal log message with no secrets';
199
+ expect(redactSensitiveData(input)).toBe(input);
200
+ });
201
+ it('should handle multiple tokens in same string', () => {
202
+ const input = 'GitHub: ghp_1234567890abcdefghijklmnopqrstuvwxyz, Stripe: sk_live_abcdefghijklmnopqrstuvwx';
203
+ const result = redactSensitiveData(input);
204
+ expect(result).toContain('ghp_[REDACTED]');
205
+ expect(result).toContain('sk_live_[REDACTED]');
206
+ });
207
+ it('should handle repeated calls (regex lastIndex reset)', () => {
208
+ const input = 'Token: ghp_1234567890abcdefghijklmnopqrstuvwxyz';
209
+ // Call multiple times to verify lastIndex is reset
210
+ const result1 = redactSensitiveData(input);
211
+ const result2 = redactSensitiveData(input);
212
+ const result3 = redactSensitiveData(input);
213
+ expect(result1).toBe('Token: ghp_[REDACTED]');
214
+ expect(result2).toBe('Token: ghp_[REDACTED]');
215
+ expect(result3).toBe('Token: ghp_[REDACTED]');
216
+ });
217
+ });
218
+ });
219
+ describe('redactSensitiveObject', () => {
220
+ it('should redact strings in simple objects', () => {
221
+ const input = {
222
+ token: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz',
223
+ name: 'test',
224
+ };
225
+ const result = redactSensitiveObject(input);
226
+ expect(result.token).toBe('ghp_[REDACTED]');
227
+ expect(result.name).toBe('test');
228
+ });
229
+ it('should redact strings in nested objects', () => {
230
+ const input = {
231
+ config: {
232
+ auth: {
233
+ apiKey: 'sk_live_abcdefghijklmnopqrstuvwx',
234
+ },
235
+ },
236
+ };
237
+ const result = redactSensitiveObject(input);
238
+ expect(result.config.auth).toEqual({
239
+ apiKey: 'sk_live_[REDACTED]',
240
+ });
241
+ });
242
+ it('should redact strings in arrays', () => {
243
+ const input = ['ghp_1234567890abcdefghijklmnopqrstuvwxyz', 'normal string'];
244
+ const result = redactSensitiveObject(input);
245
+ expect(result[0]).toBe('ghp_[REDACTED]');
246
+ expect(result[1]).toBe('normal string');
247
+ });
248
+ it('should handle mixed arrays and objects', () => {
249
+ const input = {
250
+ tokens: [
251
+ { key: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' },
252
+ { key: 'sk_live_abcdefghijklmnopqrstuvwx' },
253
+ ],
254
+ };
255
+ const result = redactSensitiveObject(input);
256
+ const tokens = result.tokens;
257
+ expect(tokens[0].key).toBe('ghp_[REDACTED]');
258
+ expect(tokens[1].key).toBe('sk_live_[REDACTED]');
259
+ });
260
+ it('should handle null and undefined', () => {
261
+ expect(redactSensitiveObject(null)).toBe(null);
262
+ expect(redactSensitiveObject(undefined)).toBe(undefined);
263
+ });
264
+ it('should preserve non-string primitives', () => {
265
+ const input = {
266
+ count: 42,
267
+ enabled: true,
268
+ ratio: 3.14,
269
+ };
270
+ const result = redactSensitiveObject(input);
271
+ expect(result).toEqual(input);
272
+ });
273
+ it('should handle Error objects by converting to plain object', () => {
274
+ const input = {
275
+ error: new Error('Failed with token ghp_1234567890abcdefghijklmnopqrstuvwxyz'),
276
+ };
277
+ const result = redactSensitiveObject(input);
278
+ // Error.message won't be in entries, but if serialized it would be redacted
279
+ expect(result.error).toBeDefined();
280
+ });
281
+ it('should mark a directly circular reference as [Circular] instead of stack-overflowing (SMI-5615 NEW-2)', () => {
282
+ const circular = { name: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' };
283
+ circular.self = circular;
284
+ const result = redactSensitiveObject(circular);
285
+ expect(result.name).toBe('ghp_[REDACTED]');
286
+ expect(result.self).toBe('[Circular]');
287
+ });
288
+ it('should mark an indirect (two-hop) circular reference as [Circular]', () => {
289
+ const a = {};
290
+ const b = { a };
291
+ a.b = b;
292
+ const result = redactSensitiveObject(a);
293
+ const nestedB = result.b;
294
+ expect(nestedB.a).toBe('[Circular]');
295
+ });
296
+ it('should NOT treat the same object appearing twice at sibling (non-cyclic) positions as circular', () => {
297
+ const shared = { key: 'ghp_1234567890abcdefghijklmnopqrstuvwxyz' };
298
+ const input = { first: shared, second: shared };
299
+ const result = redactSensitiveObject(input);
300
+ expect(result.first.key).toBe('ghp_[REDACTED]');
301
+ expect(result.second.key).toBe('ghp_[REDACTED]');
302
+ });
303
+ });
304
+ describe('stripAnsi (SMI-5615 Mode-B Wave 2 pass)', () => {
305
+ it('should strip chalk-style SGR color codes', () => {
306
+ const chalkRed = '\x1b[31mError:\x1b[39m something failed';
307
+ expect(stripAnsi(chalkRed)).toBe('Error: something failed');
308
+ });
309
+ it('should leave plain text with no escape codes untouched', () => {
310
+ expect(stripAnsi('plain text, no colors')).toBe('plain text, no colors');
311
+ });
312
+ it('should handle empty and null-ish input like redactSensitiveData does', () => {
313
+ expect(stripAnsi('')).toBe('');
314
+ });
315
+ it('closes the leading word-boundary redaction gap: a secret immediately after an SGR code is still redacted once ANSI is stripped first', () => {
316
+ // \x1b[31m ends in 'm' (a word char) directly followed by the secret's
317
+ // 's' (also a word char) — no \b between them, so redactSensitiveData
318
+ // alone would miss this. stripAnsi-then-redact is the fix (see
319
+ // `redactForDisk` in logger.ts).
320
+ const secret = 'sk_live_' + 'c'.repeat(24);
321
+ const chalkWrapped = `\x1b[31m${secret}\x1b[39m`;
322
+ // Demonstrates the gap exists when redacting the raw (un-stripped) text:
323
+ expect(redactSensitiveData(chalkWrapped)).toContain(secret);
324
+ // ...and that stripping ANSI first closes it:
325
+ expect(redactSensitiveData(stripAnsi(chalkWrapped))).not.toContain(secret);
326
+ expect(redactSensitiveData(stripAnsi(chalkWrapped))).toContain('sk_live_[REDACTED]');
327
+ });
328
+ });
329
+ });
330
+ //# sourceMappingURL=redact.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.test.js","sourceRoot":"","sources":["../../../src/logging/redact.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * SMI-5615: Per-surface serialized JSONL writer with daily/size rollover and
3
+ * retention sweep.
4
+ *
5
+ * Write-serialization invariant (F2, from
6
+ * docs/internal/implementation/production-error-logging.md — the plan's
7
+ * original P-5 draft omitted this; it was the Opus `concurrency-auditor`
8
+ * plan-audit's most likely real-world race):
9
+ *
10
+ * A redacted error record (stack ≤20 frames) can exceed `PIPE_BUF`
11
+ * (4096 bytes), so concurrent, independent `appendFile`/`appendFileSync`
12
+ * calls from parallel async tool invocations are NOT safe here — two
13
+ * large concurrent writes can interleave/tear into one invalid JSONL line.
14
+ *
15
+ * Fix: one long-lived `fs.createWriteStream(path, { flags: 'a' })` per
16
+ * surface, created lazily on first write and cached in a module-scoped
17
+ * map. ALL writes for a given surface go through THIS single stream.
18
+ *
19
+ * That alone (Node serializing writes queued on one stream) would already
20
+ * prevent tearing between two writes to the SAME stream object. This
21
+ * module goes one step further for simplicity and an even stronger
22
+ * guarantee: every write is wrapped in an async mutex (`runExclusive`) keyed
23
+ * by surface, so at most one write is ever in flight to a surface's
24
+ * underlying file descriptor at a time — including the write that decides
25
+ * whether a daily/size rollover is needed. That decision-and-possible-swap
26
+ * (open a new stream, `end()` the old one) happens INSIDE the same
27
+ * exclusive section as the write that triggered it, so a rotation can
28
+ * never race a write: no write can land on a stream that has already been
29
+ * told to `end()`, and no two writers can simultaneously decide "today's
30
+ * file doesn't exist yet" and both create a stream.
31
+ *
32
+ * Daily rollover: `skillsmith-<surface>-<YYYY-MM-DD>.jsonl`, keyed off the
33
+ * calendar date at write time (mocked by `vi.setSystemTime` in tests — no
34
+ * separate clock seam needed).
35
+ *
36
+ * Size cap: ~10MB per file. When the currently-open file for TODAY would
37
+ * exceed the cap, roll to a `.1`/`.2`/... suffixed continuation file for the
38
+ * same day (`skillsmith-<surface>-<YYYY-MM-DD>.jsonl.<n>`), through the same
39
+ * serialization point as everything else.
40
+ *
41
+ * Retention: on module init, asynchronously (NOT awaited — never blocks
42
+ * import) sweep `~/.skillsmith/logs/` and delete files whose mtime is older
43
+ * than 14 days. `pruneExpiredLogs` is also exported directly so tests can
44
+ * await a deterministic run against a temp directory instead of racing the
45
+ * fire-and-forget module-init sweep.
46
+ */
47
+ import type { Surface } from './types.js';
48
+ /**
49
+ * Serializes `line` for `surface`: acquires that surface's exclusive queue,
50
+ * resolves (opening/rotating as needed) the current stream, and writes.
51
+ * Resolves once the OS-level write has completed; rejects (never throws
52
+ * synchronously) if the directory/file couldn't be created or the write
53
+ * failed — callers (see `logger.ts`) must handle rejection to honor the
54
+ * "logger never throws" invariant.
55
+ */
56
+ export declare function writeLogLine(surface: Surface, line: string): Promise<void>;
57
+ /**
58
+ * Deletes files under the log directory whose mtime is older than
59
+ * `RETENTION_DAYS`. Best-effort: a missing directory or a per-file stat/
60
+ * unlink failure (permissions, a concurrent process already deleted it,
61
+ * etc.) is swallowed rather than thrown — this must never be able to crash
62
+ * module init or take down a caller that awaits it in a test.
63
+ *
64
+ * Exported (not just fired at module init) so tests can await a
65
+ * deterministic run against a temp directory rather than racing the
66
+ * fire-and-forget call below.
67
+ */
68
+ export declare function pruneExpiredLogs(): Promise<void>;
69
+ /**
70
+ * Closes any open streams and clears all in-memory state. Test-only — used
71
+ * by `rotation.test.ts` between cases so state from one temp-dir scenario
72
+ * never leaks into the next.
73
+ */
74
+ export declare function __resetLoggingStateForTests(): Promise<void>;
75
+ //# sourceMappingURL=rotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../src/logging/rotation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAqLzC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBtD;AAkBD;;;;GAIG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAQjE"}