@zivis/mcp 0.1.0-alpha.9 → 0.1.6

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 (328) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +19 -0
  3. package/dist/api-client.d.ts +1 -31
  4. package/dist/api-client.js +26 -66
  5. package/dist/auth/index.d.ts +1 -22
  6. package/dist/auth/index.js +15 -46
  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 +1 -42
  12. package/dist/auth/oauth.js +22 -64
  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 +12 -47
  17. package/dist/cli.d.ts +1 -18
  18. package/dist/cli.js +30 -908
  19. package/dist/index.d.ts +0 -6
  20. package/dist/index.js +0 -7
  21. package/dist/lib/inspect-cache.d.ts +10 -0
  22. package/dist/lib/inspect-cache.js +75 -0
  23. package/dist/lib/next-steps.d.ts +27 -0
  24. package/dist/lib/next-steps.js +21 -0
  25. package/dist/matcher/ast-eval.d.ts +8 -0
  26. package/dist/matcher/ast-eval.js +95 -0
  27. package/dist/matcher/finding.d.ts +55 -0
  28. package/dist/matcher/finding.js +1 -0
  29. package/dist/matcher/index.d.ts +8 -0
  30. package/dist/matcher/index.js +202 -0
  31. package/dist/matcher/inference-candidates.d.ts +26 -0
  32. package/dist/matcher/inference-candidates.js +81 -0
  33. package/dist/matcher/walker.d.ts +7 -0
  34. package/dist/matcher/walker.js +71 -0
  35. package/dist/pattern-pack/index.d.ts +125 -0
  36. package/dist/pattern-pack/index.js +189 -0
  37. package/dist/pattern-packs/zivis-public-0.2.0/capsules/agents/privilege-separation.yaml +224 -0
  38. package/dist/pattern-packs/zivis-public-0.2.0/capsules/prompting/self-consistency-no-isolation.yaml +237 -0
  39. package/dist/pattern-packs/zivis-public-0.2.0/capsules/retrieval/context-injection-no-validator.yaml +348 -0
  40. package/dist/pattern-packs/zivis-public-0.2.0/capsules/security/late-org-filter.yaml +266 -0
  41. package/dist/pattern-packs/zivis-public-0.2.0/controls/external_validator_on_facts.yaml +37 -0
  42. package/dist/pattern-packs/zivis-public-0.2.0/controls/fact_validator_present.yaml +68 -0
  43. package/dist/pattern-packs/zivis-public-0.2.0/controls/human_approval_gate.yaml +44 -0
  44. package/dist/pattern-packs/zivis-public-0.2.0/controls/langgraph_state_machine_with_per_node_tools.yaml +35 -0
  45. package/dist/pattern-packs/zivis-public-0.2.0/controls/per_sample_retrieval_diversification.yaml +38 -0
  46. package/dist/pattern-packs/zivis-public-0.2.0/controls/prisma_extension_or_middleware_attaching_org_filter.yaml +31 -0
  47. package/dist/pattern-packs/zivis-public-0.2.0/controls/row_level_security_policy.yaml +37 -0
  48. package/dist/pattern-packs/zivis-public-0.2.0/controls/source_attribution_present.yaml +58 -0
  49. package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +167 -0
  50. package/dist/pattern-packs/zivis-public-0.2.0/prompts/agents/privilege-separation/identify.md +54 -0
  51. package/dist/pattern-packs/zivis-public-0.2.0/prompts/prompting/self-consistency-no-isolation/identify.md +60 -0
  52. package/dist/pattern-packs/zivis-public-0.2.0/prompts/retrieval/context-injection-no-validator/identify.md +109 -0
  53. package/dist/pattern-packs/zivis-public-0.2.0/prompts/security/late-org-filter/identify.md +78 -0
  54. package/dist/project-binding.d.ts +2 -19
  55. package/dist/project-binding.js +38 -21
  56. package/dist/prompts/audit-dependencies.d.ts +2 -0
  57. package/dist/prompts/audit-dependencies.js +47 -0
  58. package/dist/prompts/getting-started.d.ts +2 -0
  59. package/dist/prompts/getting-started.js +37 -0
  60. package/dist/prompts/index.d.ts +2 -0
  61. package/dist/prompts/index.js +6 -0
  62. package/dist/resolve-application-id.d.ts +0 -4
  63. package/dist/resolve-application-id.js +0 -5
  64. package/dist/sanitize.d.ts +1 -21
  65. package/dist/sanitize.js +7 -41
  66. package/dist/server.d.ts +1 -13
  67. package/dist/server.js +134 -253
  68. package/dist/tools/artifacts.d.ts +76 -0
  69. package/dist/tools/artifacts.js +178 -0
  70. package/dist/tools/check-project.d.ts +5 -18
  71. package/dist/tools/check-project.js +120 -111
  72. package/dist/tools/check-repo-trust.d.ts +4 -19
  73. package/dist/tools/check-repo-trust.js +56 -47
  74. package/dist/tools/create-diagram.d.ts +0 -5
  75. package/dist/tools/create-diagram.js +0 -10
  76. package/dist/tools/create-document.d.ts +0 -5
  77. package/dist/tools/create-document.js +3 -9
  78. package/dist/tools/create-finding.d.ts +85 -0
  79. package/dist/tools/create-finding.js +136 -0
  80. package/dist/tools/delete-finding.d.ts +19 -0
  81. package/dist/tools/delete-finding.js +36 -0
  82. package/dist/tools/discover-local-infra.d.ts +0 -10
  83. package/dist/tools/discover-local-infra.js +3 -73
  84. package/dist/tools/enterprise/get-org-zat.d.ts +0 -5
  85. package/dist/tools/enterprise/get-org-zat.js +0 -6
  86. package/dist/tools/enterprise/get-threat-model.d.ts +1 -8
  87. package/dist/tools/enterprise/get-threat-model.js +9 -31
  88. package/dist/tools/enterprise/list-attack-scenarios.d.ts +24 -0
  89. package/dist/tools/enterprise/list-attack-scenarios.js +63 -0
  90. package/dist/tools/enterprise/list-threat-models.d.ts +1 -6
  91. package/dist/tools/enterprise/list-threat-models.js +1 -9
  92. package/dist/tools/enterprise/manage-actor.d.ts +2 -7
  93. package/dist/tools/enterprise/manage-actor.js +13 -7
  94. package/dist/tools/enterprise/manage-attack-scenario.d.ts +1 -6
  95. package/dist/tools/enterprise/manage-attack-scenario.js +12 -7
  96. package/dist/tools/enterprise/manage-data-asset.d.ts +2 -7
  97. package/dist/tools/enterprise/manage-data-asset.js +16 -7
  98. package/dist/tools/enterprise/manage-security-control.d.ts +1 -6
  99. package/dist/tools/enterprise/manage-security-control.js +17 -7
  100. package/dist/tools/explain-signal-for-diff.d.ts +34 -0
  101. package/dist/tools/explain-signal-for-diff.js +75 -0
  102. package/dist/tools/generate-diagram.d.ts +0 -6
  103. package/dist/tools/generate-diagram.js +21 -13
  104. package/dist/tools/get-application-overview.d.ts +0 -5
  105. package/dist/tools/get-application-overview.js +0 -6
  106. package/dist/tools/get-application.d.ts +0 -5
  107. package/dist/tools/get-application.js +0 -6
  108. package/dist/tools/get-diagram.d.ts +0 -5
  109. package/dist/tools/get-diagram.js +1 -11
  110. package/dist/tools/get-document.d.ts +0 -5
  111. package/dist/tools/get-document.js +0 -6
  112. package/dist/tools/get-oss-zat.d.ts +0 -5
  113. package/dist/tools/get-oss-zat.js +0 -7
  114. package/dist/tools/get-signal.d.ts +24 -0
  115. package/dist/tools/get-signal.js +75 -0
  116. package/dist/tools/get-started.d.ts +18 -0
  117. package/dist/tools/get-started.js +470 -0
  118. package/dist/tools/get-trust-keys.d.ts +0 -5
  119. package/dist/tools/get-trust-keys.js +0 -6
  120. package/dist/tools/import-openapi-endpoints.d.ts +0 -5
  121. package/dist/tools/import-openapi-endpoints.js +0 -6
  122. package/dist/tools/inspect-zat.d.ts +0 -5
  123. package/dist/tools/inspect-zat.js +0 -19
  124. package/dist/tools/inspect.d.ts +21 -0
  125. package/dist/tools/inspect.js +222 -0
  126. package/dist/tools/list-applications.d.ts +1 -6
  127. package/dist/tools/list-applications.js +0 -6
  128. package/dist/tools/list-diagrams.d.ts +0 -5
  129. package/dist/tools/list-diagrams.js +0 -6
  130. package/dist/tools/list-documents.d.ts +0 -5
  131. package/dist/tools/list-documents.js +0 -6
  132. package/dist/tools/list-endpoints.d.ts +1 -6
  133. package/dist/tools/list-endpoints.js +0 -6
  134. package/dist/tools/list-signals.d.ts +37 -0
  135. package/dist/tools/list-signals.js +83 -0
  136. package/dist/tools/manage-application.d.ts +64 -0
  137. package/dist/tools/manage-application.js +129 -0
  138. package/dist/tools/manage-diagram.d.ts +0 -5
  139. package/dist/tools/manage-diagram.js +0 -16
  140. package/dist/tools/manage-endpoint-lifecycle.d.ts +80 -0
  141. package/dist/tools/manage-endpoint-lifecycle.js +180 -0
  142. package/dist/tools/open-in-ide.d.ts +2 -14
  143. package/dist/tools/open-in-ide.js +0 -13
  144. package/dist/tools/review-change.d.ts +34 -0
  145. package/dist/tools/review-change.js +93 -0
  146. package/dist/tools/security-review.d.ts +0 -16
  147. package/dist/tools/security-review.js +63 -77
  148. package/dist/tools/threat-get-capsule.d.ts +15 -0
  149. package/dist/tools/threat-get-capsule.js +53 -0
  150. package/dist/tools/threat-get-inference-prompt.d.ts +15 -0
  151. package/dist/tools/threat-get-inference-prompt.js +73 -0
  152. package/dist/tools/threat-list-relevant-capsules.d.ts +17 -0
  153. package/dist/tools/threat-list-relevant-capsules.js +158 -0
  154. package/dist/tools/threat-run-matcher.d.ts +17 -0
  155. package/dist/tools/threat-run-matcher.js +145 -0
  156. package/dist/tools/update-document.d.ts +0 -5
  157. package/dist/tools/update-document.js +3 -9
  158. package/dist/tools/update-endpoint.d.ts +1 -6
  159. package/dist/tools/update-endpoint.js +0 -7
  160. package/dist/tools/update-finding.d.ts +61 -0
  161. package/dist/tools/update-finding.js +80 -0
  162. package/dist/tools/update-mermaid-source.d.ts +0 -13
  163. package/dist/tools/update-mermaid-source.js +0 -14
  164. package/dist/tools/verify-trust-mark.d.ts +0 -5
  165. package/dist/tools/verify-trust-mark.js +0 -6
  166. package/dist/types.d.ts +13 -13
  167. package/dist/types.js +22 -28
  168. package/package.json +28 -5
  169. package/dist/api-client.js.map +0 -1
  170. package/dist/auth/index.js.map +0 -1
  171. package/dist/auth/jwt.js.map +0 -1
  172. package/dist/auth/keychain.js.map +0 -1
  173. package/dist/auth/oauth.js.map +0 -1
  174. package/dist/auth/sessions.js.map +0 -1
  175. package/dist/auth/token-refresh.js.map +0 -1
  176. package/dist/cli.js.map +0 -1
  177. package/dist/index.js.map +0 -1
  178. package/dist/project-binding.js.map +0 -1
  179. package/dist/resolve-application-id.js.map +0 -1
  180. package/dist/sanitize.js.map +0 -1
  181. package/dist/server.js.map +0 -1
  182. package/dist/tools/check-project.js.map +0 -1
  183. package/dist/tools/check-repo-trust.js.map +0 -1
  184. package/dist/tools/create-diagram.js.map +0 -1
  185. package/dist/tools/create-document.js.map +0 -1
  186. package/dist/tools/discover-local-infra.js.map +0 -1
  187. package/dist/tools/enterprise/capture-evidence.d.ts +0 -54
  188. package/dist/tools/enterprise/capture-evidence.js +0 -72
  189. package/dist/tools/enterprise/capture-evidence.js.map +0 -1
  190. package/dist/tools/enterprise/create-report-ticket.d.ts +0 -34
  191. package/dist/tools/enterprise/create-report-ticket.js +0 -44
  192. package/dist/tools/enterprise/create-report-ticket.js.map +0 -1
  193. package/dist/tools/enterprise/end-pentest-session.d.ts +0 -33
  194. package/dist/tools/enterprise/end-pentest-session.js +0 -42
  195. package/dist/tools/enterprise/end-pentest-session.js.map +0 -1
  196. package/dist/tools/enterprise/generate-report.d.ts +0 -55
  197. package/dist/tools/enterprise/generate-report.js +0 -111
  198. package/dist/tools/enterprise/generate-report.js.map +0 -1
  199. package/dist/tools/enterprise/get-org-zat.js.map +0 -1
  200. package/dist/tools/enterprise/get-report-status.d.ts +0 -27
  201. package/dist/tools/enterprise/get-report-status.js +0 -38
  202. package/dist/tools/enterprise/get-report-status.js.map +0 -1
  203. package/dist/tools/enterprise/get-threat-model.js.map +0 -1
  204. package/dist/tools/enterprise/list-agents.d.ts +0 -42
  205. package/dist/tools/enterprise/list-agents.js +0 -95
  206. package/dist/tools/enterprise/list-agents.js.map +0 -1
  207. package/dist/tools/enterprise/list-report-issues.d.ts +0 -36
  208. package/dist/tools/enterprise/list-report-issues.js +0 -50
  209. package/dist/tools/enterprise/list-report-issues.js.map +0 -1
  210. package/dist/tools/enterprise/list-threat-models.js.map +0 -1
  211. package/dist/tools/enterprise/manage-actor.js.map +0 -1
  212. package/dist/tools/enterprise/manage-attack-scenario.js.map +0 -1
  213. package/dist/tools/enterprise/manage-component.d.ts +0 -58
  214. package/dist/tools/enterprise/manage-component.js +0 -90
  215. package/dist/tools/enterprise/manage-component.js.map +0 -1
  216. package/dist/tools/enterprise/manage-data-asset.js.map +0 -1
  217. package/dist/tools/enterprise/manage-data-flow.d.ts +0 -57
  218. package/dist/tools/enterprise/manage-data-flow.js +0 -98
  219. package/dist/tools/enterprise/manage-data-flow.js.map +0 -1
  220. package/dist/tools/enterprise/manage-finding.d.ts +0 -69
  221. package/dist/tools/enterprise/manage-finding.js +0 -106
  222. package/dist/tools/enterprise/manage-finding.js.map +0 -1
  223. package/dist/tools/enterprise/manage-security-control.js.map +0 -1
  224. package/dist/tools/enterprise/manage-test-case.d.ts +0 -88
  225. package/dist/tools/enterprise/manage-test-case.js +0 -119
  226. package/dist/tools/enterprise/manage-test-case.js.map +0 -1
  227. package/dist/tools/enterprise/promote-finding-to-issue.d.ts +0 -36
  228. package/dist/tools/enterprise/promote-finding-to-issue.js +0 -65
  229. package/dist/tools/enterprise/promote-finding-to-issue.js.map +0 -1
  230. package/dist/tools/enterprise/publish-report-version.d.ts +0 -34
  231. package/dist/tools/enterprise/publish-report-version.js +0 -75
  232. package/dist/tools/enterprise/publish-report-version.js.map +0 -1
  233. package/dist/tools/enterprise/publish-test-to-library.d.ts +0 -31
  234. package/dist/tools/enterprise/publish-test-to-library.js +0 -40
  235. package/dist/tools/enterprise/publish-test-to-library.js.map +0 -1
  236. package/dist/tools/enterprise/record-test-result.d.ts +0 -67
  237. package/dist/tools/enterprise/record-test-result.js +0 -75
  238. package/dist/tools/enterprise/record-test-result.js.map +0 -1
  239. package/dist/tools/enterprise/start-pentest-session.d.ts +0 -35
  240. package/dist/tools/enterprise/start-pentest-session.js +0 -50
  241. package/dist/tools/enterprise/start-pentest-session.js.map +0 -1
  242. package/dist/tools/enterprise/sync-report-section.d.ts +0 -41
  243. package/dist/tools/enterprise/sync-report-section.js +0 -79
  244. package/dist/tools/enterprise/sync-report-section.js.map +0 -1
  245. package/dist/tools/enterprise/update-report-issue.d.ts +0 -55
  246. package/dist/tools/enterprise/update-report-issue.js +0 -69
  247. package/dist/tools/enterprise/update-report-issue.js.map +0 -1
  248. package/dist/tools/generate-diagram.js.map +0 -1
  249. package/dist/tools/get-agent-test-results.d.ts +0 -41
  250. package/dist/tools/get-agent-test-results.js +0 -86
  251. package/dist/tools/get-agent-test-results.js.map +0 -1
  252. package/dist/tools/get-application-overview.js.map +0 -1
  253. package/dist/tools/get-application.js.map +0 -1
  254. package/dist/tools/get-artifact-content.d.ts +0 -29
  255. package/dist/tools/get-artifact-content.js +0 -86
  256. package/dist/tools/get-artifact-content.js.map +0 -1
  257. package/dist/tools/get-diagram.js.map +0 -1
  258. package/dist/tools/get-document.js.map +0 -1
  259. package/dist/tools/get-finding-details.d.ts +0 -28
  260. package/dist/tools/get-finding-details.js +0 -43
  261. package/dist/tools/get-finding-details.js.map +0 -1
  262. package/dist/tools/get-findings.d.ts +0 -57
  263. package/dist/tools/get-findings.js +0 -103
  264. package/dist/tools/get-findings.js.map +0 -1
  265. package/dist/tools/get-oss-zat.js.map +0 -1
  266. package/dist/tools/get-recon-scan.d.ts +0 -27
  267. package/dist/tools/get-recon-scan.js +0 -46
  268. package/dist/tools/get-recon-scan.js.map +0 -1
  269. package/dist/tools/get-scan-output.d.ts +0 -27
  270. package/dist/tools/get-scan-output.js +0 -64
  271. package/dist/tools/get-scan-output.js.map +0 -1
  272. package/dist/tools/get-scenario-details.d.ts +0 -27
  273. package/dist/tools/get-scenario-details.js +0 -46
  274. package/dist/tools/get-scenario-details.js.map +0 -1
  275. package/dist/tools/get-test-case-results.d.ts +0 -37
  276. package/dist/tools/get-test-case-results.js +0 -66
  277. package/dist/tools/get-test-case-results.js.map +0 -1
  278. package/dist/tools/get-test-details.d.ts +0 -29
  279. package/dist/tools/get-test-details.js +0 -49
  280. package/dist/tools/get-test-details.js.map +0 -1
  281. package/dist/tools/get-trust-keys.js.map +0 -1
  282. package/dist/tools/import-openapi-endpoints.js.map +0 -1
  283. package/dist/tools/inspect-zat.js.map +0 -1
  284. package/dist/tools/list-agent-test-cases.d.ts +0 -41
  285. package/dist/tools/list-agent-test-cases.js +0 -73
  286. package/dist/tools/list-agent-test-cases.js.map +0 -1
  287. package/dist/tools/list-applications.js.map +0 -1
  288. package/dist/tools/list-diagrams.js.map +0 -1
  289. package/dist/tools/list-documents.js.map +0 -1
  290. package/dist/tools/list-endpoints.js.map +0 -1
  291. package/dist/tools/list-recon-scans.d.ts +0 -36
  292. package/dist/tools/list-recon-scans.js +0 -74
  293. package/dist/tools/list-recon-scans.js.map +0 -1
  294. package/dist/tools/list-scan-artifacts.d.ts +0 -41
  295. package/dist/tools/list-scan-artifacts.js +0 -63
  296. package/dist/tools/list-scan-artifacts.js.map +0 -1
  297. package/dist/tools/list-scans.d.ts +0 -44
  298. package/dist/tools/list-scans.js +0 -91
  299. package/dist/tools/list-scans.js.map +0 -1
  300. package/dist/tools/list-test-library.d.ts +0 -44
  301. package/dist/tools/list-test-library.js +0 -83
  302. package/dist/tools/list-test-library.js.map +0 -1
  303. package/dist/tools/list-test-scenarios.d.ts +0 -31
  304. package/dist/tools/list-test-scenarios.js +0 -66
  305. package/dist/tools/list-test-scenarios.js.map +0 -1
  306. package/dist/tools/local-scan.d.ts +0 -40
  307. package/dist/tools/local-scan.js +0 -261
  308. package/dist/tools/local-scan.js.map +0 -1
  309. package/dist/tools/manage-diagram.js.map +0 -1
  310. package/dist/tools/open-in-ide.js.map +0 -1
  311. package/dist/tools/run-test-scenario.d.ts +0 -37
  312. package/dist/tools/run-test-scenario.js +0 -70
  313. package/dist/tools/run-test-scenario.js.map +0 -1
  314. package/dist/tools/scan-pr.d.ts +0 -27
  315. package/dist/tools/scan-pr.js +0 -51
  316. package/dist/tools/scan-pr.js.map +0 -1
  317. package/dist/tools/security-review.js.map +0 -1
  318. package/dist/tools/setup-red-team-target.d.ts +0 -79
  319. package/dist/tools/setup-red-team-target.js +0 -430
  320. package/dist/tools/setup-red-team-target.js.map +0 -1
  321. package/dist/tools/triage-finding.d.ts +0 -47
  322. package/dist/tools/triage-finding.js +0 -116
  323. package/dist/tools/triage-finding.js.map +0 -1
  324. package/dist/tools/update-document.js.map +0 -1
  325. package/dist/tools/update-endpoint.js.map +0 -1
  326. package/dist/tools/update-mermaid-source.js.map +0 -1
  327. package/dist/tools/verify-trust-mark.js.map +0 -1
  328. package/dist/types.js.map +0 -1
@@ -1,19 +1,3 @@
1
- /**
2
- * zivis_security_review — AI-powered security code review with ZIVIS intelligence
3
- *
4
- * Composite tool that gathers security context from multiple ZIVIS sources
5
- * and returns it as structured input for Claude to use during code review.
6
- *
7
- * Sources:
8
- * 1. Historical findings (resolved) — regression check patterns
9
- * 2. Open findings — known vulnerabilities to verify aren't reintroduced
10
- * 3. Threat model security controls — what's expected to be in place
11
- * 4. Threat model attack scenarios — known attack vectors
12
- * 5. OSS trust data — dependency risk signals
13
- *
14
- * This tool does NOT run scans itself. It assembles intelligence from ZIVIS
15
- * so Claude can perform an informed, context-aware code review.
16
- */
17
1
  import { z } from "zod";
18
2
  import type { ApiClient } from "../api-client.js";
19
3
  import type { ZivisConfig } from "../types.js";
@@ -1,19 +1,3 @@
1
- /**
2
- * zivis_security_review — AI-powered security code review with ZIVIS intelligence
3
- *
4
- * Composite tool that gathers security context from multiple ZIVIS sources
5
- * and returns it as structured input for Claude to use during code review.
6
- *
7
- * Sources:
8
- * 1. Historical findings (resolved) — regression check patterns
9
- * 2. Open findings — known vulnerabilities to verify aren't reintroduced
10
- * 3. Threat model security controls — what's expected to be in place
11
- * 4. Threat model attack scenarios — known attack vectors
12
- * 5. OSS trust data — dependency risk signals
13
- *
14
- * This tool does NOT run scans itself. It assembles intelligence from ZIVIS
15
- * so Claude can perform an informed, context-aware code review.
16
- */
17
1
  import { z } from "zod";
18
2
  import { resolveApplicationId } from "../resolve-application-id.js";
19
3
  import { sanitizeResponse } from "../sanitize.js";
@@ -60,7 +44,6 @@ export const SECURITY_REVIEW_SCHEMA = {
60
44
  .optional()
61
45
  .describe("Specific dependencies to check trust scores for (owner/repo format)"),
62
46
  };
63
- // Severity ordering for threshold filtering
64
47
  const SEVERITY_ORDER = {
65
48
  critical: 5,
66
49
  high: 4,
@@ -89,7 +72,6 @@ export function createSecurityReviewHandler(apiClient, config) {
89
72
  parameters: { repo, application_id, threat_model_id, campaign_id },
90
73
  };
91
74
  const errors = [];
92
- // ── 1. Historical findings (regression check) ──
93
75
  if (shouldInclude("regression") && (repo || application_id)) {
94
76
  try {
95
77
  const resolvedFindings = await fetchFindings(apiClient, {
@@ -102,7 +84,6 @@ export function createSecurityReviewHandler(apiClient, config) {
102
84
  status: "false_positive",
103
85
  limit: 20,
104
86
  });
105
- // Build regression patterns: group by category/CWE
106
87
  const regressionPatterns = buildRegressionPatterns(resolvedFindings);
107
88
  context.regressionCheck = {
108
89
  _instruction: "Check code changes against these previously fixed vulnerabilities. Flag if similar patterns appear.",
@@ -116,7 +97,6 @@ export function createSecurityReviewHandler(apiClient, config) {
116
97
  errors.push(`Regression data: ${err instanceof Error ? err.message : "failed"}`);
117
98
  }
118
99
  }
119
- // ── 2. Open findings (known vulnerabilities) ──
120
100
  if (shouldInclude("regression") && (repo || application_id)) {
121
101
  try {
122
102
  const minSeverity = SEVERITY_ORDER[severity_threshold] || 2;
@@ -125,7 +105,6 @@ export function createSecurityReviewHandler(apiClient, config) {
125
105
  status: "open",
126
106
  limit: 50,
127
107
  });
128
- // Filter by severity threshold
129
108
  const filtered = openFindings.filter((f) => (SEVERITY_ORDER[f.severity] || 1) >= minSeverity);
130
109
  context.openVulnerabilities = {
131
110
  _instruction: "These are KNOWN open vulnerabilities. Check if code changes interact with or worsen these issues.",
@@ -138,64 +117,76 @@ export function createSecurityReviewHandler(apiClient, config) {
138
117
  errors.push(`Open findings: ${err instanceof Error ? err.message : "failed"}`);
139
118
  }
140
119
  }
141
- // ── 3. Threat model: security controls ──
142
- if (shouldInclude("controls") && threat_model_id) {
120
+ if ((shouldInclude("controls") || shouldInclude("attack_scenarios")) && threat_model_id) {
121
+ let tm = null;
143
122
  try {
144
- const tm = await apiClient.get(`/api/threat-models/${threat_model_id}?include=all`);
145
- const controls = tm.securityControls || [];
146
- const notImplemented = controls.filter((c) => c.status === "not_implemented");
147
- const partial = controls.filter((c) => c.status === "partial");
148
- const implemented = controls.filter((c) => c.status === "implemented");
149
- context.securityControls = {
150
- _instruction: "Verify that code implements these expected security controls. Flag missing or weak implementations.",
151
- summary: {
152
- implemented: implemented.length,
153
- partial: partial.length,
154
- notImplemented: notImplemented.length,
155
- },
156
- gapControls: [...notImplemented, ...partial].map((c) => ({
157
- name: c.name,
158
- type: c.controlType,
159
- status: c.status,
160
- description: c.description,
161
- effectiveness: c.effectivenessRating,
162
- })),
163
- implementedControls: implemented.map((c) => ({
164
- name: c.name,
165
- type: c.controlType,
166
- description: c.description,
167
- })),
168
- };
123
+ tm = await apiClient.get(`/api/threat-models/${threat_model_id}?include=all`);
169
124
  }
170
125
  catch (err) {
171
- errors.push(`Security controls: ${err instanceof Error ? err.message : "failed"}`);
126
+ errors.push(`Threat model fetch: ${err instanceof Error ? err.message : "failed"}`);
172
127
  }
173
- }
174
- // ── 4. Threat model: attack scenarios ──
175
- if (shouldInclude("attack_scenarios") && threat_model_id) {
176
- try {
177
- const tm = await apiClient.get(`/api/threat-models/${threat_model_id}?include=all`);
178
- const scenarios = tm.attackScenarios || [];
179
- const minSeverity = SEVERITY_ORDER[severity_threshold] || 2;
180
- const filtered = scenarios.filter((s) => (SEVERITY_ORDER[s.severity] || 1) >= minSeverity);
181
- context.attackScenarios = {
182
- _instruction: "Review code for susceptibility to these known attack vectors. Check that mitigations are in place.",
183
- count: filtered.length,
184
- scenarios: filtered.map((s) => ({
185
- name: s.name,
186
- strideCategory: s.strideCategory,
187
- severity: s.severity,
188
- likelihood: s.likelihood,
189
- attackVector: s.attackVector,
190
- description: s.description,
191
- })),
192
- };
128
+ const versions = Array.isArray(tm?.versions) ? tm.versions : [];
129
+ const latestVersion = versions[0] || {};
130
+ if (tm && shouldInclude("controls")) {
131
+ try {
132
+ const controls = Array.isArray(latestVersion.securityControls)
133
+ ? latestVersion.securityControls
134
+ : [];
135
+ const notImplemented = controls.filter((c) => c.status === "not_implemented");
136
+ const partial = controls.filter((c) => c.status === "partial");
137
+ const implemented = controls.filter((c) => c.status === "implemented");
138
+ context.securityControls = {
139
+ _instruction: "Verify that code implements these expected security controls. Flag missing or weak implementations.",
140
+ summary: {
141
+ implemented: implemented.length,
142
+ partial: partial.length,
143
+ notImplemented: notImplemented.length,
144
+ },
145
+ gapControls: [...notImplemented, ...partial].map((c) => ({
146
+ name: c.name,
147
+ type: c.controlType,
148
+ status: c.status,
149
+ description: c.description,
150
+ effectiveness: c.effectivenessRating,
151
+ })),
152
+ implementedControls: implemented.map((c) => ({
153
+ name: c.name,
154
+ type: c.controlType,
155
+ description: c.description,
156
+ })),
157
+ };
158
+ }
159
+ catch (err) {
160
+ errors.push(`Security controls: ${err instanceof Error ? err.message : "failed"}`);
161
+ }
193
162
  }
194
- catch (err) {
195
- errors.push(`Attack scenarios: ${err instanceof Error ? err.message : "failed"}`);
163
+ if (tm && shouldInclude("attack_scenarios")) {
164
+ try {
165
+ const scenarios = Array.isArray(latestVersion.attackScenarios)
166
+ ? latestVersion.attackScenarios
167
+ : [];
168
+ const minSeverity = SEVERITY_ORDER[severity_threshold] || 2;
169
+ const filtered = scenarios.filter((s) => (SEVERITY_ORDER[s.severity] || 1) >= minSeverity);
170
+ context.attackScenarios = {
171
+ _instruction: "Review code for susceptibility to these known attack vectors. Check that mitigations are in place.",
172
+ count: filtered.length,
173
+ scenarios: filtered.map((s) => ({
174
+ displayId: s.displayId,
175
+ title: s.title,
176
+ strideCategory: s.strideCategory,
177
+ severity: s.severity,
178
+ likelihood: s.likelihood,
179
+ riskScore: s.riskScore,
180
+ status: s.status,
181
+ narrative: s.narrative,
182
+ })),
183
+ };
184
+ }
185
+ catch (err) {
186
+ errors.push(`Attack scenarios: ${err instanceof Error ? err.message : "failed"}`);
187
+ }
196
188
  }
197
189
  }
198
- // ── 5. Dependency trust scores ──
199
190
  if (shouldInclude("dependencies") && dependency_list && dependency_list.length > 0) {
200
191
  const depResults = [];
201
192
  const baseUrl = config.apiBaseUrl;
@@ -238,7 +229,6 @@ export function createSecurityReviewHandler(apiClient, config) {
238
229
  dependencies: depResults,
239
230
  };
240
231
  }
241
- // ── 6. Campaign findings (if campaign_id provided) ──
242
232
  if (campaign_id) {
243
233
  try {
244
234
  const campaignFindings = await apiClient.get(`/api/campaigns/${campaign_id}/findings?limit=50`);
@@ -256,7 +246,6 @@ export function createSecurityReviewHandler(apiClient, config) {
256
246
  errors.push(`Campaign findings: ${err instanceof Error ? err.message : "failed"}`);
257
247
  }
258
248
  }
259
- // ── Build review guidance ──
260
249
  context.reviewGuidance = buildReviewGuidance(context);
261
250
  if (errors.length > 0) {
262
251
  context.warnings = errors;
@@ -269,7 +258,6 @@ export function createSecurityReviewHandler(apiClient, config) {
269
258
  };
270
259
  };
271
260
  }
272
- // ── Helpers ──
273
261
  async function fetchFindings(apiClient, params) {
274
262
  const query = new URLSearchParams();
275
263
  if (params.repo)
@@ -303,7 +291,6 @@ function countBySeverity(findings) {
303
291
  return counts;
304
292
  }
305
293
  function buildRegressionPatterns(resolvedFindings) {
306
- // Group by category + CWE to find recurring vulnerability patterns
307
294
  const patternMap = new Map();
308
295
  for (const f of resolvedFindings) {
309
296
  const key = `${f.category || "uncategorized"}::${f.cweId || "no-cwe"}`;
@@ -375,4 +362,3 @@ function parseRepo(input) {
375
362
  }
376
363
  return null;
377
364
  }
378
- //# sourceMappingURL=security-review.js.map
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const THREAT_GET_CAPSULE_NAME = "zivis_threat_get_capsule";
3
+ export declare const THREAT_GET_CAPSULE_DESCRIPTION = "Return the full capsule for a single threat-model pattern.\n\nUse after zivis_threat_list_relevant_capsules has surfaced an id the user wants to dig into. The capsule includes:\n- safe_summary, detect_when, risk_hints, architectural_signals \u2014 for explaining the pattern in threat-model language\n- threats[] with STRIDE categories and remediations \u2014 for grounding the conversation in component/flow/boundary terms\n- repair_contract.allowed / forbidden \u2014 what refactors are safe\n- related_patterns \u2014 adjacent ids in the library\n- model_task_prompt_ref \u2014 pass to zivis_threat_get_inference_prompt to get the prompt the host LLM should run for a deeper check\n\nCapsule data is read from the local pack (~/Library/Caches/zivis/pattern-packs/) with SHA256 integrity verification on every read.";
4
+ export declare const THREAT_GET_CAPSULE_SCHEMA: {
5
+ capsule_id: z.ZodString;
6
+ };
7
+ export declare function createThreatGetCapsuleHandler(): (params: {
8
+ capsule_id: string;
9
+ }) => Promise<{
10
+ content: Array<{
11
+ type: "text";
12
+ text: string;
13
+ }>;
14
+ isError?: boolean;
15
+ }>;
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { loadActivePack, getCapsule, listCapsuleIds } from "../pattern-pack/index.js";
3
+ import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
4
+ export const THREAT_GET_CAPSULE_NAME = "zivis_threat_get_capsule";
5
+ export const THREAT_GET_CAPSULE_DESCRIPTION = `Return the full capsule for a single threat-model pattern.
6
+
7
+ Use after zivis_threat_list_relevant_capsules has surfaced an id the user wants to dig into. The capsule includes:
8
+ - safe_summary, detect_when, risk_hints, architectural_signals — for explaining the pattern in threat-model language
9
+ - threats[] with STRIDE categories and remediations — for grounding the conversation in component/flow/boundary terms
10
+ - repair_contract.allowed / forbidden — what refactors are safe
11
+ - related_patterns — adjacent ids in the library
12
+ - model_task_prompt_ref — pass to zivis_threat_get_inference_prompt to get the prompt the host LLM should run for a deeper check
13
+
14
+ Capsule data is read from the local pack (~/Library/Caches/zivis/pattern-packs/) with SHA256 integrity verification on every read.`;
15
+ export const THREAT_GET_CAPSULE_SCHEMA = {
16
+ capsule_id: z
17
+ .string()
18
+ .describe("Capsule id, e.g. 'agents.privilege-separation'. Discoverable via zivis_threat_list_relevant_capsules."),
19
+ };
20
+ export function createThreatGetCapsuleHandler() {
21
+ return async (params) => {
22
+ const handle = await loadActivePack();
23
+ let capsule;
24
+ try {
25
+ capsule = await getCapsule(handle, params.capsule_id);
26
+ }
27
+ catch (err) {
28
+ const ids = await listCapsuleIds(handle);
29
+ return withNextStepsError(`Capsule '${params.capsule_id}' not found in pack ${handle.manifest.pack_id}@${handle.manifest.version}. ${err.message}`, [
30
+ {
31
+ id: "list_relevant_capsules_first",
32
+ label: "Find relevant capsules for the current repo first",
33
+ tool: "zivis_threat_list_relevant_capsules",
34
+ why: "Returns ids you can pass back into zivis_threat_get_capsule.",
35
+ },
36
+ ], `Available capsule ids in this pack: ${ids.join(", ")}`);
37
+ }
38
+ return withNextSteps({
39
+ pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
40
+ capsule,
41
+ }, capsule.model_task_prompt_ref
42
+ ? [
43
+ {
44
+ id: "get_inference_prompt",
45
+ label: "Get the inference prompt template the host LLM should run",
46
+ tool: "zivis_threat_get_inference_prompt",
47
+ args_hint: { capsule_id: capsule.id },
48
+ why: "Inference prompt + expected_output_schema together form the prompt bundle the IDE LLM executes.",
49
+ },
50
+ ]
51
+ : [], `Capsule ${capsule.id}@${capsule.version} (${capsule.lifecycle}, ${capsule.sensitivity_level ?? "unspecified-tier"}). Threats: ${(capsule.threats?.length ?? 0)}.`);
52
+ };
53
+ }
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const THREAT_GET_INFERENCE_PROMPT_NAME = "zivis_threat_get_inference_prompt";
3
+ export declare const THREAT_GET_INFERENCE_PROMPT_DESCRIPTION = "Return the prompt bundle for the host LLM to run local inference for a capsule.\n\nZIVIS doesn't run an LLM itself \u2014 the host (Cursor, Claude Code, etc.) does. This tool returns the prompt template + structured output schema + ambient capsule context so the host model can run the inference and produce JSON the inferred lane accepts.\n\nUse this when:\n- After zivis_threat_get_capsule, the user wants the host LLM to actually evaluate whether the pattern is present in the code\n- The user says \"go check if my code does this\" / \"is this pattern actually in my repo\"\n- The matcher emits an INFER candidate that needs host-LLM evaluation\n\nThe bundle includes:\n- prompt: the markdown inference prompt\n- expected_output_schema: JSON Schema for the structured response\n- safe_summary: ambient capsule context\n- minimum_context_required: hint to the host for how much code to attach\n- evidence_focus: spans the deterministic strategies already flagged\n\nThe host LLM is expected to gather the indicated code spans, fill in the prompt, return JSON matching the schema. That output then flows back into the inferred lane.";
4
+ export declare const THREAT_GET_INFERENCE_PROMPT_SCHEMA: {
5
+ capsule_id: z.ZodString;
6
+ };
7
+ export declare function createThreatGetInferencePromptHandler(): (params: {
8
+ capsule_id: string;
9
+ }) => Promise<{
10
+ content: Array<{
11
+ type: "text";
12
+ text: string;
13
+ }>;
14
+ isError?: boolean;
15
+ }>;
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ import { loadActivePack, getCapsule, getInferencePrompt } from "../pattern-pack/index.js";
3
+ import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
4
+ export const THREAT_GET_INFERENCE_PROMPT_NAME = "zivis_threat_get_inference_prompt";
5
+ export const THREAT_GET_INFERENCE_PROMPT_DESCRIPTION = `Return the prompt bundle for the host LLM to run local inference for a capsule.
6
+
7
+ ZIVIS doesn't run an LLM itself — the host (Cursor, Claude Code, etc.) does. This tool returns the prompt template + structured output schema + ambient capsule context so the host model can run the inference and produce JSON the inferred lane accepts.
8
+
9
+ Use this when:
10
+ - After zivis_threat_get_capsule, the user wants the host LLM to actually evaluate whether the pattern is present in the code
11
+ - The user says "go check if my code does this" / "is this pattern actually in my repo"
12
+ - The matcher emits an INFER candidate that needs host-LLM evaluation
13
+
14
+ The bundle includes:
15
+ - prompt: the markdown inference prompt
16
+ - expected_output_schema: JSON Schema for the structured response
17
+ - safe_summary: ambient capsule context
18
+ - minimum_context_required: hint to the host for how much code to attach
19
+ - evidence_focus: spans the deterministic strategies already flagged
20
+
21
+ The host LLM is expected to gather the indicated code spans, fill in the prompt, return JSON matching the schema. That output then flows back into the inferred lane.`;
22
+ export const THREAT_GET_INFERENCE_PROMPT_SCHEMA = {
23
+ capsule_id: z
24
+ .string()
25
+ .describe("Capsule id whose INFER prompt should be returned (e.g. 'agents.privilege-separation')."),
26
+ };
27
+ export function createThreatGetInferencePromptHandler() {
28
+ return async (params) => {
29
+ const handle = await loadActivePack();
30
+ let capsule;
31
+ try {
32
+ capsule = await getCapsule(handle, params.capsule_id);
33
+ }
34
+ catch (err) {
35
+ return withNextStepsError(`Capsule '${params.capsule_id}' not found. ${err.message}`, [
36
+ {
37
+ id: "list_relevant_capsules_first",
38
+ label: "List relevant capsules for the current repo first",
39
+ tool: "zivis_threat_list_relevant_capsules",
40
+ why: "Returns ids you can pass back here.",
41
+ },
42
+ ], "Capsule not found — list first to discover ids.");
43
+ }
44
+ if (!capsule.model_task_prompt_ref) {
45
+ return withNextStepsError(`Capsule '${capsule.id}' has no inference prompt defined (model_task_prompt_ref missing). This capsule is deterministic-only.`, [
46
+ {
47
+ id: "get_capsule",
48
+ label: "Read the full capsule to see its deterministic strategies",
49
+ tool: "zivis_threat_get_capsule",
50
+ args_hint: { capsule_id: capsule.id },
51
+ why: "Some capsules have no INFER strategy — only AST/GRAPH/META/etc. that the matcher runs locally.",
52
+ },
53
+ ], "No inference prompt for this capsule (deterministic only).");
54
+ }
55
+ const promptText = await getInferencePrompt(handle, capsule.model_task_prompt_ref);
56
+ return withNextSteps({
57
+ pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
58
+ capsule_id: capsule.id,
59
+ prompt: promptText,
60
+ expected_output_schema: capsule.expected_output_schema ?? null,
61
+ safe_summary: capsule.safe_summary ?? null,
62
+ minimum_context_required: capsule.minimum_context_required ?? null,
63
+ host_instructions: "Gather the code spans indicated by minimum_context_required.symbols (or any deterministic match spans the matcher already flagged), attach them to the prompt above, run inference with your model, and return JSON matching expected_output_schema. The structured output flows back into the inferred lane.",
64
+ }, [
65
+ {
66
+ id: "host_runs_inference",
67
+ label: "Host LLM runs inference now (no further tool call)",
68
+ tool: "zivis_threat_get_inference_prompt",
69
+ why: "MCP cannot invoke your model. The host orchestrates the inference using this bundle.",
70
+ },
71
+ ], `Prompt bundle ready for host-side inference of ${capsule.id}.`);
72
+ };
73
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export declare const THREAT_LIST_RELEVANT_CAPSULES_NAME = "zivis_threat_list_relevant_capsules";
3
+ export declare const THREAT_LIST_RELEVANT_CAPSULES_DESCRIPTION = "List threat-model patterns relevant to the user's current repo.\n\nUse this when the user asks any of:\n- \"what should I be worried about in this code\"\n- \"what threats apply to my app\"\n- \"are there known patterns that match my architecture\"\n- \"what's in my threat model\"\n- mid-conversation when the user describes a feature that touches deps the threat library covers\n\nReads the latest local repo graph artifact (produced by 'zivis inspect') from the user cache, runs every capsule's relevance_filter against it, and returns the subset whose filter passes \u2014 together with each capsule's safe_summary so you can frame the conversation in threat-model terms (component, flow, trust boundary, scenario).\n\nIf no graph artifact exists yet for this repo, the tool returns a next-step pointing to 'zivis inspect'. Always speak in threat-model vocabulary even when the user doesn't.";
4
+ export declare const THREAT_LIST_RELEVANT_CAPSULES_SCHEMA: {
5
+ artifact_path: z.ZodOptional<z.ZodString>;
6
+ cwd: z.ZodOptional<z.ZodString>;
7
+ };
8
+ export declare function createThreatListRelevantCapsulesHandler(): (params: {
9
+ artifact_path?: string;
10
+ cwd?: string;
11
+ }) => Promise<{
12
+ content: Array<{
13
+ type: "text";
14
+ text: string;
15
+ }>;
16
+ isError?: boolean;
17
+ }>;
@@ -0,0 +1,158 @@
1
+ import { z } from "zod";
2
+ import * as fs from "node:fs/promises";
3
+ import * as fssync from "node:fs";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import { loadActivePack, findRelevantCapsules, } from "../pattern-pack/index.js";
7
+ import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
8
+ export const THREAT_LIST_RELEVANT_CAPSULES_NAME = "zivis_threat_list_relevant_capsules";
9
+ export const THREAT_LIST_RELEVANT_CAPSULES_DESCRIPTION = `List threat-model patterns relevant to the user's current repo.
10
+
11
+ Use this when the user asks any of:
12
+ - "what should I be worried about in this code"
13
+ - "what threats apply to my app"
14
+ - "are there known patterns that match my architecture"
15
+ - "what's in my threat model"
16
+ - mid-conversation when the user describes a feature that touches deps the threat library covers
17
+
18
+ Reads the latest local repo graph artifact (produced by 'zivis inspect') from the user cache, runs every capsule's relevance_filter against it, and returns the subset whose filter passes — together with each capsule's safe_summary so you can frame the conversation in threat-model terms (component, flow, trust boundary, scenario).
19
+
20
+ If no graph artifact exists yet for this repo, the tool returns a next-step pointing to 'zivis inspect'. Always speak in threat-model vocabulary even when the user doesn't.`;
21
+ export const THREAT_LIST_RELEVANT_CAPSULES_SCHEMA = {
22
+ artifact_path: z
23
+ .string()
24
+ .optional()
25
+ .describe("Optional path to a specific RepoGraphArtifactV1 JSON. If omitted, the tool finds the most recent artifact in ~/Library/Caches/zivis/repos/<repo-id>/inspect/runs/ for the repo at cwd."),
26
+ cwd: z
27
+ .string()
28
+ .optional()
29
+ .describe("Working directory whose repo cache to search (defaults to server cwd)."),
30
+ };
31
+ export function createThreatListRelevantCapsulesHandler() {
32
+ return async (params) => {
33
+ const cwd = params.cwd ?? process.cwd();
34
+ let artifact;
35
+ let artifactPath;
36
+ try {
37
+ const resolved = await resolveArtifactPath(params.artifact_path, cwd);
38
+ artifactPath = resolved;
39
+ const raw = await fs.readFile(resolved, "utf8");
40
+ artifact = JSON.parse(raw);
41
+ }
42
+ catch (err) {
43
+ return withNextStepsError(`No repo graph artifact found. ${err.message}`, [
44
+ {
45
+ id: "run_zivis_inspect",
46
+ label: "Run `zivis inspect` to build the local repo graph",
47
+ tool: "zivis_inspect",
48
+ why: "The relevance evaluation reads from the latest inspect run in the user cache.",
49
+ },
50
+ ], "Run `zivis inspect` first; this tool reads from its output.");
51
+ }
52
+ const handle = await loadActivePack();
53
+ const relevant = await findRelevantCapsules(handle, artifact);
54
+ const summaries = relevant.map((cap) => ({
55
+ id: cap.id,
56
+ title: cap.title,
57
+ category: cap.category,
58
+ safe_summary: cap.safe_summary,
59
+ applicable_languages: cap.applicable_languages,
60
+ matched_on: matchedTerms(cap, artifact),
61
+ }));
62
+ return withNextSteps({
63
+ artifact_path: artifactPath,
64
+ pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
65
+ languages_in_scope: artifact.scope.languages ?? [],
66
+ relevant_count: summaries.length,
67
+ relevant_capsules: summaries,
68
+ }, summaries.length > 0
69
+ ? [
70
+ {
71
+ id: "get_capsule_details",
72
+ label: "Pull the full capsule for any item the user wants to investigate",
73
+ tool: "zivis_threat_get_capsule",
74
+ why: "The full capsule has threats (with STRIDE), risk_hints, repair_contract, related_patterns.",
75
+ },
76
+ {
77
+ id: "get_inference_prompt",
78
+ label: "Get the inference prompt for the host LLM to run a deeper check",
79
+ tool: "zivis_threat_get_inference_prompt",
80
+ why: "INFER strategies in each capsule reference a prompt template the user's IDE model executes.",
81
+ },
82
+ ]
83
+ : [
84
+ {
85
+ id: "no_relevant_patterns",
86
+ label: "No public-pack patterns matched this repo",
87
+ tool: "zivis_threat_list_relevant_capsules",
88
+ why: "This is normal for repos without agentic / RAG / self-consistency / multi-tenant patterns. Proprietary patterns may still apply server-side.",
89
+ },
90
+ ], summaries.length > 0
91
+ ? `Found ${summaries.length} relevant capsule(s) in the threat library.`
92
+ : "No public-pack capsules matched this repo. Proprietary patterns evaluated server-side may still apply.");
93
+ };
94
+ }
95
+ function userCacheRoot() {
96
+ const home = os.homedir();
97
+ if (process.platform === "darwin") {
98
+ return path.join(home, "Library", "Caches", "zivis");
99
+ }
100
+ if (process.platform === "win32") {
101
+ const localAppData = process.env.LOCALAPPDATA ?? path.join(home, "AppData", "Local");
102
+ return path.join(localAppData, "zivis", "Cache");
103
+ }
104
+ const xdg = process.env.XDG_CACHE_HOME;
105
+ return path.join(xdg ?? path.join(home, ".cache"), "zivis");
106
+ }
107
+ async function resolveArtifactPath(explicit, cwd) {
108
+ if (explicit) {
109
+ if (!fssync.existsSync(explicit)) {
110
+ throw new Error(`Artifact path does not exist: ${explicit}`);
111
+ }
112
+ return explicit;
113
+ }
114
+ const reposRoot = path.join(userCacheRoot(), "repos");
115
+ if (!fssync.existsSync(reposRoot)) {
116
+ throw new Error(`No inspect cache found at ${reposRoot}. Run \`zivis inspect\` from the repo to populate it.`);
117
+ }
118
+ const candidates = [];
119
+ for (const repo of await fs.readdir(reposRoot, { withFileTypes: true })) {
120
+ if (!repo.isDirectory())
121
+ continue;
122
+ const runs = path.join(reposRoot, repo.name, "inspect", "runs");
123
+ if (!fssync.existsSync(runs))
124
+ continue;
125
+ for (const entry of await fs.readdir(runs)) {
126
+ if (!entry.endsWith(".json"))
127
+ continue;
128
+ const full = path.join(runs, entry);
129
+ const stat = await fs.stat(full);
130
+ candidates.push({ file: full, mtime: stat.mtimeMs });
131
+ }
132
+ }
133
+ if (candidates.length === 0) {
134
+ throw new Error(`No inspect runs found under ${reposRoot}. Run \`zivis inspect\` from the repo to produce one.`);
135
+ }
136
+ candidates.sort((a, b) => b.mtime - a.mtime);
137
+ return candidates[0].file;
138
+ }
139
+ function matchedTerms(cap, artifact) {
140
+ const matched = [];
141
+ const pkgs = new Set();
142
+ for (const node of artifact.nodes) {
143
+ if (node.type === "external_dependency" && node.attributes?.package) {
144
+ pkgs.add(node.attributes.package);
145
+ }
146
+ }
147
+ const langs = new Set(artifact.scope.languages ?? []);
148
+ const f = cap.relevance_filter;
149
+ if (!f)
150
+ return ["always-applicable (no relevance_filter set)"];
151
+ for (const term of [...(f.any_of ?? []), ...(f.all_of ?? [])]) {
152
+ if (term.dependency && pkgs.has(term.dependency))
153
+ matched.push(`dep:${term.dependency}`);
154
+ if (term.language && langs.has(term.language))
155
+ matched.push(`language:${term.language}`);
156
+ }
157
+ return matched.length > 0 ? matched : ["language match only"];
158
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export declare const THREAT_RUN_MATCHER_NAME = "zivis_threat_run_matcher";
3
+ export declare const THREAT_RUN_MATCHER_DESCRIPTION = "Run the local pattern matcher against the latest repo graph artifact and emit normalized threat findings.\n\nUse this when:\n- The user asks ZIVIS to actually evaluate (not just list) which patterns fire on their code\n- After 'zivis inspect' has produced an artifact and the user wants concrete findings\n- \"find security issues in my code\", \"check this against the threat library\", \"what's actually wrong here\"\n\nPhase 3 v1 evaluates AST strategies for real (via @ast-grep/napi for TS/JS, plus Python and Go via dynamic language packs). INFER strategies emit a candidate the host LLM is expected to pick up via zivis_threat_get_inference_prompt and run with its own model. GRAPH / META / DEP / CONFIG strategies are surfaced as fired_strategies with match_count: 0 \u2014 visible-but-not-evaluated for now.\n\nLane assignment per finding:\n- trusted: count of fired deterministic strategies meets the capsule's required_evidence_count\n- inferred: at least one strategy fired but the bar wasn't met (host should run inference to confirm)\n\nThe output is a normalized findings array with pattern_id, lane, confidence, evidence spans, and (for inferred-lane findings) an inference_candidate the host LLM uses to run deeper analysis.";
4
+ export declare const THREAT_RUN_MATCHER_SCHEMA: {
5
+ artifact_path: z.ZodOptional<z.ZodString>;
6
+ cwd: z.ZodOptional<z.ZodString>;
7
+ };
8
+ export declare function createThreatRunMatcherHandler(): (params: {
9
+ artifact_path?: string;
10
+ cwd?: string;
11
+ }) => Promise<{
12
+ content: Array<{
13
+ type: "text";
14
+ text: string;
15
+ }>;
16
+ isError?: boolean;
17
+ }>;