@zivis/cli 0.1.0-alpha.33 → 0.1.0-alpha.35

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 (133) 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 +0 -12
  5. package/dist/commands/auth/bind.d.ts +0 -10
  6. package/dist/commands/auth/bind.js +0 -11
  7. package/dist/commands/auth/index.js +0 -1
  8. package/dist/commands/auth/init.js +12 -13
  9. package/dist/commands/auth/login.d.ts +0 -1
  10. package/dist/commands/auth/login.js +8 -3
  11. package/dist/commands/auth/logout.js +0 -3
  12. package/dist/commands/auth/sessions.js +0 -1
  13. package/dist/commands/auth/status.js +0 -2
  14. package/dist/commands/auth/token.d.ts +0 -13
  15. package/dist/commands/auth/token.js +0 -18
  16. package/dist/commands/check/index.d.ts +2 -0
  17. package/dist/commands/check/index.js +463 -0
  18. package/dist/commands/credits/index.js +0 -1
  19. package/dist/commands/inspect/index.d.ts +0 -15
  20. package/dist/commands/inspect/index.js +0 -23
  21. package/dist/commands/mcp/index.js +0 -9
  22. package/dist/commands/open/index.d.ts +0 -8
  23. package/dist/commands/open/index.js +0 -11
  24. package/dist/commands/scan/index.js +0 -6
  25. package/dist/commands/target/index.js +0 -3
  26. package/dist/commands/tm/index.js +0 -7
  27. package/dist/index.js +11 -1
  28. package/dist/internal/binding-token-mint.d.ts +0 -29
  29. package/dist/internal/binding-token-mint.js +0 -28
  30. package/dist/internal/extractor/adapters/go/index.d.ts +0 -4
  31. package/dist/internal/extractor/adapters/go/index.js +0 -6
  32. package/dist/internal/extractor/adapters/go/manifest.d.ts +0 -17
  33. package/dist/internal/extractor/adapters/go/manifest.js +1 -25
  34. package/dist/internal/extractor/adapters/go/parser.d.ts +0 -4
  35. package/dist/internal/extractor/adapters/go/parser.js +0 -5
  36. package/dist/internal/extractor/adapters/go/scanner.d.ts +0 -20
  37. package/dist/internal/extractor/adapters/go/scanner.js +0 -43
  38. package/dist/internal/extractor/adapters/python/index.d.ts +0 -3
  39. package/dist/internal/extractor/adapters/python/index.js +0 -4
  40. package/dist/internal/extractor/adapters/python/manifest.d.ts +0 -8
  41. package/dist/internal/extractor/adapters/python/manifest.js +3 -18
  42. package/dist/internal/extractor/adapters/python/parser.d.ts +0 -3
  43. package/dist/internal/extractor/adapters/python/parser.js +0 -4
  44. package/dist/internal/extractor/adapters/python/scanner.d.ts +0 -18
  45. package/dist/internal/extractor/adapters/python/scanner.js +1 -54
  46. package/dist/internal/extractor/adapters/typescript/index.d.ts +0 -7
  47. package/dist/internal/extractor/adapters/typescript/index.js +1 -21
  48. package/dist/internal/extractor/adapters/typescript/manifest.d.ts +0 -14
  49. package/dist/internal/extractor/adapters/typescript/manifest.js +1 -20
  50. package/dist/internal/extractor/adapters/typescript/parser.d.ts +0 -8
  51. package/dist/internal/extractor/adapters/typescript/parser.js +0 -9
  52. package/dist/internal/extractor/adapters/typescript/scanner.d.ts +0 -24
  53. package/dist/internal/extractor/adapters/typescript/scanner.js +0 -43
  54. package/dist/internal/extractor/graph-builder.d.ts +0 -25
  55. package/dist/internal/extractor/graph-builder.js +1 -39
  56. package/dist/internal/extractor/graph-types.d.ts +0 -10
  57. package/dist/internal/extractor/graph-types.js +0 -11
  58. package/dist/internal/extractor/index.d.ts +0 -14
  59. package/dist/internal/extractor/index.js +0 -13
  60. package/dist/internal/extractor/types.d.ts +0 -45
  61. package/dist/internal/extractor/types.js +0 -27
  62. package/dist/internal/extractor/walker.d.ts +0 -18
  63. package/dist/internal/extractor/walker.js +0 -18
  64. package/dist/internal/github-linkage-prompt.d.ts +7 -0
  65. package/dist/internal/github-linkage-prompt.js +95 -0
  66. package/dist/internal/ide-setup.d.ts +0 -23
  67. package/dist/internal/ide-setup.js +0 -53
  68. package/dist/internal/orgs.js +0 -1
  69. package/dist/internal/project-binding.d.ts +0 -1
  70. package/dist/internal/project-binding.js +0 -5
  71. package/dist/internal/target-auth/api-config.d.ts +0 -17
  72. package/dist/internal/target-auth/api-config.js +0 -18
  73. package/dist/internal/target-auth/config.d.ts +0 -12
  74. package/dist/internal/target-auth/config.js +0 -13
  75. package/dist/internal/target-auth/index.d.ts +0 -18
  76. package/dist/internal/target-auth/index.js +0 -19
  77. package/dist/internal/target-auth/keychain.d.ts +0 -18
  78. package/dist/internal/target-auth/keychain.js +3 -23
  79. package/dist/internal/target-auth/types.d.ts +0 -26
  80. package/dist/internal/target-auth/types.js +0 -10
  81. package/dist/internal/target-auth/workos.d.ts +0 -15
  82. package/dist/internal/target-auth/workos.js +0 -17
  83. package/package.json +13 -4
  84. package/dist/commands/app/index.js.map +0 -1
  85. package/dist/commands/auth/bind.js.map +0 -1
  86. package/dist/commands/auth/index.js.map +0 -1
  87. package/dist/commands/auth/init.js.map +0 -1
  88. package/dist/commands/auth/login.js.map +0 -1
  89. package/dist/commands/auth/logout.js.map +0 -1
  90. package/dist/commands/auth/sessions.js.map +0 -1
  91. package/dist/commands/auth/status.js.map +0 -1
  92. package/dist/commands/auth/token.js.map +0 -1
  93. package/dist/commands/credits/index.js.map +0 -1
  94. package/dist/commands/inspect/index.js.map +0 -1
  95. package/dist/commands/mcp/index.js.map +0 -1
  96. package/dist/commands/open/index.js.map +0 -1
  97. package/dist/commands/scan/index.js.map +0 -1
  98. package/dist/commands/target/index.js.map +0 -1
  99. package/dist/commands/tm/index.js.map +0 -1
  100. package/dist/index.js.map +0 -1
  101. package/dist/internal/binding-token-mint.js.map +0 -1
  102. package/dist/internal/extractor/adapters/go/index.js.map +0 -1
  103. package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
  104. package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
  105. package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
  106. package/dist/internal/extractor/adapters/python/index.js.map +0 -1
  107. package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
  108. package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
  109. package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
  110. package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
  111. package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
  112. package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
  113. package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
  114. package/dist/internal/extractor/graph-builder.js.map +0 -1
  115. package/dist/internal/extractor/graph-types.js.map +0 -1
  116. package/dist/internal/extractor/index.js.map +0 -1
  117. package/dist/internal/extractor/types.js.map +0 -1
  118. package/dist/internal/extractor/walker.js.map +0 -1
  119. package/dist/internal/ide-setup.js.map +0 -1
  120. package/dist/internal/orgs.js.map +0 -1
  121. package/dist/internal/pattern-pack/index.d.ts +0 -123
  122. package/dist/internal/pattern-pack/index.js +0 -230
  123. package/dist/internal/pattern-pack/index.js.map +0 -1
  124. package/dist/internal/project-binding.js.map +0 -1
  125. package/dist/internal/target-auth/api-config.js.map +0 -1
  126. package/dist/internal/target-auth/config.js.map +0 -1
  127. package/dist/internal/target-auth/index.js.map +0 -1
  128. package/dist/internal/target-auth/keychain.js.map +0 -1
  129. package/dist/internal/target-auth/types.js.map +0 -1
  130. package/dist/internal/target-auth/workos.js.map +0 -1
  131. package/dist/pattern-packs/zivis-public-0.1.0/capsules/agents/privilege-separation.yaml +0 -228
  132. package/dist/pattern-packs/zivis-public-0.1.0/manifest.json +0 -31
  133. package/dist/pattern-packs/zivis-public-0.1.0/prompts/agents/privilege-separation/identify.md +0 -54
@@ -1,14 +1,3 @@
1
- /**
2
- * Extractor orchestrator.
3
- *
4
- * Walks the customer's repo, dispatches matched files to per-language
5
- * adapters, merges their findings into a single ExtractionResult.
6
- *
7
- * Adapters register their own file extensions + manifest filenames; the
8
- * walker only reads files those filters claim. So adding a Go or Python
9
- * adapter doesn't change anything here — register the adapter and the
10
- * orchestrator picks up its files.
11
- */
12
1
  import * as path from "node:path";
13
2
  import { walk } from "./walker.js";
14
3
  import { typescriptAdapter } from "./adapters/typescript/index.js";
@@ -25,7 +14,6 @@ export async function runExtractor(opts) {
25
14
  const adapters = opts.languages
26
15
  ? ADAPTERS.filter((a) => opts.languages.includes(a.language))
27
16
  : ADAPTERS;
28
- // Aggregate the file filters from each adapter so we walk the tree once.
29
17
  const extensions = new Set();
30
18
  const manifests = new Set();
31
19
  for (const a of adapters) {
@@ -104,4 +92,3 @@ function dedupeExternalServices(items) {
104
92
  }
105
93
  return [...out.values()];
106
94
  }
107
- //# sourceMappingURL=index.js.map
@@ -1,29 +1,3 @@
1
- /**
2
- * Extractor output schema.
3
- *
4
- * Matches `THREAT-MODEL-PHASE-J.md`'s J.2 output shape, with additions
5
- * for privacy-audit metadata. The shape is the contract between the CLI
6
- * and the eventual `--apply` endpoint that maps into ThreatModelComponent
7
- * / OrgComponent records (RECON.3-gated).
8
- *
9
- * Privacy invariant — what's IN the JSON:
10
- * component names ("auth-service")
11
- * file paths ("src/auth/login.ts")
12
- * line numbers (42)
13
- * framework + SDK identifiers ("express", "@anthropic-ai/sdk")
14
- * detected protocols / methods (POST /login)
15
- * dependency versions (from package.json / go.mod / pyproject.toml)
16
- *
17
- * What's NOT:
18
- * function bodies, file contents, code snippets
19
- * variable names from inside functions
20
- * comments
21
- * raw AST nodes
22
- *
23
- * `zivis tm extract --privacy-audit` prints this whole object to stdout
24
- * before any network call, so the customer can see exactly what would
25
- * be sent.
26
- */
27
1
  export type Language = "typescript" | "javascript" | "go" | "python";
28
2
  export interface EvidenceLocation {
29
3
  file: string;
@@ -44,21 +18,16 @@ export interface ConfigEvidence extends EvidenceLocation {
44
18
  export type Evidence = HttpRouteEvidence | ImportEvidence | ConfigEvidence;
45
19
  export type ComponentKind = "process" | "data_store" | "external_service" | "frontend";
46
20
  export interface ExtractedComponent {
47
- /** Stable name derived from path / module — never a value from inside a function. */
48
21
  name: string;
49
22
  kind: ComponentKind;
50
23
  language: Language;
51
- /** Detected web framework, if any (express | fastify | nextjs | trpc | hono | gin | echo | …). */
52
24
  framework?: string;
53
25
  sourceFiles: string[];
54
26
  evidence: Evidence[];
55
27
  }
56
28
  export interface ExtractedExternalService {
57
- /** Vendor / SDK name — "Anthropic", "OpenAI", "WorkOS". */
58
29
  name: string;
59
- /** What kind of integration: ai_sdk, payments, auth, observability, etc. */
60
30
  kind: string;
61
- /** npm/PyPI/Go module identifier ("@anthropic-ai/sdk"). */
62
31
  package: string;
63
32
  version?: string;
64
33
  callSites: EvidenceLocation[];
@@ -84,30 +53,16 @@ export interface ExtractionResult {
84
53
  components: ExtractedComponent[];
85
54
  externalServices: ExtractedExternalService[];
86
55
  dataStores: ExtractedDataStore[];
87
- /**
88
- * Per-language manifests detected in the scope. Surfaces dependency-only
89
- * findings (e.g., "this repo uses @anthropic-ai/sdk@^0.30") even when
90
- * we can't yet match call sites.
91
- */
92
56
  manifests: ManifestSummary[];
93
57
  }
94
58
  export interface ManifestSummary {
95
59
  language: Language;
96
60
  file: string;
97
- /** Direct dependency names → version (verbatim from manifest). */
98
61
  dependencies: Record<string, string>;
99
62
  }
100
- /**
101
- * Adapter contract — one per language. Each adapter is fed the list of
102
- * source files matched for it (already filtered by .gitignore + .zivisignore)
103
- * plus any manifest files (package.json, go.mod, pyproject.toml). Returns
104
- * structured findings the framework merges into the final ExtractionResult.
105
- */
106
63
  export interface LanguageAdapter {
107
64
  language: Language;
108
- /** File extensions this adapter handles. */
109
65
  extensions: string[];
110
- /** Manifest filenames this adapter cares about. */
111
66
  manifests: string[];
112
67
  extract(input: AdapterInput): Promise<AdapterOutput>;
113
68
  }
@@ -1,28 +1 @@
1
- /**
2
- * Extractor output schema.
3
- *
4
- * Matches `THREAT-MODEL-PHASE-J.md`'s J.2 output shape, with additions
5
- * for privacy-audit metadata. The shape is the contract between the CLI
6
- * and the eventual `--apply` endpoint that maps into ThreatModelComponent
7
- * / OrgComponent records (RECON.3-gated).
8
- *
9
- * Privacy invariant — what's IN the JSON:
10
- * component names ("auth-service")
11
- * file paths ("src/auth/login.ts")
12
- * line numbers (42)
13
- * framework + SDK identifiers ("express", "@anthropic-ai/sdk")
14
- * detected protocols / methods (POST /login)
15
- * dependency versions (from package.json / go.mod / pyproject.toml)
16
- *
17
- * What's NOT:
18
- * function bodies, file contents, code snippets
19
- * variable names from inside functions
20
- * comments
21
- * raw AST nodes
22
- *
23
- * `zivis tm extract --privacy-audit` prints this whole object to stdout
24
- * before any network call, so the customer can see exactly what would
25
- * be sent.
26
- */
27
1
  export {};
28
- //# sourceMappingURL=types.js.map
@@ -1,24 +1,7 @@
1
- /**
2
- * Filesystem walker — yields source files relative to the scan root,
3
- * filtered by .gitignore + .zivisignore + per-extractor extension filters.
4
- *
5
- * Uses the `ignore` npm package (the same engine git ships with) so the
6
- * matching semantics mirror what developers expect from .gitignore.
7
- *
8
- * Hard limits:
9
- * - Skips node_modules, dist, build, .next, .git, .yarn, vendor — even
10
- * if not in .gitignore. These exist by convention and contain
11
- * third-party code that pollutes the inventory.
12
- * - Caps total files at 50_000 to refuse to scan a generated monorepo
13
- * by accident (extractor would take forever; user should narrow scope).
14
- */
15
1
  export interface WalkOptions {
16
2
  rootDir: string;
17
- /** Extensions to include (with the leading dot, e.g. [".ts", ".tsx"]). */
18
3
  extensions: string[];
19
- /** Manifest basenames to capture regardless of extension (e.g. ["package.json"]). */
20
4
  manifests: string[];
21
- /** Extra ignore patterns from --ignore CLI flags. */
22
5
  extraIgnores?: string[];
23
6
  }
24
7
  export interface WalkResult {
@@ -28,5 +11,4 @@ export interface WalkResult {
28
11
  filesSkipped: number;
29
12
  }
30
13
  export declare function walk(opts: WalkOptions): Promise<WalkResult>;
31
- /** Convert an absolute path to a posix-style repo-relative path. */
32
14
  export declare function repoRelative(rootDir: string, absPath: string): string;
@@ -1,17 +1,3 @@
1
- /**
2
- * Filesystem walker — yields source files relative to the scan root,
3
- * filtered by .gitignore + .zivisignore + per-extractor extension filters.
4
- *
5
- * Uses the `ignore` npm package (the same engine git ships with) so the
6
- * matching semantics mirror what developers expect from .gitignore.
7
- *
8
- * Hard limits:
9
- * - Skips node_modules, dist, build, .next, .git, .yarn, vendor — even
10
- * if not in .gitignore. These exist by convention and contain
11
- * third-party code that pollutes the inventory.
12
- * - Caps total files at 50_000 to refuse to scan a generated monorepo
13
- * by accident (extractor would take forever; user should narrow scope).
14
- */
15
1
  import * as fs from "node:fs/promises";
16
2
  import * as path from "node:path";
17
3
  import ignore from "ignore";
@@ -64,7 +50,6 @@ export async function walk(opts) {
64
50
  filesSkipped++;
65
51
  continue;
66
52
  }
67
- // ignore() expects gitignore-style paths with trailing /
68
53
  if (ig.ignores(childRel + "/")) {
69
54
  filesSkipped++;
70
55
  continue;
@@ -99,12 +84,9 @@ async function loadIgnoreFile(ig, filePath) {
99
84
  ig.add(content);
100
85
  }
101
86
  catch {
102
- // No ignore file — fine.
103
87
  }
104
88
  }
105
- /** Convert an absolute path to a posix-style repo-relative path. */
106
89
  export function repoRelative(rootDir, absPath) {
107
90
  const rel = path.relative(rootDir, absPath);
108
91
  return rel.split(path.sep).join("/");
109
92
  }
110
- //# sourceMappingURL=walker.js.map
@@ -0,0 +1,7 @@
1
+ import type { ZivisConfig } from "@zivis/mcp/types";
2
+ export interface BuildLinkagePromptOpts {
3
+ config: ZivisConfig;
4
+ applicationId?: string;
5
+ style?: "short" | "full";
6
+ }
7
+ export declare function buildLinkagePrompt(opts: BuildLinkagePromptOpts): Promise<string | null>;
@@ -0,0 +1,95 @@
1
+ import { resolveAuth } from "@zivis/mcp/auth";
2
+ export async function buildLinkagePrompt(opts) {
3
+ const creds = await resolveAuth(opts.config);
4
+ if (creds.method === "none")
5
+ return null;
6
+ const appStatus = await fetchGitHubAppStatus(opts.config, creds);
7
+ if (!appStatus)
8
+ return null;
9
+ if (!appStatus.installed) {
10
+ if (!appStatus.installUrl)
11
+ return null;
12
+ return formatInstallPrompt(appStatus.installUrl, opts.style ?? "full");
13
+ }
14
+ if (opts.applicationId) {
15
+ const repoStatus = await fetchAppRepoStatus(opts.config, creds, opts.applicationId);
16
+ if (repoStatus && !repoStatus.linked) {
17
+ return formatLinkRepoPrompt(opts.config, opts.applicationId, opts.style ?? "full");
18
+ }
19
+ }
20
+ return null;
21
+ }
22
+ async function fetchGitHubAppStatus(config, creds) {
23
+ try {
24
+ const res = await fetch(`${config.apiBaseUrl}/api/github-app/status`, {
25
+ headers: authHeaders(creds),
26
+ });
27
+ if (!res.ok)
28
+ return null;
29
+ return (await res.json());
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ async function fetchAppRepoStatus(config, creds, applicationId) {
36
+ try {
37
+ const res = await fetch(`${config.apiBaseUrl}/api/applications/${encodeURIComponent(applicationId)}/repos/status`, { headers: authHeaders(creds) });
38
+ if (!res.ok)
39
+ return null;
40
+ return (await res.json());
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ function authHeaders(creds) {
47
+ const base = {
48
+ "Content-Type": "application/json",
49
+ "User-Agent": "@zivis/cli",
50
+ };
51
+ if (creds.method === "oauth" && creds.accessToken) {
52
+ base.Authorization = `Bearer ${creds.accessToken}`;
53
+ }
54
+ else if (creds.method === "apikey" && creds.apiKey) {
55
+ base["X-API-Key"] = creds.apiKey;
56
+ }
57
+ return base;
58
+ }
59
+ function formatInstallPrompt(installUrl, style) {
60
+ if (style === "short") {
61
+ return `Next: install the ZIVIS GitHub App — ${installUrl}`;
62
+ }
63
+ return [
64
+ "",
65
+ "Next: install the ZIVIS GitHub App",
66
+ ` ${installUrl}`,
67
+ " Enables continuous monitoring + automatic threat-model updates on push.",
68
+ ].join("\n");
69
+ }
70
+ function formatLinkRepoPrompt(config, applicationId, style) {
71
+ const appBase = process.env.ZIVIS_APP_URL || guessAppUrlFromApi(config.apiBaseUrl);
72
+ const url = `${appBase}/applications/${applicationId}`;
73
+ if (style === "short") {
74
+ return `Next: link a GitHub repo to this application — ${url}`;
75
+ }
76
+ return [
77
+ "",
78
+ "Next: link a GitHub repo to this application",
79
+ ` ${url}`,
80
+ " The GitHub App is installed but this app has no linked repo yet.",
81
+ ].join("\n");
82
+ }
83
+ function guessAppUrlFromApi(apiBaseUrl) {
84
+ try {
85
+ const u = new URL(apiBaseUrl);
86
+ if (u.host.startsWith("api.")) {
87
+ u.host = "app." + u.host.slice(4);
88
+ return `${u.protocol}//${u.host}`;
89
+ }
90
+ return apiBaseUrl;
91
+ }
92
+ catch {
93
+ return "https://app.zivis.ai";
94
+ }
95
+ }
@@ -1,34 +1,11 @@
1
1
  export type GuidanceClient = "cursor" | "claude-code-cli" | "vscode-copilot" | "vscode-claude" | "cline" | "windsurf";
2
2
  export interface GuidanceOptions {
3
- /** Workspace root to write guidance files into */
4
3
  cwd: string;
5
- /** Which IDE client to write guidance for */
6
4
  client: GuidanceClient;
7
5
  }
8
- /**
9
- * Write IDE guidance files for the given client.
10
- *
11
- * The guidance files teach the host AI (Cursor, Claude Code, etc.)
12
- * when to suggest ZIVIS tools — no security knowledge required from the user.
13
- *
14
- * All writes are idempotent: re-running replaces only the ZIVIS-managed
15
- * block, never user content.
16
- *
17
- * Returns the list of file paths written.
18
- */
19
6
  export declare function writeGuidance(opts: GuidanceOptions): string[];
20
- /**
21
- * Detect which IDE configs are present in the given workspace.
22
- * Returns client identifiers whose config files/dirs were found.
23
- */
24
7
  export declare function detectIdesInRepo(cwd: string): GuidanceClient[];
25
8
  export declare function setupCursor(): Promise<void>;
26
- /**
27
- * Write a workspace-level .cursor/mcp.json with `--workspace <cwd>` so Cursor
28
- * starts an isolated MCP process bound to this specific repo.
29
- * One process = one org = zero cross-tenant risk, regardless of what other
30
- * repos are open in Cursor.
31
- */
32
9
  export declare function setupCursorWorkspace(): Promise<void>;
33
10
  export declare function setupVsCodeCopilot(): Promise<void>;
34
11
  export declare function setupVsCodeClaude(): Promise<void>;
@@ -1,12 +1,6 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  const SERVER_NAME = "zivis";
4
- // ── Idempotent block append ──
5
- /**
6
- * Append (or replace) a ZIVIS-managed block inside a text file.
7
- * The block is wrapped in <!-- BEGIN ZIVIS:key --> / <!-- END ZIVIS:key -->
8
- * markers so future calls replace only this section without touching user content.
9
- */
10
4
  function appendBlock(filePath, blockKey, content) {
11
5
  const begin = `<!-- BEGIN ZIVIS:${blockKey} -->`;
12
6
  const end = `<!-- END ZIVIS:${blockKey} -->`;
@@ -31,8 +25,6 @@ function appendBlock(filePath, blockKey, content) {
31
25
  function escapeRegex(s) {
32
26
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
33
27
  }
34
- // ── Content templates ──
35
- /** Full Cursor .mdc rule — uses globs so it only attaches when relevant files are open */
36
28
  function cursorRuleContent() {
37
29
  return `---
38
30
  description: ZIVIS security guidance — quietly suggest security checks at the right moments
@@ -117,7 +109,6 @@ might break in", "security plan", "categories of attacks".
117
109
 
118
110
  <!-- END ZIVIS:guidance -->`;
119
111
  }
120
- /** Short block for CLAUDE.md / AGENTS.md — must be concise (read every turn) */
121
112
  function claudeBlockContent() {
122
113
  return `## ZIVIS Security (MCP)
123
114
 
@@ -135,7 +126,6 @@ ZIVIS is connected to this project. Use its tools sparingly — only for securit
135
126
 
136
127
  **Slash commands:** /zivis-getting-started /zivis-secure-my-app /zivis-audit-dependencies /zivis-prep-for-launch`;
137
128
  }
138
- /** .clinerules / .windsurfrules content */
139
129
  function ruleFileContent() {
140
130
  return `# ZIVIS Security Guidance
141
131
 
@@ -168,7 +158,6 @@ Say "security plan" not "threat model".
168
158
  /zivis-prep-for-launch — pre-launch checklist
169
159
  /zivis-weekly-check — weekly status update`;
170
160
  }
171
- /** GitHub Copilot instructions block */
172
161
  function copilotBlockContent() {
173
162
  return `## ZIVIS Security Integration
174
163
 
@@ -186,7 +175,6 @@ Use ZIVIS only for security-related user requests. Never proactively run scans o
186
175
 
187
176
  **Language:** Avoid security jargon (threat model, STRIDE, attack vector) unless user uses it first.`;
188
177
  }
189
- // ── Per-IDE writers ──
190
178
  function writeCursorGuidance(cwd) {
191
179
  const rulesDir = path.join(cwd, ".cursor", "rules");
192
180
  if (!fs.existsSync(rulesDir))
@@ -225,24 +213,12 @@ function writeWindsurfGuidance(cwd) {
225
213
  fs.writeFileSync(rulesPath, ruleFileContent());
226
214
  return rulesPath;
227
215
  }
228
- /**
229
- * Write IDE guidance files for the given client.
230
- *
231
- * The guidance files teach the host AI (Cursor, Claude Code, etc.)
232
- * when to suggest ZIVIS tools — no security knowledge required from the user.
233
- *
234
- * All writes are idempotent: re-running replaces only the ZIVIS-managed
235
- * block, never user content.
236
- *
237
- * Returns the list of file paths written.
238
- */
239
216
  export function writeGuidance(opts) {
240
217
  const { cwd, client } = opts;
241
218
  const written = [];
242
219
  switch (client) {
243
220
  case "cursor": {
244
221
  written.push(writeCursorGuidance(cwd));
245
- // Also write CLAUDE.md/AGENTS.md block if those files exist
246
222
  const extraPaths = writeClaudeBlockGuidance(cwd).filter((p) => fs.existsSync(p));
247
223
  written.push(...extraPaths);
248
224
  break;
@@ -267,46 +243,25 @@ export function writeGuidance(opts) {
267
243
  }
268
244
  return written.filter(Boolean);
269
245
  }
270
- /**
271
- * Detect which IDE configs are present in the given workspace.
272
- * Returns client identifiers whose config files/dirs were found.
273
- */
274
246
  export function detectIdesInRepo(cwd) {
275
247
  const found = [];
276
- // Cursor
277
248
  if (fs.existsSync(path.join(cwd, ".cursor"))) {
278
249
  found.push("cursor");
279
250
  }
280
- // Claude Code (CLAUDE.md)
281
251
  if (fs.existsSync(path.join(cwd, "CLAUDE.md"))) {
282
252
  found.push("claude-code-cli");
283
253
  }
284
- // VS Code (check for .vscode directory)
285
254
  if (fs.existsSync(path.join(cwd, ".vscode"))) {
286
- // Assume Copilot by default for VS Code
287
255
  found.push("vscode-copilot");
288
256
  }
289
- // Cline (.clinerules)
290
257
  if (fs.existsSync(path.join(cwd, ".clinerules"))) {
291
258
  found.push("cline");
292
259
  }
293
- // Windsurf (.windsurfrules)
294
260
  if (fs.existsSync(path.join(cwd, ".windsurfrules"))) {
295
261
  found.push("windsurf");
296
262
  }
297
263
  return found;
298
264
  }
299
- /**
300
- * Build the MCP server config for an IDE config file.
301
- *
302
- * When workspacePath is provided, we pass it as `--workspace <path>` so the
303
- * MCP server process resolves its session from `.zivis/project.json` at that
304
- * path — not from an env var that can drift or be accidentally reused across
305
- * tenants. This gives us one-process-per-org isolation at the IDE level.
306
- *
307
- * ZIVIS_SESSION is intentionally NOT used here. The workspace path is the
308
- * canonical, immutable tenant binding for an MCP process.
309
- */
310
265
  function buildServerConfig(workspacePath, extra) {
311
266
  const args = ["mcp", "serve"];
312
267
  if (workspacePath) {
@@ -342,17 +297,10 @@ async function updateMcpConfig(configPath, serverName, serverConfig, rootKey) {
342
297
  export async function setupCursor() {
343
298
  const homeDir = process.env.HOME || "";
344
299
  const configPath = path.join(homeDir, ".cursor", "mcp.json");
345
- // Global config has no workspace path — serves repos without .zivis/project.json
346
300
  await updateMcpConfig(configPath, SERVER_NAME, buildServerConfig(), "mcpServers");
347
301
  console.log(`✓ Cursor global MCP config updated: ${configPath}`);
348
302
  console.log(" Restart Cursor for changes to take effect");
349
303
  }
350
- /**
351
- * Write a workspace-level .cursor/mcp.json with `--workspace <cwd>` so Cursor
352
- * starts an isolated MCP process bound to this specific repo.
353
- * One process = one org = zero cross-tenant risk, regardless of what other
354
- * repos are open in Cursor.
355
- */
356
304
  export async function setupCursorWorkspace() {
357
305
  const workspacePath = process.cwd();
358
306
  const configPath = path.join(workspacePath, ".cursor", "mcp.json");
@@ -446,4 +394,3 @@ export function printClaudeCodeManual() {
446
394
  console.log("");
447
395
  console.log("Then restart Claude Code for changes to take effect");
448
396
  }
449
- //# sourceMappingURL=ide-setup.js.map
@@ -28,4 +28,3 @@ export function extractEmail(idToken) {
28
28
  return "unknown";
29
29
  }
30
30
  }
31
- //# sourceMappingURL=orgs.js.map
@@ -7,7 +7,6 @@ export interface EnsureBindingOpts {
7
7
  cwd: string;
8
8
  autoBind: boolean;
9
9
  skipBind: boolean;
10
- /** Overwrite an existing conflicting binding without erroring (used by `zivis auth init`). */
11
10
  force?: boolean;
12
11
  }
13
12
  export declare function ensureProjectBinding(opts: EnsureBindingOpts): Promise<void>;
@@ -28,8 +28,6 @@ export async function ensureProjectBinding(opts) {
28
28
  console.error("[zivis] This should not happen — investigate before proceeding.");
29
29
  process.exit(1);
30
30
  }
31
- // force=true: init is intentionally replacing the binding.
32
- // Clear detected so we don't accidentally inherit the OLD binding's name/id.
33
31
  const oldLabel = detected.binding.orgName ?? detected.binding.workosOrgId;
34
32
  console.log(` Replacing existing binding (was: ${oldLabel})`);
35
33
  fs.unlinkSync(detected.filePath);
@@ -43,8 +41,6 @@ export async function ensureProjectBinding(opts) {
43
41
  catch (err) {
44
42
  console.log(` WARNING: Could not fetch org info: ${err instanceof Error ? err.message : err}`);
45
43
  }
46
- // Only fall back to detected?.binding.orgName when we are UPGRADING the same org
47
- // (detected still set), not when force-replacing a different org (detected=null).
48
44
  const orgName = orgInfo?.name || detected?.binding.orgName;
49
45
  const zivisOrgId = orgInfo?.id || detected?.binding.orgId;
50
46
  const orgLabel = orgName ? `${orgName} (${jwtOrgId})` : jwtOrgId;
@@ -103,4 +99,3 @@ export async function ensureProjectBinding(opts) {
103
99
  console.log(` File: ${bindingPath}`);
104
100
  console.log(" Commit this file so future sessions in this repo are org-locked.");
105
101
  }
106
- //# sourceMappingURL=project-binding.js.map
@@ -1,14 +1,3 @@
1
- /**
2
- * Fetches an Application's auth config from the ZIVIS platform.
3
- *
4
- * Phase J.4: replaces the local `~/.config/zivis/target-configs/*.json`
5
- * file the user previously had to write by hand. The Application's IdP
6
- * discovery (clientId, domain, mode, scopes) lives on the Application
7
- * record on the platform; the CLI calls this endpoint to learn how to
8
- * PKCE-auth, then runs the flow locally and stores tokens in the user's
9
- * keychain. Tokens never leave the user's machine unless the user
10
- * explicitly ships them with a scenario-run trigger.
11
- */
12
1
  import type { TargetAuthConfig, WorkosMode } from "./types.js";
13
2
  interface AuthConfigResponse {
14
3
  applicationId: string;
@@ -27,11 +16,5 @@ interface AuthConfigResponse {
27
16
  error?: string;
28
17
  }
29
18
  export declare function fetchAuthConfig(applicationId: string, sessionName?: string): Promise<AuthConfigResponse>;
30
- /**
31
- * Adapt the platform's auth-config response into the local TargetAuthConfig
32
- * shape that the existing PKCE flow consumes. Throws when the application
33
- * isn't OAuth-PKCE-shaped (e.g., static_token, client_credentials) — the
34
- * caller should give a useful error and direct the user elsewhere.
35
- */
36
19
  export declare function adaptToWorkosConfig(resp: AuthConfigResponse): TargetAuthConfig;
37
20
  export {};
@@ -1,14 +1,3 @@
1
- /**
2
- * Fetches an Application's auth config from the ZIVIS platform.
3
- *
4
- * Phase J.4: replaces the local `~/.config/zivis/target-configs/*.json`
5
- * file the user previously had to write by hand. The Application's IdP
6
- * discovery (clientId, domain, mode, scopes) lives on the Application
7
- * record on the platform; the CLI calls this endpoint to learn how to
8
- * PKCE-auth, then runs the flow locally and stores tokens in the user's
9
- * keychain. Tokens never leave the user's machine unless the user
10
- * explicitly ships them with a scenario-run trigger.
11
- */
12
1
  import { ApiClient } from "@zivis/mcp/api-client";
13
2
  import { DEFAULT_CONFIG } from "@zivis/mcp/types";
14
3
  export async function fetchAuthConfig(applicationId, sessionName) {
@@ -18,12 +7,6 @@ export async function fetchAuthConfig(applicationId, sessionName) {
18
7
  const client = new ApiClient(config);
19
8
  return client.request("GET", `/api/applications/${encodeURIComponent(applicationId)}/auth-config`);
20
9
  }
21
- /**
22
- * Adapt the platform's auth-config response into the local TargetAuthConfig
23
- * shape that the existing PKCE flow consumes. Throws when the application
24
- * isn't OAuth-PKCE-shaped (e.g., static_token, client_credentials) — the
25
- * caller should give a useful error and direct the user elsewhere.
26
- */
27
10
  export function adaptToWorkosConfig(resp) {
28
11
  if (!resp.oauth) {
29
12
  throw new Error(resp.hint || resp.error ||
@@ -37,4 +20,3 @@ export function adaptToWorkosConfig(resp) {
37
20
  extraScopes: resp.oauth.scopes,
38
21
  };
39
22
  }
40
- //# sourceMappingURL=api-config.js.map
@@ -1,15 +1,3 @@
1
- /**
2
- * Target-auth config storage (local-only, v1).
3
- *
4
- * Per-target IdP config (domain, client_id, mode, callback port) lives under
5
- * `~/.config/zivis/target-configs/<targetId>.json`. This is *config*, not
6
- * credentials — safe to commit a sanitized version to your repo if you want
7
- * teammates to share it.
8
- *
9
- * v2: ZIVIS will serve target-auth config from the API so any team member's
10
- * CLI can discover it. For now, configure once locally with `zivis target
11
- * configure` and check in the file if you want it shared.
12
- */
13
1
  import type { TargetAuthConfig } from "./types.js";
14
2
  export declare function loadTargetConfig(targetId: string): Promise<TargetAuthConfig | null>;
15
3
  export declare function saveTargetConfig(targetId: string, cfg: TargetAuthConfig): Promise<string>;
@@ -1,15 +1,3 @@
1
- /**
2
- * Target-auth config storage (local-only, v1).
3
- *
4
- * Per-target IdP config (domain, client_id, mode, callback port) lives under
5
- * `~/.config/zivis/target-configs/<targetId>.json`. This is *config*, not
6
- * credentials — safe to commit a sanitized version to your repo if you want
7
- * teammates to share it.
8
- *
9
- * v2: ZIVIS will serve target-auth config from the API so any team member's
10
- * CLI can discover it. For now, configure once locally with `zivis target
11
- * configure` and check in the file if you want it shared.
12
- */
13
1
  import * as fs from "node:fs/promises";
14
2
  import * as path from "node:path";
15
3
  import * as os from "node:os";
@@ -55,4 +43,3 @@ export async function listTargetConfigs() {
55
43
  export function getConfigPath(targetId) {
56
44
  return configPath(targetId);
57
45
  }
58
- //# sourceMappingURL=config.js.map
@@ -1,23 +1,5 @@
1
- /**
2
- * Target-auth orchestrator: load config, run the right IdP flow, manage tokens.
3
- *
4
- * Public API:
5
- * getValidTargetToken(targetId, persona) — returns access_token; refreshes if near expiry
6
- * loginTarget(targetId, persona) — runs the appropriate IdP flow
7
- * logoutTarget(targetId, persona) — clears stored tokens
8
- *
9
- * Designed so RT-runner-side ephemeral cred plumbing only sees a flat
10
- * { accessToken, refreshToken?, expiresAt, idpType } bundle — no IdP
11
- * specifics leak past this boundary.
12
- */
13
1
  import type { EphemeralTargetCreds, TargetTokens } from "./types.js";
14
2
  export declare function loginTarget(targetId: string, persona: string): Promise<TargetTokens>;
15
- /**
16
- * J.4 path: log in against an Application by id. Auth config comes from
17
- * the platform (no local config file required). Tokens are stored under
18
- * the existing keychain namespace using applicationId as the key — same
19
- * keychain layout, no migration needed for already-stored tokens.
20
- */
21
3
  export declare function loginApplication(applicationId: string, persona: string, sessionName?: string): Promise<TargetTokens>;
22
4
  export declare function logoutTarget(targetId: string, persona: string): Promise<void>;
23
5
  export declare function getValidTargetToken(targetId: string, persona: string): Promise<TargetTokens | null>;