@zivis/mcp 0.1.8 → 0.1.11

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 (346) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +19 -0
  3. package/dist/api-client.d.ts +2 -24
  4. package/dist/api-client.js +32 -52
  5. package/dist/auth/index.d.ts +1 -22
  6. package/dist/auth/index.js +17 -38
  7. package/dist/auth/jwt.d.ts +0 -16
  8. package/dist/auth/jwt.js +0 -13
  9. package/dist/auth/keychain.d.ts +6 -32
  10. package/dist/auth/keychain.js +83 -114
  11. package/dist/auth/oauth.d.ts +3 -32
  12. package/dist/auth/oauth.js +67 -61
  13. package/dist/auth/sessions.d.ts +5 -25
  14. package/dist/auth/sessions.js +20 -39
  15. package/dist/auth/token-refresh.d.ts +2 -22
  16. package/dist/auth/token-refresh.js +33 -36
  17. package/dist/cli.d.ts +1 -18
  18. package/dist/cli.js +30 -908
  19. package/dist/http-probe/capture.d.ts +51 -0
  20. package/dist/http-probe/capture.js +96 -0
  21. package/dist/http-probe/compare.d.ts +43 -0
  22. package/dist/http-probe/compare.js +117 -0
  23. package/dist/http-probe/index.d.ts +2 -0
  24. package/dist/http-probe/index.js +2 -0
  25. package/dist/index.d.ts +0 -6
  26. package/dist/index.js +0 -7
  27. package/dist/lib/inspect-cache.d.ts +10 -0
  28. package/dist/lib/inspect-cache.js +75 -0
  29. package/dist/lib/next-steps.d.ts +27 -0
  30. package/dist/lib/next-steps.js +21 -0
  31. package/dist/matcher/ast-eval.d.ts +8 -0
  32. package/dist/matcher/ast-eval.js +95 -0
  33. package/dist/matcher/finding.d.ts +55 -0
  34. package/dist/matcher/finding.js +1 -0
  35. package/dist/matcher/index.d.ts +8 -0
  36. package/dist/matcher/index.js +202 -0
  37. package/dist/matcher/inference-candidates.d.ts +26 -0
  38. package/dist/matcher/inference-candidates.js +81 -0
  39. package/dist/matcher/walker.d.ts +7 -0
  40. package/dist/matcher/walker.js +71 -0
  41. package/dist/pattern-pack/index.d.ts +125 -0
  42. package/dist/pattern-pack/index.js +189 -0
  43. package/dist/pattern-packs/zivis-public-0.2.0/capsules/agents/privilege-separation.yaml +224 -0
  44. package/dist/pattern-packs/zivis-public-0.2.0/capsules/prompting/self-consistency-no-isolation.yaml +237 -0
  45. package/dist/pattern-packs/zivis-public-0.2.0/capsules/retrieval/context-injection-no-validator.yaml +348 -0
  46. package/dist/pattern-packs/zivis-public-0.2.0/capsules/security/late-org-filter.yaml +266 -0
  47. package/dist/pattern-packs/zivis-public-0.2.0/controls/external_validator_on_facts.yaml +37 -0
  48. package/dist/pattern-packs/zivis-public-0.2.0/controls/fact_validator_present.yaml +68 -0
  49. package/dist/pattern-packs/zivis-public-0.2.0/controls/human_approval_gate.yaml +44 -0
  50. package/dist/pattern-packs/zivis-public-0.2.0/controls/langgraph_state_machine_with_per_node_tools.yaml +35 -0
  51. package/dist/pattern-packs/zivis-public-0.2.0/controls/per_sample_retrieval_diversification.yaml +38 -0
  52. package/dist/pattern-packs/zivis-public-0.2.0/controls/prisma_extension_or_middleware_attaching_org_filter.yaml +31 -0
  53. package/dist/pattern-packs/zivis-public-0.2.0/controls/row_level_security_policy.yaml +37 -0
  54. package/dist/pattern-packs/zivis-public-0.2.0/controls/source_attribution_present.yaml +58 -0
  55. package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +167 -0
  56. package/dist/pattern-packs/zivis-public-0.2.0/prompts/agents/privilege-separation/identify.md +54 -0
  57. package/dist/pattern-packs/zivis-public-0.2.0/prompts/prompting/self-consistency-no-isolation/identify.md +60 -0
  58. package/dist/pattern-packs/zivis-public-0.2.0/prompts/retrieval/context-injection-no-validator/identify.md +109 -0
  59. package/dist/pattern-packs/zivis-public-0.2.0/prompts/security/late-org-filter/identify.md +78 -0
  60. package/dist/project-binding.d.ts +2 -19
  61. package/dist/project-binding.js +38 -21
  62. package/dist/prompts/audit-dependencies.d.ts +2 -0
  63. package/dist/prompts/audit-dependencies.js +47 -0
  64. package/dist/prompts/getting-started.d.ts +2 -0
  65. package/dist/prompts/getting-started.js +37 -0
  66. package/dist/prompts/index.d.ts +2 -0
  67. package/dist/prompts/index.js +6 -0
  68. package/dist/redact.d.ts +30 -0
  69. package/dist/redact.js +164 -0
  70. package/dist/resolve-application-id.d.ts +0 -4
  71. package/dist/resolve-application-id.js +0 -5
  72. package/dist/sanitize.d.ts +1 -21
  73. package/dist/sanitize.js +7 -41
  74. package/dist/scanners/index.d.ts +3 -0
  75. package/dist/scanners/index.js +2 -0
  76. package/dist/scanners/normalize.d.ts +6 -0
  77. package/dist/scanners/normalize.js +181 -0
  78. package/dist/scanners/run.d.ts +27 -0
  79. package/dist/scanners/run.js +142 -0
  80. package/dist/scanners/types.d.ts +40 -0
  81. package/dist/scanners/types.js +1 -0
  82. package/dist/server.d.ts +1 -13
  83. package/dist/server.js +142 -265
  84. package/dist/tools/artifacts.d.ts +76 -0
  85. package/dist/tools/artifacts.js +178 -0
  86. package/dist/tools/check-project.d.ts +5 -18
  87. package/dist/tools/check-project.js +122 -110
  88. package/dist/tools/check-repo-trust.d.ts +4 -19
  89. package/dist/tools/check-repo-trust.js +56 -47
  90. package/dist/tools/create-diagram.d.ts +0 -5
  91. package/dist/tools/create-diagram.js +0 -10
  92. package/dist/tools/create-document.d.ts +0 -5
  93. package/dist/tools/create-document.js +3 -9
  94. package/dist/tools/create-finding.d.ts +85 -0
  95. package/dist/tools/create-finding.js +136 -0
  96. package/dist/tools/delete-finding.d.ts +19 -0
  97. package/dist/tools/delete-finding.js +36 -0
  98. package/dist/tools/devx-run.d.ts +88 -0
  99. package/dist/tools/devx-run.js +175 -0
  100. package/dist/tools/discover-local-infra.d.ts +0 -10
  101. package/dist/tools/discover-local-infra.js +3 -73
  102. package/dist/tools/enterprise/get-org-zat.d.ts +0 -5
  103. package/dist/tools/enterprise/get-org-zat.js +0 -6
  104. package/dist/tools/explain-signal-for-diff.d.ts +34 -0
  105. package/dist/tools/explain-signal-for-diff.js +75 -0
  106. package/dist/tools/generate-diagram.d.ts +0 -6
  107. package/dist/tools/generate-diagram.js +21 -13
  108. package/dist/tools/get-application-overview.d.ts +0 -5
  109. package/dist/tools/get-application-overview.js +0 -6
  110. package/dist/tools/get-application.d.ts +0 -5
  111. package/dist/tools/get-application.js +0 -6
  112. package/dist/tools/get-diagram.d.ts +0 -5
  113. package/dist/tools/get-diagram.js +1 -11
  114. package/dist/tools/get-document.d.ts +0 -5
  115. package/dist/tools/get-document.js +0 -6
  116. package/dist/tools/get-oss-zat.d.ts +0 -5
  117. package/dist/tools/get-oss-zat.js +0 -7
  118. package/dist/tools/get-signal.d.ts +24 -0
  119. package/dist/tools/get-signal.js +75 -0
  120. package/dist/tools/get-started.d.ts +18 -0
  121. package/dist/tools/get-started.js +470 -0
  122. package/dist/tools/get-trust-keys.d.ts +0 -5
  123. package/dist/tools/get-trust-keys.js +0 -6
  124. package/dist/tools/import-openapi-endpoints.d.ts +0 -5
  125. package/dist/tools/import-openapi-endpoints.js +0 -6
  126. package/dist/tools/inspect-zat.d.ts +0 -5
  127. package/dist/tools/inspect-zat.js +0 -19
  128. package/dist/tools/inspect.d.ts +21 -0
  129. package/dist/tools/inspect.js +222 -0
  130. package/dist/tools/list-applications.d.ts +1 -6
  131. package/dist/tools/list-applications.js +0 -6
  132. package/dist/tools/list-diagrams.d.ts +0 -5
  133. package/dist/tools/list-diagrams.js +0 -6
  134. package/dist/tools/list-documents.d.ts +0 -5
  135. package/dist/tools/list-documents.js +0 -6
  136. package/dist/tools/list-endpoints.d.ts +1 -6
  137. package/dist/tools/list-endpoints.js +0 -6
  138. package/dist/tools/list-signals.d.ts +37 -0
  139. package/dist/tools/list-signals.js +83 -0
  140. package/dist/tools/manage-application.d.ts +64 -0
  141. package/dist/tools/manage-application.js +129 -0
  142. package/dist/tools/manage-diagram.d.ts +0 -5
  143. package/dist/tools/manage-diagram.js +0 -16
  144. package/dist/tools/manage-endpoint-lifecycle.d.ts +80 -0
  145. package/dist/tools/manage-endpoint-lifecycle.js +180 -0
  146. package/dist/tools/open-in-ide.d.ts +2 -14
  147. package/dist/tools/open-in-ide.js +0 -13
  148. package/dist/tools/review-change.d.ts +34 -0
  149. package/dist/tools/review-change.js +93 -0
  150. package/dist/tools/security-memory.d.ts +76 -0
  151. package/dist/tools/security-memory.js +202 -0
  152. package/dist/tools/security-review.d.ts +1 -21
  153. package/dist/tools/security-review.js +8 -108
  154. package/dist/tools/threat-get-capsule.d.ts +15 -0
  155. package/dist/tools/threat-get-capsule.js +53 -0
  156. package/dist/tools/threat-get-inference-prompt.d.ts +15 -0
  157. package/dist/tools/threat-get-inference-prompt.js +73 -0
  158. package/dist/tools/threat-list-relevant-capsules.d.ts +17 -0
  159. package/dist/tools/threat-list-relevant-capsules.js +158 -0
  160. package/dist/tools/threat-run-matcher.d.ts +17 -0
  161. package/dist/tools/threat-run-matcher.js +145 -0
  162. package/dist/tools/update-document.d.ts +0 -5
  163. package/dist/tools/update-document.js +3 -9
  164. package/dist/tools/update-endpoint.d.ts +1 -6
  165. package/dist/tools/update-endpoint.js +0 -7
  166. package/dist/tools/update-finding.d.ts +61 -0
  167. package/dist/tools/update-finding.js +80 -0
  168. package/dist/tools/update-mermaid-source.d.ts +0 -13
  169. package/dist/tools/update-mermaid-source.js +0 -14
  170. package/dist/tools/verify-trust-mark.d.ts +0 -5
  171. package/dist/tools/verify-trust-mark.js +0 -6
  172. package/dist/types.d.ts +14 -14
  173. package/dist/types.js +22 -28
  174. package/package.json +41 -15
  175. package/dist/api-client.js.map +0 -1
  176. package/dist/auth/index.js.map +0 -1
  177. package/dist/auth/jwt.js.map +0 -1
  178. package/dist/auth/keychain.js.map +0 -1
  179. package/dist/auth/oauth.js.map +0 -1
  180. package/dist/auth/sessions.js.map +0 -1
  181. package/dist/auth/token-refresh.js.map +0 -1
  182. package/dist/cli.js.map +0 -1
  183. package/dist/index.js.map +0 -1
  184. package/dist/project-binding.js.map +0 -1
  185. package/dist/resolve-application-id.js.map +0 -1
  186. package/dist/sanitize.js.map +0 -1
  187. package/dist/server.js.map +0 -1
  188. package/dist/tools/check-project.js.map +0 -1
  189. package/dist/tools/check-repo-trust.js.map +0 -1
  190. package/dist/tools/create-diagram.js.map +0 -1
  191. package/dist/tools/create-document.js.map +0 -1
  192. package/dist/tools/discover-local-infra.js.map +0 -1
  193. package/dist/tools/enterprise/capture-evidence.d.ts +0 -54
  194. package/dist/tools/enterprise/capture-evidence.js +0 -72
  195. package/dist/tools/enterprise/capture-evidence.js.map +0 -1
  196. package/dist/tools/enterprise/create-report-ticket.d.ts +0 -34
  197. package/dist/tools/enterprise/create-report-ticket.js +0 -44
  198. package/dist/tools/enterprise/create-report-ticket.js.map +0 -1
  199. package/dist/tools/enterprise/end-pentest-session.d.ts +0 -33
  200. package/dist/tools/enterprise/end-pentest-session.js +0 -42
  201. package/dist/tools/enterprise/end-pentest-session.js.map +0 -1
  202. package/dist/tools/enterprise/generate-report.d.ts +0 -55
  203. package/dist/tools/enterprise/generate-report.js +0 -111
  204. package/dist/tools/enterprise/generate-report.js.map +0 -1
  205. package/dist/tools/enterprise/get-org-zat.js.map +0 -1
  206. package/dist/tools/enterprise/get-report-status.d.ts +0 -27
  207. package/dist/tools/enterprise/get-report-status.js +0 -38
  208. package/dist/tools/enterprise/get-report-status.js.map +0 -1
  209. package/dist/tools/enterprise/get-threat-model.d.ts +0 -29
  210. package/dist/tools/enterprise/get-threat-model.js +0 -83
  211. package/dist/tools/enterprise/get-threat-model.js.map +0 -1
  212. package/dist/tools/enterprise/list-agents.d.ts +0 -42
  213. package/dist/tools/enterprise/list-agents.js +0 -95
  214. package/dist/tools/enterprise/list-agents.js.map +0 -1
  215. package/dist/tools/enterprise/list-report-issues.d.ts +0 -36
  216. package/dist/tools/enterprise/list-report-issues.js +0 -50
  217. package/dist/tools/enterprise/list-report-issues.js.map +0 -1
  218. package/dist/tools/enterprise/list-threat-models.d.ts +0 -36
  219. package/dist/tools/enterprise/list-threat-models.js +0 -82
  220. package/dist/tools/enterprise/list-threat-models.js.map +0 -1
  221. package/dist/tools/enterprise/manage-actor.d.ts +0 -58
  222. package/dist/tools/enterprise/manage-actor.js +0 -99
  223. package/dist/tools/enterprise/manage-actor.js.map +0 -1
  224. package/dist/tools/enterprise/manage-attack-scenario.d.ts +0 -70
  225. package/dist/tools/enterprise/manage-attack-scenario.js +0 -89
  226. package/dist/tools/enterprise/manage-attack-scenario.js.map +0 -1
  227. package/dist/tools/enterprise/manage-component.d.ts +0 -58
  228. package/dist/tools/enterprise/manage-component.js +0 -90
  229. package/dist/tools/enterprise/manage-component.js.map +0 -1
  230. package/dist/tools/enterprise/manage-data-asset.d.ts +0 -53
  231. package/dist/tools/enterprise/manage-data-asset.js +0 -90
  232. package/dist/tools/enterprise/manage-data-asset.js.map +0 -1
  233. package/dist/tools/enterprise/manage-data-flow.d.ts +0 -57
  234. package/dist/tools/enterprise/manage-data-flow.js +0 -98
  235. package/dist/tools/enterprise/manage-data-flow.js.map +0 -1
  236. package/dist/tools/enterprise/manage-finding.d.ts +0 -69
  237. package/dist/tools/enterprise/manage-finding.js +0 -106
  238. package/dist/tools/enterprise/manage-finding.js.map +0 -1
  239. package/dist/tools/enterprise/manage-security-control.d.ts +0 -59
  240. package/dist/tools/enterprise/manage-security-control.js +0 -96
  241. package/dist/tools/enterprise/manage-security-control.js.map +0 -1
  242. package/dist/tools/enterprise/manage-test-case.d.ts +0 -88
  243. package/dist/tools/enterprise/manage-test-case.js +0 -119
  244. package/dist/tools/enterprise/manage-test-case.js.map +0 -1
  245. package/dist/tools/enterprise/promote-finding-to-issue.d.ts +0 -36
  246. package/dist/tools/enterprise/promote-finding-to-issue.js +0 -65
  247. package/dist/tools/enterprise/promote-finding-to-issue.js.map +0 -1
  248. package/dist/tools/enterprise/publish-report-version.d.ts +0 -34
  249. package/dist/tools/enterprise/publish-report-version.js +0 -75
  250. package/dist/tools/enterprise/publish-report-version.js.map +0 -1
  251. package/dist/tools/enterprise/publish-test-to-library.d.ts +0 -31
  252. package/dist/tools/enterprise/publish-test-to-library.js +0 -40
  253. package/dist/tools/enterprise/publish-test-to-library.js.map +0 -1
  254. package/dist/tools/enterprise/record-test-result.d.ts +0 -67
  255. package/dist/tools/enterprise/record-test-result.js +0 -75
  256. package/dist/tools/enterprise/record-test-result.js.map +0 -1
  257. package/dist/tools/enterprise/start-pentest-session.d.ts +0 -35
  258. package/dist/tools/enterprise/start-pentest-session.js +0 -50
  259. package/dist/tools/enterprise/start-pentest-session.js.map +0 -1
  260. package/dist/tools/enterprise/sync-report-section.d.ts +0 -41
  261. package/dist/tools/enterprise/sync-report-section.js +0 -79
  262. package/dist/tools/enterprise/sync-report-section.js.map +0 -1
  263. package/dist/tools/enterprise/update-report-issue.d.ts +0 -55
  264. package/dist/tools/enterprise/update-report-issue.js +0 -69
  265. package/dist/tools/enterprise/update-report-issue.js.map +0 -1
  266. package/dist/tools/generate-diagram.js.map +0 -1
  267. package/dist/tools/get-agent-test-results.d.ts +0 -41
  268. package/dist/tools/get-agent-test-results.js +0 -86
  269. package/dist/tools/get-agent-test-results.js.map +0 -1
  270. package/dist/tools/get-application-overview.js.map +0 -1
  271. package/dist/tools/get-application.js.map +0 -1
  272. package/dist/tools/get-artifact-content.d.ts +0 -29
  273. package/dist/tools/get-artifact-content.js +0 -86
  274. package/dist/tools/get-artifact-content.js.map +0 -1
  275. package/dist/tools/get-diagram.js.map +0 -1
  276. package/dist/tools/get-document.js.map +0 -1
  277. package/dist/tools/get-finding-details.d.ts +0 -28
  278. package/dist/tools/get-finding-details.js +0 -43
  279. package/dist/tools/get-finding-details.js.map +0 -1
  280. package/dist/tools/get-findings.d.ts +0 -57
  281. package/dist/tools/get-findings.js +0 -103
  282. package/dist/tools/get-findings.js.map +0 -1
  283. package/dist/tools/get-oss-zat.js.map +0 -1
  284. package/dist/tools/get-recon-scan.d.ts +0 -27
  285. package/dist/tools/get-recon-scan.js +0 -46
  286. package/dist/tools/get-recon-scan.js.map +0 -1
  287. package/dist/tools/get-scan-output.d.ts +0 -27
  288. package/dist/tools/get-scan-output.js +0 -64
  289. package/dist/tools/get-scan-output.js.map +0 -1
  290. package/dist/tools/get-scenario-details.d.ts +0 -27
  291. package/dist/tools/get-scenario-details.js +0 -46
  292. package/dist/tools/get-scenario-details.js.map +0 -1
  293. package/dist/tools/get-test-case-results.d.ts +0 -37
  294. package/dist/tools/get-test-case-results.js +0 -66
  295. package/dist/tools/get-test-case-results.js.map +0 -1
  296. package/dist/tools/get-test-details.d.ts +0 -29
  297. package/dist/tools/get-test-details.js +0 -49
  298. package/dist/tools/get-test-details.js.map +0 -1
  299. package/dist/tools/get-trust-keys.js.map +0 -1
  300. package/dist/tools/import-openapi-endpoints.js.map +0 -1
  301. package/dist/tools/inspect-zat.js.map +0 -1
  302. package/dist/tools/list-agent-test-cases.d.ts +0 -41
  303. package/dist/tools/list-agent-test-cases.js +0 -73
  304. package/dist/tools/list-agent-test-cases.js.map +0 -1
  305. package/dist/tools/list-applications.js.map +0 -1
  306. package/dist/tools/list-diagrams.js.map +0 -1
  307. package/dist/tools/list-documents.js.map +0 -1
  308. package/dist/tools/list-endpoints.js.map +0 -1
  309. package/dist/tools/list-recon-scans.d.ts +0 -36
  310. package/dist/tools/list-recon-scans.js +0 -74
  311. package/dist/tools/list-recon-scans.js.map +0 -1
  312. package/dist/tools/list-scan-artifacts.d.ts +0 -41
  313. package/dist/tools/list-scan-artifacts.js +0 -63
  314. package/dist/tools/list-scan-artifacts.js.map +0 -1
  315. package/dist/tools/list-scans.d.ts +0 -44
  316. package/dist/tools/list-scans.js +0 -91
  317. package/dist/tools/list-scans.js.map +0 -1
  318. package/dist/tools/list-test-library.d.ts +0 -44
  319. package/dist/tools/list-test-library.js +0 -83
  320. package/dist/tools/list-test-library.js.map +0 -1
  321. package/dist/tools/list-test-scenarios.d.ts +0 -31
  322. package/dist/tools/list-test-scenarios.js +0 -66
  323. package/dist/tools/list-test-scenarios.js.map +0 -1
  324. package/dist/tools/local-scan.d.ts +0 -40
  325. package/dist/tools/local-scan.js +0 -261
  326. package/dist/tools/local-scan.js.map +0 -1
  327. package/dist/tools/manage-diagram.js.map +0 -1
  328. package/dist/tools/open-in-ide.js.map +0 -1
  329. package/dist/tools/run-test-scenario.d.ts +0 -37
  330. package/dist/tools/run-test-scenario.js +0 -70
  331. package/dist/tools/run-test-scenario.js.map +0 -1
  332. package/dist/tools/scan-pr.d.ts +0 -27
  333. package/dist/tools/scan-pr.js +0 -51
  334. package/dist/tools/scan-pr.js.map +0 -1
  335. package/dist/tools/security-review.js.map +0 -1
  336. package/dist/tools/setup-red-team-target.d.ts +0 -79
  337. package/dist/tools/setup-red-team-target.js +0 -430
  338. package/dist/tools/setup-red-team-target.js.map +0 -1
  339. package/dist/tools/triage-finding.d.ts +0 -47
  340. package/dist/tools/triage-finding.js +0 -116
  341. package/dist/tools/triage-finding.js.map +0 -1
  342. package/dist/tools/update-document.js.map +0 -1
  343. package/dist/tools/update-endpoint.js.map +0 -1
  344. package/dist/tools/update-mermaid-source.js.map +0 -1
  345. package/dist/tools/verify-trust-mark.js.map +0 -1
  346. package/dist/types.js.map +0 -1
@@ -0,0 +1,202 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as fssync from "node:fs";
3
+ import { loadActivePack, findRelevantCapsules, getControl, } from "../pattern-pack/index.js";
4
+ import { walkLanguageFiles } from "./walker.js";
5
+ import { evaluateAstStrategy } from "./ast-eval.js";
6
+ const SUPPORTED_AST_LANGS = new Set([
7
+ "typescript",
8
+ "javascript",
9
+ "python",
10
+ "go",
11
+ ]);
12
+ export async function runMatcher(opts) {
13
+ const startedAt = Date.now();
14
+ const handle = await loadActivePack(opts.packId);
15
+ const artifact = await readArtifact(opts.artifactPath);
16
+ const relevant = await findRelevantCapsules(handle, artifact);
17
+ const langsNeeded = collectAstLanguagesNeeded(relevant);
18
+ const walked = langsNeeded.length > 0
19
+ ? await walkLanguageFiles(opts.cwd, langsNeeded)
20
+ : { filesByLanguage: new Map(), filesScanned: 0, filesSkipped: 0 };
21
+ const controlPresence = await evaluateAllControls(handle, opts.cwd, walked.filesByLanguage);
22
+ const findings = [];
23
+ for (const cap of relevant) {
24
+ const finding = await evaluateCapsule(cap, opts.cwd, walked.filesByLanguage, controlPresence);
25
+ if (finding)
26
+ findings.push(finding);
27
+ }
28
+ const summary = {
29
+ trusted_count: findings.filter((f) => f.lane === "trusted").length,
30
+ inferred_count: findings.filter((f) => f.lane === "inferred").length,
31
+ total: findings.length,
32
+ };
33
+ return {
34
+ pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
35
+ artifact_path: opts.artifactPath,
36
+ cwd: opts.cwd,
37
+ capsules_relevant: relevant.length,
38
+ capsules_evaluated: relevant.length,
39
+ ast_files_scanned: walked.filesScanned,
40
+ duration_ms: Date.now() - startedAt,
41
+ summary,
42
+ findings,
43
+ };
44
+ }
45
+ async function evaluateCapsule(cap, cwd, filesByLanguage, controlPresence) {
46
+ const strategies = (cap.strategies ?? []);
47
+ const fired = [];
48
+ const evidence = [];
49
+ let inferenceCandidate;
50
+ for (const strategy of strategies) {
51
+ const code = strategy.code;
52
+ const trusted = strategy.trusted !== false && code !== "INFER" && code !== "SEM" && code !== "REGEX";
53
+ if (code === "AST") {
54
+ const lang = (strategy.language ?? "").toLowerCase();
55
+ if (!SUPPORTED_AST_LANGS.has(lang)) {
56
+ fired.push({ code, language: lang, trusted, confidence_weight: strategy.confidence_weight, match_count: 0 });
57
+ continue;
58
+ }
59
+ const files = filesByLanguage.get(lang) ?? [];
60
+ if (files.length === 0) {
61
+ fired.push({ code, language: lang, trusted, confidence_weight: strategy.confidence_weight, match_count: 0 });
62
+ continue;
63
+ }
64
+ const matches = await evaluateAstStrategy(strategy.expression, lang, files, cwd);
65
+ fired.push({
66
+ code,
67
+ language: lang,
68
+ trusted,
69
+ confidence_weight: strategy.confidence_weight,
70
+ match_count: matches.length,
71
+ });
72
+ for (const m of matches) {
73
+ evidence.push({
74
+ file: m.file,
75
+ start_line: m.start_line,
76
+ end_line: m.end_line,
77
+ matched_text: m.matched_text,
78
+ strategy_code: code,
79
+ });
80
+ }
81
+ }
82
+ else if (code === "META") {
83
+ const result = evaluateMetaStrategy(strategy.expression, controlPresence);
84
+ fired.push({
85
+ code,
86
+ trusted,
87
+ confidence_weight: strategy.confidence_weight,
88
+ match_count: result.fired ? 1 : 0,
89
+ });
90
+ if (result.fired) {
91
+ evidence.push({
92
+ file: "(synthetic)",
93
+ start_line: 0,
94
+ matched_text: `META: none_of_controls satisfied; absent: [${result.absent.join(", ")}]`,
95
+ strategy_code: code,
96
+ });
97
+ }
98
+ }
99
+ else if (code === "INFER") {
100
+ if (cap.model_task_prompt_ref) {
101
+ inferenceCandidate = {
102
+ prompt_ref: cap.model_task_prompt_ref,
103
+ expected_output_schema: cap.expected_output_schema,
104
+ minimum_context_required: cap.minimum_context_required,
105
+ reason: "Capsule has an INFER strategy. Use zivis_threat_get_inference_prompt to retrieve the prompt bundle, gather the indicated code spans, and run the inference in your model.",
106
+ };
107
+ }
108
+ fired.push({ code, trusted: false, confidence_weight: strategy.confidence_weight, match_count: 1 });
109
+ }
110
+ else {
111
+ fired.push({ code, trusted, confidence_weight: strategy.confidence_weight, match_count: 0 });
112
+ }
113
+ }
114
+ const anyFired = fired.some((f) => f.match_count > 0);
115
+ if (!anyFired)
116
+ return undefined;
117
+ const trustedFired = fired.filter((f) => f.trusted && f.match_count > 0).length;
118
+ const requiredCount = cap.required_evidence_count ?? 1;
119
+ const lane = trustedFired >= requiredCount ? "trusted" : "inferred";
120
+ const confidence = Math.min(1, fired.reduce((acc, f) => (f.match_count > 0 ? acc + f.confidence_weight : acc), 0));
121
+ return {
122
+ pattern_id: cap.id,
123
+ pattern_version: cap.version,
124
+ lane,
125
+ confidence,
126
+ fired_strategies: fired,
127
+ evidence,
128
+ inference_candidate: inferenceCandidate,
129
+ safe_summary: cap.safe_summary,
130
+ threats: cap.threats,
131
+ repair_contract: cap.repair_contract,
132
+ };
133
+ }
134
+ async function readArtifact(p) {
135
+ if (!fssync.existsSync(p)) {
136
+ throw new Error(`Artifact not found: ${p}`);
137
+ }
138
+ const raw = await fs.readFile(p, "utf8");
139
+ return JSON.parse(raw);
140
+ }
141
+ function collectAstLanguagesNeeded(capsules) {
142
+ const set = new Set();
143
+ for (const cap of capsules) {
144
+ for (const strategy of cap.strategies) {
145
+ if (strategy.code !== "AST")
146
+ continue;
147
+ const lang = (strategy.language ?? "").toLowerCase();
148
+ if (SUPPORTED_AST_LANGS.has(lang))
149
+ set.add(lang);
150
+ }
151
+ }
152
+ set.add("typescript");
153
+ set.add("python");
154
+ return [...set];
155
+ }
156
+ function evaluateMetaStrategy(expression, presence) {
157
+ const expr = expression;
158
+ if (!expr || typeof expr !== "object")
159
+ return { fired: false, absent: [] };
160
+ if (expr.none_of_controls && expr.none_of_controls.length > 0) {
161
+ const checkable = expr.none_of_controls.filter((id) => presence.get(id)?.checkable);
162
+ if (checkable.length === 0)
163
+ return { fired: false, absent: [] };
164
+ const absent = checkable.filter((id) => !presence.get(id).present);
165
+ if (absent.length === checkable.length) {
166
+ return { fired: true, absent };
167
+ }
168
+ return { fired: false, absent };
169
+ }
170
+ return { fired: false, absent: [] };
171
+ }
172
+ async function evaluateAllControls(handle, cwd, filesByLanguage) {
173
+ const out = new Map();
174
+ const controlEntries = handle.manifest.controls ?? [];
175
+ for (const entry of controlEntries) {
176
+ let control;
177
+ try {
178
+ control = await getControl(handle, entry.id);
179
+ }
180
+ catch {
181
+ continue;
182
+ }
183
+ let present = false;
184
+ let checkable = false;
185
+ for (const det of control.detection ?? []) {
186
+ const lang = det.language;
187
+ if (!SUPPORTED_AST_LANGS.has(lang))
188
+ continue;
189
+ const files = filesByLanguage.get(lang) ?? [];
190
+ if (files.length === 0)
191
+ continue;
192
+ checkable = true;
193
+ const matches = await evaluateAstStrategy(det.rule, lang, files, cwd);
194
+ if (matches.length > 0) {
195
+ present = true;
196
+ break;
197
+ }
198
+ }
199
+ out.set(control.id, { present, checkable });
200
+ }
201
+ return out;
202
+ }
@@ -0,0 +1,26 @@
1
+ import { type Capsule } from "../pattern-pack/index.js";
2
+ import type { Finding } from "./finding.js";
3
+ export interface BundledInferenceCandidate {
4
+ candidate_id: string;
5
+ capsule_id: string;
6
+ capsule_version: string;
7
+ pattern_title?: string;
8
+ prompt: string;
9
+ expected_output_schema: unknown;
10
+ evidence_focus: Array<{
11
+ file: string;
12
+ start_line: number;
13
+ end_line?: number;
14
+ note?: string;
15
+ }>;
16
+ minimum_context_required?: {
17
+ lines?: number;
18
+ symbols?: string[];
19
+ };
20
+ instructions_for_host: string;
21
+ }
22
+ export interface InferenceBundle {
23
+ inference_candidates: BundledInferenceCandidate[];
24
+ host_required_action: string;
25
+ }
26
+ export declare function buildInferenceBundle(findings: Finding[], capsuleByPatternId?: Map<string, Capsule>): Promise<InferenceBundle>;
@@ -0,0 +1,81 @@
1
+ import { loadActivePack, getInferencePrompt, } from "../pattern-pack/index.js";
2
+ export async function buildInferenceBundle(findings, capsuleByPatternId) {
3
+ const candidates = [];
4
+ let handle;
5
+ for (let i = 0; i < findings.length; i++) {
6
+ const f = findings[i];
7
+ if (!f.inference_candidate)
8
+ continue;
9
+ if (!handle) {
10
+ try {
11
+ handle = await loadActivePack();
12
+ }
13
+ catch {
14
+ candidates.push(toFallbackCandidate(f, i));
15
+ continue;
16
+ }
17
+ }
18
+ let promptText;
19
+ try {
20
+ promptText = await getInferencePrompt(handle, f.inference_candidate.prompt_ref);
21
+ }
22
+ catch {
23
+ candidates.push(toFallbackCandidate(f, i));
24
+ continue;
25
+ }
26
+ const cap = capsuleByPatternId?.get(f.pattern_id);
27
+ candidates.push({
28
+ candidate_id: `ic-${i + 1}`,
29
+ capsule_id: f.pattern_id,
30
+ capsule_version: f.pattern_version,
31
+ pattern_title: cap?.title,
32
+ prompt: promptText,
33
+ expected_output_schema: f.inference_candidate.expected_output_schema ?? null,
34
+ evidence_focus: f.evidence
35
+ .filter((e) => e.file !== "(synthetic)")
36
+ .map((e) => ({
37
+ file: e.file,
38
+ start_line: e.start_line,
39
+ end_line: e.end_line,
40
+ note: e.matched_text ? e.matched_text.slice(0, 200) : undefined,
41
+ })),
42
+ minimum_context_required: f.inference_candidate.minimum_context_required,
43
+ instructions_for_host: "Read the source code at each evidence_focus[*].file:start_line — pull at least minimum_context_required.lines around each span. " +
44
+ "Attach those snippets to the prompt above. Run the prompt against your model. " +
45
+ "Return JSON matching expected_output_schema. The output enters the inferred lane.",
46
+ });
47
+ }
48
+ const action = buildHostRequiredAction(candidates);
49
+ return { inference_candidates: candidates, host_required_action: action };
50
+ }
51
+ function toFallbackCandidate(f, i) {
52
+ return {
53
+ candidate_id: `ic-${i + 1}`,
54
+ capsule_id: f.pattern_id,
55
+ capsule_version: f.pattern_version,
56
+ prompt: "",
57
+ expected_output_schema: f.inference_candidate?.expected_output_schema ?? null,
58
+ evidence_focus: f.evidence
59
+ .filter((e) => e.file !== "(synthetic)")
60
+ .map((e) => ({
61
+ file: e.file,
62
+ start_line: e.start_line,
63
+ end_line: e.end_line,
64
+ })),
65
+ minimum_context_required: f.inference_candidate?.minimum_context_required,
66
+ instructions_for_host: "Inline prompt unavailable. Call zivis_threat_get_inference_prompt with capsule_id=" +
67
+ f.pattern_id +
68
+ " to retrieve it.",
69
+ };
70
+ }
71
+ function buildHostRequiredAction(candidates) {
72
+ if (candidates.length === 0) {
73
+ return "No inference candidates emitted by this run. Findings are deterministic-only.";
74
+ }
75
+ return (`MANDATORY HOST ACTION: For each of the ${candidates.length} inference_candidate${candidates.length === 1 ? "" : "s"} below, ` +
76
+ `you MUST: (1) read the source code at evidence_focus[*].file:start_line (open each file, grab at least minimum_context_required.lines of surrounding context), ` +
77
+ `(2) run the candidate's prompt against your model with that source attached, ` +
78
+ `(3) produce JSON output matching expected_output_schema. ` +
79
+ `Do this BEFORE summarizing findings to the user — the inferred-lane verdict from your inference is what the user actually wants. ` +
80
+ `Each candidate is a self-contained inference task; you do not need to call any other ZIVIS tool to execute it.`);
81
+ }
@@ -0,0 +1,7 @@
1
+ export type WalkLanguage = "typescript" | "javascript" | "python" | "go";
2
+ export interface WalkResult {
3
+ filesByLanguage: Map<WalkLanguage, string[]>;
4
+ filesScanned: number;
5
+ filesSkipped: number;
6
+ }
7
+ export declare function walkLanguageFiles(rootDir: string, languages: WalkLanguage[]): Promise<WalkResult>;
@@ -0,0 +1,71 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ const HARD_SKIP_DIRS = new Set([
4
+ "node_modules",
5
+ ".git",
6
+ ".yarn",
7
+ ".pnpm",
8
+ "dist",
9
+ "build",
10
+ "out",
11
+ ".next",
12
+ ".nuxt",
13
+ ".turbo",
14
+ ".cache",
15
+ "coverage",
16
+ "vendor",
17
+ "__pycache__",
18
+ ".venv",
19
+ "target",
20
+ ]);
21
+ const MAX_FILES = 50_000;
22
+ const LANG_EXTENSIONS = {
23
+ typescript: [".ts", ".tsx"],
24
+ javascript: [".js", ".jsx", ".mjs", ".cjs"],
25
+ python: [".py"],
26
+ go: [".go"],
27
+ };
28
+ export async function walkLanguageFiles(rootDir, languages) {
29
+ const extToLang = new Map();
30
+ for (const lang of languages) {
31
+ for (const ext of LANG_EXTENSIONS[lang])
32
+ extToLang.set(ext, lang);
33
+ }
34
+ const filesByLanguage = new Map();
35
+ for (const lang of languages)
36
+ filesByLanguage.set(lang, []);
37
+ let filesScanned = 0;
38
+ let filesSkipped = 0;
39
+ const total = () => Array.from(filesByLanguage.values()).reduce((n, l) => n + l.length, 0);
40
+ async function visit(dirAbs) {
41
+ if (total() >= MAX_FILES)
42
+ return;
43
+ let entries;
44
+ try {
45
+ entries = await fs.readdir(dirAbs, { withFileTypes: true });
46
+ }
47
+ catch {
48
+ return;
49
+ }
50
+ for (const entry of entries) {
51
+ if (entry.isDirectory()) {
52
+ if (HARD_SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) {
53
+ filesSkipped++;
54
+ continue;
55
+ }
56
+ await visit(path.join(dirAbs, entry.name));
57
+ continue;
58
+ }
59
+ if (!entry.isFile() && !entry.isSymbolicLink())
60
+ continue;
61
+ filesScanned++;
62
+ const ext = path.extname(entry.name).toLowerCase();
63
+ const lang = extToLang.get(ext);
64
+ if (lang) {
65
+ filesByLanguage.get(lang).push(path.join(dirAbs, entry.name));
66
+ }
67
+ }
68
+ }
69
+ await visit(rootDir);
70
+ return { filesByLanguage, filesScanned, filesSkipped };
71
+ }
@@ -0,0 +1,125 @@
1
+ export interface PackManifest {
2
+ schema_version: "1.0.0";
3
+ pack_id: string;
4
+ pack_name: string;
5
+ version: string;
6
+ built_at: string;
7
+ tier: "public_teaser" | "public" | "customer_safe";
8
+ description?: string;
9
+ capsules: ManifestCapsuleEntry[];
10
+ prompts: ManifestPromptEntry[];
11
+ controls?: ManifestControlEntry[];
12
+ }
13
+ export interface ManifestCapsuleEntry {
14
+ id: string;
15
+ version: string;
16
+ path: string;
17
+ sha256: string;
18
+ category?: string;
19
+ lifecycle?: string;
20
+ applicable_languages?: string[];
21
+ }
22
+ export interface ManifestPromptEntry {
23
+ path: string;
24
+ sha256: string;
25
+ capsule_id?: string;
26
+ }
27
+ export interface ManifestControlEntry {
28
+ id: string;
29
+ path: string;
30
+ sha256: string;
31
+ applicable_languages?: string[];
32
+ }
33
+ export interface ControlDetectionRule {
34
+ language: "typescript" | "javascript" | "python" | "go";
35
+ rule: unknown;
36
+ }
37
+ export interface Control {
38
+ id: string;
39
+ description?: string;
40
+ applicable_languages: string[];
41
+ detection: ControlDetectionRule[];
42
+ lifecycle?: string;
43
+ owner?: string;
44
+ }
45
+ export interface RelevanceTerm {
46
+ dependency?: string;
47
+ direct_only?: boolean;
48
+ language?: string;
49
+ framework?: string;
50
+ evidence?: string;
51
+ }
52
+ export interface RelevanceFilter {
53
+ any_of?: RelevanceTerm[];
54
+ all_of?: RelevanceTerm[];
55
+ none_of?: RelevanceTerm[];
56
+ }
57
+ export interface Capsule {
58
+ id: string;
59
+ slug: string;
60
+ version: string;
61
+ category: string;
62
+ title?: string;
63
+ headline?: string;
64
+ description?: string;
65
+ detection_tier: "public" | "proprietary";
66
+ scoring_tier: "public" | "proprietary";
67
+ applicable_languages: string[];
68
+ relevance_filter?: RelevanceFilter;
69
+ strategies: unknown[];
70
+ required_evidence_count: number;
71
+ threats?: unknown[];
72
+ lifecycle: "draft" | "active" | "deprecated";
73
+ sensitivity_level?: "public_teaser" | "customer_safe" | "zivis_confidential";
74
+ safe_summary?: string;
75
+ detect_when?: string;
76
+ risk_hints?: string[];
77
+ architectural_signals?: string[];
78
+ model_task_prompt_ref?: string;
79
+ expected_output_schema?: unknown;
80
+ minimum_context_required?: {
81
+ lines?: number;
82
+ symbols?: string[];
83
+ };
84
+ related_patterns?: string[];
85
+ repair_contract?: {
86
+ allowed?: string[];
87
+ forbidden?: string[];
88
+ };
89
+ validation_contract?: {
90
+ requires_tests_pass?: boolean;
91
+ requires_static_rules?: string[];
92
+ };
93
+ }
94
+ export interface PackHandle {
95
+ manifest: PackManifest;
96
+ rootDir: string;
97
+ }
98
+ export interface GraphArtifactView {
99
+ scope: {
100
+ languages?: string[];
101
+ };
102
+ nodes: Array<{
103
+ type: string;
104
+ evidence: Array<{
105
+ kind: string;
106
+ }>;
107
+ attributes?: {
108
+ package?: string;
109
+ };
110
+ }>;
111
+ }
112
+ export declare function loadActivePack(packId?: string): Promise<PackHandle>;
113
+ export declare function getCapsule(handle: PackHandle, capsuleId: string): Promise<Capsule>;
114
+ export declare function getInferencePrompt(handle: PackHandle, ref: string): Promise<string>;
115
+ export declare function listCapsuleIds(handle: PackHandle): Promise<string[]>;
116
+ export declare function listControlIds(handle: PackHandle): Promise<string[]>;
117
+ export declare function getControl(handle: PackHandle, controlId: string): Promise<Control>;
118
+ export declare function findRelevantCapsules(handle: PackHandle, artifact: GraphArtifactView): Promise<Capsule[]>;
119
+ interface EvalContext {
120
+ packageNames: Set<string>;
121
+ languages: Set<string>;
122
+ evidenceKinds: Set<string>;
123
+ }
124
+ export declare function matchesRelevance(cap: Capsule, ctx: EvalContext): boolean;
125
+ export {};