Skip to content

refactor: remove built-in formatter integration from write tools#1353

Merged
Astro-Han merged 4 commits into
devfrom
pawwork/remove-formatter-integration
Jun 17, 2026
Merged

refactor: remove built-in formatter integration from write tools#1353
Astro-Han merged 4 commits into
devfrom
pawwork/remove-formatter-integration

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

Remove the built-in auto-format-on-write behavior from edit, write, and apply_patch tools. Delete the entire format/ subsystem (~600 lines): 20+ formatter definitions, service layer, config schema, API route, and tests. The removal also propagates to the public contract — the /formatter route, the SDK Formatter client and FormatterStatus* types, and the Config.formatter field are dropped from openapi.json and the v1/v2 SDK. This was the only agent tool among Codex CLI, Claude Code, and PawWork that auto-formatted files after writing — the other two leave formatting to the user's pre-commit hooks, CI, or optional PostToolUse hooks.

Why

The built-in formatter created invisible side effects: agents writing .ts files had their code reformatted behind the scenes, causing diff mismatches and agent confusion. The AGENTS.md already states "Lint only, no formatter. Biome formatter is intentionally disabled" — this change aligns the code with that intent.

Related Issue

None.

Human Review Status

Pending

Review Focus

  • Verify that removing format.file() from the three write tools doesn't break the write-then-diff flow
  • Confirm the narrow compat shim in normalizeLoadedConfig silences old formatter config fields without erroring
  • Check that no other consumers of the Format service or the SDK formatter surface were missed

Risk Notes

  • Config contract (intentional clean break): formatter is removed from the public Config schema and the SDK Config type, and Config is strict (additionalProperties: false). So $schema-aware editors and the SDK type now flag a stale formatter key as invalid — this is the desired signal to drop the dead key. At runtime, the narrow delete copy.formatter shim in normalizeLoadedConfig strips formatter: true/false/map before the strict decode, so existing configs still load with the key silently ignored rather than hard-erroring on upgrade. Net: the contract no longer advertises formatter (tooling rejects it), while old configs keep loading during migration.
  • SDK/OpenAPI (breaking): GET /formatter, the Formatter client class and formatter getter, the FormatterStatus* request/response types, the FormatterStatus model, and the Config.formatter field are removed from openapi.json and both the v1 and v2 SDK. Any external consumer of client.formatter / GET /formatter must drop it. No internal consumers were found. The checked-in openapi.json is a periodically-refreshed snapshot (not regenerated per change), so the formatter entries were removed surgically rather than via a full regen that would churn ~20 unrelated routes.
  • No platform/packaging impact: Changes are purely in the TypeScript service layer, the generated SDK, and a CI shard list.

How To Verify

Typecheck: bun run typecheck (opencode + sdk) — passes, 0 errors
Tool tests: bun test test/tool/edit.test.ts test/tool/write.test.ts test/tool/apply_patch.test.ts — 80 pass, 0 fail
Server routes: bun test test/server/instance-root-routes.test.ts — /formatter dropped from the asserted route list
Config compat: bun test test/config/config.test.ts -t "ignores removed formatter" — formatter: true / false / {...} all load with the field stripped (verified across all three forms)
SDK surface: repo grep finds no formatter API/config types outside docs; route, client, getter, FormatterStatus*, and Config.formatter gone from openapi.json and the v1/v2 SDK
CI shard: bun test test/github/ci-workflow.test.ts — 17 pass (Windows server-tools shard no longer lists test/format, matching windows-advisory.yml)
Route inventory: bun test test/server/route-inventory-harness.test.ts — 11 pass

Screenshots or Recordings

Not applicable — no visible UI changes.

Checklist

  • Type labeltask
  • Routing labelsharness (auto-assigned by bot)
  • Priority labelP2 (auto-assigned by bot)
  • Human Review Status above is set to Pending.
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. (Config contract clean break and SDK/OpenAPI breaking change called out in Risk Notes.)
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

@github-actions github-actions Bot added the harness Model harness, prompts, tool descriptions, and session mechanics label Jun 17, 2026
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Astro-Han, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 17 minutes and 14 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 39894b94-be0c-4ede-aa73-5a142e2fb3f6

📥 Commits

Reviewing files that changed from the base of the PR and between ac1d1e1 and fad3afd.

⛔ Files ignored due to path filters (4)
  • packages/sdk/js/src/gen/sdk.gen.ts is excluded by !**/gen/**
  • packages/sdk/js/src/gen/types.gen.ts is excluded by !**/gen/**
  • packages/sdk/js/src/v2/gen/sdk.gen.ts is excluded by !**/gen/**
  • packages/sdk/js/src/v2/gen/types.gen.ts is excluded by !**/gen/**
📒 Files selected for processing (25)
  • .github/workflows/windows-advisory.yml
  • packages/opencode/src/config/config.ts
  • packages/opencode/src/config/formatter.ts
  • packages/opencode/src/config/index.ts
  • packages/opencode/src/effect/app-runtime.ts
  • packages/opencode/src/effect/bootstrap-runtime.ts
  • packages/opencode/src/format/formatter.ts
  • packages/opencode/src/format/index.ts
  • packages/opencode/src/project/bootstrap.ts
  • packages/opencode/src/server/instance/index.ts
  • packages/opencode/src/tool/apply_patch.ts
  • packages/opencode/src/tool/edit.ts
  • packages/opencode/src/tool/registry.ts
  • packages/opencode/src/tool/write.ts
  • packages/opencode/src/util/bom.ts
  • packages/opencode/test/config/config.test.ts
  • packages/opencode/test/format/format.test.ts
  • packages/opencode/test/github/ci-workflow.test.ts
  • packages/opencode/test/server/instance-root-routes.test.ts
  • packages/opencode/test/session/prompt-effect.test.ts
  • packages/opencode/test/session/snapshot-tool-race.test.ts
  • packages/opencode/test/tool/apply_patch.test.ts
  • packages/opencode/test/tool/edit.test.ts
  • packages/opencode/test/tool/write.test.ts
  • packages/sdk/openapi.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pawwork/remove-formatter-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the P2 Medium priority label Jun 17, 2026

@github-actions github-actions 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.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@Astro-Han Astro-Han added the task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work label Jun 17, 2026
Remove the auto-format-on-write behavior from edit, write, and
apply_patch tools. This was the only agent tool among Codex CLI,
Claude Code, and PawWork that auto-formatted files after writing —
the other two leave formatting to the user (pre-commit hooks, CI,
or optional PostToolUse hooks).

Changes:
- Remove format.file() calls from edit.ts, write.ts, apply_patch.ts
- Delete format/ directory (index.ts, formatter.ts) — 20+ formatter defs
- Remove Format wiring from AppLayer, BootstrapLayer, ToolRegistry
- Remove /formatter API route from server
- Remove formatter config schema field (with narrow compat shim)
- Delete Bom.syncFile (dead code — only existed for post-format resync)
- Update all related tests

The AGENTS.md already states: 'Lint only, no formatter. Biome formatter
is intentionally disabled.' This change aligns the code with that intent.

Formatting remains the user's responsibility via pre-commit hooks, CI,
or editor-level formatOnSave — consistent with how Codex CLI and
Claude Code handle formatting.
@Astro-Han Astro-Han force-pushed the pawwork/remove-formatter-integration branch from 409c43d to 81ca9cb Compare June 17, 2026 16:03
@github-actions github-actions Bot added the ci Continuous integration / GitHub Actions label Jun 17, 2026
Restore the dev-branch formatting in the touched files so the diff carries
only formatter-removal changes (deleted module/imports/layers/route, config
read-time compat shim, test rename/assertion, CI shard sync). The fork keeps
Biome's formatter disabled, so dev's line wrapping is canonical; the prior
revision had reflowed unrelated lines to a 120-column width.

- config.ts: revert isWindowsSyncUnsupportedError, wellknown read,
  withLifecycleOrigin, dispose .catch, and writeConfigTextAtomic wrapping
- registry.ts: revert isDeferredAvailable, availableDeferred, and the
  tool-info execute arrow wrapping
- server/instance/index.ts: revert the two /vcs/diff description reflows
- config.test.ts: revert readJson and provideTmpdirInstance reflows
- apply_patch.ts: revert the change.after single-line reflow
- bootstrap.ts: delete only format.init() from the boot list instead of
  collapsing the multi-line array

Verification: bun run typecheck (opencode); bun test config.test.ts (110
pass) and apply_patch/edit/write tool tests (80 pass).
The /formatter route was removed from the server, but the SDK and a CI test
still referenced it: SDK users could call a dead endpoint, Config.formatter
kept misleading new configs, and unit-opencode failed.

SDK (surgical removal, no compat shell — the checked-in openapi.json is a
periodically-refreshed snapshot, not regenerated per change, so a full
regen would churn ~20 unrelated routes):
- openapi.json: remove the /formatter path, the FormatterStatus schema, and
  the Config.formatter property (deletions only)
- v1 + v2 gen: remove the Formatter client class, the formatter getter on
  OpencodeClient, the FormatterStatus model, the FormatterStatus* request/
  response types, the Config.formatter field, and the now-unused imports

CI:
- ci-workflow.test.ts: drop test/format from the windows-server-tools shard
  command so the pinned command matches windows-advisory.yml (which already
  dropped it), fixing the "defines Windows unit packages and opencode shards"
  assertion

Verification: SDK typecheck; opencode typecheck; bun test ci-workflow.test.ts
(17 pass) and route-inventory-harness.test.ts (11 pass); repo grep confirms no
formatter API/config types remain outside docs and the negative-assertion
config test.
With the formatter integration gone, nothing mutates a file between the
write and the metadata build, so the recompute/relay scaffolding left
behind is now pure dead code.

- write.ts: drop the finalContent alias; it only ever equals contentNew
- edit.ts: drop the second, byte-identical post-write diff recompute (the
  diff built before the write is already final)
- apply_patch.ts: drop the write-only totalDiff variable, its three +=
  appends, and the post-apply rebuild loop. The permission ask and the
  result already derive the aggregate via safeTotalDiff(fileChanges), and
  the per-file `files` metadata is fully populated at build time, so the
  rebuild re-assigned identical values.

Verification: bun run typecheck (opencode); bun test test/tool/write.test.ts
test/tool/edit.test.ts test/tool/apply_patch.test.ts (80 pass).
@Astro-Han Astro-Han merged commit 8b471e3 into dev Jun 17, 2026
36 of 37 checks passed
@Astro-Han Astro-Han deleted the pawwork/remove-formatter-integration branch June 17, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration / GitHub Actions harness Model harness, prompts, tool descriptions, and session mechanics P2 Medium priority task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant