Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Format (Oxfmt)
run: bun run format:check

- name: Lint and assist (Biome)
- name: Lint (Oxlint)
run: bun run lint

- name: Anti-slop (Oxlint, baseline-aware)
Expand Down
65 changes: 0 additions & 65 deletions biome.jsonc

This file was deleted.

19 changes: 0 additions & 19 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions cli/__tests__/lint-policy.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { afterEach, describe, expect, it } from 'vitest';
import { testSpawnSync as spawnSync } from './_helpers.mts';

const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
const OXLINT = join(ROOT, 'node_modules', '.bin', 'oxlint');
const OXLINT_CONFIG = join(ROOT, 'oxc', 'oxlint.devkit-lint.json');
const roots: string[] = [];

function fixture(name: string, source: string) {
const root = mkdtempSync(join(tmpdir(), 'devkit-lint-policy-'));
roots.push(root);
const path = join(root, name);
writeFileSync(path, source);
return path;
}

afterEach(() => {
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true });
});

describe('Devkit lint ownership', () => {
it('makes the native Oxlint profile fail on a JS/TS correctness violation', () => {
const path = fixture('unused.mts', 'const unused = 1;\n');

const result = spawnSync(OXLINT, ['--config', OXLINT_CONFIG, '--disable-nested-config', path], {
encoding: 'utf8',
});

expect(result.status).toBe(1);
});

it('runs the policy without a Biome fallback command', () => {
const packageJson: { scripts?: Record<string, string> } = JSON.parse(
readFileSync(join(ROOT, 'package.json'), 'utf8'),
);

expect(packageJson.scripts?.lint).toBe('bun run lint:oxlint');
expect(packageJson.scripts?.['lint:biome']).toBeUndefined();
expect(packageJson.scripts?.['lint:regex']).toBeUndefined();
});
});
13 changes: 5 additions & 8 deletions cli/__tests__/self-host.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,15 @@ describe('buildSelfHostHook', () => {
expect(() => execFileSync('sh', ['-c', fragment ?? 'exit 1'], { cwd: root })).toThrow();
});

// The `--extra` above is only as hard as the script it names, and biome exits 0 when every
// diagnostic is warn-severity. A bare `biome check .` therefore PRINTS its findings into the gate
// log — indistinguishable from a real failure to the reader — and passes the commit anyway (a
// v0.50.0 ship shipped with six of them). `--error-on-warnings` is what makes the exit code match
// what the log shows. devkit's own root config turns `noConsole` (the one deliberately-advisory
// rule in biome/base.jsonc) off for the whole authored surface, so nothing advisory is caught here.
it('backs the lint extra with a biome invocation that exits non-zero on WARNINGS too', () => {
it('backs the lint extra with the native Oxlint policy only', () => {
const pkg: { scripts?: Record<string, string> } = JSON.parse(
readFileSync(join(ROOT, 'package.json'), 'utf8'),
);
expect(SELF_HOST_EXTRAS).toContainEqual({ label: 'lint', cmd: 'bun run lint' });
expect(pkg.scripts?.lint).toBe('biome check --formatter-enabled=false --error-on-warnings .');
expect(pkg.scripts?.lint).toBe('bun run lint:oxlint');
expect(pkg.scripts?.['lint:oxlint']).toContain('--deny-warnings');
expect(pkg.scripts?.['lint:biome']).toBeUndefined();
expect(pkg.scripts?.['lint:regex']).toBeUndefined();
});

it('preserves the advisory fallow-audit gate INSIDE the block (never blocks, survives re-run)', () => {
Expand Down
37 changes: 37 additions & 0 deletions dist/oxc/oxlint.devkit-lint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$schema": "../node_modules/oxlint/configuration_schema.json",
"plugins": ["eslint", "typescript", "oxc", "react"],
"categories": {
"correctness": "deny",
"perf": "deny",
"suspicious": "deny",
"pedantic": "allow",
"restriction": "allow",
"style": "allow",
"nursery": "allow"
},
"rules": {
"eslint/no-await-in-loop": "allow",
"eslint/no-console": "allow",
"eslint/no-extend-native": "allow",
"eslint/no-shadow": "allow",
"eslint/no-underscore-dangle": "allow",
"eslint/preserve-caught-error": "allow",
"oxc/no-map-spread": "allow",
"react/rules-of-hooks": "deny"
},
"overrides": [
{
"files": ["**/upstream-sync/scripts/sync.mjs"],
"rules": {
"eslint/no-unused-vars": "allow"
}
},
{
"files": ["**/comment-firewall/__tests__/detect.test.mts"],
"rules": {
"eslint/no-useless-concat": "allow"
}
}
]
}
10 changes: 5 additions & 5 deletions dist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"type": "module",
"license": "MIT",
"description": "Single source-of-truth devkit: shared Biome/TS configs + portable governance gate-engine + setup-wizard CLI. Consumed via `bun add git+ssh://git@github.com/norvalbv/devkit.git#<tag>`.",
"description": "Single source-of-truth devkit: shared lint/TS configs + portable governance gate-engine + setup-wizard CLI. Consumed via `bun add git+ssh://git@github.com/norvalbv/devkit.git#<tag>`.",
"exports": {
"./biome/base": "./dist/biome/base.jsonc",
"./biome/react": "./dist/biome/react.jsonc",
Expand Down Expand Up @@ -59,23 +59,23 @@
"test:run": "vitest run",
"test:e2e": "vitest run -c vitest.e2e.config.mjs",
"playground": "bun scripts/playground.mts",
"lint": "biome check --formatter-enabled=false --error-on-warnings .",
"lint": "bun run lint:oxlint",
"lint:oxlint": "oxlint --config oxc/oxlint.devkit-lint.json --disable-nested-config --deny-warnings cli gate-engine *.mjs skills",
"lint:anti-slop": "node cli/index.mts anti-slop check",
"lint:structure": "eslint cli gate-engine",
"benchmarks:check": "bun gate-engine/eval/cli.mts check",
"benchmarks:render": "bun gate-engine/eval/cli.mts render",
"benchmarks:typecheck": "tsc -p gate-engine/eval/tsconfig.json",
"comments:eval": "node gate-engine/comment-firewall/eval/run.mts",
"search-eval:check": "node gate-engine/search-tool/eval/eval.mts --fail",
"format": "oxfmt --write 'cli/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'gate-engine/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'tsconfig/**/*.{json,jsonc}' 'biome/**/*.{json,jsonc}' 'skills/**/*.mjs' .co-occurrence-allowlist.json .fallowrc.jsonc .oxfmtrc.json biome.jsonc eslint.config.mjs guard.config.example.json guard.config.json package.json search-code.config.json tsconfig.build.json tsconfig.json vitest.config.mjs vitest.e2e.config.mjs vitest.setup.mjs",
"format:check": "oxfmt --check 'cli/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'gate-engine/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'tsconfig/**/*.{json,jsonc}' 'biome/**/*.{json,jsonc}' 'skills/**/*.mjs' .co-occurrence-allowlist.json .fallowrc.jsonc .oxfmtrc.json biome.jsonc eslint.config.mjs guard.config.example.json guard.config.json package.json search-code.config.json tsconfig.build.json tsconfig.json vitest.config.mjs vitest.e2e.config.mjs vitest.setup.mjs",
"format": "oxfmt --write 'cli/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'gate-engine/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'tsconfig/**/*.{json,jsonc}' 'biome/**/*.{json,jsonc}' 'skills/**/*.mjs' .co-occurrence-allowlist.json .fallowrc.jsonc .oxfmtrc.json eslint.config.mjs guard.config.example.json guard.config.json package.json search-code.config.json tsconfig.build.json tsconfig.json vitest.config.mjs vitest.e2e.config.mjs vitest.setup.mjs",
"format:check": "oxfmt --check 'cli/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'gate-engine/**/*.{ts,tsx,js,jsx,mts,mjs,css,json,jsonc}' 'tsconfig/**/*.{json,jsonc}' 'biome/**/*.{json,jsonc}' 'skills/**/*.mjs' .co-occurrence-allowlist.json .fallowrc.jsonc .oxfmtrc.json eslint.config.mjs guard.config.example.json guard.config.json package.json search-code.config.json tsconfig.build.json tsconfig.json vitest.config.mjs vitest.e2e.config.mjs vitest.setup.mjs",
"typecheck": "tsc -p tsconfig.json",
"prepare": "husky",
"guard:freeze": "node gate-engine/ratchets/folder-fanout.mjs freeze && node gate-engine/ratchets/size-disable.mjs freeze",
"build": "tsc -p tsconfig.build.json && node scripts/copy-dist-assets.mjs"
},
"devDependencies": {
"@biomejs/biome": "^2.5.6",
"@types/node": "^25.9.3",
"@vitest/coverage-v8": "^4.1.10",
"husky": "^9.1.7",
Expand Down
Loading
Loading