@zivis/cli 0.1.0-alpha.5 → 0.1.0-alpha.52
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/LICENSE +201 -0
- package/README.md +31 -0
- package/dist/commands/app/index.d.ts +0 -8
- package/dist/commands/app/index.js +8 -18
- package/dist/commands/assurance/index.d.ts +35 -0
- package/dist/commands/assurance/index.js +154 -0
- package/dist/commands/auth/bind.d.ts +4 -0
- package/dist/commands/auth/bind.js +97 -0
- package/dist/commands/auth/index.js +21 -2
- package/dist/commands/auth/init.d.ts +2 -0
- package/dist/commands/auth/init.js +248 -96
- package/dist/commands/auth/login.d.ts +2 -0
- package/dist/commands/auth/login.js +136 -18
- package/dist/commands/auth/logout.js +19 -7
- package/dist/commands/auth/sessions.js +7 -4
- package/dist/commands/auth/status.js +33 -12
- package/dist/commands/auth/token.d.ts +4 -0
- package/dist/commands/auth/token.js +73 -0
- package/dist/commands/check/index.d.ts +2 -0
- package/dist/commands/check/index.js +463 -0
- package/dist/commands/credits/index.js +2 -3
- package/dist/commands/gate/index.d.ts +2 -0
- package/dist/commands/gate/index.js +171 -0
- package/dist/commands/inspect/index.d.ts +2 -0
- package/dist/commands/inspect/index.js +136 -0
- package/dist/commands/mcp/index.js +113 -14
- package/dist/commands/open/index.d.ts +0 -8
- package/dist/commands/open/index.js +0 -11
- package/dist/commands/run/index.d.ts +2 -0
- package/dist/commands/run/index.js +206 -0
- package/dist/commands/scan/index.js +3 -8
- package/dist/commands/share/index.d.ts +14 -0
- package/dist/commands/share/index.js +100 -0
- package/dist/commands/sync/index.d.ts +2 -0
- package/dist/commands/sync/index.js +193 -0
- package/dist/commands/target/index.js +0 -3
- package/dist/commands/test/index.d.ts +2 -0
- package/dist/commands/test/index.js +198 -0
- package/dist/commands/threatmodel/index.d.ts +2 -0
- package/dist/commands/threatmodel/index.js +167 -0
- package/dist/index.js +28 -3
- package/dist/internal/application-binding.d.ts +8 -0
- package/dist/internal/application-binding.js +167 -0
- package/dist/internal/binding-token-mint.d.ts +33 -0
- package/dist/internal/binding-token-mint.js +174 -0
- package/dist/internal/change-recommendation.d.ts +6 -0
- package/dist/internal/change-recommendation.js +113 -0
- package/dist/internal/cli-output.d.ts +16 -0
- package/dist/internal/cli-output.js +39 -0
- package/dist/internal/devx-run.d.ts +129 -0
- package/dist/internal/devx-run.js +39 -0
- package/dist/internal/extractor/adapters/go/index.d.ts +0 -4
- package/dist/internal/extractor/adapters/go/index.js +0 -6
- package/dist/internal/extractor/adapters/go/manifest.d.ts +0 -17
- package/dist/internal/extractor/adapters/go/manifest.js +19 -25
- package/dist/internal/extractor/adapters/go/parser.d.ts +0 -4
- package/dist/internal/extractor/adapters/go/parser.js +0 -5
- package/dist/internal/extractor/adapters/go/scanner.d.ts +0 -20
- package/dist/internal/extractor/adapters/go/scanner.js +0 -43
- package/dist/internal/extractor/adapters/python/index.d.ts +0 -3
- package/dist/internal/extractor/adapters/python/index.js +0 -4
- package/dist/internal/extractor/adapters/python/manifest.d.ts +0 -8
- package/dist/internal/extractor/adapters/python/manifest.js +21 -18
- package/dist/internal/extractor/adapters/python/parser.d.ts +0 -3
- package/dist/internal/extractor/adapters/python/parser.js +0 -4
- package/dist/internal/extractor/adapters/python/scanner.d.ts +0 -18
- package/dist/internal/extractor/adapters/python/scanner.js +1 -54
- package/dist/internal/extractor/adapters/typescript/index.d.ts +0 -7
- package/dist/internal/extractor/adapters/typescript/index.js +1 -21
- package/dist/internal/extractor/adapters/typescript/manifest.d.ts +0 -14
- package/dist/internal/extractor/adapters/typescript/manifest.js +26 -17
- package/dist/internal/extractor/adapters/typescript/parser.d.ts +0 -8
- package/dist/internal/extractor/adapters/typescript/parser.js +0 -9
- package/dist/internal/extractor/adapters/typescript/scanner.d.ts +0 -24
- package/dist/internal/extractor/adapters/typescript/scanner.js +0 -43
- package/dist/internal/extractor/graph-builder.d.ts +10 -0
- package/dist/internal/extractor/graph-builder.js +245 -0
- package/dist/internal/extractor/graph-types.d.ts +89 -0
- package/dist/internal/extractor/graph-types.js +1 -0
- package/dist/internal/extractor/index.d.ts +0 -14
- package/dist/internal/extractor/index.js +0 -13
- package/dist/internal/extractor/types.d.ts +0 -45
- package/dist/internal/extractor/types.js +0 -27
- package/dist/internal/extractor/walker.d.ts +0 -18
- package/dist/internal/extractor/walker.js +0 -18
- package/dist/internal/gate-evaluate.d.ts +50 -0
- package/dist/internal/gate-evaluate.js +111 -0
- package/dist/internal/gate-policy.d.ts +38 -0
- package/dist/internal/gate-policy.js +167 -0
- package/dist/internal/git-metadata.d.ts +8 -0
- package/dist/internal/git-metadata.js +38 -0
- package/dist/internal/git.d.ts +9 -0
- package/dist/internal/git.js +45 -0
- package/dist/internal/github-linkage-prompt.d.ts +7 -0
- package/dist/internal/github-linkage-prompt.js +95 -0
- package/dist/internal/ide-setup.d.ts +17 -7
- package/dist/internal/ide-setup.js +379 -46
- package/dist/internal/inventory-sync.d.ts +74 -0
- package/dist/internal/inventory-sync.js +189 -0
- package/dist/internal/org-picker.d.ts +11 -0
- package/dist/internal/org-picker.js +34 -0
- package/dist/internal/orgs.js +0 -1
- package/dist/internal/packs/cache.d.ts +8 -0
- package/dist/internal/packs/cache.js +60 -0
- package/dist/internal/packs/index.d.ts +10 -0
- package/dist/internal/packs/index.js +8 -0
- package/dist/internal/packs/integrity.d.ts +9 -0
- package/dist/internal/packs/integrity.js +24 -0
- package/dist/internal/packs/jcs.d.ts +2 -0
- package/dist/internal/packs/jcs.js +57 -0
- package/dist/internal/packs/local-paths.d.ts +4 -0
- package/dist/internal/packs/local-paths.js +26 -0
- package/dist/internal/packs/npm-registry-client.d.ts +14 -0
- package/dist/internal/packs/npm-registry-client.js +87 -0
- package/dist/internal/packs/registry-client.d.ts +9 -0
- package/dist/internal/packs/registry-client.js +25 -0
- package/dist/internal/packs/resolve.d.ts +8 -0
- package/dist/internal/packs/resolve.js +89 -0
- package/dist/internal/packs/semver.d.ts +9 -0
- package/dist/internal/packs/semver.js +57 -0
- package/dist/internal/packs/signing.d.ts +5 -0
- package/dist/internal/packs/signing.js +56 -0
- package/dist/internal/packs/types.d.ts +77 -0
- package/dist/internal/packs/types.js +20 -0
- package/dist/internal/project-binding.d.ts +1 -0
- package/dist/internal/project-binding.js +16 -11
- package/dist/internal/resolve-init-session.d.ts +8 -0
- package/dist/internal/resolve-init-session.js +36 -0
- package/dist/internal/run-workdir.d.ts +2 -0
- package/dist/internal/run-workdir.js +19 -0
- package/dist/internal/security-context.d.ts +63 -0
- package/dist/internal/security-context.js +50 -0
- package/dist/internal/sync-outbox.d.ts +40 -0
- package/dist/internal/sync-outbox.js +66 -0
- package/dist/internal/target-auth/api-config.d.ts +0 -17
- package/dist/internal/target-auth/api-config.js +0 -18
- package/dist/internal/target-auth/config.d.ts +0 -12
- package/dist/internal/target-auth/config.js +0 -13
- package/dist/internal/target-auth/index.d.ts +0 -18
- package/dist/internal/target-auth/index.js +0 -19
- package/dist/internal/target-auth/keychain.d.ts +0 -18
- package/dist/internal/target-auth/keychain.js +3 -23
- package/dist/internal/target-auth/types.d.ts +0 -26
- package/dist/internal/target-auth/types.js +0 -10
- package/dist/internal/target-auth/workos.d.ts +0 -15
- package/dist/internal/target-auth/workos.js +9 -18
- package/dist/internal/test-scope.d.ts +99 -0
- package/dist/internal/test-scope.js +101 -0
- package/dist/internal/threatmodel-run-state.d.ts +15 -0
- package/dist/internal/threatmodel-run-state.js +43 -0
- package/dist/internal/threatmodel-run.d.ts +85 -0
- package/dist/internal/threatmodel-run.js +159 -0
- package/dist/internal/trust-room-link.d.ts +10 -0
- package/dist/internal/trust-room-link.js +15 -0
- package/dist/internal/zivis-local-state.d.ts +1 -0
- package/dist/internal/zivis-local-state.js +22 -0
- package/package.json +21 -5
- package/dist/commands/app/index.js.map +0 -1
- package/dist/commands/auth/index.js.map +0 -1
- package/dist/commands/auth/init.js.map +0 -1
- package/dist/commands/auth/login.js.map +0 -1
- package/dist/commands/auth/logout.js.map +0 -1
- package/dist/commands/auth/sessions.js.map +0 -1
- package/dist/commands/auth/status.js.map +0 -1
- package/dist/commands/credits/index.js.map +0 -1
- package/dist/commands/mcp/index.js.map +0 -1
- package/dist/commands/open/index.js.map +0 -1
- package/dist/commands/scan/index.js.map +0 -1
- package/dist/commands/target/index.js.map +0 -1
- package/dist/commands/tm/index.d.ts +0 -2
- package/dist/commands/tm/index.js +0 -266
- package/dist/commands/tm/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal/extractor/adapters/go/index.js.map +0 -1
- package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
- package/dist/internal/extractor/adapters/python/index.js.map +0 -1
- package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
- package/dist/internal/extractor/index.js.map +0 -1
- package/dist/internal/extractor/types.js.map +0 -1
- package/dist/internal/extractor/walker.js.map +0 -1
- package/dist/internal/ide-setup.js.map +0 -1
- package/dist/internal/orgs.js.map +0 -1
- package/dist/internal/project-binding.js.map +0 -1
- package/dist/internal/target-auth/api-config.js.map +0 -1
- package/dist/internal/target-auth/config.js.map +0 -1
- package/dist/internal/target-auth/index.js.map +0 -1
- package/dist/internal/target-auth/keychain.js.map +0 -1
- package/dist/internal/target-auth/types.js.map +0 -1
- package/dist/internal/target-auth/workos.js.map +0 -1
|
@@ -1,16 +1,349 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
function getServerName(pkg) {
|
|
4
|
+
return pkg === "builder" ? "zivis-builder" : "zivis";
|
|
5
|
+
}
|
|
6
|
+
function appendBlock(filePath, blockKey, content) {
|
|
7
|
+
const begin = `<!-- BEGIN ZIVIS:${blockKey} -->`;
|
|
8
|
+
const end = `<!-- END ZIVIS:${blockKey} -->`;
|
|
9
|
+
let existing = fs.existsSync(filePath)
|
|
10
|
+
? fs.readFileSync(filePath, "utf-8")
|
|
11
|
+
: "";
|
|
12
|
+
const blockRegex = new RegExp(`${escapeRegex(begin)}[\\s\\S]*?${escapeRegex(end)}`, "g");
|
|
13
|
+
const newBlock = `${begin}\n${content}\n${end}`;
|
|
14
|
+
if (blockRegex.test(existing)) {
|
|
15
|
+
existing = existing.replace(blockRegex, newBlock);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (existing && !existing.endsWith("\n"))
|
|
19
|
+
existing += "\n";
|
|
20
|
+
existing += `\n${newBlock}\n`;
|
|
21
|
+
}
|
|
22
|
+
const dir = path.dirname(filePath);
|
|
23
|
+
if (!fs.existsSync(dir))
|
|
24
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
25
|
+
fs.writeFileSync(filePath, existing);
|
|
26
|
+
}
|
|
27
|
+
function escapeRegex(s) {
|
|
28
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
29
|
+
}
|
|
30
|
+
function removeBlockFrom(filePath, blockKey) {
|
|
31
|
+
if (!fs.existsSync(filePath))
|
|
32
|
+
return false;
|
|
33
|
+
const begin = `<!-- BEGIN ZIVIS:${blockKey} -->`;
|
|
34
|
+
const end = `<!-- END ZIVIS:${blockKey} -->`;
|
|
35
|
+
const blockRegex = new RegExp(`\\n?${escapeRegex(begin)}[\\s\\S]*?${escapeRegex(end)}\\n?`, "g");
|
|
36
|
+
const existing = fs.readFileSync(filePath, "utf-8");
|
|
37
|
+
if (!blockRegex.test(existing))
|
|
38
|
+
return false;
|
|
39
|
+
const stripped = existing.replace(blockRegex, "\n").replace(/\n{3,}/g, "\n\n");
|
|
40
|
+
fs.writeFileSync(filePath, stripped);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
function cursorRuleContent() {
|
|
44
|
+
return `---
|
|
45
|
+
description: ZIVIS security guidance — quietly suggest security checks at the right moments
|
|
46
|
+
globs:
|
|
47
|
+
- "**/*.{ts,tsx,js,jsx,py,go,rb,java}"
|
|
48
|
+
- "**/package.json"
|
|
49
|
+
- "**/requirements.txt"
|
|
50
|
+
- "**/pyproject.toml"
|
|
51
|
+
- "**/go.mod"
|
|
52
|
+
- "**/Dockerfile"
|
|
53
|
+
alwaysApply: false
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
<!-- BEGIN ZIVIS:guidance -->
|
|
57
|
+
|
|
58
|
+
# ZIVIS Security Guidance
|
|
59
|
+
|
|
60
|
+
ZIVIS is a security platform connected to this project as an MCP server.
|
|
61
|
+
Use it sparingly and only when relevant — never nag.
|
|
62
|
+
|
|
63
|
+
## When to suggest ZIVIS
|
|
64
|
+
|
|
65
|
+
**On first security question in this project (per session):**
|
|
66
|
+
If the user asks anything about security, safety, vulnerabilities, or "is this
|
|
67
|
+
secure", call \`zivis_get_started\` first (no arguments). Present the
|
|
68
|
+
\`recommended_next_steps\` as a numbered list. Do NOT invent your own security
|
|
69
|
+
checklist — let ZIVIS produce one based on actual project state.
|
|
70
|
+
|
|
71
|
+
**When dependencies change** (\`package.json\`, \`requirements.txt\`, \`go.mod\`,
|
|
72
|
+
\`pyproject.toml\` is being edited and a new package is added):
|
|
73
|
+
Mention once per session: "Want me to check this dependency with ZIVIS?
|
|
74
|
+
It scans for prompt-injection risks and known vulnerabilities."
|
|
75
|
+
If yes, call \`zivis_check_repo_trust\` with the package's source repo.
|
|
76
|
+
This tool requires NO auth — works for any public GitHub repo.
|
|
77
|
+
|
|
78
|
+
**When AI/LLM SDKs are imported** (\`openai\`, \`anthropic\`, \`langchain\`,
|
|
79
|
+
\`@anthropic-ai/sdk\`, \`llamaindex\`, \`cohere\`, \`together\`, etc.):
|
|
80
|
+
Mention once per session: "You're integrating an AI SDK. Want to set up a
|
|
81
|
+
red-team target with ZIVIS? It tests for prompt injection, jailbreaks, and
|
|
82
|
+
PII leakage." If yes, call \`zivis_setup_red_team_target\` with
|
|
83
|
+
target_type=ai_chat.
|
|
84
|
+
|
|
85
|
+
**When user mentions:** "audit", "compliance", "SOC 2", "pen test",
|
|
86
|
+
"customer security questionnaire", "going to production", "launch":
|
|
87
|
+
Call \`zivis_get_started\` with their phrase as the \`concern\` parameter.
|
|
88
|
+
|
|
89
|
+
**When user has unread findings:**
|
|
90
|
+
At the start of a session you may call \`zivis_get_findings\` (status=open) once.
|
|
91
|
+
If any critical findings exist, surface them before the user starts new work.
|
|
92
|
+
|
|
93
|
+
## When NOT to suggest ZIVIS
|
|
94
|
+
|
|
95
|
+
- Never for non-security questions (refactors, performance, styling, tests, business logic).
|
|
96
|
+
- Never call \`zivis_get_started\` more than once per session unless re-asked.
|
|
97
|
+
- Never run scans that cost credits without explicit user confirmation.
|
|
98
|
+
- Do not lecture about security best practices — let ZIVIS findings speak.
|
|
99
|
+
|
|
100
|
+
## Vocabulary
|
|
101
|
+
|
|
102
|
+
The user is a developer, not a security engineer. Avoid these words unless
|
|
103
|
+
the user uses them first: "actor", "attack vector", "threat model", "STRIDE",
|
|
104
|
+
"kill chain", "TTPs". Prefer plain alternatives: "tester", "how an attacker
|
|
105
|
+
might break in", "security plan", "categories of attacks".
|
|
106
|
+
|
|
107
|
+
## Available slash commands
|
|
108
|
+
|
|
109
|
+
- \`/zivis-getting-started\` — entry-point tour for new users
|
|
110
|
+
- \`/zivis-secure-my-app\` — register and test an app
|
|
111
|
+
- \`/zivis-audit-dependencies\` — check open source libraries (no auth needed)
|
|
112
|
+
- \`/zivis-prep-for-launch\` — pre-launch security checklist
|
|
113
|
+
- \`/zivis-weekly-check\` — weekly security status update
|
|
114
|
+
|
|
115
|
+
## Top tools (for quick reference)
|
|
116
|
+
|
|
117
|
+
- \`zivis_get_started\` — entry point when user is unsure
|
|
118
|
+
- \`zivis_check_repo_trust\` — scan a GitHub repo for risks (no auth needed)
|
|
119
|
+
- \`zivis_setup_red_team_target\` — register an app for testing
|
|
120
|
+
- \`zivis_run_test_scenario\` — run a security test against a target
|
|
121
|
+
- \`zivis_get_findings\` — list current security issues
|
|
122
|
+
- \`zivis_triage_finding\` — resolve / dismiss / accept-risk a finding
|
|
123
|
+
- \`zivis_security_review\` — pre-PR composite security intelligence
|
|
124
|
+
|
|
125
|
+
<!-- END ZIVIS:guidance -->`;
|
|
126
|
+
}
|
|
127
|
+
function claudeBlockContent() {
|
|
128
|
+
return `## ZIVIS
|
|
129
|
+
|
|
130
|
+
ZIVIS is connected to this project via the \`zivis\` CLI — one agent-neutral command surface, not IDE-specific tooling. Each command grounds you with the methodology + your app's live security context; you do the work, then submit the result. The submit step is what records the work — skip it and nothing is saved.
|
|
131
|
+
|
|
132
|
+
- Security-test / review → \`zivis test\` (or \`zivis test <scope>\`; \`zivis test --list\` lists scopes). Do the review it grounds, then submit with the \`zivis run complete …\` command it prints — records findings and risks.
|
|
133
|
+
- Threat model → \`zivis threatmodel\`, author/update the model, then submit with \`zivis threatmodel sync --input <file.md>\`.
|
|
134
|
+
- Inventory → derive the repo's endpoints, tech stack, and top features, write \`{ endpoints?, technologyStack?, features? }\` to JSON, then \`zivis sync --file <inventory.json>\`.
|
|
135
|
+
- Full review or onboarding → run all three in one pass: \`zivis test\` (+submit), then \`zivis sync\`, then \`zivis threatmodel\` (+sync). Together they fill findings, risks, endpoints, tech stack, features, and a living threat model.
|
|
136
|
+
- Use your own repo understanding, reasoning, and shell/tools as needed — these commands ground you; they don't replace judgment.
|
|
137
|
+
- Don't treat their output alone as a confirmed finding; verify before reporting.`;
|
|
138
|
+
}
|
|
139
|
+
function ruleFileContent() {
|
|
140
|
+
return `# ZIVIS Security Guidance
|
|
141
|
+
|
|
142
|
+
ZIVIS is connected to this project via MCP. Use it only for security-related requests.
|
|
143
|
+
|
|
144
|
+
## When to suggest ZIVIS
|
|
145
|
+
|
|
146
|
+
- User asks about security, vulnerabilities, or safety → call zivis_get_started (no args)
|
|
147
|
+
- New dependency added → offer zivis_check_repo_trust (no auth, works for any public repo)
|
|
148
|
+
- AI SDK import added (openai, anthropic, langchain, etc.) → offer zivis_setup_red_team_target with target_type=ai_chat
|
|
149
|
+
- User mentions "audit", "launch", "pen test", "SOC 2" → call zivis_get_started with concern=<their phrase>
|
|
150
|
+
|
|
151
|
+
## When NOT to use
|
|
152
|
+
|
|
153
|
+
Non-security work: refactors, performance, styling, tests, business logic.
|
|
154
|
+
Never run paid scans without user confirmation.
|
|
155
|
+
Never call zivis_get_started more than once per session unless re-asked.
|
|
156
|
+
|
|
157
|
+
## Vocabulary rule
|
|
158
|
+
|
|
159
|
+
Avoid security jargon unless the user uses it first.
|
|
160
|
+
Say "how someone might break in" not "attack vector".
|
|
161
|
+
Say "security plan" not "threat model".
|
|
162
|
+
|
|
163
|
+
## Slash commands
|
|
164
|
+
|
|
165
|
+
/zivis-getting-started — start here if user is new
|
|
166
|
+
/zivis-secure-my-app — set up an app for testing
|
|
167
|
+
/zivis-audit-dependencies — check libraries (free, no login)
|
|
168
|
+
/zivis-prep-for-launch — pre-launch checklist
|
|
169
|
+
/zivis-weekly-check — weekly status update`;
|
|
170
|
+
}
|
|
171
|
+
function copilotBlockContent() {
|
|
172
|
+
return `## ZIVIS Security Integration
|
|
173
|
+
|
|
174
|
+
This project has ZIVIS security tools available via MCP.
|
|
175
|
+
|
|
176
|
+
Use ZIVIS only for security-related user requests. Never proactively run scans or access security data for non-security work.
|
|
177
|
+
|
|
178
|
+
**Trigger conditions:**
|
|
179
|
+
1. User asks about security/vulnerabilities/safety → call zivis_get_started
|
|
180
|
+
2. New external dependency added → offer zivis_check_repo_trust (no auth required)
|
|
181
|
+
3. AI SDK import added (openai, anthropic, langchain) → offer zivis_setup_red_team_target with target_type=ai_chat
|
|
182
|
+
4. User mentions audit/launch/pen test/compliance → call zivis_get_started with concern parameter
|
|
183
|
+
|
|
184
|
+
**Key tools:** zivis_get_started, zivis_check_repo_trust, zivis_setup_red_team_target, zivis_get_findings, zivis_triage_finding
|
|
185
|
+
|
|
186
|
+
**Language:** Avoid security jargon (threat model, STRIDE, attack vector) unless user uses it first.`;
|
|
187
|
+
}
|
|
188
|
+
function writeCursorGuidance(cwd) {
|
|
189
|
+
const rulesDir = path.join(cwd, ".cursor", "rules");
|
|
190
|
+
if (!fs.existsSync(rulesDir))
|
|
191
|
+
fs.mkdirSync(rulesDir, { recursive: true });
|
|
192
|
+
const rulesPath = path.join(rulesDir, "zivis.mdc");
|
|
193
|
+
fs.writeFileSync(rulesPath, cursorRuleContent());
|
|
194
|
+
return rulesPath;
|
|
195
|
+
}
|
|
196
|
+
function writeClaudeBlockGuidance(cwd) {
|
|
197
|
+
const written = [];
|
|
198
|
+
const claudePath = path.join(cwd, "CLAUDE.md");
|
|
199
|
+
appendBlock(claudePath, "zivis-security", claudeBlockContent());
|
|
200
|
+
written.push(claudePath);
|
|
201
|
+
const agentsPath = path.join(cwd, "AGENTS.md");
|
|
202
|
+
appendBlock(agentsPath, "zivis-security", claudeBlockContent());
|
|
203
|
+
written.push(agentsPath);
|
|
204
|
+
return written;
|
|
205
|
+
}
|
|
206
|
+
function writeCopilotGuidance(cwd) {
|
|
207
|
+
const ghDir = path.join(cwd, ".github");
|
|
208
|
+
if (!fs.existsSync(ghDir))
|
|
209
|
+
fs.mkdirSync(ghDir, { recursive: true });
|
|
210
|
+
const instructionsPath = path.join(ghDir, "copilot-instructions.md");
|
|
211
|
+
appendBlock(instructionsPath, "zivis-security", copilotBlockContent());
|
|
212
|
+
return instructionsPath;
|
|
213
|
+
}
|
|
214
|
+
function writeClineGuidance(cwd) {
|
|
215
|
+
const rulesPath = path.join(cwd, ".clinerules");
|
|
216
|
+
fs.writeFileSync(rulesPath, ruleFileContent());
|
|
217
|
+
return rulesPath;
|
|
218
|
+
}
|
|
219
|
+
function writeWindsurfGuidance(cwd) {
|
|
220
|
+
const rulesPath = path.join(cwd, ".windsurfrules");
|
|
221
|
+
fs.writeFileSync(rulesPath, ruleFileContent());
|
|
222
|
+
return rulesPath;
|
|
223
|
+
}
|
|
224
|
+
export function writeGuidance(opts) {
|
|
225
|
+
const { cwd, client } = opts;
|
|
226
|
+
const written = [];
|
|
227
|
+
switch (client) {
|
|
228
|
+
case "cursor": {
|
|
229
|
+
written.push(writeCursorGuidance(cwd));
|
|
230
|
+
const claudePath = path.join(cwd, "CLAUDE.md");
|
|
231
|
+
appendBlock(claudePath, "zivis-security", claudeBlockContent());
|
|
232
|
+
written.push(claudePath);
|
|
233
|
+
const agentsPath = path.join(cwd, "AGENTS.md");
|
|
234
|
+
if (fs.existsSync(agentsPath)) {
|
|
235
|
+
appendBlock(agentsPath, "zivis-security", claudeBlockContent());
|
|
236
|
+
written.push(agentsPath);
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case "claude-code-cli":
|
|
241
|
+
case "vscode-claude": {
|
|
242
|
+
written.push(...writeClaudeBlockGuidance(cwd));
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
case "vscode-copilot": {
|
|
246
|
+
written.push(writeCopilotGuidance(cwd));
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
case "cline": {
|
|
250
|
+
written.push(writeClineGuidance(cwd));
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
case "windsurf": {
|
|
254
|
+
written.push(writeWindsurfGuidance(cwd));
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return written.filter(Boolean);
|
|
259
|
+
}
|
|
260
|
+
export function removeGuidance(opts) {
|
|
261
|
+
const { cwd, client } = opts;
|
|
262
|
+
const changed = [];
|
|
263
|
+
const unlinkIfExists = (p) => {
|
|
264
|
+
if (fs.existsSync(p)) {
|
|
265
|
+
fs.unlinkSync(p);
|
|
266
|
+
changed.push(p);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
switch (client) {
|
|
270
|
+
case "cursor": {
|
|
271
|
+
unlinkIfExists(path.join(cwd, ".cursor", "rules", "zivis.mdc"));
|
|
272
|
+
if (removeBlockFrom(path.join(cwd, "CLAUDE.md"), "zivis-security")) {
|
|
273
|
+
changed.push(path.join(cwd, "CLAUDE.md"));
|
|
274
|
+
}
|
|
275
|
+
if (removeBlockFrom(path.join(cwd, "AGENTS.md"), "zivis-security")) {
|
|
276
|
+
changed.push(path.join(cwd, "AGENTS.md"));
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case "claude-code-cli":
|
|
281
|
+
case "vscode-claude": {
|
|
282
|
+
if (removeBlockFrom(path.join(cwd, "CLAUDE.md"), "zivis-security")) {
|
|
283
|
+
changed.push(path.join(cwd, "CLAUDE.md"));
|
|
284
|
+
}
|
|
285
|
+
if (removeBlockFrom(path.join(cwd, "AGENTS.md"), "zivis-security")) {
|
|
286
|
+
changed.push(path.join(cwd, "AGENTS.md"));
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case "vscode-copilot": {
|
|
291
|
+
if (removeBlockFrom(path.join(cwd, ".github", "copilot-instructions.md"), "zivis-security")) {
|
|
292
|
+
changed.push(path.join(cwd, ".github", "copilot-instructions.md"));
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case "cline": {
|
|
297
|
+
unlinkIfExists(path.join(cwd, ".clinerules"));
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
case "windsurf": {
|
|
301
|
+
unlinkIfExists(path.join(cwd, ".windsurfrules"));
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return changed;
|
|
306
|
+
}
|
|
307
|
+
export function detectIdesInRepo(cwd) {
|
|
308
|
+
const found = [];
|
|
309
|
+
if (fs.existsSync(path.join(cwd, ".cursor"))) {
|
|
310
|
+
found.push("cursor");
|
|
311
|
+
}
|
|
312
|
+
if (fs.existsSync(path.join(cwd, "CLAUDE.md"))) {
|
|
313
|
+
found.push("claude-code-cli");
|
|
314
|
+
}
|
|
315
|
+
if (fs.existsSync(path.join(cwd, ".vscode"))) {
|
|
316
|
+
found.push("vscode-copilot");
|
|
317
|
+
}
|
|
318
|
+
if (fs.existsSync(path.join(cwd, ".clinerules"))) {
|
|
319
|
+
found.push("cline");
|
|
320
|
+
}
|
|
321
|
+
if (fs.existsSync(path.join(cwd, ".windsurfrules"))) {
|
|
322
|
+
found.push("windsurf");
|
|
323
|
+
}
|
|
324
|
+
return found;
|
|
325
|
+
}
|
|
326
|
+
function buildServerConfig(pkg, workspacePath, extra) {
|
|
327
|
+
if (pkg === "builder") {
|
|
328
|
+
const args = ["-y", "@zivis/mcp-builder@alpha", "serve"];
|
|
329
|
+
if (workspacePath) {
|
|
330
|
+
args.push("--workspace", workspacePath);
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
...extra,
|
|
334
|
+
command: "npx",
|
|
335
|
+
args,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const args = ["mcp", "serve"];
|
|
339
|
+
if (workspacePath) {
|
|
340
|
+
args.push("--workspace", workspacePath);
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
6
343
|
...extra,
|
|
7
344
|
command: "zivis",
|
|
8
|
-
args
|
|
345
|
+
args,
|
|
9
346
|
};
|
|
10
|
-
if (session) {
|
|
11
|
-
config.env = { ZIVIS_SESSION: session };
|
|
12
|
-
}
|
|
13
|
-
return config;
|
|
14
347
|
}
|
|
15
348
|
async function updateMcpConfig(configPath, serverName, serverConfig, rootKey) {
|
|
16
349
|
const configDir = path.dirname(configPath);
|
|
@@ -33,41 +366,47 @@ async function updateMcpConfig(configPath, serverName, serverConfig, rootKey) {
|
|
|
33
366
|
servers[serverName] = serverConfig;
|
|
34
367
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
35
368
|
}
|
|
36
|
-
export async function setupCursor(
|
|
369
|
+
export async function setupCursor(pkg = "appsec") {
|
|
37
370
|
const homeDir = process.env.HOME || "";
|
|
38
371
|
const configPath = path.join(homeDir, ".cursor", "mcp.json");
|
|
39
|
-
await updateMcpConfig(configPath,
|
|
40
|
-
console.log(`✓ Cursor MCP config updated: ${configPath}`);
|
|
41
|
-
if (session)
|
|
42
|
-
console.log(` Session: ${session}`);
|
|
372
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg), "mcpServers");
|
|
373
|
+
console.log(`✓ Cursor global MCP config updated: ${configPath}`);
|
|
43
374
|
console.log(" Restart Cursor for changes to take effect");
|
|
44
375
|
}
|
|
45
|
-
export async function
|
|
46
|
-
const
|
|
376
|
+
export async function setupCursorWorkspace(pkg = "appsec") {
|
|
377
|
+
const workspacePath = process.cwd();
|
|
378
|
+
const configPath = path.join(workspacePath, ".cursor", "mcp.json");
|
|
379
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
|
|
380
|
+
console.log(`✓ Cursor workspace MCP config updated: ${configPath}`);
|
|
381
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
382
|
+
console.log(" Reload Cursor for changes to take effect");
|
|
383
|
+
}
|
|
384
|
+
export async function setupVsCodeCopilot(pkg = "appsec") {
|
|
385
|
+
const workspacePath = process.cwd();
|
|
386
|
+
const localConfigPath = path.join(workspacePath, ".vscode", "mcp.json");
|
|
47
387
|
const globalConfigPath = path.join(process.env.HOME || "", ".vscode", "mcp.json");
|
|
48
388
|
let configPath = localConfigPath;
|
|
49
389
|
const exists = fs.existsSync(localConfigPath);
|
|
50
390
|
if (!exists && fs.existsSync(globalConfigPath)) {
|
|
51
391
|
configPath = globalConfigPath;
|
|
52
392
|
}
|
|
53
|
-
await updateMcpConfig(configPath,
|
|
393
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath, { type: "stdio" }), "servers");
|
|
54
394
|
console.log(`✓ VS Code (GitHub Copilot) MCP config updated: ${configPath}`);
|
|
55
|
-
|
|
56
|
-
console.log(` Session: ${session}`);
|
|
395
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
57
396
|
console.log(" Restart VS Code for changes to take effect");
|
|
58
397
|
}
|
|
59
|
-
export async function setupVsCodeClaude(
|
|
60
|
-
const
|
|
61
|
-
|
|
398
|
+
export async function setupVsCodeClaude(pkg = "appsec") {
|
|
399
|
+
const workspacePath = process.cwd();
|
|
400
|
+
const configPath = path.join(workspacePath, ".vscode", "mcp.json");
|
|
401
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
|
|
62
402
|
console.log(`✓ VS Code (Claude Code) MCP config updated: ${configPath}`);
|
|
63
|
-
|
|
64
|
-
console.log(` Session: ${session}`);
|
|
403
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
65
404
|
console.log(" Restart VS Code for changes to take effect");
|
|
66
405
|
}
|
|
67
|
-
export async function setupClaudeCodeCli(
|
|
406
|
+
export async function setupClaudeCodeCli(pkg = "appsec") {
|
|
68
407
|
const homeDir = process.env.HOME || "";
|
|
69
408
|
const configPath = path.join(homeDir, ".claude.json");
|
|
70
|
-
const
|
|
409
|
+
const workspacePath = process.cwd();
|
|
71
410
|
if (!fs.existsSync(configPath)) {
|
|
72
411
|
console.log(" Skipping Claude Code CLI (no ~/.claude.json found)");
|
|
73
412
|
return;
|
|
@@ -75,48 +414,43 @@ export async function setupClaudeCodeCli(session) {
|
|
|
75
414
|
try {
|
|
76
415
|
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
77
416
|
config.projects ??= {};
|
|
78
|
-
config.projects[
|
|
79
|
-
config.projects[
|
|
80
|
-
config.projects[
|
|
81
|
-
type: "stdio",
|
|
82
|
-
command: "zivis",
|
|
83
|
-
args: ["mcp", "serve"],
|
|
84
|
-
env: session ? { ZIVIS_SESSION: session } : {},
|
|
85
|
-
};
|
|
417
|
+
config.projects[workspacePath] ??= {};
|
|
418
|
+
config.projects[workspacePath].mcpServers ??= {};
|
|
419
|
+
config.projects[workspacePath].mcpServers[getServerName(pkg)] = buildServerConfig(pkg, workspacePath, { type: "stdio" });
|
|
86
420
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
87
421
|
console.log("✓ Claude Code CLI MCP config updated: ~/.claude.json");
|
|
88
|
-
|
|
89
|
-
console.log(` Session: ${session}`);
|
|
422
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
90
423
|
console.log(" Restart Claude Code for changes to take effect");
|
|
91
424
|
}
|
|
92
425
|
catch (err) {
|
|
93
426
|
console.log(` WARNING: Failed to update ~/.claude.json: ${err instanceof Error ? err.message : err}`);
|
|
94
427
|
}
|
|
95
428
|
}
|
|
96
|
-
export async function setupCline(
|
|
429
|
+
export async function setupCline(pkg = "appsec") {
|
|
430
|
+
const workspacePath = process.cwd();
|
|
97
431
|
const homeDir = process.env.HOME || "";
|
|
98
432
|
const configPath = process.platform === "darwin"
|
|
99
433
|
? path.join(homeDir, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json")
|
|
100
434
|
: path.join(homeDir, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
|
|
101
|
-
await updateMcpConfig(configPath,
|
|
435
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
|
|
102
436
|
console.log(`✓ Cline MCP config updated: ${configPath}`);
|
|
103
|
-
|
|
104
|
-
console.log(` Session: ${session}`);
|
|
437
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
105
438
|
console.log(" Restart VS Code for changes to take effect");
|
|
106
439
|
}
|
|
107
|
-
export async function setupWindsurf(
|
|
440
|
+
export async function setupWindsurf(pkg = "appsec") {
|
|
441
|
+
const workspacePath = process.cwd();
|
|
108
442
|
const homeDir = process.env.HOME || "";
|
|
109
443
|
const configPath = path.join(homeDir, ".codeium", "windsurf", "mcp_config.json");
|
|
110
|
-
await updateMcpConfig(configPath,
|
|
444
|
+
await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
|
|
111
445
|
console.log(`✓ Windsurf MCP config updated: ${configPath}`);
|
|
112
|
-
|
|
113
|
-
console.log(` Session: ${session}`);
|
|
446
|
+
console.log(` Workspace: ${workspacePath}`);
|
|
114
447
|
console.log(" Restart Windsurf for changes to take effect");
|
|
115
448
|
}
|
|
116
|
-
export function printClaudeCodeManual(
|
|
449
|
+
export function printClaudeCodeManual(pkg = "appsec") {
|
|
450
|
+
const workspacePath = process.cwd();
|
|
117
451
|
const serverConfig = {
|
|
118
452
|
mcpServers: {
|
|
119
|
-
[
|
|
453
|
+
[getServerName(pkg)]: buildServerConfig(pkg, workspacePath),
|
|
120
454
|
},
|
|
121
455
|
};
|
|
122
456
|
console.log("");
|
|
@@ -128,4 +462,3 @@ export function printClaudeCodeManual(session) {
|
|
|
128
462
|
console.log("");
|
|
129
463
|
console.log("Then restart Claude Code for changes to take effect");
|
|
130
464
|
}
|
|
131
|
-
//# sourceMappingURL=ide-setup.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface InventorySyncEndpoint {
|
|
2
|
+
path: string;
|
|
3
|
+
method: string;
|
|
4
|
+
summary?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
authRequired?: boolean;
|
|
7
|
+
tags?: string[];
|
|
8
|
+
deprecated?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface InventorySyncFeature {
|
|
11
|
+
name: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
criticality?: "critical" | "high" | "medium" | "low";
|
|
14
|
+
endpoints?: string[];
|
|
15
|
+
tags?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface InventorySyncInput {
|
|
18
|
+
endpoints?: InventorySyncEndpoint[];
|
|
19
|
+
features?: InventorySyncFeature[];
|
|
20
|
+
technologyStack?: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface InventorySyncProvenance {
|
|
23
|
+
gitCommitSha?: string | null;
|
|
24
|
+
repoFullName?: string | null;
|
|
25
|
+
defaultBranch?: string | null;
|
|
26
|
+
source: "cli" | "agent";
|
|
27
|
+
}
|
|
28
|
+
export type ValidationResult = {
|
|
29
|
+
ok: true;
|
|
30
|
+
value: InventorySyncInput;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
errors: string[];
|
|
34
|
+
};
|
|
35
|
+
export declare function validateInventorySyncInput(raw: unknown): ValidationResult;
|
|
36
|
+
export interface EndpointReconcileResult {
|
|
37
|
+
created: number;
|
|
38
|
+
updated: number;
|
|
39
|
+
deprecated: number;
|
|
40
|
+
total: number;
|
|
41
|
+
}
|
|
42
|
+
export interface FeatureReconcileResult {
|
|
43
|
+
created: number;
|
|
44
|
+
updated: number;
|
|
45
|
+
deprecated: number;
|
|
46
|
+
endpointsLinked: number;
|
|
47
|
+
filesLinked: number;
|
|
48
|
+
}
|
|
49
|
+
export interface TechStackResult {
|
|
50
|
+
id: string;
|
|
51
|
+
techStack: string[];
|
|
52
|
+
}
|
|
53
|
+
export interface RepoSyncResult {
|
|
54
|
+
created: boolean;
|
|
55
|
+
repoFullName: string;
|
|
56
|
+
}
|
|
57
|
+
export interface InventorySyncSummary {
|
|
58
|
+
endpoints?: EndpointReconcileResult;
|
|
59
|
+
features?: FeatureReconcileResult;
|
|
60
|
+
technologyStack?: {
|
|
61
|
+
count: number;
|
|
62
|
+
};
|
|
63
|
+
repo?: RepoSyncResult;
|
|
64
|
+
}
|
|
65
|
+
export interface InventorySyncApi {
|
|
66
|
+
put<T>(path: string, body: unknown): Promise<T>;
|
|
67
|
+
post<T>(path: string, body: unknown): Promise<T>;
|
|
68
|
+
}
|
|
69
|
+
export declare function syncApplicationInventory(params: {
|
|
70
|
+
client: InventorySyncApi;
|
|
71
|
+
applicationId: string;
|
|
72
|
+
input: InventorySyncInput;
|
|
73
|
+
provenance: InventorySyncProvenance;
|
|
74
|
+
}): Promise<InventorySyncSummary>;
|