Skip to content

chore: codebase cleanup pass (dedup, types, dead code, cycles)#420

Merged
thymikee merged 9 commits intomainfrom
chore/code-quality-cleanup
Apr 17, 2026
Merged

chore: codebase cleanup pass (dedup, types, dead code, cycles)#420
thymikee merged 9 commits intomainfrom
chore/code-quality-cleanup

Conversation

@thymikee
Copy link
Copy Markdown
Contributor

Summary

Mechanical code-quality pass delegated to six focused subagents, each reviewed and merged as a distinct commit. Every intermediate state and the final branch pass typecheck, lint, test (155 files / 1384 tests), test:smoke (8/8), and build. madge --circular drops from 44 cycles to 0.

Net lines: -566 across src/ (the circular-deps pass reshuffles ~500 lines into leaf modules; all other passes are net-negative).

Included passes (read as separate merge commits for easier review)

  1. Dead code removal — delete interaction-get.ts / interaction-is.ts / interaction-selector.ts (superseded by selector-runtime dispatchers); strip handleWaitCommand + private helpers from snapshot-wait.ts (replaced by dispatchWaitViaRuntime); remove unused rect-visibility helpers; trim unused Linux platform barrel re-exports. -568 lines, 6 files.
  2. DRY helper consolidation — single sleep() in utils/timeouts.ts (6 copies removed); use existing isApplePlatform() for ios || macos checks; merge duplicate normalizeType / trimRuntimeString. -42 lines, 15 files.
  3. Type consolidation — single owner for SnapshotDiffLine/SnapshotDiffSummary, FindLocator, JsonRpcRequestEnvelope/JsonRpcId, ClickButton (internal sites). No public SDK shape changes — duplicated types now re-export from the canonical home. 7 files.
  4. Strengthen weak types + bug fixas any casts on wire error codes replaced with a runtime-validated toAppErrorCode() helper. While converting, surfaced a real bug: session-open.ts emits DEVICE_IN_USE but it was missing from the AppErrorCode union, so the daemon→client round-trip silently downgraded it to COMMAND_FAILED. Clients can now react to same-device contention. Also: Metro worker payload, xctestrun plist, and runner-session parser now have proper types. 10 files.
  5. Comment cleanup — collapse 16 three-line catch { // ignore } blocks to catch {}. Specific comments that name a concrete failure mode (e.g. "ignore shutdown races") are kept. 9 files.
  6. Circular dependency elimination — resolve all 44 cycles reported by madge by extracting shared types into leaf modules and pointing both producer and consumer at the leaf; original modules re-export for API stability. New leaves: runtime-contract.ts, metro-types.ts, commands/runtime-types.ts, commands/diagnostics-types.ts, cli/commands/router-types.ts, core/interactor-types.ts, platforms/ios/runner-session-types.ts, utils/screenshot-diff-region-types.ts, daemon/handlers/record-trace-types.ts. No runtime behavior changes.

Passes attempted that produced zero changes

  • Defensive try/catch removal — every catch inspected serves a real purpose (boundary translation, read-or-null semantics, best-effort cleanup, narrow errno rethrow). No removals.
  • Legacy/deprecated code removal — every legacy marker is either documented public compat surface, wire-protocol fallback, or disk-format tolerance for older user state. No removals.

Test plan

  • pnpm typecheck — clean
  • pnpm lint — 0 warnings / 0 errors
  • pnpm test — 155 files / 1384 tests pass
  • pnpm test:smoke — 8/8 pass
  • pnpm build — succeeds (rslib)
  • pnpm dlx madge --circular --extensions ts src/ — 0 cycles (was 44)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3115ac6416

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const logPathOnFailure = flushDiagnosticsToSessionFile({ force: true }) ?? undefined;
const normalizedError = normalizeError(
new AppError(response.error.code as any, response.error.message, {
new AppError(toAppErrorCode(response.error.code), response.error.message, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve daemon-specific error codes during normalization

finalizeDaemonResponse now coerces handler error codes via toAppErrorCode(), which drops codes not in the AppErrorCode union. find still emits AMBIGUOUS_MATCH (src/daemon/handlers/find.ts), so ambiguous-find failures are now rewritten to COMMAND_FAILED before they reach clients. This removes a previously available signal that callers can use to handle ambiguity differently (for example, prompting to narrow selectors or retrying with --first/--last), so unknown daemon codes should be preserved or AMBIGUOUS_MATCH should be added to the accepted code set.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — fixed in 29a34a8. The narrower fix (just adding AMBIGUOUS_MATCH to the union) would have left the class-of-bug in place, so I widened the wire boundary instead:

  • AppErrorCode is now KnownAppErrorCode | (string & {}) — keeps IDE autocomplete of known codes while accepting any wire string
  • toAppErrorCode now preserves any non-empty code verbatim; fallback only kicks in for undefined/empty
  • Added AMBIGUOUS_MATCH to KnownAppErrorCode (it's documented at skills/agent-device/references/exploration.md:340, belongs on the autocomplete list)
  • Added test coverage: unknown codes are preserved, fallback is only used for missing/empty codes

No more silent downgrades for any future handler-emitted code.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 17, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstackincubator.github.io/agent-device/pr-preview/pr-420/

Built to branch gh-pages at 2026-04-17 11:13 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

- Delete interaction-get.ts, interaction-is.ts, interaction-selector.ts (superseded by selector-runtime dispatchers)
- Remove handleWaitCommand and its private helpers from snapshot-wait.ts (replaced by dispatchWaitViaRuntime)
- Remove unused distanceFromSafeViewportBand/isRectWithinSafeViewportBand from rect-visibility
- Trim Linux platform barrel to only the re-export still in use (snapshotLinux)
- Move sleep() to utils/timeouts.ts; remove 6 duplicate implementations
- Use existing isApplePlatform() helper for ios||macos checks (5 sites)
- Export trimRuntimeValue from runtime-hints; drop duplicate trimRuntimeString
- Merge normalizeTextSurfaceType/normalizeType into single text-surface helper
- Remove pointless isScrollableContainerType wrapper
- SnapshotDiffLine/Summary: single definition in utils/snapshot-diff, re-exported from capture-snapshot
- FindLocator: single definition in utils/finders, re-exported from client-types
- JsonRpc envelope in http-server now uses JsonRpcRequestEnvelope/JsonRpcId from contracts
- Inline 'primary'|'secondary'|'middle' literals replaced with ClickButton (internal sites only)
- Add toAppErrorCode() validator and DEVICE_IN_USE to AppErrorCode union
- Replace 'as any' casts on wire error codes with the validator (daemon-error, daemon-client, request-router, http-server)
- Type Metro worker payload as MetroTunnelResponseMessage
- Type xctestrun plist parsing with explicit partial schema
- Narrow 'details.stderr' via typeof checks on Android error paths
- Type runner-session parseRunnerResponse with RunnerResponsePayload

Bug fix: handler emitted 'DEVICE_IN_USE' but router cast silently downgraded to
'COMMAND_FAILED' because the code was missing from AppErrorCode. Clients can now
react to same-device contention.
- Replace 16 instances of 3-line catch { // ignore } with 1-line catch {}
- Remove one self-describing 'Re-export public API' comment

Specific 'ignore shutdown races' / 'ignore malformed pid files' style comments
that name concrete failure modes are kept.
…to leaves

Resolves all 44 cycles reported by madge. Pattern throughout: extract shared
type into a leaf module; both producer and consumer import from the leaf;
original module re-exports for API stability.

New leaf type modules:
- src/runtime-contract.ts (AgentDeviceRuntime, CommandContext, ...)
- src/metro-types.ts (MetroRuntimeHints, MetroBridgeResult, ...)
- src/commands/runtime-types.ts (CommandResult, RuntimeCommand, ...)
- src/commands/diagnostics-types.ts
- src/cli/commands/router-types.ts (ClientCommandParams, ...)
- src/core/interactor-types.ts (Interactor, BackMode, ...)
- src/platforms/ios/runner-session-types.ts (RunnerSession)
- src/utils/screenshot-diff-region-types.ts (MutableDiffRegion)
- src/daemon/handlers/record-trace-types.ts

madge --circular now reports 0 cycles (was 44). No runtime behavior changes.
The initial weak-types pass validated wire error codes against a closed
union, silently downgrading any unknown code to COMMAND_FAILED. This
dropped signals like AMBIGUOUS_MATCH that handlers emit and clients are
documented to handle (skills/agent-device/references/exploration.md).

- Widen AppErrorCode to 'KnownAppErrorCode | (string & {})' so autocomplete
  of known codes is preserved while any wire code flows through
- toAppErrorCode now preserves any non-empty code; fallback only when
  undefined or empty
- Add AMBIGUOUS_MATCH to KnownAppErrorCode (documented public code)
- Add test coverage for preservation and fallback behavior
- Add DEVICE_IN_USE to the batch error taxonomy in exploration.md (now
  observable by clients after earlier fix, needs agent-facing guidance)
- Delete one-line src/platforms/linux/index.ts barrel; both consumers
  (core/dispatch, daemon/handlers/snapshot-capture) now import from
  platforms/linux/snapshot directly
- Replace inline { tenantId; runId; leaseId } shapes with MetroBridgeScope
  alias at client-types, metro, and cli/commands/connection-runtime
- Consolidate remaining inline setTimeout wrappers onto utils/timeouts.ts#sleep
  (12 files, ~18 sites). Left test files and the runtime-clock aware helper
  in commands/selector-read-utils alone. Also removes the local sleepMs
  helper from daemon-client.ts.
- daemon-client RPC error path: stringify any non-null data.code instead
  of only forwarding strings. Preserves numeric codes from hypothetical
  future proxies/servers; for first-party daemon today this is a no-op
  since handlers already emit strings.
- errors.ts: expand AppErrorCode comment to call out the exhaustiveness
  tradeoff of the '(string & {})' widening for SDK consumers.
@thymikee thymikee force-pushed the chore/code-quality-cleanup branch from bba4d9f to 47c70c4 Compare April 17, 2026 11:12
@thymikee thymikee merged commit 33083b5 into main Apr 17, 2026
15 checks passed
@thymikee thymikee deleted the chore/code-quality-cleanup branch April 17, 2026 11:22
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