Status: ✅ Resolved on main — fixed by PR #157, commit 7073d25. Verified against a freshly-fetched origin/main before editing this issue.
Description
engine-bridge/package.json defined "lint": "eslint src --ext .ts", but eslint was not listed in devDependencies and no ESLint config file existed anywhere in engine-bridge/. npm run lint could not succeed as shipped.
Affected Component
engine-bridge/package.json, engine-bridge/.eslintrc.cjs (missing)
Original Behavior (Bug)
npm run lint failed to resolve the eslint binary since it was never installed, and even if manually installed, there was no config telling it how to parse TypeScript.
Expected Behavior
npm run lint runs ESLint against src/**/*.ts using a real TypeScript-aware config and exits 0 on clean code / non-zero on violations.
Root Cause
The lint script was added to package.json without adding the corresponding tooling — likely copy-pasted from dashboard/package.json, which has both eslint and a working .eslintrc.cjs.
Resolution
Two changes landed together:
- Added
eslint@^8.57.0, @typescript-eslint/parser@^8.61.1, @typescript-eslint/eslint-plugin@^8.61.1 to devDependencies.
- Added
engine-bridge/.eslintrc.cjs:
module.exports = {
root: true,
env: { node: true, es2022: true },
parser: '@typescript-eslint/parser',
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
plugins: ['@typescript-eslint'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
rules: {
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
'no-constant-condition': ['error', { checkLoops: false }],
'prefer-const': ['error', { destructuring: 'all' }],
},
ignorePatterns: ['dist', 'node_modules', 'coverage'],
};
The two rule overrides at the bottom aren't stylistic taste — they fix real false positives found while first running lint against src/: no-constant-condition was flagging intentional while (true) { ...; break; } polling loops in event-propagator.ts and tx-aggregator.ts (the default checkLoops: true doesn't distinguish a bounded poll-with-break from a genuine infinite loop), and prefer-const's default destructuring: 'any' was flagging path in let { queue, path } = ... even though queue in the same destructure legitimately gets reassigned later — destructuring: 'all' only requires const when every destructured binding is const-eligible.
Verification
$ git show origin/main:engine-bridge/package.json | grep -i eslint
"@typescript-eslint/eslint-plugin": "^8.61.1",
"@typescript-eslint/parser": "^8.61.1",
"eslint": "^8.57.0",
$ git cat-file -e origin/main:engine-bridge/.eslintrc.cjs && echo EXISTS
EXISTS
$ npm run lint
✖ 32 problems (0 errors, 32 warnings)
Definition of Done
Description
engine-bridge/package.jsondefined"lint": "eslint src --ext .ts", buteslintwas not listed indevDependenciesand no ESLint config file existed anywhere inengine-bridge/.npm run lintcould not succeed as shipped.Affected Component
engine-bridge/package.json,engine-bridge/.eslintrc.cjs(missing)Original Behavior (Bug)
npm run lintfailed to resolve theeslintbinary since it was never installed, and even if manually installed, there was no config telling it how to parse TypeScript.Expected Behavior
npm run lintruns ESLint againstsrc/**/*.tsusing a real TypeScript-aware config and exits 0 on clean code / non-zero on violations.Root Cause
The
lintscript was added topackage.jsonwithout adding the corresponding tooling — likely copy-pasted fromdashboard/package.json, which has botheslintand a working.eslintrc.cjs.Resolution
Two changes landed together:
eslint@^8.57.0,@typescript-eslint/parser@^8.61.1,@typescript-eslint/eslint-plugin@^8.61.1todevDependencies.engine-bridge/.eslintrc.cjs:src/:no-constant-conditionwas flagging intentionalwhile (true) { ...; break; }polling loops inevent-propagator.tsandtx-aggregator.ts(the defaultcheckLoops: truedoesn't distinguish a bounded poll-with-break from a genuine infinite loop), andprefer-const's defaultdestructuring: 'any'was flaggingpathinlet { queue, path } = ...even thoughqueuein the same destructure legitimately gets reassigned later —destructuring: 'all'only requiresconstwhen every destructured binding is const-eligible.Verification
npm run lintruns and exits 0 with 0 errors on currentsrc/(32 pre-existingno-explicit-any/unused-var warnings remain by design — style, not correctness — since@typescript-eslint/no-explicit-anyis intentionallywarnnoterror).dashboard's conventions (same parser, same plugin, same rule shape).Definition of Done
main(PR Fix merge-corrupted engine-core, jest/eslint setup, repo cruft #157,7073d25).npm run lintforengine-bridgeautomatically — tracked separately in [BUG] CI never runs engine-bridge or dashboard test/lint/build #158.