auditor-lambda 0.6.7 → 0.6.9
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 +36 -2
- package/dist/cli/dispatch.d.ts +2 -0
- package/dist/cli/dispatch.js +1 -0
- package/dist/cli/lineIndex.d.ts +4 -0
- package/dist/cli/lineIndex.js +44 -0
- package/dist/cli/prompts.js +27 -2
- package/dist/cli/steps.d.ts +19 -0
- package/dist/cli/steps.js +1 -0
- package/dist/cli.js +12 -39
- package/dist/extractors/fileInventory.js +1 -1452
- package/dist/extractors/languageMap.generated.d.ts +1 -0
- package/dist/extractors/languageMap.generated.js +1455 -0
- package/dist/providers/claudeCodeProvider.d.ts +1 -1
- package/dist/providers/claudeCodeProvider.js +1 -1
- package/dist/providers/localSubprocessProvider.d.ts +1 -1
- package/dist/providers/localSubprocessProvider.js +2 -2
- package/dist/providers/opencodeProvider.js +1 -1
- package/dist/providers/subprocessTemplateProvider.js +1 -1
- package/dist/quota/index.d.ts +2 -2
- package/dist/quota/index.js +5 -2
- package/package.json +5 -4
- package/dist/providers/spawnLoggedCommand.d.ts +0 -12
- package/dist/providers/spawnLoggedCommand.js +0 -186
- package/dist/quota/scheduler.d.ts +0 -20
- package/dist/quota/scheduler.js +0 -151
|
@@ -59,6 +59,25 @@ function nodeExecutable() {
|
|
|
59
59
|
return process.execPath;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// When the wrapper runs from a source checkout (its package dir is NOT inside a
|
|
63
|
+
// node_modules tree), generated continuation commands should re-invoke THIS
|
|
64
|
+
// wrapper via `node <path>` so a dogfooded monorepo run stays pinned to local
|
|
65
|
+
// code instead of silently falling back to a globally-installed `audit-code`
|
|
66
|
+
// bin. Installed copies leave the hint unset so the dist CLI keeps emitting the
|
|
67
|
+
// `audit-code` bin. Returned as an env fragment scoped to the spawned child so
|
|
68
|
+
// it never leaks into the parent process (e.g. the test runner).
|
|
69
|
+
function selfInvocationEnv() {
|
|
70
|
+
if (process.env.AUDIT_CODE_INVOCATION) {
|
|
71
|
+
return { AUDIT_CODE_INVOCATION: process.env.AUDIT_CODE_INVOCATION };
|
|
72
|
+
}
|
|
73
|
+
if (/[\\/]node_modules[\\/]/.test(repoRoot)) {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
AUDIT_CODE_INVOCATION: JSON.stringify(['node', join(repoRoot, 'audit-code.mjs')]),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
62
81
|
function quoteForCmd(arg) {
|
|
63
82
|
if (arg.length === 0) return '""';
|
|
64
83
|
if (!/[\s"]/u.test(arg)) return arg;
|
|
@@ -82,7 +101,7 @@ function run(command, args, options = {}) {
|
|
|
82
101
|
const child = spawn(resolved.command, resolved.args, {
|
|
83
102
|
cwd: repoRoot,
|
|
84
103
|
stdio: options.capture ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
85
|
-
env: process.env
|
|
104
|
+
env: options.env ?? process.env
|
|
86
105
|
});
|
|
87
106
|
|
|
88
107
|
let stdout = '';
|
|
@@ -1008,6 +1027,13 @@ function renderSharedMcpLauncher(sourcePackageRoot) {
|
|
|
1008
1027
|
'const scriptDir = dirname(fileURLToPath(import.meta.url));',
|
|
1009
1028
|
"const repoRoot = resolve(scriptDir, '..', '..');",
|
|
1010
1029
|
"const artifactsDir = join(repoRoot, '.audit-artifacts');",
|
|
1030
|
+
'// Absolute path to the auditor-lambda package that generated this launcher.',
|
|
1031
|
+
'// Intentionally machine-specific: it is a load-bearing fallback candidate',
|
|
1032
|
+
'// (tried after a repo-local dependency) that lets the launcher find the',
|
|
1033
|
+
'// backend entrypoint when the target repo has no local auditor-lambda dep.',
|
|
1034
|
+
'// This file is regenerated per-install by `audit-code ensure`/`install` and',
|
|
1035
|
+
'// is gitignored, so the path is always re-derived for the current machine;',
|
|
1036
|
+
'// if it ever goes stale the launcher degrades gracefully to PATH/npx below.',
|
|
1011
1037
|
`const sourcePackageRoot = ${JSON.stringify(sourcePackageRoot)};`,
|
|
1012
1038
|
'',
|
|
1013
1039
|
'async function exists(path) {',
|
|
@@ -2767,7 +2793,9 @@ async function runDistCommand(commandName, argv, { ensureArtifactsDir = false }
|
|
|
2767
2793
|
}
|
|
2768
2794
|
|
|
2769
2795
|
await ensureBuilt();
|
|
2770
|
-
await run(nodeExecutable(), [distEntry, commandName, ...commandArgs]
|
|
2796
|
+
await run(nodeExecutable(), [distEntry, commandName, ...commandArgs], {
|
|
2797
|
+
env: { ...process.env, ...selfInvocationEnv() },
|
|
2798
|
+
});
|
|
2771
2799
|
}
|
|
2772
2800
|
|
|
2773
2801
|
async function runDistCommandInline(commandName, argv) {
|
|
@@ -2781,6 +2809,12 @@ async function runDistCommandInline(commandName, argv) {
|
|
|
2781
2809
|
await mkdir(artifactsDir, { recursive: true });
|
|
2782
2810
|
await ensureBuilt();
|
|
2783
2811
|
|
|
2812
|
+
// Propagate the invocation hint into this (long-lived) server process so it
|
|
2813
|
+
// and the wrapper subprocesses it spawns emit continuation commands that
|
|
2814
|
+
// match how the backend was launched. Safe here: this path is only the `mcp`
|
|
2815
|
+
// server, not a shared/test process.
|
|
2816
|
+
Object.assign(process.env, selfInvocationEnv());
|
|
2817
|
+
|
|
2784
2818
|
// Import the module that exports runCli (dist/cli.js). dist/index.js has no
|
|
2785
2819
|
// exports — it is the bare entrypoint that runs `runCli(process.argv)` as an
|
|
2786
2820
|
// import side effect — so importing it here both fails to provide runCli and
|
package/dist/cli/dispatch.d.ts
CHANGED
|
@@ -41,6 +41,8 @@ export interface PrepareDispatchResult {
|
|
|
41
41
|
packet_count: number;
|
|
42
42
|
task_count: number;
|
|
43
43
|
skipped_task_count: number;
|
|
44
|
+
/** Subagent parallelism resolved for this dispatch run. */
|
|
45
|
+
wave_size: number;
|
|
44
46
|
largest_packet: {
|
|
45
47
|
packet_id: string;
|
|
46
48
|
total_lines: number;
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -533,6 +533,7 @@ export async function prepareDispatchArtifacts(params) {
|
|
|
533
533
|
packet_count: plan.length,
|
|
534
534
|
task_count: orderedTasks.length,
|
|
535
535
|
skipped_task_count: priorResultTaskIds.size,
|
|
536
|
+
wave_size: waveSchedule.wave_size,
|
|
536
537
|
largest_packet: largestPacketId
|
|
537
538
|
? {
|
|
538
539
|
packet_id: largestPacketId,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AuditTask, RepoManifest } from "../types.js";
|
|
2
|
+
export declare function buildLineIndex(root: string, repoManifest: RepoManifest): Promise<Record<string, number>>;
|
|
3
|
+
export declare function buildLineIndexForPaths(root: string, paths: string[]): Promise<Record<string, number>>;
|
|
4
|
+
export declare function addFileLineCountHints(root: string, tasks: AuditTask[]): Promise<AuditTask[]>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { countLines } from "./args.js";
|
|
3
|
+
// Line-count helpers extracted from cli.ts. Pure functions over the repo
|
|
4
|
+
// manifest / task file paths — used to annotate audit tasks with per-file line
|
|
5
|
+
// counts and to build line indexes for prompt rendering.
|
|
6
|
+
export async function buildLineIndex(root, repoManifest) {
|
|
7
|
+
const entries = [];
|
|
8
|
+
const batchSize = 25;
|
|
9
|
+
for (let i = 0; i < repoManifest.files.length; i += batchSize) {
|
|
10
|
+
const batch = repoManifest.files.slice(i, i + batchSize);
|
|
11
|
+
const results = await Promise.all(batch.map(async (file) => {
|
|
12
|
+
try {
|
|
13
|
+
return [
|
|
14
|
+
file.path,
|
|
15
|
+
await countLines(resolve(root, file.path)),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return [file.path, 0];
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
entries.push(...results);
|
|
23
|
+
}
|
|
24
|
+
return Object.fromEntries(entries);
|
|
25
|
+
}
|
|
26
|
+
export async function buildLineIndexForPaths(root, paths) {
|
|
27
|
+
const uniquePaths = [...new Set(paths)].sort();
|
|
28
|
+
const entries = await Promise.all(uniquePaths.map(async (path) => {
|
|
29
|
+
try {
|
|
30
|
+
return [path, await countLines(resolve(root, path))];
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return [path, 0];
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
return Object.fromEntries(entries);
|
|
37
|
+
}
|
|
38
|
+
export async function addFileLineCountHints(root, tasks) {
|
|
39
|
+
const lineIndex = await buildLineIndexForPaths(root, tasks.flatMap((task) => task.file_paths));
|
|
40
|
+
return tasks.map((task) => ({
|
|
41
|
+
...task,
|
|
42
|
+
file_line_counts: Object.fromEntries(task.file_paths.map((path) => [path, lineIndex[path] ?? 0])),
|
|
43
|
+
}));
|
|
44
|
+
}
|
package/dist/cli/prompts.js
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import { renderCommand } from "./args.js";
|
|
2
|
+
/**
|
|
3
|
+
* Token prefix the host should use to re-invoke the backend in generated
|
|
4
|
+
* continuation commands. Defaults to the `audit-code` bin (correct for an
|
|
5
|
+
* installed global). The wrapper sets `AUDIT_CODE_INVOCATION` to e.g.
|
|
6
|
+
* `["node","<path>/audit-code.mjs"]` when it runs from a source checkout, so a
|
|
7
|
+
* dogfooded monorepo run keeps generated commands pinned to local code instead
|
|
8
|
+
* of silently falling back to a globally-installed `audit-code`.
|
|
9
|
+
*/
|
|
10
|
+
function cliInvocationTokens() {
|
|
11
|
+
const raw = process.env.AUDIT_CODE_INVOCATION;
|
|
12
|
+
if (raw) {
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
if (Array.isArray(parsed) &&
|
|
16
|
+
parsed.length > 0 &&
|
|
17
|
+
parsed.every((t) => typeof t === "string" && t.length > 0)) {
|
|
18
|
+
return parsed;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// malformed override — fall back to the default bin
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return ["audit-code"];
|
|
26
|
+
}
|
|
2
27
|
export function nextStepCommand(root, artifactsDir) {
|
|
3
28
|
return renderCommand([
|
|
4
|
-
|
|
29
|
+
...cliInvocationTokens(),
|
|
5
30
|
"next-step",
|
|
6
31
|
"--root",
|
|
7
32
|
root,
|
|
@@ -11,7 +36,7 @@ export function nextStepCommand(root, artifactsDir) {
|
|
|
11
36
|
}
|
|
12
37
|
export function mergeAndIngestCommand(artifactsDir, runId) {
|
|
13
38
|
return renderCommand([
|
|
14
|
-
|
|
39
|
+
...cliInvocationTokens(),
|
|
15
40
|
"merge-and-ingest",
|
|
16
41
|
"--artifacts-dir",
|
|
17
42
|
artifactsDir,
|
package/dist/cli/steps.d.ts
CHANGED
|
@@ -2,12 +2,30 @@ import type { StepStatus } from "@audit-tools/shared";
|
|
|
2
2
|
import type { AccessDeclaration } from "../types/workerSession.js";
|
|
3
3
|
export declare const STEP_CONTRACT_VERSION = "audit-code-step/v1alpha1";
|
|
4
4
|
export type StepKind = "dispatch_review" | "single_task_fallback" | "design_review" | "analyzer_install" | "edge_reasoning" | "edge_reasoning_dispatch" | "synthesis_narrative" | "present_report" | "blocked";
|
|
5
|
+
/**
|
|
6
|
+
* Lightweight run-level orientation surfaced in the step contract so a host
|
|
7
|
+
* resuming an in-flight audit knows where it stands without reading artifacts.
|
|
8
|
+
*/
|
|
9
|
+
export interface StepProgress {
|
|
10
|
+
/** One-line, human-readable summary safe to show a resuming host. */
|
|
11
|
+
summary: string;
|
|
12
|
+
/** Pending review packets in the active dispatch run, when applicable. */
|
|
13
|
+
pending_packets?: number;
|
|
14
|
+
/** Audit tasks covered by the pending packets. */
|
|
15
|
+
pending_tasks?: number;
|
|
16
|
+
/** Audit tasks already completed before this run (skipped as done). */
|
|
17
|
+
completed_tasks?: number;
|
|
18
|
+
/** Subagent parallelism resolved for this dispatch run. */
|
|
19
|
+
wave_size?: number;
|
|
20
|
+
}
|
|
5
21
|
export interface StepArtifact {
|
|
6
22
|
contract_version: typeof STEP_CONTRACT_VERSION;
|
|
7
23
|
step_kind: StepKind;
|
|
8
24
|
prompt_path: string;
|
|
9
25
|
status: StepStatus;
|
|
10
26
|
run_id: string | null;
|
|
27
|
+
/** Run-level orientation; omitted for steps that have no meaningful summary. */
|
|
28
|
+
progress?: StepProgress;
|
|
11
29
|
/** Shell commands the host may run for this step. */
|
|
12
30
|
allowed_commands: string[];
|
|
13
31
|
/**
|
|
@@ -30,6 +48,7 @@ export declare function writeCurrentStep(params: {
|
|
|
30
48
|
runId: string | null;
|
|
31
49
|
allowedCommands: string[];
|
|
32
50
|
allowedMcpTools?: string[];
|
|
51
|
+
progress?: StepProgress;
|
|
33
52
|
stopCondition: string;
|
|
34
53
|
repoRoot: string;
|
|
35
54
|
artifactPaths: Record<string, string | null>;
|
package/dist/cli/steps.js
CHANGED
|
@@ -14,6 +14,7 @@ export async function writeCurrentStep(params) {
|
|
|
14
14
|
prompt_path: promptPath,
|
|
15
15
|
status: params.status,
|
|
16
16
|
run_id: params.runId,
|
|
17
|
+
...(params.progress ? { progress: params.progress } : {}),
|
|
17
18
|
allowed_commands: params.allowedCommands,
|
|
18
19
|
...(params.allowedMcpTools && params.allowedMcpTools.length > 0
|
|
19
20
|
? { allowed_mcp_tools: params.allowedMcpTools }
|
package/dist/cli.js
CHANGED
|
@@ -45,6 +45,7 @@ import { writeCurrentStep, } from "./cli/steps.js";
|
|
|
45
45
|
import { WORKER_RESULT_CONTRACT_VERSION, buildWorkerResult, persistWorkerRunArtifacts, isWorkerResult, buildWorkerFailureBlocker, formatAuditResultValidationError, } from "./cli/workerResult.js";
|
|
46
46
|
import { DISPATCH_RESULT_MAP_FILENAME, ACTIVE_DISPATCH_FILENAME, resolveRunScopedArg, loadDispatchResultMap, entriesByTaskId, buildPendingAuditTasks, prepareDispatchArtifacts, } from "./cli/dispatch.js";
|
|
47
47
|
import { readWaveManifest, writeWaveManifest, removeWaveManifest, buildWaveSlotEntry, } from "./cli/waveManifest.js";
|
|
48
|
+
import { buildLineIndex, buildLineIndexForPaths, addFileLineCountHints, } from "./cli/lineIndex.js";
|
|
48
49
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
49
50
|
const ADVANCE_AUDIT_CONTRACT_VERSION = "audit-code/v1alpha1";
|
|
50
51
|
const SAMPLE_REPO_FILES = [
|
|
@@ -114,45 +115,6 @@ function buildBlockedAuditState(params) {
|
|
|
114
115
|
: item),
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
|
-
async function buildLineIndex(root, repoManifest) {
|
|
118
|
-
const entries = [];
|
|
119
|
-
const batchSize = 25;
|
|
120
|
-
for (let i = 0; i < repoManifest.files.length; i += batchSize) {
|
|
121
|
-
const batch = repoManifest.files.slice(i, i + batchSize);
|
|
122
|
-
const results = await Promise.all(batch.map(async (file) => {
|
|
123
|
-
try {
|
|
124
|
-
return [
|
|
125
|
-
file.path,
|
|
126
|
-
await countLines(resolve(root, file.path)),
|
|
127
|
-
];
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
return [file.path, 0];
|
|
131
|
-
}
|
|
132
|
-
}));
|
|
133
|
-
entries.push(...results);
|
|
134
|
-
}
|
|
135
|
-
return Object.fromEntries(entries);
|
|
136
|
-
}
|
|
137
|
-
async function buildLineIndexForPaths(root, paths) {
|
|
138
|
-
const uniquePaths = [...new Set(paths)].sort();
|
|
139
|
-
const entries = await Promise.all(uniquePaths.map(async (path) => {
|
|
140
|
-
try {
|
|
141
|
-
return [path, await countLines(resolve(root, path))];
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
return [path, 0];
|
|
145
|
-
}
|
|
146
|
-
}));
|
|
147
|
-
return Object.fromEntries(entries);
|
|
148
|
-
}
|
|
149
|
-
async function addFileLineCountHints(root, tasks) {
|
|
150
|
-
const lineIndex = await buildLineIndexForPaths(root, tasks.flatMap((task) => task.file_paths));
|
|
151
|
-
return tasks.map((task) => ({
|
|
152
|
-
...task,
|
|
153
|
-
file_line_counts: Object.fromEntries(task.file_paths.map((path) => [path, lineIndex[path] ?? 0])),
|
|
154
|
-
}));
|
|
155
|
-
}
|
|
156
118
|
function activeReviewRunFromTask(artifactsDir, task) {
|
|
157
119
|
if (task.preferred_executor !== "agent" || !task.audit_results_path) {
|
|
158
120
|
return null;
|
|
@@ -937,6 +899,17 @@ async function renderSemanticReviewStep(params) {
|
|
|
937
899
|
runId: activeReviewRun.run_id,
|
|
938
900
|
allowedCommands: [mergeCommand, continueCommand],
|
|
939
901
|
allowedMcpTools: ["auditor_merge_and_ingest", "auditor_continue_audit"],
|
|
902
|
+
progress: {
|
|
903
|
+
summary: `Dispatching ${dispatch.packet_count} review packet(s) covering ` +
|
|
904
|
+
`${dispatch.task_count} task(s) in waves of ${dispatch.wave_size}` +
|
|
905
|
+
(dispatch.skipped_task_count > 0
|
|
906
|
+
? `; ${dispatch.skipped_task_count} task(s) already completed.`
|
|
907
|
+
: "."),
|
|
908
|
+
pending_packets: dispatch.packet_count,
|
|
909
|
+
pending_tasks: dispatch.task_count,
|
|
910
|
+
completed_tasks: dispatch.skipped_task_count,
|
|
911
|
+
wave_size: dispatch.wave_size,
|
|
912
|
+
},
|
|
940
913
|
stopCondition: "Dispatch every packet, run merge-and-ingest once, then run next-step.",
|
|
941
914
|
repoRoot: root,
|
|
942
915
|
artifactPaths: {
|