Skip to content

refactor(gateway): kill dead code, dedupe loaders, split planner, structure errors#489

Merged
raahulrahl merged 4 commits intomainfrom
refactor/gateway-cleanup
Apr 20, 2026
Merged

refactor(gateway): kill dead code, dedupe loaders, split planner, structure errors#489
raahulrahl merged 4 commits intomainfrom
refactor/gateway-cleanup

Conversation

@raahulrahl
Copy link
Copy Markdown
Contributor

@raahulrahl raahulrahl commented Apr 20, 2026

Summary

Four-stage cleanup of gateway/ — each stage an independent commit, each verified with typecheck + full test run.

Stage Commit Net lines What
A `eb42df2` −3,446 Delete dead opencode fork remnants (src/util/, src/effect/, src/global/, src/id/, orphaned _shared/ modules). Strip matching tsconfig path aliases.
B `7a1c9c0` +21 Extract shared `parseMarkdownWithSchema` helper; agent + recipe loaders now share the split → parseYaml → validate pipeline.
C `7275036` +59 Split `planner/index.ts` (653 → 297) into `index.ts` + `skill-tool.ts` + `util.ts`. Extract `session/prompt-util.ts` from prompt.ts. Public API preserved via re-exports.
D `1899bae` +105 Return structured validation errors (`issues[]`) on /plan 400/500 instead of dumping raw ZodError JSON. 5 new unit tests.

Net: ~3,260 lines removed, 0 behavior changes.

What's dead and gone (Stage A)

Verified with grep across src/ + tests/ that nothing imports these before deleting:

  • `src/util/` — 28 files, entire directory from the opencode fork
  • `src/effect/`, `src/global/`, `src/id/` — entire directories
  • `src/_shared/filesystem.ts`, `npm.ts`, `global.ts`, `types.d.ts`
  • `src/_shared/util/` — flock, effect-flock, glob, iife, lazy, fn, hash, array, module, binary, encode, error, identifier, path, retry, slug
  • Unused tsconfig path aliases (`@/`, `@opencode-ai/shared/`)

The `_shared/util/` now contains exactly one file: `frontmatter.ts` (the actually-used markdown parser).

DRY win (Stage B)

`agent/index.ts` and `recipe/index.ts` both ran the same pipeline: `splitFrontmatter → parseYaml → build candidate → safeParse → throw on error`. Consolidated into `parseMarkdownWithSchema({path, raw, kind, schema, build})` in frontmatter.ts. Each loader now only owns its candidate shape.

Planner split (Stage C)

`planner/index.ts` was 653 lines of schemas + service + tool factory + pure helpers. New layout:

```
planner/index.ts 297 schemas + Service + layer (public API)
planner/skill-tool.ts 216 buildSkillTool + padToolDescription
planner/util.ts 184 normalizeToolName, findDuplicateToolIds,
computeVerifiedLabel, wrapRemoteContent,
jsonSchemaToZod, etc.
```

Tests consuming `../planner` exports (collisions, verified-label, schemas) still work via re-exports in `index.ts`. No test changes required.

Also trimmed `session/prompt.ts` (462 → 391 lines) by lifting `buildSystemPrompt`, `mapFinishReason`, `evtUsage`, and `wrapTool` into `session/prompt-util.ts`.

Error shape fix (Stage D)

Before: `/plan` 400 responses returned `{ error: "invalid_request", detail: "" }` — unreadable and forced clients to re-parse.

After: ZodError → `{ error, detail: "question: must be non-empty; agents.0.endpoint: Invalid url", issues: [{path, message}, ...] }`. Non-Zod errors pass the message through unchanged. Same treatment on the `session_failed` 500 path.

Test plan

  • `npm run typecheck` clean on every commit
  • `npm test` — 221/221 pass (5 new tests in `tests/api/error-detail.test.ts`)
  • Baseline (pre-refactor): 216/216. All original tests still pass.
  • Spot-check a real /plan request against a running gateway before merge (reviewer)
  • Confirm openapi.yaml §/plan responses still match the shape clients expect

Review guide

Commits are ordered for readability — A is pure deletion (zero risk), B is a small consolidation, C is internal reorganization with re-exports preserving the public API, D adds behavior + tests. Review in order; each stands alone if you want to split the PR later.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved error response formatting in API endpoints with structured detail messages and issue breakdowns for validation errors.
  • Refactor

    • Consolidated internal utilities and restructured agent/recipe parsing to use shared markdown frontmatter processing.
    • Reorganized planner tool construction and session prompt handling into dedicated utility modules.
    • Removed unused internal helper functions and dependencies to simplify codebase architecture.

Entire src/util/ (28 files), src/effect/, src/global/, src/id/, plus several
orphaned _shared/ modules (filesystem, npm, flock, etc.) were carried over
from the opencode fork but never imported by anything in src/ or tests/.
Also strip the matching @/* and @opencode-ai/shared/* tsconfig path aliases
— only the deleted files referenced them.

55 files, 3,446 lines removed. Typecheck clean, 216/216 tests still pass.
…arkdownWithSchema

Both the agent and recipe loaders followed the same pattern — splitFrontmatter
→ parseYaml → build candidate → safeParse → throw on error. Extract that chain
into `parseMarkdownWithSchema` (plus a thin `parseFrontmatterDoc` helper) in
the frontmatter util. Each loader now only owns its candidate shape.

Net: fewer lines in agent/recipe, single source of truth for the error
message format. Typecheck clean, 216/216 tests pass.
planner/index.ts was 653 lines mixing three responsibilities: the public
PlanRequest schemas + Service/layer, the per-(peer,skill) tool factory, and
a bundle of pure helpers (name normalization, verified-label logic,
<remote_content> envelope, json-schema→zod). Split into:

  planner/index.ts      297  schemas + Service + layer
  planner/skill-tool.ts 216  buildSkillTool + padToolDescription
  planner/util.ts       184  pure helpers, re-exported from index

session/prompt.ts shed its bottom 70 lines of buildSystemPrompt,
mapFinishReason, evtUsage, and wrapTool into session/prompt-util.ts so
the layer factory reads top-to-bottom without scrolling past helpers.

Typecheck clean, 216/216 tests pass. No behavior changes — tests
consuming `../planner` exports still work via re-exports in index.ts.
…w ZodError

Clients previously received the ZodError's raw JSON-array message in the
`detail` field — unreadable and forced a second parse to find the bad
field. Route 400s (invalid body) and 500s (session_failed) now run through
a shared `formatErrorDetail` that turns Zod failures into a `{path,
message}[]` under `issues` plus a human-readable `detail` summary; non-Zod
errors pass their message through unchanged.

Adds 5 unit tests for the formatter covering single-field, multi-field,
root-level, Error, and string-thrown cases.
@raahulrahl raahulrahl merged commit bc1c015 into main Apr 20, 2026
1 of 4 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 20, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: da273840-8c6e-4fef-8eed-158b6b913eb1

📥 Commits

Reviewing files that changed from the base of the PR and between 0261b51 and 1899bae.

📒 Files selected for processing (65)
  • gateway/src/_shared/filesystem.ts
  • gateway/src/_shared/global.ts
  • gateway/src/_shared/npm.ts
  • gateway/src/_shared/types.d.ts
  • gateway/src/_shared/util/array.ts
  • gateway/src/_shared/util/binary.ts
  • gateway/src/_shared/util/effect-flock.ts
  • gateway/src/_shared/util/encode.ts
  • gateway/src/_shared/util/error.ts
  • gateway/src/_shared/util/flock.ts
  • gateway/src/_shared/util/fn.ts
  • gateway/src/_shared/util/frontmatter.ts
  • gateway/src/_shared/util/glob.ts
  • gateway/src/_shared/util/hash.ts
  • gateway/src/_shared/util/identifier.ts
  • gateway/src/_shared/util/iife.ts
  • gateway/src/_shared/util/lazy.ts
  • gateway/src/_shared/util/module.ts
  • gateway/src/_shared/util/path.ts
  • gateway/src/_shared/util/retry.ts
  • gateway/src/_shared/util/slug.ts
  • gateway/src/agent/index.ts
  • gateway/src/api/plan-route.ts
  • gateway/src/effect/index.ts
  • gateway/src/effect/instance-registry.ts
  • gateway/src/effect/logger.ts
  • gateway/src/effect/runner.ts
  • gateway/src/global/index.ts
  • gateway/src/id/id.ts
  • gateway/src/planner/index.ts
  • gateway/src/planner/skill-tool.ts
  • gateway/src/planner/util.ts
  • gateway/src/recipe/index.ts
  • gateway/src/session/prompt-util.ts
  • gateway/src/session/prompt.ts
  • gateway/src/util/abort.ts
  • gateway/src/util/archive.ts
  • gateway/src/util/color.ts
  • gateway/src/util/data-url.ts
  • gateway/src/util/defer.ts
  • gateway/src/util/effect-http-client.ts
  • gateway/src/util/effect-zod.ts
  • gateway/src/util/error.ts
  • gateway/src/util/filesystem.ts
  • gateway/src/util/fn.ts
  • gateway/src/util/format.ts
  • gateway/src/util/iife.ts
  • gateway/src/util/index.ts
  • gateway/src/util/lazy.ts
  • gateway/src/util/local-context.ts
  • gateway/src/util/locale.ts
  • gateway/src/util/lock.ts
  • gateway/src/util/log.ts
  • gateway/src/util/process.ts
  • gateway/src/util/queue.ts
  • gateway/src/util/record.ts
  • gateway/src/util/schema.ts
  • gateway/src/util/scrap.ts
  • gateway/src/util/signal.ts
  • gateway/src/util/timeout.ts
  • gateway/src/util/token.ts
  • gateway/src/util/update-schema.ts
  • gateway/src/util/wildcard.ts
  • gateway/tests/api/error-detail.test.ts
  • gateway/tsconfig.json

📝 Walkthrough

Walkthrough

This PR significantly simplifies the codebase by removing numerous utility modules and shared services from gateway/src/_shared/, gateway/src/util/, and gateway/src/effect/ while refactoring the planner's tool-creation logic into dedicated modules and improving error handling in API routes.

Changes

Cohort / File(s) Summary
Removed shared utility modules
gateway/src/_shared/filesystem.ts, gateway/src/_shared/global.ts, gateway/src/_shared/npm.ts, gateway/src/_shared/types.d.ts
Deleted AppFileSystem namespace with filesystem operations, Global namespace with XDG path management, Npm service for package installation/discovery, and ambient type declarations for @npmcli/arborist and Bun.
Removed shared utility functions
gateway/src/_shared/util/array.ts, gateway/src/_shared/util/binary.ts, gateway/src/_shared/util/effect-flock.ts, gateway/src/_shared/util/encode.ts, gateway/src/_shared/util/error.ts, gateway/src/_shared/util/flock.ts, gateway/src/_shared/util/fn.ts, gateway/src/_shared/util/glob.ts, gateway/src/_shared/util/hash.ts, gateway/src/_shared/util/identifier.ts, gateway/src/_shared/util/iife.ts, gateway/src/_shared/util/lazy.ts, gateway/src/_shared/util/module.ts, gateway/src/_shared/util/path.ts, gateway/src/_shared/util/retry.ts, gateway/src/_shared/util/slug.ts
Removed array searching, binary operations, filesystem locking, encoding/hashing, error handling abstractions, globbing, ID generation, and various utility functions.
Enhanced frontmatter parsing
gateway/src/_shared/util/frontmatter.ts
Added parseFrontmatterDoc() and parseMarkdownWithSchema<T>() to centralize markdown frontmatter parsing with Zod schema validation.
Removed gateway utility modules
gateway/src/util/abort.ts, gateway/src/util/archive.ts, gateway/src/util/color.ts, gateway/src/util/data-url.ts, gateway/src/util/defer.ts, gateway/src/util/effect-http-client.ts, gateway/src/util/effect-zod.ts, gateway/src/util/error.ts, gateway/src/util/filesystem.ts, gateway/src/util/fn.ts, gateway/src/util/format.ts, gateway/src/util/iife.ts, gateway/src/util/lazy.ts, gateway/src/util/local-context.ts, gateway/src/util/locale.ts, gateway/src/util/lock.ts, gateway/src/util/log.ts, gateway/src/util/process.ts, gateway/src/util/queue.ts, gateway/src/util/record.ts, gateway/src/util/schema.ts, gateway/src/util/scrap.ts, gateway/src/util/signal.ts, gateway/src/util/timeout.ts, gateway/src/util/token.ts, gateway/src/util/update-schema.ts, gateway/src/util/wildcard.ts, gateway/src/util/index.ts
Removed numerous utility functions for abort handling, file operations, color handling, error formatting, path manipulation, process execution, logging, locking, schema transformation, token estimation, and pattern matching.
Removed effect framework modules
gateway/src/effect/index.ts, gateway/src/effect/instance-registry.ts, gateway/src/effect/logger.ts, gateway/src/effect/runner.ts
Deleted Runner abstraction, EffectLogger handle, instance disposal registry, and their public exports.
Removed ID and global path management
gateway/src/id/id.ts, gateway/src/global/index.ts
Deleted monotonic ID generation and XDG-based filesystem path initialization.
Refactored planner tool factory
gateway/src/planner/index.ts, gateway/src/planner/skill-tool.ts (new), gateway/src/planner/util.ts (new)
Extracted tool-building logic and utilities from main planner into dedicated modules; skill-tool.ts defines buildSkillTool() factory and BuildToolDeps interface; util.ts provides normalizeToolName(), findDuplicateToolIds(), extractPlainTextInput/OutputText(), computeVerifiedLabel(), wrapRemoteContent(), and jsonSchemaToZod(); main index now re-exports these utilities.
Refactored session prompt handling
gateway/src/session/prompt-util.ts (new), gateway/src/session/prompt.ts
New module exports buildSystemPrompt(), mapFinishReason(), evtUsage(), and wrapTool() to centralize prompt construction and tool wrapping; existing prompt.ts delegates to these utilities.
Improved API error handling
gateway/src/api/plan-route.ts
Added formatErrorDetail() to structure error responses (Zod validation errors include issues array with path/message; non-Zod errors use standard message).
Updated markdown parsing consumers
gateway/src/agent/index.ts, gateway/src/recipe/index.ts
Refactored parseAgentFile() and parseRecipeFile() to use new parseMarkdownWithSchema() utility for cleaner frontmatter parsing and validation.
Configuration and testing updates
gateway/tsconfig.json, gateway/tests/api/error-detail.test.ts (new)
Removed TypeScript path aliases; added test suite for formatErrorDetail() covering Zod errors, standard errors, and edge cases.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through code so clean,
Deleting clutter in between,
New utilities, refactored flows,
Where planner's wisdom freshly grows,
Simpler paths, less to maintain—
A garden tended once again! 🌿

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/gateway-cleanup

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.

@raahulrahl raahulrahl deleted the refactor/gateway-cleanup branch April 20, 2026 15:45
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