bilt-toolkit 1.0.0

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 (116) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +168 -0
  3. package/bin/bilt.js +2 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +161 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/doctor.d.ts +13 -0
  9. package/dist/commands/doctor.d.ts.map +1 -0
  10. package/dist/commands/doctor.js +194 -0
  11. package/dist/commands/doctor.js.map +1 -0
  12. package/dist/commands/fix.d.ts +12 -0
  13. package/dist/commands/fix.d.ts.map +1 -0
  14. package/dist/commands/fix.js +273 -0
  15. package/dist/commands/fix.js.map +1 -0
  16. package/dist/commands/init.d.ts +11 -0
  17. package/dist/commands/init.d.ts.map +1 -0
  18. package/dist/commands/init.js +101 -0
  19. package/dist/commands/init.js.map +1 -0
  20. package/dist/commands/scan.d.ts +17 -0
  21. package/dist/commands/scan.d.ts.map +1 -0
  22. package/dist/commands/scan.js +267 -0
  23. package/dist/commands/scan.js.map +1 -0
  24. package/dist/commands/undo.d.ts +12 -0
  25. package/dist/commands/undo.d.ts.map +1 -0
  26. package/dist/commands/undo.js +90 -0
  27. package/dist/commands/undo.js.map +1 -0
  28. package/dist/commands/watch.d.ts +10 -0
  29. package/dist/commands/watch.d.ts.map +1 -0
  30. package/dist/commands/watch.js +68 -0
  31. package/dist/commands/watch.js.map +1 -0
  32. package/dist/config/config.d.ts +8 -0
  33. package/dist/config/config.d.ts.map +1 -0
  34. package/dist/config/config.js +75 -0
  35. package/dist/config/config.js.map +1 -0
  36. package/dist/core/fix/confirm.d.ts +21 -0
  37. package/dist/core/fix/confirm.d.ts.map +1 -0
  38. package/dist/core/fix/confirm.js +60 -0
  39. package/dist/core/fix/confirm.js.map +1 -0
  40. package/dist/core/fix/env-fix.d.ts +40 -0
  41. package/dist/core/fix/env-fix.d.ts.map +1 -0
  42. package/dist/core/fix/env-fix.js +186 -0
  43. package/dist/core/fix/env-fix.js.map +1 -0
  44. package/dist/core/fix/snapshot.d.ts +30 -0
  45. package/dist/core/fix/snapshot.d.ts.map +1 -0
  46. package/dist/core/fix/snapshot.js +186 -0
  47. package/dist/core/fix/snapshot.js.map +1 -0
  48. package/dist/core/rules/entropy.d.ts +29 -0
  49. package/dist/core/rules/entropy.d.ts.map +1 -0
  50. package/dist/core/rules/entropy.js +117 -0
  51. package/dist/core/rules/entropy.js.map +1 -0
  52. package/dist/core/rules/providers.d.ts +12 -0
  53. package/dist/core/rules/providers.d.ts.map +1 -0
  54. package/dist/core/rules/providers.js +184 -0
  55. package/dist/core/rules/providers.js.map +1 -0
  56. package/dist/core/rules/secret-rules.d.ts +3 -0
  57. package/dist/core/rules/secret-rules.d.ts.map +1 -0
  58. package/dist/core/rules/secret-rules.js +205 -0
  59. package/dist/core/rules/secret-rules.js.map +1 -0
  60. package/dist/core/scan/env.d.ts +47 -0
  61. package/dist/core/scan/env.d.ts.map +1 -0
  62. package/dist/core/scan/env.js +301 -0
  63. package/dist/core/scan/env.js.map +1 -0
  64. package/dist/core/scan/framework.d.ts +26 -0
  65. package/dist/core/scan/framework.d.ts.map +1 -0
  66. package/dist/core/scan/framework.js +254 -0
  67. package/dist/core/scan/framework.js.map +1 -0
  68. package/dist/core/scan/gitignore.d.ts +20 -0
  69. package/dist/core/scan/gitignore.d.ts.map +1 -0
  70. package/dist/core/scan/gitignore.js +217 -0
  71. package/dist/core/scan/gitignore.js.map +1 -0
  72. package/dist/core/scan/secrets.d.ts +27 -0
  73. package/dist/core/scan/secrets.d.ts.map +1 -0
  74. package/dist/core/scan/secrets.js +247 -0
  75. package/dist/core/scan/secrets.js.map +1 -0
  76. package/dist/core/score/health.d.ts +29 -0
  77. package/dist/core/score/health.d.ts.map +1 -0
  78. package/dist/core/score/health.js +73 -0
  79. package/dist/core/score/health.js.map +1 -0
  80. package/dist/core/watch/watcher.d.ts +29 -0
  81. package/dist/core/watch/watcher.d.ts.map +1 -0
  82. package/dist/core/watch/watcher.js +176 -0
  83. package/dist/core/watch/watcher.js.map +1 -0
  84. package/dist/index.d.ts +2 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +2 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/plugins/interface.d.ts +12 -0
  89. package/dist/plugins/interface.d.ts.map +1 -0
  90. package/dist/plugins/interface.js +91 -0
  91. package/dist/plugins/interface.js.map +1 -0
  92. package/dist/plugins/loader.d.ts +10 -0
  93. package/dist/plugins/loader.d.ts.map +1 -0
  94. package/dist/plugins/loader.js +104 -0
  95. package/dist/plugins/loader.js.map +1 -0
  96. package/dist/plugins/official/docker.d.ts +4 -0
  97. package/dist/plugins/official/docker.d.ts.map +1 -0
  98. package/dist/plugins/official/docker.js +111 -0
  99. package/dist/plugins/official/docker.js.map +1 -0
  100. package/dist/plugins/official/terraform.d.ts +4 -0
  101. package/dist/plugins/official/terraform.d.ts.map +1 -0
  102. package/dist/plugins/official/terraform.js +131 -0
  103. package/dist/plugins/official/terraform.js.map +1 -0
  104. package/dist/types/index.d.ts +158 -0
  105. package/dist/types/index.d.ts.map +1 -0
  106. package/dist/types/index.js +3 -0
  107. package/dist/types/index.js.map +1 -0
  108. package/dist/ui/format.d.ts +43 -0
  109. package/dist/ui/format.d.ts.map +1 -0
  110. package/dist/ui/format.js +207 -0
  111. package/dist/ui/format.js.map +1 -0
  112. package/dist/ui/reporter.d.ts +39 -0
  113. package/dist/ui/reporter.d.ts.map +1 -0
  114. package/dist/ui/reporter.js +254 -0
  115. package/dist/ui/reporter.js.map +1 -0
  116. package/package.json +65 -0
@@ -0,0 +1,273 @@
1
+ // ─── Fix Command ─────────────────────────────────────────────────────────────
2
+ // Scans for issues, generates fix actions, and applies them interactively.
3
+ import path from "node:path";
4
+ import chalk from "chalk";
5
+ import Enquirer from "enquirer";
6
+ import { promises as fs } from "node:fs";
7
+ import { executeScan } from "./scan.js";
8
+ import { loadConfig } from "../config/config.js";
9
+ import { createSnapshot } from "../core/fix/snapshot.js";
10
+ import { addToGitignore, generateEnvExample, addMissingEnvVars, } from "../core/fix/env-fix.js";
11
+ import { requireTypedConfirmation, requireSimpleConfirmation, } from "../core/fix/confirm.js";
12
+ import { reportFixPreview, reportFixComplete } from "../ui/reporter.js";
13
+ import { parseEnvFile } from "../core/scan/env.js";
14
+ import { SECRET_RULES } from "../core/rules/secret-rules.js";
15
+ /**
16
+ * Execute the `bilt fix` command.
17
+ *
18
+ * 1. Run scan to find issues
19
+ * 2. Generate fix actions
20
+ * 3. Apply fixes (auto for --safe, preview for --dry-run, interactive otherwise)
21
+ * 4. Create snapshot before applying
22
+ * 5. Report results
23
+ */
24
+ export async function executeFix(projectDir, options = {}) {
25
+ const rootDir = path.resolve(projectDir);
26
+ const config = await loadConfig(rootDir);
27
+ // ── Run scan ────────────────────────────────────────────────────────
28
+ const result = await executeScan(rootDir, {
29
+ quiet: true,
30
+ });
31
+ if (result.findings.length === 0) {
32
+ console.log("");
33
+ console.log(chalk.green.bold(" ✨ No issues found — nothing to fix!"));
34
+ console.log("");
35
+ return;
36
+ }
37
+ // ── Generate fix actions ────────────────────────────────────────────
38
+ const actions = await generateFixActions(rootDir, result.findings);
39
+ if (actions.length === 0) {
40
+ console.log("");
41
+ console.log(chalk.yellow(" ⚠ Issues found but no automated fixes available. Review manually."));
42
+ console.log("");
43
+ return;
44
+ }
45
+ // ── Dry-run: preview only ───────────────────────────────────────────
46
+ if (options.dryRun) {
47
+ reportFixPreview(actions);
48
+ console.log(chalk.dim(" (Dry run — no changes applied)"));
49
+ console.log("");
50
+ return;
51
+ }
52
+ // ── Create snapshot before modifying files ──────────────────────────
53
+ const affectedFiles = new Set();
54
+ for (const action of actions) {
55
+ // Extract file from finding ID heuristic
56
+ affectedFiles.add(".gitignore");
57
+ affectedFiles.add(".env");
58
+ affectedFiles.add(".env.example");
59
+ }
60
+ try {
61
+ await createSnapshot([...affectedFiles].map((f) => path.join(rootDir, f)), `Pre-fix snapshot (${actions.length} fixes)`, rootDir);
62
+ }
63
+ catch {
64
+ // Snapshot creation failure shouldn't block fixes
65
+ }
66
+ // ── Safe mode: auto-apply safe fixes only ───────────────────────────
67
+ if (options.safe) {
68
+ const safeActions = actions.filter((a) => a.type === "safe");
69
+ if (safeActions.length === 0) {
70
+ console.log("");
71
+ console.log(chalk.yellow(" ⚠ No safe fixes available. Run without --safe for interactive mode."));
72
+ console.log("");
73
+ return;
74
+ }
75
+ reportFixPreview(safeActions);
76
+ let applied = 0;
77
+ let skipped = 0;
78
+ for (const action of safeActions) {
79
+ try {
80
+ const success = await action.apply();
81
+ if (success) {
82
+ applied++;
83
+ if (options.verbose) {
84
+ console.log(chalk.green(` ✓ ${action.description}`));
85
+ }
86
+ }
87
+ else {
88
+ skipped++;
89
+ }
90
+ }
91
+ catch (error) {
92
+ skipped++;
93
+ if (options.verbose) {
94
+ const msg = error instanceof Error ? error.message : String(error);
95
+ console.log(chalk.red(` ✗ Failed: ${action.description} (${msg})`));
96
+ }
97
+ }
98
+ }
99
+ reportFixComplete(applied, skipped);
100
+ return;
101
+ }
102
+ // ── Interactive mode ────────────────────────────────────────────────
103
+ reportFixPreview(actions);
104
+ let applied = 0;
105
+ let skipped = 0;
106
+ for (const action of actions) {
107
+ console.log("");
108
+ console.log(chalk.bold(` ${action.description}`));
109
+ if (action.preview) {
110
+ console.log(chalk.dim(` ${action.preview}`));
111
+ }
112
+ let shouldApply = false;
113
+ if (action.type === "safe") {
114
+ shouldApply = await requireSimpleConfirmation(action);
115
+ }
116
+ else if (action.type === "destructive") {
117
+ shouldApply = await requireSimpleConfirmation(action);
118
+ }
119
+ else {
120
+ // Irreversible — require typed confirmation
121
+ shouldApply = await requireTypedConfirmation(action, "confirm");
122
+ }
123
+ if (shouldApply) {
124
+ try {
125
+ const success = await action.apply();
126
+ if (success) {
127
+ applied++;
128
+ console.log(chalk.green(" ✓ Applied"));
129
+ }
130
+ else {
131
+ skipped++;
132
+ console.log(chalk.yellow(" ⏭ Skipped (failed to apply)"));
133
+ }
134
+ }
135
+ catch (error) {
136
+ skipped++;
137
+ const msg = error instanceof Error ? error.message : String(error);
138
+ console.log(chalk.red(` ✗ Error: ${msg}`));
139
+ }
140
+ }
141
+ else {
142
+ skipped++;
143
+ console.log(chalk.dim(" ⏭ Skipped"));
144
+ }
145
+ }
146
+ reportFixComplete(applied, skipped);
147
+ }
148
+ // ─── Fix Action Generator ────────────────────────────────────────────────────
149
+ /**
150
+ * Generate fix actions from scan findings.
151
+ */
152
+ async function generateFixActions(rootDir, findings) {
153
+ const actions = [];
154
+ const addedTypes = new Set();
155
+ const config = await loadConfig(rootDir);
156
+ for (const finding of findings) {
157
+ switch (finding.category) {
158
+ case "gitignore-missing": {
159
+ if (!addedTypes.has("gitignore")) {
160
+ addedTypes.add("gitignore");
161
+ actions.push({
162
+ id: `fix-gitignore-${Date.now()}`,
163
+ description: "Add .env patterns to .gitignore",
164
+ type: "safe",
165
+ findingId: finding.id,
166
+ preview: "Will append .env, .env.*, .env.local to .gitignore",
167
+ apply: async () => {
168
+ const gitignorePath = path.join(rootDir, ".gitignore");
169
+ const newContent = await addToGitignore([".env", ".env.*", ".env.local", ".env.*.local", ".bilt/"], gitignorePath);
170
+ await fs.writeFile(gitignorePath, newContent, "utf-8");
171
+ return true;
172
+ },
173
+ });
174
+ }
175
+ break;
176
+ }
177
+ case "env-missing": {
178
+ const key = finding.message.match(/["']([^"']+)["']/)?.[1] ??
179
+ finding.message.match(/`([^`]+)`/)?.[1] ??
180
+ finding.message.match(/(\w+)/)?.[1];
181
+ if (key && !addedTypes.has(`env-missing-${key}`)) {
182
+ addedTypes.add(`env-missing-${key}`);
183
+ actions.push({
184
+ id: `fix-env-missing-${key}-${Date.now()}`,
185
+ description: `Add missing env var ${key} to ${finding.file}`,
186
+ type: "safe",
187
+ findingId: finding.id,
188
+ preview: `Will append ${key}= to ${finding.file}`,
189
+ apply: async () => {
190
+ const envFilePath = path.join(rootDir, finding.file);
191
+ let content = "";
192
+ try {
193
+ content = await fs.readFile(envFilePath, "utf-8");
194
+ }
195
+ catch { }
196
+ const newContent = addMissingEnvVars(content, [key]);
197
+ await fs.writeFile(envFilePath, newContent, "utf-8");
198
+ return true;
199
+ },
200
+ });
201
+ }
202
+ break;
203
+ }
204
+ case "env-mismatch": {
205
+ if (!addedTypes.has("env-example")) {
206
+ addedTypes.add("env-example");
207
+ actions.push({
208
+ id: `fix-env-example-${Date.now()}`,
209
+ description: "Generate .env.example with all required keys",
210
+ type: "safe",
211
+ findingId: finding.id,
212
+ preview: "Will create .env.example with placeholder values",
213
+ apply: async () => {
214
+ const envFilePath = path.join(rootDir, ".env");
215
+ let content = "";
216
+ try {
217
+ content = await fs.readFile(envFilePath, "utf-8");
218
+ }
219
+ catch {
220
+ return false;
221
+ }
222
+ const parsed = parseEnvFile(content, envFilePath);
223
+ const exampleContent = generateEnvExample(parsed, SECRET_RULES, config.entropyThreshold);
224
+ await fs.writeFile(path.join(rootDir, ".env.example"), exampleContent, "utf-8");
225
+ return true;
226
+ },
227
+ });
228
+ }
229
+ break;
230
+ }
231
+ case "secret-detected": {
232
+ // Secrets can't be auto-fixed — provide guidance
233
+ actions.push({
234
+ id: `fix-secret-${finding.id}`,
235
+ description: `Remove secret from ${finding.file}${finding.line ? `:${finding.line}` : ""}`,
236
+ type: "destructive",
237
+ findingId: finding.id,
238
+ preview: finding.suggestion ??
239
+ "Move secret to env var and add to .gitignore",
240
+ apply: async () => {
241
+ // We can't auto-remove secrets safely — this needs manual review
242
+ // But we can offer to add the file to .gitignore
243
+ console.log(chalk.yellow(` ℹ Please manually remove the secret from ${finding.file}`));
244
+ console.log(chalk.dim(` Move the value to a .env file and reference it via an environment variable.`));
245
+ return true;
246
+ },
247
+ });
248
+ break;
249
+ }
250
+ case "framework-warning":
251
+ case "env-exposed": {
252
+ actions.push({
253
+ id: `fix-exposed-${finding.id}`,
254
+ description: `Review client-exposed secret in ${finding.file}`,
255
+ type: "destructive",
256
+ findingId: finding.id,
257
+ preview: finding.suggestion ??
258
+ "Ensure this env var should be exposed to the client bundle",
259
+ apply: async () => {
260
+ console.log(chalk.yellow(` ℹ Review ${finding.file} — this value is exposed to the client.`));
261
+ return true;
262
+ },
263
+ });
264
+ break;
265
+ }
266
+ default:
267
+ // No auto-fix available for this category
268
+ break;
269
+ }
270
+ }
271
+ return actions;
272
+ }
273
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Execute the `bilt init` command.
3
+ *
4
+ * 1. Print welcome banner
5
+ * 2. Run full scan
6
+ * 3. Create snapshot
7
+ * 4. Auto-fix safe issues (.gitignore, .env.example)
8
+ * 5. Report results with the beautiful health card
9
+ */
10
+ export declare function executeInit(projectDir: string): Promise<void>;
11
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyGnE"}
@@ -0,0 +1,101 @@
1
+ // ─── Init Command ────────────────────────────────────────────────────────────
2
+ // Zero-friction onboarding: scan, auto-fix safe issues, show health card.
3
+ import path from "node:path";
4
+ import chalk from "chalk";
5
+ import boxen from "boxen";
6
+ import { promises as fs } from "node:fs";
7
+ import { executeScan } from "./scan.js";
8
+ import { createSnapshot } from "../core/fix/snapshot.js";
9
+ import { addToGitignore, generateEnvExample } from "../core/fix/env-fix.js";
10
+ import { checkEnvFilesIgnoredWithGit } from "../core/scan/gitignore.js";
11
+ import { findEnvFiles, parseEnvFile } from "../core/scan/env.js";
12
+ import { reportInitComplete } from "../ui/reporter.js";
13
+ import { SECRET_RULES } from "../core/rules/secret-rules.js";
14
+ import { loadConfig } from "../config/config.js";
15
+ /**
16
+ * Execute the `bilt init` command.
17
+ *
18
+ * 1. Print welcome banner
19
+ * 2. Run full scan
20
+ * 3. Create snapshot
21
+ * 4. Auto-fix safe issues (.gitignore, .env.example)
22
+ * 5. Report results with the beautiful health card
23
+ */
24
+ export async function executeInit(projectDir) {
25
+ const rootDir = path.resolve(projectDir);
26
+ const config = await loadConfig(rootDir);
27
+ // ── Welcome banner ──────────────────────────────────────────────────
28
+ const banner = boxen(`\n${chalk.bold.cyan(" 🏗️ BILT — Project Health Toolkit")}\n\n` +
29
+ chalk.dim(" Zero-configuration setup. One command to a healthy repo.\n"), {
30
+ padding: 0,
31
+ margin: { top: 1, bottom: 0, left: 1, right: 1 },
32
+ borderStyle: "round",
33
+ borderColor: "cyan",
34
+ });
35
+ console.log(banner);
36
+ console.log("");
37
+ // ── Run full scan ───────────────────────────────────────────────────
38
+ const result = await executeScan(rootDir, {
39
+ quiet: false,
40
+ fun: true,
41
+ });
42
+ // ── Snapshot before fixes ───────────────────────────────────────────
43
+ let fixesApplied = 0;
44
+ // Determine what safe fixes we can apply
45
+ const envFiles = await findEnvFiles(rootDir);
46
+ const envRelativePaths = envFiles.map((f) => path.relative(rootDir, f));
47
+ // Collect files to snapshot
48
+ const filesToSnapshot = [".gitignore", ...envRelativePaths];
49
+ try {
50
+ await createSnapshot(filesToSnapshot.map((f) => path.join(rootDir, f)), "Pre-init snapshot", rootDir);
51
+ }
52
+ catch {
53
+ // Snapshot creation failed — proceed anyway
54
+ }
55
+ // ── Auto-fix: .gitignore entries ────────────────────────────────────
56
+ let gitignoreContent = "";
57
+ try {
58
+ gitignoreContent = await fs.readFile(path.join(rootDir, ".gitignore"), "utf-8");
59
+ }
60
+ catch { }
61
+ const gitignoreFindings = await checkEnvFilesIgnoredWithGit(rootDir, envFiles);
62
+ if (gitignoreFindings.length > 0) {
63
+ try {
64
+ const envPatterns = [
65
+ ".env",
66
+ ".env.*",
67
+ ".env.local",
68
+ ".env.*.local",
69
+ ".bilt/",
70
+ ];
71
+ const gitignorePath = path.join(rootDir, ".gitignore");
72
+ const newContent = await addToGitignore(envPatterns, gitignorePath);
73
+ await fs.writeFile(gitignorePath, newContent, "utf-8");
74
+ fixesApplied++;
75
+ console.log(chalk.green(" ✅ Added .env patterns to .gitignore"));
76
+ }
77
+ catch {
78
+ // Failed to update .gitignore — non-critical
79
+ }
80
+ }
81
+ // ── Auto-fix: generate .env.example ─────────────────────────────────
82
+ if (envFiles.length > 0) {
83
+ try {
84
+ const envFilePath = envFiles[0];
85
+ const envContent = await fs.readFile(envFilePath, "utf-8");
86
+ const parsed = parseEnvFile(envContent, envFilePath);
87
+ const exampleContent = generateEnvExample(parsed, SECRET_RULES, config.entropyThreshold);
88
+ await fs.writeFile(path.join(rootDir, ".env.example"), exampleContent, "utf-8");
89
+ fixesApplied++;
90
+ console.log(chalk.green(" ✅ Generated .env.example"));
91
+ }
92
+ catch {
93
+ // Failed to generate .env.example — non-critical
94
+ }
95
+ }
96
+ // ── Re-run scan to get updated results ──────────────────────────────
97
+ const updatedResult = fixesApplied > 0 ? await executeScan(rootDir, { quiet: true }) : result;
98
+ // ── Report ──────────────────────────────────────────────────────────
99
+ reportInitComplete(updatedResult, fixesApplied);
100
+ }
101
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ScanResult, ScanOptions } from "../types/index.js";
2
+ /**
3
+ * Execute a full project scan, returning a ScanResult.
4
+ *
5
+ * 1. Load config
6
+ * 2. Find & parse .env files
7
+ * 3. Detect env mismatches (missing/unused vars)
8
+ * 4. Check .gitignore coverage
9
+ * 5. Scan working tree for secrets
10
+ * 6. Scan git history for secrets
11
+ * 7. Detect framework & client-exposed secrets
12
+ * 8. Run plugins
13
+ * 9. Calculate health score
14
+ * 10. Report results
15
+ */
16
+ export declare function executeScan(projectDir: string, options?: ScanOptions): Promise<ScanResult>;
17
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,UAAU,EAEV,WAAW,EAGZ,MAAM,mBAAmB,CAAC;AA0B3B;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAyRrB"}