@zivis/cli 0.1.0-alpha.4 → 0.1.0-alpha.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +31 -0
  3. package/dist/commands/app/index.d.ts +0 -8
  4. package/dist/commands/app/index.js +8 -18
  5. package/dist/commands/assurance/index.d.ts +33 -0
  6. package/dist/commands/assurance/index.js +149 -0
  7. package/dist/commands/auth/bind.d.ts +4 -0
  8. package/dist/commands/auth/bind.js +97 -0
  9. package/dist/commands/auth/index.js +21 -2
  10. package/dist/commands/auth/init.d.ts +2 -0
  11. package/dist/commands/auth/init.js +249 -73
  12. package/dist/commands/auth/login.d.ts +2 -0
  13. package/dist/commands/auth/login.js +136 -18
  14. package/dist/commands/auth/logout.js +19 -7
  15. package/dist/commands/auth/sessions.js +7 -4
  16. package/dist/commands/auth/status.js +33 -12
  17. package/dist/commands/auth/token.d.ts +4 -0
  18. package/dist/commands/auth/token.js +73 -0
  19. package/dist/commands/check/index.d.ts +2 -0
  20. package/dist/commands/check/index.js +463 -0
  21. package/dist/commands/credits/index.js +2 -3
  22. package/dist/commands/gate/index.d.ts +2 -0
  23. package/dist/commands/gate/index.js +171 -0
  24. package/dist/commands/inspect/index.d.ts +2 -0
  25. package/dist/commands/inspect/index.js +136 -0
  26. package/dist/commands/mcp/index.js +113 -14
  27. package/dist/commands/open/index.d.ts +0 -8
  28. package/dist/commands/open/index.js +0 -11
  29. package/dist/commands/run/index.d.ts +2 -0
  30. package/dist/commands/run/index.js +111 -0
  31. package/dist/commands/scan/index.js +3 -8
  32. package/dist/commands/sync/index.d.ts +2 -0
  33. package/dist/commands/sync/index.js +187 -0
  34. package/dist/commands/target/index.js +0 -3
  35. package/dist/commands/test/index.d.ts +2 -0
  36. package/dist/commands/test/index.js +115 -0
  37. package/dist/commands/tm/index.js +7 -10
  38. package/dist/index.js +24 -1
  39. package/dist/internal/application-binding.d.ts +8 -0
  40. package/dist/internal/application-binding.js +167 -0
  41. package/dist/internal/binding-token-mint.d.ts +33 -0
  42. package/dist/internal/binding-token-mint.js +174 -0
  43. package/dist/internal/cli-output.d.ts +16 -0
  44. package/dist/internal/cli-output.js +39 -0
  45. package/dist/internal/devx-run.d.ts +47 -0
  46. package/dist/internal/devx-run.js +36 -0
  47. package/dist/internal/extractor/adapters/go/index.d.ts +0 -4
  48. package/dist/internal/extractor/adapters/go/index.js +0 -6
  49. package/dist/internal/extractor/adapters/go/manifest.d.ts +0 -17
  50. package/dist/internal/extractor/adapters/go/manifest.js +19 -25
  51. package/dist/internal/extractor/adapters/go/parser.d.ts +0 -4
  52. package/dist/internal/extractor/adapters/go/parser.js +0 -5
  53. package/dist/internal/extractor/adapters/go/scanner.d.ts +0 -20
  54. package/dist/internal/extractor/adapters/go/scanner.js +0 -43
  55. package/dist/internal/extractor/adapters/python/index.d.ts +0 -3
  56. package/dist/internal/extractor/adapters/python/index.js +0 -4
  57. package/dist/internal/extractor/adapters/python/manifest.d.ts +0 -8
  58. package/dist/internal/extractor/adapters/python/manifest.js +21 -18
  59. package/dist/internal/extractor/adapters/python/parser.d.ts +0 -3
  60. package/dist/internal/extractor/adapters/python/parser.js +0 -4
  61. package/dist/internal/extractor/adapters/python/scanner.d.ts +0 -18
  62. package/dist/internal/extractor/adapters/python/scanner.js +1 -54
  63. package/dist/internal/extractor/adapters/typescript/index.d.ts +0 -7
  64. package/dist/internal/extractor/adapters/typescript/index.js +1 -21
  65. package/dist/internal/extractor/adapters/typescript/manifest.d.ts +0 -14
  66. package/dist/internal/extractor/adapters/typescript/manifest.js +26 -17
  67. package/dist/internal/extractor/adapters/typescript/parser.d.ts +0 -8
  68. package/dist/internal/extractor/adapters/typescript/parser.js +0 -9
  69. package/dist/internal/extractor/adapters/typescript/scanner.d.ts +0 -24
  70. package/dist/internal/extractor/adapters/typescript/scanner.js +0 -43
  71. package/dist/internal/extractor/graph-builder.d.ts +10 -0
  72. package/dist/internal/extractor/graph-builder.js +245 -0
  73. package/dist/internal/extractor/graph-types.d.ts +89 -0
  74. package/dist/internal/extractor/graph-types.js +1 -0
  75. package/dist/internal/extractor/index.d.ts +0 -14
  76. package/dist/internal/extractor/index.js +0 -13
  77. package/dist/internal/extractor/types.d.ts +0 -45
  78. package/dist/internal/extractor/types.js +0 -27
  79. package/dist/internal/extractor/walker.d.ts +0 -18
  80. package/dist/internal/extractor/walker.js +0 -18
  81. package/dist/internal/gate-evaluate.d.ts +50 -0
  82. package/dist/internal/gate-evaluate.js +111 -0
  83. package/dist/internal/gate-policy.d.ts +38 -0
  84. package/dist/internal/gate-policy.js +167 -0
  85. package/dist/internal/git-metadata.d.ts +8 -0
  86. package/dist/internal/git-metadata.js +38 -0
  87. package/dist/internal/git.d.ts +8 -0
  88. package/dist/internal/git.js +30 -0
  89. package/dist/internal/github-linkage-prompt.d.ts +7 -0
  90. package/dist/internal/github-linkage-prompt.js +95 -0
  91. package/dist/internal/ide-setup.d.ts +17 -7
  92. package/dist/internal/ide-setup.js +377 -46
  93. package/dist/internal/inventory-sync.d.ts +74 -0
  94. package/dist/internal/inventory-sync.js +189 -0
  95. package/dist/internal/org-picker.d.ts +11 -0
  96. package/dist/internal/org-picker.js +34 -0
  97. package/dist/internal/orgs.js +0 -1
  98. package/dist/internal/packs/cache.d.ts +8 -0
  99. package/dist/internal/packs/cache.js +60 -0
  100. package/dist/internal/packs/index.d.ts +10 -0
  101. package/dist/internal/packs/index.js +7 -0
  102. package/dist/internal/packs/integrity.d.ts +9 -0
  103. package/dist/internal/packs/integrity.js +24 -0
  104. package/dist/internal/packs/jcs.d.ts +2 -0
  105. package/dist/internal/packs/jcs.js +57 -0
  106. package/dist/internal/packs/local-paths.d.ts +4 -0
  107. package/dist/internal/packs/local-paths.js +26 -0
  108. package/dist/internal/packs/registry-client.d.ts +20 -0
  109. package/dist/internal/packs/registry-client.js +40 -0
  110. package/dist/internal/packs/resolve.d.ts +8 -0
  111. package/dist/internal/packs/resolve.js +89 -0
  112. package/dist/internal/packs/semver.d.ts +9 -0
  113. package/dist/internal/packs/semver.js +57 -0
  114. package/dist/internal/packs/signing.d.ts +5 -0
  115. package/dist/internal/packs/signing.js +49 -0
  116. package/dist/internal/packs/types.d.ts +70 -0
  117. package/dist/internal/packs/types.js +20 -0
  118. package/dist/internal/project-binding.d.ts +1 -0
  119. package/dist/internal/project-binding.js +14 -9
  120. package/dist/internal/run-workdir.d.ts +1 -0
  121. package/dist/internal/run-workdir.js +11 -0
  122. package/dist/internal/security-context.d.ts +62 -0
  123. package/dist/internal/security-context.js +50 -0
  124. package/dist/internal/sync-outbox.d.ts +40 -0
  125. package/dist/internal/sync-outbox.js +66 -0
  126. package/dist/internal/target-auth/api-config.d.ts +0 -17
  127. package/dist/internal/target-auth/api-config.js +0 -18
  128. package/dist/internal/target-auth/config.d.ts +0 -12
  129. package/dist/internal/target-auth/config.js +0 -13
  130. package/dist/internal/target-auth/index.d.ts +0 -18
  131. package/dist/internal/target-auth/index.js +0 -19
  132. package/dist/internal/target-auth/keychain.d.ts +0 -18
  133. package/dist/internal/target-auth/keychain.js +3 -23
  134. package/dist/internal/target-auth/types.d.ts +0 -26
  135. package/dist/internal/target-auth/types.js +0 -10
  136. package/dist/internal/target-auth/workos.d.ts +0 -15
  137. package/dist/internal/target-auth/workos.js +9 -18
  138. package/dist/internal/test-scope.d.ts +68 -0
  139. package/dist/internal/test-scope.js +69 -0
  140. package/dist/internal/zivis-local-state.d.ts +1 -0
  141. package/dist/internal/zivis-local-state.js +22 -0
  142. package/package.json +20 -5
  143. package/dist/commands/app/index.js.map +0 -1
  144. package/dist/commands/auth/index.js.map +0 -1
  145. package/dist/commands/auth/init.js.map +0 -1
  146. package/dist/commands/auth/login.js.map +0 -1
  147. package/dist/commands/auth/logout.js.map +0 -1
  148. package/dist/commands/auth/sessions.js.map +0 -1
  149. package/dist/commands/auth/status.js.map +0 -1
  150. package/dist/commands/credits/index.js.map +0 -1
  151. package/dist/commands/mcp/index.js.map +0 -1
  152. package/dist/commands/open/index.js.map +0 -1
  153. package/dist/commands/scan/index.js.map +0 -1
  154. package/dist/commands/target/index.js.map +0 -1
  155. package/dist/commands/tm/index.js.map +0 -1
  156. package/dist/index.js.map +0 -1
  157. package/dist/internal/extractor/adapters/go/index.js.map +0 -1
  158. package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
  159. package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
  160. package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
  161. package/dist/internal/extractor/adapters/python/index.js.map +0 -1
  162. package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
  163. package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
  164. package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
  165. package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
  166. package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
  167. package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
  168. package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
  169. package/dist/internal/extractor/index.js.map +0 -1
  170. package/dist/internal/extractor/types.js.map +0 -1
  171. package/dist/internal/extractor/walker.js.map +0 -1
  172. package/dist/internal/ide-setup.js.map +0 -1
  173. package/dist/internal/orgs.js.map +0 -1
  174. package/dist/internal/project-binding.js.map +0 -1
  175. package/dist/internal/target-auth/api-config.js.map +0 -1
  176. package/dist/internal/target-auth/config.js.map +0 -1
  177. package/dist/internal/target-auth/index.js.map +0 -1
  178. package/dist/internal/target-auth/keychain.js.map +0 -1
  179. package/dist/internal/target-auth/types.js.map +0 -1
  180. package/dist/internal/target-auth/workos.js.map +0 -1
@@ -1,16 +1,347 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- const SERVER_NAME = "zivis";
4
- function buildServerConfig(session, extra) {
5
- const config = {
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.
131
+
132
+ - Asked to security test or review this repo → run \`zivis test\` (or \`zivis test <scope>\` for a focused pass; \`zivis test --list\` shows available scopes) and follow the guidance it returns.
133
+ - Asked to threat model this repo → run \`zivis threatmodel\` and follow the guidance it returns.
134
+ - Use your own repo understanding, reasoning, and shell/tools/browser access as needed — these commands are a starting point, not a substitute for judgment.
135
+ - Do not treat their output alone as a confirmed finding; verify before reporting.`;
136
+ }
137
+ function ruleFileContent() {
138
+ return `# ZIVIS Security Guidance
139
+
140
+ ZIVIS is connected to this project via MCP. Use it only for security-related requests.
141
+
142
+ ## When to suggest ZIVIS
143
+
144
+ - User asks about security, vulnerabilities, or safety → call zivis_get_started (no args)
145
+ - New dependency added → offer zivis_check_repo_trust (no auth, works for any public repo)
146
+ - AI SDK import added (openai, anthropic, langchain, etc.) → offer zivis_setup_red_team_target with target_type=ai_chat
147
+ - User mentions "audit", "launch", "pen test", "SOC 2" → call zivis_get_started with concern=<their phrase>
148
+
149
+ ## When NOT to use
150
+
151
+ Non-security work: refactors, performance, styling, tests, business logic.
152
+ Never run paid scans without user confirmation.
153
+ Never call zivis_get_started more than once per session unless re-asked.
154
+
155
+ ## Vocabulary rule
156
+
157
+ Avoid security jargon unless the user uses it first.
158
+ Say "how someone might break in" not "attack vector".
159
+ Say "security plan" not "threat model".
160
+
161
+ ## Slash commands
162
+
163
+ /zivis-getting-started — start here if user is new
164
+ /zivis-secure-my-app — set up an app for testing
165
+ /zivis-audit-dependencies — check libraries (free, no login)
166
+ /zivis-prep-for-launch — pre-launch checklist
167
+ /zivis-weekly-check — weekly status update`;
168
+ }
169
+ function copilotBlockContent() {
170
+ return `## ZIVIS Security Integration
171
+
172
+ This project has ZIVIS security tools available via MCP.
173
+
174
+ Use ZIVIS only for security-related user requests. Never proactively run scans or access security data for non-security work.
175
+
176
+ **Trigger conditions:**
177
+ 1. User asks about security/vulnerabilities/safety → call zivis_get_started
178
+ 2. New external dependency added → offer zivis_check_repo_trust (no auth required)
179
+ 3. AI SDK import added (openai, anthropic, langchain) → offer zivis_setup_red_team_target with target_type=ai_chat
180
+ 4. User mentions audit/launch/pen test/compliance → call zivis_get_started with concern parameter
181
+
182
+ **Key tools:** zivis_get_started, zivis_check_repo_trust, zivis_setup_red_team_target, zivis_get_findings, zivis_triage_finding
183
+
184
+ **Language:** Avoid security jargon (threat model, STRIDE, attack vector) unless user uses it first.`;
185
+ }
186
+ function writeCursorGuidance(cwd) {
187
+ const rulesDir = path.join(cwd, ".cursor", "rules");
188
+ if (!fs.existsSync(rulesDir))
189
+ fs.mkdirSync(rulesDir, { recursive: true });
190
+ const rulesPath = path.join(rulesDir, "zivis.mdc");
191
+ fs.writeFileSync(rulesPath, cursorRuleContent());
192
+ return rulesPath;
193
+ }
194
+ function writeClaudeBlockGuidance(cwd) {
195
+ const written = [];
196
+ const claudePath = path.join(cwd, "CLAUDE.md");
197
+ appendBlock(claudePath, "zivis-security", claudeBlockContent());
198
+ written.push(claudePath);
199
+ const agentsPath = path.join(cwd, "AGENTS.md");
200
+ appendBlock(agentsPath, "zivis-security", claudeBlockContent());
201
+ written.push(agentsPath);
202
+ return written;
203
+ }
204
+ function writeCopilotGuidance(cwd) {
205
+ const ghDir = path.join(cwd, ".github");
206
+ if (!fs.existsSync(ghDir))
207
+ fs.mkdirSync(ghDir, { recursive: true });
208
+ const instructionsPath = path.join(ghDir, "copilot-instructions.md");
209
+ appendBlock(instructionsPath, "zivis-security", copilotBlockContent());
210
+ return instructionsPath;
211
+ }
212
+ function writeClineGuidance(cwd) {
213
+ const rulesPath = path.join(cwd, ".clinerules");
214
+ fs.writeFileSync(rulesPath, ruleFileContent());
215
+ return rulesPath;
216
+ }
217
+ function writeWindsurfGuidance(cwd) {
218
+ const rulesPath = path.join(cwd, ".windsurfrules");
219
+ fs.writeFileSync(rulesPath, ruleFileContent());
220
+ return rulesPath;
221
+ }
222
+ export function writeGuidance(opts) {
223
+ const { cwd, client } = opts;
224
+ const written = [];
225
+ switch (client) {
226
+ case "cursor": {
227
+ written.push(writeCursorGuidance(cwd));
228
+ const claudePath = path.join(cwd, "CLAUDE.md");
229
+ appendBlock(claudePath, "zivis-security", claudeBlockContent());
230
+ written.push(claudePath);
231
+ const agentsPath = path.join(cwd, "AGENTS.md");
232
+ if (fs.existsSync(agentsPath)) {
233
+ appendBlock(agentsPath, "zivis-security", claudeBlockContent());
234
+ written.push(agentsPath);
235
+ }
236
+ break;
237
+ }
238
+ case "claude-code-cli":
239
+ case "vscode-claude": {
240
+ written.push(...writeClaudeBlockGuidance(cwd));
241
+ break;
242
+ }
243
+ case "vscode-copilot": {
244
+ written.push(writeCopilotGuidance(cwd));
245
+ break;
246
+ }
247
+ case "cline": {
248
+ written.push(writeClineGuidance(cwd));
249
+ break;
250
+ }
251
+ case "windsurf": {
252
+ written.push(writeWindsurfGuidance(cwd));
253
+ break;
254
+ }
255
+ }
256
+ return written.filter(Boolean);
257
+ }
258
+ export function removeGuidance(opts) {
259
+ const { cwd, client } = opts;
260
+ const changed = [];
261
+ const unlinkIfExists = (p) => {
262
+ if (fs.existsSync(p)) {
263
+ fs.unlinkSync(p);
264
+ changed.push(p);
265
+ }
266
+ };
267
+ switch (client) {
268
+ case "cursor": {
269
+ unlinkIfExists(path.join(cwd, ".cursor", "rules", "zivis.mdc"));
270
+ if (removeBlockFrom(path.join(cwd, "CLAUDE.md"), "zivis-security")) {
271
+ changed.push(path.join(cwd, "CLAUDE.md"));
272
+ }
273
+ if (removeBlockFrom(path.join(cwd, "AGENTS.md"), "zivis-security")) {
274
+ changed.push(path.join(cwd, "AGENTS.md"));
275
+ }
276
+ break;
277
+ }
278
+ case "claude-code-cli":
279
+ case "vscode-claude": {
280
+ if (removeBlockFrom(path.join(cwd, "CLAUDE.md"), "zivis-security")) {
281
+ changed.push(path.join(cwd, "CLAUDE.md"));
282
+ }
283
+ if (removeBlockFrom(path.join(cwd, "AGENTS.md"), "zivis-security")) {
284
+ changed.push(path.join(cwd, "AGENTS.md"));
285
+ }
286
+ break;
287
+ }
288
+ case "vscode-copilot": {
289
+ if (removeBlockFrom(path.join(cwd, ".github", "copilot-instructions.md"), "zivis-security")) {
290
+ changed.push(path.join(cwd, ".github", "copilot-instructions.md"));
291
+ }
292
+ break;
293
+ }
294
+ case "cline": {
295
+ unlinkIfExists(path.join(cwd, ".clinerules"));
296
+ break;
297
+ }
298
+ case "windsurf": {
299
+ unlinkIfExists(path.join(cwd, ".windsurfrules"));
300
+ break;
301
+ }
302
+ }
303
+ return changed;
304
+ }
305
+ export function detectIdesInRepo(cwd) {
306
+ const found = [];
307
+ if (fs.existsSync(path.join(cwd, ".cursor"))) {
308
+ found.push("cursor");
309
+ }
310
+ if (fs.existsSync(path.join(cwd, "CLAUDE.md"))) {
311
+ found.push("claude-code-cli");
312
+ }
313
+ if (fs.existsSync(path.join(cwd, ".vscode"))) {
314
+ found.push("vscode-copilot");
315
+ }
316
+ if (fs.existsSync(path.join(cwd, ".clinerules"))) {
317
+ found.push("cline");
318
+ }
319
+ if (fs.existsSync(path.join(cwd, ".windsurfrules"))) {
320
+ found.push("windsurf");
321
+ }
322
+ return found;
323
+ }
324
+ function buildServerConfig(pkg, workspacePath, extra) {
325
+ if (pkg === "builder") {
326
+ const args = ["-y", "@zivis/mcp-builder@alpha", "serve"];
327
+ if (workspacePath) {
328
+ args.push("--workspace", workspacePath);
329
+ }
330
+ return {
331
+ ...extra,
332
+ command: "npx",
333
+ args,
334
+ };
335
+ }
336
+ const args = ["mcp", "serve"];
337
+ if (workspacePath) {
338
+ args.push("--workspace", workspacePath);
339
+ }
340
+ return {
6
341
  ...extra,
7
342
  command: "zivis",
8
- args: ["mcp", "serve"],
343
+ args,
9
344
  };
10
- if (session) {
11
- config.env = { ZIVIS_SESSION: session };
12
- }
13
- return config;
14
345
  }
15
346
  async function updateMcpConfig(configPath, serverName, serverConfig, rootKey) {
16
347
  const configDir = path.dirname(configPath);
@@ -33,41 +364,47 @@ async function updateMcpConfig(configPath, serverName, serverConfig, rootKey) {
33
364
  servers[serverName] = serverConfig;
34
365
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
35
366
  }
36
- export async function setupCursor(session) {
367
+ export async function setupCursor(pkg = "appsec") {
37
368
  const homeDir = process.env.HOME || "";
38
369
  const configPath = path.join(homeDir, ".cursor", "mcp.json");
39
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session), "mcpServers");
40
- console.log(`✓ Cursor MCP config updated: ${configPath}`);
41
- if (session)
42
- console.log(` Session: ${session}`);
370
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg), "mcpServers");
371
+ console.log(`✓ Cursor global MCP config updated: ${configPath}`);
43
372
  console.log(" Restart Cursor for changes to take effect");
44
373
  }
45
- export async function setupVsCodeCopilot(session) {
46
- const localConfigPath = path.join(process.cwd(), ".vscode", "mcp.json");
374
+ export async function setupCursorWorkspace(pkg = "appsec") {
375
+ const workspacePath = process.cwd();
376
+ const configPath = path.join(workspacePath, ".cursor", "mcp.json");
377
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
378
+ console.log(`✓ Cursor workspace MCP config updated: ${configPath}`);
379
+ console.log(` Workspace: ${workspacePath}`);
380
+ console.log(" Reload Cursor for changes to take effect");
381
+ }
382
+ export async function setupVsCodeCopilot(pkg = "appsec") {
383
+ const workspacePath = process.cwd();
384
+ const localConfigPath = path.join(workspacePath, ".vscode", "mcp.json");
47
385
  const globalConfigPath = path.join(process.env.HOME || "", ".vscode", "mcp.json");
48
386
  let configPath = localConfigPath;
49
387
  const exists = fs.existsSync(localConfigPath);
50
388
  if (!exists && fs.existsSync(globalConfigPath)) {
51
389
  configPath = globalConfigPath;
52
390
  }
53
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session, { type: "stdio" }), "servers");
391
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath, { type: "stdio" }), "servers");
54
392
  console.log(`✓ VS Code (GitHub Copilot) MCP config updated: ${configPath}`);
55
- if (session)
56
- console.log(` Session: ${session}`);
393
+ console.log(` Workspace: ${workspacePath}`);
57
394
  console.log(" Restart VS Code for changes to take effect");
58
395
  }
59
- export async function setupVsCodeClaude(session) {
60
- const configPath = path.join(process.cwd(), ".vscode", "mcp.json");
61
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session), "mcpServers");
396
+ export async function setupVsCodeClaude(pkg = "appsec") {
397
+ const workspacePath = process.cwd();
398
+ const configPath = path.join(workspacePath, ".vscode", "mcp.json");
399
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
62
400
  console.log(`✓ VS Code (Claude Code) MCP config updated: ${configPath}`);
63
- if (session)
64
- console.log(` Session: ${session}`);
401
+ console.log(` Workspace: ${workspacePath}`);
65
402
  console.log(" Restart VS Code for changes to take effect");
66
403
  }
67
- export async function setupClaudeCodeCli(session) {
404
+ export async function setupClaudeCodeCli(pkg = "appsec") {
68
405
  const homeDir = process.env.HOME || "";
69
406
  const configPath = path.join(homeDir, ".claude.json");
70
- const projectPath = process.cwd();
407
+ const workspacePath = process.cwd();
71
408
  if (!fs.existsSync(configPath)) {
72
409
  console.log(" Skipping Claude Code CLI (no ~/.claude.json found)");
73
410
  return;
@@ -75,48 +412,43 @@ export async function setupClaudeCodeCli(session) {
75
412
  try {
76
413
  const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
77
414
  config.projects ??= {};
78
- config.projects[projectPath] ??= {};
79
- config.projects[projectPath].mcpServers ??= {};
80
- config.projects[projectPath].mcpServers[SERVER_NAME] = {
81
- type: "stdio",
82
- command: "zivis",
83
- args: ["mcp", "serve"],
84
- env: session ? { ZIVIS_SESSION: session } : {},
85
- };
415
+ config.projects[workspacePath] ??= {};
416
+ config.projects[workspacePath].mcpServers ??= {};
417
+ config.projects[workspacePath].mcpServers[getServerName(pkg)] = buildServerConfig(pkg, workspacePath, { type: "stdio" });
86
418
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
87
419
  console.log("✓ Claude Code CLI MCP config updated: ~/.claude.json");
88
- if (session)
89
- console.log(` Session: ${session}`);
420
+ console.log(` Workspace: ${workspacePath}`);
90
421
  console.log(" Restart Claude Code for changes to take effect");
91
422
  }
92
423
  catch (err) {
93
424
  console.log(` WARNING: Failed to update ~/.claude.json: ${err instanceof Error ? err.message : err}`);
94
425
  }
95
426
  }
96
- export async function setupCline(session) {
427
+ export async function setupCline(pkg = "appsec") {
428
+ const workspacePath = process.cwd();
97
429
  const homeDir = process.env.HOME || "";
98
430
  const configPath = process.platform === "darwin"
99
431
  ? path.join(homeDir, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json")
100
432
  : path.join(homeDir, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
101
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session), "mcpServers");
433
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
102
434
  console.log(`✓ Cline MCP config updated: ${configPath}`);
103
- if (session)
104
- console.log(` Session: ${session}`);
435
+ console.log(` Workspace: ${workspacePath}`);
105
436
  console.log(" Restart VS Code for changes to take effect");
106
437
  }
107
- export async function setupWindsurf(session) {
438
+ export async function setupWindsurf(pkg = "appsec") {
439
+ const workspacePath = process.cwd();
108
440
  const homeDir = process.env.HOME || "";
109
441
  const configPath = path.join(homeDir, ".codeium", "windsurf", "mcp_config.json");
110
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session), "mcpServers");
442
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
111
443
  console.log(`✓ Windsurf MCP config updated: ${configPath}`);
112
- if (session)
113
- console.log(` Session: ${session}`);
444
+ console.log(` Workspace: ${workspacePath}`);
114
445
  console.log(" Restart Windsurf for changes to take effect");
115
446
  }
116
- export function printClaudeCodeManual(session) {
447
+ export function printClaudeCodeManual(pkg = "appsec") {
448
+ const workspacePath = process.cwd();
117
449
  const serverConfig = {
118
450
  mcpServers: {
119
- [SERVER_NAME]: buildServerConfig(session),
451
+ [getServerName(pkg)]: buildServerConfig(pkg, workspacePath),
120
452
  },
121
453
  };
122
454
  console.log("");
@@ -128,4 +460,3 @@ export function printClaudeCodeManual(session) {
128
460
  console.log("");
129
461
  console.log("Then restart Claude Code for changes to take effect");
130
462
  }
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>;