Skip to content

chore: housekeeping & make eslint happy - #488

Merged
SukkaW merged 25 commits into
masterfrom
housekeeping-make-eslint-happy
Aug 29, 2026
Merged

chore: housekeeping & make eslint happy#488
SukkaW merged 25 commits into
masterfrom
housekeeping-make-eslint-happy

Conversation

@SukkaW

@SukkaW SukkaW commented Aug 28, 2026

Copy link
Copy Markdown
Member

Summary

Housekeeping phase 1: sweep existing ESLint issues.

Verification

  • 686 lint errors -> 0
  • 454 lint warnings -> 415
  • all existing passed tests still pass after the changes
  • two callback refs are introduced to replace layout effect
  • ci all green after fixes

11 eslint-disable reports for vibe-proof are introduced, mostly potential race conditions. These require future refactors.

re-ran codegen to update artifacts.

Checklist

  • pnpm check:ci and pnpm test both pass (plus cargo fmt / clippy / test for Rust changes)
  • I ran the affected surface and observed the change working
  • If a wire message changed: WIRE_PROTOCOL_VERSION is bumped
  • New code and assets are my own work, or their origin and license compatibility are noted above
  • Docs and comments are updated where behavior changed

SukkaW added 21 commits August 29, 2026 00:04
prefer-array-from-mapper, prefer-timer-args, prefer-slice-over-split-index,
prefer-string-code-point-operations; foxts added to schema for split-nth
@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown

Greptile Summary

This housekeeping PR resolves existing ESLint violations across the monorepo while preserving the application’s overall architecture.

  • Reworks collection iteration, callback declarations, imports, and React effect/ref patterns to satisfy lint rules.
  • Updates lint-related dependencies, shared utility packages, workspace manifests, and generated lockfile artifacts.
  • Refreshes associated tests and generated assets.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/src/shell/desktop-shell.tsx Replaces layout-effect-driven panel host attachment with stable callback refs; no eligible follow-up defect was established.
packages/presentation/ui/src/keyboard/hooks.ts Refactors keyboard listener and registration hooks for lint compliance; no publishable follow-up issue was established.
packages/foundation/schema/src/remote-config.ts Applies utility and iteration refactors to remote configuration handling without an established contract regression.
packages/host/agent-adapter/src/native/claude-code.ts Performs extensive lint-oriented control-flow and iteration cleanup in the Claude Code adapter.
pnpm-lock.yaml Regenerates dependency resolution after workspace-wide utility and lint-tool upgrades.

Reviews (4): Last reviewed commit: "Update packages/host/agent-adapter/src/n..." | Re-trigger Greptile

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ No correctness defects found. Two process concerns (undeclared dependency scope, one release-age pin) and a few nitpicks.

Reviewed changes

  • A repo-wide ESLint codemod across 340 files: ~500 for...of → hoisted-len indexed loops, Object.fromEntriesreduce object builders, [...x].map()Array.from(x, fn), localeCompare → module-scope Intl.Collator, setTimeout(() => f(a), ms)setTimeout(f, ms, a), codePointAtcharCodeAt, and the sukka/*vibe-proof/* rule-id namespace migration.
  • eslint-suppressions.json (ESLint native bulk suppressions) is deleted outright.
  • ~15 new split0th / split1st call sites from foxts/split-nth, replacing str.split(sep, n)[i], including two request-routing hot paths (transport/src/http-server.ts, daemon/src/sim/mcp-endpoint.ts).
  • Genuine behavioral rewrites folded into the sweep: desktop-shell.tsx moves from useState + useLayoutEffect DOM capture to React 19 callback refs; transport/src/hub.ts converts an if/else if chain to switch (p.kind); keyboard/hooks.ts adopts foxact/use-abortable-effect with { signal } listener teardown; brand-assets.ts / verify-artifacts switch to lstatSync(…, { throwIfNoEntry: false }) with an explicit undefined guard.
  • Dependency and toolchain bumps: foxts^5.9.1 across 8 packages, eslint ^10.8.0^10.9.1, the sukka config/react/formatter trio ^8.14.2^9.0.1 (major), packageManager pnpm@11.10.0pnpm@11.24.0, verkit@0.3.2 added, and ~2,874 lockfile lines.

✅ What I verified rather than assumed

Three properties of a codemod this size are only trustworthy if actually checked, so I checked them:

  • Hoisted len never freezes a live worklist. Every one of the ~500 converted loops was classified by whether its body can grow the array it iterates. None can. The one genuine BFS worklist — packages/host/engine/src/workspace/file-suggest-service.ts — is correctly exempted with a prefer-indexed-array-loop disable and a comment explaining why both .length reads must stay live. Good catch by the author; that's the case that would have silently truncated file search.
  • foxts/split-nth is an exact substitution. split0th(s, sep)s.split(sep)[0] and split1st(s, sep)s.split(sep)[1]split1st returns the segment between the first and second separator, not the remainder, so split1st(name, '/') really does match name.split('/', 2)[1] for scoped package names in host/assets/src/closure.ts. (Worth stating explicitly: had it returned the remainder, the npm tarball URL builder and the MIME-subtype label would both have been wrong.)
  • The desktop-shell.tsx callback refs are not a regression. The docked and maximized panel regions can never both render the ref'd <div>: contentHidden gates it, and the two instances are driven by the same expandedPanel value in layout/workspace.tsx:280-292. The new attachRightContentHost / attachBottomContentHost also ignore the null call entirely and just re-parent a useSingleton-owned host node, so there is no state to clobber. This is strictly simpler than the useState + useLayoutEffect version it replaces.

Also confirmed: OPENCODE_TOOL_NAME_SANITIZE_RE carries the g flag, so the replacereplaceAll change in native/opencode/history.ts cannot throw; and providers/routing.ts exports only a type, so export *export type * in presentation/ui/src/shell/index.ts is safe.

⚠️ The PR body under-describes what's in the commit

The title and description read as a pure lint sweep, but the diff also carries a major-version bump of the ESLint config trio (eslint-config-sukka, @eslint-sukka/react, eslint-formatter-sukka ^8.14.2^9.0.1), a packageManager change from pnpm@11.10.0 to pnpm@11.24.0, a new verkit@0.3.2 dependency, and hand-edited version ranges in packages/vendor/coss-ui/package.json (@base-ui/react ^1.6.0^1.7.0, foxact ^0.3.8^0.3.10, input-otp ^1.4.2^1.5.0).

Two things follow from that:

  1. The sukka major bump is almost certainly why the codemod exists — new rules landed. Saying so in the body turns 340 files of unexplained churn into a legible consequence of one line.
  2. packages/vendor/coss-ui is the repo's designated vendored package: AGENTS.md says upstream formatting is "preserved as-synced — never hand-edit". Bumping its dependency ranges directly is a divergence from that sync contract. If these came from an upstream coss-ui resync, that's fine and worth stating; if they were bumped by hand to satisfy the lockfile, it will get clobbered on the next sync.

Neither blocks the PR — but a reviewer skimming "make eslint happy" will not expect to be reviewing a toolchain upgrade.

ℹ️ foxact@0.3.10 may trip pnpm's release-age gate

.github/dependabot.yml:6 documents that pnpm 11's default minimumReleaseAge (1 day) gates installs, and pnpm-workspace.yaml carries a 90-entry minimumReleaseAgeExclude allowlist for exactly this. Of the newly pinned versions:

  • foxts — allow-listed (bare entry, line 141) ✅
  • eslint-config-sukka / @eslint-sukka/react / eslint-formatter-sukka — covered by the eslint-*-sukka and @eslint-sukka/* globs ✅
  • eslint@10.9.1 (2026-08-24), input-otp@1.5.0 (2026-08-18), verkit@0.3.2 (2026-08-15), @base-ui/react@1.7.0 (2026-08-04) — all comfortably past 1 day ✅
  • foxact@0.3.10 — published 2026-08-27T16:19Z, and not in the allowlist.

That is right on the 24-hour boundary as of this PR. A CI runner doing a cold install before 2026-08-27T16:19Z + 24h would be refused the version the lockfile pins. It self-heals with the clock, so this is informational rather than blocking — but if CI has already gone red on install, this is the reason.

ℹ️ Nitpicks

  • Object.defineProperty is applied unevenly. Eight of the new reduce-based object builders use Object.defineProperty with a comment explaining that acc.__proto__ = … would mutate the prototype instead of creating an own property — remote-config.ts even notes that a JSON __proto__ member "must survive into the canonical payload". Four sites use plain acc[key] = value instead. Three of those four take keys from in-repo string literals or a closed Zod enum and are unreachable; the fourth is flagged inline below. Not a vulnerability, but the rationale the author wrote eight times should either apply everywhere or the safe sites should say why they're special.
  • The codemod emits a redundant alias in ~10 files: const index = i, item = items[i]; where i is already the loop variable (chat/activity-groups.ts, foundation/common/src/config/i-json.ts, node/release-artifact.ts, node/release-compliance.ts, schema/src/model/{linkcode-marketplace,permission,question}.ts, remote-config.ts, native/claude-code.ts, native/opencode/adapter.ts, engine/src/__tests__/engine-sessions.test.ts, workbench/src/history/use-provider-history.ts). Naming the loop variable index directly drops a line at each site.
  • presentation/ui/src/lib/base-ui.ts drops import type * as React from 'react' while the file still writes React.SyntheticEvent, so the type now resolves through the @types/react UMD global namespace rather than an explicit import. It typechecks, but it's a silent dependency on ambient types in a package that otherwise imports what it uses.
  • shell/git/diff-viewer.tsx hoists DiffViewerSkeleton from a component to a module-scope diffViewerSkeletonJsx element. Correct (React permits reusing element objects), and it does remove a component identity — just noting it's a rendering-semantics change, not a rename.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread packages/host/agent-adapter/src/native/claude-code.ts Outdated
Comment thread packages/presentation/ui/src/chat/content-block-view.tsx Outdated
Comment thread packages/presentation/ui/src/chat/code-language.ts Outdated
Comment thread packages/presentation/ui/src/chat/activity-groups.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ All four of my earlier comments are genuinely addressed — I've replied to and resolved those threads. One informational note below, plus a correction to a call I got wrong last round.

Three new commits since my last review (96df5ef7..e52164a4, 16 files, +92/−89).

0290143b is a real bug fix, and a good catch. Resolving artifact paths against realpath(root) matters because a symlinked root — macOS /var/private/var — makes every legitimate path read as an escape. Containment still holds for absolute and .. inputs, so the fix doesn't weaken the guard. CI never caught this because /tmp on Linux isn't a symlink and the tests use bare mkdtemp(join(tmpdir(), …)); codex-commands.test.ts:369 shows the repo already wraps with realpath elsewhere. I grepped every realpath( site — no sibling instance of the same bug.

b96a69d8 is faithful to the lockfile. I ran the repo's own drift guard (closure.test.ts → "the committed pi manifest matches the lockfile") and cross-read pnpm-lock.yaml: @google/genai@1.52.0 and @mistralai/mistralai@2.2.6 both now list ws: 8.21.1, matching the hoisted top-level, so the nested copies correctly disappear. See the one scope question below.

Tests run locally, all passing: foundation/{schema,common} + host/agent-adapter + presentation/ui (148 files / 1537 tests), closure.test.ts + common/src/node/__tests__ (7 / 59), engine-sessions.test.ts + client/workbench (43 / 260).

ℹ️ The pi closure revision change forces every existing user to re-download the closure

packages/host/assets/src/pi-closure.gen.ts moves revision: 'd6ff0228b84fa10c''6fdb7aeb2039774d' while pi itself stays at 0.80.6. Because installIdentity keys the store directory on <version>+<revision>:

// packages/host/assets/src/install.ts:50
return isClosureDescriptor(descriptor) ? `${version}+${descriptor.closure.revision}` : version;

…the new identity is 0.80.6+6fdb7aeb2039774d, a directory nobody has. Every existing pi user re-fetches the whole ~230-package closure.

The manifest is correct — it's the honest output of the generator against the current lockfile. But the delta is entirely incidental transitive churn from the pnpm 11.24 lockfile regen, not anything about pi: ws@8.21.0 nested copies deduped away, minimatch@10.2.5 newly nested under pi (top-level moved 10.2.5→10.2.6), @opentelemetry/semantic-conventions 1.41.1→1.43.0, brace-expansion 5.0.8→5.0.9, has-flag@4.0.0 and supports-color@8.1.1 added.

Not a defect, and nothing to change in the code — just flagging that a lint-sweep PR carries a full re-download for every pi user, which is a scope call only you can make. Committing the regen is clearly right if the lockfile bump is staying in this PR; the question is whether the lockfile bump belongs here at all (which is the same scope-creep thread from my last review, still open).

Not re-raising

The foxact@0.3.10 release-age gate from my last review is moot — 0.3.10 is now well past the 24h minimumReleaseAge boundary. The three items I verified in round 1 (hoisted len never freezing a live worklist, foxts/split-nth being an exact substitution, desktop-shell.tsx callback refs) are unaffected by these commits and stay settled.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread packages/host/agent-adapter/src/native/claude-code.ts Outdated
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
@SukkaW
SukkaW requested review from AprilNEA and Zerlight August 28, 2026 19:49
@SukkaW
SukkaW requested a review from lucas77778 August 28, 2026 19:49
@SukkaW
SukkaW merged commit 0bbe318 into master Aug 29, 2026
12 of 13 checks passed
@SukkaW
SukkaW deleted the housekeeping-make-eslint-happy branch August 29, 2026 04:03
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