Skip to content

chore(tooling): wave 1 — mypy + eslint + prettier + CI + pre-commit#48

Merged
ty13r merged 3 commits intomainfrom
refactor/wave-1-tooling-and-ci
Apr 19, 2026
Merged

chore(tooling): wave 1 — mypy + eslint + prettier + CI + pre-commit#48
ty13r merged 3 commits intomainfrom
refactor/wave-1-tooling-and-ci

Conversation

@ty13r
Copy link
Copy Markdown
Owner

@ty13r ty13r commented Apr 19, 2026

Summary

Wave 1 of the clean-code overhaul (see docs/clean-code.md). Adds the safety net — every subsequent refactor wave runs behind green CI.

No code-behavior changes. Mechanical lint fixes + config. This PR makes main green on the new gates so Wave 2+ can land incremental refactors without flying blind.

What's new

  • Python: mypy baseline (permissive today, per-module strict opt-in as files are refactored), expanded ruff rules (LOG, RET, PTH — BLE + TRY deferred to Wave 2 with the bare-except cleanup).
  • Frontend: ESLint 9 flat config + typescript-eslint strict, Prettier 3, @/ path aliases in tsconfig.json + vite.config.ts.
  • Gates: .pre-commit-config.yaml running ruff + mypy + prettier + eslint. .github/workflows/ci.yml running pytest + ruff + mypy + npm run lint + format:check + build + vitest.

Lint fixes bundled in

45 pre-existing ruff errors are addressed to establish a green baseline:

  • Module-level import placements (E402) — moved loggers below imports where practical, # noqa with reason where intentional (e.g. seeds/__init__.py avoiding circular imports).
  • B904 raise-from in uploads.py, B008 FastAPI File() default noqa'd, B007 unused loop var fixed.
  • SIM105 try/except/passcontextlib.suppress, SIM108 if/else → ternary.
  • RET505 unnecessary else after return, RET503 missing explicit return at end of LLM retry loop.
  • F841 dead variable removed.

Flaky test fix

tests/test_config.py patched SKILLFORGE_COMPETITOR_BACKEND=managed and reloaded skillforge.config. The finally block reloaded before monkeypatch teardown, leaving the module stuck in managed mode for downstream tests — which then tried to hit the real Anthropic API and failed with a 401. Fixed via a _restore_cfg() helper that explicitly delenvs before the final reload.

Before: 403 passed, 2 skipped, 1 failed (flaky).
After: 403 passed, 2 skipped, 0 failed (stable).

Commit layout

  1. chore(tooling): wave 1 — ... — configs + substantive lint fixes.
  2. style: apply prettier to frontend — mechanical reformat of 56 files. Diff is pure whitespace — skim-only.

Test plan

All verified locally. CI will run them again on push:

  • uv run ruff check skillforge — clean
  • uv run mypy skillforge — 51 files, 0 errors (17 excluded until later waves)
  • uv run pytest tests/ — 403 passed, 2 skipped
  • cd frontend && npm run lint — clean
  • cd frontend && npm run format:check — clean
  • cd frontend && npm run build — passes
  • cd frontend && npm run test — 35/35 pass

What's next

Wave 2 lands the cross-cutting hygiene: skillforge/errors.py, replace 75 except Exception with typed + logging.exception(...), kill print(...) diagnostics, extract _json.py helper, eliminate mutable module globals via run_registry.py. All safe behind the test net this PR establishes.

🤖 Generated with Claude Code

Matt (via Claude Code) and others added 3 commits April 19, 2026 11:35
Adds the safety net before refactor waves touch code:

Python:
- mypy baseline (permissive; strict on models.* + config; hotspots opted
  out per-module until Wave 3 refactors land)
- expanded ruff rules: LOG, RET, PTH (BLE + TRY deferred to Wave 2
  alongside the bare-except cleanup)
- fixes 45 pre-existing ruff errors (module-top imports, SIM105/108,
  B904 raise-from, F841 dead vars) for a green baseline

Frontend:
- ESLint 9 flat config + @eslint/js + typescript-eslint strict preset
- Prettier 3 config + ignore
- @/ path aliases in tsconfig + vite
- package.json scripts: lint, lint:fix, format, format:check, typecheck

Quality gates:
- pre-commit hooks: ruff, mypy, prettier, eslint
- GitHub Actions CI: pytest + ruff + mypy + npm run lint + format:check
  + build + vitest on pushes and PRs to main
- fixes a flaky env-leak in tests/test_config.py that left cfg in
  "managed" backend state across the suite, causing downstream tests to
  attempt real Anthropic API calls with an invalid key

See docs/clean-code.md for the standard these tools enforce.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mechanical reformat of 56 files under frontend/ — double quotes, 100ch
width, trailing commas, consistent arrow-param parens. Zero behavior
changes. Establishes the format baseline that CI now enforces via
\`npm run format:check\`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The taxonomy tests assumed the FastAPI lifespan had run and populated
the DB with seed families (terraform-module-full et al.). Locally this
"worked" because the dev DB persisted between uvicorn runs. In CI —
fresh filesystem, no prior boot — the tables didn't exist and every
query raised OperationalError: no such table: taxonomy_nodes.

Root cause: TestClient(app) only intercepts HTTP; it does NOT trigger
the lifespan unless used as a context manager. The rest of the suite
gets away with this because those tests build their own state through
endpoints; taxonomy tests specifically need the bootstrap.

Fix: wrap the TestClient in "with ... as c:" inside the fixture so the
lifespan runs, and point the bootstrap at a per-test temp DB so the
dev DB stays clean and tests stay independent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ty13r ty13r merged commit 0eddaf6 into main Apr 19, 2026
2 checks passed
@ty13r ty13r deleted the refactor/wave-1-tooling-and-ci branch April 19, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant