Skip to content

Adopt Effect across the codebase #24

Description

@oveddan

Adopt Effect across the codebase. Split out of #23, which deliberately kept the MCP server migration in plain TypeScript so the two changes stay reviewable on their own.

Why here

This code is mostly the kind of thing Effect models well, and currently hand-rolls:

  • Timeouts and retries. exportConfiguration threads timeoutMs / retries through every pull, and discovery sleeps timeoutMs per MIDI output.
  • Resource cleanup. Every path that opens MIDI ports closes them in a finally; discovery opens every input at once. These become scoped resources that close even on interruption.
  • Serialization. The MCP server's device lock is a hand-written promise queue; a semaphore replaces it.
  • Typed failures. Errors are plain Error strings today. Apply in particular has outcomes (failed vs unknown after send, stale snapshot, identity mismatch) that callers must treat differently and currently tell apart by message.

Suggested order

  1. MIDI backend and discovery: scoped ports, timeouts.
  2. Exporter: retries and timeouts as schedules instead of parameters.
  3. MCP server: semaphore for the device lock; tool handlers run Effects at the edge.
  4. Applier and journal, once Close the apply boundary: forgeable eligibility, replayable plans, cwd-relative state #14 lands, with typed apply outcomes.

Open questions

  • Replace zod with effect/Schema? The MCP SDK accepts any Standard Schema, so tool inputs don't force zod.
  • Bundle-size and startup cost for npx -y mft-config mcp, which starts on every agent session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions