auditor-lambda 0.9.1 → 0.10.0
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 -9
- package/audit-code-wrapper-lib.mjs +19 -915
- package/dispatch/merge-results.mjs +1 -1
- package/dist/cli/auditStep.d.ts +1 -33
- package/dist/cli/dispatch.d.ts +47 -0
- package/dist/cli/dispatch.js +116 -1
- package/dist/cli/mergeAndIngestCommand.js +55 -8
- package/dist/cli/nextStepCommand.js +43 -15
- package/dist/cli/prompts.d.ts +2 -0
- package/dist/cli/prompts.js +9 -0
- package/dist/cli/reviewRun.js +1 -1
- package/dist/cli/runToCompletion.js +21 -8
- package/dist/cli/semanticReviewStep.js +12 -1
- package/dist/cli/steps.d.ts +15 -0
- package/dist/cli.js +1 -8
- package/dist/io/artifacts.d.ts +9 -1
- package/dist/io/artifacts.js +7 -0
- package/dist/io/runArtifacts.d.ts +14 -0
- package/dist/io/runArtifacts.js +23 -0
- package/dist/orchestrator/designReviewPrompt.d.ts +4 -1
- package/dist/orchestrator/designReviewPrompt.js +43 -2
- package/dist/orchestrator/executorResult.d.ts +25 -0
- package/dist/orchestrator/intakeExecutors.d.ts +19 -1
- package/dist/orchestrator/intakeExecutors.js +89 -3
- package/dist/orchestrator/nextStep.d.ts +1 -0
- package/dist/orchestrator/nextStep.js +1 -1
- package/dist/orchestrator/state.js +8 -1
- package/dist/providers/constants.d.ts +1 -1
- package/dist/providers/constants.js +1 -1
- package/dist/reporting/synthesis.d.ts +8 -0
- package/dist/reporting/synthesis.js +16 -1
- package/dist/supervisor/operatorHandoff.js +8 -1
- package/dist/types/auditScope.d.ts +16 -2
- package/dist/validation/sessionConfig.js +35 -0
- package/docs/contracts.md +0 -16
- package/docs/operator-guide.md +6 -8
- package/package.json +1 -1
- package/schemas/audit_findings.schema.json +1 -0
- package/scripts/postinstall.mjs +0 -174
- package/skills/audit-code/SKILL.md +17 -1
- package/skills/audit-code/audit-code.prompt.md +25 -0
- package/dist/mcp/server.d.ts +0 -72
- package/dist/mcp/server.js +0 -765
|
@@ -164,7 +164,9 @@ export function validateSessionConfig(value) {
|
|
|
164
164
|
}
|
|
165
165
|
validateTemplateProviderSection(value.subprocess_template, "subprocess_template", issues, provider === "subprocess-template");
|
|
166
166
|
validateTemplateProviderSection(value.vscode_task, "vscode_task", issues, provider === "vscode-task");
|
|
167
|
+
validateTemplateProviderSection(value.antigravity, "antigravity", issues, provider === "antigravity");
|
|
167
168
|
validateAgentProviderSection(value.claude_code, "claude_code", issues);
|
|
169
|
+
validateAgentProviderSection(value.codex, "codex", issues);
|
|
168
170
|
validateAgentProviderSection(value.opencode, "opencode", issues);
|
|
169
171
|
if (value.synthesis !== undefined) {
|
|
170
172
|
if (!isRecord(value.synthesis)) {
|
|
@@ -175,6 +177,27 @@ export function validateSessionConfig(value) {
|
|
|
175
177
|
pushIssue(issues, "synthesis.narrative", "synthesis.narrative must be a boolean when provided.");
|
|
176
178
|
}
|
|
177
179
|
}
|
|
180
|
+
if (value.dispatch !== undefined) {
|
|
181
|
+
if (!isRecord(value.dispatch)) {
|
|
182
|
+
pushIssue(issues, "dispatch", "dispatch must be a JSON object.");
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
if (value.dispatch.canary !== undefined &&
|
|
186
|
+
typeof value.dispatch.canary !== "boolean") {
|
|
187
|
+
pushIssue(issues, "dispatch.canary", "dispatch.canary must be a boolean when provided.");
|
|
188
|
+
}
|
|
189
|
+
if (value.dispatch.confirm_threshold !== undefined &&
|
|
190
|
+
(!Number.isInteger(value.dispatch.confirm_threshold) ||
|
|
191
|
+
Number(value.dispatch.confirm_threshold) < 0)) {
|
|
192
|
+
pushIssue(issues, "dispatch.confirm_threshold", "dispatch.confirm_threshold must be a non-negative integer when provided.");
|
|
193
|
+
}
|
|
194
|
+
if (value.dispatch.max_packets !== undefined &&
|
|
195
|
+
(!Number.isInteger(value.dispatch.max_packets) ||
|
|
196
|
+
Number(value.dispatch.max_packets) < 0)) {
|
|
197
|
+
pushIssue(issues, "dispatch.max_packets", "dispatch.max_packets must be a non-negative integer when provided.");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
178
201
|
if (value.analyzers !== undefined) {
|
|
179
202
|
if (!isRecord(value.analyzers)) {
|
|
180
203
|
pushIssue(issues, "analyzers", "analyzers must be a JSON object mapping analyzer id to a setting.");
|
|
@@ -219,6 +242,18 @@ export async function validateConfiguredProviderEnvironment(sessionConfig, optio
|
|
|
219
242
|
pushIssue(issues, "opencode.command", "Configured opencode command must be a bare executable name or direct path. Put CLI flags in extra_args.");
|
|
220
243
|
}
|
|
221
244
|
}
|
|
245
|
+
if (provider === "codex") {
|
|
246
|
+
const command = sessionConfig.codex?.command ?? "codex";
|
|
247
|
+
if (isBareExecutableName(command) && !(await lookupCommand(command))) {
|
|
248
|
+
pushIssue(issues, "codex.command", `Configured codex executable was not found on PATH: ${command}.`);
|
|
249
|
+
}
|
|
250
|
+
else if (isDirectExecutablePath(command) && !lookupPath(command)) {
|
|
251
|
+
pushIssue(issues, "codex.command", `Configured codex executable path does not exist: ${command}.`);
|
|
252
|
+
}
|
|
253
|
+
else if (!isSupportedConfiguredCommand(command)) {
|
|
254
|
+
pushIssue(issues, "codex.command", "Configured codex command must be a bare executable name or direct path. Put CLI flags in extra_args.");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
222
257
|
return issues;
|
|
223
258
|
}
|
|
224
259
|
export { formatValidationIssues } from "@audit-tools/shared";
|
package/docs/contracts.md
CHANGED
|
@@ -214,22 +214,6 @@ Review packets may expose graph-derived context for workers:
|
|
|
214
214
|
- `quality` metrics for cohesion, internal edges, boundary edges, and
|
|
215
215
|
unexplained files
|
|
216
216
|
|
|
217
|
-
## MCP contract
|
|
218
|
-
|
|
219
|
-
The local MCP server exposes:
|
|
220
|
-
|
|
221
|
-
- `start_audit`
|
|
222
|
-
- `get_status`
|
|
223
|
-
- `continue_audit`
|
|
224
|
-
- `explain_task`
|
|
225
|
-
- `validate_artifacts`
|
|
226
|
-
- `import_results`
|
|
227
|
-
- `import_runtime_updates`
|
|
228
|
-
|
|
229
|
-
It also exposes resources for current artifacts, operator handoff, install
|
|
230
|
-
guidance, and the current report. MCP consumers should prefer the tool and
|
|
231
|
-
resource contracts over reading internal files directly.
|
|
232
|
-
|
|
233
217
|
## Guided recovery
|
|
234
218
|
|
|
235
219
|
Failure responses should distinguish:
|
package/docs/operator-guide.md
CHANGED
|
@@ -43,9 +43,9 @@ Host-specific files may include:
|
|
|
43
43
|
|
|
44
44
|
- Codex: managed `AGENTS.md` fallback guidance
|
|
45
45
|
- Claude Desktop: project template, remote MCP connector, local MCP bundle
|
|
46
|
-
- OpenCode: `opencode.json` with auditor
|
|
46
|
+
- OpenCode: `opencode.json` with auditor agent and permission wiring; the `/audit-code` command is global npm-installed state
|
|
47
47
|
- VS Code/Copilot: prompt, custom agent, instructions, and `.vscode/mcp.json`
|
|
48
|
-
- Antigravity: planning-mode
|
|
48
|
+
- Antigravity: planning-mode guidance
|
|
49
49
|
|
|
50
50
|
Use `.audit-code/install/GETTING-STARTED.md` as the repo-local handoff after
|
|
51
51
|
bootstrap.
|
|
@@ -61,18 +61,17 @@ repo-local `AGENTS.md` fallback guidance. The installed skill includes
|
|
|
61
61
|
`agents/openai.yaml` metadata so Codex can keep the slash-list display aligned
|
|
62
62
|
with the canonical `/audit-code` spelling.
|
|
63
63
|
|
|
64
|
-
Claude Desktop is treated as
|
|
64
|
+
Claude Desktop is treated as a bundle-install host. Use the generated project
|
|
65
65
|
template and local bundle artifacts when installing the integration.
|
|
66
66
|
|
|
67
67
|
OpenCode uses the global command seeded by `npm install -g auditor-lambda`.
|
|
68
68
|
The generated project `opencode.json` should not define `command["audit-code"]`;
|
|
69
|
-
it only wires the auditor
|
|
69
|
+
it only wires the auditor agent and project permissions. VS Code uses
|
|
70
70
|
repo-local prompt and MCP configuration files.
|
|
71
71
|
|
|
72
72
|
Antigravity should be treated as a workflow-and-artifacts host until it has a
|
|
73
|
-
stable project-local config surface. Use generated planning-mode guidance
|
|
74
|
-
|
|
75
|
-
terminal when needed.
|
|
73
|
+
stable project-local config surface. Use generated planning-mode guidance
|
|
74
|
+
or the backend fallback from an Antigravity-managed terminal when needed.
|
|
76
75
|
|
|
77
76
|
Manual prompt-import hosts can use:
|
|
78
77
|
|
|
@@ -110,7 +109,6 @@ audit-code --external-analyzer-results /path/to/external_analyzer_results.json
|
|
|
110
109
|
audit-code explain-task <task_id>
|
|
111
110
|
audit-code validate
|
|
112
111
|
audit-code cleanup
|
|
113
|
-
audit-code mcp
|
|
114
112
|
```
|
|
115
113
|
|
|
116
114
|
`audit-code next-step` is the backend-rendered step engine used by the
|
package/package.json
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"audited_file_count": { "type": "integer", "minimum": 0 },
|
|
28
28
|
"excluded_file_count": { "type": "integer", "minimum": 0 },
|
|
29
|
+
"budget_deferred_task_count": { "type": "integer", "minimum": 0 },
|
|
29
30
|
"runtime_validation_status_breakdown": {
|
|
30
31
|
"type": "object",
|
|
31
32
|
"additionalProperties": { "type": "integer", "minimum": 0 }
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -92,114 +92,6 @@ function renderOpenCodeExternalDirectoryPermission() {
|
|
|
92
92
|
return { '*': 'allow' };
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
function renderGlobalMcpLauncher(installedPkgRoot) {
|
|
96
|
-
return [
|
|
97
|
-
"import { access, readFile, appendFile } from 'node:fs/promises';",
|
|
98
|
-
"import { constants } from 'node:fs';",
|
|
99
|
-
"import { spawn } from 'node:child_process';",
|
|
100
|
-
"import { join } from 'node:path';",
|
|
101
|
-
"import { homedir } from 'node:os';",
|
|
102
|
-
'',
|
|
103
|
-
"const repoRoot = process.env.AUDIT_CODE_REPO_ROOT || process.cwd();",
|
|
104
|
-
"const artifactsDir = process.env.AUDIT_CODE_ARTIFACTS_DIR || join(repoRoot, '.audit-artifacts');",
|
|
105
|
-
`const globalPackageRoot = ${JSON.stringify(installedPkgRoot)};`,
|
|
106
|
-
"const logPath = join(homedir(), '.audit-code', 'mcp-server.log');",
|
|
107
|
-
'',
|
|
108
|
-
'async function log(msg) {',
|
|
109
|
-
' try {',
|
|
110
|
-
' const ts = new Date().toISOString();',
|
|
111
|
-
" await appendFile(logPath, `${ts} ${msg}\\n`, 'utf8');",
|
|
112
|
-
' } catch {',
|
|
113
|
-
' // ignore log failures',
|
|
114
|
-
' }',
|
|
115
|
-
'}',
|
|
116
|
-
'',
|
|
117
|
-
'async function exists(path) {',
|
|
118
|
-
' try {',
|
|
119
|
-
' await access(path, constants.F_OK);',
|
|
120
|
-
' return true;',
|
|
121
|
-
' } catch {',
|
|
122
|
-
' return false;',
|
|
123
|
-
' }',
|
|
124
|
-
'}',
|
|
125
|
-
'',
|
|
126
|
-
'function spawnForward(command, args) {',
|
|
127
|
-
' return new Promise((resolvePromise, rejectPromise) => {',
|
|
128
|
-
' const child = spawn(command, args, {',
|
|
129
|
-
' cwd: repoRoot,',
|
|
130
|
-
' env: process.env,',
|
|
131
|
-
" stdio: ['inherit', 'inherit', 'inherit'],",
|
|
132
|
-
' });',
|
|
133
|
-
" child.on('error', rejectPromise);",
|
|
134
|
-
" child.on('exit', (code) => resolvePromise(code ?? 1));",
|
|
135
|
-
' });',
|
|
136
|
-
'}',
|
|
137
|
-
'',
|
|
138
|
-
'async function tryCandidates() {',
|
|
139
|
-
" const localPackageEntrypoint = join(repoRoot, 'node_modules', 'auditor-lambda', 'audit-code.mjs');",
|
|
140
|
-
" const localBin = process.platform === 'win32'",
|
|
141
|
-
" ? join(repoRoot, 'node_modules', '.bin', 'audit-code.cmd')",
|
|
142
|
-
" : join(repoRoot, 'node_modules', '.bin', 'audit-code');",
|
|
143
|
-
" const repoPackageJsonPath = join(repoRoot, 'package.json');",
|
|
144
|
-
" const globalPackageEntrypoint = globalPackageRoot ? join(globalPackageRoot, 'audit-code.mjs') : null;",
|
|
145
|
-
" const sharedArgs = ['mcp', '--root', repoRoot, '--artifacts-dir', artifactsDir];",
|
|
146
|
-
'',
|
|
147
|
-
' if (await exists(localPackageEntrypoint)) {',
|
|
148
|
-
" await log(`launching local node_modules candidate: ${localPackageEntrypoint}`);",
|
|
149
|
-
' return await spawnForward(process.execPath, [localPackageEntrypoint, ...sharedArgs]);',
|
|
150
|
-
' }',
|
|
151
|
-
'',
|
|
152
|
-
" if (await exists(repoPackageJsonPath) && await exists(join(repoRoot, 'audit-code.mjs'))) {",
|
|
153
|
-
' try {',
|
|
154
|
-
" const packageJson = JSON.parse(await readFile(repoPackageJsonPath, 'utf8'));",
|
|
155
|
-
" if (packageJson?.name === 'auditor-lambda') {",
|
|
156
|
-
" await log(`launching repo-root candidate: ${join(repoRoot, 'audit-code.mjs')}`);",
|
|
157
|
-
" return await spawnForward(process.execPath, [join(repoRoot, 'audit-code.mjs'), ...sharedArgs]);",
|
|
158
|
-
' }',
|
|
159
|
-
' } catch {',
|
|
160
|
-
' // fall through to the next candidate',
|
|
161
|
-
' }',
|
|
162
|
-
' }',
|
|
163
|
-
'',
|
|
164
|
-
' if (globalPackageEntrypoint && await exists(globalPackageEntrypoint)) {',
|
|
165
|
-
" await log(`launching global candidate: ${globalPackageEntrypoint}`);",
|
|
166
|
-
' return await spawnForward(process.execPath, [globalPackageEntrypoint, ...sharedArgs]);',
|
|
167
|
-
' }',
|
|
168
|
-
'',
|
|
169
|
-
' if (await exists(localBin)) {',
|
|
170
|
-
" await log(`launching local bin candidate: ${localBin}`);",
|
|
171
|
-
' return await spawnForward(localBin, sharedArgs);',
|
|
172
|
-
' }',
|
|
173
|
-
'',
|
|
174
|
-
" const pathCandidate = process.platform === 'win32' ? 'audit-code.cmd' : 'audit-code';",
|
|
175
|
-
" await log(`trying PATH candidate: ${pathCandidate}`);",
|
|
176
|
-
' let exitCode = await spawnForward(pathCandidate, sharedArgs).catch(() => null);',
|
|
177
|
-
" if (typeof exitCode === 'number') {",
|
|
178
|
-
' return exitCode;',
|
|
179
|
-
' }',
|
|
180
|
-
'',
|
|
181
|
-
" exitCode = await spawnForward('npx', ['--no-install', 'audit-code', ...sharedArgs]).catch(() => null);",
|
|
182
|
-
" if (typeof exitCode === 'number') {",
|
|
183
|
-
' return exitCode;',
|
|
184
|
-
' }',
|
|
185
|
-
'',
|
|
186
|
-
" await log('ERROR: no candidate found');",
|
|
187
|
-
' throw new Error(',
|
|
188
|
-
" 'Unable to locate an audit-code executable. Install auditor-lambda globally or as a local dependency.',",
|
|
189
|
-
' );',
|
|
190
|
-
'}',
|
|
191
|
-
'',
|
|
192
|
-
"log(`run-mcp-server.mjs started: node=${process.execPath} cwd=${repoRoot} globalPkg=${globalPackageRoot}`).catch(() => {});",
|
|
193
|
-
'const code = await tryCandidates().catch(async (err) => {',
|
|
194
|
-
" await log(`FATAL: ${err.message}`);",
|
|
195
|
-
' process.stderr.write(err.message + "\\n");',
|
|
196
|
-
' return 1;',
|
|
197
|
-
'});',
|
|
198
|
-
'process.exitCode = code;',
|
|
199
|
-
'',
|
|
200
|
-
].join('\n');
|
|
201
|
-
}
|
|
202
|
-
|
|
203
95
|
function objectValue(value) {
|
|
204
96
|
return value && typeof value === 'object' && !Array.isArray(value)
|
|
205
97
|
? value
|
|
@@ -284,7 +176,6 @@ function mergeOpenCodeGlobalConfig(existing) {
|
|
|
284
176
|
const parsed = existing ? JSON.parse(existing) : {};
|
|
285
177
|
const auditPermission = renderOpenCodePermissionConfig();
|
|
286
178
|
const existingAuditor = objectValue(objectValue(parsed.agent).auditor);
|
|
287
|
-
const pkgEntrypoint = replaceBackslashes(join(pkgRoot, 'audit-code.mjs'));
|
|
288
179
|
return {
|
|
289
180
|
...parsed,
|
|
290
181
|
command: {
|
|
@@ -298,15 +189,6 @@ function mergeOpenCodeGlobalConfig(existing) {
|
|
|
298
189
|
subtask: false,
|
|
299
190
|
},
|
|
300
191
|
},
|
|
301
|
-
mcp: {
|
|
302
|
-
...objectValue(parsed.mcp),
|
|
303
|
-
auditor: {
|
|
304
|
-
type: 'local',
|
|
305
|
-
command: ['node', pkgEntrypoint, 'mcp'],
|
|
306
|
-
enabled: true,
|
|
307
|
-
timeout: 10000,
|
|
308
|
-
},
|
|
309
|
-
},
|
|
310
192
|
permission: {
|
|
311
193
|
...mergeOpenCodePermissionConfig(parsed.permission, auditPermission),
|
|
312
194
|
external_directory: { '*': 'allow' },
|
|
@@ -334,33 +216,6 @@ function claudePluginExternalDir() {
|
|
|
334
216
|
return join(homedir(), '.claude', 'plugins', 'marketplaces', 'claude-plugins-official', 'external_plugins', 'audit-code');
|
|
335
217
|
}
|
|
336
218
|
|
|
337
|
-
function claudeDesktopConfigPath() {
|
|
338
|
-
if (process.platform === 'win32') {
|
|
339
|
-
return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
|
|
340
|
-
}
|
|
341
|
-
if (process.platform === 'darwin') {
|
|
342
|
-
return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
343
|
-
}
|
|
344
|
-
return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function mergeClaudeDesktopConfig(existing, globalMcpLauncherPath) {
|
|
348
|
-
const parsed = existing ? JSON.parse(existing) : {};
|
|
349
|
-
const mcpServers = parsed.mcpServers && typeof parsed.mcpServers === 'object' && !Array.isArray(parsed.mcpServers)
|
|
350
|
-
? parsed.mcpServers
|
|
351
|
-
: {};
|
|
352
|
-
return {
|
|
353
|
-
...parsed,
|
|
354
|
-
mcpServers: {
|
|
355
|
-
...mcpServers,
|
|
356
|
-
auditor: {
|
|
357
|
-
command: 'node',
|
|
358
|
-
args: [replaceBackslashes(globalMcpLauncherPath)],
|
|
359
|
-
},
|
|
360
|
-
},
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
|
|
364
219
|
function installMergedJson(path, buildMerged) {
|
|
365
220
|
const existing = existsSync(path) ? readFileSync(path, 'utf8') : null;
|
|
366
221
|
const merged = buildMerged(existing);
|
|
@@ -429,17 +284,6 @@ for (const install of installs) {
|
|
|
429
284
|
}
|
|
430
285
|
}
|
|
431
286
|
|
|
432
|
-
// Install global MCP launcher for OpenCode (and other hosts that support global config)
|
|
433
|
-
const globalMcpLauncherPath = join(homedir(), '.audit-code', 'run-mcp-server.mjs');
|
|
434
|
-
try {
|
|
435
|
-
const action = writeGeneratedFile(globalMcpLauncherPath, Buffer.from(renderGlobalMcpLauncher(pkgRoot)));
|
|
436
|
-
console.log(`audit-code: ${action} global MCP launcher at ${globalMcpLauncherPath}`);
|
|
437
|
-
succeeded++;
|
|
438
|
-
} catch (err) {
|
|
439
|
-
console.warn(`audit-code: could not install global MCP launcher (${err.message})`);
|
|
440
|
-
failed++;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
287
|
// Install OpenCode global command and MCP via merged config
|
|
444
288
|
const opencodeGlobalConfig = join(homedir(), '.config', 'opencode', 'opencode.json');
|
|
445
289
|
try {
|
|
@@ -515,22 +359,4 @@ try {
|
|
|
515
359
|
failed++;
|
|
516
360
|
}
|
|
517
361
|
|
|
518
|
-
// Register auditor MCP server with Claude Desktop so /audit-code appears in its slash-command menu
|
|
519
|
-
const claudeDesktopConfig = claudeDesktopConfigPath();
|
|
520
|
-
try {
|
|
521
|
-
const action = installMergedJson(claudeDesktopConfig, (existing) =>
|
|
522
|
-
mergeClaudeDesktopConfig(existing, globalMcpLauncherPath),
|
|
523
|
-
);
|
|
524
|
-
console.log(`audit-code: ${action} Claude Desktop MCP server entry in ${claudeDesktopConfig}`);
|
|
525
|
-
console.log(`audit-code: restart Claude Desktop for /audit-code to appear`);
|
|
526
|
-
console.log(`audit-code: to target a specific repo, set AUDIT_CODE_REPO_ROOT in Claude Desktop's MCP env settings`);
|
|
527
|
-
succeeded++;
|
|
528
|
-
} catch (err) {
|
|
529
|
-
console.warn(`audit-code: could not update Claude Desktop config (${err.message})`);
|
|
530
|
-
console.warn(` To register manually, add "mcpServers.auditor" to:`);
|
|
531
|
-
console.warn(` ${claudeDesktopConfig}`);
|
|
532
|
-
console.warn(` with command "node" and args ["${replaceBackslashes(globalMcpLauncherPath)}"]`);
|
|
533
|
-
failed++;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
362
|
console.log(`audit-code: postinstall complete — ${succeeded} succeeded, ${failed} failed (${Date.now() - postinstallStart}ms)`);
|
|
@@ -22,7 +22,9 @@ dispatch them. The conversation orchestrator owns dispatch and ingestion control
|
|
|
22
22
|
it should not perform broad review itself when subagents are available.
|
|
23
23
|
Entering `/audit-code` is explicit user authorization to fan out those review
|
|
24
24
|
subagents; do not require a separate delegation request before parallel
|
|
25
|
-
dispatch
|
|
25
|
+
dispatch — unless `confirmation_recommended` is true (agent_count exceeds
|
|
26
|
+
`sessionConfig.dispatch.confirm_threshold`, default 10), in which case pause for
|
|
27
|
+
user confirmation.
|
|
26
28
|
|
|
27
29
|
If the host cannot delegate to subagents, the conversation orchestrator may
|
|
28
30
|
complete exactly one assigned review task, ingest it through the provided backend
|
|
@@ -36,6 +38,20 @@ the orchestrator does not need to infer the first task from a broad batch prompt
|
|
|
36
38
|
Subagent fan-out belongs to the host agent runtime rather than to repo-local
|
|
37
39
|
backend provider settings.
|
|
38
40
|
|
|
41
|
+
### Scope confirmation
|
|
42
|
+
|
|
43
|
+
The loader emits a scope summary after the intake step (the first `next-step`):
|
|
44
|
+
the resolved repo root, the auditable file count, whether git is available, and
|
|
45
|
+
any mis-scope smells. It echoes `Auditing <root>, <N> files, git: yes/no` so the
|
|
46
|
+
operator can see exactly what is about to be audited. When a mis-scope smell is
|
|
47
|
+
set — the resolved root has no `.git` but an ancestor does, or the root is a
|
|
48
|
+
workspace member of a parent monorepo — the loader pauses and requires explicit
|
|
49
|
+
confirmation before continuing. Expect the workflow to pause on the first step
|
|
50
|
+
when targeting a workspace subdirectory or a non-git root whose ancestor is a
|
|
51
|
+
repo; in the normal case the echo is informational and the run proceeds without
|
|
52
|
+
interruption. Resolution behaviour is unchanged — only the visibility and the
|
|
53
|
+
confirm gate are added.
|
|
54
|
+
|
|
39
55
|
When dispatch-plan entries include provider-neutral complexity and
|
|
40
56
|
`model_hint.tier` metadata, a capable host may map those tiers to its own
|
|
41
57
|
subagent models. The backend should not prescribe concrete model names.
|
|
@@ -48,6 +48,31 @@ follow only that prompt. Do not read packet prompts, schemas, command catalogs,
|
|
|
48
48
|
or handoff files unless the current step prompt explicitly instructs you to do
|
|
49
49
|
so.
|
|
50
50
|
|
|
51
|
+
If the returned step is a dispatch step, before launching subagents check
|
|
52
|
+
`progress.confirmation_recommended` in `steps/current-step.json`:
|
|
53
|
+
|
|
54
|
+
- If `progress.confirmation_recommended` is `true`, pause and ask the user:
|
|
55
|
+
"Ready to launch **{progress.dispatch_summary}** — continue?"
|
|
56
|
+
Wait for an affirmative reply before proceeding with subagent dispatch.
|
|
57
|
+
- If `progress.confirmation_recommended` is `false` (or absent), proceed
|
|
58
|
+
immediately.
|
|
59
|
+
|
|
60
|
+
After the **first** `next-step` (the intake step) completes, confirm the audit
|
|
61
|
+
scope before proceeding. Read `scope_summary.json` from the `.audit-artifacts/`
|
|
62
|
+
directory (if absent, extract the JSON that follows the `SCOPE_SUMMARY:` marker
|
|
63
|
+
at the start of the step's `progress_summary`). It contains `repo_root`,
|
|
64
|
+
`auditable_file_count`, `git_available`, and `mis_scope_smells`. Then:
|
|
65
|
+
|
|
66
|
+
- Echo one informational line to the user:
|
|
67
|
+
`Auditing <repo_root>, <auditable_file_count> files, git: <yes|no>`.
|
|
68
|
+
- If `mis_scope_smells` is **non-empty**, display each smell as a warning and ask
|
|
69
|
+
`Auditing <repo_root>, <auditable_file_count> files, git: <yes|no> — proceed? (yes/no)`.
|
|
70
|
+
Wait for an affirmative reply before the next `next-step`. If the user declines,
|
|
71
|
+
stop and suggest the correct root (e.g. the ancestor git repo or monorepo root
|
|
72
|
+
named in the smell).
|
|
73
|
+
- If `mis_scope_smells` is empty, the echo is informational only — continue
|
|
74
|
+
automatically without interrupting the workflow.
|
|
75
|
+
|
|
51
76
|
Use MCP tools only as a compatibility adapter when direct shell access to
|
|
52
77
|
`audit-code next-step` is unavailable. The MCP `start_audit` and
|
|
53
78
|
`continue_audit` tools return the same one-step contract; they are not a
|
package/dist/mcp/server.d.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
interface ServerOptions {
|
|
2
|
-
root: string;
|
|
3
|
-
artifactsDir: string;
|
|
4
|
-
}
|
|
5
|
-
interface JsonRpcRequest {
|
|
6
|
-
jsonrpc?: string;
|
|
7
|
-
id?: string | number | null;
|
|
8
|
-
method?: string;
|
|
9
|
-
params?: Record<string, unknown>;
|
|
10
|
-
}
|
|
11
|
-
interface JsonRpcResponse {
|
|
12
|
-
jsonrpc: "2.0";
|
|
13
|
-
id: string | number | null;
|
|
14
|
-
result?: unknown;
|
|
15
|
-
error?: {
|
|
16
|
-
code: number;
|
|
17
|
-
message: string;
|
|
18
|
-
data?: unknown;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
interface ToolCallContext {
|
|
22
|
-
root: string;
|
|
23
|
-
artifactsDir: string;
|
|
24
|
-
}
|
|
25
|
-
export declare function parseContentLength(headerBlock: string): number;
|
|
26
|
-
interface ResourceRegistryEntry {
|
|
27
|
-
uri: string;
|
|
28
|
-
name: string;
|
|
29
|
-
description: string;
|
|
30
|
-
mimeType: string;
|
|
31
|
-
read: (context: ToolCallContext) => Promise<{
|
|
32
|
-
mimeType: string;
|
|
33
|
-
text: string;
|
|
34
|
-
}>;
|
|
35
|
-
}
|
|
36
|
-
export declare const resourceRegistry: ResourceRegistryEntry[];
|
|
37
|
-
interface PromptRegistryEntry {
|
|
38
|
-
name: string;
|
|
39
|
-
description: string;
|
|
40
|
-
arguments: Array<{
|
|
41
|
-
name: string;
|
|
42
|
-
required?: boolean;
|
|
43
|
-
description: string;
|
|
44
|
-
}>;
|
|
45
|
-
render: (args: Record<string, unknown> | undefined) => string;
|
|
46
|
-
}
|
|
47
|
-
export declare const promptRegistry: PromptRegistryEntry[];
|
|
48
|
-
/**
|
|
49
|
-
* Extract zero or more complete Content-Length framed messages from a buffer.
|
|
50
|
-
* Returns an array of parsed body strings and the remaining unconsumed buffer.
|
|
51
|
-
* On framing errors, emits a framing error response via `emit` and resets the buffer.
|
|
52
|
-
*/
|
|
53
|
-
export declare function extractFrames(buffer: Buffer, emit: (response: JsonRpcResponse) => void): {
|
|
54
|
-
bodies: string[];
|
|
55
|
-
remaining: Buffer<ArrayBufferLike>;
|
|
56
|
-
};
|
|
57
|
-
interface DispatchContext {
|
|
58
|
-
version: string;
|
|
59
|
-
defaults: ServerOptions;
|
|
60
|
-
shutdownRequested: boolean;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Dispatch a single JSON-RPC request and return the response(s) to send,
|
|
64
|
-
* plus updated shutdown state.
|
|
65
|
-
*/
|
|
66
|
-
export declare function dispatchRequest(request: JsonRpcRequest, ctx: DispatchContext): Promise<{
|
|
67
|
-
responses: JsonRpcResponse[];
|
|
68
|
-
shutdownRequested: boolean;
|
|
69
|
-
exit?: number;
|
|
70
|
-
}>;
|
|
71
|
-
export declare function runAuditCodeMcpServer(argv: string[]): Promise<void>;
|
|
72
|
-
export {};
|