auditor-lambda 0.2.1 → 0.2.3
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/audit-code-wrapper-lib.mjs +229 -289
- package/dist/adapters/eslint.js +4 -2
- package/dist/adapters/npmAudit.js +1 -1
- package/dist/cli.js +82 -45
- package/dist/extractors/bucketing.js +14 -35
- package/dist/extractors/disposition.js +8 -9
- package/dist/extractors/fileInventory.js +0 -2
- package/dist/extractors/flows.js +14 -23
- package/dist/extractors/fsIntake.js +4 -1
- package/dist/extractors/pathPatterns.d.ts +19 -0
- package/dist/extractors/pathPatterns.js +91 -0
- package/dist/extractors/surfaces.js +2 -7
- package/dist/io/artifacts.d.ts +23 -1
- package/dist/io/artifacts.js +4 -3
- package/dist/io/runArtifacts.js +1 -1
- package/dist/orchestrator/advance.js +53 -71
- package/dist/orchestrator/flowCoverage.js +1 -2
- package/dist/orchestrator/internalExecutors.js +4 -6
- package/dist/orchestrator/planning.js +12 -20
- package/dist/orchestrator/resultIngestion.js +3 -2
- package/dist/orchestrator/runtimeValidation.js +5 -0
- package/dist/orchestrator/syntaxResolutionExecutor.js +10 -2
- package/dist/orchestrator/taskBuilder.js +15 -28
- package/dist/prompts/renderWorkerPrompt.js +2 -1
- package/dist/providers/claudeCodeProvider.js +1 -2
- package/dist/providers/constants.d.ts +1 -0
- package/dist/providers/constants.js +1 -0
- package/dist/providers/index.js +7 -3
- package/dist/providers/opencodeProvider.js +1 -6
- package/dist/providers/spawnLoggedCommand.js +4 -0
- package/dist/providers/types.d.ts +0 -1
- package/dist/supervisor/operatorHandoff.d.ts +2 -0
- package/dist/supervisor/operatorHandoff.js +21 -9
- package/dist/supervisor/runLedger.js +7 -8
- package/dist/supervisor/sessionConfig.js +1 -0
- package/dist/types/flowCoverage.d.ts +1 -1
- package/dist/types/runLedger.d.ts +1 -1
- package/dist/types/runtimeValidation.d.ts +2 -1
- package/dist/types/sessionConfig.d.ts +0 -6
- package/dist/types/surfaces.d.ts +2 -1
- package/dist/types/workerSession.d.ts +2 -0
- package/dist/types.d.ts +0 -1
- package/dist/validation/sessionConfig.js +1 -15
- package/package.json +1 -1
- package/schemas/audit-code-v1alpha1.schema.json +4 -0
- package/schemas/audit_result.schema.json +9 -3
- package/schemas/audit_state.schema.json +2 -2
- package/schemas/audit_task.schema.json +14 -3
- package/schemas/blind_spot_register.schema.json +13 -3
- package/schemas/coverage_matrix.schema.json +16 -4
- package/schemas/critical_flows.schema.json +6 -3
- package/schemas/external_analyzer_results.schema.json +10 -4
- package/schemas/finding.schema.json +31 -3
- package/schemas/flow_coverage.schema.json +12 -3
- package/schemas/graph_bundle.schema.json +12 -6
- package/schemas/merged_findings.schema.json +7 -2
- package/schemas/risk_register.schema.json +5 -1
- package/schemas/root_cause_clusters.schema.json +2 -1
- package/schemas/runtime_validation_tasks.schema.json +4 -1
- package/schemas/surface_manifest.schema.json +4 -1
- package/schemas/unit_manifest.schema.json +10 -3
- package/skills/audit-code/audit-code.prompt.md +0 -2
|
@@ -1,42 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readdir,
|
|
7
|
-
stat,
|
|
8
|
-
unlink,
|
|
9
|
-
writeFile,
|
|
10
|
-
} from "node:fs/promises";
|
|
11
|
-
import { constants } from "node:fs";
|
|
12
|
-
import { spawn } from "node:child_process";
|
|
13
|
-
import { dirname, join, relative, resolve } from "node:path";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
1
|
+
import { access, mkdir, open, readFile, readdir, stat, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { constants } from 'node:fs';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
15
6
|
|
|
16
7
|
const repoRoot = dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
const distEntry = join(repoRoot,
|
|
18
|
-
const packageJsonPath = join(repoRoot,
|
|
19
|
-
const promptAssetPath = join(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
25
|
-
const skillAssetPath = join(repoRoot, "skills", "audit-code", "SKILL.md");
|
|
26
|
-
const tsconfigPath = join(repoRoot, "tsconfig.json");
|
|
27
|
-
const sourceRoot = join(repoRoot, "src");
|
|
28
|
-
const buildLockPath = join(repoRoot, ".audit-code-build.lock");
|
|
8
|
+
const distEntry = join(repoRoot, 'dist', 'index.js');
|
|
9
|
+
const packageJsonPath = join(repoRoot, 'package.json');
|
|
10
|
+
const promptAssetPath = join(repoRoot, 'skills', 'audit-code', 'audit-code.prompt.md');
|
|
11
|
+
const skillAssetPath = join(repoRoot, 'skills', 'audit-code', 'SKILL.md');
|
|
12
|
+
const tsconfigPath = join(repoRoot, 'tsconfig.json');
|
|
13
|
+
const sourceRoot = join(repoRoot, 'src');
|
|
14
|
+
const buildLockPath = join(repoRoot, '.audit-code-build.lock');
|
|
29
15
|
const BUILD_LOCK_MAX_AGE_MS = 5 * 60 * 1000;
|
|
30
16
|
const BUILD_LOCK_WAIT_TIMEOUT_MS = 2 * 60 * 1000;
|
|
31
17
|
const BUILD_LOCK_WAIT_INTERVAL_MS = 200;
|
|
32
|
-
const INSTALL_MARKER_START =
|
|
33
|
-
const INSTALL_MARKER_END =
|
|
34
|
-
const INSTALL_GUIDE_FILENAME =
|
|
35
|
-
const DEFAULT_INSTALL_HOST =
|
|
36
|
-
const INSTALLED_PROMPT_FILENAME =
|
|
37
|
-
const packageVersion = JSON.parse(
|
|
38
|
-
await readFile(packageJsonPath, "utf8"),
|
|
39
|
-
).version;
|
|
18
|
+
const INSTALL_MARKER_START = '<!-- audit-code:begin -->';
|
|
19
|
+
const INSTALL_MARKER_END = '<!-- audit-code:end -->';
|
|
20
|
+
const INSTALL_GUIDE_FILENAME = 'GETTING-STARTED.md';
|
|
21
|
+
const DEFAULT_INSTALL_HOST = 'all';
|
|
22
|
+
const INSTALLED_PROMPT_FILENAME = 'audit-code.import.md';
|
|
23
|
+
const packageVersion = JSON.parse(await readFile(packageJsonPath, 'utf8')).version;
|
|
40
24
|
|
|
41
25
|
function hasFlag(argv, name) {
|
|
42
26
|
return argv.includes(name);
|
|
@@ -63,7 +47,7 @@ function requireFlagValue(argv, name) {
|
|
|
63
47
|
}
|
|
64
48
|
|
|
65
49
|
function npmExecutable() {
|
|
66
|
-
return process.platform ===
|
|
50
|
+
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
67
51
|
}
|
|
68
52
|
|
|
69
53
|
function nodeExecutable() {
|
|
@@ -77,13 +61,13 @@ function quoteForCmd(arg) {
|
|
|
77
61
|
}
|
|
78
62
|
|
|
79
63
|
function resolveSpawn(command, args) {
|
|
80
|
-
if (!(process.platform ===
|
|
64
|
+
if (!(process.platform === 'win32' && /\.(cmd|bat)$/i.test(command))) {
|
|
81
65
|
return { command, args };
|
|
82
66
|
}
|
|
83
67
|
|
|
84
68
|
return {
|
|
85
|
-
command: process.env.ComSpec ??
|
|
86
|
-
args: [
|
|
69
|
+
command: process.env.ComSpec ?? 'cmd.exe',
|
|
70
|
+
args: ['/d', '/s', '/c', [command, ...args].map(quoteForCmd).join(' ')],
|
|
87
71
|
};
|
|
88
72
|
}
|
|
89
73
|
|
|
@@ -92,35 +76,29 @@ function run(command, args, options = {}) {
|
|
|
92
76
|
const resolved = resolveSpawn(command, args);
|
|
93
77
|
const child = spawn(resolved.command, resolved.args, {
|
|
94
78
|
cwd: repoRoot,
|
|
95
|
-
stdio: options.capture ? [
|
|
96
|
-
env: process.env
|
|
79
|
+
stdio: options.capture ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
80
|
+
env: process.env
|
|
97
81
|
});
|
|
98
82
|
|
|
99
|
-
let stdout =
|
|
100
|
-
let stderr =
|
|
83
|
+
let stdout = '';
|
|
84
|
+
let stderr = '';
|
|
101
85
|
|
|
102
86
|
if (options.capture) {
|
|
103
|
-
child.stdout?.on(
|
|
87
|
+
child.stdout?.on('data', (chunk) => {
|
|
104
88
|
stdout += String(chunk);
|
|
105
89
|
});
|
|
106
|
-
child.stderr?.on(
|
|
90
|
+
child.stderr?.on('data', (chunk) => {
|
|
107
91
|
stderr += String(chunk);
|
|
108
92
|
});
|
|
109
93
|
}
|
|
110
94
|
|
|
111
|
-
child.on(
|
|
112
|
-
child.on(
|
|
95
|
+
child.on('error', rejectPromise);
|
|
96
|
+
child.on('exit', (code) => {
|
|
113
97
|
if (code === 0) {
|
|
114
98
|
resolvePromise({ stdout, stderr });
|
|
115
99
|
return;
|
|
116
100
|
}
|
|
117
|
-
rejectPromise(
|
|
118
|
-
new Error(
|
|
119
|
-
options.capture
|
|
120
|
-
? stderr || `Command failed with exit code ${code}.`
|
|
121
|
-
: `Command failed with exit code ${code}.`,
|
|
122
|
-
),
|
|
123
|
-
);
|
|
101
|
+
rejectPromise(new Error(options.capture ? stderr || `Command failed with exit code ${code}.` : `Command failed with exit code ${code}.`));
|
|
124
102
|
});
|
|
125
103
|
});
|
|
126
104
|
}
|
|
@@ -163,7 +141,7 @@ async function shouldBuildDist() {
|
|
|
163
141
|
if (!(await fileExists(distEntry))) {
|
|
164
142
|
if (!(await fileExists(sourceRoot)) || !(await fileExists(tsconfigPath))) {
|
|
165
143
|
throw new Error(
|
|
166
|
-
|
|
144
|
+
'Bundled dist is missing and source files are unavailable for rebuild.',
|
|
167
145
|
);
|
|
168
146
|
}
|
|
169
147
|
return true;
|
|
@@ -208,16 +186,11 @@ async function waitForPeerBuild() {
|
|
|
208
186
|
async function acquireBuildLock() {
|
|
209
187
|
while (true) {
|
|
210
188
|
try {
|
|
211
|
-
const handle = await open(buildLockPath,
|
|
212
|
-
await handle.writeFile(
|
|
213
|
-
JSON.stringify({
|
|
214
|
-
pid: process.pid,
|
|
215
|
-
acquired_at: new Date().toISOString(),
|
|
216
|
-
}),
|
|
217
|
-
);
|
|
189
|
+
const handle = await open(buildLockPath, 'wx');
|
|
190
|
+
await handle.writeFile(JSON.stringify({ pid: process.pid, acquired_at: new Date().toISOString() }));
|
|
218
191
|
return handle;
|
|
219
192
|
} catch (error) {
|
|
220
|
-
if (error && error.code ===
|
|
193
|
+
if (error && error.code === 'EEXIST') {
|
|
221
194
|
try {
|
|
222
195
|
const lockStats = await stat(buildLockPath);
|
|
223
196
|
if (Date.now() - lockStats.mtimeMs > BUILD_LOCK_MAX_AGE_MS) {
|
|
@@ -253,7 +226,7 @@ async function ensureBuilt() {
|
|
|
253
226
|
if (!(await shouldBuildDist())) {
|
|
254
227
|
return;
|
|
255
228
|
}
|
|
256
|
-
await run(npmExecutable(), [
|
|
229
|
+
await run(npmExecutable(), ['run', 'build']);
|
|
257
230
|
} finally {
|
|
258
231
|
await releaseBuildLock(lockHandle);
|
|
259
232
|
}
|
|
@@ -262,33 +235,33 @@ async function ensureBuilt() {
|
|
|
262
235
|
function printHelp({ usageName, preferredEntrypoint }) {
|
|
263
236
|
const lines = [
|
|
264
237
|
`Usage: node ${usageName} [--single-step] [--root PATH] [--artifacts-dir PATH] [--results FILE] [--updates FILE] [--external-analyzer-results FILE]`,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
238
|
+
'',
|
|
239
|
+
'Helper commands:',
|
|
240
|
+
'- prompt-path prints the absolute path to the canonical /audit-code prompt asset',
|
|
241
|
+
'- install bootstraps /audit-code into supported repo-local host surfaces',
|
|
242
|
+
'- install-host --host copilot keeps the narrower Copilot-focused install path available',
|
|
243
|
+
'- validate checks the current artifact bundle plus session-config/provider readiness and exits non-zero when issues exist',
|
|
244
|
+
'',
|
|
245
|
+
'Primary usage:',
|
|
246
|
+
'- from the repository root, run the wrapper with no arguments',
|
|
247
|
+
'- default behavior advances the audit automatically until it completes or no further automatic progress is possible',
|
|
248
|
+
'- each wrapper response refreshes operator-handoff.json and operator-handoff.md under the artifacts directory',
|
|
249
|
+
'- use --single-step only for debugging or bounded-step testing',
|
|
250
|
+
'',
|
|
251
|
+
'Defaults:',
|
|
252
|
+
'- --root .',
|
|
253
|
+
'- --artifacts-dir <root>/.audit-artifacts',
|
|
254
|
+
'',
|
|
255
|
+
'Completion signals:',
|
|
256
|
+
'- done: audit_state.status is complete',
|
|
257
|
+
'- blocked/no further automatic progress: progress_made is false and next_likely_step is null'
|
|
285
258
|
];
|
|
286
259
|
|
|
287
260
|
if (preferredEntrypoint && preferredEntrypoint !== usageName) {
|
|
288
|
-
lines.push(
|
|
261
|
+
lines.push('', `Preferred entrypoint: node ${preferredEntrypoint}`);
|
|
289
262
|
}
|
|
290
263
|
|
|
291
|
-
console.log(lines.join(
|
|
264
|
+
console.log(lines.join('\n'));
|
|
292
265
|
}
|
|
293
266
|
|
|
294
267
|
async function printPromptPath() {
|
|
@@ -300,7 +273,7 @@ async function printPromptPath() {
|
|
|
300
273
|
}
|
|
301
274
|
|
|
302
275
|
function normalizeNewlines(value) {
|
|
303
|
-
return value.replace(/\r\n/g,
|
|
276
|
+
return value.replace(/\r\n/g, '\n');
|
|
304
277
|
}
|
|
305
278
|
|
|
306
279
|
function splitFrontmatter(markdown) {
|
|
@@ -322,22 +295,22 @@ function renderFrontmatter(fields) {
|
|
|
322
295
|
return false;
|
|
323
296
|
}
|
|
324
297
|
|
|
325
|
-
if (typeof value ===
|
|
298
|
+
if (typeof value === 'string') {
|
|
326
299
|
return value.length > 0;
|
|
327
300
|
}
|
|
328
301
|
|
|
329
302
|
return true;
|
|
330
303
|
});
|
|
331
304
|
if (entries.length === 0) {
|
|
332
|
-
return
|
|
305
|
+
return '';
|
|
333
306
|
}
|
|
334
307
|
|
|
335
308
|
return [
|
|
336
|
-
|
|
309
|
+
'---',
|
|
337
310
|
...entries.map(([key, value]) => `${key}: ${value}`),
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
].join(
|
|
311
|
+
'---',
|
|
312
|
+
'',
|
|
313
|
+
].join('\n');
|
|
341
314
|
}
|
|
342
315
|
|
|
343
316
|
function renderPromptFile(fields, body) {
|
|
@@ -345,19 +318,19 @@ function renderPromptFile(fields, body) {
|
|
|
345
318
|
}
|
|
346
319
|
|
|
347
320
|
function toRepoRelativePath(root, targetPath) {
|
|
348
|
-
const value = relative(root, targetPath).replace(/\\/g,
|
|
349
|
-
return value.length > 0 ? value :
|
|
321
|
+
const value = relative(root, targetPath).replace(/\\/g, '/');
|
|
322
|
+
return value.length > 0 ? value : '.';
|
|
350
323
|
}
|
|
351
324
|
|
|
352
325
|
function buildInstallDirective(relativePromptPath) {
|
|
353
326
|
return [
|
|
354
327
|
INSTALL_MARKER_START,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
`If your host does not automatically register the installed slash command file, load and follow [the repo-local audit directive](${relativePromptPath.replace(/\\/g,
|
|
358
|
-
|
|
328
|
+
'## /audit-code',
|
|
329
|
+
'When the user enters `/audit-code`, treat it as this repository\'s autonomous audit workflow.',
|
|
330
|
+
`If your host does not automatically register the installed slash command file, load and follow [the repo-local audit directive](${relativePromptPath.replace(/\\/g, '/')}).`,
|
|
331
|
+
'Normal usage should stay conversation-first and avoid manual `--root`, provider flags, or model-selection arguments.',
|
|
359
332
|
INSTALL_MARKER_END,
|
|
360
|
-
].join(
|
|
333
|
+
].join('\n');
|
|
361
334
|
}
|
|
362
335
|
|
|
363
336
|
function buildInstallHostGuidance({
|
|
@@ -369,90 +342,90 @@ function buildInstallHostGuidance({
|
|
|
369
342
|
|
|
370
343
|
if (slashCommandSurfaces.vscode_prompt) {
|
|
371
344
|
guidance.push({
|
|
372
|
-
host:
|
|
373
|
-
label:
|
|
374
|
-
support_level:
|
|
375
|
-
setup_kind:
|
|
345
|
+
host: 'vscode',
|
|
346
|
+
label: 'VS Code',
|
|
347
|
+
support_level: 'supported',
|
|
348
|
+
setup_kind: 'repo-local-slash-command',
|
|
376
349
|
summary:
|
|
377
|
-
|
|
350
|
+
'Use the generated VS Code / Copilot prompt surface, then invoke `/audit-code` in chat.',
|
|
378
351
|
primary_path: slashCommandSurfaces.vscode_prompt,
|
|
379
352
|
supporting_paths: [
|
|
380
353
|
instructionSurfaces.copilot_instructions,
|
|
381
354
|
instructionSurfaces.agents,
|
|
382
355
|
].filter(Boolean),
|
|
383
356
|
steps: [
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
357
|
+
'Open this repository in VS Code or GitHub Copilot Chat.',
|
|
358
|
+
'Invoke `/audit-code` in chat.',
|
|
359
|
+
'Use the integrated terminal and run `audit-code` only when you intentionally need the repo-local backend fallback.',
|
|
387
360
|
],
|
|
388
361
|
});
|
|
389
362
|
}
|
|
390
363
|
|
|
391
364
|
if (slashCommandSurfaces.opencode_command) {
|
|
392
365
|
guidance.push({
|
|
393
|
-
host:
|
|
394
|
-
label:
|
|
395
|
-
support_level:
|
|
396
|
-
setup_kind:
|
|
366
|
+
host: 'opencode',
|
|
367
|
+
label: 'OpenCode',
|
|
368
|
+
support_level: 'supported',
|
|
369
|
+
setup_kind: 'repo-local-slash-command',
|
|
397
370
|
summary:
|
|
398
|
-
|
|
371
|
+
'Use the generated OpenCode command surface so `/audit-code` is available without extra provider flags.',
|
|
399
372
|
primary_path: slashCommandSurfaces.opencode_command,
|
|
400
373
|
supporting_paths: [instructionSurfaces.agents].filter(Boolean),
|
|
401
374
|
steps: [
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
375
|
+
'Open this repository in OpenCode.',
|
|
376
|
+
'Invoke `/audit-code` from the OpenCode command surface.',
|
|
377
|
+
'Use the repo-local backend wrapper only when you intentionally need the fallback automation path.',
|
|
405
378
|
],
|
|
406
379
|
});
|
|
407
380
|
}
|
|
408
381
|
|
|
409
382
|
if (slashCommandSurfaces.claude_code_command) {
|
|
410
383
|
guidance.push({
|
|
411
|
-
host:
|
|
412
|
-
label:
|
|
413
|
-
support_level:
|
|
414
|
-
setup_kind:
|
|
384
|
+
host: 'claude-code',
|
|
385
|
+
label: 'Claude Code',
|
|
386
|
+
support_level: 'supported',
|
|
387
|
+
setup_kind: 'repo-local-slash-command',
|
|
415
388
|
summary:
|
|
416
|
-
|
|
389
|
+
'Use the generated Claude Code command surface so `/audit-code` is available inside the repository without extra provider wiring.',
|
|
417
390
|
primary_path: slashCommandSurfaces.claude_code_command,
|
|
418
391
|
supporting_paths: [instructionSurfaces.claude].filter(Boolean),
|
|
419
392
|
steps: [
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
393
|
+
'Open this repository in Claude Code.',
|
|
394
|
+
'Invoke `/audit-code` from the Claude Code project command surface.',
|
|
395
|
+
'Use the terminal fallback and run `audit-code` only when you intentionally need the repo-local backend wrapper.',
|
|
423
396
|
],
|
|
424
397
|
});
|
|
425
398
|
}
|
|
426
399
|
|
|
427
400
|
guidance.push({
|
|
428
|
-
host:
|
|
429
|
-
label:
|
|
430
|
-
support_level:
|
|
431
|
-
setup_kind:
|
|
401
|
+
host: 'claude-desktop',
|
|
402
|
+
label: 'Claude Desktop',
|
|
403
|
+
support_level: 'manual-import',
|
|
404
|
+
setup_kind: 'prompt-import',
|
|
432
405
|
summary:
|
|
433
|
-
|
|
406
|
+
'No verified project-local slash-command surface is shipped for Claude Desktop, so use the installed prompt asset as the primary path.',
|
|
434
407
|
primary_path: installedPromptPath,
|
|
435
408
|
supporting_paths: [instructionSurfaces.claude].filter(Boolean),
|
|
436
409
|
steps: [
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
410
|
+
'Import the installed prompt asset into Claude Desktop\'s prompt or instruction surface.',
|
|
411
|
+
'Invoke `/audit-code` conversationally inside Claude Desktop after the prompt is available.',
|
|
412
|
+
'If you intentionally need the repo-local backend fallback instead, run `audit-code` from the repository root.',
|
|
440
413
|
],
|
|
441
414
|
});
|
|
442
415
|
|
|
443
416
|
guidance.push({
|
|
444
|
-
host:
|
|
445
|
-
label:
|
|
446
|
-
support_level:
|
|
447
|
-
setup_kind:
|
|
417
|
+
host: 'antigravity',
|
|
418
|
+
label: 'Antigravity',
|
|
419
|
+
support_level: 'manual-import',
|
|
420
|
+
setup_kind: 'prompt-import-or-terminal',
|
|
448
421
|
summary:
|
|
449
|
-
|
|
422
|
+
'No verified repo-local slash-command surface is shipped for Antigravity, so start from the installed prompt asset or an Antigravity-managed terminal.',
|
|
450
423
|
primary_path: installedPromptPath,
|
|
451
424
|
supporting_paths: [instructionSurfaces.agents].filter(Boolean),
|
|
452
425
|
steps: [
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
426
|
+
'Import the installed prompt asset into Antigravity\'s prompt or instruction surface when that surface is available.',
|
|
427
|
+
'Invoke `/audit-code` conversationally inside Antigravity.',
|
|
428
|
+
'If you prefer the backend fallback, run `audit-code` from an Antigravity-managed terminal with `local-subprocess` first.',
|
|
456
429
|
],
|
|
457
430
|
});
|
|
458
431
|
|
|
@@ -462,30 +435,30 @@ function buildInstallHostGuidance({
|
|
|
462
435
|
function renderInstallHostSection(root, guide) {
|
|
463
436
|
const lines = [
|
|
464
437
|
`## ${guide.label}`,
|
|
465
|
-
|
|
438
|
+
'',
|
|
466
439
|
`Support level: ${guide.support_level}`,
|
|
467
440
|
`Setup kind: ${guide.setup_kind}`,
|
|
468
|
-
|
|
441
|
+
'',
|
|
469
442
|
guide.summary,
|
|
470
|
-
|
|
471
|
-
|
|
443
|
+
'',
|
|
444
|
+
'Primary repo-local path:',
|
|
472
445
|
`- \`${toRepoRelativePath(root, guide.primary_path)}\``,
|
|
473
446
|
];
|
|
474
447
|
|
|
475
448
|
if (guide.supporting_paths.length > 0) {
|
|
476
|
-
lines.push(
|
|
449
|
+
lines.push('', 'Supporting repo-local paths:');
|
|
477
450
|
for (const targetPath of guide.supporting_paths) {
|
|
478
451
|
lines.push(`- \`${toRepoRelativePath(root, targetPath)}\``);
|
|
479
452
|
}
|
|
480
453
|
}
|
|
481
454
|
|
|
482
|
-
lines.push(
|
|
455
|
+
lines.push('', 'Recommended steps:');
|
|
483
456
|
for (const step of guide.steps) {
|
|
484
457
|
lines.push(`- ${step}`);
|
|
485
458
|
}
|
|
486
|
-
lines.push(
|
|
459
|
+
lines.push('');
|
|
487
460
|
|
|
488
|
-
return lines.join(
|
|
461
|
+
return lines.join('\n');
|
|
489
462
|
}
|
|
490
463
|
|
|
491
464
|
function renderInstallGuide({
|
|
@@ -501,67 +474,67 @@ function renderInstallGuide({
|
|
|
501
474
|
const slashCommandPaths = Object.values(slashCommandSurfaces).filter(Boolean);
|
|
502
475
|
const instructionPaths = Object.values(instructionSurfaces).filter(Boolean);
|
|
503
476
|
const lines = [
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
477
|
+
'# audit-code bootstrap guide',
|
|
478
|
+
'',
|
|
479
|
+
'The canonical product route is `/audit-code` in conversation.',
|
|
480
|
+
'',
|
|
481
|
+
'Canonical installed assets:',
|
|
509
482
|
`- prompt asset: \`${toRepoRelativePath(root, installedPromptPath)}\``,
|
|
510
483
|
`- skill asset: \`${toRepoRelativePath(root, installedSkillPath)}\``,
|
|
511
484
|
];
|
|
512
485
|
|
|
513
486
|
if (slashCommandPaths.length > 0) {
|
|
514
|
-
lines.push(
|
|
487
|
+
lines.push('', 'Repo-local slash-command surfaces:');
|
|
515
488
|
for (const targetPath of slashCommandPaths) {
|
|
516
489
|
lines.push(`- \`${toRepoRelativePath(root, targetPath)}\``);
|
|
517
490
|
}
|
|
518
491
|
}
|
|
519
492
|
|
|
520
493
|
if (instructionPaths.length > 0) {
|
|
521
|
-
lines.push(
|
|
494
|
+
lines.push('', 'Compatibility instruction surfaces:');
|
|
522
495
|
for (const targetPath of instructionPaths) {
|
|
523
496
|
lines.push(`- \`${toRepoRelativePath(root, targetPath)}\``);
|
|
524
497
|
}
|
|
525
498
|
}
|
|
526
499
|
|
|
527
|
-
lines.push(
|
|
500
|
+
lines.push('', 'Host-specific quick starts:');
|
|
528
501
|
for (const guide of hostGuidance) {
|
|
529
502
|
lines.push(`- ${guide.label}: ${guide.summary}`);
|
|
530
503
|
}
|
|
531
504
|
|
|
532
505
|
for (const guide of hostGuidance) {
|
|
533
|
-
lines.push(
|
|
506
|
+
lines.push('', renderInstallHostSection(root, guide).trimEnd());
|
|
534
507
|
}
|
|
535
508
|
|
|
536
509
|
lines.push(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
510
|
+
'',
|
|
511
|
+
'Backend fallback:',
|
|
512
|
+
'- from the repository root, run `audit-code` only when you intentionally need the repo-local backend wrapper',
|
|
540
513
|
);
|
|
541
514
|
|
|
542
515
|
if (unsupportedHosts.length > 0) {
|
|
543
|
-
lines.push(
|
|
516
|
+
lines.push('', 'Hosts still requiring extra handling today:');
|
|
544
517
|
for (const item of unsupportedHosts) {
|
|
545
518
|
lines.push(`- ${item.host}: ${item.reason}`);
|
|
546
519
|
}
|
|
547
520
|
}
|
|
548
521
|
|
|
549
|
-
if (host !==
|
|
522
|
+
if (host !== 'all') {
|
|
550
523
|
lines.push(
|
|
551
|
-
|
|
524
|
+
'',
|
|
552
525
|
`This install was scoped to \`${host}\`, so some repo-local surfaces may be intentionally omitted.`,
|
|
553
526
|
);
|
|
554
527
|
}
|
|
555
528
|
|
|
556
|
-
lines.push(
|
|
557
|
-
return lines.join(
|
|
529
|
+
lines.push('');
|
|
530
|
+
return lines.join('\n');
|
|
558
531
|
}
|
|
559
532
|
|
|
560
533
|
function upsertManagedBlock(existingContent, blockContent) {
|
|
561
534
|
const normalized = normalizeNewlines(existingContent);
|
|
562
535
|
const blockPattern = new RegExp(
|
|
563
536
|
`${INSTALL_MARKER_START}[\\s\\S]*?${INSTALL_MARKER_END}`,
|
|
564
|
-
|
|
537
|
+
'u',
|
|
565
538
|
);
|
|
566
539
|
|
|
567
540
|
if (blockPattern.test(normalized)) {
|
|
@@ -572,34 +545,34 @@ function upsertManagedBlock(existingContent, blockContent) {
|
|
|
572
545
|
return `${blockContent}\n`;
|
|
573
546
|
}
|
|
574
547
|
|
|
575
|
-
return `${normalized.replace(/\s+$/u,
|
|
548
|
+
return `${normalized.replace(/\s+$/u, '')}\n\n${blockContent}\n`;
|
|
576
549
|
}
|
|
577
550
|
|
|
578
551
|
async function writeManagedMarkdown(targetPath, blockContent) {
|
|
579
552
|
const existed = await fileExists(targetPath);
|
|
580
|
-
const existingContent = existed ? await readFile(targetPath,
|
|
553
|
+
const existingContent = existed ? await readFile(targetPath, 'utf8') : '';
|
|
581
554
|
const nextContent = upsertManagedBlock(existingContent, blockContent);
|
|
582
555
|
await mkdir(dirname(targetPath), { recursive: true });
|
|
583
|
-
await writeFile(targetPath, nextContent,
|
|
556
|
+
await writeFile(targetPath, nextContent, 'utf8');
|
|
584
557
|
return {
|
|
585
558
|
path: targetPath,
|
|
586
|
-
mode: existed ?
|
|
559
|
+
mode: existed ? 'updated' : 'created',
|
|
587
560
|
};
|
|
588
561
|
}
|
|
589
562
|
|
|
590
563
|
async function writeGeneratedMarkdown(targetPath, content) {
|
|
591
564
|
const existed = await fileExists(targetPath);
|
|
592
565
|
await mkdir(dirname(targetPath), { recursive: true });
|
|
593
|
-
await writeFile(targetPath, content,
|
|
566
|
+
await writeFile(targetPath, content, 'utf8');
|
|
594
567
|
return {
|
|
595
568
|
path: targetPath,
|
|
596
|
-
mode: existed ?
|
|
569
|
+
mode: existed ? 'updated' : 'created',
|
|
597
570
|
};
|
|
598
571
|
}
|
|
599
572
|
|
|
600
573
|
function getInstallProfile(host) {
|
|
601
574
|
switch (host) {
|
|
602
|
-
case
|
|
575
|
+
case 'all':
|
|
603
576
|
return {
|
|
604
577
|
writeVSCodePrompt: true,
|
|
605
578
|
writeCopilotInstructions: true,
|
|
@@ -609,7 +582,7 @@ function getInstallProfile(host) {
|
|
|
609
582
|
writeClaudeCommand: true,
|
|
610
583
|
writeCompatibilitySkills: true,
|
|
611
584
|
};
|
|
612
|
-
case
|
|
585
|
+
case 'copilot':
|
|
613
586
|
return {
|
|
614
587
|
writeVSCodePrompt: true,
|
|
615
588
|
writeCopilotInstructions: true,
|
|
@@ -619,7 +592,7 @@ function getInstallProfile(host) {
|
|
|
619
592
|
writeClaudeCommand: false,
|
|
620
593
|
writeCompatibilitySkills: false,
|
|
621
594
|
};
|
|
622
|
-
case
|
|
595
|
+
case 'vscode':
|
|
623
596
|
return {
|
|
624
597
|
writeVSCodePrompt: true,
|
|
625
598
|
writeCopilotInstructions: true,
|
|
@@ -629,7 +602,7 @@ function getInstallProfile(host) {
|
|
|
629
602
|
writeClaudeCommand: false,
|
|
630
603
|
writeCompatibilitySkills: false,
|
|
631
604
|
};
|
|
632
|
-
case
|
|
605
|
+
case 'opencode':
|
|
633
606
|
return {
|
|
634
607
|
writeVSCodePrompt: false,
|
|
635
608
|
writeCopilotInstructions: false,
|
|
@@ -639,7 +612,7 @@ function getInstallProfile(host) {
|
|
|
639
612
|
writeClaudeCommand: false,
|
|
640
613
|
writeCompatibilitySkills: true,
|
|
641
614
|
};
|
|
642
|
-
case
|
|
615
|
+
case 'claude-code':
|
|
643
616
|
return {
|
|
644
617
|
writeVSCodePrompt: false,
|
|
645
618
|
writeCopilotInstructions: false,
|
|
@@ -670,65 +643,49 @@ async function assertDirectoryExists(path, description) {
|
|
|
670
643
|
}
|
|
671
644
|
|
|
672
645
|
async function installBootstrap(argv) {
|
|
673
|
-
const host = (getFlag(argv,
|
|
674
|
-
const root = resolve(getFlag(argv,
|
|
675
|
-
await assertDirectoryExists(root,
|
|
646
|
+
const host = (getFlag(argv, '--host') ?? DEFAULT_INSTALL_HOST).toLowerCase();
|
|
647
|
+
const root = resolve(getFlag(argv, '--root') ?? '.');
|
|
648
|
+
await assertDirectoryExists(root, 'Target repository root');
|
|
676
649
|
const profile = getInstallProfile(host);
|
|
677
|
-
const promptSource = await readFile(promptAssetPath,
|
|
678
|
-
const skillSource = await readFile(skillAssetPath,
|
|
650
|
+
const promptSource = await readFile(promptAssetPath, 'utf8');
|
|
651
|
+
const skillSource = (await readFile(skillAssetPath, 'utf8')).replace(/\r\n/g, '\n');
|
|
679
652
|
const { body: promptBody } = splitFrontmatter(promptSource);
|
|
680
|
-
const installedPromptPath = join(
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
INSTALLED_PROMPT_FILENAME,
|
|
685
|
-
);
|
|
686
|
-
const legacyInstalledPromptPath = join(
|
|
687
|
-
root,
|
|
688
|
-
".audit-code",
|
|
689
|
-
"install",
|
|
690
|
-
"audit-code.prompt.md",
|
|
691
|
-
);
|
|
692
|
-
const installedSkillPath = join(root, ".audit-code", "install", "SKILL.md");
|
|
693
|
-
const installGuidePath = join(
|
|
694
|
-
root,
|
|
695
|
-
".audit-code",
|
|
696
|
-
"install",
|
|
697
|
-
INSTALL_GUIDE_FILENAME,
|
|
698
|
-
);
|
|
653
|
+
const installedPromptPath = join(root, '.audit-code', 'install', INSTALLED_PROMPT_FILENAME);
|
|
654
|
+
const legacyInstalledPromptPath = join(root, '.audit-code', 'install', 'audit-code.prompt.md');
|
|
655
|
+
const installedSkillPath = join(root, '.audit-code', 'install', 'SKILL.md');
|
|
656
|
+
const installGuidePath = join(root, '.audit-code', 'install', INSTALL_GUIDE_FILENAME);
|
|
699
657
|
const slashCommandSurfaces = {
|
|
700
658
|
vscode_prompt: profile.writeVSCodePrompt
|
|
701
|
-
? join(root,
|
|
659
|
+
? join(root, '.github', 'prompts', 'audit-code.prompt.md')
|
|
702
660
|
: null,
|
|
703
661
|
opencode_command: profile.writeOpenCodeCommand
|
|
704
|
-
? join(root,
|
|
662
|
+
? join(root, '.opencode', 'commands', 'audit-code.md')
|
|
705
663
|
: null,
|
|
706
664
|
claude_code_command: profile.writeClaudeCommand
|
|
707
|
-
? join(root,
|
|
665
|
+
? join(root, '.claude', 'commands', 'audit-code.md')
|
|
708
666
|
: null,
|
|
709
667
|
};
|
|
710
668
|
const instructionSurfaces = {
|
|
711
669
|
copilot_instructions: profile.writeCopilotInstructions
|
|
712
|
-
? join(root,
|
|
670
|
+
? join(root, '.github', 'copilot-instructions.md')
|
|
713
671
|
: null,
|
|
714
|
-
agents: profile.writeAgents ? join(root,
|
|
715
|
-
claude: profile.writeClaudeMemory ? join(root,
|
|
672
|
+
agents: profile.writeAgents ? join(root, 'AGENTS.md') : null,
|
|
673
|
+
claude: profile.writeClaudeMemory ? join(root, 'CLAUDE.md') : null,
|
|
716
674
|
};
|
|
717
|
-
const unsupportedHosts =
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
: [];
|
|
675
|
+
const unsupportedHosts = host === 'all'
|
|
676
|
+
? [
|
|
677
|
+
{
|
|
678
|
+
host: 'claude-desktop',
|
|
679
|
+
reason:
|
|
680
|
+
'No verified project-local slash-command installation surface is currently shipped for Claude Desktop.',
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
host: 'antigravity',
|
|
684
|
+
reason:
|
|
685
|
+
'No verified repo-local slash-command installation surface is currently shipped for Antigravity.',
|
|
686
|
+
},
|
|
687
|
+
]
|
|
688
|
+
: [];
|
|
732
689
|
const hostGuidance = buildInstallHostGuidance({
|
|
733
690
|
installedPromptPath,
|
|
734
691
|
slashCommandSurfaces,
|
|
@@ -739,18 +696,23 @@ async function installBootstrap(argv) {
|
|
|
739
696
|
if (await fileExists(legacyInstalledPromptPath)) {
|
|
740
697
|
await unlink(legacyInstalledPromptPath).catch(() => {});
|
|
741
698
|
}
|
|
742
|
-
results.push(
|
|
699
|
+
results.push(
|
|
700
|
+
await writeGeneratedMarkdown(
|
|
701
|
+
installedPromptPath,
|
|
702
|
+
promptSource,
|
|
703
|
+
),
|
|
704
|
+
);
|
|
743
705
|
results.push(await writeGeneratedMarkdown(installedSkillPath, skillSource));
|
|
744
706
|
|
|
745
707
|
if (profile.writeVSCodePrompt) {
|
|
746
708
|
results.push(
|
|
747
709
|
await writeGeneratedMarkdown(
|
|
748
|
-
join(root,
|
|
710
|
+
join(root, '.github', 'prompts', 'audit-code.prompt.md'),
|
|
749
711
|
renderPromptFile(
|
|
750
712
|
{
|
|
751
|
-
name:
|
|
752
|
-
description:
|
|
753
|
-
agent:
|
|
713
|
+
name: 'audit-code',
|
|
714
|
+
description: 'Autonomous local loop code auditing',
|
|
715
|
+
agent: 'agent',
|
|
754
716
|
},
|
|
755
717
|
promptBody,
|
|
756
718
|
),
|
|
@@ -761,11 +723,11 @@ async function installBootstrap(argv) {
|
|
|
761
723
|
if (profile.writeOpenCodeCommand) {
|
|
762
724
|
results.push(
|
|
763
725
|
await writeGeneratedMarkdown(
|
|
764
|
-
join(root,
|
|
726
|
+
join(root, '.opencode', 'commands', 'audit-code.md'),
|
|
765
727
|
renderPromptFile(
|
|
766
728
|
{
|
|
767
|
-
description:
|
|
768
|
-
agent:
|
|
729
|
+
description: 'Autonomous local loop code auditing',
|
|
730
|
+
agent: 'build',
|
|
769
731
|
subtask: false,
|
|
770
732
|
},
|
|
771
733
|
promptBody,
|
|
@@ -777,10 +739,10 @@ async function installBootstrap(argv) {
|
|
|
777
739
|
if (profile.writeClaudeCommand) {
|
|
778
740
|
results.push(
|
|
779
741
|
await writeGeneratedMarkdown(
|
|
780
|
-
join(root,
|
|
742
|
+
join(root, '.claude', 'commands', 'audit-code.md'),
|
|
781
743
|
renderPromptFile(
|
|
782
744
|
{
|
|
783
|
-
description:
|
|
745
|
+
description: 'Autonomous local loop code auditing',
|
|
784
746
|
},
|
|
785
747
|
promptBody,
|
|
786
748
|
),
|
|
@@ -788,16 +750,14 @@ async function installBootstrap(argv) {
|
|
|
788
750
|
);
|
|
789
751
|
}
|
|
790
752
|
|
|
791
|
-
const compatibilityBlockTargets =
|
|
792
|
-
Object.values(instructionSurfaces).filter(Boolean);
|
|
753
|
+
const compatibilityBlockTargets = Object.values(instructionSurfaces).filter(Boolean);
|
|
793
754
|
|
|
794
755
|
for (const targetPath of compatibilityBlockTargets) {
|
|
795
756
|
results.push(
|
|
796
757
|
await writeManagedMarkdown(
|
|
797
758
|
targetPath,
|
|
798
759
|
buildInstallDirective(
|
|
799
|
-
relative(dirname(targetPath), installedPromptPath) ||
|
|
800
|
-
`./.audit-code/install/${INSTALLED_PROMPT_FILENAME}`,
|
|
760
|
+
relative(dirname(targetPath), installedPromptPath) || `./.audit-code/install/${INSTALLED_PROMPT_FILENAME}`,
|
|
801
761
|
),
|
|
802
762
|
),
|
|
803
763
|
);
|
|
@@ -805,18 +765,18 @@ async function installBootstrap(argv) {
|
|
|
805
765
|
|
|
806
766
|
if (profile.writeCompatibilitySkills) {
|
|
807
767
|
const skillTargets = [
|
|
808
|
-
join(root,
|
|
809
|
-
join(root,
|
|
810
|
-
join(root,
|
|
768
|
+
join(root, '.opencode', 'skills', 'audit-code'),
|
|
769
|
+
join(root, '.claude', 'skills', 'audit-code'),
|
|
770
|
+
join(root, '.agents', 'skills', 'audit-code'),
|
|
811
771
|
];
|
|
812
772
|
|
|
813
773
|
for (const targetDir of skillTargets) {
|
|
814
774
|
results.push(
|
|
815
|
-
await writeGeneratedMarkdown(join(targetDir,
|
|
775
|
+
await writeGeneratedMarkdown(join(targetDir, 'SKILL.md'), skillSource),
|
|
816
776
|
);
|
|
817
777
|
results.push(
|
|
818
778
|
await writeGeneratedMarkdown(
|
|
819
|
-
join(targetDir,
|
|
779
|
+
join(targetDir, 'audit-code.prompt.md'),
|
|
820
780
|
promptSource,
|
|
821
781
|
),
|
|
822
782
|
);
|
|
@@ -839,24 +799,16 @@ async function installBootstrap(argv) {
|
|
|
839
799
|
),
|
|
840
800
|
);
|
|
841
801
|
|
|
842
|
-
const sessionConfigPath = join(
|
|
843
|
-
root,
|
|
844
|
-
".audit-artifacts",
|
|
845
|
-
"session-config.json",
|
|
846
|
-
);
|
|
802
|
+
const sessionConfigPath = join(root, '.audit-artifacts', 'session-config.json');
|
|
847
803
|
let sessionConfigWritten = false;
|
|
848
804
|
if (!(await fileExists(sessionConfigPath))) {
|
|
849
805
|
const insideClaudeCode = Boolean(process.env.CLAUDECODE);
|
|
850
806
|
const defaultConfig = insideClaudeCode
|
|
851
|
-
? { provider:
|
|
852
|
-
: { provider:
|
|
807
|
+
? { provider: 'local-subprocess' }
|
|
808
|
+
: { provider: 'auto' };
|
|
853
809
|
await mkdir(dirname(sessionConfigPath), { recursive: true });
|
|
854
|
-
await writeFile(
|
|
855
|
-
|
|
856
|
-
JSON.stringify(defaultConfig, null, 2) + "\n",
|
|
857
|
-
"utf8",
|
|
858
|
-
);
|
|
859
|
-
results.push({ path: sessionConfigPath, mode: "created" });
|
|
810
|
+
await writeFile(sessionConfigPath, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
|
|
811
|
+
results.push({ path: sessionConfigPath, mode: 'created' });
|
|
860
812
|
sessionConfigWritten = true;
|
|
861
813
|
}
|
|
862
814
|
|
|
@@ -875,9 +827,9 @@ async function installBootstrap(argv) {
|
|
|
875
827
|
host_guidance: hostGuidance,
|
|
876
828
|
unsupported_hosts: unsupportedHosts,
|
|
877
829
|
next_steps: [
|
|
878
|
-
|
|
830
|
+
'Open the repository in your preferred host and follow the matching host_guidance entry.',
|
|
879
831
|
`Open ${installGuidePath} for repo-local quick-start steps for VS Code, OpenCode, Claude Code, Claude Desktop, and Antigravity.`,
|
|
880
|
-
|
|
832
|
+
'If a host does not auto-discover slash commands, use the installed prompt asset or the listed compatibility instruction surfaces.',
|
|
881
833
|
],
|
|
882
834
|
},
|
|
883
835
|
null,
|
|
@@ -887,9 +839,9 @@ async function installBootstrap(argv) {
|
|
|
887
839
|
}
|
|
888
840
|
|
|
889
841
|
async function installHostPrompt(argv) {
|
|
890
|
-
const host = requireFlagValue(argv,
|
|
842
|
+
const host = requireFlagValue(argv, '--host').toLowerCase();
|
|
891
843
|
|
|
892
|
-
if (host !==
|
|
844
|
+
if (host !== 'copilot') {
|
|
893
845
|
throw new Error(
|
|
894
846
|
`install-host currently supports only "copilot". Use "install --host ${host}" for the broader bootstrap flow.`,
|
|
895
847
|
);
|
|
@@ -898,20 +850,13 @@ async function installHostPrompt(argv) {
|
|
|
898
850
|
await installBootstrap(argv);
|
|
899
851
|
}
|
|
900
852
|
|
|
901
|
-
async function runDistCommand(
|
|
902
|
-
commandName,
|
|
903
|
-
argv,
|
|
904
|
-
{ ensureArtifactsDir = false } = {},
|
|
905
|
-
) {
|
|
853
|
+
async function runDistCommand(commandName, argv, { ensureArtifactsDir = false } = {}) {
|
|
906
854
|
const commandArgs = [...argv];
|
|
907
|
-
const rootValue = resolve(getFlag(commandArgs,
|
|
908
|
-
const artifactsDir = resolve(
|
|
909
|
-
getFlag(commandArgs, "--artifacts-dir") ??
|
|
910
|
-
join(rootValue, ".audit-artifacts"),
|
|
911
|
-
);
|
|
855
|
+
const rootValue = resolve(getFlag(commandArgs, '--root') ?? '.');
|
|
856
|
+
const artifactsDir = resolve(getFlag(commandArgs, '--artifacts-dir') ?? join(rootValue, '.audit-artifacts'));
|
|
912
857
|
|
|
913
|
-
setDefaultFlag(commandArgs,
|
|
914
|
-
setDefaultFlag(commandArgs,
|
|
858
|
+
setDefaultFlag(commandArgs, '--root', rootValue);
|
|
859
|
+
setDefaultFlag(commandArgs, '--artifacts-dir', artifactsDir);
|
|
915
860
|
|
|
916
861
|
if (ensureArtifactsDir) {
|
|
917
862
|
await mkdir(artifactsDir, { recursive: true });
|
|
@@ -926,58 +871,53 @@ export async function runAuditCodeWrapper({
|
|
|
926
871
|
argv = process.argv.slice(2),
|
|
927
872
|
ensureArtifactsDir = true,
|
|
928
873
|
preferredEntrypoint,
|
|
929
|
-
defaultSingleStep = false
|
|
874
|
+
defaultSingleStep = false
|
|
930
875
|
}) {
|
|
931
|
-
if (hasFlag(argv,
|
|
876
|
+
if (hasFlag(argv, '--help') || hasFlag(argv, '-h')) {
|
|
932
877
|
printHelp({ usageName, preferredEntrypoint });
|
|
933
878
|
return;
|
|
934
879
|
}
|
|
935
880
|
|
|
936
|
-
if (hasFlag(argv,
|
|
881
|
+
if (hasFlag(argv, '--version') || hasFlag(argv, '-v')) {
|
|
937
882
|
console.log(packageVersion);
|
|
938
883
|
return;
|
|
939
884
|
}
|
|
940
885
|
|
|
941
|
-
if (argv[0] ===
|
|
886
|
+
if (argv[0] === 'prompt-path') {
|
|
942
887
|
await printPromptPath();
|
|
943
888
|
return;
|
|
944
889
|
}
|
|
945
890
|
|
|
946
|
-
if (argv[0] ===
|
|
891
|
+
if (argv[0] === 'install') {
|
|
947
892
|
await installBootstrap(argv.slice(1));
|
|
948
893
|
return;
|
|
949
894
|
}
|
|
950
895
|
|
|
951
|
-
if (argv[0] ===
|
|
896
|
+
if (argv[0] === 'install-host') {
|
|
952
897
|
await installHostPrompt(argv.slice(1));
|
|
953
898
|
return;
|
|
954
899
|
}
|
|
955
900
|
|
|
956
|
-
if (argv[0] ===
|
|
957
|
-
await runDistCommand(
|
|
901
|
+
if (argv[0] === 'validate') {
|
|
902
|
+
await runDistCommand('validate', argv.slice(1));
|
|
958
903
|
return;
|
|
959
904
|
}
|
|
960
905
|
|
|
961
906
|
const wrapperArgs = [...argv];
|
|
962
|
-
if (defaultSingleStep && !hasFlag(wrapperArgs,
|
|
963
|
-
wrapperArgs.push(
|
|
907
|
+
if (defaultSingleStep && !hasFlag(wrapperArgs, '--single-step')) {
|
|
908
|
+
wrapperArgs.push('--single-step');
|
|
964
909
|
}
|
|
965
|
-
const rootValue = resolve(getFlag(wrapperArgs,
|
|
966
|
-
const artifactsDir = resolve(
|
|
967
|
-
getFlag(wrapperArgs, "--artifacts-dir") ??
|
|
968
|
-
join(rootValue, ".audit-artifacts"),
|
|
969
|
-
);
|
|
910
|
+
const rootValue = resolve(getFlag(wrapperArgs, '--root') ?? '.');
|
|
911
|
+
const artifactsDir = resolve(getFlag(wrapperArgs, '--artifacts-dir') ?? join(rootValue, '.audit-artifacts'));
|
|
970
912
|
|
|
971
|
-
setDefaultFlag(wrapperArgs,
|
|
972
|
-
setDefaultFlag(wrapperArgs,
|
|
913
|
+
setDefaultFlag(wrapperArgs, '--root', rootValue);
|
|
914
|
+
setDefaultFlag(wrapperArgs, '--artifacts-dir', artifactsDir);
|
|
973
915
|
|
|
974
916
|
if (ensureArtifactsDir) {
|
|
975
917
|
await mkdir(artifactsDir, { recursive: true });
|
|
976
918
|
}
|
|
977
919
|
|
|
978
920
|
await ensureBuilt();
|
|
979
|
-
const command = hasFlag(wrapperArgs,
|
|
980
|
-
? "advance-audit"
|
|
981
|
-
: "run-to-completion";
|
|
921
|
+
const command = hasFlag(wrapperArgs, '--single-step') ? 'advance-audit' : 'run-to-completion';
|
|
982
922
|
await run(nodeExecutable(), [distEntry, command, ...wrapperArgs]);
|
|
983
923
|
}
|