@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
@@ -10,19 +10,40 @@
10
10
  * mutation) so arrow-const exports can be wrapped without mutation.
11
11
  * Applied review change H4: `framework` is captured per-call, not memoised.
12
12
  */
13
+ import type { AgentMarker } from './agent-marker.js';
13
14
  type AnyFunction = (...args: never[]) => unknown;
14
15
  /**
15
- * Install (or clear) the per-process emission gate.
16
+ * Run `fn` with `enabled` installed as the emission-gate decision for every
17
+ * telemetry emit inside its async continuation. Concurrency-safe: parallel
18
+ * invocations each see only their own value; code outside any
19
+ * `runWithEmissionGate` scope falls back to the module `let` (default-suppress
20
+ * when that too is unset).
16
21
  *
17
- * Pass a predicate to enable telemetry only when the predicate returns true;
18
- * pass `undefined` to revert to the default-suppress behaviour. Callers should
19
- * always reset to `undefined` in a `finally` so a thrown handler does not
20
- * leak emission permission to the next request.
22
+ * Takes a resolved boolean VALUE (consent resolved once at dispatch) contrast
23
+ * `setEmissionGate`, which takes a predicate thunk. The value is read live in
24
+ * the emit path, so an in-flight call always observes the gate active for ITS
25
+ * OWN scope, never a sibling's.
26
+ */
27
+ export declare function runWithEmissionGate<T>(enabled: boolean, fn: () => Promise<T>): Promise<T>;
28
+ /**
29
+ * Install (or clear) the process-wide FALLBACK emission gate.
21
30
  *
22
- * The predicate is evaluated once per call to a wrapped function, inside the
23
- * `finally` block, so it sees the live state of any per-request resolver.
31
+ * @deprecated Prefer `runWithEmissionGate`, which scopes the decision to a
32
+ * single call's async continuation and auto-unwinds no reset discipline, no
33
+ * cross-call leak. `setEmissionGate` survives only as a test seam and the
34
+ * pre-SMI-5479 fallback: its predicate is consulted (evaluated once per wrapped
35
+ * call, in the `finally` block) ONLY when no `runWithEmissionGate` scope is
36
+ * active. Pass a predicate to enable emission when it returns true; pass
37
+ * `undefined` to revert to default-suppress.
24
38
  */
25
39
  export declare function setEmissionGate(gate: (() => boolean) | undefined): void;
40
+ /**
41
+ * Run `fn` with `marker` installed as the agent-mediation context for every
42
+ * telemetry emit inside its async continuation. Concurrency-safe: parallel
43
+ * invocations each see only their own marker; code outside any
44
+ * `runWithMarkerContext` scope sees no marker (fields default false/false/null).
45
+ */
46
+ export declare function runWithMarkerContext<T>(marker: AgentMarker, fn: () => Promise<T>): Promise<T>;
26
47
  /**
27
48
  * Options for `withTelemetry`.
28
49
  *
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../../src/telemetry/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,KAAK,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAA;AAyBhD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAEvE;AAMD;;;;;;GAMG;AAMH,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE;IACjE,8EAA8E;IAC9E,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,kBAAkB,CAAA;IAC/C,qEAAqE;IACrE,cAAc,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;CAC3C;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EAAE,OAAO,EACrE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,EACvD,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAC7B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAoCtC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAEtD"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../../src/telemetry/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAWpD,KAAK,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAA;AAwChD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEzF;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAEvE;AAsBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAE7F;AAmCD;;;;;;GAMG;AAMH,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE;IACjE,8EAA8E;IAC9E,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,kBAAkB,CAAA;IAC/C,qEAAqE;IACrE,cAAc,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;CAC3C;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EAAE,OAAO,EACrE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,EACvD,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAC7B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CA0FtC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * SMI-5479: `runWithEmissionGate` (AsyncLocalStorage emission gate) unit +
3
+ * concurrency coverage. Sibling to `wrap.test.ts` (split per the 500-line file
4
+ * gate); the pre-SMI-5479 module-`let` emission-gate cases stay in
5
+ * `wrap.test.ts` §9 untouched, proving the retained fallback's zero churn.
6
+ *
7
+ * Covers:
8
+ * - T5: `runWithEmissionGate` unit — basic emit/suppress, nested scopes
9
+ * (inner shadows outer), auto-unwind on return AND on throw,
10
+ * ALS-store-beats-module-`let` precedence, fallback to the module `let`
11
+ * when no store is present, and the false-shadow pin
12
+ * (`setEmissionGate(() => true)` + active `runWithEmissionGate(false, …)`
13
+ * → zero emit — pins `??` vs `||` at the emit read; an accidental `||`
14
+ * would leak emission from a consent-off call).
15
+ * - T3: parallel no-bleed for the GATE (P-5 heart) — manually-resolved
16
+ * promises interleave one scope's exit against an in-flight call in another
17
+ * scope; the in-flight call still emits per ITS OWN scope. The committed
18
+ * regression pin for the `wrap.ts` ALS-precedence read — it fails if that
19
+ * read is ever reverted to consult the module `let` only.
20
+ */
21
+ export {};
22
+ //# sourceMappingURL=wrap.gate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.gate.test.d.ts","sourceRoot":"","sources":["../../../src/telemetry/wrap.gate.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * SMI-5479: `runWithEmissionGate` (AsyncLocalStorage emission gate) unit +
3
+ * concurrency coverage. Sibling to `wrap.test.ts` (split per the 500-line file
4
+ * gate); the pre-SMI-5479 module-`let` emission-gate cases stay in
5
+ * `wrap.test.ts` §9 untouched, proving the retained fallback's zero churn.
6
+ *
7
+ * Covers:
8
+ * - T5: `runWithEmissionGate` unit — basic emit/suppress, nested scopes
9
+ * (inner shadows outer), auto-unwind on return AND on throw,
10
+ * ALS-store-beats-module-`let` precedence, fallback to the module `let`
11
+ * when no store is present, and the false-shadow pin
12
+ * (`setEmissionGate(() => true)` + active `runWithEmissionGate(false, …)`
13
+ * → zero emit — pins `??` vs `||` at the emit read; an accidental `||`
14
+ * would leak emission from a consent-off call).
15
+ * - T3: parallel no-bleed for the GATE (P-5 heart) — manually-resolved
16
+ * promises interleave one scope's exit against an in-flight call in another
17
+ * scope; the in-flight call still emits per ITS OWN scope. The committed
18
+ * regression pin for the `wrap.ts` ALS-precedence read — it fails if that
19
+ * read is ever reverted to consult the module `let` only.
20
+ */
21
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
22
+ import { withTelemetry, setEmissionGate, runWithEmissionGate } from './wrap.js';
23
+ vi.mock('./posthog.js', () => ({
24
+ trackSkillInvoke: vi.fn(),
25
+ }));
26
+ // SMI-5615: test seam for the Wave-2 `logging/redact.ts` module — see
27
+ // wrap.test.ts for rationale.
28
+ vi.mock('../logging/redact.js', () => ({
29
+ redactSensitiveData: (s) => s,
30
+ }));
31
+ import { trackSkillInvoke } from './posthog.js';
32
+ const mockTrack = vi.mocked(trackSkillInvoke);
33
+ beforeEach(() => {
34
+ mockTrack.mockReset();
35
+ // No module `let` gate by default — the ALS scope is the unit under test.
36
+ // Cases that exercise the fallback / false-shadow install one explicitly.
37
+ setEmissionGate(undefined);
38
+ });
39
+ afterEach(() => {
40
+ setEmissionGate(undefined);
41
+ // The ALS gate needs no reset — `runWithEmissionGate` auto-scopes to its
42
+ // callback, so nothing can leak across tests.
43
+ });
44
+ const BASE_OPTS = {
45
+ source: 'mcp-tool',
46
+ extractSkillId: () => 'test/skill',
47
+ };
48
+ // ---------------------------------------------------------------------------
49
+ // T5 — runWithEmissionGate unit
50
+ // ---------------------------------------------------------------------------
51
+ describe('runWithEmissionGate (T5 — ALS emission gate)', () => {
52
+ it('emits inside a runWithEmissionGate(true) scope', async () => {
53
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
54
+ await runWithEmissionGate(true, () => wrapped());
55
+ expect(mockTrack).toHaveBeenCalledOnce();
56
+ });
57
+ it('suppresses inside a runWithEmissionGate(false) scope', async () => {
58
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
59
+ await runWithEmissionGate(false, () => wrapped());
60
+ expect(mockTrack).not.toHaveBeenCalled();
61
+ });
62
+ it('nested scopes — inner false shadows outer true (no emit)', async () => {
63
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
64
+ await runWithEmissionGate(true, () => runWithEmissionGate(false, () => wrapped()));
65
+ expect(mockTrack).not.toHaveBeenCalled();
66
+ });
67
+ it('nested scopes — inner true shadows outer false (emit)', async () => {
68
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
69
+ await runWithEmissionGate(false, () => runWithEmissionGate(true, () => wrapped()));
70
+ expect(mockTrack).toHaveBeenCalledOnce();
71
+ });
72
+ it('auto-unwinds on return — a call after the scope resolves falls back to default-suppress', async () => {
73
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
74
+ await runWithEmissionGate(true, () => wrapped());
75
+ expect(mockTrack).toHaveBeenCalledOnce();
76
+ mockTrack.mockReset();
77
+ // Outside the scope now — no module gate installed → default-suppress.
78
+ await wrapped();
79
+ expect(mockTrack).not.toHaveBeenCalled();
80
+ });
81
+ it('auto-unwinds on throw — the scope does not leak to a later out-of-scope call', async () => {
82
+ const boom = withTelemetry(() => {
83
+ throw new Error('handler exploded');
84
+ }, BASE_OPTS);
85
+ await expect(runWithEmissionGate(true, () => boom())).rejects.toThrow('handler exploded');
86
+ // The throwing call itself emits (success:false) — the `finally` runs inside
87
+ // the still-live scope.
88
+ expect(mockTrack).toHaveBeenCalledOnce();
89
+ expect(mockTrack).toHaveBeenCalledWith(expect.objectContaining({ success: false }));
90
+ mockTrack.mockReset();
91
+ // The scope has unwound — a later out-of-scope call must not inherit `true`.
92
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
93
+ await wrapped();
94
+ expect(mockTrack).not.toHaveBeenCalled();
95
+ });
96
+ it('ALS store beats the module `let` — store true wins over a module-`let` false', async () => {
97
+ setEmissionGate(() => false);
98
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
99
+ await runWithEmissionGate(true, () => wrapped());
100
+ expect(mockTrack).toHaveBeenCalledOnce();
101
+ });
102
+ it('false-shadow pin (`??` not `||`) — store false wins over a permissive module `let`', async () => {
103
+ // The heart of the `??` vs `||` pin: a permissive module gate is installed,
104
+ // but an active consent-OFF ALS scope must suppress. `||` would let the
105
+ // module `true` leak emission from a consent-off call.
106
+ setEmissionGate(() => true);
107
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
108
+ await runWithEmissionGate(false, () => wrapped());
109
+ expect(mockTrack).not.toHaveBeenCalled();
110
+ });
111
+ it('falls back to the module `let` when no ALS scope is present (thunk true → emit)', async () => {
112
+ setEmissionGate(() => true);
113
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
114
+ await wrapped();
115
+ expect(mockTrack).toHaveBeenCalledOnce();
116
+ });
117
+ it('falls back to the module `let` when no ALS scope is present (thunk false → no emit)', async () => {
118
+ setEmissionGate(() => false);
119
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
120
+ await wrapped();
121
+ expect(mockTrack).not.toHaveBeenCalled();
122
+ });
123
+ it('default-suppress — no ALS scope and no module gate → no emit', async () => {
124
+ const wrapped = withTelemetry(() => 'ok', BASE_OPTS);
125
+ await wrapped();
126
+ expect(mockTrack).not.toHaveBeenCalled();
127
+ });
128
+ });
129
+ // ---------------------------------------------------------------------------
130
+ // T3 — parallel no-bleed for the GATE (P-5 heart; committed regression pin)
131
+ // ---------------------------------------------------------------------------
132
+ describe('parallel no-bleed for the emission gate (T3 — P-5 invariant)', () => {
133
+ it('concurrent calls in different gate scopes each emit per their OWN scope', async () => {
134
+ // Failure mode this guards: if the emit read ignored the ALS store (a
135
+ // revert of the `wrap.ts` precedence read to the module `let` only), a
136
+ // consent-ON call's emit would be governed by whatever shared state last
137
+ // held — here call A's consent-OFF scope exiting mid-flight of B. Force the
138
+ // interleaving with manually-resolved promises: A (gate OFF) and B (gate
139
+ // ON) both start; A finishes (and must NOT emit) while B is still awaiting;
140
+ // then B finishes and MUST still emit per its own ON scope.
141
+ let releaseA;
142
+ let releaseB;
143
+ const blockA = new Promise((r) => (releaseA = r));
144
+ const blockB = new Promise((r) => (releaseB = r));
145
+ const emitted = [];
146
+ mockTrack.mockImplementation((p) => {
147
+ emitted.push(p.skillId);
148
+ });
149
+ const wrappedA = withTelemetry(async () => {
150
+ await blockA;
151
+ return 'A';
152
+ }, { ...BASE_OPTS, extractSkillId: () => 'tool-a' });
153
+ const wrappedB = withTelemetry(async () => {
154
+ await blockB;
155
+ return 'B';
156
+ }, { ...BASE_OPTS, extractSkillId: () => 'tool-b' });
157
+ // A in a consent-OFF scope, B in a consent-ON scope, both in flight.
158
+ const callA = runWithEmissionGate(false, () => wrappedA());
159
+ const callB = runWithEmissionGate(true, () => wrappedB());
160
+ // A completes (its `finally` runs inside A's OFF scope) while B still awaits.
161
+ releaseA();
162
+ await callA;
163
+ expect(emitted).toEqual([]); // A suppressed correctly; B not yet emitted.
164
+ // B completes — its emit reads B's OWN ON scope, not A's exited OFF scope.
165
+ releaseB();
166
+ await callB;
167
+ expect(emitted).toEqual(['tool-b']);
168
+ });
169
+ it('a sibling ON call still emits after a nested (middleware-style) ON scope unwinds', async () => {
170
+ // Models the double-gate reconciliation (Steps 2-3): an outer dispatch
171
+ // scope (ON) drives call X through a NESTED runWithEmissionGate (the
172
+ // middleware's own scope) that resolves and auto-unwinds first, while a
173
+ // sibling direct-dispatch call Y (ON) is still in flight. Y's emit must
174
+ // still fire — the inner scope's exit must not disturb Y's own scope.
175
+ let releaseX;
176
+ let releaseY;
177
+ const blockX = new Promise((r) => (releaseX = r));
178
+ const blockY = new Promise((r) => (releaseY = r));
179
+ const emitted = [];
180
+ mockTrack.mockImplementation((p) => {
181
+ emitted.push(p.skillId);
182
+ });
183
+ const wrappedX = withTelemetry(async () => {
184
+ await blockX;
185
+ return 'X';
186
+ }, { ...BASE_OPTS, extractSkillId: () => 'tool-x' });
187
+ const wrappedY = withTelemetry(async () => {
188
+ await blockY;
189
+ return 'Y';
190
+ }, { ...BASE_OPTS, extractSkillId: () => 'tool-y' });
191
+ // X: a nested ON scope inside an ON dispatch scope (the double-gate shape).
192
+ const callX = runWithEmissionGate(true, () => runWithEmissionGate(true, () => wrappedX()));
193
+ // Y: a sibling direct-dispatch ON scope, in flight.
194
+ const callY = runWithEmissionGate(true, () => wrappedY());
195
+ releaseX();
196
+ await callX;
197
+ releaseY();
198
+ await callY;
199
+ expect(emitted).toEqual(['tool-x', 'tool-y']);
200
+ });
201
+ });
202
+ //# sourceMappingURL=wrap.gate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.gate.test.js","sourceRoot":"","sources":["../../../src/telemetry/wrap.gate.test.ts"],"names":[],"mappings":"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"}
@@ -10,43 +10,137 @@
10
10
  * mutation) so arrow-const exports can be wrapped without mutation.
11
11
  * Applied review change H4: `framework` is captured per-call, not memoised.
12
12
  */
13
+ import { AsyncLocalStorage } from 'node:async_hooks';
14
+ import { randomUUID } from 'node:crypto';
13
15
  import { trackSkillInvoke } from './posthog.js';
16
+ import { getCorrelationId, runWithCorrelationId } from '../logging/context.js';
17
+ import { redactSensitiveData } from '../logging/redact.js';
14
18
  const wrapped = new Set();
15
19
  // ---------------------------------------------------------------------------
16
- // Emission gate (SMI-5019 wire-in)
20
+ // Emission gate (SMI-5019 wire-in; SMI-5479 AsyncLocalStorage refactor)
17
21
  // ---------------------------------------------------------------------------
18
22
  //
19
- // Default-suppress: until an emission gate is installed via `setEmissionGate`,
20
- // `withTelemetry` does NOT emit. Privacy-safe by construction — consumers
21
- // (e.g. the mcp-server license-gate middleware) MUST call `setEmissionGate`
22
- // during request handling to enable emission for their context.
23
- //
24
- // The alternative (default-emit) would be backwards-compatible but risks
23
+ // Default-suppress: until an emission gate is active, `withTelemetry` does NOT
24
+ // emit. Privacy-safe by construction — the alternative (default-emit) risks
25
25
  // emitting telemetry for an unknown anonymous_id before consent has been
26
- // resolved. We pick the privacy-safe default per SMI-5019; a misconfigured
27
- // host that forgets to install a gate simply emits no telemetry, which is
28
- // observable (counts stay at zero) and recoverable.
26
+ // resolved. We pick the privacy-safe default per SMI-5019; a misconfigured host
27
+ // that never opens a gate simply emits no telemetry, which is observable
28
+ // (counts stay at zero) and recoverable.
29
29
  //
30
- // Multi-tenancy caveat: the gate is module-scoped. For a single-tenant MCP
31
- // server process (the v1 shape) this is correct. A future multi-tenant
32
- // transport would need `AsyncLocalStorage`-backed per-request state — see
33
- // the matching caveat in `license.gate.ts`.
34
- let emissionGate;
30
+ // Two gates feed the emit-path read (in the `finally` block below), in
31
+ // precedence order:
32
+ //
33
+ // 1. `emissionGateStorage` (PRIMARY) an `AsyncLocalStorage<boolean>`
34
+ // scoped per tool call via `runWithEmissionGate`. New call sites (the
35
+ // mcp-server dispatch handler + license-gate middleware) resolve consent
36
+ // ONCE at dispatch and pass that resolved VALUE into the scope; the store
37
+ // then governs every emit for the whole of that call's async
38
+ // continuation. Mirrors the marker-context ALS below one-for-one — the
39
+ // reason nested / concurrent installs are safe: `.run()` is reentrant and
40
+ // each async continuation is isolated, so a sibling call can never observe
41
+ // or clear this call's gate.
42
+ // 2. `emissionGate` (FALLBACK) — a process-wide module `let`, a THUNK
43
+ // installed via `setEmissionGate`, consulted only when no ALS store is
44
+ // present. Retained solely as a test seam and a deprecated fallback for
45
+ // the pre-SMI-5479 shape; new production code MUST use
46
+ // `runWithEmissionGate`.
47
+ //
48
+ // Multi-tenancy caveat (RESOLVED by SMI-5479): the gate used to be purely
49
+ // module-scoped, which a future multi-tenant transport could not share safely.
50
+ // The `AsyncLocalStorage`-backed per-request state that caveat deferred is now
51
+ // applied here — per-call scope isolates concurrent consents. See the matching
52
+ // note in `license.gate.ts`.
53
+ const emissionGateStorage = new AsyncLocalStorage();
35
54
  /**
36
- * Install (or clear) the per-process emission gate.
55
+ * Run `fn` with `enabled` installed as the emission-gate decision for every
56
+ * telemetry emit inside its async continuation. Concurrency-safe: parallel
57
+ * invocations each see only their own value; code outside any
58
+ * `runWithEmissionGate` scope falls back to the module `let` (default-suppress
59
+ * when that too is unset).
37
60
  *
38
- * Pass a predicate to enable telemetry only when the predicate returns true;
39
- * pass `undefined` to revert to the default-suppress behaviour. Callers should
40
- * always reset to `undefined` in a `finally` so a thrown handler does not
41
- * leak emission permission to the next request.
61
+ * Takes a resolved boolean VALUE (consent resolved once at dispatch) contrast
62
+ * `setEmissionGate`, which takes a predicate thunk. The value is read live in
63
+ * the emit path, so an in-flight call always observes the gate active for ITS
64
+ * OWN scope, never a sibling's.
65
+ */
66
+ export function runWithEmissionGate(enabled, fn) {
67
+ return emissionGateStorage.run(enabled, fn);
68
+ }
69
+ // Process-wide FALLBACK gate — a module `let` thunk (test-only / deprecated).
70
+ // Superseded by `runWithEmissionGate`; retained so existing unit tests and any
71
+ // pre-SMI-5479 caller keep working with zero churn.
72
+ let emissionGate;
73
+ /**
74
+ * Install (or clear) the process-wide FALLBACK emission gate.
42
75
  *
43
- * The predicate is evaluated once per call to a wrapped function, inside the
44
- * `finally` block, so it sees the live state of any per-request resolver.
76
+ * @deprecated Prefer `runWithEmissionGate`, which scopes the decision to a
77
+ * single call's async continuation and auto-unwinds no reset discipline, no
78
+ * cross-call leak. `setEmissionGate` survives only as a test seam and the
79
+ * pre-SMI-5479 fallback: its predicate is consulted (evaluated once per wrapped
80
+ * call, in the `finally` block) ONLY when no `runWithEmissionGate` scope is
81
+ * active. Pass a predicate to enable emission when it returns true; pass
82
+ * `undefined` to revert to default-suppress.
45
83
  */
46
84
  export function setEmissionGate(gate) {
47
85
  emissionGate = gate;
48
86
  }
49
87
  // ---------------------------------------------------------------------------
88
+ // Agent-mediation marker context (SMI-5456)
89
+ // ---------------------------------------------------------------------------
90
+ //
91
+ // The three per-event marker fields (`agent_session`, `nudge_origin`,
92
+ // `trigger_id`) do not live in the handler's arguments — they arrive on the MCP
93
+ // request's `_meta` or a session marker file, both resolved by the dispatch
94
+ // layer. The dispatcher runs each dispatch inside `runWithMarkerContext` and
95
+ // `withTelemetry` reads the store live in its emit path — never memoised,
96
+ // mirroring the per-call `framework` capture (H4).
97
+ //
98
+ // `AsyncLocalStorage` (not a module-scoped variable) because harnesses batch
99
+ // PARALLEL tool calls to one server process (Claude Code emits multiple
100
+ // tool_use blocks in one response). A module-scoped slot would let call A's
101
+ // completion clear call B's still-in-flight marker — silently zeroing
102
+ // `agent_session` on genuinely mediated calls and undercounting the mediation
103
+ // gate metric. ALS scopes the marker to each call's own async continuation, so
104
+ // concurrent calls cannot observe or clear each other's context.
105
+ const markerStorage = new AsyncLocalStorage();
106
+ /**
107
+ * Run `fn` with `marker` installed as the agent-mediation context for every
108
+ * telemetry emit inside its async continuation. Concurrency-safe: parallel
109
+ * invocations each see only their own marker; code outside any
110
+ * `runWithMarkerContext` scope sees no marker (fields default false/false/null).
111
+ */
112
+ export function runWithMarkerContext(marker, fn) {
113
+ return markerStorage.run(marker, fn);
114
+ }
115
+ // ---------------------------------------------------------------------------
116
+ // Error capture (SMI-5615)
117
+ // ---------------------------------------------------------------------------
118
+ //
119
+ // `trackSkillInvoke` previously reported only `success: boolean` on failure —
120
+ // the caught error was discarded entirely. No stack traces leave the machine:
121
+ // only the error's class name and a redacted, truncated message ride the
122
+ // already-consent-gated `skill_invoke` event.
123
+ const MAX_ERROR_MESSAGE_LENGTH = 256;
124
+ /** Extract a best-effort string message from an unknown caught value. */
125
+ function errorMessageOf(e) {
126
+ if (e instanceof Error)
127
+ return e.message;
128
+ if (typeof e === 'string')
129
+ return e;
130
+ try {
131
+ return JSON.stringify(e);
132
+ }
133
+ catch {
134
+ return String(e);
135
+ }
136
+ }
137
+ /** Truncate a (already redacted) error message to `MAX_ERROR_MESSAGE_LENGTH`. */
138
+ function truncateErrorMessage(message) {
139
+ return message.length > MAX_ERROR_MESSAGE_LENGTH
140
+ ? message.slice(0, MAX_ERROR_MESSAGE_LENGTH)
141
+ : message;
142
+ }
143
+ // ---------------------------------------------------------------------------
50
144
  // HOF
51
145
  // ---------------------------------------------------------------------------
52
146
  /**
@@ -69,39 +163,89 @@ export function setEmissionGate(gate) {
69
163
  */
70
164
  export function withTelemetry(handler, opts) {
71
165
  const wrappedFn = async (...args) => {
72
- const start = Date.now();
73
- const skillId = opts.extractSkillId(args);
74
- // Per H4: evaluated per-call so a single server process can serve multiple
75
- // clients with different frameworks on the same HTTP transport.
76
- const framework = opts.extractFramework?.(args) ?? 'unknown';
77
- let success = true;
78
- try {
79
- return await handler(...args);
80
- }
81
- catch (e) {
82
- success = false;
83
- throw e;
84
- }
85
- finally {
86
- // Emit BEFORE the catch re-throw lands; swallow telemetry errors so they
87
- // never affect the wrapped function's observable behaviour.
166
+ // SMI-5615 (F1 fix, corrected from the naive design): the correlation-ID
167
+ // scope wraps the ENTIRE body below — try *and* finally — not just the
168
+ // `handler(...args)` call. Installing it around only the handler would
169
+ // leave the finally block's emit path outside the ALS scope, so the
170
+ // `getCorrelationId()` read there would always see `undefined`, silently
171
+ // defeating the feature. Mint-if-absent (`getCorrelationId() ?? randomUUID()`)
172
+ // means a wrapped call nested inside another wrapped call's continuation
173
+ // inherits the outer ID instead of fragmenting one logical request's trace.
174
+ return runWithCorrelationId(getCorrelationId() ?? randomUUID(), async () => {
175
+ const start = Date.now();
176
+ const skillId = opts.extractSkillId(args);
177
+ // Per H4: evaluated per-call so a single server process can serve multiple
178
+ // clients with different frameworks on the same HTTP transport.
179
+ const framework = opts.extractFramework?.(args) ?? 'unknown';
180
+ let success = true;
181
+ let caughtError;
88
182
  try {
89
- // SMI-5019 wire-in: consult the emission gate. Default-suppress when
90
- // no gate is installed — see module-level comment for the rationale.
91
- if (emissionGate && emissionGate()) {
92
- trackSkillInvoke({
93
- skillId,
94
- source: opts.source,
95
- framework,
96
- durationMs: Date.now() - start,
97
- success,
98
- });
99
- }
183
+ return await handler(...args);
100
184
  }
101
- catch {
102
- // Intentionally swallowed — telemetry must never break user code.
185
+ catch (e) {
186
+ success = false;
187
+ caughtError = e;
188
+ throw e;
189
+ }
190
+ finally {
191
+ // Emit BEFORE the catch re-throw lands; swallow telemetry errors so they
192
+ // never affect the wrapped function's observable behaviour.
193
+ try {
194
+ // SMI-5019 wire-in / SMI-5479 refactor: consult the emission gate. The
195
+ // per-call ALS store (PRIMARY) wins over the module `let` thunk
196
+ // (FALLBACK). `??` — not `||` — so an ALS `false` suppresses even when a
197
+ // permissive module gate is installed: a consent-off scope must never
198
+ // leak emission. Default-suppress holds when neither is present (no
199
+ // store + no thunk → `undefined` → no emit).
200
+ const gateOn = emissionGateStorage.getStore() ?? (emissionGate ? emissionGate() : undefined);
201
+ if (gateOn) {
202
+ // SMI-5456: thread the marker from this call's ALS scope into the
203
+ // event. Read here (not memoised) so it reflects the marker installed
204
+ // for THIS call's async continuation — concurrent calls each see
205
+ // their own. Consent parity is automatic — these fields only ride an
206
+ // event that the emission gate already permitted.
207
+ const marker = markerStorage.getStore();
208
+ trackSkillInvoke({
209
+ skillId,
210
+ source: opts.source,
211
+ // Per-harness attribution: the marker channel's vocabulary-validated
212
+ // `harness` wins over the extractor result — every MCP-tool call
213
+ // site hardcodes `extractFramework: () => 'unknown'`, so without
214
+ // this the per-harness split never survives to the wire. H4
215
+ // (per-call, never memoised) is preserved: the ALS store IS
216
+ // per-request state, read here on every emit. CLI / VS Code
217
+ // callers never install marker context, so `getStore()` is
218
+ // undefined there and their real extractors keep winning.
219
+ framework: marker?.harness ?? framework,
220
+ durationMs: Date.now() - start,
221
+ success,
222
+ agentSession: marker?.agentSession ?? false,
223
+ nudgeOrigin: marker?.nudgeOrigin ?? false,
224
+ triggerId: marker?.triggerId ?? null,
225
+ // SMI-5615: cross-signal join key — a disk log line, an OTel span,
226
+ // and this PostHog event for one failure share this ID. Read live
227
+ // from the still-open scope established above (F1 fix), always
228
+ // present regardless of success/failure.
229
+ correlationId: getCorrelationId(),
230
+ // SMI-5615: capture the previously-discarded error on failure only.
231
+ // No stack traces leave the machine — class name + redacted,
232
+ // truncated (<=256 char) message only.
233
+ ...(success
234
+ ? {}
235
+ : {
236
+ errorName: caughtError instanceof Error
237
+ ? caughtError.constructor.name
238
+ : typeof caughtError,
239
+ errorMessage: truncateErrorMessage(redactSensitiveData(errorMessageOf(caughtError))),
240
+ }),
241
+ });
242
+ }
243
+ }
244
+ catch {
245
+ // Intentionally swallowed — telemetry must never break user code.
246
+ }
103
247
  }
104
- }
248
+ });
105
249
  };
106
250
  wrapped.add(wrappedFn);
107
251
  return wrappedFn;
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../../src/telemetry/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAW/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAA;AAEtC,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,0EAA0E;AAC1E,4EAA4E;AAC5E,gEAAgE;AAChE,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,4CAA4C;AAC5C,IAAI,YAAyC,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,IAAiC;IAC/D,YAAY,GAAG,IAAI,CAAA;AACrB,CAAC;AA+BD,8EAA8E;AAC9E,MAAM;AACN,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAuD,EACvD,IAA8B;IAE9B,MAAM,SAAS,GAAG,KAAK,EAAE,GAAG,IAAW,EAAoB,EAAE;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACzC,2EAA2E;QAC3E,gEAAgE;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;QAC5D,IAAI,OAAO,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,GAAG,KAAK,CAAA;YACf,MAAM,CAAC,CAAA;QACT,CAAC;gBAAS,CAAC;YACT,yEAAyE;YACzE,4DAA4D;YAC5D,IAAI,CAAC;gBACH,qEAAqE;gBACrE,qEAAqE;gBACrE,IAAI,YAAY,IAAI,YAAY,EAAE,EAAE,CAAC;oBACnC,gBAAgB,CAAC;wBACf,OAAO;wBACP,MAAM,EAAE,IAAI,CAAC,MAAM;wBACnB,SAAS;wBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;wBAC9B,OAAO;qBACR,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACtB,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,EAAe;IAC3C,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACxB,CAAC"}
1
+ {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../../src/telemetry/wrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SMI-5456: withTelemetry agent-mediation marker threading + Tier-2 framework
3
+ * emission. Sibling to `wrap.test.ts` (split per the 500-line file gate).
4
+ *
5
+ * Covers:
6
+ * - marker context threaded into the emitted payload (via runWithMarkerContext)
7
+ * - defaults false / false / null outside any marker scope
8
+ * - consent parity (suppressed gate emits nothing, marker or not)
9
+ * - concurrent no-bleed (P-5 invariant) — parallel calls each emit their
10
+ * OWN marker; an unscoped call stays neutral while others' scopes are live
11
+ * - per-framework emission incl. the opencode / hermes enum additions
12
+ * - marker `harness` feeds the event's `framework` (single-point per-harness
13
+ * attribution — MCP call sites hardcode `extractFramework: () => 'unknown'`)
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=wrap.marker.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.marker.test.d.ts","sourceRoot":"","sources":["../../../src/telemetry/wrap.marker.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}