auditor-lambda 0.3.7 → 0.3.8

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 CHANGED
@@ -22,7 +22,28 @@ The canonical asset for editor and conversation integrations is:
22
22
 
23
23
  Packaged installs and repository checkouts both ship that prompt asset.
24
24
 
25
- The recommended zero-guess setup path is now:
25
+ The intended user install is one global tool install:
26
+
27
+ ```bash
28
+ npm install -g auditor-lambda
29
+ ```
30
+
31
+ That makes `audit-code` available on `PATH`. During package install, the package
32
+ also writes user-level command/skill assets for hosts we can seed safely, including
33
+ the Claude command file and Codex skill bundle.
34
+
35
+ After that, invoke `/audit-code` in a supported host. The prompt self-bootstraps
36
+ the current repository by running:
37
+
38
+ ```bash
39
+ audit-code ensure --quiet
40
+ ```
41
+
42
+ That command writes or refreshes the repo-local assets only when they are missing
43
+ or stale, then normal audit execution continues without manual paths, provider
44
+ flags, or model-selection arguments.
45
+
46
+ The explicit repair and compatibility setup path remains:
26
47
 
27
48
  ```bash
28
49
  audit-code install
@@ -36,9 +57,9 @@ That bootstraps repo-local `/audit-code` surfaces for the hosts we can automate
36
57
  - VS Code prompt, custom agent, Copilot instructions, and `.vscode/mcp.json`
37
58
  - Antigravity planning-mode guidance plus the shared repo-local MCP launcher
38
59
 
39
- Re-run the same `audit-code install` command whenever the packaged prompt or
40
- skill changes. It is the single supported refresh path for the shared
41
- `.audit-code/install/*` assets and every generated host surface.
60
+ `audit-code ensure` refreshes those files automatically when the packaged prompt
61
+ or skill changes. Use `audit-code install` or `audit-code ensure --force` when
62
+ you intentionally want to rewrite every generated host surface on demand.
42
63
 
43
64
  After bootstrap, you can smoke-test the generated host assets and launcher from the repository root:
44
65
 
@@ -161,7 +182,8 @@ Optional backend config:
161
182
  ## Practical Guidance
162
183
 
163
184
  - use `/audit-code` in conversation as the canonical product surface
164
- - use `audit-code install` first when you want the lowest-friction repo bootstrap
185
+ - install once with `npm install -g auditor-lambda`, then let `/audit-code` run `audit-code ensure --quiet` in each repository
186
+ - use `audit-code install` when you want to repair or force-refresh repo-local host assets
165
187
  - use `audit-code prompt-path` to locate the packaged prompt asset
166
188
  - use `audit-code` from the repository root only when you need the repo-local backend fallback
167
189
  - use omitted provider or `local-subprocess` for the safest deterministic fallback behavior
@@ -253,6 +253,7 @@ function printHelp({ usageName, preferredEntrypoint }) {
253
253
  '',
254
254
  'Helper commands:',
255
255
  '- prompt-path prints the absolute path to the canonical /audit-code prompt asset',
256
+ '- ensure lazily bootstraps repo-local /audit-code assets when they are missing or stale',
256
257
  '- install bootstraps /audit-code into supported repo-local host surfaces',
257
258
  '- verify-install smoke-tests the generated host assets and repo-local MCP launchers after install',
258
259
  '- mcp starts the local stdio MCP server for repo-local IDE integrations',
@@ -1952,7 +1953,188 @@ async function verifyInstalledBootstrap(argv) {
1952
1953
  process.exitCode = issueCount > 0 ? 1 : 0;
1953
1954
  }
1954
1955
 
1955
- async function installBootstrap(argv) {
1956
+ async function readTextIfExists(path) {
1957
+ try {
1958
+ return await readFile(path, 'utf8');
1959
+ } catch {
1960
+ return null;
1961
+ }
1962
+ }
1963
+
1964
+ async function detectBootstrapRefreshReason(root, host) {
1965
+ const installManifestPath = join(
1966
+ root,
1967
+ '.audit-code',
1968
+ 'install',
1969
+ INSTALL_MANIFEST_FILENAME,
1970
+ );
1971
+
1972
+ if (!(await fileExists(installManifestPath))) {
1973
+ return 'missing_install_manifest';
1974
+ }
1975
+
1976
+ let installManifest;
1977
+ try {
1978
+ installManifest = JSON.parse(await readFile(installManifestPath, 'utf8'));
1979
+ } catch {
1980
+ return 'invalid_install_manifest';
1981
+ }
1982
+
1983
+ if (installManifest?.contract_version !== 'audit-code-install/v1alpha1') {
1984
+ return 'stale_install_manifest_contract';
1985
+ }
1986
+
1987
+ const assetPaths = installManifest.asset_paths ?? {};
1988
+ const hostCatalog = new Set(
1989
+ (installManifest.hosts ?? []).map((entry) => entry.host),
1990
+ );
1991
+
1992
+ for (const hostKey of getInstallHostKeys(host)) {
1993
+ if (!hostCatalog.has(hostKey)) {
1994
+ return `missing_host_surface:${hostKey}`;
1995
+ }
1996
+
1997
+ const definition = INSTALL_HOST_DEFINITIONS[hostKey];
1998
+ const requiredPathKeys = [
1999
+ definition.primary_path_key,
2000
+ ...definition.supporting_path_keys,
2001
+ ];
2002
+ for (const pathKey of requiredPathKeys) {
2003
+ const targetPath = assetPaths[pathKey];
2004
+ if (targetPath && !(await fileExists(targetPath))) {
2005
+ return `missing_host_asset:${hostKey}:${pathKey}`;
2006
+ }
2007
+ }
2008
+ }
2009
+
2010
+ const installedPrompt = await readTextIfExists(assetPaths.installedPromptPath);
2011
+ if (installedPrompt === null) {
2012
+ return 'missing_installed_prompt';
2013
+ }
2014
+ const sourcePrompt = await readFile(promptAssetPath, 'utf8');
2015
+ if (installedPrompt !== sourcePrompt) {
2016
+ return 'stale_installed_prompt';
2017
+ }
2018
+ const { body: sourcePromptBody } = splitFrontmatter(sourcePrompt);
2019
+
2020
+ const installedSkill = await readTextIfExists(assetPaths.installedSkillPath);
2021
+ if (installedSkill === null) {
2022
+ return 'missing_installed_skill';
2023
+ }
2024
+ const sourceSkill = (await readFile(skillAssetPath, 'utf8')).replace(/\r\n/g, '\n');
2025
+ if (installedSkill.replace(/\r\n/g, '\n') !== sourceSkill) {
2026
+ return 'stale_installed_skill';
2027
+ }
2028
+
2029
+ for (const hostKey of getInstallHostKeys(host)) {
2030
+ switch (hostKey) {
2031
+ case 'codex': {
2032
+ const codexSkill = await readTextIfExists(assetPaths.codexSkillPath);
2033
+ if (codexSkill?.replace(/\r\n/g, '\n') !== sourceSkill) {
2034
+ return 'stale_host_asset:codex:skill';
2035
+ }
2036
+ const codexPrompt = await readTextIfExists(assetPaths.codexPromptPath);
2037
+ if (codexPrompt !== sourcePrompt) {
2038
+ return 'stale_host_asset:codex:prompt';
2039
+ }
2040
+ break;
2041
+ }
2042
+ case 'opencode': {
2043
+ const opencodeSkill = await readTextIfExists(assetPaths.opencodeSkillPath);
2044
+ if (opencodeSkill?.replace(/\r\n/g, '\n') !== sourceSkill) {
2045
+ return 'stale_host_asset:opencode:skill';
2046
+ }
2047
+ const opencodePrompt = await readTextIfExists(assetPaths.opencodePromptPath);
2048
+ if (opencodePrompt !== sourcePrompt) {
2049
+ return 'stale_host_asset:opencode:prompt';
2050
+ }
2051
+ const opencodeCommand = await readTextIfExists(assetPaths.opencodeCommandPath);
2052
+ if (opencodeCommand === null) {
2053
+ return 'missing_host_asset:opencode:command';
2054
+ }
2055
+ if (splitFrontmatter(opencodeCommand).body !== sourcePromptBody.trimStart()) {
2056
+ return 'stale_host_asset:opencode:command';
2057
+ }
2058
+ break;
2059
+ }
2060
+ case 'vscode': {
2061
+ const vscodePrompt = await readTextIfExists(assetPaths.vscodePromptPath);
2062
+ if (vscodePrompt === null) {
2063
+ return 'missing_host_asset:vscode:prompt';
2064
+ }
2065
+ if (splitFrontmatter(vscodePrompt).body !== sourcePromptBody.trimStart()) {
2066
+ return 'stale_host_asset:vscode:prompt';
2067
+ }
2068
+ break;
2069
+ }
2070
+ default:
2071
+ break;
2072
+ }
2073
+ }
2074
+
2075
+ const launcherPath =
2076
+ assetPaths.mcpLauncherPath ?? installManifest.mcp_server_launcher_path;
2077
+ const launcher = launcherPath ? await readTextIfExists(launcherPath) : null;
2078
+ if (launcher === null) {
2079
+ return 'missing_mcp_launcher';
2080
+ }
2081
+ if (!launcher.includes('Unable to locate an audit-code executable')) {
2082
+ return 'stale_mcp_launcher';
2083
+ }
2084
+
2085
+ return null;
2086
+ }
2087
+
2088
+ async function ensureBootstrap(argv) {
2089
+ const host = (getFlag(argv, '--host') ?? DEFAULT_INSTALL_HOST).toLowerCase();
2090
+ const root = resolve(getFlag(argv, '--root') ?? '.');
2091
+ const quiet = hasFlag(argv, '--quiet');
2092
+ const force = hasFlag(argv, '--force');
2093
+ await assertDirectoryExists(root, 'Target repository root');
2094
+
2095
+ const reason = force
2096
+ ? 'forced'
2097
+ : await detectBootstrapRefreshReason(root, host);
2098
+
2099
+ if (reason) {
2100
+ const installed = await installBootstrap(argv, { quiet: true });
2101
+ const payload = {
2102
+ status: 'ok',
2103
+ action: 'installed',
2104
+ reason,
2105
+ host: installed.host,
2106
+ repo_root: installed.repo_root,
2107
+ install_manifest_path: installed.install_manifest_path,
2108
+ mcp_server_launcher_path: installed.mcp_server_launcher_path,
2109
+ host_count: installed.host_guidance.length,
2110
+ file_count: installed.files.length,
2111
+ };
2112
+ if (!quiet) {
2113
+ console.log(JSON.stringify(payload, null, 2));
2114
+ }
2115
+ return payload;
2116
+ }
2117
+
2118
+ const payload = {
2119
+ status: 'ok',
2120
+ action: 'skipped',
2121
+ reason: null,
2122
+ host,
2123
+ repo_root: root,
2124
+ install_manifest_path: join(
2125
+ root,
2126
+ '.audit-code',
2127
+ 'install',
2128
+ INSTALL_MANIFEST_FILENAME,
2129
+ ),
2130
+ };
2131
+ if (!quiet) {
2132
+ console.log(JSON.stringify(payload, null, 2));
2133
+ }
2134
+ return payload;
2135
+ }
2136
+
2137
+ async function installBootstrap(argv, options = {}) {
1956
2138
  const host = (getFlag(argv, '--host') ?? DEFAULT_INSTALL_HOST).toLowerCase();
1957
2139
  const root = resolve(getFlag(argv, '--root') ?? '.');
1958
2140
  await assertDirectoryExists(root, 'Target repository root');
@@ -2221,49 +2403,49 @@ async function installBootstrap(argv) {
2221
2403
  results.push({ path: sessionConfigPath, mode: 'created' });
2222
2404
  }
2223
2405
 
2224
- console.log(
2225
- JSON.stringify(
2226
- {
2227
- host,
2228
- repo_root: root,
2229
- installed_prompt_path: installedPromptPath,
2230
- installed_skill_path: installedSkillPath,
2231
- install_guide_path: installGuidePath,
2232
- install_manifest_path: installManifestPath,
2233
- mcp_server_launcher_path: mcpLauncherPath,
2234
- source_prompt_path: resolve(promptAssetPath),
2235
- source_skill_path: resolve(skillAssetPath),
2236
- files: results,
2237
- slash_command_surfaces: {
2238
- vscode_prompt: assetPaths.vscodePromptPath,
2239
- opencode_command: assetPaths.opencodeCommandPath,
2240
- },
2241
- instruction_surfaces: {
2242
- agents: assetPaths.agentsInstructionsPath,
2243
- copilot_instructions: assetPaths.copilotInstructionsPath,
2244
- },
2245
- mcp_surfaces: {
2246
- vscode_workspace: assetPaths.vscodeMcpConfigPath,
2247
- opencode_project: assetPaths.opencodeConfigPath,
2248
- codex_setup: assetPaths.codexMcpSetupPath,
2249
- shared_launcher: mcpLauncherPath,
2250
- claude_desktop_dxt: assetPaths.claudeDesktopDxtPath,
2251
- claude_desktop_mcpb: assetPaths.claudeDesktopMcpbPath,
2252
- antigravity_planning_guide: assetPaths.antigravityPlanningGuidePath,
2253
- },
2254
- host_guidance: hostGuidance,
2255
- unsupported_hosts: [],
2256
- next_steps: [
2257
- 'Open the repository in your preferred host and follow the matching host_guidance entry.',
2258
- `Open ${installGuidePath} for repo-local quick-start steps for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity.`,
2259
- 'Run `audit-code verify-install` from the repository root to smoke-test the generated launchers and host configs.',
2260
- 'Use the shared MCP launcher as the source of truth for local stdio MCP registration across hosts.',
2261
- ],
2262
- },
2263
- null,
2264
- 2,
2265
- ),
2266
- );
2406
+ const payload = {
2407
+ host,
2408
+ repo_root: root,
2409
+ installed_prompt_path: installedPromptPath,
2410
+ installed_skill_path: installedSkillPath,
2411
+ install_guide_path: installGuidePath,
2412
+ install_manifest_path: installManifestPath,
2413
+ mcp_server_launcher_path: mcpLauncherPath,
2414
+ source_prompt_path: resolve(promptAssetPath),
2415
+ source_skill_path: resolve(skillAssetPath),
2416
+ files: results,
2417
+ slash_command_surfaces: {
2418
+ vscode_prompt: assetPaths.vscodePromptPath,
2419
+ opencode_command: assetPaths.opencodeCommandPath,
2420
+ },
2421
+ instruction_surfaces: {
2422
+ agents: assetPaths.agentsInstructionsPath,
2423
+ copilot_instructions: assetPaths.copilotInstructionsPath,
2424
+ },
2425
+ mcp_surfaces: {
2426
+ vscode_workspace: assetPaths.vscodeMcpConfigPath,
2427
+ opencode_project: assetPaths.opencodeConfigPath,
2428
+ codex_setup: assetPaths.codexMcpSetupPath,
2429
+ shared_launcher: mcpLauncherPath,
2430
+ claude_desktop_dxt: assetPaths.claudeDesktopDxtPath,
2431
+ claude_desktop_mcpb: assetPaths.claudeDesktopMcpbPath,
2432
+ antigravity_planning_guide: assetPaths.antigravityPlanningGuidePath,
2433
+ },
2434
+ host_guidance: hostGuidance,
2435
+ unsupported_hosts: [],
2436
+ next_steps: [
2437
+ 'Open the repository in your preferred host and follow the matching host_guidance entry.',
2438
+ `Open ${installGuidePath} for repo-local quick-start steps for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity.`,
2439
+ 'Run `audit-code verify-install` from the repository root to smoke-test the generated launchers and host configs.',
2440
+ 'Use the shared MCP launcher as the source of truth for local stdio MCP registration across hosts.',
2441
+ ],
2442
+ };
2443
+
2444
+ if (!options.quiet) {
2445
+ console.log(JSON.stringify(payload, null, 2));
2446
+ }
2447
+
2448
+ return payload;
2267
2449
  }
2268
2450
 
2269
2451
  async function installHostPrompt(argv) {
@@ -2316,6 +2498,11 @@ export async function runAuditCodeWrapper({
2316
2498
  return;
2317
2499
  }
2318
2500
 
2501
+ if (argv[0] === 'ensure') {
2502
+ await ensureBootstrap(argv.slice(1));
2503
+ return;
2504
+ }
2505
+
2319
2506
  if (argv[0] === 'install') {
2320
2507
  await installBootstrap(argv.slice(1));
2321
2508
  return;
@@ -31,14 +31,33 @@ The canonical prompt asset is:
31
31
 
32
32
  `skills/audit-code/audit-code.prompt.md`
33
33
 
34
- The preferred bootstrap path is:
34
+ The preferred install path for users is:
35
35
 
36
36
  ```bash
37
- audit-code install
37
+ npm install -g auditor-lambda
38
+ ```
39
+
40
+ That makes `audit-code` available on `PATH` and seeds user-level command/skill
41
+ assets for hosts we can safely update during package installation. Once the
42
+ slash command is available, `/audit-code` self-bootstraps the current repository
43
+ with:
44
+
45
+ ```bash
46
+ audit-code ensure --quiet
38
47
  ```
39
48
 
40
- That installs repo-local `/audit-code` surfaces and MCP-oriented support assets for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity.
41
- It also writes `.audit-code/install/GETTING-STARTED.md` with dedicated quick-start sections for each host plus `.audit-code/install/manifest.json` and a shared repo-local MCP launcher.
49
+ `ensure` writes repo-local `/audit-code` surfaces and MCP-oriented support assets
50
+ for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity only when they are
51
+ missing or stale. It also writes `.audit-code/install/GETTING-STARTED.md` with
52
+ dedicated quick-start sections for each host plus `.audit-code/install/manifest.json`
53
+ and a shared repo-local MCP launcher.
54
+
55
+ Use the explicit installer when you want to repair or force-refresh those
56
+ repo-local assets:
57
+
58
+ ```bash
59
+ audit-code install
60
+ ```
42
61
 
43
62
  Use one of these supported ways to obtain the raw prompt asset directly when you need prompt import instead:
44
63
 
@@ -57,7 +76,12 @@ Use `/audit-code` in conversation, treat the active conversation model as the de
57
76
 
58
77
  ### Codex
59
78
 
60
- Use `audit-code install --host codex` or the default `audit-code install` from the target repository root.
79
+ The global npm install seeds `~/.codex/skills/audit-code/` so the command can be
80
+ available before a repository is bootstrapped. The first `/audit-code` run then
81
+ uses `audit-code ensure --quiet` to create or refresh repo-local Codex support.
82
+
83
+ Use `audit-code install --host codex` only when you want to repair or force-refresh
84
+ the Codex repo-local files from the target repository root.
61
85
 
62
86
  That writes a repo-local Codex skill bundle, updates `AGENTS.md` through a managed block when needed, and emits Codex-specific MCP setup guidance plus an automation recipe in `.audit-code/install/codex/`.
63
87
  The intended operator flow is still conversational first, with the generated skill and AGENTS guidance steering the active Codex session toward `/audit-code` and the MCP-backed workflow.
@@ -79,21 +103,29 @@ Manual prompt import remains a fallback, not the primary documented path.
79
103
 
80
104
  ### OpenCode
81
105
 
82
- Use `audit-code install` from the target repository root.
106
+ OpenCode currently relies on repo-local command and MCP config files for the
107
+ cleanest experience. A global `/audit-code` prompt can run `audit-code ensure --quiet`
108
+ first; otherwise run `audit-code install` from the target repository root once.
83
109
 
84
110
  That writes `.opencode/commands/audit-code.md`, a repo-local OpenCode skill bundle, and `opencode.json` so `/audit-code` is available in the repository with no extra provider flags.
85
111
  The generated OpenCode assets also point OpenCode toward the shared auditor MCP server instead of rebuilding backend state ad hoc.
86
112
 
87
113
  ### VS Code
88
114
 
89
- Run `audit-code install` from the target repository root, then open `.audit-code/install/GETTING-STARTED.md` if you want the exact repo-local path that bootstrap created for VS Code chat surfaces.
115
+ VS Code currently relies on workspace prompt and MCP config files for the
116
+ cleanest experience. A global `/audit-code` prompt can run `audit-code ensure --quiet`
117
+ first; otherwise run `audit-code install` from the target repository root, then
118
+ open `.audit-code/install/GETTING-STARTED.md` if you want the exact repo-local
119
+ path that bootstrap created for VS Code chat surfaces.
90
120
 
91
121
  That writes `.github/prompts/audit-code.prompt.md`, `.github/copilot-instructions.md`, `.github/agents/auditor.agent.md`, and `.vscode/mcp.json`.
92
122
  The expected happy path is still to invoke `/audit-code` from chat, not to start from the backend CLI.
93
123
 
94
124
  ### Antigravity
95
125
 
96
- Run `audit-code install` from the target repository root, then open `.audit-code/install/GETTING-STARTED.md`.
126
+ Run `/audit-code` from a global prompt-capable host and let `audit-code ensure --quiet`
127
+ create the repo-local guidance, or run `audit-code install` from the target
128
+ repository root, then open `.audit-code/install/GETTING-STARTED.md`.
97
129
 
98
130
  There is still no documented native repo-local saved-workflow surface for Antigravity in this repository today, so the intended path is:
99
131
 
@@ -229,7 +261,9 @@ Only use the repo-local `audit-code` wrapper with `provider: "opencode"` when yo
229
261
 
230
262
  ### VS Code
231
263
 
232
- Run `audit-code install` once from the target repository root, then use `/audit-code` from chat.
264
+ Use `/audit-code` from chat and let the prompt run `audit-code ensure --quiet`.
265
+ Run `audit-code install` manually only when VS Code has not yet discovered the
266
+ workspace prompt/MCP files or you want to force-refresh them.
233
267
 
234
268
  The backend fallback is still available from the integrated terminal and should keep `local-subprocess` unless you specifically need a task bridge.
235
269
 
@@ -242,7 +276,7 @@ No dedicated Antigravity provider adapter is shipped today.
242
276
  Current recommended usage is one of these:
243
277
 
244
278
  - use the skill-first conversational contract as the primary surface
245
- - run `audit-code install` first so compatibility files are present
279
+ - let `/audit-code` run `audit-code ensure --quiet`, or run `audit-code install` manually so compatibility files are present
246
280
  - run `audit-code` from an Antigravity-managed terminal with `local-subprocess`
247
281
  - use `subprocess-template` if you have a reliable Antigravity-side launcher bridge
248
282
 
@@ -272,7 +306,7 @@ The product direction remains skill-first:
272
306
  For a polished operator experience today:
273
307
 
274
308
  1. treat `/audit-code` as the canonical user-facing contract
275
- 2. use `audit-code install` first, and fall back to `audit-code prompt-path` only for hosts that still require manual prompt import
309
+ 2. install once with `npm install -g auditor-lambda`, then let `/audit-code` run `audit-code ensure --quiet` in each repository
276
310
  3. use `audit-code` as the repo-local backend fallback
277
311
  4. prefer `local-subprocess` unless you explicitly want a backend provider bridge
278
312
  5. use `subprocess-template` only when integrating a non-native editor or launcher surface
@@ -1,15 +1,34 @@
1
1
  # Bootstrap install
2
2
 
3
- The intended setup flow is a single bootstrap step from the target repository root:
3
+ The intended user setup is one global package install:
4
+
5
+ ```bash
6
+ npm install -g auditor-lambda
7
+ ```
8
+
9
+ That makes the `audit-code` command available from any repository. Package
10
+ install also seeds user-level command or skill assets for hosts we can update
11
+ safely, including the Claude command file and Codex skill bundle.
12
+
13
+ After that, the normal user flow is to invoke `/audit-code` in a supported host.
14
+ The prompt starts by running:
15
+
16
+ ```bash
17
+ audit-code ensure --quiet
18
+ ```
19
+
20
+ `ensure` is idempotent. From the target repository root, it writes the
21
+ repo-local `/audit-code` surfaces only when they are missing or stale.
22
+
23
+ The explicit repair or compatibility command remains:
4
24
 
5
25
  ```bash
6
26
  audit-code install
7
27
  ```
8
28
 
9
- That command installs the repo-local `/audit-code` surfaces we can automate today.
10
- It is also the single refresh path: rerun `audit-code install` after prompt or
11
- skill updates to rewrite the shared install assets and every generated
12
- host-specific surface from the same source files.
29
+ That command always rewrites the repo-local `/audit-code` surfaces we can
30
+ automate today. `audit-code ensure --force` is the equivalent self-bootstrap
31
+ entrypoint when you want forced refresh semantics.
13
32
  The generated manifest records the canonical prompt and skill source paths so
14
33
  host surfaces can be checked against one shared source of truth instead of
15
34
  drifting independently.
@@ -79,6 +98,9 @@ without supplying extra root paths, provider flags, or model-selection arguments
79
98
 
80
99
  ## What is fully automated today
81
100
 
101
+ - global `npm install -g auditor-lambda` seeds user-level Claude command and
102
+ Codex skill assets when filesystem permissions allow it
103
+ - `/audit-code` runs `audit-code ensure --quiet` before advancing the audit
82
104
  - shared installer output, manifest generation, and repo-local MCP launcher generation
83
105
  - default backend fallback session-config creation when no config exists yet
84
106
  - Codex skill-bundle and AGENTS-oriented install output
@@ -1,12 +1,27 @@
1
1
  # GitHub Copilot setup
2
2
 
3
- This is the first shipped native host integration for the `/audit-code` conversation surface.
3
+ This is one repo-local host integration for the `/audit-code` conversation surface.
4
4
 
5
- It is now a narrower host-specific path. The preferred setup flow is `audit-code install`, which bootstraps all supported repo-local host surfaces in one step.
5
+ It is now a narrower host-specific path. The preferred user flow is a global
6
+ package install plus the prompt's self-bootstrap step; `audit-code install`
7
+ remains the explicit repair or force-refresh path.
6
8
 
7
9
  ## Recommended path
8
10
 
9
- From the target repository root:
11
+ Install once:
12
+
13
+ ```bash
14
+ npm install -g auditor-lambda
15
+ ```
16
+
17
+ Then invoke `/audit-code` in a supported chat surface. The prompt runs:
18
+
19
+ ```bash
20
+ audit-code ensure --quiet
21
+ ```
22
+
23
+ If Copilot has not discovered the workspace prompt/MCP files yet, run this from
24
+ the target repository root:
10
25
 
11
26
  ```bash
12
27
  audit-code install
@@ -29,7 +44,8 @@ audit-code install --host vscode
29
44
 
30
45
  ## Behavior
31
46
 
32
- - the command copies the canonical prompt payload from `skills/audit-code/audit-code.prompt.md`
47
+ - `audit-code ensure` creates or refreshes the same files only when missing or stale
48
+ - `audit-code install` force-refreshes the canonical prompt payload from `skills/audit-code/audit-code.prompt.md`
33
49
  - the generated prompt file explicitly sets `agent: auditor` so Copilot Chat uses the generated auditor custom agent
34
50
  - the installer upserts its managed compatibility block into `.github/copilot-instructions.md` instead of clobbering unrelated instructions
35
51
  - it prints machine-readable JSON describing the installed targets
@@ -46,5 +62,5 @@ audit-code install --root /path/to/repo
46
62
 
47
63
  The goal is to reduce conversation setup friction without repositioning the backend CLI as the primary product surface.
48
64
 
49
- GitHub Copilot now shares the same repo-native bootstrap path as the other currently automated hosts.
65
+ GitHub Copilot now shares the same repo-native self-bootstrap path as the other currently automated hosts.
50
66
  The older `audit-code install-host --host copilot` alias still exists for compatibility, but it is no longer the recommended setup flow.
@@ -16,7 +16,9 @@ The repository now supports:
16
16
  - `/audit-code` as the documented canonical product route
17
17
  - packaged and repository-local access to `skills/audit-code/audit-code.prompt.md`
18
18
  - `audit-code prompt-path` as a stable prompt lookup helper
19
- - `audit-code install --host vscode|opencode|codex|claude-desktop|antigravity|all` as a bootstrap installer for the current host surfaces
19
+ - `npm install -g auditor-lambda` as the intended one-time user install
20
+ - `audit-code ensure` as an idempotent self-bootstrap helper for current repository host surfaces
21
+ - `audit-code install --host vscode|opencode|codex|claude-desktop|antigravity|all` as an explicit repair or force-refresh installer for the current host surfaces
20
22
  - `audit-code mcp` as a first-class stdio MCP server entrypoint
21
23
  - a stable MCP contract with the `start_audit`, `get_status`, `continue_audit`, `explain_task`, `validate_artifacts`, `import_results`, and `import_runtime_updates` tools
22
24
  - repo-local MCP resources for current artifacts, operator handoff, install guidance, and the current audit report
@@ -109,7 +111,7 @@ The repository should not be described as frictionless and production-ready unti
109
111
 
110
112
  ### Codex, Claude Desktop, OpenCode, and VS Code
111
113
 
112
- - `audit-code install` remains the default bootstrap path
114
+ - `audit-code ensure` remains the default self-bootstrap path and `audit-code install` remains the explicit repair path
113
115
  - the generated repo-local surfaces are obvious in installer output and in `.audit-code/install/GETTING-STARTED.md`
114
116
  - a new user can invoke `/audit-code` without guessing where prompts or commands were written
115
117
  - the generated MCP setup path works in the real host, not only in unit tests
package/docs/packaging.md CHANGED
@@ -4,6 +4,7 @@ This repository validates the packaged installation story for both:
4
4
 
5
5
  1. the canonical conversation prompt asset
6
6
  2. the backend fallback `audit-code` entrypoint
7
+ 3. the self-bootstrap `audit-code ensure` path used by global slash commands
7
8
 
8
9
  It does so in two installation modes:
9
10
 
@@ -20,6 +21,10 @@ That means the package needs to ship:
20
21
  - the companion Codex/OpenCode skill asset at `skills/audit-code/SKILL.md`
21
22
  - packet-dispatch support data such as `dispatch/lens-definitions.json`
22
23
  - the backend fallback wrapper exposed as `audit-code`
24
+ - user-level postinstall assets for hosts we can safely seed from a global npm
25
+ install, currently the Claude command and Codex skill bundle
26
+ - `audit-code ensure`, so a globally installed slash command can lazily create
27
+ the repo-local host assets it needs in each target repository
23
28
 
24
29
  A linked-command smoke test proves the installed wrapper and prompt lookup work from the working tree.
25
30
  A packaged-install smoke test proves the same assets still work when consumed from the packed artifact that a downstream installer would receive.
@@ -52,6 +57,7 @@ That script:
52
57
  - installs it into a fresh temporary directory
53
58
  - verifies the packaged prompt asset is present and discoverable
54
59
  - verifies `audit-code install` can write the bootstrap host surfaces from the packaged install
60
+ - verifies `audit-code ensure` can create those surfaces lazily from the packaged install
55
61
  - invokes the installed `audit-code` binary from `node_modules/.bin`
56
62
  - validates emitted JSON against `schemas/audit-code-v1alpha1.schema.json`
57
63
  - exercises the same evidence-import and completion flow used by the linked-command smoke test
@@ -33,7 +33,26 @@ audit-code prompt-path
33
33
 
34
34
  That command exists to locate the conversation prompt asset, not to reposition the CLI as the primary user surface.
35
35
 
36
- The preferred bootstrap installer is:
36
+ The intended package install is:
37
+
38
+ ```bash
39
+ npm install -g auditor-lambda
40
+ ```
41
+
42
+ That makes the backend command globally available and lets hosts with user-level
43
+ command or skill discovery expose `/audit-code` before any repository-local
44
+ files exist.
45
+
46
+ The conversation prompt should self-bootstrap the current repository with:
47
+
48
+ ```bash
49
+ audit-code ensure --quiet
50
+ ```
51
+
52
+ That command creates or refreshes repo-local `/audit-code` surfaces only when
53
+ they are missing or stale.
54
+
55
+ The explicit repair and compatibility installer is:
37
56
 
38
57
  ```bash
39
58
  audit-code install
@@ -10,8 +10,10 @@ The current product surfaces are:
10
10
 
11
11
  1. `/audit-code` in conversation as the canonical user-facing route
12
12
  2. `audit-code prompt-path` as the stable way to locate the packaged prompt asset
13
- 3. `audit-code install` as the preferred repo-local bootstrap installer
14
- 4. `audit-code` as the repo-local backend fallback wrapper
13
+ 3. `npm install -g auditor-lambda` as the intended one-time user install
14
+ 4. `audit-code ensure` as the idempotent repo-local self-bootstrap helper
15
+ 5. `audit-code install` as the explicit repo-local repair or force-refresh installer
16
+ 6. `audit-code` as the repo-local backend fallback wrapper
15
17
 
16
18
  Anything below `dist/index.js` remains a backend or development interface rather than the primary end-user contract.
17
19
 
@@ -30,6 +32,9 @@ Anything below `dist/index.js` remains a backend or development interface rather
30
32
  - `skills/audit-code/audit-code.prompt.md`
31
33
  - `schemas/audit-code-v1alpha1.schema.json`
32
34
  - the checked-in `dist/` output is part of the shipped runtime contract for installed usage
35
+ - global package postinstall should seed user-level command/skill assets only for
36
+ hosts with stable user-local paths; repo-local assets remain the responsibility
37
+ of `audit-code ensure` or `audit-code install`
33
38
 
34
39
  ### Backend providers
35
40
 
@@ -40,7 +45,7 @@ Anything below `dist/index.js` remains a backend or development interface rather
40
45
  ### Host surfaces
41
46
 
42
47
  - ChatGPT-style project conversations are the intended `/audit-code` product surface
43
- - Codex, Claude Desktop, OpenCode, VS Code / GitHub Copilot, and Antigravity repository surfaces are generated through `audit-code install`
48
+ - Codex, Claude Desktop, OpenCode, VS Code / GitHub Copilot, and Antigravity repository surfaces are generated through `audit-code ensure` or explicit `audit-code install`
44
49
  - editor integrations that import `skills/audit-code/audit-code.prompt.md` are supported as prompt-based integrations
45
50
  - no editor-specific native install surface should be called production-ready until it has explicit documentation and a repeatable verification path
46
51
 
@@ -16,7 +16,8 @@ What is already true:
16
16
  - npm registry state should be verified at release time rather than inferred from checked-in docs
17
17
  - malformed config and corrupted artifact handling are explicit
18
18
  - blocked fallback runs now emit structured operator handoff guidance
19
- - supported repo-local hosts now share a bootstrap install path via `audit-code install`
19
+ - supported repo-local hosts now share an idempotent self-bootstrap path via `audit-code ensure`
20
+ - `audit-code install` remains the explicit repair and force-refresh path
20
21
  - configured provider-assisted review can now continue to completion in a single wrapper invocation
21
22
  - the GitHub publish workflow is configured for Trusted Publishing through GitHub OIDC rather than a long-lived npm token
22
23
 
@@ -27,7 +28,7 @@ The biggest remaining gaps are product and release-operational, not core wrapper
27
28
  1. npm publication is not fully proven end to end.
28
29
  The repo now has a Trusted Publishing workflow and a passing local dry run, but npm-side trusted publisher setup plus the first GitHub Actions dry run still need to be completed outside the codebase.
29
30
  2. The primary conversation-first product still has setup friction on hosts without a verified repo-local slash-command surface.
30
- Codex, Claude Desktop, OpenCode, VS Code / Copilot, and Antigravity now share the same bootstrap command, but each generated host surface still needs real-product verification before it can be called frictionless.
31
+ Codex, Claude Desktop, OpenCode, VS Code / Copilot, and Antigravity now share the same self-bootstrap command, but each generated host surface still needs real-product verification before it can be called frictionless.
31
32
  3. Provider-assisted continuation still needs polish outside the happy path.
32
33
  Configured interactive bridges can now continue through audit-task review, but operator guidance and host-specific ergonomics still need refinement when a provider cannot produce results cleanly.
33
34
 
@@ -38,7 +39,7 @@ The explicit launch bar is now documented in `docs/production-launch-bar.md`, an
38
39
  1. Confirm release operations externally.
39
40
  Validate npm package-name ownership for `auditor-lambda`, configure npm Trusted Publishing for `.github/workflows/publish-package.yml`, and run a real GitHub Actions dry run or prerelease publish from that workflow path.
40
41
  2. Extend bootstrap coverage beyond the currently automated hosts.
41
- Keep `audit-code install` stable for Codex, Claude Desktop, OpenCode, VS Code / Copilot, and Antigravity, and close the remaining friction gap for hosts that still lack a verified repo-local install surface.
42
+ Keep `audit-code ensure` and `audit-code install` stable for Codex, Claude Desktop, OpenCode, VS Code / Copilot, and Antigravity, and close the remaining friction gap for hosts that still lack a verified repo-local install surface.
42
43
  3. Polish provider-assisted UX.
43
44
  Keep the new continuation path explicit and inspectable while improving failure hints, host guidance, and operator recovery when a provider bridge misbehaves.
44
45
 
package/docs/usage.md CHANGED
@@ -6,7 +6,28 @@ The primary product remains `/audit-code` in conversation.
6
6
 
7
7
  ## Stable installed helpers
8
8
 
9
- Bootstrap the supported repo-local `/audit-code` surfaces for the current repository:
9
+ Install the package once for the current user:
10
+
11
+ ```bash
12
+ npm install -g auditor-lambda
13
+ ```
14
+
15
+ Then invoke `/audit-code` in a supported host. The prompt runs this idempotent
16
+ bootstrap helper before advancing the audit:
17
+
18
+ ```bash
19
+ audit-code ensure --quiet
20
+ ```
21
+
22
+ Run the same helper manually when you want to create or refresh the repo-local
23
+ host assets without starting an audit:
24
+
25
+ ```bash
26
+ audit-code ensure
27
+ ```
28
+
29
+ Explicitly rewrite the supported repo-local `/audit-code` surfaces for the
30
+ current repository:
10
31
 
11
32
  ```bash
12
33
  audit-code install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auditor-lambda",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "private": false,
5
5
  "description": "Portable hybrid code-auditing framework for arbitrary repositories.",
6
6
  "type": "module",
@@ -5,23 +5,60 @@ import { mkdirSync, existsSync, readFileSync, writeFileSync } from 'fs';
5
5
  import { fileURLToPath } from 'url';
6
6
 
7
7
  const pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
- const sourceFile = join(pkgRoot, 'skills', 'audit-code', 'audit-code.prompt.md');
9
- const destDir = join(homedir(), '.claude', 'commands');
10
- const destFile = join(destDir, 'audit-code.md');
8
+ const promptSourceFile = join(pkgRoot, 'skills', 'audit-code', 'audit-code.prompt.md');
9
+ const skillSourceFile = join(pkgRoot, 'skills', 'audit-code', 'SKILL.md');
11
10
 
12
- if (!existsSync(sourceFile)) {
13
- console.warn(`audit-code: skill source not found at ${sourceFile} — skipping Claude command install`);
11
+ function readRequiredSource(path, label) {
12
+ if (!existsSync(path)) {
13
+ console.warn(`audit-code: ${label} source not found at ${path} - skipping global command install`);
14
+ process.exitCode = 0;
15
+ return null;
16
+ }
17
+
18
+ return readFileSync(path);
19
+ }
20
+
21
+ function writeGeneratedFile(path, content) {
22
+ const action = existsSync(path) ? 'updated' : 'installed';
23
+ mkdirSync(dirname(path), { recursive: true });
24
+ writeFileSync(path, content);
25
+ return action;
26
+ }
27
+
28
+ const promptSource = readRequiredSource(promptSourceFile, 'prompt');
29
+ const skillSource = readRequiredSource(skillSourceFile, 'skill');
30
+
31
+ if (!promptSource || !skillSource) {
14
32
  process.exit(0);
15
33
  }
16
34
 
17
- try {
18
- mkdirSync(destDir, { recursive: true });
19
- const action = existsSync(destFile) ? 'updated' : 'installed';
20
- // Read then write to avoid Windows file-lock issues with copyFileSync
21
- writeFileSync(destFile, readFileSync(sourceFile));
22
- console.log(`audit-code: ${action} /audit-code Claude command → ${destFile}`);
23
- } catch (err) {
24
- console.warn(`audit-code: could not install Claude command (${err.message})`);
25
- console.warn(` To install manually, run:`);
26
- console.warn(` cp "${sourceFile}" "${destFile}"`);
35
+ const installs = [
36
+ {
37
+ label: 'Claude command',
38
+ path: join(homedir(), '.claude', 'commands', 'audit-code.md'),
39
+ content: promptSource,
40
+ },
41
+ {
42
+ label: 'Codex skill',
43
+ path: join(homedir(), '.codex', 'skills', 'audit-code', 'SKILL.md'),
44
+ content: skillSource,
45
+ },
46
+ {
47
+ label: 'Codex prompt',
48
+ path: join(homedir(), '.codex', 'skills', 'audit-code', 'audit-code.prompt.md'),
49
+ content: promptSource,
50
+ },
51
+ ];
52
+
53
+ for (const install of installs) {
54
+ try {
55
+ const action = writeGeneratedFile(install.path, install.content);
56
+ console.log(`audit-code: ${action} global ${install.label} at ${install.path}`);
57
+ } catch (err) {
58
+ console.warn(`audit-code: could not install global ${install.label} (${err.message})`);
59
+ console.warn(` To install manually, copy from:`);
60
+ console.warn(` ${install.label === 'Codex skill' ? skillSourceFile : promptSourceFile}`);
61
+ console.warn(` to:`);
62
+ console.warn(` ${install.path}`);
63
+ }
27
64
  }
@@ -38,13 +38,29 @@ Bounded steps are a backend implementation detail, not the intended user experie
38
38
 
39
39
  The prompt payload in `audit-code.prompt.md` remains the canonical instruction asset.
40
40
 
41
- The preferred setup path is:
41
+ The intended user setup is one global package install:
42
42
 
43
43
  ```bash
44
- audit-code install
44
+ npm install -g auditor-lambda
45
+ ```
46
+
47
+ That makes `audit-code` available on `PATH` and seeds user-level command/skill
48
+ assets for hosts the package can safely update. The prompt self-bootstraps the
49
+ current repository before advancing the audit:
50
+
51
+ ```bash
52
+ audit-code ensure --quiet
45
53
  ```
46
54
 
47
- That bootstrap writes repo-local host assets for Codex, Claude Desktop, OpenCode, VS Code, and Antigravity plus shared MCP setup guidance.
55
+ That idempotent bootstrap writes repo-local host assets for Codex, Claude Desktop,
56
+ OpenCode, VS Code, and Antigravity plus shared MCP setup guidance only when they
57
+ are missing or stale.
58
+
59
+ Use the explicit installer for repair or forced refresh:
60
+
61
+ ```bash
62
+ audit-code install
63
+ ```
48
64
 
49
65
  Use direct prompt import only when the target host still needs it after bootstrap.
50
66
 
@@ -33,7 +33,20 @@ and ingest results mechanically.
33
33
 
34
34
  ## Step 1 - Advance Deterministic State
35
35
 
36
- Run:
36
+ First, make sure the repository has the minimal local assets required by the
37
+ current host:
38
+
39
+ ```bash
40
+ audit-code ensure --quiet
41
+ ```
42
+
43
+ Inside the `auditor-lambda` repository itself, use:
44
+
45
+ ```bash
46
+ node audit-code.mjs ensure --quiet
47
+ ```
48
+
49
+ Then run:
37
50
 
38
51
  ```bash
39
52
  audit-code