Skip to content

deps(deps-dev): bump eslint from 8.57.1 to 10.2.0#2

Merged
hunchom merged 1 commit intomainfrom
dependabot/npm_and_yarn/eslint-10.2.0
Apr 21, 2026
Merged

deps(deps-dev): bump eslint from 8.57.1 to 10.2.0#2
hunchom merged 1 commit intomainfrom
dependabot/npm_and_yarn/eslint-10.2.0

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github Apr 15, 2026

Bumps eslint from 8.57.1 to 10.2.0.

Release notes

Sourced from eslint's releases.

v10.2.0

Features

  • 586ec2f feat: Add meta.languages support to rules (#20571) (Copilot)
  • 14207de feat: add Temporal to no-obj-calls (#20675) (Pixel998)
  • bbb2c93 feat: add Temporal to ES2026 globals (#20672) (Pixel998)

Bug Fixes

  • 542cb3e fix: update first-party dependencies (#20714) (Francesco Trotta)

Documentation

  • a2af743 docs: add language to configuration objects (#20712) (Francesco Trotta)
  • 845f23f docs: Update README (GitHub Actions Bot)
  • 5fbcf59 docs: remove sourceType from ts playground link (#20477) (Tanuj Kanti)
  • 8702a47 docs: Update README (GitHub Actions Bot)
  • ddeaded docs: Update README (GitHub Actions Bot)
  • 2b44966 docs: add Major Releases section to Manage Releases (#20269) (Milos Djermanovic)
  • eab65c7 docs: update eslint versions in examples (#20664) (루밀LuMir)
  • 3e4a299 docs: update ESM Dependencies policies with note for own-usage packages (#20660) (Milos Djermanovic)

Chores

  • 8120e30 refactor: extract no unmodified loop condition (#20679) (kuldeep kumar)
  • 46e8469 chore: update dependency markdownlint-cli2 to ^0.22.0 (#20697) (renovate[bot])
  • 01ed3aa test: add unit tests for unicode utilities (#20622) (Manish chaudhary)
  • 811f493 ci: remove --legacy-peer-deps from types integration tests (#20667) (Milos Djermanovic)
  • 6b86fcf chore: update dependency npm-run-all2 to v8 (#20663) (renovate[bot])
  • 632c4f8 chore: add prettier update commit to .git-blame-ignore-revs (#20662) (루밀LuMir)
  • b0b0f21 chore: update dependency eslint-plugin-regexp to ^3.1.0 (#20659) (Milos Djermanovic)
  • 228a2dd chore: update dependency eslint-plugin-eslint-plugin to ^7.3.2 (#20661) (Milos Djermanovic)
  • 3ab4d7e test: Add tests for eslintrc-style keys (#20645) (kuldeep kumar)

v10.1.0

Features

  • ff4382b feat: apply fix for no-var in TSModuleBlock (#20638) (Tanuj Kanti)
  • 0916995 feat: Implement api support for bulk-suppressions (#20565) (Blake Sager)

Bug Fixes

  • 2b8824e fix: Prevent no-var autofix when a variable is used before declaration (#20464) (Amaresh S M)
  • e58b4bf fix: update eslint (#20597) (renovate[bot])

Documentation

  • b7b57fe docs: use correct JSDoc link in require-jsdoc.md (#20641) (mkemna-clb)
  • 58e4cfc docs: add deprecation notice partial (#20639) (Milos Djermanovic)
  • 7143dbf docs: update v9 migration guide for @eslint/js usage (#20540) (fnx)
  • 035fc4f docs: note that globalReturn applies only with sourceType: "script" (#20630) (Milos Djermanovic)
  • e972c88 docs: merge ESLint option descriptions into type definitions (#20608) (Francesco Trotta)
  • 7f10d84 docs: Update README (GitHub Actions Bot)
  • aeed007 docs: open playground link in new tab (#20602) (Tanuj Kanti)
  • a0d1a37 docs: Add AI Usage Policy (#20510) (Nicholas C. Zakas)

Chores

... (truncated)

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [eslint](https://github.com/eslint/eslint) from 8.57.1 to 10.2.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v8.57.1...v10.2.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 10.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github
Copy link
Copy Markdown
Contributor Author

dependabot Bot commented on behalf of github Apr 15, 2026

Labels

The following labels could not be found: dependencies. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@dependabot dependabot Bot requested a review from hunchom as a code owner April 15, 2026 02:04
@hunchom
Copy link
Copy Markdown
Owner

hunchom commented Apr 21, 2026

Holding this until either (a) package.json engines bumps to >=20.19.0 (matching eslint 10's requirement) or (b) repo migrates to flat config. eslint 10 drops Node 18 support while this repo currently advertises node >=18 — so merging now would break npm install for anyone on Node 18 even though CI's lint job runs on Node 20.

hunchom added a commit that referenced this pull request Apr 21, 2026
Required to merge eslint 10 in PR #2 -- eslint 10 dropped Node 18.
Node 18 reached end-of-life a year ago; every actively maintained LTS
line (20, 22, 24) gets tested in CI. Users on Node 18 can stay on
claude-code-ssh 3.2.x.
hunchom added a commit that referenced this pull request Apr 21, 2026
…s + cancellation, 32 new tests (#6)

* cleanup: remove 2259 lines of dead code and tighten lint

- Delete 4 pre-rewrite manager modules that nothing imports anymore:
  backup-manager, database-manager, health-monitor, session-manager
  (1859 LOC). Everything that used them has been reimplemented in
  src/tools/*-tools.js for a while.
- Strip the dead import block + formatDuration duplicate in index.js.
- Remove unused ssh-manager methods: execCommandStream, requestShell,
  putFiles (82 lines). No caller remained.
- Retire ssh_alert_setup. It wrote thresholds to a config file with no
  runner and no delivery -- a trap. Deleting is better than shipping a
  stub. Tool count goes 51 to 50, monitoring group 6 to 5.
- Expand lint surface from src/*.js to src/**/*.js (covers 11k LOC of
  handlers in src/tools/ that were never linted). Promote no-unused-vars
  to error so the next cleanup can't regress.
- Clean the seven no-unused-vars errors the expanded lint surfaced:
  defaultRender/renderMarkdown/healthStderr/localSize and friends.
- Use healthStderr snippet in the deploy health_check failure reason so
  the error is actually useful instead of just a numeric exit code.

npm test: 575 pass, 0 fail. npm run lint: clean.

* fix: correctness + secret-handling bugs from audit (C1-C4, H1-H8, M1-M10)

Critical:
  C1  ssh_sync -- rsync argv was checking serverConfig.keypath (lowercase)
      while config-loader stores keyPath (camelCase), so every key-auth
      server fell through to a miswired password branch. Resolve with both
      field names; keyPath is canonical. Broken for months.
  C2  ssh_backup_schedule -- refused to silently embed DB passwords in the
      crontab (plaintext persistence). Now rejects the call with a clear
      message pointing at ~/.my.cnf / ~/.pgpass / PGPASSFILE.
  C3  ssh_db_import mongo path -- mongorestore --archive= built via hand-
      rolled quote escape; paths with spaces/&/$/;/\\ broke the command.
      Switch to shQuote() like the mysql/postgres branches already do.
  C4  ssh_session_close "all" -- the schema advertised "all" but the
      handler did sessions.get("all") and returned already_closed. Now
      iterates every tracked session, closes each, returns a typed
      summary + per-session errors.

High:
  H1  ssh_diff cross-server -- SFTP channels opened via getSftpChannel()
      were never endSftp()'d. After ~5 cross-server diffs the connection
      hit OpenSSH's default MaxSessions=10 and refused new channels.
      Close both SFTPs on success and error paths.
  H2  ssh_docker pull -- 60s timeout is unusable for any real image.
      Added PULL_TIMEOUT_MS = 600_000 specifically for pulls.
  H3  Hardened fail() -- handles Error, string, object (with/without
      .message), and null. Avoids "[object Object]" rendering for
      unusual shapes. Opt-in stack trace via MCP_SSH_INCLUDE_STACK=1.
  H4  ssh_sync password auth -- previously put the password in argv
      (visible via `ps aux`). Now wraps in `sshpass -e rsync ...` and
      passes the password via SSHPASS env var.
  H6  ssh_tunnel_create type="dynamic" -- was a stub that destroyed
      every inbound connection (black-holed traffic). Remove from the
      allowed enum until a real SOCKS5 handler lands; explicit fail
      message so users aren't blindsided.
  H8  ssh_db_query mongo -- positional URI ordering was wrong;
      mongosh would interpret the database name as a host. Now builds
      a proper URI at runtime in SSH_MGR_DB_URI env var and uses
      `mongosh --nodb` + new Mongo() + getDB(). Credentials never
      touch argv on the target host.

Medium / Low:
  M1  writeMeta printf -- added `--` separator so JSON with a leading
      `%` (e.g. /backups/50%-used/) isn't consumed as a format directive.
  M2  ssh_health_check -- LANG=C LC_ALL=C pin so parsers don't choke
      on non-English output formats.
  M10 ssh_execute -- command capped at 512KB (well under ARG_MAX after
      shQuote expansion). "Argument list too long" becomes a clear zod
      error instead.
  L6  Server version now read from package.json instead of hardcoded.

Tests:
  - 5 regressions added: keyPath canonical + keypath alias + password
    not in argv; ssh_sync password uses sshpass -e + SSHPASS env;
    backup_schedule refuses DB passwords; session_close "all"; mongo
    query uses --nodb + env URI + getDB.

npm test: 580 pass, 0 fail (was 575 pre-commit). npm run lint: clean.

* mcp: tool annotations + titles + cancellation wiring

Annotations (MCP 2025-06-18):
  - Every one of the 50 registered tools now declares readOnlyHint /
    destructiveHint / idempotentHint / openWorldHint and a human `title`
    via src/tool-annotations.js. The table is the canonical truth -- a
    new test (test-tool-annotations.js, 9 cases) pins the invariants:
      * every registered tool has an annotations entry
      * no dangling annotations for unknown tools
      * readOnlyHint + destructiveHint are never both set
      * every obvious destructive/readOnly tool is marked correctly

  Claude Code and other MCP hosts use these for auto-approval decisions
  and palette rendering; prior to this, every tool looked identical to
  the client and users had to eyeball the description.

Cancellation (MCP $/cancelRequest):
  - registerToolConditional now forwards `extra.signal` from the SDK as
    `args.abortSignal` to every handler. streamExecCommand already accepts
    an AbortSignal in its options -- so exec / execute_sudo / execute_group
    / cat / tail handlers now actually honor client-side cancel (Esc in
    Claude Code). Before this, a cancelled tool call would still run to
    completion on the remote host and keep the SSH channel busy.

  Remaining tools (transfer, docker, backup, db, deploy, monitoring,
  port-test, systemctl, journalctl) still rely on their local timeouts;
  they pick up abortSignal next iteration.

npm test: 589 pass (+9 new annotations tests). npm run lint: clean.

* test: close zero-coverage gaps in gatekeeper + config-loader + drift-guard

Three new test files + one hardening extension:

  tests/test-tool-config-manager.js (17 tests)
    - Default config when file absent (all enabled).
    - Corrupt JSON falls back to defaults without crashing.
    - Invalid structure (missing fields / bad mode) falls back.
    - mode=all / mode=minimal / mode=custom semantics.
    - Individual tool overrides win over group settings.
    - disableGroup("core") is refused (core is load-bearing).
    - Unknown tool / unknown group rejected by helpers.
    - getEnabledTools + getDisabledTools arithmetic matches registry.
    - exportClaudeCodeConfig emits correct mcp__ssh-manager__ patterns.
    Zero coverage before; gate for all 50 tools.

  tests/test-config-loader.js (9 tests)
    - TOML loading with key_path/keypath/ssh_key aliases, default_dir,
      proxy_jump, case-insensitive server names.
    - .env loading via SSH_SERVER_NAME_* pattern.
    - Precedence: process.env > .env > TOML (documented in CLAUDE.md,
      was untested). Regression here silently changes which host
      Claude connects to.
    - configSource reflects actual load origin.
    - Corrupt TOML does not crash; falls through to .env.
    Zero coverage before.

  tests/test-index-registration.js (6 tests)
    - Every TOOL_GROUPS entry has a registerToolConditional() in index.js.
    - Every registerToolConditional() maps to a TOOL_GROUPS entry.
    - Tool count matches registry exactly.
    - No duplicates across groups, no empty groups.
    Catches silent drift when someone adds a tool to the registry but
    forgets to wire a handler (or vice versa).

  tests/test-structured-result.js (+7 tests)
    - fail() regression suite for the Wave 2 hardening: null, undefined,
      plain object w/o .message, circular objects, MCP_SSH_INCLUDE_STACK
      behavior. No more "[object Object]" errors reaching users.

npm test: 628 pass (was 589). validate.sh: clean.

* docs: sync README/CLAUDE.md/wiki with 50-tool reality, drop ssh_alert_setup refs

The tool count dropped from 51 to 50 when ssh_alert_setup was retired
(it was the dead trap that wrote alert thresholds to disk with no runner).
Also found the wiki pie chart had four drifted counts (sessions/monitoring/
gamechanger) that didn't match the registry.

  - README.md / CLAUDE.md: 51 -> 50 in two places each.
  - CLAUDE.md: drop ssh_alert_setup bullet from Health & Monitoring.
  - docs/TOOL_MANAGEMENT.md: drop ssh_alert_setup bullet.
  - wiki/Home.md: fix pie chart counts (sessions 4->6, monitoring 6->5,
    gamechanger 14->12) and 51->50 total.
  - wiki/Tool-reference.md: 51->50, drop ssh_alert_setup row.
  - wiki/Recipes.md: replace ssh_alert_setup example with ssh_hooks
    (which actually delivers alert-on-failure via user-defined actions).
  - src/tool-registry.js: 51->50 in docstring header.

npm test: 628 pass, 0 fail.

* fix: B1 mongodb schedule + reviewer nits (N1, N5), drop 3 more dead modules

Reviewer caught one blocker and two non-blockers in PR #6:

B1 (blocking, fixed):
  handleSshBackupSchedule was bricked for mongodb without a password. My
  defense-in-depth check rejected any non-empty envPrefix, but the mongo
  branch of buildBackupCommand unconditionally builds
  `MCP_BACKUP_URI=mongodb://localhost:27017/db` -- that's a connection
  string, not a secret carrier, when no password is supplied. Passwordless
  mongo schedules always hit the internal-error path.

  Fix: buildBackupCommand now also returns `envCarriesSecret: !!password`.
  handleSshBackupSchedule gates on that instead of prefix truthiness, and
  prepends the (non-secret) env prefix to the cron line so mongo jobs
  actually run. Regression test added: mongo schedule without password
  installs a cron line whose URI contains no `@` (no userinfo).

N1 (non-blocking, fixed):
  withAnnotations() spread-merged `{ ...schema.annotations, ...ann.annotations }`
  -- map wins. The docstring says "smart defaults", so the caller should
  win. Swapped the order + added a test that exercises override.

N5 (non-blocking, fixed):
  session_close "all" pushed a session into `closed[]` even when close()
  threw. Same session then also appeared in `errors[]`. Now errored sessions
  appear only in `errors[]`. Stale reference to session.server / commandCount
  is still read after sessions.delete(id) -- that's fine, we captured the
  reference before deleting.

Extra dead-code sweep (double-check pass caught these):
  - src/tunnel-manager.js (576 LOC) -- index.js's dead import block at
    lines 52-147 was the only consumer; deleting it earlier made this
    parallel SOCKS5 / forwardIn implementation unreachable. Includes the
    stale SOCKS5 half-implementation that was never exposed to users.
  - src/tool-exec-stream.js (87 LOC) + tests/test-tool-exec-stream.js
    (202 LOC) -- runStreamedExec was never adopted by any handler; only
    the test imported it. Either adopt or delete per architecture audit;
    adopting is Wave-5 material, deleting now.
  - src/config.js (~90 LOC) -- OUTPUT_LIMITS / truncateOutput / format-
    JSONResponse all referenced only within config.js itself.

Doc cleanup:
  - tests/test-sql-safety.js: stale comment pointing at the deleted
    database-manager.js replaced with an accurate one-liner.

npm test: 621 pass, 0 fail. npm run lint: clean. validate.sh: clean.

* feat: implement the three deleted documented features instead of removing them

The previous commit dropped three things that turned out to be documented
features, not pure cruft. Implementing each properly:

1. config.js + output-limits env vars (MCP_SSH_MAX_OUTPUT_LENGTH,
   MCP_SSH_MAX_TAIL_LINES, MCP_SSH_MAX_RSYNC_OUTPUT, MCP_SSH_COMPACT_JSON,
   MCP_SSH_DEBUG). Listed in .env.example but the module never actually
   wired them anywhere. Restored with real wiring:
   - output-formatter.truncateHeadTail + formatExecResult now default to
     OUTPUT_LIMITS.MAX_OUTPUT_LENGTH, so setting MCP_SSH_MAX_OUTPUT_LENGTH=5000
     actually changes the truncation cap.
   - logger.js accepts MCP_SSH_DEBUG as a shorthand for SSH_LOG_LEVEL=DEBUG.
   - Added truncateOutput() as a standalone helper for handlers that don't
     flow through the formatter.
   - Values parsed at import-time with min/max guards so a bad env doesn't
     misbehave silently -- bad values fall back to documented defaults.
   - 6 tests in test-config.js.

2. ssh_alert_setup as a real handler (src/tools/alerts-tools.js). The
   previous handler wrote thresholds to /etc/ssh-manager-alerts.json on the
   REMOTE host and had no runner -- a trap. New design:
   - Thresholds stored on the OPERATOR machine at
     ~/.ssh-manager/alerts/<server>.json, atomic tmp+rename write at 0600.
   - `set` / `get` / `check` actions.
   - `check` delegates to handleSshHealthCheck (one aggregated remote call,
     typed output) and compares cpu.usage_percent, memory.used_percent,
     and per-mount disk.used_percent against configured thresholds.
   - Returns {status, alert_count, alerts[], current_metrics}.
   - No background runner by design -- operators wire `check` into cron,
     CI, or an ssh_hooks event. Keeps the MCP server stateless.
   - Server name sanitized to [a-z0-9_-] before path join so a crafted
     name can't escape ALERTS_DIR (verified by test).
   - 12 tests in test-alerts-tools.js.

3. SOCKS5 dynamic tunnels (src/tools/tunnel-tools.js
   parseSocksConnectRequest + handleSocks5Connection). The previous
   implementation destroyed every inbound connection -- a black hole.
   New implementation is a real RFC-1928 SOCKS5 server:
   - No-auth method only (0x00). Offers 0xFF if the client won't accept.
   - CMD=CONNECT only; responds COMMAND_NOT_SUPPORTED otherwise.
   - ATYP 0x01 IPv4, 0x03 domain, 0x04 IPv6.
   - forwardOut errors map to SOCKS REP codes (REFUSED / UNREACHABLE /
     GENERAL_FAILURE) so the client sees a meaningful failure instead of
     a dropped connection.
   - Any residual client bytes received during the reply are flushed into
     the new SSH channel so we don't lose the first packet of the stream.
   - 10 unit tests in test-socks5.js covering parser edge cases + full
     handshake happy path + method negotiation failure + forwardOut error.

Registry updated: 50 tools -> 51 (monitoring group 5 -> 6). All docs
(README, CLAUDE.md, wiki, TOOL_MANAGEMENT.md) re-synced. tool-registry.js
docstring, TOOL_GROUP_COUNTS, and test-tool-registry.js all match.

npm test: 649 pass, 0 fail (was 619; +30 new tests). npm run lint: clean.
./scripts/validate.sh: clean.

* chore: eslint cleanup + MCP conformance pass

- Clear all 46 eslint errors (unused imports, dead helpers, legacy examples)
- Overrides no-console for tests/examples/debug (intentional output)
- Add destructiveHint to 9 arbitrary-exec tools (ssh_execute, session_send,
  process_manager, systemctl, docker, db_dump, backup_create, tunnel_create,
  execute_group) so conservative hosts prompt appropriately
- Fix 8 legacy inline handlers that returned error content without isError:true
  (ssh_history, ssh_group_manage, ssh_deploy, ssh_command_alias, ssh_hooks,
  ssh_profile, ssh_connection_status, ssh_alias)
- Wrap applyPatches() in try/catch so ssh_edit bad regex returns structured fail
- Fix ssh_hooks 'disable' success path that was mislabeled as [err]
- Fix examples/backup-workflow.js: /* */ block comments with */ inside strings
  were prematurely terminating; switched to // line comments + ES export

* security: close cron + SQL-ident injection paths in backup/db tools

Two findings from the security review, both require adversarial input to
reach (MCP caller controls the args), but the blast radius exceeds what
the tool is supposed to allow:

1. **ssh_backup_schedule: cron injection via newline**
   The cron validator counted whitespace-separated tokens, so a value like
   "0 0 * * *\n* * * * * rm -rf ~" passed. shQuote preserves newlines
   inside single-quoted strings, so `printf '%s\n' ${shQuote(cronLine)}`
   installed a multi-line crontab. Fix: reject cron with any \r\n\t and
   any shell metacharacter ($, `), then split on spaces only.

2. **ssh_db_{query,list,dump,import}: SQL ident injection via database/user**
   `database` and `user` were shQuote'd for the shell but interpolated into
   SQL strings like `SHOW TABLES FROM 'name'` and `pg_database_size('name')`.
   A database name of `app'; DROP DATABASE x; --` shell-unquotes to a valid
   SQL injection payload. Fix: validate database/user against
   [A-Za-z0-9_][A-Za-z0-9_.-]{0,63} (the conservative intersection of
   MySQL/PG/Mongo identifier rules) at handler entry.

+4 regression tests (651 -> 653 passing). No existing behavior changed for
well-formed inputs.

* test: remove TOCTOU pattern in profile test cleanup

Replace `existsSync` + `unlinkSync` with try/unlink/ignore-ENOENT so
CodeQL stops flagging tests/test-profiles.js:100,109 as new file-system
race alerts. Behavior is identical (cleanup either restores the original
profile or removes the test-only one), just without the check-then-act
pattern.

* test: drop existsSync precheck in test-profiles.js

CodeQL's file-system-race detector was linking existsSync(testProfileFile)
(read-time check) to the later writeFileSync in cleanup. Read the file
directly via try/readFileSync/ignore-ENOENT so there is no check-then-use
pair for the taint tracker to flag.

* chore: clear remaining repo-level CodeQL alerts

These 52 alerts were flagged against main. This commit touches everything
not already cleaned by earlier commits on op-overhaul:

- Remove TOCTOU (check-then-act) patterns in src/:
  - profile-loader.createProfile: openSync with 'wx' (atomic create-if-not-exists)
    instead of existsSync + writeFileSync.
  - ssh-key-manager.addHostKey: copyFileSync in try/catch(ENOENT); rely on
    mkdir {recursive:true} being idempotent instead of precheck.
  - config-loader: read Codex config via try/readFileSync/ignore-ENOENT
    instead of existsSync + readFileSync.
- Move markdown-table cell escaping into output-formatter.escapeMdCell()
  so CodeQL stops flagging the inline .replace(/\|/g,'\\\\|') chains as
  "incomplete sanitization". The helper also escapes backslashes first
  (so our own escape doesn't double-up) and collapses newlines.
- Drop useless "let stat = 'unknown'" initializers in transfer-tools
  upload/download/edit preview paths; every code path that reaches the
  plan writer assigns stat via try/catch.

* chore: bump node floor to 20.19 (Node 18 EOL'd 2025-04)

Required to merge eslint 10 in PR #2 -- eslint 10 dropped Node 18.
Node 18 reached end-of-life a year ago; every actively maintained LTS
line (20, 22, 24) gets tested in CI. Users on Node 18 can stay on
claude-code-ssh 3.2.x.

---------

Co-authored-by: hunchom <hunchom@users.noreply.github.com>
@hunchom hunchom merged commit 5c74fa7 into main Apr 21, 2026
14 checks passed
@hunchom hunchom deleted the dependabot/npm_and_yarn/eslint-10.2.0 branch April 21, 2026 02:08
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