hermes-agent/ui-tui-opentui-v2/eslint.config.mjs
alt-glitch bc79644f16 opentui(ts): no-non-null-assertion + noUnusedLocals + noImplicitReturns
Promote strictness in ui-tui-opentui-v2:
- eslint: @typescript-eslint/no-non-null-assertion: error (with a test
  override block keeping `!` in *.test.ts/tsx fixtures), and promote
  unused-imports/no-unused-vars warn → error.
- tsconfig: add noUnusedLocals + noImplicitReturns.

Remove all 24 production `!` non-null assertions by replacing each with
a real guard / default / early-return, preserving rendered behavior:
- gateway/client.ts: read the pending entry once and guard (vs has()+get()!).
- logic/theme.ts: guard the parseHex regex match; `?? 0` on the always-
  in-bounds XTERM_6_LEVELS lookups; restructure backgroundLuminance to
  branch into a typed tuple and use charAt() for the 3-digit hex expand.
- view/homeHint.tsx: use Solid's <Show>{value => …} callback form to
  narrow info().model / info().cwd instead of `!`.
- view/reasoningPart.tsx: guard the regex match before slicing m[0].
- view/statusBar.tsx: read model/cwd/pct into locals + guard; `?? 0` on
  the showBar()-guarded context-bar percentage.
- view/toolPart.tsx: guard the single-arg entry; `?? 0` on the
  duration-guarded fmtDuration.
2026-06-09 08:02:25 +00:00

74 lines
3.0 KiB
JavaScript

import js from "@eslint/js"
import tseslint from "typescript-eslint"
import unusedImports from "eslint-plugin-unused-imports"
export default tseslint.config(
{
ignores: ["node_modules/**", "dist/**", ".repos/**", "*.frame.txt", "*.ansi"],
},
js.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
{
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
plugins: {
"unused-imports": unusedImports,
},
rules: {
// Boundary code bans these; the Solid view follows TS-strict but is not Effect.
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports" }],
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-non-null-assertion": "error",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"error",
{ vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_" },
],
// --- Type-aware, high-value: ON as ERROR ---
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/await-thenable": "error",
// --- Phase 2: promote to error after Schema decode replaces the casts ---
// The cast/`unknown` family fires on the `as`/`unknown` boundary code that
// Phase 2 will replace with Schema decoding. Deferred to 'warn' so the gate
// stays green (eslint exits 0 on warnings) without masking the real signal.
"@typescript-eslint/no-unsafe-assignment": "warn",
"@typescript-eslint/no-unsafe-member-access": "warn",
"@typescript-eslint/no-unsafe-argument": "warn",
"@typescript-eslint/no-unsafe-return": "warn",
"@typescript-eslint/no-unsafe-call": "warn",
"@typescript-eslint/no-unnecessary-condition": "warn",
"@typescript-eslint/no-base-to-string": "warn",
"@typescript-eslint/restrict-template-expressions": "warn",
// `no-unnecessary-type-assertion` is the cast family (the one site is a
// `effect as Effect.Effect<…>` test cast); `require-await` fires only on
// async test-mock fns satisfying an async signature. Both are recommended
// -TypeChecked errors by default — demote to 'warn' to keep the gate green
// until Phase 2 (Schema decode) removes the casts.
"@typescript-eslint/no-unnecessary-type-assertion": "warn",
"@typescript-eslint/require-await": "warn",
},
},
{
// Tests keep their `!` non-null assertions (fixtures with known-present data).
files: ["**/*.test.ts", "**/*.test.tsx"],
rules: {
"@typescript-eslint/no-non-null-assertion": "off",
},
},
{
// The eslint flat config is JS-only; the typed parser project service does not
// cover it, so disable type-checking there to avoid parser errors.
files: ["eslint.config.mjs"],
...tseslint.configs.disableTypeChecked,
},
)