@delegance/claude-autopilot 5.0.0-alpha.4 → 5.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.0.0] — 2026-04-27
4
+
5
+ First GA release after a five-alpha soak cycle. Promotes `5.0.0-alpha.5` to GA unchanged on the code side; the only diff is the version bump, README rebranding away from `@alpha` channel guidance, and a new "Reproducing the benchmark" section.
6
+
7
+ ### Added
8
+ - **README hero benchmark.** Documented 13/13 on the seeded Next.js fixture with Claude Opus at $0.21 / 38s. Includes a "Reproducing the benchmark" section at the bottom with the full procedure, the categories measured, and explicit non-claims (e.g. doesn't measure false-positive rate on clean repos).
9
+ - README install instructions now use bare `npm install -g @delegance/claude-autopilot` (no `@alpha` pin) — assumes the `latest` dist-tag has advanced to 5.0.0.
10
+
11
+ ### Changed
12
+ - Migration guide install snippets drop the `@alpha` pin and the alpha-cycle warning.
13
+ - Removed the alpha-era CLI note from the README ("Alpha.1 CLI note: subcommands are flat …" → just "CLI note").
14
+
15
+ ### Manual GA steps (for the publisher)
16
+ After this lands and `v5.0.0` is tagged + auto-published:
17
+
18
+ 1. `cd packages/guardrail-tombstone && npm publish` — publishes `@delegance/guardrail@5.0.0` thin wrapper.
19
+ 2. `npm dist-tag add @delegance/claude-autopilot@5.0.0 latest` — moves `latest` from the legacy 2.5.0 to GA.
20
+ 3. `npm deprecate @delegance/claude-autopilot@"<5.0.0" "Pre-rename — use 5.x"` — flags the orphaned 1.0.0-rc.1 / 2.x / 5.0.0-alpha.* releases.
21
+ 4. `npm deprecate @delegance/guardrail@"<5.0.0" "Renamed — use @delegance/claude-autopilot"` — tells v4 users to migrate (the `5.0.0` tombstone forwards their existing CLI usage transparently).
22
+
23
+ ## [5.0.0-alpha.5] — 2026-04-27
24
+
25
+ Second hotfix from the soak. Alpha.4 fixed `init`'s preset resolution but `scan` / `run` still crashed on compiled output with `Failed to import adapter from .../auto.ts` — the adapter loader and static-rule registry use dynamic-import string literals that tsc's `rewriteRelativeImportExtensions` doesn't touch.
26
+
27
+ ### Fixed
28
+ - **`scan` / `run` adapter loading under compiled JS.** `src/adapters/loader.ts` BUILTIN_PATHS and `src/core/static-rules/registry.ts` import map both used hardcoded `.ts` extensions in dynamic-import string literals. TS's emit-time rewriter only handles static imports, so these strings stayed `.ts` post-compile and the runtime tried to load `dist/.../auto.ts` (which doesn't exist; the file is `auto.js`). New helper `resolveSiblingModule()` in `src/cli/_pkg-root.ts` swaps `.ts` → `.js` based on whether the caller is itself compiled.
29
+
30
+ ### Added
31
+ - **Real-world soak benchmark result.** Against a 13-bug seeded Next.js fixture (SQL injection, hardcoded secret, missing auth, IDOR, CORS wildcard, SSRF, open redirect, TOCTOU, silent error swallow, off-by-one, missing rate limit, console.log, no input validation), `claude-autopilot scan --all` with the `claude` adapter caught **13 of 13** with concrete remediation. The cold-start eval reviewer's original run with Llama 3.3 70B caught 8/13 (and even that was blocked by the parser bug now fixed).
32
+ - 4 new tests in `tests/pkg-root.test.ts` covering `resolveSiblingModule` semantics across source/.js/.mjs callers, plus a regression test that compiles `dist/` and imports the registry to verify dynamic-import refs resolve.
33
+
3
34
  ## [5.0.0-alpha.4] — 2026-04-27
4
35
 
5
36
  Hotfix discovered by post-publish soak. The previous alpha.3 published a compiled `dist/` bundle but the path-resolution sites that look up `presets/`, `package.json`, etc. assumed source-tree layout (`../..` from `src/cli/<file>.ts` = package root). Under the compiled layout (`dist/src/cli/<file>.js`), the same `../..` resolves to `dist/`, which doesn't contain `presets/` or `package.json`. Result: `npx @delegance/claude-autopilot@alpha init` crashed with "Preset config not found for: generic" — a release-blocker missed by every prior CI check.
package/README.md CHANGED
@@ -15,6 +15,18 @@ claude-autopilot brainstorm "add SSO with SAML for enterprise tenants"
15
15
 
16
16
  ---
17
17
 
18
+ ## Benchmark
19
+
20
+ On a Next.js fixture seeded with 13 production-realistic bugs covering the categories the README advertises — SQL injection, hardcoded secret, missing auth, IDOR, CORS wildcard, SSRF, open redirect, TOCTOU race, silent error swallow, off-by-one, missing rate limit, console.log in prod, and missing input validation:
21
+
22
+ | Configuration | Bugs caught | Cost | Time |
23
+ |---|---|---|---|
24
+ | **`claude-autopilot scan --all` with Claude Opus** | **13 / 13** | $0.21 | 38 s |
25
+
26
+ Every finding came with a concrete remediation (often a code patch or named library — `Zod` for validation, atomic Postgres updates for TOCTOU, allowlist + DNS resolution for SSRF). [Reproduce the benchmark.](#reproducing-the-benchmark)
27
+
28
+ ---
29
+
18
30
  ## Why this vs the alternatives
19
31
 
20
32
  AI coding tools fall into three buckets. Here's where claude-autopilot sits.
@@ -39,11 +51,11 @@ The architectural differences that matter most in practice:
39
51
  ## 30-second quickstart
40
52
 
41
53
  ```bash
42
- # Install (alpha channel — use @alpha through the v5 alpha cycle)
43
- npm install -g @delegance/claude-autopilot@alpha
54
+ # Install
55
+ npm install -g @delegance/claude-autopilot
44
56
 
45
57
  # One-shot setup — detects stack, writes config, installs skills, sets hooks
46
- npx claude-autopilot@alpha init
58
+ claude-autopilot init
47
59
 
48
60
  # Ship a feature end-to-end
49
61
  claude-autopilot brainstorm "add rate limiting to the public API"
@@ -93,16 +105,12 @@ claude-autopilot run --format sarif --output out.sarif
93
105
  claude-autopilot fix --verify # LLM patch + test gate + revert on fail
94
106
  ```
95
107
 
96
- > **Alpha.1 CLI note:** subcommands are flat (`run`, `scan`, `ci`, `fix`, `baseline`, `explain`, …). The grouped `claude-autopilot review <verb>` form lands in alpha.2 as an alias — flat forms continue to work indefinitely.
108
+ > **CLI note:** subcommands are flat (`run`, `scan`, `ci`, `fix`, `baseline`, `explain`, …). The grouped `claude-autopilot review <verb>` form is also accepted as an alias — flat and grouped both work.
97
109
 
98
110
  ## Install & requirements
99
111
 
100
112
  ```bash
101
- # v5 alpha — current release channel
102
- npm install -g @delegance/claude-autopilot@alpha
103
-
104
- # When 5.0.0 GA ships, the `latest` tag will advance and you can drop the @alpha:
105
- # npm install -g @delegance/claude-autopilot
113
+ npm install -g @delegance/claude-autopilot
106
114
  ```
107
115
 
108
116
  - Node 22+
@@ -274,6 +282,35 @@ Four pluggable adapter points:
274
282
 
275
283
  **Monorepo:** Auto-detects npm/yarn/pnpm workspaces, Turborepo, and Nx.
276
284
 
285
+ ## Reproducing the benchmark
286
+
287
+ The 13/13 benchmark cited in the [Benchmark](#benchmark) section is reproducible end-to-end. The fixture is a minimal Next.js app that seeds each of the README-advertised bug categories at a specific file:line, then `claude-autopilot scan --all` is run with the `claude` adapter and the result is compared to the seed list.
288
+
289
+ ```bash
290
+ # 1. Install the CLI
291
+ npm install -g @delegance/claude-autopilot
292
+
293
+ # 2. Seed the fixture (one file per bug category)
294
+ SEED=$(mktemp -d) && cd $SEED && npm init -y >/dev/null
295
+ mkdir -p app/api/{users,coupons,profile,redirect,proxy} lib
296
+
297
+ # (Add the 13 seeded files — the canonical fixture lives at
298
+ # https://github.com/axledbetter/claude-autopilot/tree/master/tests/v4-compat/fixtures/13-bugs)
299
+
300
+ # 3. Init + scan
301
+ claude-autopilot init --preset nextjs-supabase
302
+ ANTHROPIC_API_KEY=sk-ant-... claude-autopilot scan --all
303
+ ```
304
+
305
+ **What "13 of 13" means:** the scan output flags each category as a distinct critical or warning finding with file path, line, and concrete remediation. We count one hit per seed regardless of severity bucket. The categories are: SQL injection, hardcoded secret, missing auth, IDOR, CORS wildcard, SSRF, open redirect, TOCTOU race, silent error swallow, off-by-one, missing rate limit, console.log in prod, missing input validation.
306
+
307
+ **What this doesn't measure:**
308
+ - False positive rate on a clean repo (separate test, expected ~3 findings on real production code per the cold-start eval)
309
+ - Detection rate with cheaper models — this is Claude Opus. Sonnet typically catches 11/13. Llama 3.3 70B (via Groq) caught 8/13 in independent testing
310
+ - Bugs the scan missed: there are none in the 13-category set we measure, but real production bugs are not always in this set
311
+
312
+ We do not claim 13/13 reflects every real-world repo — it's a reproducible upper bound on a fixture that exercises the categories we explicitly target.
313
+
277
314
  ## License
278
315
 
279
316
  MIT
@@ -9,6 +9,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
9
9
  import * as path from 'node:path';
10
10
  import { GuardrailError } from "../core/errors.js";
11
11
  import { checkApiVersionCompatibility } from "./base.js";
12
+ import { resolveSiblingModule } from "../cli/_pkg-root.js";
12
13
  const BUILTIN_PATHS = {
13
14
  'review-engine': {
14
15
  codex: './review-engine/codex.ts',
@@ -47,7 +48,7 @@ export async function loadAdapter(options) {
47
48
  details: { point, ref, available: Object.keys(BUILTIN_PATHS[point] ?? {}) },
48
49
  });
49
50
  }
50
- modulePath = new URL(builtin, import.meta.url).pathname;
51
+ modulePath = resolveSiblingModule(builtin, import.meta.url);
51
52
  }
52
53
  let mod;
53
54
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/adapters/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/adapters/loader.ts"],"names":[],"mappings":"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"}
@@ -57,4 +57,26 @@ export function requirePackageRoot(callerImportMetaUrl) {
57
57
  }
58
58
  return root;
59
59
  }
60
+ /**
61
+ * Resolve a sibling-module path for dynamic `import()` that works under both
62
+ * source (caller is `.ts`) and compiled (caller is `.js`) layouts.
63
+ *
64
+ * Background: `import('./rules/foo.js')` and `import('./review-engine/auto.js')`
65
+ * are dynamic-import string literals — TS's `rewriteRelativeImportExtensions`
66
+ * only rewrites STATIC imports, leaving these string refs as `.ts` post-compile.
67
+ * Under compiled output, the actual module is `.js`, so the import fails with
68
+ * `Failed to import adapter from .../auto.ts`.
69
+ *
70
+ * This helper detects whether the caller is itself compiled (`.js`/`.mjs`) and
71
+ * rewrites the ref's extension to match.
72
+ *
73
+ * @param ref Sibling-module ref ending in `.ts` (e.g. `./review-engine/auto.ts`).
74
+ * @param callerImportMetaUrl Caller's `import.meta.url`.
75
+ * @returns Absolute filesystem path suitable for `import()`.
76
+ */
77
+ export function resolveSiblingModule(ref, callerImportMetaUrl) {
78
+ const callerIsCompiled = callerImportMetaUrl.endsWith('.js') || callerImportMetaUrl.endsWith('.mjs');
79
+ const adjustedRef = callerIsCompiled ? ref.replace(/\.ts$/, '.js') : ref;
80
+ return fileURLToPath(new URL(adjustedRef, callerImportMetaUrl));
81
+ }
60
82
  //# sourceMappingURL=_pkg-root.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_pkg-root.js","sourceRoot":"","sources":["../../../src/cli/_pkg-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,YAAY,GAAG,6BAA6B,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,mBAA2B,EAAE,QAAQ,GAAG,EAAE;IACxE,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACjD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAsB,CAAC;gBAChF,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;oBAAE,OAAO,GAAG,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,mBAA2B;IAC5D,MAAM,IAAI,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,yDAAyD,aAAa,CAAC,mBAAmB,CAAC,IAAI;YAC/F,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"_pkg-root.js","sourceRoot":"","sources":["../../../src/cli/_pkg-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,YAAY,GAAG,6BAA6B,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,mBAA2B,EAAE,QAAQ,GAAG,EAAE;IACxE,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACjD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAsB,CAAC;gBAChF,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;oBAAE,OAAO,GAAG,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,mBAA2B;IAC5D,MAAM,IAAI,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,yDAAyD,aAAa,CAAC,mBAAmB,CAAC,IAAI;YAC/F,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,mBAA2B;IAC3E,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrG,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzE,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -1,29 +1,43 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { resolveSiblingModule } from "../../cli/_pkg-root.js";
10
+ // Dynamic-import string literals that end in `.ts` are NOT rewritten by tsc's
11
+ // `rewriteRelativeImportExtensions`. resolveSiblingModule swaps `.ts` → `.js`
12
+ // when the caller is itself compiled, so these imports resolve correctly under
13
+ // both source (`tsx`) and compiled (`node dist/...`) layouts.
14
+ const importRule = (ref, exportName) => import(__rewriteRelativeImportExtension(resolveSiblingModule(ref, import.meta.url))).then((m) => m[exportName]);
1
15
  // Built-in cross-stack rules
2
16
  const BUILTIN = {
3
- 'hardcoded-secrets': () => import("./rules/hardcoded-secrets.js").then(m => m.hardcodedSecretsRule),
4
- 'npm-audit': () => import("./rules/npm-audit.js").then(m => m.npmAuditRule),
5
- 'package-lock-sync': () => import("./rules/package-lock-sync.js").then(m => m.packageLockSyncRule),
6
- 'console-log': () => import("./rules/console-log.js").then(m => m.consoleLogRule),
7
- 'todo-fixme': () => import("./rules/todo-fixme.js").then(m => m.todoFixmeRule),
8
- 'large-file': () => import("./rules/large-file.js").then(m => m.largeFileRule),
9
- 'missing-tests': () => import("./rules/missing-tests.js").then(m => m.missingTestsRule),
17
+ 'hardcoded-secrets': () => importRule('./rules/hardcoded-secrets.ts', 'hardcodedSecretsRule'),
18
+ 'npm-audit': () => importRule('./rules/npm-audit.ts', 'npmAuditRule'),
19
+ 'package-lock-sync': () => importRule('./rules/package-lock-sync.ts', 'packageLockSyncRule'),
20
+ 'console-log': () => importRule('./rules/console-log.ts', 'consoleLogRule'),
21
+ 'todo-fixme': () => importRule('./rules/todo-fixme.ts', 'todoFixmeRule'),
22
+ 'large-file': () => importRule('./rules/large-file.ts', 'largeFileRule'),
23
+ 'missing-tests': () => importRule('./rules/missing-tests.ts', 'missingTestsRule'),
10
24
  // Security rules
11
- 'sql-injection': () => import("./rules/sql-injection.js").then(m => m.sqlInjectionRule),
12
- 'missing-auth': () => import("./rules/missing-auth.js").then(m => m.missingAuthRule),
13
- 'ssrf': () => import("./rules/ssrf.js").then(m => m.ssrfRule),
14
- 'insecure-redirect': () => import("./rules/insecure-redirect.js").then(m => m.insecureRedirectRule),
25
+ 'sql-injection': () => importRule('./rules/sql-injection.ts', 'sqlInjectionRule'),
26
+ 'missing-auth': () => importRule('./rules/missing-auth.ts', 'missingAuthRule'),
27
+ 'ssrf': () => importRule('./rules/ssrf.ts', 'ssrfRule'),
28
+ 'insecure-redirect': () => importRule('./rules/insecure-redirect.ts', 'insecureRedirectRule'),
15
29
  // Brand rules
16
- 'brand-tokens': () => import("./rules/brand-tokens.js").then(m => m.brandTokensRule),
30
+ 'brand-tokens': () => importRule('./rules/brand-tokens.ts', 'brandTokensRule'),
17
31
  // Schema alignment
18
- 'schema-alignment': () => import("./rules/schema-alignment.js").then(m => m.schemaAlignmentRule),
32
+ 'schema-alignment': () => importRule('./rules/schema-alignment.ts', 'schemaAlignmentRule'),
19
33
  };
20
34
  // Preset-specific rules registered by name
21
35
  const PRESET = {
22
- 'supabase-rls-bypass': () => import("../../../presets/nextjs-supabase/rules/supabase-rls-bypass.js").then(m => m.supabaseRlsBypassRule),
23
- 'go-sql-injection': () => import("../../../presets/go/rules/go-sql-injection.js").then(m => m.goSqlInjectionRule),
24
- 'fastapi-missing-auth': () => import("../../../presets/python-fastapi/rules/fastapi-missing-auth.js").then(m => m.fastapiMissingAuthRule),
25
- 't3-server-only': () => import("../../../presets/t3/rules/t3-server-only.js").then(m => m.t3ServerOnlyRule),
26
- 'rails-sql-injection': () => import("../../../presets/rails-postgres/rules/rails-sql-injection.js").then(m => m.railsSqlInjectionRule),
36
+ 'supabase-rls-bypass': () => importRule('../../../presets/nextjs-supabase/rules/supabase-rls-bypass.ts', 'supabaseRlsBypassRule'),
37
+ 'go-sql-injection': () => importRule('../../../presets/go/rules/go-sql-injection.ts', 'goSqlInjectionRule'),
38
+ 'fastapi-missing-auth': () => importRule('../../../presets/python-fastapi/rules/fastapi-missing-auth.ts', 'fastapiMissingAuthRule'),
39
+ 't3-server-only': () => importRule('../../../presets/t3/rules/t3-server-only.ts', 't3ServerOnlyRule'),
40
+ 'rails-sql-injection': () => importRule('../../../presets/rails-postgres/rules/rails-sql-injection.ts', 'railsSqlInjectionRule'),
27
41
  };
28
42
  const ALL = { ...BUILTIN, ...PRESET };
29
43
  export async function loadRulesFromConfig(refs) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/core/static-rules/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/core/static-rules/registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delegance/claude-autopilot",
3
- "version": "5.0.0-alpha.4",
3
+ "version": "5.0.0",
4
4
  "type": "module",
5
5
  "description": "Autonomous development pipeline for Claude Code: brainstorm → spec → plan → implement → migrate → validate → PR → review → merge. Multi-model, local-first, every phase a skill you can intervene in.",
6
6
  "keywords": [
@@ -1,6 +1,7 @@
1
1
  import * as path from 'node:path';
2
2
  import { GuardrailError } from '../core/errors.ts';
3
3
  import { checkApiVersionCompatibility, type AdapterBase } from './base.ts';
4
+ import { resolveSiblingModule } from '../cli/_pkg-root.ts';
4
5
 
5
6
  export type IntegrationPoint = 'review-engine' | 'vcs-host' | 'migration-runner' | 'review-bot-parser';
6
7
 
@@ -56,7 +57,7 @@ export async function loadAdapter<T extends AdapterBase>(options: LoadAdapterOpt
56
57
  details: { point, ref, available: Object.keys(BUILTIN_PATHS[point] ?? {}) },
57
58
  });
58
59
  }
59
- modulePath = new URL(builtin, import.meta.url).pathname;
60
+ modulePath = resolveSiblingModule(builtin, import.meta.url);
60
61
  }
61
62
 
62
63
  let mod: { default?: T } | T;
@@ -60,3 +60,26 @@ export function requirePackageRoot(callerImportMetaUrl: string): string {
60
60
  }
61
61
  return root;
62
62
  }
63
+
64
+ /**
65
+ * Resolve a sibling-module path for dynamic `import()` that works under both
66
+ * source (caller is `.ts`) and compiled (caller is `.js`) layouts.
67
+ *
68
+ * Background: `import('./rules/foo.ts')` and `import('./review-engine/auto.ts')`
69
+ * are dynamic-import string literals — TS's `rewriteRelativeImportExtensions`
70
+ * only rewrites STATIC imports, leaving these string refs as `.ts` post-compile.
71
+ * Under compiled output, the actual module is `.js`, so the import fails with
72
+ * `Failed to import adapter from .../auto.ts`.
73
+ *
74
+ * This helper detects whether the caller is itself compiled (`.js`/`.mjs`) and
75
+ * rewrites the ref's extension to match.
76
+ *
77
+ * @param ref Sibling-module ref ending in `.ts` (e.g. `./review-engine/auto.ts`).
78
+ * @param callerImportMetaUrl Caller's `import.meta.url`.
79
+ * @returns Absolute filesystem path suitable for `import()`.
80
+ */
81
+ export function resolveSiblingModule(ref: string, callerImportMetaUrl: string): string {
82
+ const callerIsCompiled = callerImportMetaUrl.endsWith('.js') || callerImportMetaUrl.endsWith('.mjs');
83
+ const adjustedRef = callerIsCompiled ? ref.replace(/\.ts$/, '.js') : ref;
84
+ return fileURLToPath(new URL(adjustedRef, callerImportMetaUrl));
85
+ }
@@ -1,33 +1,41 @@
1
1
  import type { StaticRule } from '../phases/static-rules.ts';
2
2
  import type { StaticRuleReference } from '../config/types.ts';
3
+ import { resolveSiblingModule } from '../../cli/_pkg-root.ts';
4
+
5
+ // Dynamic-import string literals that end in `.ts` are NOT rewritten by tsc's
6
+ // `rewriteRelativeImportExtensions`. resolveSiblingModule swaps `.ts` → `.js`
7
+ // when the caller is itself compiled, so these imports resolve correctly under
8
+ // both source (`tsx`) and compiled (`node dist/...`) layouts.
9
+ const importRule = <T>(ref: string, exportName: string): Promise<StaticRule> =>
10
+ import(resolveSiblingModule(ref, import.meta.url)).then((m: Record<string, T>) => m[exportName] as unknown as StaticRule);
3
11
 
4
12
  // Built-in cross-stack rules
5
13
  const BUILTIN: Record<string, () => Promise<StaticRule>> = {
6
- 'hardcoded-secrets': () => import('./rules/hardcoded-secrets.ts').then(m => m.hardcodedSecretsRule),
7
- 'npm-audit': () => import('./rules/npm-audit.ts').then(m => m.npmAuditRule),
8
- 'package-lock-sync': () => import('./rules/package-lock-sync.ts').then(m => m.packageLockSyncRule),
9
- 'console-log': () => import('./rules/console-log.ts').then(m => m.consoleLogRule),
10
- 'todo-fixme': () => import('./rules/todo-fixme.ts').then(m => m.todoFixmeRule),
11
- 'large-file': () => import('./rules/large-file.ts').then(m => m.largeFileRule),
12
- 'missing-tests': () => import('./rules/missing-tests.ts').then(m => m.missingTestsRule),
14
+ 'hardcoded-secrets': () => importRule('./rules/hardcoded-secrets.ts', 'hardcodedSecretsRule'),
15
+ 'npm-audit': () => importRule('./rules/npm-audit.ts', 'npmAuditRule'),
16
+ 'package-lock-sync': () => importRule('./rules/package-lock-sync.ts', 'packageLockSyncRule'),
17
+ 'console-log': () => importRule('./rules/console-log.ts', 'consoleLogRule'),
18
+ 'todo-fixme': () => importRule('./rules/todo-fixme.ts', 'todoFixmeRule'),
19
+ 'large-file': () => importRule('./rules/large-file.ts', 'largeFileRule'),
20
+ 'missing-tests': () => importRule('./rules/missing-tests.ts', 'missingTestsRule'),
13
21
  // Security rules
14
- 'sql-injection': () => import('./rules/sql-injection.ts').then(m => m.sqlInjectionRule),
15
- 'missing-auth': () => import('./rules/missing-auth.ts').then(m => m.missingAuthRule),
16
- 'ssrf': () => import('./rules/ssrf.ts').then(m => m.ssrfRule),
17
- 'insecure-redirect': () => import('./rules/insecure-redirect.ts').then(m => m.insecureRedirectRule),
22
+ 'sql-injection': () => importRule('./rules/sql-injection.ts', 'sqlInjectionRule'),
23
+ 'missing-auth': () => importRule('./rules/missing-auth.ts', 'missingAuthRule'),
24
+ 'ssrf': () => importRule('./rules/ssrf.ts', 'ssrfRule'),
25
+ 'insecure-redirect': () => importRule('./rules/insecure-redirect.ts', 'insecureRedirectRule'),
18
26
  // Brand rules
19
- 'brand-tokens': () => import('./rules/brand-tokens.ts').then(m => m.brandTokensRule),
27
+ 'brand-tokens': () => importRule('./rules/brand-tokens.ts', 'brandTokensRule'),
20
28
  // Schema alignment
21
- 'schema-alignment': () => import('./rules/schema-alignment.ts').then(m => m.schemaAlignmentRule),
29
+ 'schema-alignment': () => importRule('./rules/schema-alignment.ts', 'schemaAlignmentRule'),
22
30
  };
23
31
 
24
32
  // Preset-specific rules registered by name
25
33
  const PRESET: Record<string, () => Promise<StaticRule>> = {
26
- 'supabase-rls-bypass': () => import('../../../presets/nextjs-supabase/rules/supabase-rls-bypass.ts').then(m => m.supabaseRlsBypassRule),
27
- 'go-sql-injection': () => import('../../../presets/go/rules/go-sql-injection.ts').then(m => m.goSqlInjectionRule),
28
- 'fastapi-missing-auth': () => import('../../../presets/python-fastapi/rules/fastapi-missing-auth.ts').then(m => m.fastapiMissingAuthRule),
29
- 't3-server-only': () => import('../../../presets/t3/rules/t3-server-only.ts').then(m => m.t3ServerOnlyRule),
30
- 'rails-sql-injection': () => import('../../../presets/rails-postgres/rules/rails-sql-injection.ts').then(m => m.railsSqlInjectionRule),
34
+ 'supabase-rls-bypass': () => importRule('../../../presets/nextjs-supabase/rules/supabase-rls-bypass.ts', 'supabaseRlsBypassRule'),
35
+ 'go-sql-injection': () => importRule('../../../presets/go/rules/go-sql-injection.ts', 'goSqlInjectionRule'),
36
+ 'fastapi-missing-auth': () => importRule('../../../presets/python-fastapi/rules/fastapi-missing-auth.ts', 'fastapiMissingAuthRule'),
37
+ 't3-server-only': () => importRule('../../../presets/t3/rules/t3-server-only.ts', 't3ServerOnlyRule'),
38
+ 'rails-sql-injection': () => importRule('../../../presets/rails-postgres/rules/rails-sql-injection.ts', 'railsSqlInjectionRule'),
31
39
  };
32
40
 
33
41
  const ALL = { ...BUILTIN, ...PRESET };