@zivis/mcp 0.1.11 → 0.1.17
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/api-client.js +18 -9
- package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +1 -1
- package/dist/project-binding.d.ts +1 -0
- package/dist/project-binding.js +50 -6
- package/dist/prompts/audit-dependencies.js +9 -21
- package/dist/server.js +0 -15
- package/dist/tools/check-project.js +7 -12
- package/dist/tools/create-diagram.d.ts +3 -73
- package/dist/tools/create-diagram.js +8 -100
- package/dist/tools/devx-run.d.ts +1 -1
- package/dist/tools/devx-run.js +1 -1
- package/dist/tools/discover-local-infra.d.ts +1 -1
- package/dist/tools/discover-local-infra.js +9 -16
- package/dist/tools/get-diagram.d.ts +1 -1
- package/dist/tools/get-diagram.js +2 -52
- package/dist/tools/get-started.d.ts +1 -1
- package/dist/tools/get-started.js +110 -94
- package/dist/tools/get-trust-keys.d.ts +1 -1
- package/dist/tools/get-trust-keys.js +1 -1
- package/dist/tools/inspect-zat.d.ts +1 -1
- package/dist/tools/inspect-zat.js +2 -2
- package/dist/tools/list-diagrams.d.ts +1 -1
- package/dist/tools/list-diagrams.js +2 -3
- package/dist/tools/manage-diagram.d.ts +1 -64
- package/dist/tools/manage-diagram.js +2 -211
- package/dist/tools/security-review.d.ts +2 -7
- package/dist/tools/security-review.js +12 -91
- package/dist/tools/update-mermaid-source.d.ts +1 -1
- package/dist/tools/update-mermaid-source.js +1 -3
- package/package.json +3 -2
- package/dist/tools/check-repo-trust.d.ts +0 -18
- package/dist/tools/check-repo-trust.js +0 -221
- package/dist/tools/generate-diagram.d.ts +0 -30
- package/dist/tools/generate-diagram.js +0 -161
- package/dist/tools/get-oss-zat.d.ts +0 -22
- package/dist/tools/get-oss-zat.js +0 -98
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { sanitizeResponse } from "../sanitize.js";
|
|
3
3
|
export const GET_DIAGRAM_NAME = "zivis_get_diagram";
|
|
4
|
-
export const GET_DIAGRAM_DESCRIPTION = `Get the full content of a diagram including
|
|
4
|
+
export const GET_DIAGRAM_DESCRIPTION = `Get the full content of a diagram, including its Mermaid source.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
For mermaid-type diagrams, the \`content\` field contains the full Mermaid source string — use it to read or render the diagram. For canvas-type diagrams, \`content\` is null and the structure is expressed via nodes/connections/boundaries.
|
|
9
|
-
|
|
10
|
-
Use this before modifying a diagram — you need node/connection/boundary IDs for zivis_manage_diagram (canvas) or the Mermaid source for zivis_update_mermaid_source (mermaid).`;
|
|
6
|
+
Use this before modifying a diagram — you need the current Mermaid source for zivis_update_mermaid_source.`;
|
|
11
7
|
export const GET_DIAGRAM_SCHEMA = {
|
|
12
8
|
diagram_id: z
|
|
13
9
|
.string()
|
|
@@ -18,49 +14,6 @@ export function createGetDiagramHandler(apiClient) {
|
|
|
18
14
|
try {
|
|
19
15
|
const data = await apiClient.get(`/api/diagrams/${params.diagram_id}`);
|
|
20
16
|
const sanitized = sanitizeResponse(data);
|
|
21
|
-
const nodes = Array.isArray(sanitized.nodes)
|
|
22
|
-
? sanitized.nodes.map((n) => ({
|
|
23
|
-
node_id: n.id,
|
|
24
|
-
name: n.name,
|
|
25
|
-
description: n.description || null,
|
|
26
|
-
tags: n.tags || [],
|
|
27
|
-
icon: n.icon || null,
|
|
28
|
-
color: n.color || null,
|
|
29
|
-
position_x: n.positionX,
|
|
30
|
-
position_y: n.positionY,
|
|
31
|
-
width: n.width,
|
|
32
|
-
height: n.height,
|
|
33
|
-
step_order: n.stepOrder || null,
|
|
34
|
-
boundary_id: n.boundaryId || null,
|
|
35
|
-
metadata: n.metadata || null,
|
|
36
|
-
linked_finding_ids: n.linkedFindingIds || [],
|
|
37
|
-
linked_evidence_ids: n.linkedEvidenceIds || [],
|
|
38
|
-
}))
|
|
39
|
-
: [];
|
|
40
|
-
const connections = Array.isArray(sanitized.connections)
|
|
41
|
-
? sanitized.connections.map((c) => ({
|
|
42
|
-
connection_id: c.id,
|
|
43
|
-
source_node_id: c.sourceNodeId,
|
|
44
|
-
target_node_id: c.targetNodeId,
|
|
45
|
-
label: c.label || null,
|
|
46
|
-
description: c.description || null,
|
|
47
|
-
tags: c.tags || [],
|
|
48
|
-
bidirectional: c.bidirectional || false,
|
|
49
|
-
metadata: c.metadata || null,
|
|
50
|
-
}))
|
|
51
|
-
: [];
|
|
52
|
-
const boundaries = Array.isArray(sanitized.boundaries)
|
|
53
|
-
? sanitized.boundaries.map((b) => ({
|
|
54
|
-
boundary_id: b.id,
|
|
55
|
-
label: b.label,
|
|
56
|
-
description: b.description || null,
|
|
57
|
-
color: b.color || null,
|
|
58
|
-
position_x: b.positionX,
|
|
59
|
-
position_y: b.positionY,
|
|
60
|
-
width: b.width,
|
|
61
|
-
height: b.height,
|
|
62
|
-
}))
|
|
63
|
-
: [];
|
|
64
17
|
const linkedThreatModelIds = Array.isArray(sanitized.threatModelLinks)
|
|
65
18
|
? sanitized.threatModelLinks.map((l) => l.threatModelId)
|
|
66
19
|
: [];
|
|
@@ -74,9 +27,6 @@ export function createGetDiagramHandler(apiClient) {
|
|
|
74
27
|
source_type: sanitized.sourceType,
|
|
75
28
|
created_at: sanitized.createdAt,
|
|
76
29
|
updated_at: sanitized.updatedAt,
|
|
77
|
-
nodes,
|
|
78
|
-
connections,
|
|
79
|
-
boundaries,
|
|
80
30
|
linked_threat_model_ids: linkedThreatModelIds,
|
|
81
31
|
};
|
|
82
32
|
return {
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import type { ApiClient } from "../api-client.js";
|
|
3
3
|
import type { ZivisConfig } from "../types.js";
|
|
4
4
|
export declare const GET_STARTED_NAME = "zivis_get_started";
|
|
5
|
-
export declare const GET_STARTED_DESCRIPTION = "Call this FIRST on any turn where the user asks about security, vulnerabilities, code review, deployment readiness, threat modeling, dependencies, or \"what should I do next.\" Idempotent and safe to call repeatedly \u2014 detects prior inspect runs and never re-inspects unnecessarily. Prefer this over calling zivis_inspect directly.\n\nUse this when the user says any of:\n- \"what should I do for security on this app\"\n- \"uhh, where do I start\"\n- \"is my app safe\" / \"is my chatbot safe\"\n- \"I need to do security stuff before launch\"\n- \"I have an audit / pen test / customer asking about security\"\n- \"check my dependencies / libraries / repos\"\n- \"how do I use ZIVIS\"\n- \"what can ZIVIS do for me\"\n\nThis tool inspects the current project state \u2014 binding, application, scans, findings \u2014\nAND if a recent 'zivis inspect' artifact exists for this repo, evaluates the local\nthreat library against it to surface architectural patterns ZIVIS thinks may apply\n(self-consistency without context isolation, late org filter, privilege separation, etc.).\nThe 'relevant_threats' field in the response is what makes this tool different from a\ngeneric security menu: ZIVIS is reading the user's actual codebase via the graph\nartifact and naming threats by their architectural shape.\n\
|
|
5
|
+
export declare const GET_STARTED_DESCRIPTION = "Call this FIRST on any turn where the user asks about security, vulnerabilities, code review, deployment readiness, threat modeling, dependencies, or \"what should I do next.\" Idempotent and safe to call repeatedly \u2014 detects prior inspect runs and never re-inspects unnecessarily. Prefer this over calling zivis_inspect directly.\n\nUse this when the user says any of:\n- \"what should I do for security on this app\"\n- \"uhh, where do I start\"\n- \"is my app safe\" / \"is my chatbot safe\"\n- \"I need to do security stuff before launch\"\n- \"I have an audit / pen test / customer asking about security\"\n- \"check my dependencies / libraries / repos\"\n- \"how do I use ZIVIS\"\n- \"what can ZIVIS do for me\"\n\nThis tool inspects the current project state \u2014 binding, application, scans, findings \u2014\nAND if a recent 'zivis inspect' artifact exists for this repo, evaluates the local\nthreat library against it to surface architectural patterns ZIVIS thinks may apply\n(self-consistency without context isolation, late org filter, privilege separation, etc.).\nThe 'relevant_threats' field in the response is what makes this tool different from a\ngeneric security menu: ZIVIS is reading the user's actual codebase via the graph\nartifact and naming threats by their architectural shape.\n\nSpeak in plain developer language by default \u2014 do not introduce jargon (actor, STRIDE,\nkill chain, TTPs) unless the user already used it. Naming the actual product concepts\n(\"your threat model\", `zivis threatmodel`) is fine when they are the literal thing being\ndiscussed; that is a product noun, not jargon to avoid.\n\nOutput is a structured JSON object. Present recommended_next_steps as a numbered list\nto the user, in order, and ask them to pick one. If relevant_threats is non-empty, lead\nwith that \u2014 it's the most concrete thing ZIVIS knows about their repo. Use the label\nand why fields verbatim; do not invent new steps. If the user is unsure which to pick,\nrecommend the item flagged in if_user_unsure.";
|
|
6
6
|
export declare const GET_STARTED_SCHEMA: {
|
|
7
7
|
concern: z.ZodOptional<z.ZodString>;
|
|
8
8
|
cwd: z.ZodOptional<z.ZodString>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { detectProjectBinding } from "../project-binding.js";
|
|
4
5
|
import { loadActivePack, findRelevantCapsules, } from "../pattern-pack/index.js";
|
|
@@ -24,8 +25,10 @@ The 'relevant_threats' field in the response is what makes this tool different f
|
|
|
24
25
|
generic security menu: ZIVIS is reading the user's actual codebase via the graph
|
|
25
26
|
artifact and naming threats by their architectural shape.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
Speak in plain developer language by default — do not introduce jargon (actor, STRIDE,
|
|
29
|
+
kill chain, TTPs) unless the user already used it. Naming the actual product concepts
|
|
30
|
+
("your threat model", \`zivis threatmodel\`) is fine when they are the literal thing being
|
|
31
|
+
discussed; that is a product noun, not jargon to avoid.
|
|
29
32
|
|
|
30
33
|
Output is a structured JSON object. Present recommended_next_steps as a numbered list
|
|
31
34
|
to the user, in order, and ask them to pick one. If relevant_threats is non-empty, lead
|
|
@@ -80,42 +83,44 @@ function stepCheckDeps() {
|
|
|
80
83
|
return {
|
|
81
84
|
id: "check_dependencies",
|
|
82
85
|
label: "Check the open source libraries you depend on",
|
|
83
|
-
tool: "
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
tool: "cli_command",
|
|
87
|
+
args_hint: { command: "zivis test dependencies" },
|
|
88
|
+
why: "Runs the ZIVIS dependency-risk methodology (reachability triage) against your resolved lockfile.",
|
|
89
|
+
estimated_time: "a few minutes — the coding agent does the reasoning",
|
|
90
|
+
requires_auth: true,
|
|
87
91
|
};
|
|
88
92
|
}
|
|
89
|
-
function
|
|
93
|
+
function stepTestScope(scopeId, label, why) {
|
|
90
94
|
return {
|
|
91
|
-
id:
|
|
92
|
-
label
|
|
93
|
-
tool: "
|
|
94
|
-
args_hint: {
|
|
95
|
-
why
|
|
96
|
-
estimated_time: "
|
|
95
|
+
id: `test_${scopeId}`,
|
|
96
|
+
label,
|
|
97
|
+
tool: "cli_command",
|
|
98
|
+
args_hint: { command: `zivis test ${scopeId}` },
|
|
99
|
+
why,
|
|
100
|
+
estimated_time: "a few minutes — the coding agent does the reasoning",
|
|
97
101
|
requires_auth: true,
|
|
98
102
|
};
|
|
99
103
|
}
|
|
100
|
-
function
|
|
104
|
+
function stepBareTest() {
|
|
101
105
|
return {
|
|
102
|
-
id: "
|
|
103
|
-
label: "
|
|
104
|
-
tool: "
|
|
105
|
-
args_hint: {
|
|
106
|
-
why: "
|
|
107
|
-
estimated_time: "
|
|
106
|
+
id: "run_test",
|
|
107
|
+
label: "Run a ZIVIS security review of what changed",
|
|
108
|
+
tool: "cli_command",
|
|
109
|
+
args_hint: { command: "zivis test" },
|
|
110
|
+
why: "Change-aware by default: recommends only the scopes your recent changes touch, using ZIVIS's memory of what was last tested.",
|
|
111
|
+
estimated_time: "a few minutes — the coding agent does the reasoning",
|
|
108
112
|
requires_auth: true,
|
|
109
113
|
};
|
|
110
114
|
}
|
|
111
|
-
function
|
|
115
|
+
function stepListScopes() {
|
|
112
116
|
return {
|
|
113
|
-
id: "
|
|
114
|
-
label: "
|
|
115
|
-
tool: "
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
id: "list_scopes",
|
|
118
|
+
label: "See the security areas ZIVIS can test",
|
|
119
|
+
tool: "cli_command",
|
|
120
|
+
args_hint: { command: "zivis test --list" },
|
|
121
|
+
why: "Lists the scopes defined by the verified ZIVIS AppSec methodology pack — pick one instead of guessing a scope name.",
|
|
122
|
+
estimated_time: "a few seconds",
|
|
123
|
+
requires_auth: false,
|
|
119
124
|
};
|
|
120
125
|
}
|
|
121
126
|
function stepViewFindings(count) {
|
|
@@ -124,8 +129,7 @@ function stepViewFindings(count) {
|
|
|
124
129
|
label: count
|
|
125
130
|
? `Review the ${count} open security issue${count === 1 ? "" : "s"} ZIVIS found`
|
|
126
131
|
: "Review open security issues ZIVIS found",
|
|
127
|
-
tool: "
|
|
128
|
-
args_hint: { status: "open" },
|
|
132
|
+
tool: "zivis_security_review",
|
|
129
133
|
why: "Look at what's been found already before starting new scans — no point duplicating work.",
|
|
130
134
|
estimated_time: "5 minutes",
|
|
131
135
|
requires_auth: true,
|
|
@@ -136,18 +140,52 @@ function stepRunSecurityReview() {
|
|
|
136
140
|
id: "run_security_review",
|
|
137
141
|
label: "Get a security readiness summary before launch or audit",
|
|
138
142
|
tool: "zivis_security_review",
|
|
139
|
-
why: "Pulls together
|
|
143
|
+
why: "Pulls together open findings and regression history from prior ZIVIS work into one pre-launch checklist.",
|
|
140
144
|
estimated_time: "3 minutes",
|
|
141
145
|
requires_auth: true,
|
|
142
146
|
};
|
|
143
147
|
}
|
|
148
|
+
function stepThreatModel() {
|
|
149
|
+
return {
|
|
150
|
+
id: "threat_model",
|
|
151
|
+
label: "Start or continue this Application's living threat model",
|
|
152
|
+
tool: "cli_command",
|
|
153
|
+
args_hint: { command: "zivis threatmodel" },
|
|
154
|
+
why: "Captures components, data flows, and trust boundaries as a durable, versioned artifact.",
|
|
155
|
+
estimated_time: "a few minutes — the coding agent does the reasoning",
|
|
156
|
+
requires_auth: true,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function stepGateShip() {
|
|
160
|
+
return {
|
|
161
|
+
id: "gate_ship",
|
|
162
|
+
label: "Get a deterministic ship/no-ship verdict against your committed policy",
|
|
163
|
+
tool: "cli_command",
|
|
164
|
+
args_hint: { command: "zivis gate ship" },
|
|
165
|
+
why: "Deterministic — reads your committed .zivis/policy.yaml against live Zivis state. Never an invented verdict.",
|
|
166
|
+
estimated_time: "a few seconds",
|
|
167
|
+
requires_auth: true,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function stepGateInit() {
|
|
171
|
+
return {
|
|
172
|
+
id: "gate_init",
|
|
173
|
+
label: "Create a committed ship policy so 'can we ship?' has a real answer",
|
|
174
|
+
tool: "cli_command",
|
|
175
|
+
args_hint: { command: "zivis gate --init" },
|
|
176
|
+
why: "No .zivis/policy.yaml exists yet, so zivis gate has nothing to evaluate — this scaffolds a starter policy to review and commit.",
|
|
177
|
+
estimated_time: "a minute to review and adjust the generated thresholds",
|
|
178
|
+
requires_auth: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
144
181
|
function stepSetupProject() {
|
|
145
182
|
return {
|
|
146
183
|
id: "setup_project",
|
|
147
184
|
label: "Connect this project to your ZIVIS org",
|
|
148
|
-
tool: "
|
|
149
|
-
|
|
150
|
-
|
|
185
|
+
tool: "cli_command",
|
|
186
|
+
args_hint: { command: "zivis init" },
|
|
187
|
+
why: "Every ZIVIS command needs a bound Application before it can run tests or store results — this is the one thing that has to happen first.",
|
|
188
|
+
estimated_time: "2 minutes",
|
|
151
189
|
requires_auth: false,
|
|
152
190
|
};
|
|
153
191
|
}
|
|
@@ -163,6 +201,10 @@ function stepInstallGitHubApp(installUrl) {
|
|
|
163
201
|
};
|
|
164
202
|
}
|
|
165
203
|
async function fetchState(apiClient, cwd) {
|
|
204
|
+
const hasGatePolicy = await fs
|
|
205
|
+
.access(path.join(cwd, ".zivis", "policy.yaml"))
|
|
206
|
+
.then(() => true)
|
|
207
|
+
.catch(() => false);
|
|
166
208
|
const detected = detectProjectBinding(cwd);
|
|
167
209
|
if (!detected) {
|
|
168
210
|
return {
|
|
@@ -171,6 +213,7 @@ async function fetchState(apiClient, cwd) {
|
|
|
171
213
|
has_scans: false,
|
|
172
214
|
has_findings: false,
|
|
173
215
|
open_findings_count: 0,
|
|
216
|
+
has_gate_policy: hasGatePolicy,
|
|
174
217
|
};
|
|
175
218
|
}
|
|
176
219
|
const state = {
|
|
@@ -180,6 +223,7 @@ async function fetchState(apiClient, cwd) {
|
|
|
180
223
|
has_scans: false,
|
|
181
224
|
has_findings: false,
|
|
182
225
|
open_findings_count: 0,
|
|
226
|
+
has_gate_policy: hasGatePolicy,
|
|
183
227
|
};
|
|
184
228
|
try {
|
|
185
229
|
const appsResp = await apiClient.get("/api/rt/applications?limit=1");
|
|
@@ -221,28 +265,19 @@ function buildMenu(intent, state, concern) {
|
|
|
221
265
|
if (!state.bound) {
|
|
222
266
|
return {
|
|
223
267
|
headline: "Welcome to ZIVIS! First, let's connect this project to your organization so results are stored and tracked.",
|
|
224
|
-
recommended_next_steps: [
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
guidance_for_assistant: "Present these as a numbered list. The user should run 'zivis auth init' in their terminal to complete step 1. " +
|
|
230
|
-
"Step 2 (check_dependencies) requires no auth and can be done immediately. " +
|
|
231
|
-
"If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
232
|
-
if_user_unsure: "Recommend option 2 (check_dependencies) — it requires no setup and gives immediate results.",
|
|
268
|
+
recommended_next_steps: [stepSetupProject()],
|
|
269
|
+
guidance_for_assistant: "Present this as a single step. The user should run 'zivis init' in their terminal — it handles login and " +
|
|
270
|
+
"Application binding together. Every other ZIVIS command needs this to succeed first; there is nothing " +
|
|
271
|
+
"useful to offer in parallel. If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
272
|
+
if_user_unsure: "Run 'zivis init' — it's the only step available until this project is connected.",
|
|
233
273
|
};
|
|
234
274
|
}
|
|
235
275
|
if (state.has_findings && intent !== "dep_audit") {
|
|
236
276
|
const steps = [
|
|
237
277
|
stepViewFindings(state.open_findings_count),
|
|
278
|
+
stepBareTest(),
|
|
238
279
|
stepCheckDeps(),
|
|
239
280
|
];
|
|
240
|
-
if (!state.has_application) {
|
|
241
|
-
steps.push(stepSetupWebTarget());
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
steps.push(stepBrowseTests());
|
|
245
|
-
}
|
|
246
281
|
return {
|
|
247
282
|
headline: `ZIVIS sees your project (${state.org_name ?? "connected"}) and has found ${state.open_findings_count} open security issue${state.open_findings_count === 1 ? "" : "s"}.`,
|
|
248
283
|
recommended_next_steps: steps,
|
|
@@ -253,46 +288,28 @@ function buildMenu(intent, state, concern) {
|
|
|
253
288
|
}
|
|
254
289
|
if (intent === "ai_red_team") {
|
|
255
290
|
const steps = [
|
|
256
|
-
|
|
291
|
+
stepTestScope("ai", "Test your AI system for prompt injection, jailbreaks, and data leakage", "Runs the ZIVIS 'ai' scope methodology, grounded in your actual code — not a generic checklist."),
|
|
257
292
|
stepCheckDeps(),
|
|
258
|
-
stepBrowseTests(),
|
|
259
293
|
];
|
|
260
294
|
return {
|
|
261
|
-
headline: state.
|
|
262
|
-
? `ZIVIS sees your project (${state.org_name ?? "connected"}) and has a target configured. Ready to test your AI system.`
|
|
263
|
-
: `ZIVIS sees your project (${state.org_name ?? "connected"}) but no security testing has run yet.`,
|
|
295
|
+
headline: `ZIVIS sees your project (${state.org_name ?? "connected"}). Let's test the AI-specific surface.`,
|
|
264
296
|
recommended_next_steps: steps,
|
|
265
297
|
guidance_for_assistant: "The user wants to test an AI/chatbot system. Present these as a numbered list. " +
|
|
266
|
-
"If they already have a target URL, include it in args_hint. " +
|
|
267
298
|
"If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
268
|
-
if_user_unsure: "Recommend option 1 (
|
|
299
|
+
if_user_unsure: "Recommend option 1 (test_ai) — it's the scope built for exactly this.",
|
|
269
300
|
};
|
|
270
301
|
}
|
|
271
302
|
if (intent === "dep_audit") {
|
|
272
303
|
return {
|
|
273
|
-
headline: "Checking your dependencies is a great place to start — it
|
|
274
|
-
recommended_next_steps: [
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
stepBrowseTests(),
|
|
278
|
-
],
|
|
279
|
-
guidance_for_assistant: "Present these as a numbered list. For step 1, ask the user to share which packages they want to check " +
|
|
280
|
-
"(the GitHub org/repo of the dependency, e.g. openai/openai-python). " +
|
|
281
|
-
"If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
282
|
-
if_user_unsure: "Recommend option 1 (check_dependencies) — it works right now with no setup.",
|
|
304
|
+
headline: "Checking your dependencies is a great place to start — it often finds the most impactful issues fastest.",
|
|
305
|
+
recommended_next_steps: [stepCheckDeps(), stepBareTest()],
|
|
306
|
+
guidance_for_assistant: "Present these as a numbered list. If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
307
|
+
if_user_unsure: "Recommend option 1 (check_dependencies).",
|
|
283
308
|
};
|
|
284
309
|
}
|
|
285
310
|
if (intent === "pre_audit" || intent === "pre_launch") {
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
stepCheckDeps(),
|
|
289
|
-
];
|
|
290
|
-
if (!state.has_application) {
|
|
291
|
-
steps.push(stepSetupWebTarget());
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
steps.push(stepBrowseTests());
|
|
295
|
-
}
|
|
311
|
+
const gateStep = state.has_gate_policy ? stepGateShip() : stepGateInit();
|
|
312
|
+
const steps = [stepRunSecurityReview(), gateStep, stepBareTest(), stepCheckDeps()];
|
|
296
313
|
const headline = intent === "pre_audit"
|
|
297
314
|
? `ZIVIS can help you prepare for an audit. Let's get a security readiness picture first.`
|
|
298
315
|
: `ZIVIS can help you check security before you go live.`;
|
|
@@ -300,47 +317,46 @@ function buildMenu(intent, state, concern) {
|
|
|
300
317
|
headline,
|
|
301
318
|
recommended_next_steps: steps,
|
|
302
319
|
guidance_for_assistant: "The user has a deadline (audit or launch). Start with a security review to understand the current state, " +
|
|
303
|
-
"then address the highest-severity issues first. " +
|
|
304
|
-
"
|
|
305
|
-
|
|
320
|
+
"then address the highest-severity issues first. The security review reflects known findings, not a " +
|
|
321
|
+
"deterministic ship verdict. If the user actually asks 'can we ship?' / 'go or no-go?', route to " +
|
|
322
|
+
"'zivis gate' — NEVER answer that question yourself from the review or from general judgment. " +
|
|
323
|
+
(state.has_gate_policy
|
|
324
|
+
? "A committed policy already exists here, so 'zivis gate ship' (or the relevant gate name) gives a real deterministic answer."
|
|
325
|
+
: "No committed policy exists yet, so gate has nothing to evaluate — offer 'zivis gate --init' to scaffold one first, then run the real evaluation. Do not substitute your own opinion in the meantime.") +
|
|
326
|
+
" If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
327
|
+
if_user_unsure: "Recommend option 1 (run_security_review) — it gives the fastest complete picture of what's already known.",
|
|
306
328
|
};
|
|
307
329
|
}
|
|
308
330
|
if (intent === "view_findings") {
|
|
309
331
|
return {
|
|
310
332
|
headline: state.has_findings
|
|
311
333
|
? `ZIVIS has ${state.open_findings_count} open finding${state.open_findings_count === 1 ? "" : "s"} for this project.`
|
|
312
|
-
: `No open findings
|
|
334
|
+
: `No open findings on record yet — that means no test has found one, not that the project is clean.`,
|
|
313
335
|
recommended_next_steps: [
|
|
314
336
|
stepViewFindings(state.open_findings_count > 0 ? state.open_findings_count : undefined),
|
|
315
|
-
|
|
316
|
-
stepCheckDeps(),
|
|
337
|
+
stepBareTest(),
|
|
317
338
|
],
|
|
318
|
-
guidance_for_assistant: "Present these as a numbered list. If the user wants to see findings, call
|
|
339
|
+
guidance_for_assistant: "Present these as a numbered list. If the user wants to see findings, call zivis_security_review directly. " +
|
|
340
|
+
"No open findings does not mean the project passed a test — say so explicitly if the count is zero. " +
|
|
319
341
|
"If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
320
342
|
if_user_unsure: "Recommend option 1 (view_open_findings) — let's see what ZIVIS already knows.",
|
|
321
343
|
};
|
|
322
344
|
}
|
|
323
|
-
const steps = [];
|
|
324
|
-
if (!state.has_application) {
|
|
325
|
-
steps.push(stepSetupWebTarget());
|
|
326
|
-
}
|
|
327
|
-
steps.push(stepCheckDeps());
|
|
345
|
+
const steps = [stepBareTest(), stepCheckDeps()];
|
|
328
346
|
if (state.has_findings) {
|
|
329
347
|
steps.push(stepViewFindings(state.open_findings_count));
|
|
330
348
|
}
|
|
331
349
|
else {
|
|
332
|
-
steps.push(
|
|
350
|
+
steps.push(stepListScopes());
|
|
333
351
|
}
|
|
334
|
-
if (
|
|
335
|
-
steps.push(
|
|
352
|
+
if (!state.has_application)
|
|
353
|
+
steps.push(stepThreatModel());
|
|
336
354
|
return {
|
|
337
|
-
headline: state.
|
|
338
|
-
? `ZIVIS is connected to your project (${state.org_name ?? "org"}). Here are the most useful things to do next.`
|
|
339
|
-
: `ZIVIS is connected to your project (${state.org_name ?? "org"}) but no app has been registered for testing yet.`,
|
|
355
|
+
headline: `ZIVIS is connected to your project (${state.org_name ?? "org"}). Here are the most useful things to do next.`,
|
|
340
356
|
recommended_next_steps: steps.slice(0, 4),
|
|
341
357
|
guidance_for_assistant: "Present these as a numbered list. Ask the user to pick one before taking any action. " +
|
|
342
358
|
"If they ask 'why' something matters, expand on the 'why' field — do not make new claims.",
|
|
343
|
-
if_user_unsure: "Recommend option
|
|
359
|
+
if_user_unsure: "Recommend option 1 (run_test) — bare 'zivis test' is change-aware and the natural default entry point.",
|
|
344
360
|
};
|
|
345
361
|
}
|
|
346
362
|
async function findRelevantThreats(cwd) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ZivisConfig } from "../types.js";
|
|
2
2
|
export declare const GET_TRUST_KEYS_NAME = "zivis_get_trust_keys";
|
|
3
|
-
export declare const GET_TRUST_KEYS_DESCRIPTION = "Retrieve the ZIVIS public signing keys (JWKS) for independent cryptographic verification of trust marks and ZATs.\n\nReturns a JWKS (JSON Web Key Set) containing two keys:\n\n1. **ML-DSA-65 key** (post-quantum, FIPS-204):\n - Algorithm: CRYSTALS-Dilithium Level 3\n - NIST Security Category 3 (128-bit quantum security)\n - Used to verify the full digital signature on ZATs and trust marks\n - Key type: \"PQ-LWE\" (proposed post-quantum JWK key type)\n - The \"x\" field is the base64url-encoded public key bytes\n\n2. **Ed25519 key** (RFC 8032):\n - Used to verify compact trust tokens (shorter, URL-safe format)\n - Standard JWK format (kty: \"OKP\", crv: \"Ed25519\")\n\nThese keys enable third-party, offline verification without trusting ZIVIS infrastructure.\nThis is critical for ATNP (Agent Trust Negotiation Protocol) where agents must independently verify trust marks.\n\nVerification workflow:\n1. Get a ZAT (from
|
|
3
|
+
export declare const GET_TRUST_KEYS_DESCRIPTION = "Retrieve the ZIVIS public signing keys (JWKS) for independent cryptographic verification of trust marks and ZATs.\n\nReturns a JWKS (JSON Web Key Set) containing two keys:\n\n1. **ML-DSA-65 key** (post-quantum, FIPS-204):\n - Algorithm: CRYSTALS-Dilithium Level 3\n - NIST Security Category 3 (128-bit quantum security)\n - Used to verify the full digital signature on ZATs and trust marks\n - Key type: \"PQ-LWE\" (proposed post-quantum JWK key type)\n - The \"x\" field is the base64url-encoded public key bytes\n\n2. **Ed25519 key** (RFC 8032):\n - Used to verify compact trust tokens (shorter, URL-safe format)\n - Standard JWK format (kty: \"OKP\", crv: \"Ed25519\")\n\nThese keys enable third-party, offline verification without trusting ZIVIS infrastructure.\nThis is critical for ATNP (Agent Trust Negotiation Protocol) where agents must independently verify trust marks.\n\nVerification workflow:\n1. Get a ZAT (from zivis_get_org_zat)\n2. Get the public keys (this tool)\n3. Verify the signature using ML-DSA-65 or Ed25519 library of your choice\n4. Check expiration and claims\n\nNo parameters required. No authentication required.";
|
|
4
4
|
export declare const GET_TRUST_KEYS_SCHEMA: {};
|
|
5
5
|
export declare function createGetTrustKeysHandler(config: ZivisConfig): () => Promise<{
|
|
6
6
|
content: {
|
|
@@ -18,7 +18,7 @@ These keys enable third-party, offline verification without trusting ZIVIS infra
|
|
|
18
18
|
This is critical for ATNP (Agent Trust Negotiation Protocol) where agents must independently verify trust marks.
|
|
19
19
|
|
|
20
20
|
Verification workflow:
|
|
21
|
-
1. Get a ZAT (from
|
|
21
|
+
1. Get a ZAT (from zivis_get_org_zat)
|
|
22
22
|
2. Get the public keys (this tool)
|
|
23
23
|
3. Verify the signature using ML-DSA-65 or Ed25519 library of your choice
|
|
24
24
|
4. Check expiration and claims
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const INSPECT_ZAT_NAME = "zivis_inspect_zat";
|
|
3
|
-
export declare const INSPECT_ZAT_DESCRIPTION = "Parse a ZIVIS Attestation Token (ZAT) JSON and produce a human-readable explanation of all fields.\n\nThis tool does NOT make any API calls \u2014 it parses the ZAT locally and explains what each field means.\n\nUse this after retrieving a ZAT from
|
|
3
|
+
export declare const INSPECT_ZAT_DESCRIPTION = "Parse a ZIVIS Attestation Token (ZAT) JSON and produce a human-readable explanation of all fields.\n\nThis tool does NOT make any API calls \u2014 it parses the ZAT locally and explains what each field means.\n\nUse this after retrieving a ZAT from zivis_get_org_zat to understand:\n- What the claims mean (Z-Score, trust tiers, coverage, findings)\n- Whether signatures are present and which algorithms were used\n- Token validity and expiration\n- Evidence manifest integrity\n- Framework and methodology details\n- Lens-level scores (for OSS ZATs)\n\nAccepts either:\n- A JSON string (the raw ZAT output)\n- A JSON object with a \"zat\" field (the wrapper returned by the API)\n\nZAT Field Reference:\n- **iss**: Issuer (always \"zivis.ai\")\n- **sub**: Subject \u2014 \"org:<slug>\" for enterprise, \"github:<owner>/<repo>\" for OSS\n- **mark_id**: Unique identifier (ztm_...) \u2014 references the trust mark\n- **issued_at / expires_at**: ISO 8601 timestamps \u2014 ZATs are short-lived (48h)\n- **frameworks[]**: Which security frameworks were assessed (NIST IR 8596, ISO 42001, OWASP LLM Top 10, etc.)\n - basis: \"tested\" | \"mapped\" | \"self-attested\" | \"third-party\" \u2014 how the assessment was performed\n - csf_version: Present if framework is NIST CSF 2.0 derived (enables cross-framework comparison)\n- **claims**: The actual trust posture\n - For enterprise: z_score_raw (0-1), z_score_display (0-1000), tier (0-3), tier_label, coverage_pct, mapped_outcomes\n - For OSS: score (0-100), grade (A+ to F), check_types, findings by severity, commit SHA\n - Tier meanings: 0=Commitment, 1=Foundational Trust (600+), 2=Operational Trust (700+), 3=Systemic Trust (800+)\n- **evidence_manifest**: SHA-256 hash of the evidence bundle \u2014 proves the assessment data hasn't been tampered with\n- **methodology**: How the assessment was performed (model version, scoring algorithm, evaluator type)\n- **sig**: Cryptographic signatures\n - alg: \"ML-DSA-65\" (FIPS-204, post-quantum CRYSTALS-Dilithium Level 3)\n - compact: Ed25519 (RFC 8032) compact token for lightweight verification\n- **ver**: ZAT spec version (e.g., \"0.3.0\")";
|
|
4
4
|
export declare const INSPECT_ZAT_SCHEMA: {
|
|
5
5
|
zat_json: z.ZodString;
|
|
6
6
|
};
|
|
@@ -4,7 +4,7 @@ export const INSPECT_ZAT_DESCRIPTION = `Parse a ZIVIS Attestation Token (ZAT) JS
|
|
|
4
4
|
|
|
5
5
|
This tool does NOT make any API calls — it parses the ZAT locally and explains what each field means.
|
|
6
6
|
|
|
7
|
-
Use this after retrieving a ZAT from
|
|
7
|
+
Use this after retrieving a ZAT from zivis_get_org_zat to understand:
|
|
8
8
|
- What the claims mean (Z-Score, trust tiers, coverage, findings)
|
|
9
9
|
- Whether signatures are present and which algorithms were used
|
|
10
10
|
- Token validity and expiration
|
|
@@ -37,7 +37,7 @@ ZAT Field Reference:
|
|
|
37
37
|
export const INSPECT_ZAT_SCHEMA = {
|
|
38
38
|
zat_json: z
|
|
39
39
|
.string()
|
|
40
|
-
.describe("The ZAT JSON string to inspect (from
|
|
40
|
+
.describe("The ZAT JSON string to inspect (from zivis_get_org_zat output)"),
|
|
41
41
|
};
|
|
42
42
|
export function createInspectZatHandler() {
|
|
43
43
|
return async (params) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { ApiClient } from "../api-client.js";
|
|
3
3
|
export declare const LIST_DIAGRAMS_NAME = "zivis_list_diagrams";
|
|
4
|
-
export declare const LIST_DIAGRAMS_DESCRIPTION = "List diagrams for your organization. Returns summary info (name, type,
|
|
4
|
+
export declare const LIST_DIAGRAMS_DESCRIPTION = "List diagrams for your organization. Returns summary info (name, type, description) for each diagram.\n\nUse this tool to find existing diagrams before modifying them. To get the full content (Mermaid source), use zivis_get_diagram with the diagram_id from this response.\n\nDiagrams can be linked to threat models. Use linked_threat_model_id to find diagrams for a specific threat model.";
|
|
5
5
|
export declare const LIST_DIAGRAMS_SCHEMA: {
|
|
6
6
|
diagram_type: z.ZodOptional<z.ZodEnum<{
|
|
7
7
|
custom: "custom";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { sanitizeResponse } from "../sanitize.js";
|
|
3
3
|
export const LIST_DIAGRAMS_NAME = "zivis_list_diagrams";
|
|
4
|
-
export const LIST_DIAGRAMS_DESCRIPTION = `List diagrams for your organization. Returns summary info (name, type,
|
|
4
|
+
export const LIST_DIAGRAMS_DESCRIPTION = `List diagrams for your organization. Returns summary info (name, type, description) for each diagram.
|
|
5
5
|
|
|
6
|
-
Use this tool to find existing diagrams before modifying them. To get the full content (
|
|
6
|
+
Use this tool to find existing diagrams before modifying them. To get the full content (Mermaid source), use zivis_get_diagram with the diagram_id from this response.
|
|
7
7
|
|
|
8
8
|
Diagrams can be linked to threat models. Use linked_threat_model_id to find diagrams for a specific threat model.`;
|
|
9
9
|
export const LIST_DIAGRAMS_SCHEMA = {
|
|
@@ -52,7 +52,6 @@ export function createListDiagramsHandler(apiClient) {
|
|
|
52
52
|
description: d.description || null,
|
|
53
53
|
created_at: d.createdAt,
|
|
54
54
|
updated_at: d.updatedAt,
|
|
55
|
-
stats: d._count || null,
|
|
56
55
|
}))
|
|
57
56
|
: sanitized.diagrams;
|
|
58
57
|
return {
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { ApiClient } from "../api-client.js";
|
|
3
3
|
export declare const MANAGE_DIAGRAM_NAME = "zivis_manage_diagram";
|
|
4
|
-
export declare const MANAGE_DIAGRAM_DESCRIPTION = "Modify an existing diagram: update metadata,
|
|
4
|
+
export declare const MANAGE_DIAGRAM_DESCRIPTION = "Modify an existing diagram: update metadata, delete it, or link/unlink it to a threat model.\n\nTo change a diagram's Mermaid source, use zivis_update_mermaid_source instead.\n\nActions:\n- update_metadata: Update diagram name, description, or type\n- delete_diagram: Delete the entire diagram\n- link_threat_model: Link diagram to a threat model (requires threat_model_id)\n- unlink_threat_model: Unlink from a threat model (requires threat_model_id)";
|
|
5
5
|
export declare const MANAGE_DIAGRAM_SCHEMA: {
|
|
6
6
|
diagram_id: z.ZodString;
|
|
7
7
|
action: z.ZodEnum<{
|
|
8
8
|
update_metadata: "update_metadata";
|
|
9
9
|
delete_diagram: "delete_diagram";
|
|
10
|
-
add_node: "add_node";
|
|
11
|
-
update_node: "update_node";
|
|
12
|
-
delete_node: "delete_node";
|
|
13
|
-
add_connection: "add_connection";
|
|
14
|
-
update_connection: "update_connection";
|
|
15
|
-
delete_connection: "delete_connection";
|
|
16
|
-
add_boundary: "add_boundary";
|
|
17
|
-
update_boundary: "update_boundary";
|
|
18
|
-
delete_boundary: "delete_boundary";
|
|
19
10
|
link_threat_model: "link_threat_model";
|
|
20
11
|
unlink_threat_model: "unlink_threat_model";
|
|
21
12
|
}>;
|
|
@@ -31,33 +22,6 @@ export declare const MANAGE_DIAGRAM_SCHEMA: {
|
|
|
31
22
|
trust_boundary: "trust_boundary";
|
|
32
23
|
network: "network";
|
|
33
24
|
}>>;
|
|
34
|
-
node_id: z.ZodOptional<z.ZodString>;
|
|
35
|
-
node_name: z.ZodOptional<z.ZodString>;
|
|
36
|
-
node_description: z.ZodOptional<z.ZodString>;
|
|
37
|
-
node_tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
38
|
-
node_icon: z.ZodOptional<z.ZodString>;
|
|
39
|
-
node_color: z.ZodOptional<z.ZodString>;
|
|
40
|
-
position_x: z.ZodOptional<z.ZodNumber>;
|
|
41
|
-
position_y: z.ZodOptional<z.ZodNumber>;
|
|
42
|
-
width: z.ZodOptional<z.ZodNumber>;
|
|
43
|
-
height: z.ZodOptional<z.ZodNumber>;
|
|
44
|
-
step_order: z.ZodOptional<z.ZodNumber>;
|
|
45
|
-
boundary_id: z.ZodOptional<z.ZodString>;
|
|
46
|
-
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
47
|
-
connection_id: z.ZodOptional<z.ZodString>;
|
|
48
|
-
source_node_id: z.ZodOptional<z.ZodString>;
|
|
49
|
-
target_node_id: z.ZodOptional<z.ZodString>;
|
|
50
|
-
label: z.ZodOptional<z.ZodString>;
|
|
51
|
-
connection_description: z.ZodOptional<z.ZodString>;
|
|
52
|
-
connection_tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
|
-
bidirectional: z.ZodOptional<z.ZodBoolean>;
|
|
54
|
-
boundary_label: z.ZodOptional<z.ZodString>;
|
|
55
|
-
boundary_description: z.ZodOptional<z.ZodString>;
|
|
56
|
-
boundary_color: z.ZodOptional<z.ZodString>;
|
|
57
|
-
boundary_position_x: z.ZodOptional<z.ZodNumber>;
|
|
58
|
-
boundary_position_y: z.ZodOptional<z.ZodNumber>;
|
|
59
|
-
boundary_width: z.ZodOptional<z.ZodNumber>;
|
|
60
|
-
boundary_height: z.ZodOptional<z.ZodNumber>;
|
|
61
25
|
threat_model_id: z.ZodOptional<z.ZodString>;
|
|
62
26
|
};
|
|
63
27
|
type ManageDiagramParams = {
|
|
@@ -66,33 +30,6 @@ type ManageDiagramParams = {
|
|
|
66
30
|
name?: string;
|
|
67
31
|
description?: string;
|
|
68
32
|
diagram_type?: string;
|
|
69
|
-
node_id?: string;
|
|
70
|
-
node_name?: string;
|
|
71
|
-
node_description?: string;
|
|
72
|
-
node_tags?: string[];
|
|
73
|
-
node_icon?: string;
|
|
74
|
-
node_color?: string;
|
|
75
|
-
position_x?: number;
|
|
76
|
-
position_y?: number;
|
|
77
|
-
width?: number;
|
|
78
|
-
height?: number;
|
|
79
|
-
step_order?: number;
|
|
80
|
-
boundary_id?: string;
|
|
81
|
-
metadata?: Record<string, unknown>;
|
|
82
|
-
connection_id?: string;
|
|
83
|
-
source_node_id?: string;
|
|
84
|
-
target_node_id?: string;
|
|
85
|
-
label?: string;
|
|
86
|
-
connection_description?: string;
|
|
87
|
-
connection_tags?: string[];
|
|
88
|
-
bidirectional?: boolean;
|
|
89
|
-
boundary_label?: string;
|
|
90
|
-
boundary_description?: string;
|
|
91
|
-
boundary_color?: string;
|
|
92
|
-
boundary_position_x?: number;
|
|
93
|
-
boundary_position_y?: number;
|
|
94
|
-
boundary_width?: number;
|
|
95
|
-
boundary_height?: number;
|
|
96
33
|
threat_model_id?: string;
|
|
97
34
|
};
|
|
98
35
|
export declare function createManageDiagramHandler(apiClient: ApiClient): (params: ManageDiagramParams) => Promise<{
|