@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.
Files changed (197) 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 +35 -0
  6. package/dist/commands/assurance/index.js +154 -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 +248 -96
  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 +206 -0
  31. package/dist/commands/scan/index.js +3 -8
  32. package/dist/commands/share/index.d.ts +14 -0
  33. package/dist/commands/share/index.js +100 -0
  34. package/dist/commands/sync/index.d.ts +2 -0
  35. package/dist/commands/sync/index.js +193 -0
  36. package/dist/commands/target/index.js +0 -3
  37. package/dist/commands/test/index.d.ts +2 -0
  38. package/dist/commands/test/index.js +198 -0
  39. package/dist/commands/threatmodel/index.d.ts +2 -0
  40. package/dist/commands/threatmodel/index.js +167 -0
  41. package/dist/index.js +28 -3
  42. package/dist/internal/application-binding.d.ts +8 -0
  43. package/dist/internal/application-binding.js +167 -0
  44. package/dist/internal/binding-token-mint.d.ts +33 -0
  45. package/dist/internal/binding-token-mint.js +174 -0
  46. package/dist/internal/change-recommendation.d.ts +6 -0
  47. package/dist/internal/change-recommendation.js +113 -0
  48. package/dist/internal/cli-output.d.ts +16 -0
  49. package/dist/internal/cli-output.js +39 -0
  50. package/dist/internal/devx-run.d.ts +129 -0
  51. package/dist/internal/devx-run.js +39 -0
  52. package/dist/internal/extractor/adapters/go/index.d.ts +0 -4
  53. package/dist/internal/extractor/adapters/go/index.js +0 -6
  54. package/dist/internal/extractor/adapters/go/manifest.d.ts +0 -17
  55. package/dist/internal/extractor/adapters/go/manifest.js +19 -25
  56. package/dist/internal/extractor/adapters/go/parser.d.ts +0 -4
  57. package/dist/internal/extractor/adapters/go/parser.js +0 -5
  58. package/dist/internal/extractor/adapters/go/scanner.d.ts +0 -20
  59. package/dist/internal/extractor/adapters/go/scanner.js +0 -43
  60. package/dist/internal/extractor/adapters/python/index.d.ts +0 -3
  61. package/dist/internal/extractor/adapters/python/index.js +0 -4
  62. package/dist/internal/extractor/adapters/python/manifest.d.ts +0 -8
  63. package/dist/internal/extractor/adapters/python/manifest.js +21 -18
  64. package/dist/internal/extractor/adapters/python/parser.d.ts +0 -3
  65. package/dist/internal/extractor/adapters/python/parser.js +0 -4
  66. package/dist/internal/extractor/adapters/python/scanner.d.ts +0 -18
  67. package/dist/internal/extractor/adapters/python/scanner.js +1 -54
  68. package/dist/internal/extractor/adapters/typescript/index.d.ts +0 -7
  69. package/dist/internal/extractor/adapters/typescript/index.js +1 -21
  70. package/dist/internal/extractor/adapters/typescript/manifest.d.ts +0 -14
  71. package/dist/internal/extractor/adapters/typescript/manifest.js +26 -17
  72. package/dist/internal/extractor/adapters/typescript/parser.d.ts +0 -8
  73. package/dist/internal/extractor/adapters/typescript/parser.js +0 -9
  74. package/dist/internal/extractor/adapters/typescript/scanner.d.ts +0 -24
  75. package/dist/internal/extractor/adapters/typescript/scanner.js +0 -43
  76. package/dist/internal/extractor/graph-builder.d.ts +10 -0
  77. package/dist/internal/extractor/graph-builder.js +245 -0
  78. package/dist/internal/extractor/graph-types.d.ts +89 -0
  79. package/dist/internal/extractor/graph-types.js +1 -0
  80. package/dist/internal/extractor/index.d.ts +0 -14
  81. package/dist/internal/extractor/index.js +0 -13
  82. package/dist/internal/extractor/types.d.ts +0 -45
  83. package/dist/internal/extractor/types.js +0 -27
  84. package/dist/internal/extractor/walker.d.ts +0 -18
  85. package/dist/internal/extractor/walker.js +0 -18
  86. package/dist/internal/gate-evaluate.d.ts +50 -0
  87. package/dist/internal/gate-evaluate.js +111 -0
  88. package/dist/internal/gate-policy.d.ts +38 -0
  89. package/dist/internal/gate-policy.js +167 -0
  90. package/dist/internal/git-metadata.d.ts +8 -0
  91. package/dist/internal/git-metadata.js +38 -0
  92. package/dist/internal/git.d.ts +9 -0
  93. package/dist/internal/git.js +45 -0
  94. package/dist/internal/github-linkage-prompt.d.ts +7 -0
  95. package/dist/internal/github-linkage-prompt.js +95 -0
  96. package/dist/internal/ide-setup.d.ts +17 -7
  97. package/dist/internal/ide-setup.js +379 -46
  98. package/dist/internal/inventory-sync.d.ts +74 -0
  99. package/dist/internal/inventory-sync.js +189 -0
  100. package/dist/internal/org-picker.d.ts +11 -0
  101. package/dist/internal/org-picker.js +34 -0
  102. package/dist/internal/orgs.js +0 -1
  103. package/dist/internal/packs/cache.d.ts +8 -0
  104. package/dist/internal/packs/cache.js +60 -0
  105. package/dist/internal/packs/index.d.ts +10 -0
  106. package/dist/internal/packs/index.js +8 -0
  107. package/dist/internal/packs/integrity.d.ts +9 -0
  108. package/dist/internal/packs/integrity.js +24 -0
  109. package/dist/internal/packs/jcs.d.ts +2 -0
  110. package/dist/internal/packs/jcs.js +57 -0
  111. package/dist/internal/packs/local-paths.d.ts +4 -0
  112. package/dist/internal/packs/local-paths.js +26 -0
  113. package/dist/internal/packs/npm-registry-client.d.ts +14 -0
  114. package/dist/internal/packs/npm-registry-client.js +87 -0
  115. package/dist/internal/packs/registry-client.d.ts +9 -0
  116. package/dist/internal/packs/registry-client.js +25 -0
  117. package/dist/internal/packs/resolve.d.ts +8 -0
  118. package/dist/internal/packs/resolve.js +89 -0
  119. package/dist/internal/packs/semver.d.ts +9 -0
  120. package/dist/internal/packs/semver.js +57 -0
  121. package/dist/internal/packs/signing.d.ts +5 -0
  122. package/dist/internal/packs/signing.js +56 -0
  123. package/dist/internal/packs/types.d.ts +77 -0
  124. package/dist/internal/packs/types.js +20 -0
  125. package/dist/internal/project-binding.d.ts +1 -0
  126. package/dist/internal/project-binding.js +16 -11
  127. package/dist/internal/resolve-init-session.d.ts +8 -0
  128. package/dist/internal/resolve-init-session.js +36 -0
  129. package/dist/internal/run-workdir.d.ts +2 -0
  130. package/dist/internal/run-workdir.js +19 -0
  131. package/dist/internal/security-context.d.ts +63 -0
  132. package/dist/internal/security-context.js +50 -0
  133. package/dist/internal/sync-outbox.d.ts +40 -0
  134. package/dist/internal/sync-outbox.js +66 -0
  135. package/dist/internal/target-auth/api-config.d.ts +0 -17
  136. package/dist/internal/target-auth/api-config.js +0 -18
  137. package/dist/internal/target-auth/config.d.ts +0 -12
  138. package/dist/internal/target-auth/config.js +0 -13
  139. package/dist/internal/target-auth/index.d.ts +0 -18
  140. package/dist/internal/target-auth/index.js +0 -19
  141. package/dist/internal/target-auth/keychain.d.ts +0 -18
  142. package/dist/internal/target-auth/keychain.js +3 -23
  143. package/dist/internal/target-auth/types.d.ts +0 -26
  144. package/dist/internal/target-auth/types.js +0 -10
  145. package/dist/internal/target-auth/workos.d.ts +0 -15
  146. package/dist/internal/target-auth/workos.js +9 -18
  147. package/dist/internal/test-scope.d.ts +99 -0
  148. package/dist/internal/test-scope.js +101 -0
  149. package/dist/internal/threatmodel-run-state.d.ts +15 -0
  150. package/dist/internal/threatmodel-run-state.js +43 -0
  151. package/dist/internal/threatmodel-run.d.ts +85 -0
  152. package/dist/internal/threatmodel-run.js +159 -0
  153. package/dist/internal/trust-room-link.d.ts +10 -0
  154. package/dist/internal/trust-room-link.js +15 -0
  155. package/dist/internal/zivis-local-state.d.ts +1 -0
  156. package/dist/internal/zivis-local-state.js +22 -0
  157. package/package.json +21 -5
  158. package/dist/commands/app/index.js.map +0 -1
  159. package/dist/commands/auth/index.js.map +0 -1
  160. package/dist/commands/auth/init.js.map +0 -1
  161. package/dist/commands/auth/login.js.map +0 -1
  162. package/dist/commands/auth/logout.js.map +0 -1
  163. package/dist/commands/auth/sessions.js.map +0 -1
  164. package/dist/commands/auth/status.js.map +0 -1
  165. package/dist/commands/credits/index.js.map +0 -1
  166. package/dist/commands/mcp/index.js.map +0 -1
  167. package/dist/commands/open/index.js.map +0 -1
  168. package/dist/commands/scan/index.js.map +0 -1
  169. package/dist/commands/target/index.js.map +0 -1
  170. package/dist/commands/tm/index.d.ts +0 -2
  171. package/dist/commands/tm/index.js +0 -266
  172. package/dist/commands/tm/index.js.map +0 -1
  173. package/dist/index.js.map +0 -1
  174. package/dist/internal/extractor/adapters/go/index.js.map +0 -1
  175. package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
  176. package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
  177. package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
  178. package/dist/internal/extractor/adapters/python/index.js.map +0 -1
  179. package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
  180. package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
  181. package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
  182. package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
  183. package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
  184. package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
  185. package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
  186. package/dist/internal/extractor/index.js.map +0 -1
  187. package/dist/internal/extractor/types.js.map +0 -1
  188. package/dist/internal/extractor/walker.js.map +0 -1
  189. package/dist/internal/ide-setup.js.map +0 -1
  190. package/dist/internal/orgs.js.map +0 -1
  191. package/dist/internal/project-binding.js.map +0 -1
  192. package/dist/internal/target-auth/api-config.js.map +0 -1
  193. package/dist/internal/target-auth/config.js.map +0 -1
  194. package/dist/internal/target-auth/index.js.map +0 -1
  195. package/dist/internal/target-auth/keychain.js.map +0 -1
  196. package/dist/internal/target-auth/types.js.map +0 -1
  197. 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
- 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. 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: ["mcp", "serve"],
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(session) {
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, SERVER_NAME, buildServerConfig(session), "mcpServers");
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 setupVsCodeCopilot(session) {
46
- const localConfigPath = path.join(process.cwd(), ".vscode", "mcp.json");
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, SERVER_NAME, buildServerConfig(session, { type: "stdio" }), "servers");
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
- if (session)
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(session) {
60
- const configPath = path.join(process.cwd(), ".vscode", "mcp.json");
61
- await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(session), "mcpServers");
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
- if (session)
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(session) {
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 projectPath = process.cwd();
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[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
- };
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
- if (session)
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(session) {
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, SERVER_NAME, buildServerConfig(session), "mcpServers");
435
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
102
436
  console.log(`✓ Cline MCP config updated: ${configPath}`);
103
- if (session)
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(session) {
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, SERVER_NAME, buildServerConfig(session), "mcpServers");
444
+ await updateMcpConfig(configPath, getServerName(pkg), buildServerConfig(pkg, workspacePath), "mcpServers");
111
445
  console.log(`✓ Windsurf MCP config updated: ${configPath}`);
112
- if (session)
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(session) {
449
+ export function printClaudeCodeManual(pkg = "appsec") {
450
+ const workspacePath = process.cwd();
117
451
  const serverConfig = {
118
452
  mcpServers: {
119
- [SERVER_NAME]: buildServerConfig(session),
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>;