Extract shared dor/lib code into dor-lib-common#196
Merged
Conversation
dor and the lib agent-browser host each carried a near-identical copy of the hard-won Windows spawn recipe (cross-spawn for PATHEXT/.cmd, windowsHide, exit-vs-close with an exit-time output snapshot). Extract it once into a new dor-lib-common workspace package as spawnAndCapture, and collapse both helpers to thin adapters over it. Resolution respects the type-system split: dor avoids @types/node, and the lib host is esbuild-only (excluded from every tsc), so dor is the sole type-checking consumer. dor-lib-common's package exports point at its built dist — a clean, Node-type-free .d.ts for dor's tsc — while every esbuild/Vite consumer inlines it. dor's prebuild builds dor-lib-common first. Drops dor's hand-rolled cross-spawn/child_process ambient decls (no longer imports either) and both packages' direct cross-spawn dependency. The host test now mocks the dor-lib-common boundary; spawnAndCapture's own behavior is covered by dor-lib-common's tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dor (parseStreamPort) and the lib host (inline, inside readStreamPort) each
parsed `agent-browser stream status --json` with the same { port } | { data:
{ port } } shape — the host even noted it "Mirrors the parse in dor". Move it
to dor-lib-common as parseStreamPort and call it from both.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dor's sessionForKey (dormouse.<workspaceId>.<key>) and the lib host's generateGuiSession both hardcoded the dormouse.1. prefix — the host even noted it was "mirroring dor ab's namespacing." Move sessionForKey and the workspace id into dor-lib-common and call it from both; the host's GUI sessions become sessionForKey(`gui-<hex>`). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The eight surface.* control method strings were hardcoded on both sides of the wire: dor/src/control-client.ts emits them and lib's Wall.tsx dispatches on them, with no shared constant and no type safety — a rename had to be mirrored by hand. Add SURFACE_CONTROL_METHODS (and a SurfaceControlMethod union) to dor/protocol.ts, already the shared protocol module lib imports, and reference it from both the client and the webview handler. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dor and the lib host independently hardcoded the same agent-browser contracts: the DORMOUSE_AGENT_BROWSER_BIN override env var, the 'agent-browser' default binary name, and the ['--session', s, 'stream', 'status', '--json'] invocation that feeds the already-shared parseStreamPort. Move them to dor-lib-common as AGENT_BROWSER_BIN_ENV, DEFAULT_AGENT_BROWSER_BIN, and streamStatusArgs, and reference from both. Not unified: the binary-resolution algorithm itself stays per-package — dor stats PATH/PATHEXT, while the host resolves by spawning candidates because it can't trust the GUI login PATH. Only the shared constants move. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up cleanups on the dor-lib-common extraction: - Drop speculative barrel exports (AGENT_BROWSER_WORKSPACE_ID, the SpawnCaptureSuccess/Failure member types) that no consumer imports; make the workspace id module-private so callers go through sessionForKey. - Inline the single-caller spawnAgentBrowser adapter into runWithBinaryFallback, dropping the stringly-typed 'ENOENT' sentinel union. - Add incremental compilation to dor-lib-common's tsc so dor's prebuild doesn't fully recompile it on every build/watch. - Give lib a pretest that builds dor-lib-common, so the host test's importOriginal finds its dist on an isolated `pnpm --filter lib test`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
9a40e0b
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e7fd0db7.mouseterm.pages.dev |
| Branch Preview URL: | https://dor-lib-common.mouseterm.pages.dev |
dormouse-bot
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dor(the CLI) anddormouse-lib's agent-browser host had grown several copies of the same logic and contracts. This extracts them into one place so they can't drift.What moved
A new
dor-lib-commonworkspace package holds the code both packages genuinely share:spawnAndCapture— the hard-won Windows spawn recipe (cross-spawn for PATHEXT/.cmd,windowsHide, resolve-on-exit-with-grace + exit-time output snapshot). Was a ~30-line state machine duplicated in both; both call sites are now thin adapters.parseStreamPort—agent-browser stream status --jsonparsing ({port}|{data:{port}}).sessionForKey— thedormouse.<workspaceId>.<key>session namespace.streamStatusArgs+AGENT_BROWSER_BIN_ENV/DEFAULT_AGENT_BROWSER_BIN— the remaining shared agent-browser invocation/binary constants.Separately, the eight
surface.*control method names moved intodor/protocol.ts(already the shared protocol modulelibimports) asSURFACE_CONTROL_METHODS+ aSurfaceControlMethodunion — they were hardcoded on both the client (control-client.ts) and the webview handler (Wall.tsx) with no single source of truth.How resolution works
The key constraint:
dordeliberately avoids@types/node(hand-rolled ambients), and the lib host is esbuild-only (excluded from everytsc), sodoris the only type-checking consumer.dor-lib-common's packageexportstherefore point at its builtdist— a clean, Node-type-free.d.tsfordor'stsc— while every esbuild/Vite consumer inlines it.dor'sprebuild(andlib'spretest) build it first; resolution is a plainworkspace:*dependency, no per-bundler alias wiring.dorsheds its hand-rolledcross-spawn/child_processambients and both packages drop their directcross-spawndependency.Verification
dor-lib-common7/7,dor63/63, fulllibsuite 684/684, sidecar bundle, and thevscode-extesbuild + standalone Vite frontend bundles all build clean (the latter confirmsWall.tsx's new value import fromdor/protocolresolves end-to-end).🤖 Generated with Claude Code