Skip to content

Replace prettier, eslint, and solhint with Biome and forge lint, installed without npm - #1429

Merged
ryanio merged 17 commits into
mainfrom
ryan/biome-forge-lint
Nov 10, 2026
Merged

ryanio merged 17 commits into
mainfrom
ryan/biome-forge-lint

Conversation

@ryanio

@ryanio ryanio commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #1428. It retargets to main once the earlier PRs merge.

Moves linting off the Node toolchain and off npm entirely: every tool is a pinned binary checked against a recorded SHA-256.

  • Solidity uses forge fmt and forge lint --deny warnings (configured in foundry.toml) instead of prettier-plugin-solidity and solhint. The deployed contracts (Seaport.sol, conduit/, helpers/, interfaces/, zones/) are excluded, so their source still matches what was verified onchain. Lint also skips contracts/test/, whose mocks are deliberately unsafe.
  • TypeScript, JavaScript, JSON, Markdown, and YAML use Biome 2.6.3 instead of prettier and eslint. Biome's linter is off for test/, which holds the legacy Hardhat suite that later PRs port to Foundry. Formatting is still enforced there.
  • foundry.toml is formatted with taplo. Shell scripts get shellcheck and shfmt, and workflows get actionlint. .editorconfig records each language's indent.
  • lefthook replaces husky and lint-staged for the optional pre-commit hook.
  • scripts/install-tools.sh installs Biome, taplo, lefthook, shellcheck, shfmt, and actionlint into .tools/bin from each tool's GitHub release. Every file is checked against a pinned SHA-256, so a replaced asset fails the install, and nothing comes from a package registry. Every release is at least two weeks old. scripts/lint.sh check|fix runs what CI runs, and warns when the local Foundry differs from CI's. The CI lint job no longer installs Node.
  • The CI lint job runs each check as its own step.

Commits

  1. forge fmt over tests, scripts, mocks, and reference/. Whitespace and line wrapping only, so review it with whitespace hidden. The bytecode check still passes, and reference/ isn't deployed.
  2. 23 forge lint findings in four test files: block.timestamp reads in functions that call vm.warp, which via_ir can cache across the warp. They now use vm.getBlockTimestamp().
  3. The tooling swap itself, plus Biome's formatting and safe fixes on the TypeScript.
  4. Removal of the readme.io front matter, the stub pages, and prepare-docs.js. They only fed the docs sync, whose destination repo is archived, and Biome's Markdown formatter mangles front matter. This commit also carries Biome's Markdown reformatting of docs/.
  5. Biome for Markdown and YAML, plus taplo, shellcheck, shfmt, and actionlint. Inline FOUNDRY_PROFILE=... prefixes in workflows move into env: blocks.
  6. Small follow-ups: Biome pinned to 2.6.3, and the pre-commit hook covers Markdown and YAML.
  7. The pinned-binary install script and scripts/lint.sh, replacing the npm packages for Biome, taplo, and lefthook.
  8. forge fmt over reference/, which the first commit missed (plain forge fmt skips it), and explicit fmt paths in lint.sh and CI so it stays checked.

Verification

  • scripts/lint.sh check (forge fmt, forge lint, Biome, taplo, shellcheck, shfmt, actionlint) is clean locally with Foundry 1.9.0.
  • scripts/install-tools.sh installs all six tools on macOS arm64, skips them on a second run, and refuses to install a tool when its hash doesn't match.
  • The Forge suites touched by the timestamp change pass: FulfillAdvancedOrder, FulfillOrderTest, MatchAdvancedOrder, and FuzzMain.
  • After the Biome rewrite, the Hardhat suites pass: yarn test with 402 passing and yarn test:ref with 376 passing. One local test:ref run had two flaky failures under load; the rerun was clean.

🤖 Generated with Claude Code

ryanio and others added 5 commits November 9, 2026 14:23
AGENTS.md states the one rule for this repo (the deployed 1.6 bytecode
must not change), the layout, the pinned toolchain, and the build and
test commands. CLAUDE.md imports it.

docs/Seaport-1.7-candidates.md collects ideas from past PRs and issues
that would change the deployed bytecode, each linked to its source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code reads AGENTS.md directly, so the CLAUDE.md import is not
needed. The root file now covers only the bytecode rule, layout, and
commands; test/foundry/AGENTS.md covers precompiled artifacts, profiles,
and fuzz-test pitfalls. The 1.7 list drops the optimizer runs note,
since max runs reproduces the deployed bytecode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Configure forge fmt and forge lint in foundry.toml and apply forge fmt.
The deployed contracts (Seaport.sol, conduit, helpers, interfaces,
zones) are excluded so their source keeps matching what was verified
onchain. This commit only changes whitespace and line wrapping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
forge lint flags block.timestamp reads in test functions that also call
vm.warp, since via_ir can cache the value across the warp. These four
files now use vm.getBlockTimestamp(), and forge lint reports no
findings outside the excluded deployed contracts and mocks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Solidity: forge fmt and forge lint --deny warnings, configured in
  foundry.toml, replace prettier-plugin-solidity and solhint.
- TypeScript, JavaScript, and JSON: Biome 2.6.6 replaces prettier and
  eslint, with SeaDrop's config. Markdown is excluded (Biome's formatter
  breaks the docs front matter), and Biome's linter is off for test/,
  which holds the legacy Hardhat suite being ported to Foundry.
- lefthook replaces husky and lint-staged for the pre-commit hook.
- The CI lint job checks out submodules, installs Foundry, and runs the
  three checks as separate steps.

Biome's formatter and safe fixes rewrote the TypeScript; both Hardhat
suites still pass (402 and 376).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

socket-security Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

ryanio and others added 2 commits November 9, 2026 14:50
The front matter and the AuditLink, SeaportDiagramLink, and Overview
stubs only fed the readme.io sync, whose workflow published to the
now-archived developer-docs repo. prepare-docs.js belonged to the same
pipeline. The remaining docs keep their content.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Biome now also formats Markdown and YAML, so every non-Solidity text
  file follows one formatter.
- taplo formats foundry.toml (4-space indent via .taplo.toml).
- shellcheck and shfmt check the shell scripts in CI, and actionlint
  checks the workflows. Inline FOUNDRY_PROFILE=... prefixes move into
  env blocks, which actionlint's shellcheck pass prefers.
- .editorconfig records the indent for each language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Socket blocks packages published in the last few days, and 2.6.6 is
three days old. 2.6.3 is over two weeks old and produces identical
results on this repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

The Biome pre-commit glob excludes Markdown and YAML, so commits containing only those files skip the formatting checks enforced in CI.

1 open issue
What changed in this PR

This PR migrates Seaport’s formatting and linting to Forge, Biome, and supporting tools while preserving deployed contract sources and compiler settings.

Changes:

  • Replaces Prettier, ESLint, Solhint, and Husky with Forge checks, Biome, taplo, and lefthook; adds separate CI checks.
  • Applies formatter output and targeted TypeScript cleanups across tests, mocks, and scripts.
  • Removes obsolete documentation-sync assets and updates contributor instructions.
File Description
tsconfig.json Removes the deleted docs script from compilation inputs.
test/​zone.spec.ts Applies Biome import ordering and callback cleanup.
test/​utils/​fixtures/​tokens.ts Reorders type imports.
test/​utils/​fixtures/​marketplace.ts Formats imports and conditional expressions.
test/​utils/​fixtures/​index.ts Reorders imports and adopts flatMap.
test/​utils/​fixtures/​create2.ts Reorders imports.
test/​utils/​fixtures/​conduit.ts Formats imports and contract calls.
test/​utils/​faucet.ts Reorders type imports.
test/​utils/​encoding.ts Formats imports, generics, and conditionals.
test/​utils/​eip712/​utils.ts Reorders imports.
test/​utils/​eip712/​Eip712MerkleTree.ts Reorders imports and uses exponentiation syntax.
test/​utils/​eip712/​defaults.ts Reorders imports.
test/​utils/​eip712/​bulk-orders.ts Reorders imports.
test/​utils/​contracts.ts Formats imports and nullish expressions.
test/​router.spec.ts Applies Biome import and callback cleanup.
test/​revert.spec.ts Formats imports, callbacks, and assignments.
test/​getter.spec.ts Applies Biome import and callback cleanup.
test/​foundry/​zone/​TestZoneCalldataFidelity.t.sol Applies Forge formatting to zone tests.
test/​foundry/​zone/​impl/​VerboseAuthZone.sol Formats zone mock functions.
test/​foundry/​zone/​impl/​TestZone.sol Formats zone mock functions.
test/​foundry/​zone/​impl/​StatefulTestZone.sol Formats stateful zone checks.
test/​foundry/​zone/​impl/​HashCalldataTestZone.sol Formats calldata-hash zone helpers.
test/​foundry/​zone/​impl/​BadZone.sol Formats invalid-zone mock functions.
test/​foundry/​utils/​TestTokenMinter.sol Formats token allocation helpers.
test/​foundry/​utils/​StructCopier.sol Formats struct-copying helpers.
test/​foundry/​utils/​reentrancy/​ReentrantStructs.sol Wraps a long struct member declaration.
test/​foundry/​utils/​OfferConsiderationItemAdder.sol Formats item-building helpers.
test/​foundry/​utils/​ERC721Recipient.sol Formats the receiver callback.
test/​foundry/​utils/​EIP712MerkleTree.sol Formats Merkle-tree and signature helpers.
test/​foundry/​utils/​DifferentialTest.sol Formats the passing-result hash declaration.
test/​foundry/​utils/​ConsiderationErrorsWrapper.sol Formats error wrapper functions.
test/​foundry/​utils/​BaseConsiderationTest.sol Formats shared test setup and signing helpers.
test/​foundry/​TokenTransferrer.t.sol Formats token transfer tests.
test/​foundry/​token/​StubERC20.sol Formats the transfer stub.
test/​foundry/​token/​CustomERC721.sol Formats the custom token implementation.
test/​foundry/​offerers/​TestPoolOffererTest.t.sol Formats pool offerer tests.
test/​foundry/​offerers/​impl/​TestPoolOfferer.sol Formats pool offerer functions.
test/​foundry/​offerers/​impl/​TestPoolFactory.sol Formats pool deployment and transfer calls.
test/​foundry/​offerers/​impl/​StatefulRatifierOfferer.sol Formats ratification mock functions.
test/​foundry/​offerers/​impl/​PassthroughOfferer.sol Formats passthrough offerer helpers.
test/​foundry/​offerers/​impl/​BadOfferer.sol Formats invalid-offerer mock functions.
test/​foundry/​offerers/​impl/​AdjustedAmountOfferer.sol Formats amount-adjustment helpers.
test/​foundry/​offerers/​ContractOffersNativeTokenOfferItems.t.sol Formats native-token offer tests.
test/​foundry/​offerers/​BadOfferer.t.sol Formats invalid-offerer tests.
test/​foundry/​offerers/​AdjustedAmountOfferer.t.sol Formats adjusted-amount offerer tests.
test/​foundry/​NonMatchSelectorTest.t.sol Formats selector assertions.
test/​foundry/​new/​zones/​ValidationOffererZone.sol Formats validation zone functions.
test/​foundry/​new/​SelfRestrictedContractOfferer.t.sol Formats restricted-offerer tests.
test/​foundry/​new/​SeaportNavigatorTest.sol Formats navigator initialization.
test/​foundry/​new/​helpers/​VmUtils.sol Formats the cheatcode address declaration.
test/​foundry/​new/​helpers/​sol/​lib/​types/​MatchComponentType.t.sol Formats match-component tests.
test/​foundry/​new/​helpers/​sol/​lib/​fulfillment/​AmountDeriverHelper.t.sol Formats amount-derivation tests.
test/​foundry/​new/​helpers/​PreapprovedERC721.sol Formats approval helper functions.
test/​foundry/​new/​helpers/​Labeler.sol Formats label storage helpers.
test/​foundry/​new/​helpers/​FractionUtil.sol Formats fraction calculations and results.
test/​foundry/​new/​helpers/​event-utils/​TransferEventsLib.sol Formats transfer event helpers.
test/​foundry/​new/​helpers/​event-utils/​OrdersMatchedEventsLib.sol Formats matched-order event helpers.
test/​foundry/​new/​helpers/​event-utils/​OrderFulfilledEventsLib.sol Formats fulfillment event hashing.
test/​foundry/​new/​helpers/​event-utils/​EventSerializer.sol Formats an event serialization call.
test/​foundry/​new/​helpers/​event-utils/​EventHashes.sol Formats event hash functions.
test/​foundry/​new/​helpers/​ERC721Recipient.sol Formats the receiver callback.
test/​foundry/​new/​helpers/​EIP712MerkleTree.sol Formats Merkle-tree signing helpers.
test/​foundry/​new/​helpers/​EIP1271Offerer.sol Formats signature validation mock functions.
test/​foundry/​new/​helpers/​DifferentialTest.sol Formats the passing-result hash declaration.
test/​foundry/​new/​helpers/​BaseSeaportTest.sol Formats shared setup and signing helpers.
test/​foundry/​new/​FuzzMain.t.sol Formats fuzz configuration arguments.
test/​foundry/​new/​FuzzCoverage.t.sol Formats seed encoding arguments.
test/​foundry/​new/​FractionUtil.t.sol Formats fraction assertions.
test/​foundry/​interfaces/​ProxyRegistry.sol Formats an interface declaration.
test/​foundry/​GetterTests.t.sol Formats tuple assignments.
test/​foundry/​FulfillAvailableAdvancedOrderCriteria.t.sol Formats criteria fulfillment tests.
test/​foundry/​ConstantsTest.t.sol Formats selector assertions.
test/​foundry/​ConsiderationErrors.t.sol Formats revert expectations.
test/​foundry/​conduit/​ConduitExecuteWithBatch1155.t.sol Formats combined conduit transfer tests.
test/​foundry/​conduit/​ConduitExecuteBatch1155.t.sol Formats batch conduit transfer tests.
test/​foundry/​conduit/​ConduitExecute.t.sol Formats conduit execution tests.
test/​foundry/​CeilEquivalenceTest.t.sol Formats the test function declaration.
test/​findings/​PartialFillFractionOverflow.spec.ts Reorders regression-test imports.
test/​findings/​FulfillmentOverflowWithMissingItems.spec.ts Reorders regression-test imports.
test/​findings/​CriteriaResolverUnhashedLeaves.spec.ts Reorders regression-test imports.
test/​findings/​AdditionalRecipientsOffByOne.spec.ts Reorders imports and simplifies a callback.
test/​counter.spec.ts Formats counter tests and imports.
test/​conduit.spec.ts Formats imports, type expressions, and calls.
test/​basic.spec.ts Applies Biome import and callback cleanup.
test/​advanced.spec.ts Formats advanced-order tests and imports.
scripts/​write_reports.ts Uses a Node-prefixed import and reorders types.
scripts/​utils.ts Uses Node-prefixed imports and explicit decimal parsing.
scripts/​print_report.ts Reorders report utility imports.
scripts/​plot_metrics.ts Uses a Node-prefixed filesystem import.
scripts/​find_optimizer_runs.sh Applies shell formatting and quotes command output.
scripts/​compare_reports.ts Reorders report comparison imports.
scripts/​comment-table.ts Replaces an ESLint suppression with a Biome directive.
script/​TransferHelperDeployer.s.sol Formats the empty setup function.
script/​SeaportDeployer.s.sol Formats deployment interfaces and expressions.
script/​NavigatorDeployer.s.sol Formats navigator deployment helpers.
script/​CallNavigator.s.sol Formats example order construction.
README.md Documents the replacement linting tools and hook.
package.json Replaces lint dependencies, scripts, and hook installation.
lefthook.yml Adds staged-file formatting jobs.
hardhat.config.ts Reorders imports and tightens callback parameter types.
hardhat-validator.config.ts Reorders imports and types source paths.
hardhat-reference.config.ts Reorders imports and types source paths.
foundry.toml Configures formatting and lint exclusions; normalizes TOML.
docs/​ZoneDocumentation.md Removes obsolete publishing metadata.
docs/​SeaportDiagramLink.md Deletes the obsolete publishing link stub.
docs/​prepare-docs.js Deletes the retired docs preparation script.
docs/​Overview.md Deletes the retired publishing overview page.
docs/​FunctionSignatures.md Removes publishing metadata and normalizes formatting.
docs/​Deployment.md Removes publishing metadata and formats Markdown.
docs/​Code4rena-Guidelines.md Normalizes Markdown emphasis and lists.
docs/​AuditLink.md Deletes the obsolete audit link stub.
contracts/​test/​TypehashDirectory.sol Formats type-hash generation helpers.
contracts/​test/​TestZone.sol Formats zone mock functions.
contracts/​test/​TestPostExecution.sol Formats post-execution validation functions.
contracts/​test/​TestInvalidZone.sol Formats invalid-zone mock functions.
contracts/​test/​TestInvalidContractOffererRatifyOrder.sol Formats the mock constructor.
contracts/​test/​TestInvalidContractOfferer165.sol Formats invalid-offerer mock functions.
contracts/​test/​TestInvalidContractOfferer.sol Formats the mock constructor.
contracts/​test/​TestERC721Revert.sol Formats the reverting transfer declaration.
contracts/​test/​TestERC721Fee.sol Formats royalty token mock functions.
contracts/​test/​TestERC20Revert.sol Formats the reverting transfer declaration.
contracts/​test/​TestERC20Panic.sol Formats the panic transfer declaration.
contracts/​test/​TestERC20NotOk.sol Formats the unsuccessful transfer declaration.
contracts/​test/​TestERC20.sol Formats transfer and allowance functions.
contracts/​test/​TestERC1271.sol Formats signature validation functions.
contracts/​test/​TestERC1155Revert.sol Formats reverting transfer declarations.
contracts/​test/​TestERC1155.sol Formats the mint function.
contracts/​test/​TestContractOffererNativeToken.sol Formats native-token offerer functions.
contracts/​test/​TestContractOfferer.sol Formats contract offerer mock functions.
contracts/​test/​TestBadContractOfferer.sol Formats invalid-offerer mock functions.
contracts/​test/​Reenterer.sol Formats low-level calls and tuple assignments.
contracts/​test/​InvalidERC721Recipient.sol Formats invalid receiver declarations.
contracts/​test/​ExcessReturnDataRecipient.sol Formats assembly and arithmetic expressions.
contracts/​test/​ERC2981.sol Formats royalty helper functions.
contracts/​test/​EIP1271Wallet.sol Formats wallet signature validation.
contracts/​test/​ConduitMockRevertNoReason.sol Formats conduit mock declarations.
contracts/​test/​ConduitMockRevertBytes.sol Formats conduit mock declarations.
contracts/​test/​ConduitMockInvalidMagic.sol Formats conduit mock declarations.
contracts/​test/​ConduitMock.sol Formats conduit mock declarations.
config/​.solhintignore Removes obsolete Solhint exclusions.
config/​.solhint.json Removes obsolete Solhint configuration.
biome.json Configures Biome formatting, linting, and exclusions.
AGENTS.md Adds the lint-check command.
.taplo.toml Configures TOML formatting.
.prettierrc.js Removes obsolete Prettier configuration.
.prettierignore Removes obsolete Prettier exclusions.
.github/​workflows/​test.yml Adds separate lint checks and explicit profile environments.
.github/​actions/​forge-precompile/​action.yml Moves build profiles into environment blocks.
.eslintrc.js Removes obsolete ESLint configuration.
.eslintignore Removes obsolete ESLint exclusions.
.editorconfig Defines shared whitespace and indentation settings.

Review effort: Balanced

Comment thread lefthook.yml Resolved
ryanio and others added 2 commits November 9, 2026 14:55
assertPass raises it for any run that didn't end in the expected passing
status, including failures both implementations share, so it doesn't by
itself mean the optimized and reference builds disagree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Biome now checks both formats in CI, so the hook covers them as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI 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.

🟢 Approval recommended

The formatting and linting tooling migration has no active review issues blocking approval.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Biome, taplo, and lefthook came from npm, which puts a registry and its
dependency tree in the path of every lint run. scripts/install-tools.sh
now downloads them, plus shellcheck, shfmt, and actionlint, from each
tool's GitHub release into .tools/bin and checks every file against a
pinned SHA-256, so a replaced asset fails the install. All six releases
are at least two weeks old.

scripts/lint.sh runs the same checks as CI and warns when the local
Foundry differs from CI's. The CI lint job no longer installs Node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanio ryanio changed the title Replace prettier, eslint, and solhint with Biome and forge lint Replace prettier, eslint, and solhint with Biome and forge lint, installed without npm Nov 10, 2026
@ryanio
ryanio requested a balanced review from Copilot November 10, 2026 02:10

Copilot AI 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.

🔵 Needs a closer look

Formatting checks skip reference/, allowing reference-only regressions to pass locally and in CI; both lint branches and the CI workflow need explicit formatting paths that include it.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Include reference files in forge fmt checks and fixes

scripts/​lint.sh:20

With the default profile, forge fmt checks contracts/, test/foundry/, and script/, but skips reference/, so reference-only formatting regressions pass both local checks and CI. Pass contracts test/foundry script reference explicitly to forge fmt in both the check and fix branches. Apply the same change to .github/workflows/test.yml:64.

Review effort: Balanced

forge fmt with no arguments covers only the profile's src, test, and
script dirs, so reference/ was never formatted or checked. lint.sh and
CI now pass contracts, test, script, and reference explicitly; the
deployed contracts stay excluded by the fmt ignore list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanio

ryanio commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator Author

Copilot's body-only finding was right, and it's fixed in f0f6bc8. With no arguments, forge fmt covers only the profile's contracts, test/foundry and script dirs, so reference/ was never formatted. That also means the first commit's message overstates what it did. reference/ is now formatted (20 files, whitespace only; it still compiles), and scripts/lint.sh and the CI step pass contracts test script reference explicitly. The deployed contracts stay excluded through the [fmt] ignore list, which still applies with explicit paths.

Copilot AI 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.

🟢 Approval recommended

The linting and formatting migration has no active review issues blocking approval.

No open issues 🎉

Review effort: Balanced

@tomhirst

Copy link
Copy Markdown

Review: 7/10. Safe to merge once the two P1s are fixed.

What checks out:

  • No contract changes. I compared all 176 changed .sol files token by token, ignoring whitespace, comments and quote style. The only real difference is the braces added in FuzzEngineLib.sol, and those don't change behaviour.
  • Only test mocks touched under contracts/. The edits are all in contracts/test/.
  • Tool installs look safe. install-tools.sh downloads pinned release URLs and checks each SHA-256 before extracting. There's no curl | sh.
  • CI looks right. CI has contents: read, third-party actions are SHA-pinned, and I found nothing left that still references prettier, eslint or solhint.

P0: none

P1:

  • test/utils/seeded-rng.js:66,89: Biome turned the Mash and uheprng constructors into arrow functions, but lines 102 and 267 still call them with new.
    • Failure: With REPORT_GAS set, test/utils/encoding.ts calls SeededRNG.create("gas-report") when it's imported. So yarn profile and yarn profile:nospec throw TypeError: uheprng is not a constructor before any test runs. I reproduced this in Node.
    • Why CI is green: CI never sets REPORT_GAS.
    • Still present at the top of the stack: the bug carries through to Bump test-only libraries and apply the open dependabot fixes #1431.
    • Fix: Revert the file to the version before this PR, and add it to Biome's ignore list, since it's vendored code.
  • lefthook.yml:5-10: the forge fmt {staged_files} pre-commit hook skips most of the [fmt] ignore list.
    • Cause: When a file path is passed explicitly, Forge 1.9.0 honours only the exact-path entry (contracts/Seaport.sol), not the ** globs.
    • Repro: forge fmt --check contracts/conduit/ConduitController.sol and contracts/zones/PausableZone.sol both exit 1. forge fmt --check contracts exits 0.
    • Failure: Edit a comment in ConduitController.sol and commit. The hook reformats the whole deployed file and re-stages it (stage_fixed: true). CI won't catch this either: the directory-level fmt check skips the file, and DeployedBytecode.t.sol only covers Seaport. This also contradicts the README's statement that deployed contracts are excluded from forge fmt.
    • Fix: Add the same globs to that job's exclude list in lefthook.yml. Ideally, also add a CI guard that fails when contracts/{Seaport.sol,conduit,helpers,interfaces,zones} change.

P2 / optional:

  • Bytecode check coverage: extend DeployedBytecode.t.sol to cover ConduitController and Conduit as well, to back up the claim that the deployed contracts are frozen.
  • Dead lint comments: the eslint-disable comments left in test/ (e.g. seeded-rng.js:1-2, fixtures/index.ts:766) no longer do anything. Drop them or convert them to biome-ignore.
  • Commit message: commit 1 says it formatted reference/, but that formatting happened in f0f6bc8a.
  • Windows: install-tools.sh supports only macOS and Linux, so Windows contributors lose yarn lint:check. Worth noting in the README.

Name the settings the optimized profile inherits from the default
profile, note that tests need both builds, add the single bytecode check
command, and correct who closed seaport-core#10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ryanio and others added 2 commits November 10, 2026 02:09
Biome rewrote the vendored Mash and uheprng constructors as arrow
functions, so `new uheprng()` threw when REPORT_GAS was set. Restore
the original file and exclude it from Biome.

forge fmt applies only exact-path ignores when given files, so the
pre-commit hook would reformat deployed contracts. Exclude them in
lefthook too, and pin their sources in scripts/frozen-contracts.sha256,
which CI and scripts/lint.sh check.

Drop the eslint-disable comments Biome doesn't read, and note that the
tool installer needs WSL on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanio

ryanio commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks @tomhirst, both P1s were real. Fixed in f3d7edc.

seeded-rng.js: I reproduced TypeError: uheprng is not a constructor with the old file. The file is now byte-identical to main and excluded from Biome as vendored code, and SeededRNG.create("gas-report") works again. I also checked every other function-to-arrow rewrite in the diff. The rest are Mocha describe callbacks whose bodies never use this or arguments, so they behave the same.

lefthook.yml: confirmed with Forge 1.9.0. With explicit paths, forge fmt --check exits 1 on ConduitController.sol, PausableZone.sol, and SeaportRouter.sol, and only Seaport.sol is skipped. The forge fmt job now excludes the same globs, and lefthook run pre-commit on those files now skips them while still formatting contracts/test/. For the CI guard, scripts/frozen-contracts.sha256 pins all 48 deployed sources. CI and scripts/lint.sh check run shasum -a 256 --check against it, so any edit fails, whitespace included. A deliberate change regenerates it with scripts/lint.sh freeze, and that shows up in review.

P2s:

  • I didn't extend DeployedBytecode.t.sol to ConduitController. Etherscan shows the deployed controller was compiled with solc 0.8.14 at 1,000,000 runs, so this repo's 0.8.24 build can't reproduce it, and Conduit's code comes from the controller. The source manifest covers both instead.
  • The dead eslint-disable comments are gone. Biome's linter is off for test/, so they needed no biome-ignore replacement.
  • The commit message overstated it, as I noted above. I'm leaving history as is instead of force-pushing.
  • The README now says the installer supports macOS and Linux, and to use WSL on Windows.

@ryanio
ryanio changed the base branch from ryan/agents-and-1.7-notes to main November 10, 2026 17:50
@ryanio
ryanio merged commit a587a32 into main Nov 10, 2026
12 of 22 checks passed
@ryanio
ryanio deleted the ryan/biome-forge-lint branch November 10, 2026 18:28
ryanio added a commit to ProjectOpenSea/seadrop that referenced this pull request Nov 10, 2026
SeaDrop's only npm dependencies were two dev tools, Biome and lefthook.
This replaces them with the same pinned tooling seaport now uses
([seaport#1429](ProjectOpenSea/seaport#1429)),
so the repo has no Node or npm dependencies at all.

- `scripts/install-tools.sh` downloads Biome, taplo, lefthook,
shellcheck, shfmt and actionlint from their GitHub releases into
`.tools/bin`, and checks each file against a pinned SHA-256. It's the
same script as seaport's.
- `scripts/lint.sh check` runs what CI runs: `forge fmt --check`, the
Seaport pragma patch, `forge lint --deny warnings`, Biome, taplo,
shellcheck, shfmt and actionlint. `scripts/lint.sh fix` applies the
formatters.
- CI's lint job installs the tools (cached by the install script's hash)
instead of setting up Node and running `npm ci`.
- `package.json`, `package-lock.json` and `.nvmrc` are gone.
`.gitignore` ignores `.tools/` instead of `node_modules`.
- Biome is pinned at 2.6.3, the version seaport uses. 2.6.6, which
`package.json` had, was released on November 6, which is under the two
weeks we wait before pinning a release. Its output on this repo is
unchanged.
- `lefthook.yml` runs the binaries from `.tools/bin` and also formats
TOML and shell scripts.
- The shell scripts are reindented to four spaces for shfmt, and seven
unquoted variables that shellcheck flagged in `check_deployments.sh`,
`find_optimizer_runs.sh` and `forge_script_multichain.sh` are now
quoted.
- AGENTS.md and the docs replace the `npm run` commands with the scripts
and the plain build command.

No Solidity changes. The same change for `main` is
[seadrop#229](#229).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
ryanio added a commit to ProjectOpenSea/seadrop that referenced this pull request Nov 10, 2026
SeaDrop's only npm dependencies were two dev tools, Biome and lefthook.
This replaces them with the same pinned tooling seaport now uses
([seaport#1429](ProjectOpenSea/seaport#1429)),
so the repo has no Node or npm dependencies at all.

- `scripts/install-tools.sh` downloads Biome, taplo, lefthook,
shellcheck, shfmt and actionlint from their GitHub releases into
`.tools/bin`, and checks each file against a pinned SHA-256. It's the
same script as seaport's.
- `scripts/lint.sh check` runs what CI runs: `forge fmt --check`, `forge
lint --deny warnings`, Biome, taplo, shellcheck, shfmt and actionlint.
`scripts/lint.sh fix` applies the formatters.
- CI's lint job installs the tools (cached by the install script's hash)
instead of setting up Node and running `npm ci`.
- `package.json`, `package-lock.json` and `.nvmrc` are gone.
`.gitignore` ignores `.tools/` instead of `node_modules`.
- Biome is pinned at 2.6.3, the version seaport uses. 2.6.6, which
`package.json` had, was released on November 6, which is under the two
weeks we wait before pinning a release. Its output on this repo is
unchanged.
- `lefthook.yml` runs the binaries from `.tools/bin` and also formats
TOML and shell scripts.
- `scripts/check_sizes.sh` is reindented to four spaces for shfmt.
That's whitespace only.
- AGENTS.md and the docs replace the `npm run` commands with the scripts
and the plain `forge coverage` command.

No Solidity changes. A matching PR for the `v2` branch follows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

4 participants