Skip to content

refactor: decompose the three largest TypeScript god files into single-responsibility modules#1183

Merged
willwashburn merged 7 commits into
mainfrom
claude/architecture-refactor-bftmcr
Jun 24, 2026
Merged

refactor: decompose the three largest TypeScript god files into single-responsibility modules#1183
willwashburn merged 7 commits into
mainfrom
claude/architecture-refactor-bftmcr

Conversation

@willwashburn

@willwashburn willwashburn commented Jun 22, 2026

Copy link
Copy Markdown
Member

Summary

Continues the god-file decomposition pattern (prior e7fd375 did the CLI) on the three largest TypeScript files — the system's most central client/orchestration surfaces. Each change is a behavior-preserving pure move behind an unchanged public API.

File Before → After New modules
sdk/messaging/relaycast.ts 1654 → 1126 relaycast-translate.ts, relaycast-placement.ts, relaycast-client.ts
harness-driver/client.ts 1199 → 931 spawn-request.ts, broker-process.ts
cloud/workflows.ts 1129 → 893 workflow-paths.ts

The common thread: separate pure logic (wire↔domain translation, spawn-request shaping, workflow-path parsing) from the stateful/IO code (messaging client, broker-process client, cloud S3/API orchestrator). Public surfaces are preserved via re-exports, so consumers and tests are unaffected.

Per-file detail

  • relaycast.tsrelaycast-translate.ts (pure wire↔domain translation + record readers), relaycast-placement.ts (RelayPlacementError, placement payload helpers), relaycast-client.ts (structural relaycast adapter types, options, createRelaycastClient). Re-exports RelayPlacementError and RelaycastMessagingOptions. A follow-up commit also unexports the translate readers that don't cross a module boundary (review feedback).
  • harness-driver/client.tsspawn-request.ts (/api/spawn body builders + patch applier), broker-process.ts (managed broker child-process lifecycle: API-URL wait, stdio drain, recent-output buffering, startup-error formatting, shutdown). BrokerExitInfo moved and re-exported so the package barrel is unchanged.
  • cloud/workflows.tsworkflow-paths.ts (YAML path parser + TS literal scanner + parseWorkflowPaths/inferWorkflowFileType/shouldSyncCodeByDefault). Validation (which shells out), the runtime PATH_NAME_RE guard, GitHub-remote helpers, and all execution/API/S3 code stay behind; the three parser entry points are re-exported so the barrel and tests still import from ./workflows.js.

Verification (every step)

  • Build: npm run build:core green, 0 TS errors.
  • Tests: full vitest run959 passed / 5 skipped, identical to baseline throughout.
  • Live smoke tests: exercised the moved code through the built packages (SDK public surface + agents.list; harness-driver isProcessRunning/buffer-cap/spawn-body builders; cloud YAML+TS path parsing + re-export identity).
  • Independent autoreview on each diff (finder + verifier agents): all returned APPROVE / empty bug list — verbatim-move integrity, import hygiene, public-surface preservation, and no-import-cycle confirmed.

Notes

  • One reviewer flag was deliberately not acted on: merging the translate.ts record readers with normalize.ts's. They have genuine semantic divergence (normalize.readString coerces numbers→strings; readRecord clones) — consolidating would be a silent behavior change, not a refactor.
  • No CHANGELOG.md entry: these are internal module reorganizations with no user-visible effect.

🤖 Generated with Claude Code


Generated by Claude Code

Review in cubic

claude added 5 commits June 21, 2026 15:02
…ules

Decompose the 1654-line RelaycastMessagingClient file into single-
responsibility siblings behind an unchanged public surface:

- relaycast-translate.ts: pure wire<->domain translation and record readers
- relaycast-placement.ts: RelayPlacementError, placement payload helpers
- relaycast-client.ts: structural relaycast adapter types, options, factory

relaycast.ts (now 1126 lines) keeps the stateful client and re-exports
RelayPlacementError and RelaycastMessagingOptions so consumers are unaffected.
Pure move: no behavior change. Verified with build, full test suite (959
pass), and an SDK public-surface smoke test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPFXDfGA74hrgEBah6KTT2
…modules

Drop the export keyword on readRecord/readNumber/readBoolean/readStringArray/
readMention in relaycast-translate.ts — they are only used within the module.
asRecord, readStr, and definedOptions stay exported since relaycast.ts and
relaycast-client.ts consume them. No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPFXDfGA74hrgEBah6KTT2
…rocess

Decompose the 1199-line HarnessDriverClient file into two single-responsibility
siblings behind an unchanged public surface (client.ts now 931 lines):

- spawn-request.ts: spawn input -> broker /api/spawn request-body builders and
  the beforeAgentSpawn patch applier
- broker-process.ts: managed broker child-process lifecycle (API-URL wait,
  stdio drain, recent-output buffering, startup-error formatting, shutdown)

BrokerExitInfo moved into broker-process.ts and is re-exported from client.ts so
the package barrel surface is unchanged. Pure move: no behavior change. Verified
with build, full test suite (959 pass), and a harness-driver smoke test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPFXDfGA74hrgEBah6KTT2
Move the pure, side-effect-free workflow-path parsers out of workflows.ts
(1129 -> 893 lines) into a focused workflow-paths.ts module: the YAML path
parser, the TypeScript literal scanner, the parseWorkflowPaths dispatcher, and
inferWorkflowFileType / shouldSyncCodeByDefault.

Validation (validateYamlWorkflow / validateTypeScriptWorkflow, which shells out),
the runtime PATH_NAME_RE guard, GitHub-remote helpers, and the cloud
execution/API/S3 code stay in workflows.ts, which re-exports the three parser
entry points so the package barrel and tests still import them from
'./workflows.js'. Pure move: no behavior change. Verified with build, full test
suite (959 pass), and a parser smoke test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPFXDfGA74hrgEBah6KTT2
Move the trajectory from active/ to completed/ after wrapping up the SDK/
harness-driver/cloud god-file decompositions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPFXDfGA74hrgEBah6KTT2
@willwashburn willwashburn requested a review from khaliqgant as a code owner June 22, 2026 02:46
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c8d3d9c0-0e49-4e0d-8fdd-027d2778e1e9

📥 Commits

Reviewing files that changed from the base of the PR and between a3e1427 and 6f38382.

📒 Files selected for processing (3)
  • packages/cloud/src/workflow-paths.ts
  • packages/cloud/src/workflows.test.ts
  • packages/harness-driver/src/broker-process.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/harness-driver/src/broker-process.ts

📝 Walkthrough

Walkthrough

Three large TypeScript modules (cloud/workflows.ts, harness-driver/client.ts, sdk/messaging/relaycast.ts) are decomposed into dedicated single-responsibility sibling modules. Extracted code is re-imported and re-exported to preserve public API surfaces. Agent-workforce trajectory artifacts documenting the refactor are also added.

Changes

God-file decomposition across cloud, harness-driver, and sdk packages

Layer / File(s) Summary
cloud: workflow-paths extraction and delegation
packages/cloud/src/workflow-paths.ts, packages/cloud/src/workflows.ts, packages/cloud/src/workflows.test.ts
New workflow-paths.ts implements WorkflowPathDefinition type, YAML line-scanner with block-scalar support (|/>), TypeScript literal-scanner (bracket/brace matching with comment/quote handling), parseWorkflowPaths dispatcher, inferWorkflowFileType, and shouldSyncCodeByDefault. workflows.ts imports and re-exports those symbols, removing ~245 lines of inline parsing code. Tests extended with YAML block-scalar and TS comment-handling cases.
harness-driver: broker-process module extraction
packages/harness-driver/src/broker-process.ts
New broker-process.ts provides BrokerExitInfo/BrokerStartupDebugContext types, isProcessRunning (via process.kill(pid, 0) with EPERM handling), waitForApiUrl (readline-based URL detection with timeout and SIGTERM), drainBrokerStdioAfterStartup (no-op listeners), pushBufferedLine (rolling 40-line buffer), cloneBrokerExitInfo, formatBrokerStartupError (diagnostic message builder), and waitForExit (force-kills with SIGKILL on timeout).
harness-driver: spawn-request module extraction
packages/harness-driver/src/spawn-request.ts
New spawn-request.ts exports isBundledHeadlessCli type guard, resolveSpawnTransport (derives AgentTransport from SpawnCliInput), buildSpawnPtyBody and buildSpawnCliBody (broker /api/spawn JSON body builders with agentResultSchema coercion), and applySpawnPatch (selective in-place mutation of args/channels/task/model/team/agentToken/harnessConfig/spawnMode/exitAfterTask).
harness-driver: client.ts wiring after extraction
packages/harness-driver/src/client.ts
Removes the @agent-relay/sdk/actions import and inline BrokerExitInfo definition. Imports all helpers from broker-process.js and spawn-request.js, re-exports BrokerExitInfo as a type, adjusts ./protocol.js imports, and updates __clientTestInternals to source drainBrokerStdioAfterStartup from the extracted module.
sdk: relaycast-client and relaycast-placement new modules
packages/sdk/src/messaging/relaycast-client.ts, packages/sdk/src/messaging/relaycast-placement.ts
relaycast-client.ts defines RelaycastWorkspaceLike, RelaycastAgentLike, RelaycastMessagingOptions, delivery status/surface types, and createRelaycastClient (reuses injected client or constructs RelayCast with workspaceKey/apiKey validation and telemetry). relaycast-placement.ts defines PlacementReconcileReason, PlacementSelection discriminated union, RelayPlacementError class, placementActionInput with spawn CLI mismatch validation, and delay utility.
sdk: relaycast-translate stateless translation layer
packages/sdk/src/messaging/relaycast-translate.ts
New relaycast-translate.ts adds record-reader primitives (asRecord, readStr, readNum, readBool, readStrArray), Relay→Relaycast request mappers (register action, trigger, invocation completion), Relaycast wire→Relay domain converters (capabilities, nodes with status/repo coercion, triggers, fleet config, invocation acks, webhooks with camelCase/snake_case normalization), and option/attachment serialization utilities.
sdk: relaycast.ts wiring and re-exports after extraction
packages/sdk/src/messaging/relaycast.ts
Rewrites imports to pull createRelaycastClient, placement types/errors, and all translation helpers from sibling modules; updates ./types.js import list; removes ~566 lines of inline implementations; re-exports RelayPlacementError and RelaycastMessagingOptions to preserve the consumer-facing API surface.

Agent trajectory artifacts

Layer / File(s) Summary
Trajectory trace, summary, and decision log
.agentworkforce/trajectories/completed/2026-06/traj_q768ixcuyzh7.*
Adds traj_q768ixcuyzh7.trace.json (trajectory metadata and source file index with line ranges), summary.md (status, timestamps, refactor outcome, module decompositions, key decisions, work highlights, artifact commits), and trajectory.json (task record, decision entries, retrospective, filesChanged list) documenting the completed god-file decomposition.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

Possibly related PRs

  • AgentWorkforce/relay#1082: Overlaps directly with the new spawn-request.ts module — both touch agentResultSchema coercion logic and spawn body construction in harness-driver.
  • AgentWorkforce/relay#1108: Both modify packages/sdk/src/messaging/relaycast.ts — that PR added node/trigger APIs while this PR restructures the file into sibling modules.
  • AgentWorkforce/relay#1141: Directly overlaps with relaycast-placement.ts — that PR extends placement/spawn orchestration in the same messaging layer being refactored here.

Suggested reviewers

  • khaliqgant

Poem

🐇 Hop hop, the god-files grow too wide,
So rabbit split them, module by module inside!
workflow-paths hops free, broker-process takes flight,
relaycast-translate glows with pure, stateless light.
Re-exports keep the old paths intact and true —
One warren, many burrows, all fresh and new! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: decomposing three large TypeScript files into smaller, single-responsibility modules. It is concise, specific, and directly reflects the primary objective of the PR.
Description check ✅ Passed The description comprehensively covers the refactoring with a summary table, per-file details, thorough verification steps (build, tests, live smoke tests, autoreview), and important notes about reviewer feedback. It exceeds the basic template requirements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 claude/architecture-refactor-bftmcr

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cloud/src/workflow-paths.ts`:
- Around line 126-201: The functions extractPathArrayLiterals,
extractObjectLiterals, and readStringProperty scan raw source code without
skipping comments, which causes commented-out paths to be incorrectly extracted
as active workflow paths. Add comment-skipping logic to the scanner by creating
a helper function that identifies and skips single-line comments (starting with
//) and block comments (/* ... */), then integrate this helper into the
extraction functions propertyPattern and methodPattern execution loops in
extractPathArrayLiterals, and in the character-by-character scanning loops of
extractObjectLiterals and readStringProperty to ensure commented content is
never parsed as active declarations.
- Around line 52-67: The parser in the switch statement handling the key-value
pairs does not properly process YAML block scalars (indicated by | or >) for the
pushPrBody field. When a block scalar indicator like pushPrBody: | is
encountered, the code currently stores only the marker character instead of
collecting the subsequent indented lines. Modify the handling for the pushPrBody
case to detect when the value starts with | or > (block scalar indicators) and
if so, collect all following indented lines as the actual multi-line content
rather than storing just the marker. Apply the same fix to any other cases
mentioned at lines 117-119 that also handle multi-line content.

In `@packages/harness-driver/src/broker-process.ts`:
- Around line 176-189: The fast-path check in the waitForExit function only
checks if child.exitCode is not null to determine if the process has already
exited, but this misses processes that exited via signal where exitCode is null
and signalCode is not null. Update the condition to also check for
child.signalCode !== null so that processes that have already exited via signal
are detected immediately and the function can resolve without waiting for the
timeout, avoiding unnecessary SIGKILL attempts and shutdown latency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 46dc6c62-0bb3-4a0e-9463-a9862e05be94

📥 Commits

Reviewing files that changed from the base of the PR and between c7380ef and a3e1427.

📒 Files selected for processing (12)
  • .agentworkforce/trajectories/completed/2026-06/traj_q768ixcuyzh7.trace.json
  • .agentworkforce/trajectories/completed/2026-06/traj_q768ixcuyzh7/summary.md
  • .agentworkforce/trajectories/completed/2026-06/traj_q768ixcuyzh7/trajectory.json
  • packages/cloud/src/workflow-paths.ts
  • packages/cloud/src/workflows.ts
  • packages/harness-driver/src/broker-process.ts
  • packages/harness-driver/src/client.ts
  • packages/harness-driver/src/spawn-request.ts
  • packages/sdk/src/messaging/relaycast-client.ts
  • packages/sdk/src/messaging/relaycast-placement.ts
  • packages/sdk/src/messaging/relaycast-translate.ts
  • packages/sdk/src/messaging/relaycast.ts

Comment thread packages/cloud/src/workflow-paths.ts Outdated
Comment thread packages/cloud/src/workflow-paths.ts
Comment thread packages/harness-driver/src/broker-process.ts
- workflow-paths: parse YAML block scalars (`pushPrBody: |`/`>`) instead of
  storing just the marker, so multi-line PR bodies survive parsing.
- workflow-paths: strip TS comments before the literal scanner so commented-out
  `paths` declarations are no longer extracted and synced.
- broker-process: in waitForExit, treat a signal-killed child (exitCode null,
  signalCode set) as already exited to avoid a redundant SIGKILL/timeout wait.

Adds parser tests for block scalars, folded scalars, and commented-out paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtB14k7pSUoKwd5SgUj2Pc
@willwashburn willwashburn merged commit 82691d5 into main Jun 24, 2026
41 of 42 checks passed
@willwashburn willwashburn deleted the claude/architecture-refactor-bftmcr branch June 24, 2026 01:37
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.

2 participants