@zivis/mcp 0.1.0-alpha.21 → 0.1.0-alpha.23
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.
- package/dist/matcher/ast-eval.d.ts +27 -0
- package/dist/matcher/ast-eval.js +132 -0
- package/dist/matcher/ast-eval.js.map +1 -0
- package/dist/matcher/finding.d.ts +76 -0
- package/dist/matcher/finding.js +14 -0
- package/dist/matcher/finding.js.map +1 -0
- package/dist/matcher/index.d.ts +30 -0
- package/dist/matcher/index.js +255 -0
- package/dist/matcher/index.js.map +1 -0
- package/dist/matcher/inference-candidates.d.ts +54 -0
- package/dist/matcher/inference-candidates.js +106 -0
- package/dist/matcher/inference-candidates.js.map +1 -0
- package/dist/matcher/walker.d.ts +14 -0
- package/dist/matcher/walker.js +79 -0
- package/dist/matcher/walker.js.map +1 -0
- package/dist/pattern-pack/index.d.ts +154 -0
- package/dist/pattern-pack/index.js +224 -0
- package/dist/pattern-pack/index.js.map +1 -0
- package/dist/pattern-packs/zivis-public-0.1.0/capsules/agents/privilege-separation.yaml +224 -0
- package/dist/pattern-packs/zivis-public-0.1.0/capsules/prompting/self-consistency-no-isolation.yaml +237 -0
- package/dist/pattern-packs/zivis-public-0.1.0/capsules/security/late-org-filter.yaml +266 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/external_validator_on_facts.yaml +37 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/human_approval_gate.yaml +44 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/langgraph_state_machine_with_per_node_tools.yaml +35 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/per_sample_retrieval_diversification.yaml +38 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/prisma_extension_or_middleware_attaching_org_filter.yaml +31 -0
- package/dist/pattern-packs/zivis-public-0.1.0/controls/row_level_security_policy.yaml +37 -0
- package/dist/pattern-packs/zivis-public-0.1.0/manifest.json +129 -0
- package/dist/pattern-packs/zivis-public-0.1.0/prompts/agents/privilege-separation/identify.md +54 -0
- package/dist/pattern-packs/zivis-public-0.1.0/prompts/prompting/self-consistency-no-isolation/identify.md +60 -0
- package/dist/pattern-packs/zivis-public-0.1.0/prompts/security/late-org-filter/identify.md +78 -0
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.js +1 -7
- package/dist/prompts/index.js.map +1 -1
- package/dist/server.js +36 -166
- package/dist/server.js.map +1 -1
- package/dist/tools/enterprise/get-threat-model-artifact.d.ts +30 -0
- package/dist/tools/enterprise/get-threat-model-artifact.js +80 -0
- package/dist/tools/enterprise/get-threat-model-artifact.js.map +1 -0
- package/dist/tools/enterprise/get-threat-model.d.ts +1 -1
- package/dist/tools/enterprise/get-threat-model.js +59 -11
- package/dist/tools/enterprise/get-threat-model.js.map +1 -1
- package/dist/tools/enterprise/list-threat-model-artifacts.d.ts +67 -0
- package/dist/tools/enterprise/list-threat-model-artifacts.js +121 -0
- package/dist/tools/enterprise/list-threat-model-artifacts.js.map +1 -0
- package/dist/tools/enterprise/manage-actor.d.ts +1 -1
- package/dist/tools/enterprise/manage-actor.js +14 -1
- package/dist/tools/enterprise/manage-actor.js.map +1 -1
- package/dist/tools/enterprise/manage-attack-scenario.d.ts +1 -1
- package/dist/tools/enterprise/manage-attack-scenario.js +13 -1
- package/dist/tools/enterprise/manage-attack-scenario.js.map +1 -1
- package/dist/tools/enterprise/manage-component.d.ts +1 -1
- package/dist/tools/enterprise/manage-component.js +20 -1
- package/dist/tools/enterprise/manage-component.js.map +1 -1
- package/dist/tools/enterprise/manage-data-asset.d.ts +2 -2
- package/dist/tools/enterprise/manage-data-asset.js +17 -1
- package/dist/tools/enterprise/manage-data-asset.js.map +1 -1
- package/dist/tools/enterprise/manage-data-flow.d.ts +2 -2
- package/dist/tools/enterprise/manage-data-flow.js +19 -1
- package/dist/tools/enterprise/manage-data-flow.js.map +1 -1
- package/dist/tools/enterprise/manage-security-control.d.ts +1 -1
- package/dist/tools/enterprise/manage-security-control.js +18 -1
- package/dist/tools/enterprise/manage-security-control.js.map +1 -1
- package/dist/tools/enterprise/manage-test-case.d.ts +2 -2
- package/dist/tools/enterprise/manage-test-case.js +8 -0
- package/dist/tools/enterprise/manage-test-case.js.map +1 -1
- package/dist/tools/get-started.d.ts +1 -1
- package/dist/tools/get-started.js +185 -8
- package/dist/tools/get-started.js.map +1 -1
- package/dist/tools/inspect.d.ts +38 -0
- package/dist/tools/inspect.js +252 -0
- package/dist/tools/inspect.js.map +1 -0
- package/dist/tools/manage-application.d.ts +1 -1
- package/dist/tools/security-review.js +67 -50
- package/dist/tools/security-review.js.map +1 -1
- package/dist/tools/threat-get-capsule.d.ts +25 -0
- package/dist/tools/threat-get-capsule.js +64 -0
- package/dist/tools/threat-get-capsule.js.map +1 -0
- package/dist/tools/threat-get-inference-prompt.d.ts +32 -0
- package/dist/tools/threat-get-inference-prompt.js +91 -0
- package/dist/tools/threat-get-inference-prompt.js.map +1 -0
- package/dist/tools/threat-guide.d.ts +39 -0
- package/dist/tools/threat-guide.js +111 -0
- package/dist/tools/threat-guide.js.map +1 -0
- package/dist/tools/threat-list-relevant-capsules.d.ts +30 -0
- package/dist/tools/threat-list-relevant-capsules.js +176 -0
- package/dist/tools/threat-list-relevant-capsules.js.map +1 -0
- package/dist/tools/threat-run-matcher.d.ts +27 -0
- package/dist/tools/threat-run-matcher.js +164 -0
- package/dist/tools/threat-run-matcher.js.map +1 -0
- package/package.json +13 -3
- package/dist/prompts/prep-for-launch.d.ts +0 -9
- package/dist/prompts/prep-for-launch.js +0 -62
- package/dist/prompts/prep-for-launch.js.map +0 -1
- package/dist/prompts/secure-my-app.d.ts +0 -9
- package/dist/prompts/secure-my-app.js +0 -70
- package/dist/prompts/secure-my-app.js.map +0 -1
- package/dist/prompts/weekly-check.d.ts +0 -9
- package/dist/prompts/weekly-check.js +0 -48
- package/dist/prompts/weekly-check.js.map +0 -1
- package/dist/tools/enterprise/capture-evidence.d.ts +0 -54
- package/dist/tools/enterprise/capture-evidence.js +0 -72
- package/dist/tools/enterprise/capture-evidence.js.map +0 -1
- package/dist/tools/enterprise/create-report-ticket.d.ts +0 -34
- package/dist/tools/enterprise/create-report-ticket.js +0 -44
- package/dist/tools/enterprise/create-report-ticket.js.map +0 -1
- package/dist/tools/enterprise/end-pentest-session.d.ts +0 -33
- package/dist/tools/enterprise/end-pentest-session.js +0 -42
- package/dist/tools/enterprise/end-pentest-session.js.map +0 -1
- package/dist/tools/enterprise/generate-report.d.ts +0 -55
- package/dist/tools/enterprise/generate-report.js +0 -111
- package/dist/tools/enterprise/generate-report.js.map +0 -1
- package/dist/tools/enterprise/get-campaign.d.ts +0 -27
- package/dist/tools/enterprise/get-campaign.js +0 -31
- package/dist/tools/enterprise/get-campaign.js.map +0 -1
- package/dist/tools/enterprise/get-report-status.d.ts +0 -27
- package/dist/tools/enterprise/get-report-status.js +0 -38
- package/dist/tools/enterprise/get-report-status.js.map +0 -1
- package/dist/tools/enterprise/list-agents.d.ts +0 -42
- package/dist/tools/enterprise/list-agents.js +0 -95
- package/dist/tools/enterprise/list-agents.js.map +0 -1
- package/dist/tools/enterprise/list-campaigns.d.ts +0 -37
- package/dist/tools/enterprise/list-campaigns.js +0 -60
- package/dist/tools/enterprise/list-campaigns.js.map +0 -1
- package/dist/tools/enterprise/list-report-issues.d.ts +0 -36
- package/dist/tools/enterprise/list-report-issues.js +0 -50
- package/dist/tools/enterprise/list-report-issues.js.map +0 -1
- package/dist/tools/enterprise/manage-campaign-agent-instance.d.ts +0 -42
- package/dist/tools/enterprise/manage-campaign-agent-instance.js +0 -68
- package/dist/tools/enterprise/manage-campaign-agent-instance.js.map +0 -1
- package/dist/tools/enterprise/manage-campaign-target.d.ts +0 -44
- package/dist/tools/enterprise/manage-campaign-target.js +0 -70
- package/dist/tools/enterprise/manage-campaign-target.js.map +0 -1
- package/dist/tools/enterprise/manage-campaign.d.ts +0 -62
- package/dist/tools/enterprise/manage-campaign.js +0 -114
- package/dist/tools/enterprise/manage-campaign.js.map +0 -1
- package/dist/tools/enterprise/manage-finding.d.ts +0 -69
- package/dist/tools/enterprise/manage-finding.js +0 -106
- package/dist/tools/enterprise/manage-finding.js.map +0 -1
- package/dist/tools/enterprise/promote-finding-to-issue.d.ts +0 -36
- package/dist/tools/enterprise/promote-finding-to-issue.js +0 -65
- package/dist/tools/enterprise/promote-finding-to-issue.js.map +0 -1
- package/dist/tools/enterprise/publish-report-version.d.ts +0 -34
- package/dist/tools/enterprise/publish-report-version.js +0 -75
- package/dist/tools/enterprise/publish-report-version.js.map +0 -1
- package/dist/tools/enterprise/publish-test-to-library.d.ts +0 -31
- package/dist/tools/enterprise/publish-test-to-library.js +0 -40
- package/dist/tools/enterprise/publish-test-to-library.js.map +0 -1
- package/dist/tools/enterprise/record-test-result.d.ts +0 -67
- package/dist/tools/enterprise/record-test-result.js +0 -75
- package/dist/tools/enterprise/record-test-result.js.map +0 -1
- package/dist/tools/enterprise/start-pentest-session.d.ts +0 -35
- package/dist/tools/enterprise/start-pentest-session.js +0 -50
- package/dist/tools/enterprise/start-pentest-session.js.map +0 -1
- package/dist/tools/enterprise/sync-report-section.d.ts +0 -41
- package/dist/tools/enterprise/sync-report-section.js +0 -79
- package/dist/tools/enterprise/sync-report-section.js.map +0 -1
- package/dist/tools/enterprise/update-report-issue.d.ts +0 -55
- package/dist/tools/enterprise/update-report-issue.js +0 -69
- package/dist/tools/enterprise/update-report-issue.js.map +0 -1
- package/dist/tools/get-agent-test-results.d.ts +0 -41
- package/dist/tools/get-agent-test-results.js +0 -86
- package/dist/tools/get-agent-test-results.js.map +0 -1
- package/dist/tools/get-application-auth-config.d.ts +0 -27
- package/dist/tools/get-application-auth-config.js +0 -44
- package/dist/tools/get-application-auth-config.js.map +0 -1
- package/dist/tools/get-artifact-content.d.ts +0 -29
- package/dist/tools/get-artifact-content.js +0 -86
- package/dist/tools/get-artifact-content.js.map +0 -1
- package/dist/tools/get-finding-details.d.ts +0 -22
- package/dist/tools/get-finding-details.js +0 -61
- package/dist/tools/get-finding-details.js.map +0 -1
- package/dist/tools/get-findings.d.ts +0 -51
- package/dist/tools/get-findings.js +0 -124
- package/dist/tools/get-findings.js.map +0 -1
- package/dist/tools/get-recon-scan.d.ts +0 -27
- package/dist/tools/get-recon-scan.js +0 -46
- package/dist/tools/get-recon-scan.js.map +0 -1
- package/dist/tools/get-scan-output.d.ts +0 -27
- package/dist/tools/get-scan-output.js +0 -64
- package/dist/tools/get-scan-output.js.map +0 -1
- package/dist/tools/get-scenario-details.d.ts +0 -27
- package/dist/tools/get-scenario-details.js +0 -46
- package/dist/tools/get-scenario-details.js.map +0 -1
- package/dist/tools/get-test-case-results.d.ts +0 -37
- package/dist/tools/get-test-case-results.js +0 -66
- package/dist/tools/get-test-case-results.js.map +0 -1
- package/dist/tools/get-test-details.d.ts +0 -29
- package/dist/tools/get-test-details.js +0 -49
- package/dist/tools/get-test-details.js.map +0 -1
- package/dist/tools/list-agent-test-cases.d.ts +0 -41
- package/dist/tools/list-agent-test-cases.js +0 -73
- package/dist/tools/list-agent-test-cases.js.map +0 -1
- package/dist/tools/list-recon-scans.d.ts +0 -36
- package/dist/tools/list-recon-scans.js +0 -74
- package/dist/tools/list-recon-scans.js.map +0 -1
- package/dist/tools/list-scan-artifacts.d.ts +0 -41
- package/dist/tools/list-scan-artifacts.js +0 -63
- package/dist/tools/list-scan-artifacts.js.map +0 -1
- package/dist/tools/list-scans.d.ts +0 -38
- package/dist/tools/list-scans.js +0 -125
- package/dist/tools/list-scans.js.map +0 -1
- package/dist/tools/list-test-library.d.ts +0 -44
- package/dist/tools/list-test-library.js +0 -83
- package/dist/tools/list-test-library.js.map +0 -1
- package/dist/tools/list-test-scenarios.d.ts +0 -25
- package/dist/tools/list-test-scenarios.js +0 -94
- package/dist/tools/list-test-scenarios.js.map +0 -1
- package/dist/tools/local-scan.d.ts +0 -40
- package/dist/tools/local-scan.js +0 -261
- package/dist/tools/local-scan.js.map +0 -1
- package/dist/tools/run-test-scenario.d.ts +0 -37
- package/dist/tools/run-test-scenario.js +0 -70
- package/dist/tools/run-test-scenario.js.map +0 -1
- package/dist/tools/scan-pr.d.ts +0 -27
- package/dist/tools/scan-pr.js +0 -51
- package/dist/tools/scan-pr.js.map +0 -1
- package/dist/tools/setup-red-team-target.d.ts +0 -73
- package/dist/tools/setup-red-team-target.js +0 -461
- package/dist/tools/setup-red-team-target.js.map +0 -1
- package/dist/tools/triage-finding.d.ts +0 -41
- package/dist/tools/triage-finding.js +0 -125
- package/dist/tools/triage-finding.js.map +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_get_inference_prompt — return the prompt bundle for a capsule's
|
|
3
|
+
* INFER strategy so the host LLM can run local inference.
|
|
4
|
+
*
|
|
5
|
+
* MCP servers cannot invoke the customer's LLM. The host (Cursor, Claude Code)
|
|
6
|
+
* runs the model. This tool returns:
|
|
7
|
+
* - the prompt template (markdown)
|
|
8
|
+
* - the capsule's expected_output_schema
|
|
9
|
+
* - the capsule's safe_summary as ambient context
|
|
10
|
+
* - guidance on which evidence spans the host should attach
|
|
11
|
+
*
|
|
12
|
+
* The host LLM consumes the bundle, gathers code spans per minimum_context_required,
|
|
13
|
+
* runs the inference, and returns structured JSON. That JSON enters the
|
|
14
|
+
* `inferred` lane until promoted to `trusted` per the platform's promotion policy.
|
|
15
|
+
*
|
|
16
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 2A)
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { loadActivePack, getCapsule, getInferencePrompt } from "../pattern-pack/index.js";
|
|
20
|
+
import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
|
|
21
|
+
export const THREAT_GET_INFERENCE_PROMPT_NAME = "zivis_threat_get_inference_prompt";
|
|
22
|
+
export const THREAT_GET_INFERENCE_PROMPT_DESCRIPTION = `Return the prompt bundle for the host LLM to run local inference for a capsule.
|
|
23
|
+
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
Use this when:
|
|
27
|
+
- After zivis_threat_get_capsule, the user wants the host LLM to actually evaluate whether the pattern is present in the code
|
|
28
|
+
- The user says "go check if my code does this" / "is this pattern actually in my repo"
|
|
29
|
+
- The matcher emits an INFER candidate that needs host-LLM evaluation
|
|
30
|
+
|
|
31
|
+
The bundle includes:
|
|
32
|
+
- prompt: the markdown inference prompt
|
|
33
|
+
- expected_output_schema: JSON Schema for the structured response
|
|
34
|
+
- safe_summary: ambient capsule context
|
|
35
|
+
- minimum_context_required: hint to the host for how much code to attach
|
|
36
|
+
- evidence_focus: spans the deterministic strategies already flagged
|
|
37
|
+
|
|
38
|
+
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.`;
|
|
39
|
+
export const THREAT_GET_INFERENCE_PROMPT_SCHEMA = {
|
|
40
|
+
capsule_id: z
|
|
41
|
+
.string()
|
|
42
|
+
.describe("Capsule id whose INFER prompt should be returned (e.g. 'agents.privilege-separation')."),
|
|
43
|
+
};
|
|
44
|
+
export function createThreatGetInferencePromptHandler() {
|
|
45
|
+
return async (params) => {
|
|
46
|
+
const handle = await loadActivePack();
|
|
47
|
+
let capsule;
|
|
48
|
+
try {
|
|
49
|
+
capsule = await getCapsule(handle, params.capsule_id);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return withNextStepsError(`Capsule '${params.capsule_id}' not found. ${err.message}`, [
|
|
53
|
+
{
|
|
54
|
+
id: "list_relevant_capsules_first",
|
|
55
|
+
label: "List relevant capsules for the current repo first",
|
|
56
|
+
tool: "zivis_threat_list_relevant_capsules",
|
|
57
|
+
why: "Returns ids you can pass back here.",
|
|
58
|
+
},
|
|
59
|
+
], "Capsule not found — list first to discover ids.");
|
|
60
|
+
}
|
|
61
|
+
if (!capsule.model_task_prompt_ref) {
|
|
62
|
+
return withNextStepsError(`Capsule '${capsule.id}' has no inference prompt defined (model_task_prompt_ref missing). This capsule is deterministic-only.`, [
|
|
63
|
+
{
|
|
64
|
+
id: "get_capsule",
|
|
65
|
+
label: "Read the full capsule to see its deterministic strategies",
|
|
66
|
+
tool: "zivis_threat_get_capsule",
|
|
67
|
+
args_hint: { capsule_id: capsule.id },
|
|
68
|
+
why: "Some capsules have no INFER strategy — only AST/GRAPH/META/etc. that the matcher runs locally.",
|
|
69
|
+
},
|
|
70
|
+
], "No inference prompt for this capsule (deterministic only).");
|
|
71
|
+
}
|
|
72
|
+
const promptText = await getInferencePrompt(handle, capsule.model_task_prompt_ref);
|
|
73
|
+
return withNextSteps({
|
|
74
|
+
pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
|
|
75
|
+
capsule_id: capsule.id,
|
|
76
|
+
prompt: promptText,
|
|
77
|
+
expected_output_schema: capsule.expected_output_schema ?? null,
|
|
78
|
+
safe_summary: capsule.safe_summary ?? null,
|
|
79
|
+
minimum_context_required: capsule.minimum_context_required ?? null,
|
|
80
|
+
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.",
|
|
81
|
+
}, [
|
|
82
|
+
{
|
|
83
|
+
id: "host_runs_inference",
|
|
84
|
+
label: "Host LLM runs inference now (no further tool call)",
|
|
85
|
+
tool: "zivis_threat_get_inference_prompt",
|
|
86
|
+
why: "MCP cannot invoke your model. The host orchestrates the inference using this bundle.",
|
|
87
|
+
},
|
|
88
|
+
], `Prompt bundle ready for host-side inference of ${capsule.id}.`);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=threat-get-inference-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-get-inference-prompt.js","sourceRoot":"","sources":["../../src/tools/threat-get-inference-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAEzE,MAAM,CAAC,MAAM,gCAAgC,GAAG,mCAAmC,CAAC;AAEpF,MAAM,CAAC,MAAM,uCAAuC,GAAG;;;;;;;;;;;;;;;;sKAgB+G,CAAC;AAEvK,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,QAAQ,CAAC,wFAAwF,CAAC;CACtG,CAAC;AAEF,MAAM,UAAU,qCAAqC;IACnD,OAAO,KAAK,EAAE,MAA8B,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;QAEtC,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,kBAAkB,CACvB,YAAY,MAAM,CAAC,UAAU,gBAAiB,GAAa,CAAC,OAAO,EAAE,EACrE;gBACE;oBACE,EAAE,EAAE,8BAA8B;oBAClC,KAAK,EAAE,mDAAmD;oBAC1D,IAAI,EAAE,qCAAqC;oBAC3C,GAAG,EAAE,qCAAqC;iBAC3C;aACF,EACD,iDAAiD,CAClD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACnC,OAAO,kBAAkB,CACvB,YAAY,OAAO,CAAC,EAAE,wGAAwG,EAC9H;gBACE;oBACE,EAAE,EAAE,aAAa;oBACjB,KAAK,EAAE,2DAA2D;oBAClE,IAAI,EAAE,0BAA0B;oBAChC,SAAS,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;oBACrC,GAAG,EAAE,gGAAgG;iBACtG;aACF,EACD,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEnF,OAAO,aAAa,CAClB;YACE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE;YACvE,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,MAAM,EAAE,UAAU;YAClB,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,IAAI,IAAI;YAC9D,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;YAC1C,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,IAAI,IAAI;YAClE,iBAAiB,EACf,+SAA+S;SAClT,EACD;YACE;gBACE,EAAE,EAAE,qBAAqB;gBACzB,KAAK,EAAE,oDAAoD;gBAC3D,IAAI,EAAE,mCAAmC;gBACzC,GAAG,EAAE,sFAAsF;aAC5F;SACF,EACD,kDAAkD,OAAO,CAAC,EAAE,GAAG,CAChE,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_guide — per-turn orchestrator for the IDE sidekick.
|
|
3
|
+
*
|
|
4
|
+
* The IDE model should call this on every conversation turn that touches
|
|
5
|
+
* code, architecture, integrations, dependencies, security, or a launch.
|
|
6
|
+
* The endpoint returns a structured next_action the model executes verbatim:
|
|
7
|
+
* call a specific CRUD tool with pre-filled args, ask one specific question,
|
|
8
|
+
* run /inspect first, or stay quiet.
|
|
9
|
+
*
|
|
10
|
+
* No graph mutations happen here — this tool only returns guidance. The
|
|
11
|
+
* downstream CRUD tools (zivis_manage_actor, zivis_manage_component, etc.)
|
|
12
|
+
* are what the model calls based on next_action.tool.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import type { ApiClient } from "../api-client.js";
|
|
16
|
+
export declare const THREAT_GUIDE_NAME = "zivis_threat_guide";
|
|
17
|
+
export declare const THREAT_GUIDE_DESCRIPTION = "Call this on every conversation turn that touches code, architecture, integrations, dependencies, security, or a launch. Returns the next concrete action to take \u2014 either a specific CRUD tool to call with pre-filled args, one specific question to ask the user, a recommendation to run /inspect first, or \"no_action\" (continue conversationally).\n\nUse this when the user says any of:\n- \"we just added <X>\" / \"we're going to integrate <X>\" / \"we're using <library>\"\n- \"<service A> calls / sends to / fetches from <service B>\"\n- describes any user role, attacker, partner, or external system\n- \"what if <bad thing>?\" / \"could someone <attack>?\" / \"is this safe?\"\n- \"we store <data type>\" / \"we process <PII / payments / credentials>\"\n- \"we added <encryption / rate limiting / WAF / audit logging>\"\n- mentions of launch, audit, compliance, customer ask, regulated buyer\n- any architecture or security clarification request\n\nHow to use the response:\n- next_action.type === \"call_tool\" \u2192 call next_action.tool with next_action.args_preview as a starting point. Confirm any unclear fields with the user briefly, then call the CRUD tool.\n- next_action.type === \"ask_user\" \u2192 ask next_action.question (use it verbatim or paraphrase). Pass the answer back through this tool on the next turn.\n- next_action.type === \"run_inspect_first\" \u2192 call zivis_inspect to bootstrap the threat model from the repo before doing anything else.\n- next_action.type === \"no_action\" \u2192 continue the conversation normally; no graph operation is needed for this turn.\n\nIf this tool returns gaps[] with priority \"high\", surface them to the user even if the immediate utterance was about something else \u2014 gaps are foundational issues blocking other work.\n\nThe tm_snapshot field is a current count of graph entities for this app; reference it when explaining state (\"you have 5 components but 0 actors\").\n\nInputs are all optional. If user_utterance is empty, the response is driven purely by the highest-priority gap \u2014 useful for \"what should I work on next?\" prompts.";
|
|
18
|
+
export declare const THREAT_GUIDE_SCHEMA: {
|
|
19
|
+
user_utterance: z.ZodOptional<z.ZodString>;
|
|
20
|
+
application_id: z.ZodOptional<z.ZodString>;
|
|
21
|
+
context_hint: z.ZodOptional<z.ZodEnum<{
|
|
22
|
+
code_change: "code_change";
|
|
23
|
+
architecture_question: "architecture_question";
|
|
24
|
+
security_worry: "security_worry";
|
|
25
|
+
feature: "feature";
|
|
26
|
+
unknown: "unknown";
|
|
27
|
+
}>>;
|
|
28
|
+
};
|
|
29
|
+
export declare function createThreatGuideHandler(apiClient: ApiClient): (params: {
|
|
30
|
+
user_utterance?: string;
|
|
31
|
+
application_id?: string;
|
|
32
|
+
context_hint?: "code_change" | "architecture_question" | "security_worry" | "feature" | "unknown";
|
|
33
|
+
}) => Promise<{
|
|
34
|
+
content: Array<{
|
|
35
|
+
type: "text";
|
|
36
|
+
text: string;
|
|
37
|
+
}>;
|
|
38
|
+
isError?: boolean;
|
|
39
|
+
}>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_guide — per-turn orchestrator for the IDE sidekick.
|
|
3
|
+
*
|
|
4
|
+
* The IDE model should call this on every conversation turn that touches
|
|
5
|
+
* code, architecture, integrations, dependencies, security, or a launch.
|
|
6
|
+
* The endpoint returns a structured next_action the model executes verbatim:
|
|
7
|
+
* call a specific CRUD tool with pre-filled args, ask one specific question,
|
|
8
|
+
* run /inspect first, or stay quiet.
|
|
9
|
+
*
|
|
10
|
+
* No graph mutations happen here — this tool only returns guidance. The
|
|
11
|
+
* downstream CRUD tools (zivis_manage_actor, zivis_manage_component, etc.)
|
|
12
|
+
* are what the model calls based on next_action.tool.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
|
|
16
|
+
export const THREAT_GUIDE_NAME = "zivis_threat_guide";
|
|
17
|
+
export const THREAT_GUIDE_DESCRIPTION = `Call this on every conversation turn that touches code, architecture, integrations, dependencies, security, or a launch. Returns the next concrete action to take — either a specific CRUD tool to call with pre-filled args, one specific question to ask the user, a recommendation to run /inspect first, or "no_action" (continue conversationally).
|
|
18
|
+
|
|
19
|
+
Use this when the user says any of:
|
|
20
|
+
- "we just added <X>" / "we're going to integrate <X>" / "we're using <library>"
|
|
21
|
+
- "<service A> calls / sends to / fetches from <service B>"
|
|
22
|
+
- describes any user role, attacker, partner, or external system
|
|
23
|
+
- "what if <bad thing>?" / "could someone <attack>?" / "is this safe?"
|
|
24
|
+
- "we store <data type>" / "we process <PII / payments / credentials>"
|
|
25
|
+
- "we added <encryption / rate limiting / WAF / audit logging>"
|
|
26
|
+
- mentions of launch, audit, compliance, customer ask, regulated buyer
|
|
27
|
+
- any architecture or security clarification request
|
|
28
|
+
|
|
29
|
+
How to use the response:
|
|
30
|
+
- next_action.type === "call_tool" → call next_action.tool with next_action.args_preview as a starting point. Confirm any unclear fields with the user briefly, then call the CRUD tool.
|
|
31
|
+
- next_action.type === "ask_user" → ask next_action.question (use it verbatim or paraphrase). Pass the answer back through this tool on the next turn.
|
|
32
|
+
- next_action.type === "run_inspect_first" → call zivis_inspect to bootstrap the threat model from the repo before doing anything else.
|
|
33
|
+
- next_action.type === "no_action" → continue the conversation normally; no graph operation is needed for this turn.
|
|
34
|
+
|
|
35
|
+
If this tool returns gaps[] with priority "high", surface them to the user even if the immediate utterance was about something else — gaps are foundational issues blocking other work.
|
|
36
|
+
|
|
37
|
+
The tm_snapshot field is a current count of graph entities for this app; reference it when explaining state ("you have 5 components but 0 actors").
|
|
38
|
+
|
|
39
|
+
Inputs are all optional. If user_utterance is empty, the response is driven purely by the highest-priority gap — useful for "what should I work on next?" prompts.`;
|
|
40
|
+
export const THREAT_GUIDE_SCHEMA = {
|
|
41
|
+
user_utterance: z
|
|
42
|
+
.string()
|
|
43
|
+
.max(2000)
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Verbatim or near-verbatim of what the user just said. Pass the user's actual words — the classifier reads phrasing cues (verbs, vendor names, role nouns). Omit only when the user is asking 'what should I do next?' with no specific topic."),
|
|
46
|
+
application_id: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Application UUID. If omitted, uses applicationId from .zivis/project.json when set. Required when the binding doesn't resolve a unique app."),
|
|
50
|
+
context_hint: z
|
|
51
|
+
.enum(["code_change", "architecture_question", "security_worry", "feature", "unknown"])
|
|
52
|
+
.optional()
|
|
53
|
+
.describe("Optional hint about the kind of turn this is. Helps the classifier disambiguate. If unsure, omit or pass 'unknown'."),
|
|
54
|
+
};
|
|
55
|
+
export function createThreatGuideHandler(apiClient) {
|
|
56
|
+
return async (params) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await apiClient.request("POST", "/api/mcp/guide", {
|
|
59
|
+
user_utterance: params.user_utterance,
|
|
60
|
+
application_id: params.application_id,
|
|
61
|
+
context_hint: params.context_hint,
|
|
62
|
+
});
|
|
63
|
+
// Translate next_action into a guidance next-step the LLM can act on.
|
|
64
|
+
const next = result.next_action;
|
|
65
|
+
const nextSteps = [];
|
|
66
|
+
if (next.type === "call_tool") {
|
|
67
|
+
nextSteps.push({
|
|
68
|
+
id: "execute_suggested_tool",
|
|
69
|
+
label: `Call ${next.tool} with the suggested args`,
|
|
70
|
+
tool: String(next.tool),
|
|
71
|
+
args_hint: next.args_preview ?? {},
|
|
72
|
+
why: next.follow_up ??
|
|
73
|
+
"The threat-guide endpoint mapped this utterance to a concrete graph operation.",
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (next.type === "ask_user") {
|
|
77
|
+
nextSteps.push({
|
|
78
|
+
id: "ask_clarifying_question",
|
|
79
|
+
label: "Ask the user this clarifying question",
|
|
80
|
+
tool: "zivis_threat_guide",
|
|
81
|
+
args_hint: {},
|
|
82
|
+
why: String(next.question ?? "Need more info before acting on the graph."),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else if (next.type === "run_inspect_first") {
|
|
86
|
+
nextSteps.push({
|
|
87
|
+
id: "run_inspect",
|
|
88
|
+
label: "Run /inspect to bootstrap the threat model from the repo",
|
|
89
|
+
tool: "zivis_inspect",
|
|
90
|
+
args_hint: {},
|
|
91
|
+
why: "The threat model is empty — bootstrap from the repo before modeling further.",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return withNextSteps(result, nextSteps, next.type === "no_action"
|
|
95
|
+
? "No graph operation needed for this turn — continue conversationally."
|
|
96
|
+
: `Next: ${next.type === "call_tool" ? `call ${next.tool}` : next.type === "ask_user" ? "ask the clarifying question" : next.type}`);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
const message = err instanceof Error ? err.message : "threat_guide call failed";
|
|
100
|
+
return withNextStepsError(message, [
|
|
101
|
+
{
|
|
102
|
+
id: "check_project",
|
|
103
|
+
label: "Verify project binding + auth",
|
|
104
|
+
tool: "zivis_check_project",
|
|
105
|
+
why: "If the call failed because of auth or binding, this surfaces the specific fix.",
|
|
106
|
+
},
|
|
107
|
+
], "threat_guide call failed — check binding/auth.");
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=threat-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-guide.js","sourceRoot":"","sources":["../../src/tools/threat-guide.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_list_relevant_capsules — surface threat-model patterns
|
|
3
|
+
* relevant to the user's current repo, mid-IDE-conversation.
|
|
4
|
+
*
|
|
5
|
+
* Reads the latest RepoGraphArtifactV1 from the user cache, evaluates
|
|
6
|
+
* every capsule's relevance_filter against it, and returns the matching
|
|
7
|
+
* capsules with their safe_summary so the host LLM can frame the
|
|
8
|
+
* conversation in threat-model terms.
|
|
9
|
+
*
|
|
10
|
+
* Tier 1 / public pack only. Proprietary patterns are evaluated platform-side.
|
|
11
|
+
*
|
|
12
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 2A)
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
export declare const THREAT_LIST_RELEVANT_CAPSULES_NAME = "zivis_threat_list_relevant_capsules";
|
|
16
|
+
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.";
|
|
17
|
+
export declare const THREAT_LIST_RELEVANT_CAPSULES_SCHEMA: {
|
|
18
|
+
artifact_path: z.ZodOptional<z.ZodString>;
|
|
19
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
20
|
+
};
|
|
21
|
+
export declare function createThreatListRelevantCapsulesHandler(): (params: {
|
|
22
|
+
artifact_path?: string;
|
|
23
|
+
cwd?: string;
|
|
24
|
+
}) => Promise<{
|
|
25
|
+
content: Array<{
|
|
26
|
+
type: "text";
|
|
27
|
+
text: string;
|
|
28
|
+
}>;
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_list_relevant_capsules — surface threat-model patterns
|
|
3
|
+
* relevant to the user's current repo, mid-IDE-conversation.
|
|
4
|
+
*
|
|
5
|
+
* Reads the latest RepoGraphArtifactV1 from the user cache, evaluates
|
|
6
|
+
* every capsule's relevance_filter against it, and returns the matching
|
|
7
|
+
* capsules with their safe_summary so the host LLM can frame the
|
|
8
|
+
* conversation in threat-model terms.
|
|
9
|
+
*
|
|
10
|
+
* Tier 1 / public pack only. Proprietary patterns are evaluated platform-side.
|
|
11
|
+
*
|
|
12
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 2A)
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import * as fs from "node:fs/promises";
|
|
16
|
+
import * as fssync from "node:fs";
|
|
17
|
+
import * as os from "node:os";
|
|
18
|
+
import * as path from "node:path";
|
|
19
|
+
import { loadActivePack, findRelevantCapsules, } from "../pattern-pack/index.js";
|
|
20
|
+
import { withNextSteps, withNextStepsError } from "../lib/next-steps.js";
|
|
21
|
+
export const THREAT_LIST_RELEVANT_CAPSULES_NAME = "zivis_threat_list_relevant_capsules";
|
|
22
|
+
export const THREAT_LIST_RELEVANT_CAPSULES_DESCRIPTION = `List threat-model patterns relevant to the user's current repo.
|
|
23
|
+
|
|
24
|
+
Use this when the user asks any of:
|
|
25
|
+
- "what should I be worried about in this code"
|
|
26
|
+
- "what threats apply to my app"
|
|
27
|
+
- "are there known patterns that match my architecture"
|
|
28
|
+
- "what's in my threat model"
|
|
29
|
+
- mid-conversation when the user describes a feature that touches deps the threat library covers
|
|
30
|
+
|
|
31
|
+
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).
|
|
32
|
+
|
|
33
|
+
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.`;
|
|
34
|
+
export const THREAT_LIST_RELEVANT_CAPSULES_SCHEMA = {
|
|
35
|
+
artifact_path: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.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."),
|
|
39
|
+
cwd: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Working directory whose repo cache to search (defaults to server cwd)."),
|
|
43
|
+
};
|
|
44
|
+
export function createThreatListRelevantCapsulesHandler() {
|
|
45
|
+
return async (params) => {
|
|
46
|
+
const cwd = params.cwd ?? process.cwd();
|
|
47
|
+
let artifact;
|
|
48
|
+
let artifactPath;
|
|
49
|
+
try {
|
|
50
|
+
const resolved = await resolveArtifactPath(params.artifact_path, cwd);
|
|
51
|
+
artifactPath = resolved;
|
|
52
|
+
const raw = await fs.readFile(resolved, "utf8");
|
|
53
|
+
artifact = JSON.parse(raw);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
return withNextStepsError(`No repo graph artifact found. ${err.message}`, [
|
|
57
|
+
{
|
|
58
|
+
id: "run_zivis_inspect",
|
|
59
|
+
label: "Run `zivis inspect` to build the local repo graph",
|
|
60
|
+
tool: "zivis_inspect",
|
|
61
|
+
why: "The relevance evaluation reads from the latest inspect run in the user cache.",
|
|
62
|
+
},
|
|
63
|
+
], "Run `zivis inspect` first; this tool reads from its output.");
|
|
64
|
+
}
|
|
65
|
+
const handle = await loadActivePack();
|
|
66
|
+
const relevant = await findRelevantCapsules(handle, artifact);
|
|
67
|
+
const summaries = relevant.map((cap) => ({
|
|
68
|
+
id: cap.id,
|
|
69
|
+
title: cap.title,
|
|
70
|
+
category: cap.category,
|
|
71
|
+
safe_summary: cap.safe_summary,
|
|
72
|
+
applicable_languages: cap.applicable_languages,
|
|
73
|
+
matched_on: matchedTerms(cap, artifact),
|
|
74
|
+
}));
|
|
75
|
+
return withNextSteps({
|
|
76
|
+
artifact_path: artifactPath,
|
|
77
|
+
pack: { id: handle.manifest.pack_id, version: handle.manifest.version },
|
|
78
|
+
languages_in_scope: artifact.scope.languages ?? [],
|
|
79
|
+
relevant_count: summaries.length,
|
|
80
|
+
relevant_capsules: summaries,
|
|
81
|
+
}, summaries.length > 0
|
|
82
|
+
? [
|
|
83
|
+
{
|
|
84
|
+
id: "get_capsule_details",
|
|
85
|
+
label: "Pull the full capsule for any item the user wants to investigate",
|
|
86
|
+
tool: "zivis_threat_get_capsule",
|
|
87
|
+
why: "The full capsule has threats (with STRIDE), risk_hints, repair_contract, related_patterns.",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "get_inference_prompt",
|
|
91
|
+
label: "Get the inference prompt for the host LLM to run a deeper check",
|
|
92
|
+
tool: "zivis_threat_get_inference_prompt",
|
|
93
|
+
why: "INFER strategies in each capsule reference a prompt template the user's IDE model executes.",
|
|
94
|
+
},
|
|
95
|
+
]
|
|
96
|
+
: [
|
|
97
|
+
{
|
|
98
|
+
id: "no_relevant_patterns",
|
|
99
|
+
label: "No public-pack patterns matched this repo",
|
|
100
|
+
tool: "zivis_threat_list_relevant_capsules",
|
|
101
|
+
why: "This is normal for repos without agentic / RAG / self-consistency / multi-tenant patterns. Proprietary patterns may still apply server-side.",
|
|
102
|
+
},
|
|
103
|
+
], summaries.length > 0
|
|
104
|
+
? `Found ${summaries.length} relevant capsule(s) in the threat library.`
|
|
105
|
+
: "No public-pack capsules matched this repo. Proprietary patterns evaluated server-side may still apply.");
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ── Helpers ──
|
|
109
|
+
function userCacheRoot() {
|
|
110
|
+
const home = os.homedir();
|
|
111
|
+
if (process.platform === "darwin") {
|
|
112
|
+
return path.join(home, "Library", "Caches", "zivis");
|
|
113
|
+
}
|
|
114
|
+
if (process.platform === "win32") {
|
|
115
|
+
const localAppData = process.env.LOCALAPPDATA ?? path.join(home, "AppData", "Local");
|
|
116
|
+
return path.join(localAppData, "zivis", "Cache");
|
|
117
|
+
}
|
|
118
|
+
const xdg = process.env.XDG_CACHE_HOME;
|
|
119
|
+
return path.join(xdg ?? path.join(home, ".cache"), "zivis");
|
|
120
|
+
}
|
|
121
|
+
async function resolveArtifactPath(explicit, cwd) {
|
|
122
|
+
if (explicit) {
|
|
123
|
+
if (!fssync.existsSync(explicit)) {
|
|
124
|
+
throw new Error(`Artifact path does not exist: ${explicit}`);
|
|
125
|
+
}
|
|
126
|
+
return explicit;
|
|
127
|
+
}
|
|
128
|
+
const reposRoot = path.join(userCacheRoot(), "repos");
|
|
129
|
+
if (!fssync.existsSync(reposRoot)) {
|
|
130
|
+
throw new Error(`No inspect cache found at ${reposRoot}. Run \`zivis inspect\` from the repo to populate it.`);
|
|
131
|
+
}
|
|
132
|
+
// Best-effort: find the newest .json under any repo's inspect/runs/ directory.
|
|
133
|
+
// The future improvement is to derive the repo-id from cwd's git remote and
|
|
134
|
+
// pick its newest run only.
|
|
135
|
+
const candidates = [];
|
|
136
|
+
for (const repo of await fs.readdir(reposRoot, { withFileTypes: true })) {
|
|
137
|
+
if (!repo.isDirectory())
|
|
138
|
+
continue;
|
|
139
|
+
const runs = path.join(reposRoot, repo.name, "inspect", "runs");
|
|
140
|
+
if (!fssync.existsSync(runs))
|
|
141
|
+
continue;
|
|
142
|
+
for (const entry of await fs.readdir(runs)) {
|
|
143
|
+
if (!entry.endsWith(".json"))
|
|
144
|
+
continue;
|
|
145
|
+
const full = path.join(runs, entry);
|
|
146
|
+
const stat = await fs.stat(full);
|
|
147
|
+
candidates.push({ file: full, mtime: stat.mtimeMs });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (candidates.length === 0) {
|
|
151
|
+
throw new Error(`No inspect runs found under ${reposRoot}. Run \`zivis inspect\` from the repo to produce one.`);
|
|
152
|
+
}
|
|
153
|
+
candidates.sort((a, b) => b.mtime - a.mtime);
|
|
154
|
+
return candidates[0].file;
|
|
155
|
+
}
|
|
156
|
+
function matchedTerms(cap, artifact) {
|
|
157
|
+
const matched = [];
|
|
158
|
+
const pkgs = new Set();
|
|
159
|
+
for (const node of artifact.nodes) {
|
|
160
|
+
if (node.type === "external_dependency" && node.attributes?.package) {
|
|
161
|
+
pkgs.add(node.attributes.package);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const langs = new Set(artifact.scope.languages ?? []);
|
|
165
|
+
const f = cap.relevance_filter;
|
|
166
|
+
if (!f)
|
|
167
|
+
return ["always-applicable (no relevance_filter set)"];
|
|
168
|
+
for (const term of [...(f.any_of ?? []), ...(f.all_of ?? [])]) {
|
|
169
|
+
if (term.dependency && pkgs.has(term.dependency))
|
|
170
|
+
matched.push(`dep:${term.dependency}`);
|
|
171
|
+
if (term.language && langs.has(term.language))
|
|
172
|
+
matched.push(`language:${term.language}`);
|
|
173
|
+
}
|
|
174
|
+
return matched.length > 0 ? matched : ["language match only"];
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=threat-list-relevant-capsules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-list-relevant-capsules.js","sourceRoot":"","sources":["../../src/tools/threat-list-relevant-capsules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zivis_threat_run_matcher — evaluate the local pack against a repo graph
|
|
3
|
+
* artifact + the source files in cwd.
|
|
4
|
+
*
|
|
5
|
+
* Phase 3 v1: AST strategies eval for real (via @ast-grep/napi). INFER
|
|
6
|
+
* strategies emit candidates the host LLM picks up. GRAPH/META/etc. are
|
|
7
|
+
* surfaced as fired_strategies with match_count: 0 (visible-not-evaluated).
|
|
8
|
+
*
|
|
9
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 3)
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
export declare const THREAT_RUN_MATCHER_NAME = "zivis_threat_run_matcher";
|
|
13
|
+
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.";
|
|
14
|
+
export declare const THREAT_RUN_MATCHER_SCHEMA: {
|
|
15
|
+
artifact_path: z.ZodOptional<z.ZodString>;
|
|
16
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
17
|
+
};
|
|
18
|
+
export declare function createThreatRunMatcherHandler(): (params: {
|
|
19
|
+
artifact_path?: string;
|
|
20
|
+
cwd?: string;
|
|
21
|
+
}) => Promise<{
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: "text";
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
isError?: boolean;
|
|
27
|
+
}>;
|