Skip to content
Open
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
17 changes: 17 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,20 @@ points at a `seed.ts` that does not exist. Follow the code; don't propagate the
Done = code + tests + contracts/migrations updated together · `npx tsc --noEmit` and `npx vitest run` green
with output shown (or the exact blocker/UNKNOWN stated) · diff reviewed for scope creep · no known
unreported regression · Unknowns recorded, never invented.

<!-- BEGIN L9 FORMATTER OWNERSHIP (generated — do not edit) -->

## Formatter ownership

Workspace class: `eslint_owned` — Workspaces where ESLint/Prettier config in the repo is authoritative for JS/TS. Python is still Ruff-owned.

Exactly one formatter owns each language. Do not reformat a file with a tool other than its owner, and do not add config for a competing formatter: the result is a diff that churns on every save.

| Languages | Owner | Note |
|---|---|---|
| `javascript`, `javascriptreact`, `typescript`, `typescriptreact`, `json`, `jsonc` | eslint (this repo's own config) | do not add a competing formatter config |
| `python` | **ruff** | bound by the governed IDE profile |

Generated from `environment/ide/policy.json` in the governance clone by `ops/scripts/adapters/agentdocs.sh`. Edit the policy, not this block.

<!-- END L9 FORMATTER OWNERSHIP -->
38 changes: 38 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @ts-check
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

// ESLint v9 flat config. This repo is ESM (`"type": "module"`) and TypeScript-only:
// src/ is the shipped surface, tests/ and scripts/ are dev-time TS. The `lint` script
// targets src/ only; the tests/scripts blocks below apply when a wider path is passed.
//
// Not type-aware (`recommended`, not `recommendedTypeChecked`): type-aware linting
// needs a resolved tsconfig program per file, and tsconfig.json excludes tests/, so
// the type-checked preset would error on every test file it was asked to lint.
export default tseslint.config(
{
ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'drizzle/**'],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['src/**/*.ts'],
rules: {
// Warn, not error, during the initial rollout: this config is being added to a
// codebase that has never been linted, so pre-existing findings become visible
// debt rather than a wall of failures on the first run. As of this config there
// are 58 `any` warnings and 15 unused-binding warnings, all pre-existing. Raise
// both to 'error' once that backlog is cleared, so new violations block.
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
},
},
{
// Tests and one-off scripts legitimately reach for `any` and console output.
files: ['tests/**/*.ts', 'scripts/**/*.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
},
},
);
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"name": "l9-seo-bot",
"version": "2.0.0",
Expand Down Expand Up @@ -43,12 +43,14 @@
"nodemailer": "^6.9.0"
},
"devDependencies": {
"@eslint/js": "^9.39.5",
"@types/node": "^22.0.0",
"@types/nodemailer": "^6.4.0",
"@types/pg": "^8.11.0",
"eslint": "^9.0.0",
"tsx": "^4.19.0",
"typescript": "^5.6.0",
"typescript-eslint": "^8.64.0",
"vitest": "^2.1.0",
"drizzle-kit": "^0.28.1"
},
Expand Down
Loading