Skip to content

chore(os): ESLint flat config with slice-boundary rule and lint-staged pre-commit - #94

Merged
xcjs merged 2 commits into
mainfrom
chore/lint-precommit
Oct 5, 2026
Merged

xcjs merged 2 commits into
mainfrom
chore/lint-precommit

Conversation

@xcjs

@xcjs xcjs commented Oct 3, 2026

Copy link
Copy Markdown
Owner

Summary

Implements issue #82: ESLint flat config with a slice-boundary rule, lint-staged in pre-commit, and an ESLint job in CI. Completes the deferred "Future" gates from ADR 0002 (type-aware ESLint + enforcement in CI and pre-commit).

  • eslint.config.mjs (new): @eslint/js + typescript-eslint (projectService, type-aware where possible) + eslint-plugin-vue flat/recommended. A no-restricted-imports slice-boundary rule blocks cross-slice imports per ADR 0001, with exemptions for the composition root (app/app.vue), the shared kernel (app/features/shared/**), and server/ boundary usage.
  • package.json: lint / lint:fix scripts; lint-staged config (eslint --fix on JS/TS/Vue, markdownlint on MD).
  • .husky/pre-commit: now npm run lint:md + npx lint-staged.
  • .github/workflows/ci.yml: new eslint job alongside markdownlint/typecheck/build.

Deviation from the issue plan, declared per protocol: vue-tsc is NOT wired into pre-commit on staged files. nuxt typecheck requires the full Nuxt context and takes minutes locally, which would block every commit; CI already gates it (typecheck job), and pre-commit now blocks on ESLint + markdownlint. ## Done when only requires "CI runs lint and typecheck green", which this satisfies.

Scope expansion, declared: issue ## Files declared package.json,.husky/**; this PR also touches .github/workflows/ci.yml, new eslint.config.mjs, and mechanical lint-compliance fixes across app/features/** + app/app.vue (vue/max-attributes-per-line auto-fixes, defineOptions({ name: "OsTaskbar" }), one dead prefix removed from app/features/shared/vfs.ts, one unused error destructure removed from ChatWindow.vue). No logic changes; npm run build and npm run typecheck exit 0.

Known follow-up (not blocking): 13 @typescript-eslint/no-explicit-any warnings remain at the runtime/ai boundary, downgraded to warn with intent to tighten in the runtime-engine lane.

Closes #82.

@xcjs xcjs self-assigned this Oct 3, 2026
@xcjs
xcjs requested a review from Sullux October 3, 2026 01:02
@xcjs
xcjs force-pushed the chore/lint-precommit branch from 5939866 to 2e2fbc7 Compare October 3, 2026 01:59
@xcjs

xcjs commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

Rebased onto current main (bb2d1ab + 2e2fbc7): absorbs #91's test:e2e script, the e2e lint:md excludes, and Playwright devDeps into package.json/package-lock.json; also lints playwright.config.ts via allowDefaultProject in eslint.config.mjs. lint 0 errors/13 warnings, typecheck exit 0 locally. Re-review requested.

@xcjs

xcjs commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

Friendly ping @Sullux - #94 (ESLint flat config + lint-staged pre-commit, issue #82) has been waiting on a review since 01:59Z. It was rebased onto current main (absorbs #91's e2e script + Playwright devDeps + lint:md excludes) and lints playwright.config.ts via allowDefaultProject. CI 4/4 green. Whenever you have a moment, it unblocks the 0.4 step of Phase 0.

@xcjs

xcjs commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

Rebased onto main (688046a, post-#103). Conflicts in app.vue/Taskbar.vue resolved in favor of main's mobile-shell markup (#100); ESLint config unchanged (allowDefaultProject for playwright.config.ts intact).
pm run lint\ 1 error/17 warnings before npm re-install; after
pm install\ 0 errors/17 warnings (the playwright.config.ts projectService error was transient/stale on my machine — re-running resolved it). typecheck 0. @Sullux re-review requested.

@m-vawter m-vawter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified merged into current main in a clean container. Lint: 0 errors and 17 warnings. Typecheck passes, and the e2e suite passes 6/6. The hook works end to end:

  • husky installs;
  • a staged cross-slice import (~/features/os/... from the chat slice) blocks the commit;
  • a fixable .vue file is reformatted by eslint --fix, and the fixed version is what gets committed;
  • each commit takes about 3 seconds.

Keeping vue-tsc in CI matches ADR 0002, which defers it from pre-commit. Approving. Follow-ups, none blocking:

  1. Relative cross-slice imports pass the rule. import { useOsStore } from '../../os/stores/os' in app/features/chat/... lints clean, in .ts and .vue alike. no-restricted-imports matches the specifier as written, not the resolved path, so the "plain relative forms" in the config comment aren't covered. Nothing on main does this today, so it's latent. A path-resolving rule would close it, such as import-x/no-restricted-paths with a zone per slice.

  2. The kernel path is app/features/shared/, not app/shared/. The exemption block and the error message both name app/shared/, which doesn't exist. So the message sends agents to a folder that isn't there.

  3. Records for Phase 0's "ADRs match the code":

    • ADR 0002's as-built notes (lines 96–97 and 113–114) say the hook runs markdown linting only. After this it also runs ESLint on staged files.
    • NEXT.md 0.4 still says pre-commit runs vue-tsc.

    Both are small edits, and I can draft them if Brandon wants.

  4. Nits:

    • the hook lints Markdown twice (lint:md on all files, then lint-staged's *.md);
    • .husky/pre-commit has no trailing newline.

On review order: Charles's two files only get lint fixes, an SVG reflow and an unused variable, so I don't think this needs to wait on his lane review. Your call. Once it's in, could you add ESLint to main's required checks? It's the fifth CI job, and adding it keeps the gate complete.

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.

0.4 ESLint flat config and vue-tsc in pre-commit

2 participants