@zivis/cli 0.1.0-alpha.34 → 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 (135) 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 +0 -19
  9. package/dist/commands/auth/login.d.ts +0 -1
  10. package/dist/commands/auth/login.js +0 -6
  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 +0 -18
  17. package/dist/commands/check/index.js +1 -37
  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 +9 -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 +0 -19
  65. package/dist/internal/github-linkage-prompt.js +1 -27
  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 +22 -13
  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/check/index.js.map +0 -1
  94. package/dist/commands/credits/index.js.map +0 -1
  95. package/dist/commands/inspect/index.js.map +0 -1
  96. package/dist/commands/mcp/index.js.map +0 -1
  97. package/dist/commands/open/index.js.map +0 -1
  98. package/dist/commands/scan/index.js.map +0 -1
  99. package/dist/commands/target/index.js.map +0 -1
  100. package/dist/commands/tm/index.js.map +0 -1
  101. package/dist/index.js.map +0 -1
  102. package/dist/internal/binding-token-mint.js.map +0 -1
  103. package/dist/internal/extractor/adapters/go/index.js.map +0 -1
  104. package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
  105. package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
  106. package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
  107. package/dist/internal/extractor/adapters/python/index.js.map +0 -1
  108. package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
  109. package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
  110. package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
  111. package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
  112. package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
  113. package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
  114. package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
  115. package/dist/internal/extractor/graph-builder.js.map +0 -1
  116. package/dist/internal/extractor/graph-types.js.map +0 -1
  117. package/dist/internal/extractor/index.js.map +0 -1
  118. package/dist/internal/extractor/types.js.map +0 -1
  119. package/dist/internal/extractor/walker.js.map +0 -1
  120. package/dist/internal/github-linkage-prompt.js.map +0 -1
  121. package/dist/internal/ide-setup.js.map +0 -1
  122. package/dist/internal/orgs.js.map +0 -1
  123. package/dist/internal/pattern-pack/index.d.ts +0 -123
  124. package/dist/internal/pattern-pack/index.js +0 -230
  125. package/dist/internal/pattern-pack/index.js.map +0 -1
  126. package/dist/internal/project-binding.js.map +0 -1
  127. package/dist/internal/target-auth/api-config.js.map +0 -1
  128. package/dist/internal/target-auth/config.js.map +0 -1
  129. package/dist/internal/target-auth/index.js.map +0 -1
  130. package/dist/internal/target-auth/keychain.js.map +0 -1
  131. package/dist/internal/target-auth/types.js.map +0 -1
  132. package/dist/internal/target-auth/workos.js.map +0 -1
  133. package/dist/pattern-packs/zivis-public-0.1.0/capsules/agents/privilege-separation.yaml +0 -228
  134. package/dist/pattern-packs/zivis-public-0.1.0/manifest.json +0 -31
  135. package/dist/pattern-packs/zivis-public-0.1.0/prompts/agents/privilege-separation/identify.md +0 -54
@@ -1,32 +1,8 @@
1
- /**
2
- * Build a RepoGraphArtifactV1 from an ExtractionResult.
3
- *
4
- * The existing extractor emits an entity-list shape (components,
5
- * externalServices, dataStores, manifests). This builder is the canonical
6
- * translator from that internal intermediate into the graph artifact that
7
- * downstream pattern matching, threat modeling, and evidence storage all
8
- * consume.
9
- *
10
- * Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 1)
11
- * Schema: schemas/repo-graph-artifact.schema.json
12
- *
13
- * v1 scope (locked): three node types (service, endpoint, external_dependency)
14
- * and two edge types (exposes, depends_on). Datastores and the corresponding
15
- * reads/writes edges are deferred to Phase 1.5.
16
- *
17
- * Lane assignment for v1: every node and edge produced by deterministic
18
- * adapter output is `trusted`. Inferred-lane nodes are introduced later by
19
- * the matching engine (Phase 3), not by extraction.
20
- */
21
1
  const TRUSTED_LANE = "trusted";
22
2
  const TRUSTED_SOURCE = "inspect.trusted";
23
3
  export function buildRepoGraphArtifact(result, opts = {}) {
24
4
  const nodes = [];
25
5
  const edges = [];
26
- // Service nodes — every component that isn't an external service or pure datastore.
27
- // The existing extractor models datastores via `dataStores` and external SDKs via
28
- // `externalServices`; `components` covers code-defined services and frontends.
29
- // Skip components that arrive with empty evidence — schema requires minItems: 1.
30
6
  const serviceById = new Map();
31
7
  for (const component of result.components) {
32
8
  if (component.kind === "external_service" || component.kind === "data_store") {
@@ -38,10 +14,6 @@ export function buildRepoGraphArtifact(result, opts = {}) {
38
14
  serviceById.set(node.id, node);
39
15
  nodes.push(node);
40
16
  }
41
- // Endpoint nodes + exposes edges — derived from each service's http_route evidence.
42
- // Non-canonical methods (e.g. Express `app.use()` mounts emitted by the TS adapter)
43
- // are dropped here — they're middleware mounts, not endpoints. Fixing them belongs
44
- // upstream in the adapter; the graph-builder enforces the contract.
45
17
  for (const component of result.components) {
46
18
  const owningServiceId = serviceIdFor(component);
47
19
  if (!serviceById.has(owningServiceId))
@@ -61,9 +33,6 @@ export function buildRepoGraphArtifact(result, opts = {}) {
61
33
  edges.push(buildExposesEdge(owningServiceId, endpointNode.id, ev));
62
34
  }
63
35
  }
64
- // External dependency nodes — one per (registry, package) tuple.
65
- // Manifest-only deps (no callSites) fall back to manifest evidence so they still
66
- // satisfy the schema's evidence: minItems: 1 invariant.
67
36
  const manifestEvidenceByPackage = indexManifestsByPackage(result);
68
37
  const depById = new Map();
69
38
  for (const ext of result.externalServices) {
@@ -71,11 +40,10 @@ export function buildRepoGraphArtifact(result, opts = {}) {
71
40
  if (depById.has(node.id))
72
41
  continue;
73
42
  if (node.evidence.length === 0)
74
- continue; // truly orphaned — skip
43
+ continue;
75
44
  depById.set(node.id, node);
76
45
  nodes.push(node);
77
46
  }
78
- // File-to-service index for resolving callSites into depends_on edges.
79
47
  const fileToServiceId = buildFileToServiceIndex(result.components, serviceById);
80
48
  for (const ext of result.externalServices) {
81
49
  const depId = externalDepId(ext);
@@ -119,7 +87,6 @@ export function buildRepoGraphArtifact(result, opts = {}) {
119
87
  edges,
120
88
  };
121
89
  }
122
- // ── Node builders ──
123
90
  function buildServiceNode(component) {
124
91
  const id = serviceIdFor(component);
125
92
  return {
@@ -208,7 +175,6 @@ function buildDependsOnEdge(serviceId, depId, evidence) {
208
175
  evidence,
209
176
  };
210
177
  }
211
- // ── Helpers ──
212
178
  function serviceIdFor(component) {
213
179
  return `service::${component.language}::${component.name}`;
214
180
  }
@@ -217,12 +183,9 @@ function externalDepId(ext) {
217
183
  return `external_dependency::${registry}::${ext.package}`;
218
184
  }
219
185
  function registryFor(ext) {
220
- // Heuristic — the existing extractor doesn't tag registry, so derive from package shape.
221
186
  if (ext.package.startsWith("github.com/"))
222
187
  return "go";
223
188
  if (ext.package.startsWith("@") || /^[a-z0-9-]+$/.test(ext.package)) {
224
- // npm + pypi share many shapes; lean npm by default since most ai_sdks live there.
225
- // PyPI-only packages can be retagged once adapters expose registry directly.
226
189
  return "npm";
227
190
  }
228
191
  return "npm";
@@ -280,4 +243,3 @@ function toImportEvidence(loc, pkg) {
280
243
  function stripPrefix(value, prefix) {
281
244
  return value.startsWith(prefix) ? value.slice(prefix.length) : value;
282
245
  }
283
- //# sourceMappingURL=graph-builder.js.map
@@ -1,13 +1,3 @@
1
- /**
2
- * TypeScript interfaces for RepoGraphArtifactV1.
3
- *
4
- * Canonical source: schemas/repo-graph-artifact.schema.json
5
- * Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 1)
6
- *
7
- * The JSON schema is authoritative — these types must stay in sync. A
8
- * repo-level test (planned) validates extractor output against the schema
9
- * to catch drift.
10
- */
11
1
  export type Lane = "trusted" | "inferred";
12
2
  export type Source = "inspect.trusted" | "inspect.inferred";
13
3
  export type GraphLanguage = "typescript" | "javascript" | "python" | "go";
@@ -1,12 +1 @@
1
- /**
2
- * TypeScript interfaces for RepoGraphArtifactV1.
3
- *
4
- * Canonical source: schemas/repo-graph-artifact.schema.json
5
- * Plan: docs/plans/LOCAL-REPO-GRAPH-IMPLEMENTATION.md (Phase 1)
6
- *
7
- * The JSON schema is authoritative — these types must stay in sync. A
8
- * repo-level test (planned) validates extractor output against the schema
9
- * to catch drift.
10
- */
11
1
  export {};
12
- //# sourceMappingURL=graph-types.js.map
@@ -1,22 +1,8 @@
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 type { ExtractionResult } from "./types.js";
13
2
  export interface RunOptions {
14
3
  rootDir: string;
15
- /** Subset of language adapters to run; defaults to all registered. */
16
4
  languages?: Array<"typescript" | "go" | "python">;
17
- /** Extra ignore patterns from --ignore flags. */
18
5
  extraIgnores?: string[];
19
- /** Version string for the extractor — usually @zivis/cli's package version. */
20
6
  extractorVersion: string;
21
7
  }
22
8
  export declare function runExtractor(opts: RunOptions): Promise<ExtractionResult>;
@@ -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
@@ -1,26 +1,7 @@
1
- /**
2
- * Lane-2 conversion prompts — nudges the user to install the ZIVIS
3
- * GitHub App and / or link a repo to a specific Application.
4
- *
5
- * Surfaced from `zivis auth login`, `zivis auth init`, and `zivis check`
6
- * so the next step is obvious right after a developer signs in.
7
- *
8
- * Best-effort by design: any fetch failure returns `null` so we don't
9
- * fail an otherwise-successful auth or check run on a transient API
10
- * blip.
11
- */
12
1
  import type { ZivisConfig } from "@zivis/mcp/types";
13
2
  export interface BuildLinkagePromptOpts {
14
3
  config: ZivisConfig;
15
- /** Optional. When provided we also check whether THIS app has linked repos. */
16
4
  applicationId?: string;
17
- /** Format hint: "short" omits the explanatory why-line. Default "full". */
18
5
  style?: "short" | "full";
19
6
  }
20
- /**
21
- * Fetch GitHub App status + (if applicationId given) per-app repo
22
- * linkage status, then return a multi-line printable prompt suggesting
23
- * the next step. Returns null when nothing actionable is missing
24
- * (fully linked) or when we couldn't determine the state.
25
- */
26
7
  export declare function buildLinkagePrompt(opts: BuildLinkagePromptOpts): Promise<string | null>;
@@ -1,21 +1,4 @@
1
- /**
2
- * Lane-2 conversion prompts — nudges the user to install the ZIVIS
3
- * GitHub App and / or link a repo to a specific Application.
4
- *
5
- * Surfaced from `zivis auth login`, `zivis auth init`, and `zivis check`
6
- * so the next step is obvious right after a developer signs in.
7
- *
8
- * Best-effort by design: any fetch failure returns `null` so we don't
9
- * fail an otherwise-successful auth or check run on a transient API
10
- * blip.
11
- */
12
1
  import { resolveAuth } from "@zivis/mcp/auth";
13
- /**
14
- * Fetch GitHub App status + (if applicationId given) per-app repo
15
- * linkage status, then return a multi-line printable prompt suggesting
16
- * the next step. Returns null when nothing actionable is missing
17
- * (fully linked) or when we couldn't determine the state.
18
- */
19
2
  export async function buildLinkagePrompt(opts) {
20
3
  const creds = await resolveAuth(opts.config);
21
4
  if (creds.method === "none")
@@ -23,24 +6,19 @@ export async function buildLinkagePrompt(opts) {
23
6
  const appStatus = await fetchGitHubAppStatus(opts.config, creds);
24
7
  if (!appStatus)
25
8
  return null;
26
- // Case 1: GitHub App not installed at all → install URL.
27
9
  if (!appStatus.installed) {
28
10
  if (!appStatus.installUrl)
29
- return null; // env not configured; don't show a broken link
11
+ return null;
30
12
  return formatInstallPrompt(appStatus.installUrl, opts.style ?? "full");
31
13
  }
32
- // Case 2: App installed but caller has a specific applicationId and
33
- // that app has no linked repo → web link-repo prompt.
34
14
  if (opts.applicationId) {
35
15
  const repoStatus = await fetchAppRepoStatus(opts.config, creds, opts.applicationId);
36
16
  if (repoStatus && !repoStatus.linked) {
37
17
  return formatLinkRepoPrompt(opts.config, opts.applicationId, opts.style ?? "full");
38
18
  }
39
19
  }
40
- // Case 3: All good (or no applicationId to check at app-level).
41
20
  return null;
42
21
  }
43
- // ── HTTP helpers ──
44
22
  async function fetchGitHubAppStatus(config, creds) {
45
23
  try {
46
24
  const res = await fetch(`${config.apiBaseUrl}/api/github-app/status`, {
@@ -78,7 +56,6 @@ function authHeaders(creds) {
78
56
  }
79
57
  return base;
80
58
  }
81
- // ── Formatters ──
82
59
  function formatInstallPrompt(installUrl, style) {
83
60
  if (style === "short") {
84
61
  return `Next: install the ZIVIS GitHub App — ${installUrl}`;
@@ -104,18 +81,15 @@ function formatLinkRepoPrompt(config, applicationId, style) {
104
81
  ].join("\n");
105
82
  }
106
83
  function guessAppUrlFromApi(apiBaseUrl) {
107
- // Standard mapping: api.* ⇄ app.* on the same root domain.
108
84
  try {
109
85
  const u = new URL(apiBaseUrl);
110
86
  if (u.host.startsWith("api.")) {
111
87
  u.host = "app." + u.host.slice(4);
112
88
  return `${u.protocol}//${u.host}`;
113
89
  }
114
- // localhost / non-standard hosts → fall back to the api URL itself.
115
90
  return apiBaseUrl;
116
91
  }
117
92
  catch {
118
93
  return "https://app.zivis.ai";
119
94
  }
120
95
  }
121
- //# sourceMappingURL=github-linkage-prompt.js.map
@@ -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>;