@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,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregate inference candidates from matcher findings into a top-level
|
|
3
|
+
* bundle the host LLM can't ignore.
|
|
4
|
+
*
|
|
5
|
+
* The matcher already attaches `inference_candidate` to each finding (when
|
|
6
|
+
* the capsule has an INFER strategy with model_task_prompt_ref), but if
|
|
7
|
+
* the host LLM only reads the headline it'll never call
|
|
8
|
+
* `zivis_threat_get_inference_prompt` and the inference never happens.
|
|
9
|
+
*
|
|
10
|
+
* This module promotes inference candidates to a structured top-level
|
|
11
|
+
* `inference_candidates[]` block with the prompt text bundled inline,
|
|
12
|
+
* plus a `host_required_action` directive. The host LLM gets everything
|
|
13
|
+
* it needs to run inference in one tool result — no extra calls.
|
|
14
|
+
*
|
|
15
|
+
* This is "Option A" from the local-inference triage. Modes B (local LLM
|
|
16
|
+
* sidecar) and C (ZIVIS-hosted cloud inference) are roadmap items.
|
|
17
|
+
*/
|
|
18
|
+
import { loadActivePack, getInferencePrompt, } from "../pattern-pack/index.js";
|
|
19
|
+
/**
|
|
20
|
+
* Build the inline inference bundle for a list of findings. Loads the pack
|
|
21
|
+
* once, fetches each capsule's inference prompt, and packages it with the
|
|
22
|
+
* deterministic-strategy evidence so the host can run inference without
|
|
23
|
+
* any further MCP round-trip.
|
|
24
|
+
*/
|
|
25
|
+
export async function buildInferenceBundle(findings, capsuleByPatternId) {
|
|
26
|
+
const candidates = [];
|
|
27
|
+
let handle;
|
|
28
|
+
for (let i = 0; i < findings.length; i++) {
|
|
29
|
+
const f = findings[i];
|
|
30
|
+
if (!f.inference_candidate)
|
|
31
|
+
continue;
|
|
32
|
+
if (!handle) {
|
|
33
|
+
try {
|
|
34
|
+
handle = await loadActivePack();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// No pack — emit candidates without inline prompt; host falls back to get_inference_prompt.
|
|
38
|
+
candidates.push(toFallbackCandidate(f, i));
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let promptText;
|
|
43
|
+
try {
|
|
44
|
+
promptText = await getInferencePrompt(handle, f.inference_candidate.prompt_ref);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
candidates.push(toFallbackCandidate(f, i));
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const cap = capsuleByPatternId?.get(f.pattern_id);
|
|
51
|
+
candidates.push({
|
|
52
|
+
candidate_id: `ic-${i + 1}`,
|
|
53
|
+
capsule_id: f.pattern_id,
|
|
54
|
+
capsule_version: f.pattern_version,
|
|
55
|
+
pattern_title: cap?.title,
|
|
56
|
+
prompt: promptText,
|
|
57
|
+
expected_output_schema: f.inference_candidate.expected_output_schema ?? null,
|
|
58
|
+
evidence_focus: f.evidence
|
|
59
|
+
.filter((e) => e.file !== "(synthetic)")
|
|
60
|
+
.map((e) => ({
|
|
61
|
+
file: e.file,
|
|
62
|
+
start_line: e.start_line,
|
|
63
|
+
end_line: e.end_line,
|
|
64
|
+
note: e.matched_text ? e.matched_text.slice(0, 200) : undefined,
|
|
65
|
+
})),
|
|
66
|
+
minimum_context_required: f.inference_candidate.minimum_context_required,
|
|
67
|
+
instructions_for_host: "Read the source code at each evidence_focus[*].file:start_line — pull at least minimum_context_required.lines around each span. " +
|
|
68
|
+
"Attach those snippets to the prompt above. Run the prompt against your model. " +
|
|
69
|
+
"Return JSON matching expected_output_schema. The output enters the inferred lane.",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const action = buildHostRequiredAction(candidates);
|
|
73
|
+
return { inference_candidates: candidates, host_required_action: action };
|
|
74
|
+
}
|
|
75
|
+
function toFallbackCandidate(f, i) {
|
|
76
|
+
return {
|
|
77
|
+
candidate_id: `ic-${i + 1}`,
|
|
78
|
+
capsule_id: f.pattern_id,
|
|
79
|
+
capsule_version: f.pattern_version,
|
|
80
|
+
prompt: "",
|
|
81
|
+
expected_output_schema: f.inference_candidate?.expected_output_schema ?? null,
|
|
82
|
+
evidence_focus: f.evidence
|
|
83
|
+
.filter((e) => e.file !== "(synthetic)")
|
|
84
|
+
.map((e) => ({
|
|
85
|
+
file: e.file,
|
|
86
|
+
start_line: e.start_line,
|
|
87
|
+
end_line: e.end_line,
|
|
88
|
+
})),
|
|
89
|
+
minimum_context_required: f.inference_candidate?.minimum_context_required,
|
|
90
|
+
instructions_for_host: "Inline prompt unavailable. Call zivis_threat_get_inference_prompt with capsule_id=" +
|
|
91
|
+
f.pattern_id +
|
|
92
|
+
" to retrieve it.",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function buildHostRequiredAction(candidates) {
|
|
96
|
+
if (candidates.length === 0) {
|
|
97
|
+
return "No inference candidates emitted by this run. Findings are deterministic-only.";
|
|
98
|
+
}
|
|
99
|
+
return (`MANDATORY HOST ACTION: For each of the ${candidates.length} inference_candidate${candidates.length === 1 ? "" : "s"} below, ` +
|
|
100
|
+
`you MUST: (1) read the source code at evidence_focus[*].file:start_line (open each file, grab at least minimum_context_required.lines of surrounding context), ` +
|
|
101
|
+
`(2) run the candidate's prompt against your model with that source attached, ` +
|
|
102
|
+
`(3) produce JSON output matching expected_output_schema. ` +
|
|
103
|
+
`Do this BEFORE summarizing findings to the user — the inferred-lane verdict from your inference is what the user actually wants. ` +
|
|
104
|
+
`Each candidate is a self-contained inference task; you do not need to call any other ZIVIS tool to execute it.`);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=inference-candidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inference-candidates.js","sourceRoot":"","sources":["../../src/matcher/inference-candidates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal source-file walker for the matcher.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the extractor's walker conventions (hard-skip dirs, file cap,
|
|
5
|
+
* .gitignore awareness via plain readdir) but stays self-contained inside
|
|
6
|
+
* the MCP package so the matcher can run without dragging in the CLI.
|
|
7
|
+
*/
|
|
8
|
+
export type WalkLanguage = "typescript" | "javascript" | "python" | "go";
|
|
9
|
+
export interface WalkResult {
|
|
10
|
+
filesByLanguage: Map<WalkLanguage, string[]>;
|
|
11
|
+
filesScanned: number;
|
|
12
|
+
filesSkipped: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function walkLanguageFiles(rootDir: string, languages: WalkLanguage[]): Promise<WalkResult>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal source-file walker for the matcher.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the extractor's walker conventions (hard-skip dirs, file cap,
|
|
5
|
+
* .gitignore awareness via plain readdir) but stays self-contained inside
|
|
6
|
+
* the MCP package so the matcher can run without dragging in the CLI.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from "node:fs/promises";
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
const HARD_SKIP_DIRS = new Set([
|
|
11
|
+
"node_modules",
|
|
12
|
+
".git",
|
|
13
|
+
".yarn",
|
|
14
|
+
".pnpm",
|
|
15
|
+
"dist",
|
|
16
|
+
"build",
|
|
17
|
+
"out",
|
|
18
|
+
".next",
|
|
19
|
+
".nuxt",
|
|
20
|
+
".turbo",
|
|
21
|
+
".cache",
|
|
22
|
+
"coverage",
|
|
23
|
+
"vendor",
|
|
24
|
+
"__pycache__",
|
|
25
|
+
".venv",
|
|
26
|
+
"target",
|
|
27
|
+
]);
|
|
28
|
+
const MAX_FILES = 50_000;
|
|
29
|
+
const LANG_EXTENSIONS = {
|
|
30
|
+
typescript: [".ts", ".tsx"],
|
|
31
|
+
javascript: [".js", ".jsx", ".mjs", ".cjs"],
|
|
32
|
+
python: [".py"],
|
|
33
|
+
go: [".go"],
|
|
34
|
+
};
|
|
35
|
+
export async function walkLanguageFiles(rootDir, languages) {
|
|
36
|
+
const extToLang = new Map();
|
|
37
|
+
for (const lang of languages) {
|
|
38
|
+
for (const ext of LANG_EXTENSIONS[lang])
|
|
39
|
+
extToLang.set(ext, lang);
|
|
40
|
+
}
|
|
41
|
+
const filesByLanguage = new Map();
|
|
42
|
+
for (const lang of languages)
|
|
43
|
+
filesByLanguage.set(lang, []);
|
|
44
|
+
let filesScanned = 0;
|
|
45
|
+
let filesSkipped = 0;
|
|
46
|
+
const total = () => Array.from(filesByLanguage.values()).reduce((n, l) => n + l.length, 0);
|
|
47
|
+
async function visit(dirAbs) {
|
|
48
|
+
if (total() >= MAX_FILES)
|
|
49
|
+
return;
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = await fs.readdir(dirAbs, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (entry.isDirectory()) {
|
|
59
|
+
if (HARD_SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) {
|
|
60
|
+
filesSkipped++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
await visit(path.join(dirAbs, entry.name));
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!entry.isFile() && !entry.isSymbolicLink())
|
|
67
|
+
continue;
|
|
68
|
+
filesScanned++;
|
|
69
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
70
|
+
const lang = extToLang.get(ext);
|
|
71
|
+
if (lang) {
|
|
72
|
+
filesByLanguage.get(lang).push(path.join(dirAbs, entry.name));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
await visit(rootDir);
|
|
77
|
+
return { filesByLanguage, filesScanned, filesSkipped };
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walker.js","sourceRoot":"","sources":["../../src/matcher/walker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local pattern pack reader.
|
|
3
|
+
*
|
|
4
|
+
* The pack ships bundled inside the @zivis/mcp npm package at
|
|
5
|
+
* `dist/pattern-packs/<pack-id>-<version>/`. On first use we copy it to
|
|
6
|
+
* `~/Library/Caches/zivis/pattern-packs/<pack-id>-<version>/` so future
|
|
7
|
+
* runs read from the user cache directly.
|
|
8
|
+
*
|
|
9
|
+
* Both the CLI's matcher (Phase 3) and the MCP tools that surface
|
|
10
|
+
* relevant capsules mid-IDE-conversation read through this module.
|
|
11
|
+
*
|
|
12
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 2A)
|
|
13
|
+
* Schemas:
|
|
14
|
+
* - schemas/pattern-pack-manifest.schema.json (manifest.json)
|
|
15
|
+
* - schemas/pattern-detection-card.schema.json (capsule yaml)
|
|
16
|
+
*/
|
|
17
|
+
export interface PackManifest {
|
|
18
|
+
schema_version: "1.0.0";
|
|
19
|
+
pack_id: string;
|
|
20
|
+
pack_name: string;
|
|
21
|
+
version: string;
|
|
22
|
+
built_at: string;
|
|
23
|
+
tier: "public_teaser" | "public" | "customer_safe";
|
|
24
|
+
description?: string;
|
|
25
|
+
capsules: ManifestCapsuleEntry[];
|
|
26
|
+
prompts: ManifestPromptEntry[];
|
|
27
|
+
controls?: ManifestControlEntry[];
|
|
28
|
+
}
|
|
29
|
+
export interface ManifestCapsuleEntry {
|
|
30
|
+
id: string;
|
|
31
|
+
version: string;
|
|
32
|
+
path: string;
|
|
33
|
+
sha256: string;
|
|
34
|
+
category?: string;
|
|
35
|
+
lifecycle?: string;
|
|
36
|
+
applicable_languages?: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface ManifestPromptEntry {
|
|
39
|
+
path: string;
|
|
40
|
+
sha256: string;
|
|
41
|
+
capsule_id?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ManifestControlEntry {
|
|
44
|
+
id: string;
|
|
45
|
+
path: string;
|
|
46
|
+
sha256: string;
|
|
47
|
+
applicable_languages?: string[];
|
|
48
|
+
}
|
|
49
|
+
export interface ControlDetectionRule {
|
|
50
|
+
language: "typescript" | "javascript" | "python" | "go";
|
|
51
|
+
rule: unknown;
|
|
52
|
+
}
|
|
53
|
+
export interface Control {
|
|
54
|
+
id: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
applicable_languages: string[];
|
|
57
|
+
detection: ControlDetectionRule[];
|
|
58
|
+
lifecycle?: string;
|
|
59
|
+
owner?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface RelevanceTerm {
|
|
62
|
+
dependency?: string;
|
|
63
|
+
direct_only?: boolean;
|
|
64
|
+
language?: string;
|
|
65
|
+
framework?: string;
|
|
66
|
+
evidence?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface RelevanceFilter {
|
|
69
|
+
any_of?: RelevanceTerm[];
|
|
70
|
+
all_of?: RelevanceTerm[];
|
|
71
|
+
none_of?: RelevanceTerm[];
|
|
72
|
+
}
|
|
73
|
+
export interface Capsule {
|
|
74
|
+
id: string;
|
|
75
|
+
slug: string;
|
|
76
|
+
version: string;
|
|
77
|
+
category: string;
|
|
78
|
+
title?: string;
|
|
79
|
+
headline?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
detection_tier: "public" | "proprietary";
|
|
82
|
+
scoring_tier: "public" | "proprietary";
|
|
83
|
+
applicable_languages: string[];
|
|
84
|
+
relevance_filter?: RelevanceFilter;
|
|
85
|
+
strategies: unknown[];
|
|
86
|
+
required_evidence_count: number;
|
|
87
|
+
threats?: unknown[];
|
|
88
|
+
lifecycle: "draft" | "active" | "deprecated";
|
|
89
|
+
sensitivity_level?: "public_teaser" | "customer_safe" | "zivis_confidential";
|
|
90
|
+
safe_summary?: string;
|
|
91
|
+
detect_when?: string;
|
|
92
|
+
risk_hints?: string[];
|
|
93
|
+
architectural_signals?: string[];
|
|
94
|
+
model_task_prompt_ref?: string;
|
|
95
|
+
expected_output_schema?: unknown;
|
|
96
|
+
minimum_context_required?: {
|
|
97
|
+
lines?: number;
|
|
98
|
+
symbols?: string[];
|
|
99
|
+
};
|
|
100
|
+
related_patterns?: string[];
|
|
101
|
+
repair_contract?: {
|
|
102
|
+
allowed?: string[];
|
|
103
|
+
forbidden?: string[];
|
|
104
|
+
};
|
|
105
|
+
validation_contract?: {
|
|
106
|
+
requires_tests_pass?: boolean;
|
|
107
|
+
requires_static_rules?: string[];
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export interface PackHandle {
|
|
111
|
+
manifest: PackManifest;
|
|
112
|
+
rootDir: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Minimal structural interface of a RepoGraphArtifactV1 that the reader
|
|
116
|
+
* actually needs. Lets this module avoid a hard dep on the full graph-types
|
|
117
|
+
* package while preserving compatibility with `RepoGraphArtifactV1`.
|
|
118
|
+
*/
|
|
119
|
+
export interface GraphArtifactView {
|
|
120
|
+
scope: {
|
|
121
|
+
languages?: string[];
|
|
122
|
+
};
|
|
123
|
+
nodes: Array<{
|
|
124
|
+
type: string;
|
|
125
|
+
evidence: Array<{
|
|
126
|
+
kind: string;
|
|
127
|
+
}>;
|
|
128
|
+
attributes?: {
|
|
129
|
+
package?: string;
|
|
130
|
+
};
|
|
131
|
+
}>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Locate the active pack and ensure it's available in the user cache.
|
|
135
|
+
*
|
|
136
|
+
* Resolution order:
|
|
137
|
+
* 1. ZIVIS_PACK_DIR env var (override for tests / enterprise air-gap imports)
|
|
138
|
+
* 2. User cache, if present
|
|
139
|
+
* 3. Bundled pack inside @zivis/mcp (copied to user cache on first use)
|
|
140
|
+
*/
|
|
141
|
+
export declare function loadActivePack(packId?: string): Promise<PackHandle>;
|
|
142
|
+
export declare function getCapsule(handle: PackHandle, capsuleId: string): Promise<Capsule>;
|
|
143
|
+
export declare function getInferencePrompt(handle: PackHandle, ref: string): Promise<string>;
|
|
144
|
+
export declare function listCapsuleIds(handle: PackHandle): Promise<string[]>;
|
|
145
|
+
export declare function listControlIds(handle: PackHandle): Promise<string[]>;
|
|
146
|
+
export declare function getControl(handle: PackHandle, controlId: string): Promise<Control>;
|
|
147
|
+
export declare function findRelevantCapsules(handle: PackHandle, artifact: GraphArtifactView): Promise<Capsule[]>;
|
|
148
|
+
interface EvalContext {
|
|
149
|
+
packageNames: Set<string>;
|
|
150
|
+
languages: Set<string>;
|
|
151
|
+
evidenceKinds: Set<string>;
|
|
152
|
+
}
|
|
153
|
+
export declare function matchesRelevance(cap: Capsule, ctx: EvalContext): boolean;
|
|
154
|
+
export {};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local pattern pack reader.
|
|
3
|
+
*
|
|
4
|
+
* The pack ships bundled inside the @zivis/mcp npm package at
|
|
5
|
+
* `dist/pattern-packs/<pack-id>-<version>/`. On first use we copy it to
|
|
6
|
+
* `~/Library/Caches/zivis/pattern-packs/<pack-id>-<version>/` so future
|
|
7
|
+
* runs read from the user cache directly.
|
|
8
|
+
*
|
|
9
|
+
* Both the CLI's matcher (Phase 3) and the MCP tools that surface
|
|
10
|
+
* relevant capsules mid-IDE-conversation read through this module.
|
|
11
|
+
*
|
|
12
|
+
* Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 2A)
|
|
13
|
+
* Schemas:
|
|
14
|
+
* - schemas/pattern-pack-manifest.schema.json (manifest.json)
|
|
15
|
+
* - schemas/pattern-detection-card.schema.json (capsule yaml)
|
|
16
|
+
*/
|
|
17
|
+
import * as fs from "node:fs/promises";
|
|
18
|
+
import * as fssync from "node:fs";
|
|
19
|
+
import * as os from "node:os";
|
|
20
|
+
import * as path from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import * as crypto from "node:crypto";
|
|
23
|
+
import * as yaml from "js-yaml";
|
|
24
|
+
// ── Cache layout ──
|
|
25
|
+
function userCacheRoot() {
|
|
26
|
+
const home = os.homedir();
|
|
27
|
+
if (process.platform === "darwin") {
|
|
28
|
+
return path.join(home, "Library", "Caches", "zivis");
|
|
29
|
+
}
|
|
30
|
+
if (process.platform === "win32") {
|
|
31
|
+
const localAppData = process.env.LOCALAPPDATA ?? path.join(home, "AppData", "Local");
|
|
32
|
+
return path.join(localAppData, "zivis", "Cache");
|
|
33
|
+
}
|
|
34
|
+
const xdg = process.env.XDG_CACHE_HOME;
|
|
35
|
+
return path.join(xdg ?? path.join(home, ".cache"), "zivis");
|
|
36
|
+
}
|
|
37
|
+
function userPackRoot() {
|
|
38
|
+
return path.join(userCacheRoot(), "pattern-packs");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Locate the pack bundled inside the @zivis/mcp npm install. We resolve
|
|
42
|
+
* from this module's own URL so it works whether the MCP is installed
|
|
43
|
+
* globally, locally, or run via pnpm workspace symlink.
|
|
44
|
+
*/
|
|
45
|
+
function bundledPackRoot() {
|
|
46
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
47
|
+
// dist layout: dist/pattern-pack/index.js → dist/pattern-packs
|
|
48
|
+
return path.resolve(here, "../pattern-packs");
|
|
49
|
+
}
|
|
50
|
+
const DEFAULT_PACK_ID = "zivis-public";
|
|
51
|
+
// ── Loader ──
|
|
52
|
+
/**
|
|
53
|
+
* Locate the active pack and ensure it's available in the user cache.
|
|
54
|
+
*
|
|
55
|
+
* Resolution order:
|
|
56
|
+
* 1. ZIVIS_PACK_DIR env var (override for tests / enterprise air-gap imports)
|
|
57
|
+
* 2. User cache, if present
|
|
58
|
+
* 3. Bundled pack inside @zivis/mcp (copied to user cache on first use)
|
|
59
|
+
*/
|
|
60
|
+
export async function loadActivePack(packId = DEFAULT_PACK_ID) {
|
|
61
|
+
if (process.env.ZIVIS_PACK_DIR) {
|
|
62
|
+
return readManifest(process.env.ZIVIS_PACK_DIR);
|
|
63
|
+
}
|
|
64
|
+
const cached = await findCachedPack(packId);
|
|
65
|
+
if (cached) {
|
|
66
|
+
return readManifest(cached);
|
|
67
|
+
}
|
|
68
|
+
const bundledDir = await findBundledPack(packId);
|
|
69
|
+
if (!bundledDir) {
|
|
70
|
+
throw new Error(`No pattern pack found. Looked in user cache (${userPackRoot()}) and bundled location (${bundledPackRoot()}). ` +
|
|
71
|
+
`Set ZIVIS_PACK_DIR to override.`);
|
|
72
|
+
}
|
|
73
|
+
const handle = await readManifest(bundledDir);
|
|
74
|
+
const cacheDir = path.join(userPackRoot(), `${handle.manifest.pack_id}-${handle.manifest.version}`);
|
|
75
|
+
await copyDir(bundledDir, cacheDir);
|
|
76
|
+
return { manifest: handle.manifest, rootDir: cacheDir };
|
|
77
|
+
}
|
|
78
|
+
async function findCachedPack(packId) {
|
|
79
|
+
const root = userPackRoot();
|
|
80
|
+
if (!fssync.existsSync(root))
|
|
81
|
+
return undefined;
|
|
82
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
83
|
+
const candidates = entries
|
|
84
|
+
.filter((e) => e.isDirectory() && e.name.startsWith(`${packId}-`))
|
|
85
|
+
.map((e) => e.name)
|
|
86
|
+
.sort()
|
|
87
|
+
.reverse();
|
|
88
|
+
for (const name of candidates) {
|
|
89
|
+
const dir = path.join(root, name);
|
|
90
|
+
if (fssync.existsSync(path.join(dir, "manifest.json"))) {
|
|
91
|
+
return dir;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
async function findBundledPack(packId) {
|
|
97
|
+
const root = bundledPackRoot();
|
|
98
|
+
if (!fssync.existsSync(root))
|
|
99
|
+
return undefined;
|
|
100
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
101
|
+
const matches = entries
|
|
102
|
+
.filter((e) => e.isDirectory() && e.name.startsWith(`${packId}-`))
|
|
103
|
+
.map((e) => path.join(root, e.name))
|
|
104
|
+
.sort()
|
|
105
|
+
.reverse();
|
|
106
|
+
return matches[0];
|
|
107
|
+
}
|
|
108
|
+
async function readManifest(rootDir) {
|
|
109
|
+
const manifestPath = path.join(rootDir, "manifest.json");
|
|
110
|
+
const raw = await fs.readFile(manifestPath, "utf8");
|
|
111
|
+
const manifest = JSON.parse(raw);
|
|
112
|
+
return { manifest, rootDir };
|
|
113
|
+
}
|
|
114
|
+
async function copyDir(src, dst) {
|
|
115
|
+
await fs.mkdir(dst, { recursive: true });
|
|
116
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
117
|
+
await Promise.all(entries.map(async (entry) => {
|
|
118
|
+
const s = path.join(src, entry.name);
|
|
119
|
+
const d = path.join(dst, entry.name);
|
|
120
|
+
if (entry.isDirectory())
|
|
121
|
+
await copyDir(s, d);
|
|
122
|
+
else if (entry.isFile())
|
|
123
|
+
await fs.copyFile(s, d);
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
// ── Reader API ──
|
|
127
|
+
export async function getCapsule(handle, capsuleId) {
|
|
128
|
+
const entry = handle.manifest.capsules.find((c) => c.id === capsuleId);
|
|
129
|
+
if (!entry)
|
|
130
|
+
throw new Error(`Capsule not found in pack: ${capsuleId}`);
|
|
131
|
+
const fullPath = path.join(handle.rootDir, entry.path);
|
|
132
|
+
const raw = await fs.readFile(fullPath, "utf8");
|
|
133
|
+
await verifySha256(raw, entry.sha256, entry.path);
|
|
134
|
+
return yaml.load(raw);
|
|
135
|
+
}
|
|
136
|
+
export async function getInferencePrompt(handle, ref) {
|
|
137
|
+
const entry = handle.manifest.prompts.find((p) => p.path === ref);
|
|
138
|
+
if (!entry)
|
|
139
|
+
throw new Error(`Prompt not found in pack: ${ref}`);
|
|
140
|
+
const fullPath = path.join(handle.rootDir, ref);
|
|
141
|
+
const raw = await fs.readFile(fullPath, "utf8");
|
|
142
|
+
await verifySha256(raw, entry.sha256, ref);
|
|
143
|
+
return raw;
|
|
144
|
+
}
|
|
145
|
+
async function verifySha256(content, expected, label) {
|
|
146
|
+
const actual = crypto.createHash("sha256").update(content).digest("hex");
|
|
147
|
+
if (actual !== expected) {
|
|
148
|
+
throw new Error(`Pack integrity check failed for ${label}: expected ${expected.slice(0, 12)}…, got ${actual.slice(0, 12)}…`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export async function listCapsuleIds(handle) {
|
|
152
|
+
return handle.manifest.capsules.map((c) => c.id);
|
|
153
|
+
}
|
|
154
|
+
export async function listControlIds(handle) {
|
|
155
|
+
return (handle.manifest.controls ?? []).map((c) => c.id);
|
|
156
|
+
}
|
|
157
|
+
export async function getControl(handle, controlId) {
|
|
158
|
+
const entry = (handle.manifest.controls ?? []).find((c) => c.id === controlId);
|
|
159
|
+
if (!entry)
|
|
160
|
+
throw new Error(`Control not found in pack: ${controlId}`);
|
|
161
|
+
const fullPath = path.join(handle.rootDir, entry.path);
|
|
162
|
+
const raw = await fs.readFile(fullPath, "utf8");
|
|
163
|
+
await verifySha256(raw, entry.sha256, entry.path);
|
|
164
|
+
return yaml.load(raw);
|
|
165
|
+
}
|
|
166
|
+
// ── Relevance evaluation ──
|
|
167
|
+
export async function findRelevantCapsules(handle, artifact) {
|
|
168
|
+
const out = [];
|
|
169
|
+
const ctx = buildEvalContext(artifact);
|
|
170
|
+
for (const entry of handle.manifest.capsules) {
|
|
171
|
+
const cap = await getCapsule(handle, entry.id);
|
|
172
|
+
if (matchesRelevance(cap, ctx))
|
|
173
|
+
out.push(cap);
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
function buildEvalContext(artifact) {
|
|
178
|
+
const packageNames = new Set();
|
|
179
|
+
for (const node of artifact.nodes) {
|
|
180
|
+
if (node.type === "external_dependency" && node.attributes?.package) {
|
|
181
|
+
packageNames.add(node.attributes.package);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const languages = new Set(artifact.scope.languages ?? []);
|
|
185
|
+
const evidenceKinds = new Set();
|
|
186
|
+
for (const node of artifact.nodes) {
|
|
187
|
+
for (const ev of node.evidence)
|
|
188
|
+
evidenceKinds.add(ev.kind);
|
|
189
|
+
}
|
|
190
|
+
return { packageNames, languages, evidenceKinds };
|
|
191
|
+
}
|
|
192
|
+
export function matchesRelevance(cap, ctx) {
|
|
193
|
+
if (cap.applicable_languages.length > 0) {
|
|
194
|
+
const hit = cap.applicable_languages.some((l) => l === "cross" || ctx.languages.has(l));
|
|
195
|
+
if (!hit)
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
const f = cap.relevance_filter;
|
|
199
|
+
if (!f)
|
|
200
|
+
return true;
|
|
201
|
+
if (f.any_of && f.any_of.length > 0) {
|
|
202
|
+
if (!f.any_of.some((t) => evalTerm(t, ctx)))
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (f.all_of && f.all_of.length > 0) {
|
|
206
|
+
if (!f.all_of.every((t) => evalTerm(t, ctx)))
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (f.none_of && f.none_of.length > 0) {
|
|
210
|
+
if (f.none_of.some((t) => evalTerm(t, ctx)))
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
function evalTerm(term, ctx) {
|
|
216
|
+
if (term.dependency !== undefined)
|
|
217
|
+
return ctx.packageNames.has(term.dependency);
|
|
218
|
+
if (term.language !== undefined)
|
|
219
|
+
return ctx.languages.has(term.language);
|
|
220
|
+
if (term.evidence !== undefined)
|
|
221
|
+
return ctx.evidenceKinds.has(term.evidence);
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pattern-pack/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAuHhC,qBAAqB;AAErB,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,eAAe,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,+DAA+D;IAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,eAAe,GAAG,cAAc,CAAC;AAEvC,eAAe;AAEf;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB,eAAe;IACnE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,gDAAgD,YAAY,EAAE,2BAA2B,eAAe,EAAE,KAAK;YAC7G,iCAAiC,CACpC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpG,MAAM,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,MAAc;IAC1C,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,OAAO;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;SACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,EAAE;SACN,OAAO,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,OAAO;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;SACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;SACnC,IAAI,EAAE;SACN,OAAO,EAAE,CAAC;IACb,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe;IACzC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACjD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,GAAW;IAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aACxC,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,mBAAmB;AAEnB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB,EAAE,SAAiB;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IACvE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAY,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAkB,EAAE,GAAW;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,QAAgB,EAAE,KAAa;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,mCAAmC,KAAK,cAAc,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAC5G,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAkB;IACrD,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAkB;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB,EAAE,SAAiB;IACpE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IAC/E,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAY,CAAC;AACnC,CAAC;AAED,6BAA6B;AAE7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAkB,EAClB,QAA2B;IAE3B,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAQD,SAAS,gBAAgB,CAAC,QAA2B;IACnD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;YACpE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ;YAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,GAAgB;IAC7D,IAAI,GAAG,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,GAAG,GAAG,CAAC,gBAAgB,CAAC;IAC/B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB,EAAE,GAAgB;IACrD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC;AACf,CAAC"}
|