auditor-lambda 0.3.30 → 0.3.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/audit-code-wrapper-lib.mjs +208 -198
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +65 -101
- package/dist/extractors/risk.js +6 -4
- package/dist/io/artifacts.d.ts +2 -0
- package/dist/io/artifacts.js +1 -0
- package/dist/io/toolingManifest.d.ts +1 -0
- package/dist/io/toolingManifest.js +1 -1
- package/dist/mcp/server.d.ts +71 -0
- package/dist/mcp/server.js +261 -222
- package/dist/orchestrator/artifactFreshness.d.ts +4 -0
- package/dist/orchestrator/artifactFreshness.js +45 -0
- package/dist/orchestrator/artifactMetadata.js +2 -51
- package/dist/orchestrator/dependencyMap.js +14 -0
- package/dist/orchestrator/internalExecutors.js +8 -0
- package/dist/orchestrator/staleness.js +2 -46
- package/dist/orchestrator/state.js +1 -1
- package/dist/orchestrator/syntaxResolutionExecutor.js +121 -13
- package/dist/orchestrator/unitBuilder.js +2 -1
- package/dist/providers/spawnLoggedCommand.js +71 -18
- package/dist/providers/types.d.ts +5 -0
- package/dist/quota/scheduler.js +10 -2
- package/dist/quota/state.js +6 -2
- package/dist/supervisor/operatorHandoff.js +1 -1
- package/dist/types/externalAnalyzer.d.ts +10 -0
- package/dist/types/sessionConfig.d.ts +1 -0
- package/dist/types/workerSession.js +1 -2
- package/dist/validation/artifacts.js +36 -0
- package/dist/validation/sessionConfig.js +4 -0
- package/package.json +1 -1
- package/schemas/audit_task.schema.json +2 -2
- package/schemas/risk_register.schema.json +1 -1
- package/schemas/unit_manifest.schema.json +2 -1
- package/scripts/postinstall.mjs +10 -41
- package/skills/audit-code/audit-code.prompt.md +5 -0
package/README.md
CHANGED
|
@@ -138,7 +138,8 @@ audit-code next-step
|
|
|
138
138
|
|
|
139
139
|
This writes `.audit-artifacts/steps/current-step.json` and
|
|
140
140
|
`.audit-artifacts/steps/current-prompt.md`; hosts should follow only the
|
|
141
|
-
returned step prompt.
|
|
141
|
+
returned step prompt. MCP tools are compatibility adapters over this same
|
|
142
|
+
`next-step` contract rather than a separate orchestration path.
|
|
142
143
|
|
|
143
144
|
For an operator-side artifact consistency check:
|
|
144
145
|
|
|
@@ -580,16 +580,17 @@ function replaceBackslashes(value) {
|
|
|
580
580
|
function renderVSCodeAgentFile() {
|
|
581
581
|
return [
|
|
582
582
|
'---',
|
|
583
|
-
'description: Plan and orchestrate /audit-code
|
|
583
|
+
'description: Plan and orchestrate /audit-code through the next-step machine before making code changes.',
|
|
584
584
|
'---',
|
|
585
585
|
'',
|
|
586
586
|
'# Auditor Agent',
|
|
587
587
|
'',
|
|
588
|
-
'Use
|
|
588
|
+
'Use `audit-code next-step` as the primary integration surface for the audit workflow. The installed auditor MCP server is a compatibility adapter over the same step contract.',
|
|
589
589
|
'',
|
|
590
590
|
'When the user asks to run or continue `/audit-code`:',
|
|
591
591
|
'',
|
|
592
|
-
'-
|
|
592
|
+
'- run `audit-code next-step` directly when shell access is available',
|
|
593
|
+
'- if MCP is the only available integration, call `start_audit`, `get_status`, and `continue_audit`; those tools return the same one-step contract',
|
|
593
594
|
'- read `audit-code://handoff/current` and `audit-code://artifacts/current` when the audit blocks or you need current context',
|
|
594
595
|
'- prefer imported audit results and runtime updates over ad hoc manual state edits',
|
|
595
596
|
'- treat the deterministic audit report as the final source of truth once the audit completes',
|
|
@@ -615,7 +616,7 @@ function renderCodexMcpSetupGuide(root) {
|
|
|
615
616
|
`args = ["${replaceBackslashes(toRepoRelativePath(root, join(root, '.audit-code', 'install', MCP_LAUNCHER_FILENAME)))}"]`,
|
|
616
617
|
'```',
|
|
617
618
|
'',
|
|
618
|
-
'
|
|
619
|
+
'Prefer `audit-code next-step` directly. Use the registered `auditor` MCP tools only when shell access is unavailable; they return the same one-step contract.',
|
|
619
620
|
'',
|
|
620
621
|
].join('\n');
|
|
621
622
|
}
|
|
@@ -626,9 +627,9 @@ function renderCodexAutomationRecipe() {
|
|
|
626
627
|
'',
|
|
627
628
|
'Suggested recurring task:',
|
|
628
629
|
'',
|
|
629
|
-
'- Prompt: Re-run the autonomous audit workflow for this repository
|
|
630
|
+
'- Prompt: Re-run the autonomous audit workflow for this repository with `audit-code next-step`, summarize only new or regressed findings, and stop once the deterministic report is current.',
|
|
630
631
|
'- Cadence: daily on active branches or before release cut-offs',
|
|
631
|
-
'- Inputs: repository root
|
|
632
|
+
'- Inputs: repository root; the installed `auditor` MCP server is optional compatibility plumbing',
|
|
632
633
|
'',
|
|
633
634
|
'Use this recipe as a starting point for a Codex automation once the local workflow is stable in your environment.',
|
|
634
635
|
'',
|
|
@@ -706,16 +707,17 @@ function renderOpenCodePermissionConfig() {
|
|
|
706
707
|
const OPENCODE_MCP_COMMAND_TEMPLATE = [
|
|
707
708
|
'# audit-code',
|
|
708
709
|
'',
|
|
709
|
-
'Use
|
|
710
|
+
'Use `audit-code next-step` as the primary interface to the audit workflow.',
|
|
710
711
|
'',
|
|
711
|
-
'1.
|
|
712
|
-
'2.
|
|
713
|
-
'3.
|
|
714
|
-
'4.
|
|
712
|
+
'1. Run `audit-code next-step` directly when shell access is available.',
|
|
713
|
+
'2. If MCP is your only available interface, call `auditor_start_audit` or `auditor_continue_audit`; both return the same one-step contract.',
|
|
714
|
+
'3. Read `prompt_content` in the response and follow it.',
|
|
715
|
+
'4. When a step completes (not blocked), run `audit-code next-step` again or call `auditor_continue_audit` as the compatibility adapter.',
|
|
716
|
+
'5. Stop when the step instructions say to stop.',
|
|
715
717
|
'',
|
|
716
|
-
'
|
|
718
|
+
'Use the `task` tool or equivalent for subagent dispatch when the step tells you to fan out review work.',
|
|
717
719
|
'',
|
|
718
|
-
'If `auditor_start_audit` is
|
|
720
|
+
'If neither shell access nor `auditor_start_audit` is available, stop and report that no next-step interface is connected.',
|
|
719
721
|
].join('\n');
|
|
720
722
|
|
|
721
723
|
function renderOpenCodeProjectConfig(_root) {
|
|
@@ -939,7 +941,7 @@ function renderClaudeDesktopProjectTemplate() {
|
|
|
939
941
|
'Suggested project instructions:',
|
|
940
942
|
'',
|
|
941
943
|
'- Treat `/audit-code` as the canonical autonomous audit workflow for this repository.',
|
|
942
|
-
'- Prefer the installed auditor MCP tools over
|
|
944
|
+
'- Prefer `audit-code next-step`; use the installed auditor MCP tools only as a compatibility adapter over the same step contract.',
|
|
943
945
|
'- Read the operator handoff and artifact resources before asking for more context.',
|
|
944
946
|
'- Present the final deterministic audit report as work blocks first.',
|
|
945
947
|
'',
|
|
@@ -951,7 +953,7 @@ function renderClaudeDesktopProjectTemplate() {
|
|
|
951
953
|
'',
|
|
952
954
|
'Starter prompt:',
|
|
953
955
|
'',
|
|
954
|
-
'> Start `/audit-code` for this repository using
|
|
956
|
+
'> Start `/audit-code` for this repository using `audit-code next-step`. Continue until the audit is complete or blocked for operator input, and summarize the current handoff status before you stop.',
|
|
955
957
|
'',
|
|
956
958
|
].join('\n');
|
|
957
959
|
}
|
|
@@ -981,7 +983,7 @@ function renderAntigravityPlanningGuide(root) {
|
|
|
981
983
|
'',
|
|
982
984
|
'1. Open Antigravity in Planning mode.',
|
|
983
985
|
'2. Load the repo-local prompt asset or the AGENTS instructions before starting the audit conversation.',
|
|
984
|
-
'3. Ask Antigravity to use
|
|
986
|
+
'3. Ask Antigravity to use `audit-code next-step` directly. The installed auditor MCP server is available only as compatibility plumbing when direct shell access is unavailable.',
|
|
985
987
|
'4. Review Antigravity artifacts before accepting major code changes or imported evidence.',
|
|
986
988
|
'',
|
|
987
989
|
'Recommended repo-local paths:',
|
|
@@ -1266,9 +1268,9 @@ async function buildClaudeDesktopBundle(root, results) {
|
|
|
1266
1268
|
name: 'auditor-lambda',
|
|
1267
1269
|
display_name: 'Auditor Lambda',
|
|
1268
1270
|
version: packageVersion,
|
|
1269
|
-
description: '
|
|
1271
|
+
description: 'Compatibility MCP bundle for the /audit-code autonomous audit workflow.',
|
|
1270
1272
|
long_description:
|
|
1271
|
-
'Runs
|
|
1273
|
+
'Runs a local compatibility MCP adapter whose start and continue tools return the same audit-code next-step contract as the direct CLI loop.',
|
|
1272
1274
|
author: {
|
|
1273
1275
|
name: 'auditor-lambda',
|
|
1274
1276
|
url: 'https://github.com/OhOkThisIsFine/auditor-lambda',
|
|
@@ -1371,6 +1373,18 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1371
1373
|
profile: {
|
|
1372
1374
|
writeAgents: true,
|
|
1373
1375
|
},
|
|
1376
|
+
async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
|
|
1377
|
+
await collect(checks, 'codex_global_surface', async () => {
|
|
1378
|
+
const content = await readFile(assetPaths.agentsInstructionsPath, 'utf8');
|
|
1379
|
+
if (!content.includes('/audit-code')) {
|
|
1380
|
+
throw new Error(`AGENTS instructions do not reference /audit-code: ${assetPaths.agentsInstructionsPath}`);
|
|
1381
|
+
}
|
|
1382
|
+
return {
|
|
1383
|
+
summary: 'Codex uses the global skill surface with AGENTS fallback instructions.',
|
|
1384
|
+
path: assetPaths.agentsInstructionsPath,
|
|
1385
|
+
};
|
|
1386
|
+
});
|
|
1387
|
+
},
|
|
1374
1388
|
},
|
|
1375
1389
|
'claude-desktop': {
|
|
1376
1390
|
host: 'claude-desktop',
|
|
@@ -1378,7 +1392,7 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1378
1392
|
support_level: 'supported',
|
|
1379
1393
|
setup_kind: 'local-mcp-bundle',
|
|
1380
1394
|
summary:
|
|
1381
|
-
'Install the generated local MCP bundle in Claude Desktop, then use the project template and prompt asset as supporting context.',
|
|
1395
|
+
'Install the generated local MCP compatibility bundle in Claude Desktop, then use the project template and prompt asset as supporting context.',
|
|
1382
1396
|
primary_path_key: 'claudeDesktopDxtPath',
|
|
1383
1397
|
supporting_path_keys: [
|
|
1384
1398
|
'claudeDesktopMcpbPath',
|
|
@@ -1388,12 +1402,91 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1388
1402
|
],
|
|
1389
1403
|
steps: [
|
|
1390
1404
|
'Open Claude Desktop Settings and install the generated `.dxt` bundle.',
|
|
1391
|
-
'Configure the repository root when prompted so the bundle can launch the local auditor MCP
|
|
1405
|
+
'Configure the repository root when prompted so the bundle can launch the local auditor MCP adapter.',
|
|
1392
1406
|
'Use the project template and prompt asset to kick off `/audit-code` in conversation.',
|
|
1393
1407
|
],
|
|
1394
1408
|
profile: {
|
|
1395
1409
|
writeClaudeDesktop: true,
|
|
1396
1410
|
},
|
|
1411
|
+
async verify({ checks, root, assetPaths, collectVerifyCheck: collect }) {
|
|
1412
|
+
const bundleManifestPath = join(
|
|
1413
|
+
root,
|
|
1414
|
+
'.audit-code',
|
|
1415
|
+
'install',
|
|
1416
|
+
'claude-desktop',
|
|
1417
|
+
'bundle',
|
|
1418
|
+
'manifest.json',
|
|
1419
|
+
);
|
|
1420
|
+
const bundleServerPath = join(
|
|
1421
|
+
root,
|
|
1422
|
+
'.audit-code',
|
|
1423
|
+
'install',
|
|
1424
|
+
'claude-desktop',
|
|
1425
|
+
'bundle',
|
|
1426
|
+
'server',
|
|
1427
|
+
'index.js',
|
|
1428
|
+
);
|
|
1429
|
+
|
|
1430
|
+
await collect(checks, 'claude_bundle_manifest', async () => {
|
|
1431
|
+
const manifest = await readJson(bundleManifestPath, 'Claude Desktop bundle manifest');
|
|
1432
|
+
if (manifest?.server?.entry_point !== 'server/index.js') {
|
|
1433
|
+
throw new Error(`Claude Desktop bundle manifest has an unexpected entry_point: ${manifest?.server?.entry_point ?? 'missing'}.`);
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
summary: 'Claude Desktop bundle manifest parsed successfully.',
|
|
1437
|
+
path: bundleManifestPath,
|
|
1438
|
+
};
|
|
1439
|
+
});
|
|
1440
|
+
await collect(checks, 'claude_connector_template', async () => {
|
|
1441
|
+
const connector = await readJson(
|
|
1442
|
+
assetPaths.claudeDesktopRemoteConnectorPath,
|
|
1443
|
+
'Claude Desktop remote connector template',
|
|
1444
|
+
);
|
|
1445
|
+
if (connector?.transport !== 'remote-mcp') {
|
|
1446
|
+
throw new Error(`Claude Desktop remote connector transport must be "remote-mcp", got ${connector?.transport ?? 'missing'}.`);
|
|
1447
|
+
}
|
|
1448
|
+
return {
|
|
1449
|
+
summary: 'Claude Desktop remote connector template parsed successfully.',
|
|
1450
|
+
path: assetPaths.claudeDesktopRemoteConnectorPath,
|
|
1451
|
+
};
|
|
1452
|
+
});
|
|
1453
|
+
await collect(checks, 'claude_dxt_archive', async () => ({
|
|
1454
|
+
summary: 'Claude Desktop .dxt bundle is present.',
|
|
1455
|
+
path: assetPaths.claudeDesktopDxtPath,
|
|
1456
|
+
size_bytes: await verifyZipFile(
|
|
1457
|
+
assetPaths.claudeDesktopDxtPath,
|
|
1458
|
+
'Claude Desktop .dxt bundle',
|
|
1459
|
+
),
|
|
1460
|
+
}));
|
|
1461
|
+
await collect(checks, 'claude_mcpb_archive', async () => ({
|
|
1462
|
+
summary: 'Claude Desktop .mcpb bundle is present.',
|
|
1463
|
+
path: assetPaths.claudeDesktopMcpbPath,
|
|
1464
|
+
size_bytes: await verifyZipFile(
|
|
1465
|
+
assetPaths.claudeDesktopMcpbPath,
|
|
1466
|
+
'Claude Desktop .mcpb bundle',
|
|
1467
|
+
),
|
|
1468
|
+
}));
|
|
1469
|
+
await collect(checks, 'claude_bundle_mcp', async () => {
|
|
1470
|
+
const probe = await probeMcpServer({
|
|
1471
|
+
label: 'Claude Desktop bundle server',
|
|
1472
|
+
command: process.execPath,
|
|
1473
|
+
args: [bundleServerPath],
|
|
1474
|
+
cwd: root,
|
|
1475
|
+
env: {
|
|
1476
|
+
AUDIT_CODE_REPO_ROOT: root,
|
|
1477
|
+
AUDIT_CODE_ARTIFACTS_DIR: join(root, '.audit-artifacts'),
|
|
1478
|
+
},
|
|
1479
|
+
});
|
|
1480
|
+
const toolNames = (probe.tools?.tools ?? []).map((tool) => tool.name);
|
|
1481
|
+
if (!toolNames.includes('start_audit')) {
|
|
1482
|
+
throw new Error('Claude Desktop bundle server did not expose the start_audit tool.');
|
|
1483
|
+
}
|
|
1484
|
+
return {
|
|
1485
|
+
summary: 'Claude Desktop bundle completed an MCP handshake.',
|
|
1486
|
+
tool_count: toolNames.length,
|
|
1487
|
+
};
|
|
1488
|
+
});
|
|
1489
|
+
},
|
|
1397
1490
|
},
|
|
1398
1491
|
opencode: {
|
|
1399
1492
|
host: 'opencode',
|
|
@@ -1401,7 +1494,7 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1401
1494
|
support_level: 'supported',
|
|
1402
1495
|
setup_kind: 'global-command+project-mcp',
|
|
1403
1496
|
summary:
|
|
1404
|
-
'Use the global OpenCode `/audit-code` command installed by npm plus generated project MCP
|
|
1497
|
+
'Use the global OpenCode `/audit-code` command installed by npm plus generated project permissions; MCP is compatibility-only.',
|
|
1405
1498
|
primary_path_key: 'opencodeConfigPath',
|
|
1406
1499
|
supporting_path_keys: [
|
|
1407
1500
|
'agentsInstructionsPath',
|
|
@@ -1410,12 +1503,29 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1410
1503
|
steps: [
|
|
1411
1504
|
'Open this repository in OpenCode.',
|
|
1412
1505
|
'Use the global `/audit-code` command installed by `npm install -g auditor-lambda`.',
|
|
1413
|
-
'Let OpenCode load the generated `opencode.json` for the
|
|
1506
|
+
'Let OpenCode load the generated `opencode.json` for project permissions; the global command drives `audit-code next-step` directly.',
|
|
1414
1507
|
],
|
|
1415
1508
|
profile: {
|
|
1416
1509
|
writeOpenCode: true,
|
|
1417
1510
|
writeAgents: true,
|
|
1418
1511
|
},
|
|
1512
|
+
async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
|
|
1513
|
+
await collect(checks, 'opencode_config', async () => {
|
|
1514
|
+
const config = await readJson(assetPaths.opencodeConfigPath, 'OpenCode project config');
|
|
1515
|
+
if (config?.command?.['audit-code']) {
|
|
1516
|
+
throw new Error('OpenCode project config must not define command["audit-code"]; the slash command is global npm-installed state. Run "audit-code install --host opencode" to remove the stale local command.');
|
|
1517
|
+
}
|
|
1518
|
+
if (config?.mcp?.auditor) {
|
|
1519
|
+
throw new Error('OpenCode project config must not define mcp.auditor; the MCP server is supplied by the global npm-installed config. Run "audit-code install --host opencode" to remove the stale project-level MCP entry.');
|
|
1520
|
+
}
|
|
1521
|
+
assertOpenCodeAuditPermissionConfig(config?.permission, 'permission');
|
|
1522
|
+
assertOpenCodeAuditPermissionConfig(config?.agent?.auditor?.permission, 'agent.auditor.permission');
|
|
1523
|
+
return {
|
|
1524
|
+
summary: 'OpenCode project config has audit permissions; /audit-code is supplied by the global npm-installed config.',
|
|
1525
|
+
path: assetPaths.opencodeConfigPath,
|
|
1526
|
+
};
|
|
1527
|
+
});
|
|
1528
|
+
},
|
|
1419
1529
|
},
|
|
1420
1530
|
vscode: {
|
|
1421
1531
|
host: 'vscode',
|
|
@@ -1423,7 +1533,7 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1423
1533
|
support_level: 'supported',
|
|
1424
1534
|
setup_kind: 'prompt+agent+mcp',
|
|
1425
1535
|
summary:
|
|
1426
|
-
'Use the generated prompt file
|
|
1536
|
+
'Use the generated prompt file and custom agent for next-step-first VS Code integration; workspace MCP is compatibility-only.',
|
|
1427
1537
|
primary_path_key: 'vscodePromptPath',
|
|
1428
1538
|
supporting_path_keys: [
|
|
1429
1539
|
'vscodeAgentPath',
|
|
@@ -1432,13 +1542,46 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1432
1542
|
],
|
|
1433
1543
|
steps: [
|
|
1434
1544
|
'Open this repository in VS Code with Copilot.',
|
|
1435
|
-
'
|
|
1436
|
-
'
|
|
1545
|
+
'Invoke `/audit-code` from the generated prompt or chat so the workflow calls `audit-code next-step` directly.',
|
|
1546
|
+
'Use the workspace MCP adapter only when direct shell access is unavailable.',
|
|
1437
1547
|
],
|
|
1438
1548
|
profile: {
|
|
1439
1549
|
writeVSCode: true,
|
|
1440
1550
|
writeCopilotInstructions: true,
|
|
1441
1551
|
},
|
|
1552
|
+
async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
|
|
1553
|
+
await collect(checks, 'vscode_prompt', async () => {
|
|
1554
|
+
const content = await readFile(assetPaths.vscodePromptPath, 'utf8');
|
|
1555
|
+
if (!content.includes('name: audit-code')) {
|
|
1556
|
+
throw new Error(`VS Code prompt file is missing the expected frontmatter name: ${assetPaths.vscodePromptPath}`);
|
|
1557
|
+
}
|
|
1558
|
+
const { body: promptBody } = splitFrontmatter(content);
|
|
1559
|
+
const { body: sourceBody } = splitFrontmatter(await readFile(promptAssetPath, 'utf8'));
|
|
1560
|
+
if (promptBody !== sourceBody.trimStart()) {
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
`VS Code prompt body is out of sync with the source prompt. Run "audit-code install --host vscode" or "audit-code install".`,
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
return {
|
|
1566
|
+
summary: 'VS Code prompt file is present and uses the source prompt body.',
|
|
1567
|
+
path: assetPaths.vscodePromptPath,
|
|
1568
|
+
};
|
|
1569
|
+
});
|
|
1570
|
+
await collect(checks, 'vscode_mcp_config', async () => {
|
|
1571
|
+
const config = await readJson(assetPaths.vscodeMcpConfigPath, 'VS Code MCP config');
|
|
1572
|
+
const args = config?.servers?.auditor?.args;
|
|
1573
|
+
if (config?.servers?.auditor?.command !== 'node') {
|
|
1574
|
+
throw new Error(`VS Code MCP config must use node as the command, got ${config?.servers?.auditor?.command ?? 'missing'}.`);
|
|
1575
|
+
}
|
|
1576
|
+
if (!Array.isArray(args) || args[0] !== '${workspaceFolder}/.audit-code/install/run-mcp-server.mjs') {
|
|
1577
|
+
throw new Error(`VS Code MCP config must point at \${workspaceFolder}/.audit-code/install/${MCP_LAUNCHER_FILENAME}.`);
|
|
1578
|
+
}
|
|
1579
|
+
return {
|
|
1580
|
+
summary: 'VS Code MCP config parsed successfully.',
|
|
1581
|
+
path: assetPaths.vscodeMcpConfigPath,
|
|
1582
|
+
};
|
|
1583
|
+
});
|
|
1584
|
+
},
|
|
1442
1585
|
},
|
|
1443
1586
|
antigravity: {
|
|
1444
1587
|
host: 'antigravity',
|
|
@@ -1446,7 +1589,7 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1446
1589
|
support_level: 'supported',
|
|
1447
1590
|
setup_kind: 'agent-skill+gemini-command+planning-guide+mcp-ready',
|
|
1448
1591
|
summary:
|
|
1449
|
-
'Uses the project-scoped .agent/skills/audit-code/SKILL.md skill, the .gemini/commands/audit-code.toml slash command, the planning guide, and AGENTS instructions. The shared MCP launcher is
|
|
1592
|
+
'Uses the project-scoped .agent/skills/audit-code/SKILL.md skill, the .gemini/commands/audit-code.toml slash command, the planning guide, and AGENTS instructions. The shared MCP launcher is compatibility-only.',
|
|
1450
1593
|
primary_path_key: 'antigravitySkillPath',
|
|
1451
1594
|
supporting_path_keys: [
|
|
1452
1595
|
'geminiCommandPath',
|
|
@@ -1459,12 +1602,34 @@ const INSTALL_HOST_DEFINITIONS = {
|
|
|
1459
1602
|
'Open this repository in Antigravity.',
|
|
1460
1603
|
'The audit-code skill is automatically discovered from .agent/skills/audit-code/SKILL.md.',
|
|
1461
1604
|
'The /audit-code slash command is also available from .gemini/commands/audit-code.toml.',
|
|
1462
|
-
'Use the shared auditor MCP
|
|
1605
|
+
'Use `audit-code next-step` directly; use the shared auditor MCP launcher only when direct shell access is unavailable.',
|
|
1463
1606
|
],
|
|
1464
1607
|
profile: {
|
|
1465
1608
|
writeAntigravity: true,
|
|
1466
1609
|
writeAgents: true,
|
|
1467
1610
|
},
|
|
1611
|
+
async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
|
|
1612
|
+
await collect(checks, 'antigravity_skill', async () => {
|
|
1613
|
+
const content = await readFile(assetPaths.antigravitySkillPath, 'utf8');
|
|
1614
|
+
if (!content.includes('name: audit-code')) {
|
|
1615
|
+
throw new Error('Antigravity skill SKILL.md must contain "name: audit-code" in frontmatter.');
|
|
1616
|
+
}
|
|
1617
|
+
return {
|
|
1618
|
+
summary: 'Antigravity .agent/skills/audit-code/SKILL.md is present and valid.',
|
|
1619
|
+
path: assetPaths.antigravitySkillPath,
|
|
1620
|
+
};
|
|
1621
|
+
});
|
|
1622
|
+
await collect(checks, 'antigravity_guide', async () => {
|
|
1623
|
+
const content = await readFile(assetPaths.antigravityPlanningGuidePath, 'utf8');
|
|
1624
|
+
if (!content.includes(MCP_LAUNCHER_FILENAME) || !content.includes(INSTALLED_PROMPT_FILENAME)) {
|
|
1625
|
+
throw new Error(`Antigravity guide must reference both ${MCP_LAUNCHER_FILENAME} and ${INSTALLED_PROMPT_FILENAME}.`);
|
|
1626
|
+
}
|
|
1627
|
+
return {
|
|
1628
|
+
summary: 'Antigravity planning guide references the repo-local prompt asset and MCP launcher.',
|
|
1629
|
+
path: assetPaths.antigravityPlanningGuidePath,
|
|
1630
|
+
};
|
|
1631
|
+
});
|
|
1632
|
+
},
|
|
1468
1633
|
},
|
|
1469
1634
|
};
|
|
1470
1635
|
|
|
@@ -1505,6 +1670,13 @@ function getInstallProfile(host) {
|
|
|
1505
1670
|
return profile;
|
|
1506
1671
|
}
|
|
1507
1672
|
|
|
1673
|
+
export {
|
|
1674
|
+
INSTALL_HOST_ORDER as _INSTALL_HOST_ORDER,
|
|
1675
|
+
INSTALL_HOST_DEFINITIONS as _INSTALL_HOST_DEFINITIONS,
|
|
1676
|
+
getInstallHostKeys as _getInstallHostKeys,
|
|
1677
|
+
getInstallProfile as _getInstallProfile,
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1508
1680
|
function buildHostCatalog({ root, host, assets }) {
|
|
1509
1681
|
return getInstallHostKeys(host)
|
|
1510
1682
|
.map((hostKey) => {
|
|
@@ -2028,177 +2200,15 @@ async function verifyInstalledBootstrap(argv) {
|
|
|
2028
2200
|
primary_path: hostEntry.primary_path,
|
|
2029
2201
|
}));
|
|
2030
2202
|
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
path: assetPaths.agentsInstructionsPath,
|
|
2041
|
-
};
|
|
2042
|
-
});
|
|
2043
|
-
break;
|
|
2044
|
-
case 'claude-desktop': {
|
|
2045
|
-
const bundleManifestPath = join(
|
|
2046
|
-
root,
|
|
2047
|
-
'.audit-code',
|
|
2048
|
-
'install',
|
|
2049
|
-
'claude-desktop',
|
|
2050
|
-
'bundle',
|
|
2051
|
-
'manifest.json',
|
|
2052
|
-
);
|
|
2053
|
-
const bundleServerPath = join(
|
|
2054
|
-
root,
|
|
2055
|
-
'.audit-code',
|
|
2056
|
-
'install',
|
|
2057
|
-
'claude-desktop',
|
|
2058
|
-
'bundle',
|
|
2059
|
-
'server',
|
|
2060
|
-
'index.js',
|
|
2061
|
-
);
|
|
2062
|
-
|
|
2063
|
-
await collectVerifyCheck(checks, 'claude_bundle_manifest', async () => {
|
|
2064
|
-
const manifest = await readJson(bundleManifestPath, 'Claude Desktop bundle manifest');
|
|
2065
|
-
if (manifest?.server?.entry_point !== 'server/index.js') {
|
|
2066
|
-
throw new Error(`Claude Desktop bundle manifest has an unexpected entry_point: ${manifest?.server?.entry_point ?? 'missing'}.`);
|
|
2067
|
-
}
|
|
2068
|
-
return {
|
|
2069
|
-
summary: 'Claude Desktop bundle manifest parsed successfully.',
|
|
2070
|
-
path: bundleManifestPath,
|
|
2071
|
-
};
|
|
2072
|
-
});
|
|
2073
|
-
await collectVerifyCheck(checks, 'claude_connector_template', async () => {
|
|
2074
|
-
const connector = await readJson(
|
|
2075
|
-
assetPaths.claudeDesktopRemoteConnectorPath,
|
|
2076
|
-
'Claude Desktop remote connector template',
|
|
2077
|
-
);
|
|
2078
|
-
if (connector?.transport !== 'remote-mcp') {
|
|
2079
|
-
throw new Error(`Claude Desktop remote connector transport must be "remote-mcp", got ${connector?.transport ?? 'missing'}.`);
|
|
2080
|
-
}
|
|
2081
|
-
return {
|
|
2082
|
-
summary: 'Claude Desktop remote connector template parsed successfully.',
|
|
2083
|
-
path: assetPaths.claudeDesktopRemoteConnectorPath,
|
|
2084
|
-
};
|
|
2085
|
-
});
|
|
2086
|
-
await collectVerifyCheck(checks, 'claude_dxt_archive', async () => ({
|
|
2087
|
-
summary: 'Claude Desktop .dxt bundle is present.',
|
|
2088
|
-
path: assetPaths.claudeDesktopDxtPath,
|
|
2089
|
-
size_bytes: await verifyZipFile(
|
|
2090
|
-
assetPaths.claudeDesktopDxtPath,
|
|
2091
|
-
'Claude Desktop .dxt bundle',
|
|
2092
|
-
),
|
|
2093
|
-
}));
|
|
2094
|
-
await collectVerifyCheck(checks, 'claude_mcpb_archive', async () => ({
|
|
2095
|
-
summary: 'Claude Desktop .mcpb bundle is present.',
|
|
2096
|
-
path: assetPaths.claudeDesktopMcpbPath,
|
|
2097
|
-
size_bytes: await verifyZipFile(
|
|
2098
|
-
assetPaths.claudeDesktopMcpbPath,
|
|
2099
|
-
'Claude Desktop .mcpb bundle',
|
|
2100
|
-
),
|
|
2101
|
-
}));
|
|
2102
|
-
await collectVerifyCheck(checks, 'claude_bundle_mcp', async () => {
|
|
2103
|
-
const probe = await probeMcpServer({
|
|
2104
|
-
label: 'Claude Desktop bundle server',
|
|
2105
|
-
command: process.execPath,
|
|
2106
|
-
args: [bundleServerPath],
|
|
2107
|
-
cwd: root,
|
|
2108
|
-
env: {
|
|
2109
|
-
AUDIT_CODE_REPO_ROOT: root,
|
|
2110
|
-
AUDIT_CODE_ARTIFACTS_DIR: join(root, '.audit-artifacts'),
|
|
2111
|
-
},
|
|
2112
|
-
});
|
|
2113
|
-
const toolNames = (probe.tools?.tools ?? []).map((tool) => tool.name);
|
|
2114
|
-
if (!toolNames.includes('start_audit')) {
|
|
2115
|
-
throw new Error('Claude Desktop bundle server did not expose the start_audit tool.');
|
|
2116
|
-
}
|
|
2117
|
-
return {
|
|
2118
|
-
summary: 'Claude Desktop bundle completed an MCP handshake.',
|
|
2119
|
-
tool_count: toolNames.length,
|
|
2120
|
-
};
|
|
2121
|
-
});
|
|
2122
|
-
break;
|
|
2123
|
-
}
|
|
2124
|
-
case 'opencode':
|
|
2125
|
-
await collectVerifyCheck(checks, 'opencode_config', async () => {
|
|
2126
|
-
const config = await readJson(assetPaths.opencodeConfigPath, 'OpenCode project config');
|
|
2127
|
-
if (config?.command?.['audit-code']) {
|
|
2128
|
-
throw new Error('OpenCode project config must not define command["audit-code"]; the slash command is global npm-installed state. Run "audit-code install --host opencode" to remove the stale local command.');
|
|
2129
|
-
}
|
|
2130
|
-
if (config?.mcp?.auditor) {
|
|
2131
|
-
throw new Error('OpenCode project config must not define mcp.auditor; the MCP server is supplied by the global npm-installed config. Run "audit-code install --host opencode" to remove the stale project-level MCP entry.');
|
|
2132
|
-
}
|
|
2133
|
-
assertOpenCodeAuditPermissionConfig(config?.permission, 'permission');
|
|
2134
|
-
assertOpenCodeAuditPermissionConfig(config?.agent?.auditor?.permission, 'agent.auditor.permission');
|
|
2135
|
-
return {
|
|
2136
|
-
summary: 'OpenCode project config has audit permissions; MCP server and /audit-code command are supplied by the global npm-installed config.',
|
|
2137
|
-
path: assetPaths.opencodeConfigPath,
|
|
2138
|
-
};
|
|
2139
|
-
});
|
|
2140
|
-
break;
|
|
2141
|
-
case 'vscode':
|
|
2142
|
-
await collectVerifyCheck(checks, 'vscode_prompt', async () => {
|
|
2143
|
-
const content = await readFile(assetPaths.vscodePromptPath, 'utf8');
|
|
2144
|
-
if (!content.includes('name: audit-code')) {
|
|
2145
|
-
throw new Error(`VS Code prompt file is missing the expected frontmatter name: ${assetPaths.vscodePromptPath}`);
|
|
2146
|
-
}
|
|
2147
|
-
const { body: promptBody } = splitFrontmatter(content);
|
|
2148
|
-
const { body: sourceBody } = splitFrontmatter(await readFile(promptAssetPath, 'utf8'));
|
|
2149
|
-
if (promptBody !== sourceBody.trimStart()) {
|
|
2150
|
-
throw new Error(
|
|
2151
|
-
`VS Code prompt body is out of sync with the source prompt. Run "audit-code install --host vscode" or "audit-code install".`,
|
|
2152
|
-
);
|
|
2153
|
-
}
|
|
2154
|
-
return {
|
|
2155
|
-
summary: 'VS Code prompt file is present and uses the source prompt body.',
|
|
2156
|
-
path: assetPaths.vscodePromptPath,
|
|
2157
|
-
};
|
|
2158
|
-
});
|
|
2159
|
-
await collectVerifyCheck(checks, 'vscode_mcp_config', async () => {
|
|
2160
|
-
const config = await readJson(assetPaths.vscodeMcpConfigPath, 'VS Code MCP config');
|
|
2161
|
-
const args = config?.servers?.auditor?.args;
|
|
2162
|
-
if (config?.servers?.auditor?.command !== 'node') {
|
|
2163
|
-
throw new Error(`VS Code MCP config must use node as the command, got ${config?.servers?.auditor?.command ?? 'missing'}.`);
|
|
2164
|
-
}
|
|
2165
|
-
if (!Array.isArray(args) || args[0] !== '${workspaceFolder}/.audit-code/install/run-mcp-server.mjs') {
|
|
2166
|
-
throw new Error(`VS Code MCP config must point at \${workspaceFolder}/.audit-code/install/${MCP_LAUNCHER_FILENAME}.`);
|
|
2167
|
-
}
|
|
2168
|
-
return {
|
|
2169
|
-
summary: 'VS Code MCP config parsed successfully.',
|
|
2170
|
-
path: assetPaths.vscodeMcpConfigPath,
|
|
2171
|
-
};
|
|
2172
|
-
});
|
|
2173
|
-
break;
|
|
2174
|
-
case 'antigravity':
|
|
2175
|
-
await collectVerifyCheck(checks, 'antigravity_skill', async () => {
|
|
2176
|
-
const content = await readFile(assetPaths.antigravitySkillPath, 'utf8');
|
|
2177
|
-
if (!content.includes('name: audit-code')) {
|
|
2178
|
-
throw new Error('Antigravity skill SKILL.md must contain "name: audit-code" in frontmatter.');
|
|
2179
|
-
}
|
|
2180
|
-
return {
|
|
2181
|
-
summary: 'Antigravity .agent/skills/audit-code/SKILL.md is present and valid.',
|
|
2182
|
-
path: assetPaths.antigravitySkillPath,
|
|
2183
|
-
};
|
|
2184
|
-
});
|
|
2185
|
-
await collectVerifyCheck(checks, 'antigravity_guide', async () => {
|
|
2186
|
-
const content = await readFile(assetPaths.antigravityPlanningGuidePath, 'utf8');
|
|
2187
|
-
if (!content.includes(MCP_LAUNCHER_FILENAME) || !content.includes(INSTALLED_PROMPT_FILENAME)) {
|
|
2188
|
-
throw new Error(`Antigravity guide must reference both ${MCP_LAUNCHER_FILENAME} and ${INSTALLED_PROMPT_FILENAME}.`);
|
|
2189
|
-
}
|
|
2190
|
-
return {
|
|
2191
|
-
summary: 'Antigravity planning guide references the repo-local prompt asset and MCP launcher.',
|
|
2192
|
-
path: assetPaths.antigravityPlanningGuidePath,
|
|
2193
|
-
};
|
|
2194
|
-
});
|
|
2195
|
-
break;
|
|
2196
|
-
default:
|
|
2197
|
-
checks.push({
|
|
2198
|
-
id: 'host_handler',
|
|
2199
|
-
status: 'error',
|
|
2200
|
-
summary: `No verification handler is implemented for host "${hostKey}".`,
|
|
2201
|
-
});
|
|
2203
|
+
const hostDefinition = INSTALL_HOST_DEFINITIONS[hostKey];
|
|
2204
|
+
if (hostDefinition?.verify) {
|
|
2205
|
+
await hostDefinition.verify({ checks, root, assetPaths, collectVerifyCheck });
|
|
2206
|
+
} else {
|
|
2207
|
+
checks.push({
|
|
2208
|
+
id: 'host_handler',
|
|
2209
|
+
status: 'error',
|
|
2210
|
+
summary: `No verification handler is implemented for host "${hostKey}".`,
|
|
2211
|
+
});
|
|
2202
2212
|
}
|
|
2203
2213
|
|
|
2204
2214
|
hostResults.push({
|
package/dist/cli.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ import type { SessionConfig } from "./types/sessionConfig.js";
|
|
|
2
2
|
type UiMode = "visible" | "headless";
|
|
3
3
|
declare function getFlag(argv: string[], name: string, fallback?: string): string | undefined;
|
|
4
4
|
declare function hasFlag(argv: string[], name: string): boolean;
|
|
5
|
+
export declare function resolveHostDispatchCapability(options: {
|
|
6
|
+
explicit?: boolean;
|
|
7
|
+
sessionConfig: SessionConfig;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
}): boolean;
|
|
5
10
|
declare function getArtifactsDir(argv: string[]): string;
|
|
6
11
|
declare function getRootDir(argv: string[]): string;
|
|
7
12
|
declare function warnIfNotGitRepo(root: string): void;
|