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.
Files changed (87) hide show
  1. package/README.md +2 -1
  2. package/audit-code-wrapper-lib.mjs +205 -187
  3. package/dist/adapters/eslint.js +4 -2
  4. package/dist/adapters/npmAudit.js +1 -1
  5. package/dist/cli.js +296 -12
  6. package/dist/coverage.d.ts +0 -1
  7. package/dist/coverage.js +3 -34
  8. package/dist/extractors/bucketing.js +14 -35
  9. package/dist/extractors/disposition.js +8 -9
  10. package/dist/extractors/flows.js +14 -23
  11. package/dist/extractors/pathPatterns.d.ts +19 -0
  12. package/dist/extractors/pathPatterns.js +87 -0
  13. package/dist/extractors/surfaces.js +2 -7
  14. package/dist/io/artifacts.d.ts +23 -1
  15. package/dist/io/artifacts.js +3 -1
  16. package/dist/io/runArtifacts.js +1 -1
  17. package/dist/orchestrator/advance.js +1 -1
  18. package/dist/orchestrator/flowPlanning.d.ts +1 -1
  19. package/dist/orchestrator/flowPlanning.js +21 -28
  20. package/dist/orchestrator/internalExecutors.js +4 -7
  21. package/dist/orchestrator/planning.js +12 -20
  22. package/dist/orchestrator/resultIngestion.js +3 -2
  23. package/dist/orchestrator/runtimeValidation.js +5 -0
  24. package/dist/orchestrator/syntaxResolutionExecutor.js +10 -2
  25. package/dist/orchestrator/taskBuilder.d.ts +7 -2
  26. package/dist/orchestrator/taskBuilder.js +47 -52
  27. package/dist/prompts/renderWorkerPrompt.js +33 -0
  28. package/dist/providers/claudeCodeProvider.js +5 -0
  29. package/dist/providers/constants.d.ts +1 -0
  30. package/dist/providers/constants.js +1 -0
  31. package/dist/providers/index.js +9 -2
  32. package/dist/providers/spawnLoggedCommand.js +4 -0
  33. package/dist/reporting/mergeFindings.js +0 -7
  34. package/dist/reporting/rootCause.d.ts +0 -1
  35. package/dist/reporting/rootCause.js +0 -6
  36. package/dist/reporting/synthesis.js +18 -0
  37. package/dist/supervisor/operatorHandoff.d.ts +2 -0
  38. package/dist/supervisor/operatorHandoff.js +21 -9
  39. package/dist/supervisor/runLedger.js +6 -3
  40. package/dist/supervisor/sessionConfig.js +1 -0
  41. package/dist/types/flowCoverage.d.ts +1 -1
  42. package/dist/types/runLedger.d.ts +1 -1
  43. package/dist/types/runtimeValidation.d.ts +2 -1
  44. package/dist/types/sessionConfig.d.ts +2 -0
  45. package/dist/types/surfaces.d.ts +2 -1
  46. package/dist/types/workerSession.d.ts +4 -0
  47. package/dist/types.d.ts +0 -2
  48. package/dist/validation/auditResults.d.ts +11 -0
  49. package/dist/validation/auditResults.js +118 -0
  50. package/docs/agent-integrations.md +61 -56
  51. package/docs/agent-roles.md +69 -69
  52. package/docs/architecture.md +90 -90
  53. package/docs/artifacts.md +69 -69
  54. package/docs/bootstrap-install.md +1 -1
  55. package/docs/model-selection.md +86 -86
  56. package/docs/next-steps.md +11 -9
  57. package/docs/packaging.md +3 -3
  58. package/docs/pipeline.md +152 -152
  59. package/docs/production-readiness.md +6 -5
  60. package/docs/repo-layout.md +18 -18
  61. package/docs/run-flow.md +5 -5
  62. package/docs/session-config.md +216 -210
  63. package/docs/supervisor.md +70 -70
  64. package/docs/windows-setup.md +139 -139
  65. package/package.json +56 -56
  66. package/schemas/audit-code-v1alpha1.schema.json +80 -76
  67. package/schemas/audit_result.schema.json +54 -48
  68. package/schemas/audit_state.schema.json +2 -2
  69. package/schemas/audit_task.schema.json +60 -49
  70. package/schemas/blind_spot_register.schema.json +13 -3
  71. package/schemas/coverage_matrix.schema.json +14 -17
  72. package/schemas/critical_flows.schema.json +6 -3
  73. package/schemas/external_analyzer_results.schema.json +10 -4
  74. package/schemas/file_disposition.schema.json +33 -33
  75. package/schemas/finding.schema.json +86 -62
  76. package/schemas/flow_coverage.schema.json +53 -44
  77. package/schemas/graph_bundle.schema.json +12 -6
  78. package/schemas/merged_findings.schema.json +7 -2
  79. package/schemas/risk_register.schema.json +5 -1
  80. package/schemas/root_cause_clusters.schema.json +2 -5
  81. package/schemas/runtime_validation_report.schema.json +34 -34
  82. package/schemas/runtime_validation_tasks.schema.json +4 -1
  83. package/schemas/surface_manifest.schema.json +4 -1
  84. package/schemas/synthesis_report.schema.json +61 -61
  85. package/schemas/unit_manifest.schema.json +10 -3
  86. package/skills/audit-code/SKILL.md +37 -37
  87. 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
- - improve continuation when assisted or interactive review is needed
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', 'audit-code.prompt.md');
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) || './.audit-code/install/audit-code.prompt.md',
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
+ }
@@ -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 === 2)
5
+ if (value === ESLINT_SEVERITY_ERROR)
4
6
  return "medium";
5
- if (value === 1)
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 + 1}`,
4
+ id: `npm-audit-${index}`,
5
5
  category: "dependency_risk",
6
6
  severity: vuln.severity ?? "unknown",
7
7
  path: "package-lock.json",