sapper-ai 0.5.0 → 0.6.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +300 -30
- package/dist/harden.d.ts +28 -0
- package/dist/harden.d.ts.map +1 -0
- package/dist/harden.js +309 -0
- package/dist/mcp/jsonc.d.ts +3 -0
- package/dist/mcp/jsonc.d.ts.map +1 -0
- package/dist/mcp/jsonc.js +119 -0
- package/dist/mcp/wrapConfig.d.ts +22 -0
- package/dist/mcp/wrapConfig.d.ts.map +1 -0
- package/dist/mcp/wrapConfig.js +192 -0
- package/dist/policyYaml.d.ts +3 -0
- package/dist/policyYaml.d.ts.map +1 -0
- package/dist/policyYaml.js +27 -0
- package/dist/postinstall.js +1 -1
- package/dist/quarantine.d.ts +13 -0
- package/dist/quarantine.d.ts.map +1 -0
- package/dist/quarantine.js +22 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +1061 -59
- package/dist/scan.d.ts +13 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +92 -23
- package/dist/utils/env.d.ts +3 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +25 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +47 -0
- package/dist/utils/repoRoot.d.ts +2 -0
- package/dist/utils/repoRoot.d.ts.map +1 -0
- package/dist/utils/repoRoot.js +20 -0
- package/dist/utils/semver.d.ts +2 -0
- package/dist/utils/semver.d.ts.map +1 -0
- package/dist/utils/semver.js +7 -0
- package/package.json +4 -7
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAkBA,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuFpF"}
|
package/dist/cli.js
CHANGED
|
@@ -45,7 +45,12 @@ const node_path_1 = require("node:path");
|
|
|
45
45
|
const readline = __importStar(require("node:readline"));
|
|
46
46
|
const select_1 = __importDefault(require("@inquirer/select"));
|
|
47
47
|
const presets_1 = require("./presets");
|
|
48
|
+
const policyYaml_1 = require("./policyYaml");
|
|
49
|
+
const harden_1 = require("./harden");
|
|
50
|
+
const quarantine_1 = require("./quarantine");
|
|
51
|
+
const wrapConfig_1 = require("./mcp/wrapConfig");
|
|
48
52
|
const scan_1 = require("./scan");
|
|
53
|
+
const env_1 = require("./utils/env");
|
|
49
54
|
async function runCli(argv = process.argv.slice(2)) {
|
|
50
55
|
if (argv[0] === '--help' || argv[0] === '-h') {
|
|
51
56
|
printUsage();
|
|
@@ -62,7 +67,49 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
62
67
|
printUsage();
|
|
63
68
|
return 1;
|
|
64
69
|
}
|
|
65
|
-
|
|
70
|
+
const scanExitCode = await (0, scan_1.runScan)(scanOptions);
|
|
71
|
+
const shouldOfferHarden = parsed.noPrompt !== true &&
|
|
72
|
+
process.stdout.isTTY === true &&
|
|
73
|
+
process.stdin.isTTY === true &&
|
|
74
|
+
(0, env_1.isCiEnv)(process.env) !== true &&
|
|
75
|
+
(parsed.harden === true || (await (0, harden_1.getHardenPlanSummary)({ includeSystem: true })).actions.length > 0);
|
|
76
|
+
if (shouldOfferHarden) {
|
|
77
|
+
const hardenExitCode = await (0, harden_1.runHarden)({
|
|
78
|
+
apply: true,
|
|
79
|
+
includeSystem: true,
|
|
80
|
+
});
|
|
81
|
+
if (scanExitCode === 0 && hardenExitCode !== 0) {
|
|
82
|
+
return hardenExitCode;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return scanExitCode;
|
|
86
|
+
}
|
|
87
|
+
if (argv[0] === 'harden') {
|
|
88
|
+
const parsed = parseHardenArgs(argv.slice(1));
|
|
89
|
+
if (!parsed) {
|
|
90
|
+
printUsage();
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
return (0, harden_1.runHarden)(parsed);
|
|
94
|
+
}
|
|
95
|
+
if (argv[0] === 'mcp') {
|
|
96
|
+
const parsed = parseMcpArgs(argv.slice(1));
|
|
97
|
+
if (!parsed) {
|
|
98
|
+
printUsage();
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
return runMcpCommand(parsed);
|
|
102
|
+
}
|
|
103
|
+
if (argv[0] === 'quarantine') {
|
|
104
|
+
const parsed = parseQuarantineArgs(argv.slice(1));
|
|
105
|
+
if (!parsed) {
|
|
106
|
+
printUsage();
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
if (parsed.command === 'quarantine_list') {
|
|
110
|
+
return (0, quarantine_1.runQuarantineList)({ quarantineDir: parsed.quarantineDir });
|
|
111
|
+
}
|
|
112
|
+
return (0, quarantine_1.runQuarantineRestore)({ id: parsed.id, quarantineDir: parsed.quarantineDir, force: parsed.force });
|
|
66
113
|
}
|
|
67
114
|
if (argv[0] === 'dashboard') {
|
|
68
115
|
return runDashboard();
|
|
@@ -84,10 +131,20 @@ Usage:
|
|
|
84
131
|
sapper-ai scan --deep Current directory + subdirectories
|
|
85
132
|
sapper-ai scan --system AI system paths (~/.claude, ~/.cursor, ...)
|
|
86
133
|
sapper-ai scan ./path Scan a specific file/directory
|
|
134
|
+
sapper-ai scan --policy ./sapperai.config.yaml Use explicit policy path (fatal if invalid)
|
|
87
135
|
sapper-ai scan --fix Quarantine blocked files
|
|
88
136
|
sapper-ai scan --ai Deep scan with AI analysis (requires OPENAI_API_KEY)
|
|
137
|
+
sapper-ai scan --no-prompt Disable all prompts (CI-safe)
|
|
138
|
+
sapper-ai scan --harden After scan, offer to apply recommended hardening
|
|
89
139
|
sapper-ai scan --no-open Skip opening report in browser
|
|
90
140
|
sapper-ai scan --no-save Skip saving scan results to ~/.sapperai/scans/
|
|
141
|
+
sapper-ai harden Plan recommended setup changes (no writes)
|
|
142
|
+
sapper-ai harden --apply Apply recommended project changes
|
|
143
|
+
sapper-ai harden --include-system Include system changes (home directory)
|
|
144
|
+
sapper-ai mcp wrap-config Wrap MCP servers to run behind sapperai-proxy (defaults to Claude Code config)
|
|
145
|
+
sapper-ai mcp unwrap-config Undo MCP wrapping
|
|
146
|
+
sapper-ai quarantine list List quarantined files
|
|
147
|
+
sapper-ai quarantine restore <id> [--force] Restore quarantined file by id
|
|
91
148
|
sapper-ai init Interactive setup wizard
|
|
92
149
|
sapper-ai dashboard Launch web dashboard
|
|
93
150
|
sapper-ai --help Show this help
|
|
@@ -97,17 +154,30 @@ Learn more: https://github.com/sapper-ai/sapperai
|
|
|
97
154
|
}
|
|
98
155
|
function parseScanArgs(argv) {
|
|
99
156
|
const targets = [];
|
|
157
|
+
let policyPath;
|
|
100
158
|
let fix = false;
|
|
101
159
|
let deep = false;
|
|
102
160
|
let system = false;
|
|
103
161
|
let ai = false;
|
|
104
162
|
let noSave = false;
|
|
105
163
|
let noOpen = false;
|
|
106
|
-
|
|
164
|
+
let noPrompt = false;
|
|
165
|
+
let harden = false;
|
|
166
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
167
|
+
const arg = argv[index];
|
|
168
|
+
const nextArg = argv[index + 1];
|
|
107
169
|
if (arg === '--fix') {
|
|
108
170
|
fix = true;
|
|
109
171
|
continue;
|
|
110
172
|
}
|
|
173
|
+
if (arg === '--policy') {
|
|
174
|
+
if (!nextArg || nextArg.startsWith('-')) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
policyPath = nextArg;
|
|
178
|
+
index += 1;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
111
181
|
if (arg === '--deep') {
|
|
112
182
|
deep = true;
|
|
113
183
|
continue;
|
|
@@ -120,6 +190,14 @@ function parseScanArgs(argv) {
|
|
|
120
190
|
ai = true;
|
|
121
191
|
continue;
|
|
122
192
|
}
|
|
193
|
+
if (arg === '--no-prompt') {
|
|
194
|
+
noPrompt = true;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (arg === '--harden') {
|
|
198
|
+
harden = true;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
123
201
|
if (arg === '--no-open') {
|
|
124
202
|
noOpen = true;
|
|
125
203
|
continue;
|
|
@@ -133,7 +211,221 @@ function parseScanArgs(argv) {
|
|
|
133
211
|
}
|
|
134
212
|
targets.push(arg);
|
|
135
213
|
}
|
|
136
|
-
return { targets, fix, deep, system, ai, noSave, noOpen };
|
|
214
|
+
return { targets, policyPath, fix, deep, system, ai, noSave, noOpen, noPrompt, harden };
|
|
215
|
+
}
|
|
216
|
+
function parseHardenArgs(argv) {
|
|
217
|
+
let apply = false;
|
|
218
|
+
let includeSystem = false;
|
|
219
|
+
let yes = false;
|
|
220
|
+
let noPrompt = false;
|
|
221
|
+
let force = false;
|
|
222
|
+
let workflowVersion;
|
|
223
|
+
let mcpVersion;
|
|
224
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
225
|
+
const arg = argv[index];
|
|
226
|
+
const nextArg = argv[index + 1];
|
|
227
|
+
if (arg === '--dry-run') {
|
|
228
|
+
apply = false;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (arg === '--apply') {
|
|
232
|
+
apply = true;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (arg === '--include-system') {
|
|
236
|
+
includeSystem = true;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (arg === '--yes') {
|
|
240
|
+
yes = true;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (arg === '--no-prompt') {
|
|
244
|
+
noPrompt = true;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (arg === '--force') {
|
|
248
|
+
force = true;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (arg === '--workflow-version') {
|
|
252
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
253
|
+
return null;
|
|
254
|
+
workflowVersion = nextArg;
|
|
255
|
+
index += 1;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (arg === '--mcp-version') {
|
|
259
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
260
|
+
return null;
|
|
261
|
+
mcpVersion = nextArg;
|
|
262
|
+
index += 1;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
apply,
|
|
269
|
+
includeSystem,
|
|
270
|
+
yes,
|
|
271
|
+
noPrompt,
|
|
272
|
+
force,
|
|
273
|
+
workflowVersion,
|
|
274
|
+
mcpVersion,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function parseMcpArgs(argv) {
|
|
278
|
+
const subcommand = argv[0];
|
|
279
|
+
const rest = argv.slice(1);
|
|
280
|
+
if (!subcommand)
|
|
281
|
+
return null;
|
|
282
|
+
const defaultConfigPath = (0, node_path_1.join)((0, node_os_1.homedir)(), '.config', 'claude-code', 'config.json');
|
|
283
|
+
let configPath = defaultConfigPath;
|
|
284
|
+
let format = 'jsonc';
|
|
285
|
+
let dryRun = false;
|
|
286
|
+
let mcpVersion;
|
|
287
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
288
|
+
const arg = rest[index];
|
|
289
|
+
const nextArg = rest[index + 1];
|
|
290
|
+
if (arg === '--config') {
|
|
291
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
292
|
+
return null;
|
|
293
|
+
configPath = nextArg;
|
|
294
|
+
format = 'json';
|
|
295
|
+
index += 1;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (arg === '--jsonc') {
|
|
299
|
+
format = 'jsonc';
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (arg === '--dry-run') {
|
|
303
|
+
dryRun = true;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (arg === '--mcp-version') {
|
|
307
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
308
|
+
return null;
|
|
309
|
+
mcpVersion = nextArg;
|
|
310
|
+
index += 1;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
if (subcommand === 'wrap-config') {
|
|
316
|
+
return { command: 'mcp_wrap_config', configPath, format, dryRun, mcpVersion };
|
|
317
|
+
}
|
|
318
|
+
if (subcommand === 'unwrap-config') {
|
|
319
|
+
return { command: 'mcp_unwrap_config', configPath, format, dryRun };
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
async function runMcpCommand(args) {
|
|
324
|
+
if (args.command === 'mcp_unwrap_config') {
|
|
325
|
+
const result = await (0, wrapConfig_1.unwrapMcpConfigFile)({
|
|
326
|
+
filePath: args.configPath,
|
|
327
|
+
format: args.format,
|
|
328
|
+
dryRun: args.dryRun,
|
|
329
|
+
});
|
|
330
|
+
if (!result.changed) {
|
|
331
|
+
console.log('No changes needed.');
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
if (result.restoredFromBackupPath) {
|
|
335
|
+
if (args.dryRun) {
|
|
336
|
+
console.log(`Config parse failed; would restore from backup: ${result.restoredFromBackupPath}`);
|
|
337
|
+
return 0;
|
|
338
|
+
}
|
|
339
|
+
console.log(`Config parse failed; restored from backup: ${result.restoredFromBackupPath}`);
|
|
340
|
+
if (result.backupPath)
|
|
341
|
+
console.log(`Backup: ${result.backupPath}`);
|
|
342
|
+
return 0;
|
|
343
|
+
}
|
|
344
|
+
if (args.dryRun) {
|
|
345
|
+
console.log(`Would unwrap ${result.changedServers.length} server(s): ${result.changedServers.join(', ')}`);
|
|
346
|
+
return 0;
|
|
347
|
+
}
|
|
348
|
+
console.log(`Unwrapped ${result.changedServers.length} server(s): ${result.changedServers.join(', ')}`);
|
|
349
|
+
if (result.backupPath)
|
|
350
|
+
console.log(`Backup: ${result.backupPath}`);
|
|
351
|
+
return 0;
|
|
352
|
+
}
|
|
353
|
+
if (!(0, wrapConfig_1.checkNpxAvailable)()) {
|
|
354
|
+
console.error("npx is not available on PATH. Install Node.js/npm and retry.");
|
|
355
|
+
return 1;
|
|
356
|
+
}
|
|
357
|
+
const envVersion = process.env.SAPPERAI_MCP_VERSION?.trim();
|
|
358
|
+
const installedVersion = (0, wrapConfig_1.resolveInstalledPackageVersion)('@sapper-ai/mcp');
|
|
359
|
+
const mcpVersion = (args.mcpVersion ?? envVersion ?? installedVersion ?? '').trim();
|
|
360
|
+
if (!mcpVersion) {
|
|
361
|
+
console.error("Missing MCP version. Provide '--mcp-version <semver>' or install @sapper-ai/mcp.");
|
|
362
|
+
return 1;
|
|
363
|
+
}
|
|
364
|
+
const result = await (0, wrapConfig_1.wrapMcpConfigFile)({
|
|
365
|
+
filePath: args.configPath,
|
|
366
|
+
mcpVersion,
|
|
367
|
+
format: args.format,
|
|
368
|
+
dryRun: args.dryRun,
|
|
369
|
+
});
|
|
370
|
+
if (!result.changed) {
|
|
371
|
+
console.log('No changes needed.');
|
|
372
|
+
return 0;
|
|
373
|
+
}
|
|
374
|
+
if (args.dryRun) {
|
|
375
|
+
console.log(`Would wrap ${result.changedServers.length} server(s): ${result.changedServers.join(', ')}`);
|
|
376
|
+
return 0;
|
|
377
|
+
}
|
|
378
|
+
console.log(`Wrapped ${result.changedServers.length} server(s): ${result.changedServers.join(', ')}`);
|
|
379
|
+
if (result.backupPath)
|
|
380
|
+
console.log(`Backup: ${result.backupPath}`);
|
|
381
|
+
return 0;
|
|
382
|
+
}
|
|
383
|
+
function parseQuarantineArgs(argv) {
|
|
384
|
+
const subcommand = argv[0];
|
|
385
|
+
const rest = argv.slice(1);
|
|
386
|
+
if (!subcommand)
|
|
387
|
+
return null;
|
|
388
|
+
let quarantineDir;
|
|
389
|
+
let force = false;
|
|
390
|
+
if (subcommand === 'list') {
|
|
391
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
392
|
+
const arg = rest[index];
|
|
393
|
+
const nextArg = rest[index + 1];
|
|
394
|
+
if (arg === '--quarantine-dir') {
|
|
395
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
396
|
+
return null;
|
|
397
|
+
quarantineDir = nextArg;
|
|
398
|
+
index += 1;
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
return { command: 'quarantine_list', quarantineDir };
|
|
404
|
+
}
|
|
405
|
+
if (subcommand === 'restore') {
|
|
406
|
+
const id = rest[0];
|
|
407
|
+
if (!id)
|
|
408
|
+
return null;
|
|
409
|
+
const tail = rest.slice(1);
|
|
410
|
+
for (let index = 0; index < tail.length; index += 1) {
|
|
411
|
+
const arg = tail[index];
|
|
412
|
+
const nextArg = tail[index + 1];
|
|
413
|
+
if (arg === '--force') {
|
|
414
|
+
force = true;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (arg === '--quarantine-dir') {
|
|
418
|
+
if (!nextArg || nextArg.startsWith('-'))
|
|
419
|
+
return null;
|
|
420
|
+
quarantineDir = nextArg;
|
|
421
|
+
index += 1;
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
return { command: 'quarantine_restore', id, quarantineDir, force };
|
|
427
|
+
}
|
|
428
|
+
return null;
|
|
137
429
|
}
|
|
138
430
|
function displayPath(path) {
|
|
139
431
|
const home = (0, node_os_1.homedir)();
|
|
@@ -176,6 +468,7 @@ async function resolveScanOptions(args) {
|
|
|
176
468
|
fix: args.fix,
|
|
177
469
|
noSave: args.noSave,
|
|
178
470
|
noOpen: args.noOpen,
|
|
471
|
+
policyPath: args.policyPath,
|
|
179
472
|
};
|
|
180
473
|
if (args.system) {
|
|
181
474
|
if (args.targets.length > 0) {
|
|
@@ -204,8 +497,8 @@ async function resolveScanOptions(args) {
|
|
|
204
497
|
if (args.deep) {
|
|
205
498
|
return { ...common, targets: [cwd], deep: true, ai: args.ai, scopeLabel: 'Current + subdirectories' };
|
|
206
499
|
}
|
|
207
|
-
if (process.stdout.isTTY !== true) {
|
|
208
|
-
return { ...common, targets: [cwd], deep: true, ai:
|
|
500
|
+
if (args.noPrompt === true || process.stdout.isTTY !== true) {
|
|
501
|
+
return { ...common, targets: [cwd], deep: true, ai: args.ai, scopeLabel: 'Current + subdirectories' };
|
|
209
502
|
}
|
|
210
503
|
const scope = await promptScanScope(cwd);
|
|
211
504
|
const ai = args.ai ? true : await promptScanDepth();
|
|
@@ -285,9 +578,9 @@ async function runInitWizard() {
|
|
|
285
578
|
'# Generated by: sapper-ai init',
|
|
286
579
|
'# Docs: https://github.com/sapper-ai/sapperai',
|
|
287
580
|
'',
|
|
288
|
-
...buildPolicyYaml(selectedPreset, auditLogPath),
|
|
289
581
|
];
|
|
290
|
-
(0,
|
|
582
|
+
const body = (0, policyYaml_1.renderPolicyYaml)(selectedPreset, auditLogPath);
|
|
583
|
+
(0, node_fs_1.writeFileSync)(outputPath, `${lines.join('\n')}\n${body}`, 'utf8');
|
|
291
584
|
console.log(`\n Created ${outputPath}\n`);
|
|
292
585
|
console.log(' Quick start:\n');
|
|
293
586
|
console.log(" import { createGuard } from 'sapper-ai'");
|
|
@@ -296,29 +589,6 @@ async function runInitWizard() {
|
|
|
296
589
|
console.log();
|
|
297
590
|
rl.close();
|
|
298
591
|
}
|
|
299
|
-
function buildPolicyYaml(preset, auditLogPath) {
|
|
300
|
-
const p = presets_1.presets[preset].policy;
|
|
301
|
-
const lines = [];
|
|
302
|
-
lines.push(`mode: ${p.mode}`);
|
|
303
|
-
lines.push(`defaultAction: ${p.defaultAction}`);
|
|
304
|
-
lines.push(`failOpen: ${p.failOpen}`);
|
|
305
|
-
lines.push('');
|
|
306
|
-
lines.push('detectors:');
|
|
307
|
-
const detectors = p.detectors ?? ['rules'];
|
|
308
|
-
for (const d of detectors) {
|
|
309
|
-
lines.push(` - ${d}`);
|
|
310
|
-
}
|
|
311
|
-
lines.push('');
|
|
312
|
-
lines.push('thresholds:');
|
|
313
|
-
const thresholds = p.thresholds ?? {};
|
|
314
|
-
lines.push(` riskThreshold: ${thresholds.riskThreshold ?? 0.7}`);
|
|
315
|
-
lines.push(` blockMinConfidence: ${thresholds.blockMinConfidence ?? 0.5}`);
|
|
316
|
-
if (auditLogPath) {
|
|
317
|
-
lines.push('');
|
|
318
|
-
lines.push(`auditLogPath: ${auditLogPath}`);
|
|
319
|
-
}
|
|
320
|
-
return lines;
|
|
321
|
-
}
|
|
322
592
|
function isDirectExecution(argv) {
|
|
323
593
|
const entry = argv[1];
|
|
324
594
|
if (!entry) {
|
package/dist/harden.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type HardenScope = 'project' | 'system';
|
|
2
|
+
export interface HardenPlanSummary {
|
|
3
|
+
repoRoot: string;
|
|
4
|
+
notes: string[];
|
|
5
|
+
actions: Array<{
|
|
6
|
+
id: string;
|
|
7
|
+
scope: HardenScope;
|
|
8
|
+
title: string;
|
|
9
|
+
paths: string[];
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface HardenOptions {
|
|
13
|
+
cwd?: string;
|
|
14
|
+
env?: NodeJS.ProcessEnv;
|
|
15
|
+
includeSystem?: boolean;
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
apply?: boolean;
|
|
18
|
+
yes?: boolean;
|
|
19
|
+
noPrompt?: boolean;
|
|
20
|
+
force?: boolean;
|
|
21
|
+
workflowVersion?: string;
|
|
22
|
+
mcpVersion?: string;
|
|
23
|
+
write?: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
export declare function getHardenPlanSummary(options?: HardenOptions): Promise<HardenPlanSummary>;
|
|
26
|
+
export declare function runHarden(options?: HardenOptions): Promise<number>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=harden.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harden.d.ts","sourceRoot":"","sources":["../src/harden.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;AAUvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,WAAW,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,EAAE,CAAA;KAChB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAoLD,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAOlG;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgG5E"}
|