auditor-lambda 0.1.0 → 0.2.2
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/README.md +2 -1
- package/audit-code-wrapper-lib.mjs +205 -187
- package/dist/adapters/eslint.js +4 -2
- package/dist/adapters/npmAudit.js +1 -1
- package/dist/cli.js +296 -12
- package/dist/coverage.d.ts +0 -1
- package/dist/coverage.js +3 -34
- package/dist/extractors/bucketing.js +14 -35
- package/dist/extractors/disposition.js +8 -9
- package/dist/extractors/flows.js +14 -23
- package/dist/extractors/pathPatterns.d.ts +19 -0
- package/dist/extractors/pathPatterns.js +87 -0
- package/dist/extractors/surfaces.js +2 -7
- package/dist/io/artifacts.d.ts +23 -1
- package/dist/io/artifacts.js +3 -1
- package/dist/io/runArtifacts.js +1 -1
- package/dist/orchestrator/advance.js +1 -1
- package/dist/orchestrator/flowPlanning.d.ts +1 -1
- package/dist/orchestrator/flowPlanning.js +21 -28
- package/dist/orchestrator/internalExecutors.js +4 -7
- 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.d.ts +7 -2
- package/dist/orchestrator/taskBuilder.js +47 -52
- package/dist/prompts/renderWorkerPrompt.js +33 -0
- package/dist/providers/claudeCodeProvider.js +5 -0
- package/dist/providers/constants.d.ts +1 -0
- package/dist/providers/constants.js +1 -0
- package/dist/providers/index.js +9 -2
- package/dist/providers/spawnLoggedCommand.js +4 -0
- package/dist/reporting/mergeFindings.js +0 -7
- package/dist/reporting/rootCause.d.ts +0 -1
- package/dist/reporting/rootCause.js +0 -6
- package/dist/reporting/synthesis.js +18 -0
- package/dist/supervisor/operatorHandoff.d.ts +2 -0
- package/dist/supervisor/operatorHandoff.js +21 -9
- package/dist/supervisor/runLedger.js +6 -3
- 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 +2 -0
- package/dist/types/surfaces.d.ts +2 -1
- package/dist/types/workerSession.d.ts +4 -0
- package/dist/types.d.ts +0 -2
- package/dist/validation/auditResults.d.ts +11 -0
- package/dist/validation/auditResults.js +118 -0
- package/docs/agent-integrations.md +61 -56
- package/docs/agent-roles.md +69 -69
- package/docs/architecture.md +90 -90
- package/docs/artifacts.md +69 -69
- package/docs/bootstrap-install.md +1 -1
- package/docs/model-selection.md +86 -86
- package/docs/next-steps.md +11 -9
- package/docs/packaging.md +3 -3
- package/docs/pipeline.md +152 -152
- package/docs/production-readiness.md +6 -5
- package/docs/repo-layout.md +18 -18
- package/docs/run-flow.md +5 -5
- package/docs/session-config.md +216 -210
- package/docs/supervisor.md +70 -70
- package/docs/windows-setup.md +139 -139
- package/package.json +56 -56
- package/schemas/audit-code-v1alpha1.schema.json +80 -76
- package/schemas/audit_result.schema.json +54 -48
- package/schemas/audit_state.schema.json +2 -2
- package/schemas/audit_task.schema.json +60 -49
- package/schemas/blind_spot_register.schema.json +13 -3
- package/schemas/coverage_matrix.schema.json +14 -17
- package/schemas/critical_flows.schema.json +6 -3
- package/schemas/external_analyzer_results.schema.json +10 -4
- package/schemas/file_disposition.schema.json +33 -33
- package/schemas/finding.schema.json +86 -62
- package/schemas/flow_coverage.schema.json +53 -44
- 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 -5
- package/schemas/runtime_validation_report.schema.json +34 -34
- package/schemas/runtime_validation_tasks.schema.json +4 -1
- package/schemas/surface_manifest.schema.json +4 -1
- package/schemas/synthesis_report.schema.json +61 -61
- package/schemas/unit_manifest.schema.json +10 -3
- package/skills/audit-code/SKILL.md +37 -37
- package/skills/audit-code/audit-code.prompt.md +54 -54
package/README.md
CHANGED
|
@@ -78,6 +78,7 @@ This wrapper:
|
|
|
78
78
|
- creates that directory automatically
|
|
79
79
|
- auto-builds `dist/` if it is missing
|
|
80
80
|
- advances fresh worker sessions automatically until the audit completes or the remaining work requires imported results or an interactive provider
|
|
81
|
+
- continues through provider-assisted audit review automatically when `.audit-artifacts/session-config.json` selects an interactive provider bridge
|
|
81
82
|
- emits `contract_version: "audit-code/v1alpha1"`
|
|
82
83
|
- refreshes `.audit-artifacts/operator-handoff.json` and `.audit-artifacts/operator-handoff.md` with suggested evidence-import paths and continuation hints
|
|
83
84
|
|
|
@@ -145,7 +146,7 @@ The short version is:
|
|
|
145
146
|
|
|
146
147
|
- reduce prompt-import friction in the conversation setup flow
|
|
147
148
|
- make the conversation route feel more native in the first target hosts
|
|
148
|
-
-
|
|
149
|
+
- polish provider-assisted continuation and failure guidance
|
|
149
150
|
- finish publish and release hardening for packaged installs
|
|
150
151
|
|
|
151
152
|
## Build And Test
|
|
@@ -3,7 +3,7 @@ import { constants } from 'node:fs';
|
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
const repoRoot = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const distEntry = join(repoRoot, 'dist', 'index.js');
|
|
9
9
|
const packageJsonPath = join(repoRoot, 'package.json');
|
|
@@ -19,18 +19,19 @@ const INSTALL_MARKER_START = '<!-- audit-code:begin -->';
|
|
|
19
19
|
const INSTALL_MARKER_END = '<!-- audit-code:end -->';
|
|
20
20
|
const INSTALL_GUIDE_FILENAME = 'GETTING-STARTED.md';
|
|
21
21
|
const DEFAULT_INSTALL_HOST = 'all';
|
|
22
|
+
const INSTALLED_PROMPT_FILENAME = 'audit-code.import.md';
|
|
22
23
|
const packageVersion = JSON.parse(await readFile(packageJsonPath, 'utf8')).version;
|
|
23
|
-
|
|
24
|
-
function hasFlag(argv, name) {
|
|
25
|
-
return argv.includes(name);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function getFlag(argv, name) {
|
|
29
|
-
const index = argv.indexOf(name);
|
|
30
|
-
if (index < 0) return undefined;
|
|
31
|
-
return argv[index + 1];
|
|
32
|
-
}
|
|
33
|
-
|
|
24
|
+
|
|
25
|
+
function hasFlag(argv, name) {
|
|
26
|
+
return argv.includes(name);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getFlag(argv, name) {
|
|
30
|
+
const index = argv.indexOf(name);
|
|
31
|
+
if (index < 0) return undefined;
|
|
32
|
+
return argv[index + 1];
|
|
33
|
+
}
|
|
34
|
+
|
|
34
35
|
function setDefaultFlag(argv, name, value) {
|
|
35
36
|
if (!hasFlag(argv, name)) {
|
|
36
37
|
argv.push(name, value);
|
|
@@ -44,11 +45,11 @@ function requireFlagValue(argv, name) {
|
|
|
44
45
|
}
|
|
45
46
|
return value;
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
function npmExecutable() {
|
|
49
|
-
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
50
|
-
}
|
|
51
|
-
|
|
48
|
+
|
|
49
|
+
function npmExecutable() {
|
|
50
|
+
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
51
|
+
}
|
|
52
|
+
|
|
52
53
|
function nodeExecutable() {
|
|
53
54
|
return process.execPath;
|
|
54
55
|
}
|
|
@@ -78,64 +79,64 @@ function run(command, args, options = {}) {
|
|
|
78
79
|
stdio: options.capture ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
79
80
|
env: process.env
|
|
80
81
|
});
|
|
81
|
-
|
|
82
|
-
let stdout = '';
|
|
83
|
-
let stderr = '';
|
|
84
|
-
|
|
85
|
-
if (options.capture) {
|
|
86
|
-
child.stdout?.on('data', (chunk) => {
|
|
87
|
-
stdout += String(chunk);
|
|
88
|
-
});
|
|
89
|
-
child.stderr?.on('data', (chunk) => {
|
|
90
|
-
stderr += String(chunk);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
child.on('error', rejectPromise);
|
|
95
|
-
child.on('exit', (code) => {
|
|
96
|
-
if (code === 0) {
|
|
97
|
-
resolvePromise({ stdout, stderr });
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
rejectPromise(new Error(options.capture ? stderr || `Command failed with exit code ${code}.` : `Command failed with exit code ${code}.`));
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function sleep(ms) {
|
|
106
|
-
await new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
|
|
107
|
-
}
|
|
108
|
-
|
|
82
|
+
|
|
83
|
+
let stdout = '';
|
|
84
|
+
let stderr = '';
|
|
85
|
+
|
|
86
|
+
if (options.capture) {
|
|
87
|
+
child.stdout?.on('data', (chunk) => {
|
|
88
|
+
stdout += String(chunk);
|
|
89
|
+
});
|
|
90
|
+
child.stderr?.on('data', (chunk) => {
|
|
91
|
+
stderr += String(chunk);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
child.on('error', rejectPromise);
|
|
96
|
+
child.on('exit', (code) => {
|
|
97
|
+
if (code === 0) {
|
|
98
|
+
resolvePromise({ stdout, stderr });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
rejectPromise(new Error(options.capture ? stderr || `Command failed with exit code ${code}.` : `Command failed with exit code ${code}.`));
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function sleep(ms) {
|
|
107
|
+
await new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
|
|
108
|
+
}
|
|
109
|
+
|
|
109
110
|
async function fileExists(path) {
|
|
110
111
|
try {
|
|
111
112
|
await access(path, constants.F_OK);
|
|
112
113
|
return true;
|
|
113
114
|
} catch {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async function newestMtimeMs(path) {
|
|
119
|
-
const stats = await stat(path);
|
|
120
|
-
if (!stats.isDirectory()) {
|
|
121
|
-
return stats.mtimeMs;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
let newest = stats.mtimeMs;
|
|
125
|
-
const entries = await readdir(path, { withFileTypes: true });
|
|
126
|
-
for (const entry of entries) {
|
|
127
|
-
const childPath = join(path, entry.name);
|
|
128
|
-
if (entry.isDirectory()) {
|
|
129
|
-
newest = Math.max(newest, await newestMtimeMs(childPath));
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
if (entry.isFile()) {
|
|
133
|
-
newest = Math.max(newest, (await stat(childPath)).mtimeMs);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return newest;
|
|
137
|
-
}
|
|
138
|
-
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function newestMtimeMs(path) {
|
|
120
|
+
const stats = await stat(path);
|
|
121
|
+
if (!stats.isDirectory()) {
|
|
122
|
+
return stats.mtimeMs;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let newest = stats.mtimeMs;
|
|
126
|
+
const entries = await readdir(path, { withFileTypes: true });
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
const childPath = join(path, entry.name);
|
|
129
|
+
if (entry.isDirectory()) {
|
|
130
|
+
newest = Math.max(newest, await newestMtimeMs(childPath));
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (entry.isFile()) {
|
|
134
|
+
newest = Math.max(newest, (await stat(childPath)).mtimeMs);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return newest;
|
|
138
|
+
}
|
|
139
|
+
|
|
139
140
|
async function shouldBuildDist() {
|
|
140
141
|
if (!(await fileExists(distEntry))) {
|
|
141
142
|
if (!(await fileExists(sourceRoot)) || !(await fileExists(tsconfigPath))) {
|
|
@@ -152,85 +153,85 @@ async function shouldBuildDist() {
|
|
|
152
153
|
|
|
153
154
|
const distMtime = (await stat(distEntry)).mtimeMs;
|
|
154
155
|
const sourceMtime = await newestMtimeMs(sourceRoot);
|
|
155
|
-
const tsconfigMtime = (await stat(tsconfigPath)).mtimeMs;
|
|
156
|
-
const packageJsonMtime = (await stat(packageJsonPath)).mtimeMs;
|
|
157
|
-
const newestInput = Math.max(sourceMtime, tsconfigMtime, packageJsonMtime);
|
|
158
|
-
return distMtime < newestInput;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async function releaseBuildLock(handle) {
|
|
162
|
-
try {
|
|
163
|
-
await handle?.close();
|
|
164
|
-
} finally {
|
|
165
|
-
await unlink(buildLockPath).catch(() => {});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function waitForPeerBuild() {
|
|
170
|
-
const start = Date.now();
|
|
171
|
-
|
|
172
|
-
while (true) {
|
|
173
|
-
if (!(await fileExists(buildLockPath))) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (Date.now() - start > BUILD_LOCK_WAIT_TIMEOUT_MS) {
|
|
178
|
-
throw new Error(`Timed out waiting for build lock ${buildLockPath}.`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
await sleep(BUILD_LOCK_WAIT_INTERVAL_MS);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async function acquireBuildLock() {
|
|
186
|
-
while (true) {
|
|
187
|
-
try {
|
|
188
|
-
const handle = await open(buildLockPath, 'wx');
|
|
189
|
-
await handle.writeFile(JSON.stringify({ pid: process.pid, acquired_at: new Date().toISOString() }));
|
|
190
|
-
return handle;
|
|
191
|
-
} catch (error) {
|
|
192
|
-
if (error && error.code === 'EEXIST') {
|
|
193
|
-
try {
|
|
194
|
-
const lockStats = await stat(buildLockPath);
|
|
195
|
-
if (Date.now() - lockStats.mtimeMs > BUILD_LOCK_MAX_AGE_MS) {
|
|
196
|
-
await unlink(buildLockPath).catch(() => {});
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
} catch {
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
await waitForPeerBuild();
|
|
204
|
-
if (!(await shouldBuildDist())) {
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async function ensureBuilt() {
|
|
215
|
-
if (!(await shouldBuildDist())) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const lockHandle = await acquireBuildLock();
|
|
220
|
-
if (!lockHandle) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
if (!(await shouldBuildDist())) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
await run(npmExecutable(), ['run', 'build']);
|
|
229
|
-
} finally {
|
|
230
|
-
await releaseBuildLock(lockHandle);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
156
|
+
const tsconfigMtime = (await stat(tsconfigPath)).mtimeMs;
|
|
157
|
+
const packageJsonMtime = (await stat(packageJsonPath)).mtimeMs;
|
|
158
|
+
const newestInput = Math.max(sourceMtime, tsconfigMtime, packageJsonMtime);
|
|
159
|
+
return distMtime < newestInput;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function releaseBuildLock(handle) {
|
|
163
|
+
try {
|
|
164
|
+
await handle?.close();
|
|
165
|
+
} finally {
|
|
166
|
+
await unlink(buildLockPath).catch(() => {});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function waitForPeerBuild() {
|
|
171
|
+
const start = Date.now();
|
|
172
|
+
|
|
173
|
+
while (true) {
|
|
174
|
+
if (!(await fileExists(buildLockPath))) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (Date.now() - start > BUILD_LOCK_WAIT_TIMEOUT_MS) {
|
|
179
|
+
throw new Error(`Timed out waiting for build lock ${buildLockPath}.`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await sleep(BUILD_LOCK_WAIT_INTERVAL_MS);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function acquireBuildLock() {
|
|
187
|
+
while (true) {
|
|
188
|
+
try {
|
|
189
|
+
const handle = await open(buildLockPath, 'wx');
|
|
190
|
+
await handle.writeFile(JSON.stringify({ pid: process.pid, acquired_at: new Date().toISOString() }));
|
|
191
|
+
return handle;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (error && error.code === 'EEXIST') {
|
|
194
|
+
try {
|
|
195
|
+
const lockStats = await stat(buildLockPath);
|
|
196
|
+
if (Date.now() - lockStats.mtimeMs > BUILD_LOCK_MAX_AGE_MS) {
|
|
197
|
+
await unlink(buildLockPath).catch(() => {});
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
} catch {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
await waitForPeerBuild();
|
|
205
|
+
if (!(await shouldBuildDist())) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function ensureBuilt() {
|
|
216
|
+
if (!(await shouldBuildDist())) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const lockHandle = await acquireBuildLock();
|
|
221
|
+
if (!lockHandle) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
if (!(await shouldBuildDist())) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
await run(npmExecutable(), ['run', 'build']);
|
|
230
|
+
} finally {
|
|
231
|
+
await releaseBuildLock(lockHandle);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
234
235
|
function printHelp({ usageName, preferredEntrypoint }) {
|
|
235
236
|
const lines = [
|
|
236
237
|
`Usage: node ${usageName} [--single-step] [--root PATH] [--artifacts-dir PATH] [--results FILE] [--updates FILE] [--external-analyzer-results FILE]`,
|
|
@@ -246,20 +247,20 @@ function printHelp({ usageName, preferredEntrypoint }) {
|
|
|
246
247
|
'- default behavior advances the audit automatically until it completes or no further automatic progress is possible',
|
|
247
248
|
'- each wrapper response refreshes operator-handoff.json and operator-handoff.md under the artifacts directory',
|
|
248
249
|
'- use --single-step only for debugging or bounded-step testing',
|
|
249
|
-
'',
|
|
250
|
-
'Defaults:',
|
|
251
|
-
'- --root .',
|
|
252
|
-
'- --artifacts-dir <root>/.audit-artifacts',
|
|
253
|
-
'',
|
|
254
|
-
'Completion signals:',
|
|
255
|
-
'- done: audit_state.status is complete',
|
|
256
|
-
'- blocked/no further automatic progress: progress_made is false and next_likely_step is null'
|
|
257
|
-
];
|
|
258
|
-
|
|
259
|
-
if (preferredEntrypoint && preferredEntrypoint !== usageName) {
|
|
260
|
-
lines.push('', `Preferred entrypoint: node ${preferredEntrypoint}`);
|
|
261
|
-
}
|
|
262
|
-
|
|
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'
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
if (preferredEntrypoint && preferredEntrypoint !== usageName) {
|
|
261
|
+
lines.push('', `Preferred entrypoint: node ${preferredEntrypoint}`);
|
|
262
|
+
}
|
|
263
|
+
|
|
263
264
|
console.log(lines.join('\n'));
|
|
264
265
|
}
|
|
265
266
|
|
|
@@ -647,9 +648,10 @@ async function installBootstrap(argv) {
|
|
|
647
648
|
await assertDirectoryExists(root, 'Target repository root');
|
|
648
649
|
const profile = getInstallProfile(host);
|
|
649
650
|
const promptSource = await readFile(promptAssetPath, 'utf8');
|
|
650
|
-
const skillSource = await readFile(skillAssetPath, 'utf8');
|
|
651
|
+
const skillSource = (await readFile(skillAssetPath, 'utf8')).replace(/\r\n/g, '\n');
|
|
651
652
|
const { body: promptBody } = splitFrontmatter(promptSource);
|
|
652
|
-
const installedPromptPath = join(root, '.audit-code', 'install',
|
|
653
|
+
const installedPromptPath = join(root, '.audit-code', 'install', INSTALLED_PROMPT_FILENAME);
|
|
654
|
+
const legacyInstalledPromptPath = join(root, '.audit-code', 'install', 'audit-code.prompt.md');
|
|
653
655
|
const installedSkillPath = join(root, '.audit-code', 'install', 'SKILL.md');
|
|
654
656
|
const installGuidePath = join(root, '.audit-code', 'install', INSTALL_GUIDE_FILENAME);
|
|
655
657
|
const slashCommandSurfaces = {
|
|
@@ -691,6 +693,9 @@ async function installBootstrap(argv) {
|
|
|
691
693
|
});
|
|
692
694
|
|
|
693
695
|
const results = [];
|
|
696
|
+
if (await fileExists(legacyInstalledPromptPath)) {
|
|
697
|
+
await unlink(legacyInstalledPromptPath).catch(() => {});
|
|
698
|
+
}
|
|
694
699
|
results.push(
|
|
695
700
|
await writeGeneratedMarkdown(
|
|
696
701
|
installedPromptPath,
|
|
@@ -752,7 +757,7 @@ async function installBootstrap(argv) {
|
|
|
752
757
|
await writeManagedMarkdown(
|
|
753
758
|
targetPath,
|
|
754
759
|
buildInstallDirective(
|
|
755
|
-
relative(dirname(targetPath), installedPromptPath) ||
|
|
760
|
+
relative(dirname(targetPath), installedPromptPath) || `./.audit-code/install/${INSTALLED_PROMPT_FILENAME}`,
|
|
756
761
|
),
|
|
757
762
|
),
|
|
758
763
|
);
|
|
@@ -794,6 +799,19 @@ async function installBootstrap(argv) {
|
|
|
794
799
|
),
|
|
795
800
|
);
|
|
796
801
|
|
|
802
|
+
const sessionConfigPath = join(root, '.audit-artifacts', 'session-config.json');
|
|
803
|
+
let sessionConfigWritten = false;
|
|
804
|
+
if (!(await fileExists(sessionConfigPath))) {
|
|
805
|
+
const insideClaudeCode = Boolean(process.env.CLAUDECODE);
|
|
806
|
+
const defaultConfig = insideClaudeCode
|
|
807
|
+
? { provider: 'local-subprocess' }
|
|
808
|
+
: { provider: 'auto' };
|
|
809
|
+
await mkdir(dirname(sessionConfigPath), { recursive: true });
|
|
810
|
+
await writeFile(sessionConfigPath, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
|
|
811
|
+
results.push({ path: sessionConfigPath, mode: 'created' });
|
|
812
|
+
sessionConfigWritten = true;
|
|
813
|
+
}
|
|
814
|
+
|
|
797
815
|
console.log(
|
|
798
816
|
JSON.stringify(
|
|
799
817
|
{
|
|
@@ -852,14 +870,14 @@ export async function runAuditCodeWrapper({
|
|
|
852
870
|
usageName,
|
|
853
871
|
argv = process.argv.slice(2),
|
|
854
872
|
ensureArtifactsDir = true,
|
|
855
|
-
preferredEntrypoint,
|
|
856
|
-
defaultSingleStep = false
|
|
857
|
-
}) {
|
|
858
|
-
if (hasFlag(argv, '--help') || hasFlag(argv, '-h')) {
|
|
859
|
-
printHelp({ usageName, preferredEntrypoint });
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
|
|
873
|
+
preferredEntrypoint,
|
|
874
|
+
defaultSingleStep = false
|
|
875
|
+
}) {
|
|
876
|
+
if (hasFlag(argv, '--help') || hasFlag(argv, '-h')) {
|
|
877
|
+
printHelp({ usageName, preferredEntrypoint });
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
|
|
863
881
|
if (hasFlag(argv, '--version') || hasFlag(argv, '-v')) {
|
|
864
882
|
console.log(packageVersion);
|
|
865
883
|
return;
|
|
@@ -890,16 +908,16 @@ export async function runAuditCodeWrapper({
|
|
|
890
908
|
wrapperArgs.push('--single-step');
|
|
891
909
|
}
|
|
892
910
|
const rootValue = resolve(getFlag(wrapperArgs, '--root') ?? '.');
|
|
893
|
-
const artifactsDir = resolve(getFlag(wrapperArgs, '--artifacts-dir') ?? join(rootValue, '.audit-artifacts'));
|
|
894
|
-
|
|
895
|
-
setDefaultFlag(wrapperArgs, '--root', rootValue);
|
|
896
|
-
setDefaultFlag(wrapperArgs, '--artifacts-dir', artifactsDir);
|
|
897
|
-
|
|
898
|
-
if (ensureArtifactsDir) {
|
|
899
|
-
await mkdir(artifactsDir, { recursive: true });
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
await ensureBuilt();
|
|
903
|
-
const command = hasFlag(wrapperArgs, '--single-step') ? 'advance-audit' : 'run-to-completion';
|
|
904
|
-
await run(nodeExecutable(), [distEntry, command, ...wrapperArgs]);
|
|
905
|
-
}
|
|
911
|
+
const artifactsDir = resolve(getFlag(wrapperArgs, '--artifacts-dir') ?? join(rootValue, '.audit-artifacts'));
|
|
912
|
+
|
|
913
|
+
setDefaultFlag(wrapperArgs, '--root', rootValue);
|
|
914
|
+
setDefaultFlag(wrapperArgs, '--artifacts-dir', artifactsDir);
|
|
915
|
+
|
|
916
|
+
if (ensureArtifactsDir) {
|
|
917
|
+
await mkdir(artifactsDir, { recursive: true });
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
await ensureBuilt();
|
|
921
|
+
const command = hasFlag(wrapperArgs, '--single-step') ? 'advance-audit' : 'run-to-completion';
|
|
922
|
+
await run(nodeExecutable(), [distEntry, command, ...wrapperArgs]);
|
|
923
|
+
}
|
package/dist/adapters/eslint.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { normalizeGenericExternalResults } from "./normalizeExternal.js";
|
|
2
|
+
const ESLINT_SEVERITY_ERROR = 2;
|
|
3
|
+
const ESLINT_SEVERITY_WARNING = 1;
|
|
2
4
|
function mapSeverity(value) {
|
|
3
|
-
if (value ===
|
|
5
|
+
if (value === ESLINT_SEVERITY_ERROR)
|
|
4
6
|
return "medium";
|
|
5
|
-
if (value ===
|
|
7
|
+
if (value === ESLINT_SEVERITY_WARNING)
|
|
6
8
|
return "low";
|
|
7
9
|
return "info";
|
|
8
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { normalizeGenericExternalResults } from "./normalizeExternal.js";
|
|
2
2
|
export function normalizeNpmAuditJson(input) {
|
|
3
3
|
return normalizeGenericExternalResults("npm-audit", Object.entries(input.vulnerabilities ?? {}).map(([pkg, vuln], index) => ({
|
|
4
|
-
id: `npm-audit-${index
|
|
4
|
+
id: `npm-audit-${index}`,
|
|
5
5
|
category: "dependency_risk",
|
|
6
6
|
severity: vuln.severity ?? "unknown",
|
|
7
7
|
path: "package-lock.json",
|