Commit bc56fa7
authored
refactor(5/12): change handler contract to event-based emission (#323)
## Summary
This is **PR 5 of 12** in a stacked PR series that decouples the rendering pipeline from MCP transport. Depends on PR 4 (utility extraction). This is the most architecturally significant PR in the stack -- it changes the fundamental contract between tool handlers and the runtime.
### The contract change
**Before**: Tool handlers returned a `ToolResponse` object containing pre-rendered MCP content:
\`\`\`typescript
handler: (params) => Promise<ToolResponse>
\`\`\`
**After**: Tool handlers receive a context object and emit events through it, returning nothing:
\`\`\`typescript
handler: (params, ctx: ToolHandlerContext) => Promise<void>
\`\`\`
The `ToolHandlerContext` provides:
- `emit(event: PipelineEvent)`: Push a structured event into the render session
- `attach(image: ImageAttachment)`: Attach binary content (screenshots)
This decouples tools from rendering entirely. A tool says "the build succeeded" via `ctx.emit(statusLine('success', 'Build succeeded'))` without knowing whether the output will be rendered as colored terminal text, JSON, or MCP protocol content.
### Tool invoker refactor
The invoker (`tool-invoker.ts`) is significantly simplified:
- Deleted `postProcessToolResponse`, `emitNextStepsEvent`, `renderNextStepsIntoContent`, `finalizeResult`
- The invoker creates a `ToolHandlerContext`, passes it to the handler, then emits next-steps into the same render session after the handler completes
- No more `PendingBuildResult` pattern -- the handler just awaits the pipeline and the render session accumulates events progressively
### Typed tool factory
`typed-tool-factory.ts` updated to produce handlers matching the new signature. Session-aware wrappers now thread the context through.
### Core manifest and schema
- `import-resource-module.ts` added for resource manifest loading (split from tool module loading)
- Schema and load-manifest updated for the simplified handler contract
- `plugin-types.ts` updated to reflect new handler signatures
### Deleted
- `typed-tool-factory-consolidation.test.ts` (tested removed consolidation logic)
- `load-manifest.test.ts` (moved to schema test coverage)
## Stack navigation
- PR 1-4/12: Foundation and utility extraction
- **PR 5/12** (this PR): Runtime handler contract and tool invoker
- PR 6-9/12: Tool migrations (mechanical -- update handlers to use `ctx.emit`)
- PR 10-12/12: Boundaries, config, tests
### Note for reviewers
PRs 6-9 (tool migrations) depend on this contract change. Each tool handler is updated from `return toolResponse([...])` to `ctx.emit(...)` calls. Those are mechanical transformations but they cannot compile without this PR landing first. If reviewing the stack incrementally, this PR is the critical design decision point.
## Test plan
- [ ] `npx vitest run` passes -- invoker tests updated for new contract
- [ ] Handler context correctly propagates emit/attach to render session
- [ ] Next-steps are emitted into the render session after handler completion
- [ ] Typed tool factory produces handlers with correct signatures1 parent 8ad1a78 commit bc56fa7
File tree
26 files changed
+1157
-1444
lines changed- src
- core
- manifest
- __tests__
- mcp/tools
- coverage
- macos
- simulator
- runtime
- __tests__
- types
- utils
- __tests__
- responses
26 files changed
+1157
-1444
lines changedThis file was deleted.
0 commit comments