auditor-lambda 0.2.8 → 0.2.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/README.md +6 -0
- package/audit-code-wrapper-lib.mjs +1 -1
- package/dist/adapters/eslint.js +9 -5
- package/dist/cli.d.ts +42 -1
- package/dist/cli.js +114 -64
- package/dist/extractors/bucketing.d.ts +4 -0
- package/dist/extractors/bucketing.js +6 -2
- package/dist/extractors/disposition.d.ts +4 -0
- package/dist/extractors/disposition.js +6 -2
- package/dist/extractors/fileInventory.js +24 -28
- package/dist/extractors/flows.d.ts +5 -0
- package/dist/extractors/flows.js +18 -38
- package/dist/extractors/pathPatterns.d.ts +10 -3
- package/dist/extractors/pathPatterns.js +109 -61
- package/dist/extractors/surfaces.d.ts +4 -0
- package/dist/extractors/surfaces.js +11 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/io/artifacts.d.ts +55 -40
- package/dist/io/artifacts.js +73 -110
- package/dist/io/json.js +52 -21
- package/dist/io/runArtifacts.d.ts +1 -1
- package/dist/io/runArtifacts.js +26 -3
- package/dist/orchestrator/advance.js +83 -62
- package/dist/orchestrator/flowCoverage.js +11 -5
- package/dist/orchestrator/flowPlanning.d.ts +7 -2
- package/dist/orchestrator/flowPlanning.js +46 -21
- package/dist/orchestrator/flowRequeue.js +28 -8
- package/dist/orchestrator/internalExecutors.js +12 -8
- package/dist/orchestrator/planning.js +25 -3
- package/dist/orchestrator/requeue.js +11 -1
- package/dist/orchestrator/taskBuilder.d.ts +4 -2
- package/dist/orchestrator/taskBuilder.js +153 -52
- package/dist/orchestrator/unitBuilder.d.ts +3 -1
- package/dist/orchestrator/unitBuilder.js +24 -16
- package/dist/prompts/renderWorkerPrompt.d.ts +1 -1
- package/dist/prompts/renderWorkerPrompt.js +16 -8
- package/dist/providers/claudeCodeProvider.d.ts +4 -1
- package/dist/providers/claudeCodeProvider.js +8 -5
- package/dist/providers/localSubprocessProvider.d.ts +4 -0
- package/dist/providers/localSubprocessProvider.js +7 -2
- package/dist/providers/spawnLoggedCommand.d.ts +9 -1
- package/dist/providers/spawnLoggedCommand.js +77 -29
- package/dist/reporting/synthesis.d.ts +2 -0
- package/dist/reporting/synthesis.js +12 -9
- package/dist/supervisor/operatorHandoff.js +48 -18
- package/dist/supervisor/runLedger.d.ts +1 -1
- package/dist/supervisor/runLedger.js +112 -5
- package/dist/supervisor/sessionConfig.js +10 -10
- package/dist/types/externalAnalyzer.d.ts +3 -0
- package/dist/types/flowCoverage.d.ts +5 -1
- package/dist/types/flowCoverage.js +5 -1
- package/dist/types/flows.d.ts +5 -1
- package/dist/types/flows.js +1 -1
- package/dist/types/runLedger.d.ts +5 -1
- package/dist/types/runLedger.js +6 -1
- package/dist/types/runtimeValidation.d.ts +12 -3
- package/dist/types/runtimeValidation.js +16 -1
- package/dist/types/sessionConfig.d.ts +15 -2
- package/dist/types/sessionConfig.js +15 -1
- package/dist/types/surfaces.d.ts +4 -1
- package/dist/types/surfaces.js +1 -1
- package/dist/types/workerSession.d.ts +9 -0
- package/dist/types/workerSession.js +5 -1
- package/dist/validation/artifacts.d.ts +1 -1
- package/dist/validation/artifacts.js +33 -20
- package/dist/validation/auditResults.d.ts +2 -2
- package/dist/validation/auditResults.js +7 -15
- package/dist/validation/basic.d.ts +9 -1
- package/dist/validation/basic.js +40 -3
- package/dist/validation/sessionConfig.d.ts +4 -2
- package/dist/validation/sessionConfig.js +62 -15
- package/docs/agent-integrations.md +29 -9
- package/docs/next-steps.md +21 -4
- package/docs/packaging.md +14 -0
- package/docs/product-direction.md +22 -0
- package/docs/production-launch-bar.md +2 -0
- package/docs/releasing.md +17 -0
- package/docs/remediation-baseline.md +75 -0
- package/docs/run-flow.md +23 -11
- package/docs/session-config.md +50 -5
- package/docs/supervisor.md +7 -0
- package/docs/workflow-refactor-brief.md +177 -0
- package/package.json +1 -1
- package/schemas/audit_result.schema.json +4 -1
- package/schemas/audit_task.schema.json +3 -1
- package/schemas/coverage_matrix.schema.json +3 -3
- package/schemas/critical_flows.schema.json +6 -2
- package/schemas/file_disposition.schema.json +2 -2
- package/schemas/finding.schema.json +9 -4
- package/schemas/flow_coverage.schema.json +2 -2
- package/schemas/repo_manifest.schema.json +4 -4
- package/schemas/risk_register.schema.json +2 -2
- package/schemas/runtime_validation_report.schema.json +2 -2
- package/schemas/runtime_validation_tasks.schema.json +8 -2
- package/schemas/surface_manifest.schema.json +6 -3
- package/schemas/unit_manifest.schema.json +3 -2
- package/skills/audit-code/SKILL.md +5 -0
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Normal product usage should:
|
|
|
11
11
|
- use the active conversation model by default
|
|
12
12
|
- use project files and attached repository context by default
|
|
13
13
|
- avoid manual paths, provider flags, and model-selection arguments
|
|
14
|
+
- keep semantic review with the active conversation agent by default
|
|
14
15
|
- advance the audit automatically until it completes or no further automatic progress is possible
|
|
15
16
|
|
|
16
17
|
## Conversation Setup
|
|
@@ -86,6 +87,7 @@ This wrapper:
|
|
|
86
87
|
- auto-builds `dist/` if it is missing
|
|
87
88
|
- advances fresh worker sessions automatically until the audit completes or the remaining work requires imported results or an interactive provider
|
|
88
89
|
- continues through provider-assisted audit review automatically when `.audit-artifacts/session-config.json` selects an interactive provider bridge
|
|
90
|
+
- keeps those provider bridges as fallback compatibility modes rather than the primary product path
|
|
89
91
|
- emits `contract_version: "audit-code/v1alpha1"`
|
|
90
92
|
- refreshes `.audit-artifacts/operator-handoff.json` and `.audit-artifacts/operator-handoff.md` with suggested evidence-import paths and continuation hints
|
|
91
93
|
|
|
@@ -160,6 +162,7 @@ Optional backend config:
|
|
|
160
162
|
- use `audit-code` from the repository root only when you need the repo-local backend fallback
|
|
161
163
|
- use omitted provider or `local-subprocess` for the safest deterministic fallback behavior
|
|
162
164
|
- use `provider: "auto"` only when you want best-effort routing across installed backends
|
|
165
|
+
- treat explicit provider bridges as compatibility fallback, not as the intended owner of semantic review
|
|
163
166
|
|
|
164
167
|
## Implementation Next Steps
|
|
165
168
|
|
|
@@ -169,6 +172,7 @@ The next implementation work is tracked in:
|
|
|
169
172
|
|
|
170
173
|
The short version is:
|
|
171
174
|
|
|
175
|
+
- realign review dispatch around the conversation-owned, non-overlapping lens-block workflow
|
|
172
176
|
- prove the generated Codex, Claude Desktop, OpenCode, VS Code, and Antigravity guidance in real host flows
|
|
173
177
|
- tighten the repo-local MCP-first bootstrap where host smoke tests expose friction
|
|
174
178
|
- polish provider-assisted continuation and failure guidance
|
|
@@ -186,6 +190,8 @@ For GitHub Actions publication and npm Trusted Publishing setup, see `docs/relea
|
|
|
186
190
|
## Key Docs
|
|
187
191
|
|
|
188
192
|
- `docs/product-direction.md`
|
|
193
|
+
- `docs/workflow-refactor-brief.md`
|
|
194
|
+
- `docs/remediation-baseline.md`
|
|
189
195
|
- `docs/releasing.md`
|
|
190
196
|
- `docs/production-readiness.md`
|
|
191
197
|
- `docs/production-launch-bar.md`
|
|
@@ -2049,7 +2049,7 @@ async function installBootstrap(argv) {
|
|
|
2049
2049
|
|
|
2050
2050
|
const sessionConfigPath = join(root, '.audit-artifacts', 'session-config.json');
|
|
2051
2051
|
if (!(await fileExists(sessionConfigPath))) {
|
|
2052
|
-
const defaultConfig = { provider: '
|
|
2052
|
+
const defaultConfig = { provider: 'local-subprocess' };
|
|
2053
2053
|
await mkdir(dirname(sessionConfigPath), { recursive: true });
|
|
2054
2054
|
await writeFile(sessionConfigPath, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
|
|
2055
2055
|
results.push({ path: sessionConfigPath, mode: 'created' });
|
package/dist/adapters/eslint.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { normalizeGenericExternalResults } from "./normalizeExternal.js";
|
|
2
2
|
const ESLINT_SEVERITY_ERROR = 2;
|
|
3
3
|
const ESLINT_SEVERITY_WARNING = 1;
|
|
4
|
+
const ESLINT_SEVERITY_MAP = {
|
|
5
|
+
[ESLINT_SEVERITY_ERROR]: "medium",
|
|
6
|
+
[ESLINT_SEVERITY_WARNING]: "low",
|
|
7
|
+
};
|
|
4
8
|
function mapSeverity(value) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return "info";
|
|
9
|
+
// ESLint's JSON formatter emits 2 for errors and 1 for warnings.
|
|
10
|
+
if (typeof value !== "number") {
|
|
11
|
+
return "info";
|
|
12
|
+
}
|
|
13
|
+
return ESLINT_SEVERITY_MAP[value] ?? "info";
|
|
10
14
|
}
|
|
11
15
|
export function normalizeEslintJson(input) {
|
|
12
16
|
return normalizeGenericExternalResults("eslint", input.flatMap((file) => (file.messages ?? []).map((message, index) => ({
|
package/dist/cli.d.ts
CHANGED
|
@@ -1 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SessionConfig } from "./types/sessionConfig.js";
|
|
2
|
+
type UiMode = "visible" | "headless";
|
|
3
|
+
declare function getFlag(argv: string[], name: string, fallback?: string): string | undefined;
|
|
4
|
+
declare function hasFlag(argv: string[], name: string): boolean;
|
|
5
|
+
declare function getArtifactsDir(argv: string[]): string;
|
|
6
|
+
declare function getRootDir(argv: string[]): string;
|
|
7
|
+
declare function getBatchResultsDir(argv: string[]): string | undefined;
|
|
8
|
+
declare function getMaxRuns(argv: string[]): number;
|
|
9
|
+
declare function getAgentBatchSize(argv: string[], sessionConfig: SessionConfig): number;
|
|
10
|
+
declare function getParallelWorkers(argv: string[], sessionConfig: SessionConfig): number;
|
|
11
|
+
declare function getTimeoutMs(argv: string[], sessionConfig: SessionConfig): number;
|
|
12
|
+
declare function chunkArray<T>(arr: T[], size: number): T[][];
|
|
13
|
+
declare function getUiMode(argv: string[], fallback?: UiMode): UiMode;
|
|
14
|
+
declare function countLines(path: string): Promise<number>;
|
|
15
|
+
declare function looksLikeCliFlag(value: string | undefined): boolean;
|
|
16
|
+
export declare const cliTestUtils: {
|
|
17
|
+
defaults: {
|
|
18
|
+
rootDir: string;
|
|
19
|
+
artifactsDir: string;
|
|
20
|
+
maxRuns: number;
|
|
21
|
+
agentBatchSize: number;
|
|
22
|
+
parallelWorkers: number;
|
|
23
|
+
timeoutMs: number;
|
|
24
|
+
uiMode: UiMode;
|
|
25
|
+
};
|
|
26
|
+
getFlag: typeof getFlag;
|
|
27
|
+
hasFlag: typeof hasFlag;
|
|
28
|
+
getArtifactsDir: typeof getArtifactsDir;
|
|
29
|
+
getRootDir: typeof getRootDir;
|
|
30
|
+
getBatchResultsDir: typeof getBatchResultsDir;
|
|
31
|
+
getMaxRuns: typeof getMaxRuns;
|
|
32
|
+
getAgentBatchSize: typeof getAgentBatchSize;
|
|
33
|
+
getParallelWorkers: typeof getParallelWorkers;
|
|
34
|
+
getTimeoutMs: typeof getTimeoutMs;
|
|
35
|
+
chunkArray: typeof chunkArray;
|
|
36
|
+
getUiMode: typeof getUiMode;
|
|
37
|
+
looksLikeCliFlag: typeof looksLikeCliFlag;
|
|
38
|
+
countLines: typeof countLines;
|
|
39
|
+
};
|
|
40
|
+
export declare function runSample(argv?: string[]): Promise<void>;
|
|
41
|
+
export declare function runCli(argv: string[]): Promise<void>;
|
|
42
|
+
export {};
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { access, mkdir, readdir, rename } from "node:fs/promises";
|
|
2
2
|
import { createReadStream } from "node:fs";
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
import { buildRepoManifest } from "./extractors/fileInventory.js";
|
|
5
6
|
import { buildFileDisposition } from "./extractors/disposition.js";
|
|
6
7
|
import { buildCriticalFlowManifest } from "./extractors/flows.js";
|
|
@@ -13,6 +14,7 @@ import { loadArtifactBundle, writeCoreArtifacts, promoteFinalAuditReport, } from
|
|
|
13
14
|
import { readJsonFile, writeJsonFile } from "./io/json.js";
|
|
14
15
|
import { validateArtifactBundle } from "./validation/artifacts.js";
|
|
15
16
|
import { validateAuditResults, formatAuditResultIssues, } from "./validation/auditResults.js";
|
|
17
|
+
import { prefixValidationIssues } from "./validation/basic.js";
|
|
16
18
|
import { validateConfiguredProviderEnvironment, validateSessionConfig, } from "./validation/sessionConfig.js";
|
|
17
19
|
import { buildAuditReportModel, renderAuditReportMarkdown, } from "./reporting/synthesis.js";
|
|
18
20
|
import { deriveAuditState } from "./orchestrator/state.js";
|
|
@@ -28,78 +30,101 @@ import { LOCAL_SUBPROCESS_PROVIDER_NAME } from "./providers/constants.js";
|
|
|
28
30
|
import { runAuditCodeMcpServer } from "./mcp/server.js";
|
|
29
31
|
const ADVANCE_AUDIT_CONTRACT_VERSION = "audit-code/v1alpha1";
|
|
30
32
|
const WORKER_RESULT_CONTRACT_VERSION = "audit-code-worker-result/v1alpha1";
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
const DIRECT_CLI_DEFAULTS = {
|
|
34
|
+
rootDir: ".",
|
|
35
|
+
artifactsDir: ".artifacts",
|
|
36
|
+
maxRuns: 1000,
|
|
37
|
+
agentBatchSize: 1,
|
|
38
|
+
parallelWorkers: 1,
|
|
39
|
+
timeoutMs: 30 * 60 * 1000, // 30 minutes
|
|
40
|
+
uiMode: "headless",
|
|
41
|
+
};
|
|
42
|
+
// Keep the sample-run payload explicit so the demo command is deterministic.
|
|
43
|
+
const SAMPLE_REPO_FILES = [
|
|
34
44
|
{ path: "src/api/auth.ts", size_bytes: 1240, hash: "abc123" },
|
|
35
45
|
{ path: "src/lib/session.ts", size_bytes: 980, hash: "def456" },
|
|
36
46
|
{ path: "infra/deploy.yml", size_bytes: 420, hash: "ghi789" },
|
|
37
47
|
{ path: "docs/notes.md", size_bytes: 300, hash: "doc111" },
|
|
38
48
|
];
|
|
49
|
+
function isLongFlagToken(value) {
|
|
50
|
+
return typeof value === "string" && value.startsWith("--");
|
|
51
|
+
}
|
|
52
|
+
// Read a long-form CLI flag while treating a following flag token as "missing".
|
|
39
53
|
function getFlag(argv, name, fallback) {
|
|
40
54
|
const index = argv.indexOf(name);
|
|
41
|
-
if (index
|
|
42
|
-
return
|
|
43
|
-
|
|
55
|
+
if (index < 0)
|
|
56
|
+
return fallback;
|
|
57
|
+
const candidate = argv[index + 1];
|
|
58
|
+
if (!candidate || isLongFlagToken(candidate))
|
|
59
|
+
return fallback;
|
|
60
|
+
return candidate;
|
|
44
61
|
}
|
|
62
|
+
// Boolean flags only care whether the token is present at all.
|
|
45
63
|
function hasFlag(argv, name) {
|
|
46
64
|
return argv.includes(name);
|
|
47
65
|
}
|
|
66
|
+
function resolveFlagPath(argv, name, fallback) {
|
|
67
|
+
return resolve(getFlag(argv, name, fallback));
|
|
68
|
+
}
|
|
69
|
+
function normalizePositiveInteger(value) {
|
|
70
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return Math.floor(value);
|
|
74
|
+
}
|
|
75
|
+
function parsePositiveIntegerFlag(argv, name) {
|
|
76
|
+
const raw = getFlag(argv, name);
|
|
77
|
+
if (raw === undefined) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return normalizePositiveInteger(Number(raw));
|
|
81
|
+
}
|
|
48
82
|
function getArtifactsDir(argv) {
|
|
49
|
-
return
|
|
83
|
+
return resolveFlagPath(argv, "--artifacts-dir", DIRECT_CLI_DEFAULTS.artifactsDir);
|
|
50
84
|
}
|
|
51
85
|
function getRootDir(argv) {
|
|
52
|
-
return
|
|
86
|
+
return resolveFlagPath(argv, "--root", DIRECT_CLI_DEFAULTS.rootDir);
|
|
53
87
|
}
|
|
54
88
|
function getBatchResultsDir(argv) {
|
|
55
89
|
const value = getFlag(argv, "--batch-results");
|
|
56
90
|
return value ? resolve(value) : undefined;
|
|
57
91
|
}
|
|
58
92
|
function getMaxRuns(argv) {
|
|
59
|
-
|
|
60
|
-
return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : DEFAULT_MAX_RUNS;
|
|
93
|
+
return parsePositiveIntegerFlag(argv, "--max-runs") ?? DIRECT_CLI_DEFAULTS.maxRuns;
|
|
61
94
|
}
|
|
62
95
|
function getAgentBatchSize(argv, sessionConfig) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
67
|
-
return Math.floor(parsed);
|
|
68
|
-
}
|
|
69
|
-
if (typeof sessionConfig.agent_task_batch_size === "number" && sessionConfig.agent_task_batch_size > 0) {
|
|
70
|
-
return Math.floor(sessionConfig.agent_task_batch_size);
|
|
71
|
-
}
|
|
72
|
-
return 1;
|
|
96
|
+
return (parsePositiveIntegerFlag(argv, "--agent-batch-size") ??
|
|
97
|
+
normalizePositiveInteger(sessionConfig.agent_task_batch_size) ??
|
|
98
|
+
DIRECT_CLI_DEFAULTS.agentBatchSize);
|
|
73
99
|
}
|
|
74
100
|
function getParallelWorkers(argv, sessionConfig) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
79
|
-
return Math.floor(parsed);
|
|
80
|
-
}
|
|
81
|
-
if (typeof sessionConfig.parallel_workers === "number" && sessionConfig.parallel_workers > 0) {
|
|
82
|
-
return Math.floor(sessionConfig.parallel_workers);
|
|
83
|
-
}
|
|
84
|
-
return 1;
|
|
101
|
+
return (parsePositiveIntegerFlag(argv, "--parallel") ??
|
|
102
|
+
normalizePositiveInteger(sessionConfig.parallel_workers) ??
|
|
103
|
+
DIRECT_CLI_DEFAULTS.parallelWorkers);
|
|
85
104
|
}
|
|
86
105
|
function getTimeoutMs(argv, sessionConfig) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
return (parsePositiveIntegerFlag(argv, "--timeout") ??
|
|
107
|
+
normalizePositiveInteger(sessionConfig.timeout_ms) ??
|
|
108
|
+
DIRECT_CLI_DEFAULTS.timeoutMs);
|
|
109
|
+
}
|
|
110
|
+
function getExplicitProvider(argv) {
|
|
111
|
+
return getFlag(argv, "--provider");
|
|
112
|
+
}
|
|
113
|
+
function resolveRunProviderName(argv, sessionConfig) {
|
|
114
|
+
return resolveFreshSessionProviderName(getExplicitProvider(argv) ?? LOCAL_SUBPROCESS_PROVIDER_NAME, sessionConfig);
|
|
94
115
|
}
|
|
95
116
|
function chunkArray(arr, size) {
|
|
117
|
+
const chunkSize = normalizePositiveInteger(size);
|
|
118
|
+
if (chunkSize === undefined) {
|
|
119
|
+
throw new Error("chunkArray size must be a positive integer.");
|
|
120
|
+
}
|
|
96
121
|
const chunks = [];
|
|
97
|
-
for (let i = 0; i < arr.length; i +=
|
|
98
|
-
chunks.push(arr.slice(i, i +
|
|
122
|
+
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
123
|
+
chunks.push(arr.slice(i, i + chunkSize));
|
|
99
124
|
}
|
|
100
125
|
return chunks;
|
|
101
126
|
}
|
|
102
|
-
function getUiMode(argv, fallback =
|
|
127
|
+
function getUiMode(argv, fallback = DIRECT_CLI_DEFAULTS.uiMode) {
|
|
103
128
|
const raw = getFlag(argv, "--ui");
|
|
104
129
|
if (raw === "visible")
|
|
105
130
|
return "visible";
|
|
@@ -144,19 +169,9 @@ async function emitEnvelope(params) {
|
|
|
144
169
|
}
|
|
145
170
|
function buildManualReviewBlocker(providerName) {
|
|
146
171
|
return providerName === LOCAL_SUBPROCESS_PROVIDER_NAME
|
|
147
|
-
? "Automatic
|
|
172
|
+
? "Automatic backend steps are exhausted. Remaining semantic review now belongs to the active conversation agent. Review the dispatched files, write structured audit results, and run the generated worker command to ingest them. If you intentionally want a backend bridge instead, re-run audit-code with --provider auto, --provider claude-code, --provider opencode, --provider subprocess-template, or --provider vscode-task."
|
|
148
173
|
: "Automatic work is exhausted. Remaining audit tasks require explicit audit results or an interactive provider.";
|
|
149
174
|
}
|
|
150
|
-
function prefixValidationIssues(prefix, issues) {
|
|
151
|
-
return issues.map((issue) => ({
|
|
152
|
-
path: issue.path.length === 0
|
|
153
|
-
? prefix
|
|
154
|
-
: issue.path === prefix || issue.path.startsWith(`${prefix}.`)
|
|
155
|
-
? issue.path
|
|
156
|
-
: `${prefix}.${issue.path}`,
|
|
157
|
-
message: issue.message,
|
|
158
|
-
}));
|
|
159
|
-
}
|
|
160
175
|
function buildBlockedAuditState(params) {
|
|
161
176
|
return {
|
|
162
177
|
...params.state,
|
|
@@ -279,8 +294,24 @@ function buildWorkerFailureBlocker(workerResult) {
|
|
|
279
294
|
: workerResult.summary;
|
|
280
295
|
}
|
|
281
296
|
function looksLikeCliFlag(value) {
|
|
282
|
-
return
|
|
297
|
+
return isLongFlagToken(value);
|
|
283
298
|
}
|
|
299
|
+
export const cliTestUtils = {
|
|
300
|
+
defaults: DIRECT_CLI_DEFAULTS,
|
|
301
|
+
getFlag,
|
|
302
|
+
hasFlag,
|
|
303
|
+
getArtifactsDir,
|
|
304
|
+
getRootDir,
|
|
305
|
+
getBatchResultsDir,
|
|
306
|
+
getMaxRuns,
|
|
307
|
+
getAgentBatchSize,
|
|
308
|
+
getParallelWorkers,
|
|
309
|
+
getTimeoutMs,
|
|
310
|
+
chunkArray,
|
|
311
|
+
getUiMode,
|
|
312
|
+
looksLikeCliFlag,
|
|
313
|
+
countLines,
|
|
314
|
+
};
|
|
284
315
|
async function maybeArchiveLegacyPendingResults(auditResultsPath) {
|
|
285
316
|
if (!auditResultsPath || basename(auditResultsPath) !== "worker_results_pending.json") {
|
|
286
317
|
return undefined;
|
|
@@ -388,8 +419,8 @@ function isWorkerResult(value) {
|
|
|
388
419
|
value.contract_version ===
|
|
389
420
|
WORKER_RESULT_CONTRACT_VERSION);
|
|
390
421
|
}
|
|
391
|
-
export async function runSample() {
|
|
392
|
-
const repoManifest = buildRepoManifest("sample-repo",
|
|
422
|
+
export async function runSample(argv = process.argv) {
|
|
423
|
+
const repoManifest = buildRepoManifest("sample-repo", SAMPLE_REPO_FILES);
|
|
393
424
|
const disposition = buildFileDisposition(repoManifest);
|
|
394
425
|
const unitManifest = buildUnitManifest(repoManifest, disposition);
|
|
395
426
|
const surfaceManifest = buildSurfaceManifest(repoManifest, disposition);
|
|
@@ -444,7 +475,7 @@ export async function runSample() {
|
|
|
444
475
|
audit_results: sampleResults,
|
|
445
476
|
audit_report: auditReport,
|
|
446
477
|
});
|
|
447
|
-
const artifactsDir = getArtifactsDir(
|
|
478
|
+
const artifactsDir = getArtifactsDir(argv);
|
|
448
479
|
await mkdir(artifactsDir, { recursive: true });
|
|
449
480
|
await writeCoreArtifacts(artifactsDir, {
|
|
450
481
|
repo_manifest: repoManifest,
|
|
@@ -466,7 +497,7 @@ async function cmdAdvanceAudit(argv) {
|
|
|
466
497
|
const root = getRootDir(argv);
|
|
467
498
|
const artifactsDir = getArtifactsDir(argv);
|
|
468
499
|
const sessionConfig = await loadSessionConfig(artifactsDir);
|
|
469
|
-
const providerName =
|
|
500
|
+
const providerName = resolveRunProviderName(argv, sessionConfig);
|
|
470
501
|
const batchResultsDir = getBatchResultsDir(argv);
|
|
471
502
|
if (batchResultsDir && getFlag(argv, "--results")) {
|
|
472
503
|
throw new Error("Use either --results <file> or --batch-results <dir>, not both.");
|
|
@@ -532,13 +563,14 @@ async function cmdRunToCompletion(argv) {
|
|
|
532
563
|
const root = getRootDir(argv);
|
|
533
564
|
const artifactsDir = getArtifactsDir(argv);
|
|
534
565
|
const sessionConfig = await loadSessionConfig(artifactsDir);
|
|
535
|
-
const
|
|
566
|
+
const explicitProvider = getExplicitProvider(argv);
|
|
567
|
+
const provider = createFreshSessionProvider(explicitProvider ?? LOCAL_SUBPROCESS_PROVIDER_NAME, sessionConfig);
|
|
536
568
|
const uiMode = getUiMode(argv, sessionConfig.ui_mode ?? "headless");
|
|
537
569
|
const maxRuns = getMaxRuns(argv);
|
|
538
570
|
const agentBatchSize = getAgentBatchSize(argv, sessionConfig);
|
|
539
571
|
const parallelWorkers = getParallelWorkers(argv, sessionConfig);
|
|
540
572
|
const timeoutMs = getTimeoutMs(argv, sessionConfig);
|
|
541
|
-
const selfCliPath = resolve(process.argv[1] ?? "");
|
|
573
|
+
const selfCliPath = resolve(argv[1] ?? process.argv[1] ?? "");
|
|
542
574
|
await mkdir(artifactsDir, { recursive: true });
|
|
543
575
|
await ensureSupervisorDirs(artifactsDir);
|
|
544
576
|
const batchResultsDir = getBatchResultsDir(argv);
|
|
@@ -646,6 +678,8 @@ async function cmdRunToCompletion(argv) {
|
|
|
646
678
|
],
|
|
647
679
|
audit_results_path: blockAuditResultsPath,
|
|
648
680
|
pending_audit_tasks_path: blockPendingTasksPath,
|
|
681
|
+
timeout_ms: timeoutMs,
|
|
682
|
+
max_retries: 0,
|
|
649
683
|
};
|
|
650
684
|
const blockPrompt = renderWorkerPrompt(blockTask);
|
|
651
685
|
await writeWorkerTaskFiles(blockTask, blockPrompt, blockPaths, artifactsDir, blockPendingTasks);
|
|
@@ -716,7 +750,9 @@ async function cmdRunToCompletion(argv) {
|
|
|
716
750
|
worker_command: [process.execPath, selfCliPath, "worker-run", "--task", slotPaths.taskPath],
|
|
717
751
|
audit_results_path: slotAuditResultsPath,
|
|
718
752
|
pending_audit_tasks_path: slotPendingTasksPath,
|
|
719
|
-
|
|
753
|
+
worker_command_mode: "deferred",
|
|
754
|
+
timeout_ms: timeoutMs,
|
|
755
|
+
max_retries: 0,
|
|
720
756
|
};
|
|
721
757
|
const slotPrompt = renderWorkerPrompt(slotTask);
|
|
722
758
|
await writeWorkerTaskFiles(slotTask, slotPrompt, slotPaths, artifactsDir, group);
|
|
@@ -888,6 +924,8 @@ async function cmdRunToCompletion(argv) {
|
|
|
888
924
|
pending_audit_tasks_path: pendingAuditTasksPath,
|
|
889
925
|
runtime_updates_path: runtimeUpdatesPath,
|
|
890
926
|
external_analyzer_results_path: externalAnalyzerPath,
|
|
927
|
+
timeout_ms: timeoutMs,
|
|
928
|
+
max_retries: 0,
|
|
891
929
|
};
|
|
892
930
|
const prompt = renderWorkerPrompt(task);
|
|
893
931
|
await writeWorkerTaskFiles(task, prompt, paths, artifactsDir, pendingAuditTasks);
|
|
@@ -1317,7 +1355,7 @@ async function main(argv) {
|
|
|
1317
1355
|
const command = argv[2] ?? "sample-run";
|
|
1318
1356
|
switch (command) {
|
|
1319
1357
|
case "sample-run":
|
|
1320
|
-
await runSample();
|
|
1358
|
+
await runSample(argv);
|
|
1321
1359
|
return;
|
|
1322
1360
|
case "advance-audit":
|
|
1323
1361
|
await cmdAdvanceAudit(argv);
|
|
@@ -1367,7 +1405,19 @@ async function main(argv) {
|
|
|
1367
1405
|
process.exitCode = 1;
|
|
1368
1406
|
}
|
|
1369
1407
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1408
|
+
export async function runCli(argv) {
|
|
1409
|
+
await main(argv).catch((error) => {
|
|
1410
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
1411
|
+
process.exitCode = 1;
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
function isDirectCliExecution(argv) {
|
|
1415
|
+
const entryPath = argv[1];
|
|
1416
|
+
if (!entryPath) {
|
|
1417
|
+
return false;
|
|
1418
|
+
}
|
|
1419
|
+
return resolve(entryPath) === fileURLToPath(import.meta.url);
|
|
1420
|
+
}
|
|
1421
|
+
if (isDirectCliExecution(process.argv)) {
|
|
1422
|
+
await runCli(process.argv);
|
|
1423
|
+
}
|
|
@@ -4,4 +4,8 @@ export interface BucketAssignment {
|
|
|
4
4
|
buckets: FileBucket[];
|
|
5
5
|
rationale: string[];
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Buckets files using the shared extractor heuristics so intake stays
|
|
9
|
+
* consistent across OS-specific path separators and mixed-case manifests.
|
|
10
|
+
*/
|
|
7
11
|
export declare function bucketFile(path: string): BucketAssignment;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { isNodeModulesOrGit, isTestPath, isInterfacePath, isDataLayerPath, isSecuritySensitivePath, isConcurrencyPath, isScriptPath, isDeploymentConfigPath, isDocPath, isGeneratedPath, } from "./pathPatterns.js";
|
|
1
|
+
import { isNodeModulesOrGit, isTestPath, isInterfacePath, isDataLayerPath, isSecuritySensitivePath, isConcurrencyPath, isScriptPath, isDeploymentConfigPath, isDocPath, isGeneratedPath, normalizeExtractorPath, } from "./pathPatterns.js";
|
|
2
2
|
function addBucket(buckets, rationale, bucket, reason) {
|
|
3
3
|
if (!buckets.has(bucket)) {
|
|
4
4
|
buckets.add(bucket);
|
|
5
5
|
rationale.push(reason);
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Buckets files using the shared extractor heuristics so intake stays
|
|
10
|
+
* consistent across OS-specific path separators and mixed-case manifests.
|
|
11
|
+
*/
|
|
8
12
|
export function bucketFile(path) {
|
|
9
|
-
const normalized = path
|
|
13
|
+
const normalized = normalizeExtractorPath(path);
|
|
10
14
|
const buckets = new Set();
|
|
11
15
|
const rationale = [];
|
|
12
16
|
if (isNodeModulesOrGit(normalized)) {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { RepoManifest } from "../types.js";
|
|
2
2
|
import type { FileDisposition, FileDispositionStatus } from "../types/disposition.js";
|
|
3
|
+
/**
|
|
4
|
+
* Applies shared path heuristics to mark files that should be excluded or
|
|
5
|
+
* down-scoped before audit planning begins.
|
|
6
|
+
*/
|
|
3
7
|
export declare function buildFileDisposition(repoManifest: RepoManifest): FileDisposition;
|
|
4
8
|
export declare function isAuditExcludedStatus(status: FileDispositionStatus): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { isNodeModulesOrGit, isBuildOutput, isVendorPath, isBinaryArtifact, isLicensePath, isLockfilePath, isLogPath, isDocPath, } from "./pathPatterns.js";
|
|
1
|
+
import { isNodeModulesOrGit, isBuildOutput, isVendorPath, isBinaryArtifact, isLicensePath, isLockfilePath, isLogPath, isDocPath, normalizeExtractorPath, } from "./pathPatterns.js";
|
|
2
2
|
function inferDisposition(path) {
|
|
3
|
-
const normalized = path
|
|
3
|
+
const normalized = normalizeExtractorPath(path);
|
|
4
4
|
if (isNodeModulesOrGit(normalized)) {
|
|
5
5
|
return { path, status: "excluded", reason: "node_modules or .git excluded by convention." };
|
|
6
6
|
}
|
|
@@ -35,6 +35,10 @@ function inferDisposition(path) {
|
|
|
35
35
|
reason: "Default included source or config artifact.",
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Applies shared path heuristics to mark files that should be excluded or
|
|
40
|
+
* down-scoped before audit planning begins.
|
|
41
|
+
*/
|
|
38
42
|
export function buildFileDisposition(repoManifest) {
|
|
39
43
|
return {
|
|
40
44
|
files: repoManifest.files.map((file) => inferDisposition(file.path)),
|
|
@@ -1,32 +1,28 @@
|
|
|
1
|
+
import { normalizeExtractorPath } from "./pathPatterns.js";
|
|
2
|
+
const LANGUAGE_BY_EXTENSION = {
|
|
3
|
+
ts: "typescript",
|
|
4
|
+
tsx: "typescript",
|
|
5
|
+
mts: "typescript",
|
|
6
|
+
cts: "typescript",
|
|
7
|
+
js: "javascript",
|
|
8
|
+
jsx: "javascript",
|
|
9
|
+
mjs: "javascript",
|
|
10
|
+
cjs: "javascript",
|
|
11
|
+
py: "python",
|
|
12
|
+
go: "go",
|
|
13
|
+
rs: "rust",
|
|
14
|
+
java: "java",
|
|
15
|
+
cs: "csharp",
|
|
16
|
+
json: "json",
|
|
17
|
+
yml: "yaml",
|
|
18
|
+
yaml: "yaml",
|
|
19
|
+
md: "markdown",
|
|
20
|
+
};
|
|
1
21
|
function inferLanguage(path) {
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return "typescript";
|
|
7
|
-
case "js":
|
|
8
|
-
case "jsx":
|
|
9
|
-
return "javascript";
|
|
10
|
-
case "py":
|
|
11
|
-
return "python";
|
|
12
|
-
case "go":
|
|
13
|
-
return "go";
|
|
14
|
-
case "rs":
|
|
15
|
-
return "rust";
|
|
16
|
-
case "java":
|
|
17
|
-
return "java";
|
|
18
|
-
case "cs":
|
|
19
|
-
return "csharp";
|
|
20
|
-
case "json":
|
|
21
|
-
return "json";
|
|
22
|
-
case "yml":
|
|
23
|
-
case "yaml":
|
|
24
|
-
return "yaml";
|
|
25
|
-
case "md":
|
|
26
|
-
return "markdown";
|
|
27
|
-
default:
|
|
28
|
-
return "unknown";
|
|
29
|
-
}
|
|
22
|
+
const normalized = normalizeExtractorPath(path);
|
|
23
|
+
const base = normalized.split("/").pop() ?? normalized;
|
|
24
|
+
const extension = base.includes(".") ? base.split(".").pop() ?? "" : "";
|
|
25
|
+
return LANGUAGE_BY_EXTENSION[extension] ?? "unknown";
|
|
30
26
|
}
|
|
31
27
|
export function buildRepoManifest(repositoryName, files) {
|
|
32
28
|
return {
|
|
@@ -2,4 +2,9 @@ import type { RepoManifest } from "../types.js";
|
|
|
2
2
|
import type { FileDisposition } from "../types/disposition.js";
|
|
3
3
|
import type { CriticalFlowManifest } from "../types/flows.js";
|
|
4
4
|
import type { SurfaceManifest } from "../types/surfaces.js";
|
|
5
|
+
/**
|
|
6
|
+
* Builds coarse critical-flow coverage from shared path heuristics. These
|
|
7
|
+
* bootstrap flows are intentionally conservative and should be reviewed when a
|
|
8
|
+
* repo uses unconventional naming or layout conventions.
|
|
9
|
+
*/
|
|
5
10
|
export declare function buildCriticalFlowManifest(repoManifest: RepoManifest, surfaceManifest: SurfaceManifest, disposition?: FileDisposition): CriticalFlowManifest;
|