v0.9.8: finish the assigned cut - #5407
Conversation
Give direct, non-detached agent starts a turn-owned cancellation barrier. On turn end, cancel and await those children before sealing mailbox delivery; explicit detached starts retain an independent runtime token and manager visibility. Make terminal closure an explicit engine barrier so the ordering is testable: foreground children settle before the mailbox flush that precedes TurnComplete. Cover default ownership, explicit detachment, late registration, concurrent cancellation, task-future return and panic unwind, and terminal-barrier ordering.
Reject successful compaction responses that contain no usable handoff text, retry once with a conservative prompt, and fail before constructing a replacement checkpoint when the retry remains unusable. Keep the validation language-neutral, account every billed response, and report quality retries cumulatively alongside transient retries. Cover empty, punctuation-only, placeholder, non-text, multilingual, and mixed retry paths.
Apply the shipped CWC Blue Stage palette, compact rail, transcript, and composer grammar to the Rust-embedded browser client while preserving its existing Runtime authority and interaction model. Serve the canonical Codewhale mark as an embedded asset, keep noisy MCP transport diagnostics behind a compact receipt, and cover both the asset route and receipt presentation.
The embedded browser client hid the custom-answer field whenever the legacy allow_free_text hint was false, even though the terminal intentionally keeps Other available for every question. It could also submit two answers to a single-select question or post a stale card through the newly selected thread id. Always expose the custom response, make radio and custom input mutually exclusive, validate the exact answer payload, and bind submission to the selected live thread plus its pending request. The dependency-free suite covers custom, single-select, forged, stale-session, and stale-thread cases. Verified: node --check and 20/20 runtime web client tests. Agent-assisted work; nothing published.
After the browser detected an SSE continuity gap it loaded a replacement thread snapshot and resubscribed successfully, but kept streamGap set forever. The next rendered event therefore restored the error indicator even though continuity had been recovered. Clear the surfaced gap only after recoverProjection successfully loads the replacement snapshot and subscribes, and pin that ordering in the dependency-free client suite. Verified: node --check and 21/21 runtime web client tests. Agent-assisted work; nothing published.
The OS browser opener can spawn successfully without opening a tab, and a hard opener failure currently shuts down an otherwise healthy local Runtime. In both cases the one-time bootstrap URL is unavailable to the person running Codewhale. Print the loopback-only single-use URL, extend its bounded lifetime from two to ten minutes, and keep the server alive when automatic opening fails. Update the local web and Runtime API contracts to describe the terminal capability and recovery path. Verified: rustfmt --check on the touched Rust modules; dependency-free web suite 21/21. Agent-assisted work; nothing published.
Update the dependency-free palette contract to assert the CWC blue-stage user bubble introduced by the local web restyle. The semantic action, attention, status, and connection colors remain independently covered.
Require the canonical action on model-facing agent calls so action-dependent requirements always activate and an empty object no longer passes schema validation before failing at runtime. Keep the missing-action parser default for stored and programmatic legacy calls. Validate the canonical, generic, Responses-compatible, and Kimi/Moonshot forms with the real Draft 2020-12 validator. The wording reduction leaves each measured tool-catalog surface three bytes smaller, with no token-estimate increase. Agent-assisted work.
Move the conversation onto the canonical Blue Stage and flatten receipts into the quiet CWC row grammar. Make the mobile rail a real modal drawer, publish visual-viewport sizing and touch targets, and retain the runtime-owned model, mode, and permission facts on narrow screens. Keyed transcript and attention reconciliation now preserves disclosures, focus, form state, and text selection while live events arrive. New attention is announced and focused instead of being silently redrawn. Verified with both embedded web Node suites, the focused Vitest suite, node syntax validation, rustfmt, and diff checks.
Restrict the conversation log to announcing newly added rows. Streaming token updates still preserve the keyed message node, but no longer make every text mutation ARIA-relevant and repeatedly re-announce the growing response. Verified with node syntax validation, the 25-test embedded web client suite, and diff checks.
Reject Unicode punctuation and known placeholder compaction responses, keep event continuity surfaced until a replacement stream opens, and prove browser launcher failure leaves the local Runtime available for manual bootstrap.
Recognize the exact Ollama Cloud OpenAI-compatible endpoint as first-party so saved and ambient Ollama credentials resolve there while localhost remains keyless. Keep every neighboring remote URL custom and fail closed against inherited official credentials. Align TUI readiness, provider picker, Fleet preflight, doctor classification, and credential guidance with that route boundary, with focused tests and docs.
Distinguish Ollama Cloud from the local keyless runtime across config, routing, receipts, billing, readiness, inventory, and provider UX. Migrate only the exact released ollama + https://ollama.com/v1 tuple in memory, with a bounded read-only fallback to the legacy secret slot. Keep Cloud on the authenticated OpenAI-compatible /v1 chat wire and add deterministic regressions for route, credential, locality, and Fleet boundaries.
Keep released Ollama Cloud routes bound to their legacy provider table and credential slot through Fleet, session, and nested subagent resolution. Keep explicit ollama-cloud routes first-class, retain the full reasoning ladder, and document the compatibility boundary.
The TUI settled on 宪章 for Simplified Chinese in cf08cb6, and zh_hans_constitution_copy_uses_charter_term in localization.rs keeps it that way: 宪法 is a banned literal in the zh-Hans pack. The website never followed, so the same feature reads as 宪章 in the TUI and 宪法 on codewhale.net — including the copy that walks a new user from the site into setup. Replace all 15 occurrences across the four files that carry them: constitution/page.tsx, docs/constitution/page.tsx, docs-map.ts and content/getting-started.ts. The compound forms line up with the pack that is already shipping: 用户全局宪章 and 内置宪章 match the SetupCheckpointLayerOrder wording in zh-Hans.json. Copy only; no structural or English-side changes. Discussed in #4949. Analysis drafted with local tooling; every change and test verified by hand. Signed-off-by: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com>
brew tap Hmbown/deepseek-tui && brew install codewhale is the install path. The legacy deepseek-tui formula stays a deprecated alias for one overlap release. TAP_REPO is unchanged.
Harvested from #5398 and corrected: the website 44 includes Google and Ollama Cloud, and still excludes DeepseekCN, Custom, and Antigravity until the cloud-code wire is a first-class advertised outbound route.
[workshop] read_result_max_bytes and tool_result_max_bytes raise the model-visible floor and never lower the compile-time defaults. Hard cap is 2MiB (#5367).
Provider setup S fills the published token.sensenova.cn/v1 host (#5350). OpenCode Zen/Go stay first-class rows. Agnes has no published URL, so it has no preset.
… down A 503 from the control plane no longer leaves DeepSeek V4 Flash/Pro on those routes stuck at unverified_live_pricing (#5241). kimi-k3 stays unpriced until a published rate exists.
…-code DeepSeek Flash on macOS was turning HTTP/2 DATA splits into U+FFFD (#5374). Lines are now strict UTF-8. The same client speaks a text-only /v1internal:streamGenerateContent path for agy after consent (#5085). Tools, images, and unknown SSE shapes fail closed. Gemini 3.7 Flash is not advertised until a live turn succeeds; the website 44 still excludes Antigravity.
The website public-surface contract requires a dated 0.9.8 section to say the product name and version before the cut can go green.
Collapse let-chains, drop an unused Gemini 3.7 constant from lib builds, and allow the two existing 8-argument helpers so the workspace clippy gate can go green.
The agent tool copy now leads with action=start, and the write-scope test was loading host fleet profiles that pin zai. Isolate CODEWHALE_HOME so the fail-closed contract is what gets measured.
Keep this lane's full-width session-shell PTY comments. origin/main only added #5400 comment wording; the geometry identity is the same.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Claude finished @Hmbown's task in 1m 22s —— View job Reviewing PR #5407: v0.9.8 finish
Running parallel review passes over: (1) provider/model/route safety + client code, (2) TUI engine/compaction/fleet/subagent, (3) CLI/release/scripts/secrets, (4) web/runtime_web UI. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 96f802b87f
ℹ️ 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".
| let mut contents = Vec::new(); | ||
| for message in &request.messages { |
There was a problem hiding this comment.
Preserve the system prompt on cloud-code requests
Whenever the engine sends a text-only Antigravity turn, turn_loop.rs places the session constitution in MessageRequest.system, but this serializer reads only request.messages and never adds the system blocks to the cloud-code body. The request therefore succeeds without Codewhale's sole base prompt; serialize the system instruction using a proven wire shape, or fail closed when it is present rather than silently discarding it.
AGENTS.md reference: AGENTS.md:L73-L77
Useful? React with 👍 / 👎.
| Paragraph::new(Line::from(Span::styled( | ||
| "OpenAI-compatible endpoint. Store an env var name here, not a raw key.", | ||
| "OpenAI-compatible endpoint. Store an env var name, not a raw key. OpenCode Zen/Go are first-class rows. SenseNova: S. Agnes has no published URL.", | ||
| Style::default().fg(palette::TEXT_MUTED), | ||
| ))) |
There was a problem hiding this comment.
Localize the new custom-provider guidance
When the TUI locale is Chinese, opening the custom-provider form still renders this newly added English paragraph verbatim because it bypasses tr(locale, MessageId::…). Add the corresponding message ID and locale entries instead of embedding the copy in the renderer.
AGENTS.md reference: crates/tui/AGENTS.md:L36-L41
Useful? React with 👍 / 👎.
| impl WorkshopConfig { | ||
| /// Install the process-wide workshop budgets used by read/tool compactors. | ||
| pub fn install_active(config: Option<&Self>) { | ||
| let snapshot = config.cloned().unwrap_or_default(); | ||
| if let Ok(mut slot) = active_workshop_slot().lock() { | ||
| *slot = snapshot; |
There was a problem hiding this comment.
Install workshop budgets for server-created engines
For serve --http and serve --web, runtime threads receive cfg.workshop in EngineConfig, but those paths never call WorkshopConfig::install_active; the only installers are the interactive TUI frame builder and run_exec_agent. Because the new read and tool-result limit helpers consult this process-wide slot rather than the engine's config, both documented byte ceilings silently remain at their defaults for every server-created thread. Install the configuration from the server/runtime-engine path or resolve these limits from per-engine state.
Useful? React with 👍 / 👎.
Configurable read/tool-result ceilings grew every production tool surface by 371 schema bytes / 93 estimated tokens. Explicit maintainer raise so the v0.9.8 land can pass Lint. Identities unchanged.
|
Claude finished @Hmbown's task in 1m 26s —— View job Reviewing PR #5407: v0.9.8 finish
Four parallel passes in flight:
|
/plugin show already prints "/plugin trust demo", so wait_for_text returned immediately and Enter scrolled the pager. Wait on the composer/cursor band instead, and parse the review token past the scrollbar glyph. Local cucumber plugin_toml_binary_lifecycle now passes in 8.91s (was 24.99s timeout on review confirmation).
|
Claude finished @Hmbown's task in 1m 24s —— View job Reviewing PR #5407: v0.9.8 finish
Running parallel review passes over: (1) client/provider/route safety incl. new |
tiny_http read_to_string waited for EOF, so reqwest HTTP/1.1 keep-alive on macos-latest never finished the first chat POST (~80s). Read Content-Length only, send Connection: close, and rejoin wrapped /plugin trust tokens. Harvested from cursor/macos-plugin-e2e-keepalive-206d. Local: keepalive, wrap, and acceptance tests passed in 7.85s.
|
Claude finished @Hmbown's task in 1m 29s —— View job Reviewing PR #5407: v0.9.8 finish
Four parallel review passes in flight:
|
finish_reason=length now continues the headless loop (no default max-turns), so the persist-service failure case spun until the 120s wait. content_filter is still an incomplete non-limit stop and kills the pending service. Local exec_persistent_service: 3 passed in 6.14s.
|
Claude finished @Hmbown's task in 2m 54s —— View job Reviewing PR #5407: v0.9.8 finish
Confirmed all three Codex bot findings by reading the actual code paths (not just trusting the bot):
Three parallel passes now in flight over the rest of the diff:
|

Summary
codex/v098-final-20260814onto main.d30effc82492704caa1b00c342e032703427cead(this lane), never5ac75add4.Test plan
target-verify(fmt/check/clippy/web/crates dry-run/release build/npm smoke)design-qa.md= passed)No-Issue: release-cut source land; Homebrew #5357 and npm #5299 close after their publish jobs, not this merge.