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.
- package/LICENSE +0 -0
- package/README.md +168 -0
- package/bin/bilt.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +161 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +194 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/fix.d.ts +12 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +273 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +101 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scan.d.ts +17 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +267 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/undo.d.ts +12 -0
- package/dist/commands/undo.d.ts.map +1 -0
- package/dist/commands/undo.js +90 -0
- package/dist/commands/undo.js.map +1 -0
- package/dist/commands/watch.d.ts +10 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +68 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/config.d.ts +8 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +75 -0
- package/dist/config/config.js.map +1 -0
- package/dist/core/fix/confirm.d.ts +21 -0
- package/dist/core/fix/confirm.d.ts.map +1 -0
- package/dist/core/fix/confirm.js +60 -0
- package/dist/core/fix/confirm.js.map +1 -0
- package/dist/core/fix/env-fix.d.ts +40 -0
- package/dist/core/fix/env-fix.d.ts.map +1 -0
- package/dist/core/fix/env-fix.js +186 -0
- package/dist/core/fix/env-fix.js.map +1 -0
- package/dist/core/fix/snapshot.d.ts +30 -0
- package/dist/core/fix/snapshot.d.ts.map +1 -0
- package/dist/core/fix/snapshot.js +186 -0
- package/dist/core/fix/snapshot.js.map +1 -0
- package/dist/core/rules/entropy.d.ts +29 -0
- package/dist/core/rules/entropy.d.ts.map +1 -0
- package/dist/core/rules/entropy.js +117 -0
- package/dist/core/rules/entropy.js.map +1 -0
- package/dist/core/rules/providers.d.ts +12 -0
- package/dist/core/rules/providers.d.ts.map +1 -0
- package/dist/core/rules/providers.js +184 -0
- package/dist/core/rules/providers.js.map +1 -0
- package/dist/core/rules/secret-rules.d.ts +3 -0
- package/dist/core/rules/secret-rules.d.ts.map +1 -0
- package/dist/core/rules/secret-rules.js +205 -0
- package/dist/core/rules/secret-rules.js.map +1 -0
- package/dist/core/scan/env.d.ts +47 -0
- package/dist/core/scan/env.d.ts.map +1 -0
- package/dist/core/scan/env.js +301 -0
- package/dist/core/scan/env.js.map +1 -0
- package/dist/core/scan/framework.d.ts +26 -0
- package/dist/core/scan/framework.d.ts.map +1 -0
- package/dist/core/scan/framework.js +254 -0
- package/dist/core/scan/framework.js.map +1 -0
- package/dist/core/scan/gitignore.d.ts +20 -0
- package/dist/core/scan/gitignore.d.ts.map +1 -0
- package/dist/core/scan/gitignore.js +217 -0
- package/dist/core/scan/gitignore.js.map +1 -0
- package/dist/core/scan/secrets.d.ts +27 -0
- package/dist/core/scan/secrets.d.ts.map +1 -0
- package/dist/core/scan/secrets.js +247 -0
- package/dist/core/scan/secrets.js.map +1 -0
- package/dist/core/score/health.d.ts +29 -0
- package/dist/core/score/health.d.ts.map +1 -0
- package/dist/core/score/health.js +73 -0
- package/dist/core/score/health.js.map +1 -0
- package/dist/core/watch/watcher.d.ts +29 -0
- package/dist/core/watch/watcher.d.ts.map +1 -0
- package/dist/core/watch/watcher.js +176 -0
- package/dist/core/watch/watcher.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/interface.d.ts +12 -0
- package/dist/plugins/interface.d.ts.map +1 -0
- package/dist/plugins/interface.js +91 -0
- package/dist/plugins/interface.js.map +1 -0
- package/dist/plugins/loader.d.ts +10 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +104 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/official/docker.d.ts +4 -0
- package/dist/plugins/official/docker.d.ts.map +1 -0
- package/dist/plugins/official/docker.js +111 -0
- package/dist/plugins/official/docker.js.map +1 -0
- package/dist/plugins/official/terraform.d.ts +4 -0
- package/dist/plugins/official/terraform.d.ts.map +1 -0
- package/dist/plugins/official/terraform.js +131 -0
- package/dist/plugins/official/terraform.js.map +1 -0
- package/dist/types/index.d.ts +158 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/format.d.ts +43 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +207 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/reporter.d.ts +39 -0
- package/dist/ui/reporter.d.ts.map +1 -0
- package/dist/ui/reporter.js +254 -0
- package/dist/ui/reporter.js.map +1 -0
- 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"}
|