The previous #runSerialized waited on the shared #dispatchTail, then ran
unconditionally: when two or more events queued behind an in-flight run,
each resumed from the same settled await and started its own run in
parallel, defeating the ordering guarantee for a burst landing in one
coalescing window (message_end + agent_end behind a suspended flush).
Each waiter now chains its own link onto the current tail
(tail.then(run, run)), so queued runs start strictly one after another;
the idle path still runs synchronously, preserving the flush timing the
coalescing tests assert on. The in-flight flag clears only when the
settling link is still the tail, so a later chained link's settle does
not clear it early.
Regression test: two message_end events queued behind a suspended window
flush stay serialized (init call count steps 1 -> 2 -> 3 as each gate
opens); fails on the previous implementation.
The Claude/Cursor/Gemini/Windsurf importers appended user entries before
project entries, so a project `enabled: false` could not claim its dedupe key
ahead of a same-named user server and the disable was silently ignored. Load
project entries first, matching the native/Codex loaders, so a project disable
suppresses a same-named user server.
Updated docs/mcp-config.md to reflect the project-first precedence and added
compound regression coverage.
Fixes#7652
Set HOME and os.homedir() to a dedicated temporary directory for each translated-provider fixture, then restore both after every test. This prevents real user MCP configs from shadowing the project fixture through capability deduplication.
Python/Ruby raise on the removed keyword via their keyword-only
signatures; the Julia helper's kwargs... catch-all silently swallowed
agent("..."; model="default") and forwarded it to the bridge, where
the "+": "delete" strip discarded it. A caller could keep thinking a
model override was honored. Reject model loudly, matching the strict
removal decision on #7621.
The Claude Code, Cursor, Gemini CLI, Windsurf, and VS Code importers built
their canonical MCPServer object without mapping serverConfig.enabled, so a
server declared with "enabled": false stayed undefined and the central
suppressServer filter never fired. Only disabledServers masked the gap.
Map the field in each importer, mirroring opencode.ts and codex.ts, and add
a table-driven regression test across all five importers.
Fixes#7652
AgentSession.#emit fires listeners fire-and-forget, and the coalesced
message_update flush fires from its own 33ms timer — neither path awaited
the other. A rapid stream tail (message_update -> message_end ->
agent_end) could therefore run the end handlers while the flush was
suspended mid-await, agent_end removing streamingComponent before
#handleMessageEnd finalizes and records the final message (issue #7443
follow-up).
- #runSerialized chains listener dispatch and the timer flush through one
promise chain; an in-flight run holds later events until it completes.
Idle dispatch stays synchronous (no added microtask), preserving the
timing the coalescing tests assert on.
- Regression test: a message_end landing while the window flush is
suspended on init is queued behind it (initCalls 1 while suspended,
then 2), where the pristine code ran both concurrently (2 while
suspended). Fails without the fix.
Wave-3 review finding on #7586:
- scripts/release.test.ts ran in neither CI nor the documented root
command, so the release-version regression assertions guarded nothing
- add it to test:scripts and invoke that file from the workspace job
- the job deliberately does not run all of test:scripts: musl-release
fails on main, so the whole group would red this job on an unrelated
break
Review findings on #7586:
- validate an explicit release version before comparing; the shared
comparator never throws, so 999.bad previously reached every manifest
- ci-release-notes imports the comparator by relative path: the
release_github job runs without bun install
- route Bun cache pruning through compareVersions and delete
compareSemverLikeVersions
- regression test for the release-version guard
Per-event stdout writes in --mode json (and text) were fire-and-forget
and relied on an empty-write flush barrier before dispose/exit. The
barrier awaited its own callback, not the preceding large write, so a
big final agent_end could be truncated when the process exited before
the pipe drained -- while still exiting 0.
Serialize every print-mode stdout write on its own completion callback
(honoring backpressure) and block shutdown on the tail so the terminal
record is delivered in full.
Fixes#7635
Threaded the loopback hostname returned by startServer through the omp stats CLI and /stats slash command so the browser and logged URL target the actual listener instead of localhost.
Fixes#7633
Added the no-op setter to lightweight print-mode session mocks so text-mode runs without a submitted prompt no longer throw at the final commit call.
Fixes#7625
Made text replay safety depend on whether the active output sink has committed streamed text.
Kept tool calls, images, and server tools replay-unsafe while covering text and JSON print policies plus a transient socket-close recovery.
Fixes#7625
Completes the maintainer's removal of per-call model selection from
subagent spawns (9f8aa87dbf removed it from the task tool and the
model-facing agent() docs/prompt, but the eval agent() runtime and all
four preludes still accepted and forwarded a per-call model).
Subagents now always resolve through the selected agent's frontmatter
model and settings, so an explicit model: "default" can no longer
silently route children onto the parent session model.
- agent-bridge: drops "model?" from agentArgsSchema and the request
forward; adds "+": "delete" so a legacy model argument is stripped
(same contract as the task wire schemas).
- JS/Python/Ruby/Julia preludes: remove the model parameter from
agent(); completion()'s tier selector is unchanged.
- docs (tools/eval.md, python-repl.md) updated to the removed surface.
Refs #6438