Summary
Split the three highest-churn TypeScript modules along their existing concern boundaries and enforce the repository's file-size ceiling as a downward-only ratchet.
Problem to solve
src/gateway/server-methods/chat.ts, src/agents/embedded-agent-runner/run/attempt.ts, and src/agents/openai-transport-stream.ts combine separable responsibilities in files that are thousands of lines long and change frequently. This raises review and merge-conflict cost, while the existing check:loc implementation is not wired into normal checks or CI, so the oversized-file backlog can continue growing.
Proposed solution
- Move chat history budgeting, TTS markers, assistant display assembly, origin routing, and server-timing logic into focused modules while keeping the handler table in
chat.ts.
- Decompose
runEmbeddedAttempt into setup, stream transport, stream lifecycle, and finalize phases without changing cleanup ownership or runtime behavior.
- Split OpenAI Responses and Completions transports into separate modules with shared parameter and usage helpers, retaining a stable facade for existing imports and SDK declarations.
- Add a checked-in current-size baseline for production
.ts, .tsx, .mts, and .cts files over 500 lines. Reject growth, new oversized files, stale baselines, and baseline increases relative to the PR/push base.
- Run the ratchet from
check, check:changed, and the CI guards shard.
Alternatives considered
- File-only moves that leave the embedded attempt mega-function intact do not improve its control-flow shape.
- A hard 500-line gate would require an unrelated repository-wide rewrite before any incremental improvement can land.
- Splitting cohesive, low-churn storage modules would add boundaries without reducing current maintenance risk.
Impact
Maintainers get smaller ownership surfaces for the hottest gateway and agent paths, lower conflict pressure, and CI protection against future TypeScript file growth. Runtime behavior and public APIs remain unchanged.
Evidence/examples
The targeted modules were approximately 6,400, 6,500, and 4,900 lines respectively before the split. Focused transport, gateway, and embedded-runner tests; TypeScript checks; formatting/lint; a full changed gate; and a production build are part of the implementation proof.
Additional information
This intentionally leaves session-accessor.sqlite.ts unchanged because it is cohesive and comparatively low churn.
Summary
Split the three highest-churn TypeScript modules along their existing concern boundaries and enforce the repository's file-size ceiling as a downward-only ratchet.
Problem to solve
src/gateway/server-methods/chat.ts,src/agents/embedded-agent-runner/run/attempt.ts, andsrc/agents/openai-transport-stream.tscombine separable responsibilities in files that are thousands of lines long and change frequently. This raises review and merge-conflict cost, while the existingcheck:locimplementation is not wired into normal checks or CI, so the oversized-file backlog can continue growing.Proposed solution
chat.ts.runEmbeddedAttemptinto setup, stream transport, stream lifecycle, and finalize phases without changing cleanup ownership or runtime behavior..ts,.tsx,.mts, and.ctsfiles over 500 lines. Reject growth, new oversized files, stale baselines, and baseline increases relative to the PR/push base.check,check:changed, and the CI guards shard.Alternatives considered
Impact
Maintainers get smaller ownership surfaces for the hottest gateway and agent paths, lower conflict pressure, and CI protection against future TypeScript file growth. Runtime behavior and public APIs remain unchanged.
Evidence/examples
The targeted modules were approximately 6,400, 6,500, and 4,900 lines respectively before the split. Focused transport, gateway, and embedded-runner tests; TypeScript checks; formatting/lint; a full changed gate; and a production build are part of the implementation proof.
Additional information
This intentionally leaves
session-accessor.sqlite.tsunchanged because it is cohesive and comparatively low churn.