Commit Graph

3405 Commits

Author SHA1 Message Date
Peter Steinberger 6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
Peter Steinberger 2b18ef7426 feat(codex): surface native questions and goals (#109724)
* feat(codex): bridge native questions and goals

Co-authored-by: EVA <eva@100yen.org>

* fix(ui): preserve native question text encoding

* fix(codex): keep secret answers off action paths

* fix(codex): validate native action keys exactly

* fix(codex): isolate new goals and free-form answers

* style(codex): satisfy extension lint

* fix(codex): keep goal replacement non-destructive

* fix(codex): separate native goals from continuation

* fix(codex): preserve exact native answer labels

* test(codex): assert goal continuation stays disabled

* fix(codex): remove unused bridge exports

* test(codex): refresh goal feature snapshots

---------

Co-authored-by: EVA <eva@100yen.org>
2026-07-17 00:35:39 -07:00
ooiuuii fbfad6eb42 feat(codex): show answer candidates in Activity (#90610)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:58:16 -07:00
Peter Steinberger a838c68dbe feat(talk): add Gemini Live video (#109719)
Stream bounded browser camera frames directly to Gemini Live and keep camera media off the Gateway. Add lifecycle, function-calling, fake-camera E2E, and live-smoke coverage.

Co-authored-by: shushushu <1064076525@qq.com>
2026-07-16 23:55:06 -07:00
Peter Steinberger 9d3389008d feat(ui): unify sidebar scrolling, move new-thread to brand row, keep Mac titlebar search (#109694)
* feat(ui): unify sidebar scrolling, move new-thread to brand row, keep Mac titlebar search

- Sidebar body is now the single scroller (nav + sessions); brand row and
  footer stay pinned, scroll fades move to the body, and the thumb sits
  flush against the resize divider via a shared --sidebar-pad-x inset.
- New-thread button moves next to search in the brand row; the Sessions
  header keeps only sort. Agent-chip plus stays (agent-scoped).
- macOS web-chrome hosts show search + new-thread in the titlebar
  permanently; the brand-row copies hide only while that strip is visible
  (compact drawers keep them).
- Update card slims to a single-line pill.

Ref: sidebar UX feedback (scroll inset, pinned nav, button placement).

* fix(ui): refresh i18n raw-copy baseline for slim update pill separator
2026-07-16 23:50:33 -07:00
Peter Steinberger 883995f08d test: stabilize flaky tests at root cause (batch 2) and fix the isolate:false cleanup hole (#109653)
* test: stabilize four flaky tests at root cause

- test/non-isolated-runner.ts: move shared-worker cleanup from onAfterRunSuite
  to onAfterRunFiles. Vitest early-returns runSuite for files that fail during
  collection, skipping onAfterRunSuite, so a crashed sibling left its evaluated
  real modules cached and the next file's vi.mock factories silently never
  applied — the "res.setHeader is not a function" failures in
  http-utils.authorize-request.test.ts. onAfterRunFiles fires per file
  regardless of collect/run outcome. Regression meta-test spawns a child
  vitest run (collect-crash sibling + mock-dependent file) and fails on the
  old runner with flavor:real vs flavor:mocked.
- src/gateway/http-utils.authorize-request.test.ts: export every http-common
  binding http-auth-utils imports so the factory stays isolate:false-safe.
- src/gateway/session-message-events.test.ts: drop the beforeAll 60s override;
  the suite harness cold-imports the full gateway server graph, which can
  legitimately exceed 60s under contention. Sibling suites use the shared
  project hookTimeout (120s/180s) for the same boot.
- src/gateway/server-methods/agent.sessions-and-models.test-utils.ts: the
  finalize-throw test polled a 2s waitForAssertion for an off-turn background
  run; signal finalize via a promise resolved from the spy (event-driven,
  bounded by the test timeout) and keep the bounded poll for the follow-up
  respond/warn observations.
- ui/src/pages/chat/chat-responsive.browser.test.ts: budget cold-app first
  renders at 30s (real-app cases boot a cold Vite dev server whose first
  transform can starve past 10s under 6-worker contention) and replace
  one-shot isVisible reads with bounded locator waits for the state-driven
  hover reveal.

Proof: focused runs green; 5x repeats of the three gateway files and 5x
repeats of chat-responsive with OPENCLAW_VITEST_MAX_WORKERS=6 all green;
runner regression test fails pre-fix, passes post-fix.

* test: isolate runner meta-test child env from GitHub Actions

The child vitest inherited GITHUB_ACTIONS/CI from the runner job, which
turned on ANSI colors (breaking the plain-substring assertions) and let
the child's github-actions reporter emit ::error annotations the parent
job rendered as its own failures. Drop GITHUB_ACTIONS/FORCE_COLOR and set
NO_COLOR, which overrides every tinyrainbow enable path.

* test: wait for parseable pid in tsdown-build pid-file polls

waitForFile existence polling can catch writeFileSync's open-truncate
0-byte window, yielding NaN pids and false isProcessAlive failures (the
same class as #109140). Poll until the file parses to a positive pid;
covers all three sibling pid-read sites in the suite.
2026-07-16 22:18:16 -07:00
openclaw-mantis[bot] 6b608ceae1 chore(ui): refresh control ui locales (#109633)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-16 22:04:25 -07:00
Peter Steinberger 7be5d78fd0 feat(workspaces): add full-bleed single-widget tabs (#109627)
* feat(workspaces): add full-bleed app tabs

* fix(workspaces): harden full-bleed rendering

* fix(workspaces): eliminate full-bleed iframe gap

* fix(workspaces): keep tab layout type internal

---------

Co-authored-by: Eva <eva@100yen.org>
2026-07-16 21:56:57 -07:00
Peter Steinberger b1ef4265ea feat(ui): make sidebar catalog project groups collapsible (#109648)
Project group heads in the native session catalogs (Codex + Claude) are now
collapse toggles: chevron + aria-expanded, rows hidden while the head and
count stay visible. State persists per catalog+host+project through the
existing collapsed-sections localStorage set. Follow-up to #109575.
2026-07-16 21:49:57 -07:00
Peter Steinberger 9ce8ac94b9 feat(ui): fold the mobile navigation row into the chat title bar (#109635)
* feat(ui): fold the mobile navigation row into the chat title bar

On plain-browser mobile layouts the chat route drops the 58px shell topbar;
the pane title bar gains a leading nav-drawer toggle and a trailing
command-palette search button (~50px more chat). The shared mobile-nav
breakpoint moves into one module used by shell and chat; native shells and
non-chat routes keep today's chrome.

* improve(ui): anchor the workspace chip right after the session title

The chip now hugs the title text with the header's standard gap instead of
sitting at the far right; the action cluster claims the leftover width and
stays right-pinned. Where field-sizing is supported the rename input hugs
its text too, so the chip tracks the title while typing.

* chore(ui): keep hasNativeShellClass module-local
2026-07-16 21:44:29 -07:00
Peter Steinberger a0fac37f14 feat: add OpenAI Video Talk (#109579)
* feat(talk): add OpenAI Video Talk

Co-authored-by: wuxuanshu <1064076525@qq.com>

* fix(protocol): refresh native Talk capability model

* chore(i18n): refresh control UI fallback baseline

* chore(i18n): defer locale refresh to workflow

---------

Co-authored-by: wuxuanshu <1064076525@qq.com>
2026-07-16 21:25:09 -07:00
Peter Steinberger 61bec3a2de fix(ui): follow Gateway queue mode for active-run messages (#109441)
* fix(ui): inherit Gateway queue mode for follow-ups

* fix(ui): honor session queue overrides

* fix(ui): preserve Gateway follow-up semantics

* fix(ui): retain pane queue mode ownership

* fix(ui): keep Gateway queue policy authoritative

* chore(ui): leave locale refresh to workflow

* fix(ui): keep unresolved follow-ups neutral

* refactor(ui): isolate session queue projection
2026-07-16 20:59:11 -07:00
Peter Steinberger dad377cb1f feat(ui): group native session catalog rows by project in the sidebar (#109575)
* feat(ui): group native session catalog rows by project in the sidebar

Codex and Claude session catalogs in the Control UI sidebar now group each
host's sessions by project folder, mirroring Claude Code desktop: any cwd at
or under <repo>/.claude/worktrees/<name> folds into the origin repo. A folder
toggle icon in the catalog header flattens the list; grouping defaults to on
and persists via localStorage (openclaw:sidebar:sessions:catalog-grouping).

* chore(ui): drop generated i18n fallback metadata from source PR

Post-rebase main forbids catalog fallback metadata in source PRs; the
post-merge locale-refresh workflow reconciles foreign catalog parity.

* chore(ui): keep CatalogProjectGroup type module-local

knip dead-export gate: no external importers; callers rely on the inferred
return shape of groupCatalogSessionsByProject.

* test(scripts): drop retired workspace-state.json expectation

Opportunistic CI fix: b6535fb8de5/905395a3ff5 retired workspace-state
seeding from scripts/e2e/parallels/agent-workspace.ts but the smoke-model
test still asserted the removed string, breaking checks-node-compact-small-2
on every branch.

* test(scripts): restore mainline retired-state regression guard

Rebase conflict resolution wrongly kept this branch's older removal; main's
2256387885 comment plus not.toContain assertion is the canonical fix.
2026-07-16 20:58:32 -07:00
Patrick Erichsen 55bb6cfa2e feat(control-ui): proxy plugin catalog icons (#109510) 2026-07-16 20:31:27 -07:00
EVA 09575bd20f feat(workspaces): show agent status and custom-widget decisions (#101826)
* feat(workspaces): add operations widgets

* fix(workspaces): format agent progress translation

* fix(workspaces): keep operations widget helpers private

* feat(workspaces): harden operations widgets

Co-authored-by: EVA <eva@100yen.org>

* chore(i18n): defer generated locale refresh

* refactor(workspaces): isolate approval state

* fix(release): declare direct checklist execution

* fix(release): satisfy checklist declaration lint

* fix(release): align checklist declaration order

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 20:19:49 -07:00
Peter Steinberger 00a6ecb906 feat(ui): always-on chat title bar with inline rename and workspace actions (#109422)
* feat(gateway): add sessions.files.reveal to open a session workspace on the gateway host

Resolves the session's workspace root server-side (same resolution as
sessions.files.list), refuses exec-node and cloud-worker placements, and
opens the directory with the platform opener. The opener helpers move out
of config.ts into a shared open-path module that config.openFile now uses.

* feat(ui): always-on chat title bar with inline rename and workspace menu

Every chat pane now renders its header: click the session title to rename
it inline (Enter commits via sessions.patch, Escape cancels), a workspace
chip names the session's checkout with reveal/copy-path/copy-branch
actions, and cloud-worker sessions show a globe. The single-pane floating
toggle cluster and the transcript's reserved titlebar drag band fold into
the header, which keeps native macOS window dragging.

* fix(ui): resolve title-bar session aliases and clear the collapsed-nav overlay

Live verification found two gaps: route aliases like ?session=main showed
the generic key-derived title instead of the session's label (resolve via
hello defaults + key equivalence, matching the pane), and the floating
sidebar-expand pill overlapped the header title on plain web while the nav
was collapsed (52px inset, mirroring the native-shell clearances).

* fix(ui): keep the protocol schema layer out of the Control UI startup bundle

The title-bar change made session-row-badges runtime-import the
gateway-protocol barrel for one classifier, dragging typebox and every
schema into startup JS (395 KiB gzip vs the 370 KiB budget). The placement
vocabulary now lives in a dependency-free session-placement-state module:
the schema union derives from it, the barrel re-exports it, and the UI
deep-imports it (startup back to 361.8 KiB).

* fix(gateway-protocol): keep SessionPlacementStateSchema statically typed

Type.Union over a mapped array loses tuple inference and collapses Static
to never; the literal list stays explicit with a compile-time guard tying
it to the shared SESSION_PLACEMENT_STATES vocabulary.

* chore(protocol): regenerate Swift/Kotlin bindings for sessions.files.reveal

* chore: narrow new exports flagged by the deadcode gate

* chore(i18n): leave generated locale artifacts to the locale-refresh workflow

The generated-artifact isolation gate (067635cb51) landed mid-flight;
source PRs now carry en.ts only.
2026-07-16 20:04:12 -07:00
Peter Steinberger 067635cb51 fix(ui): prevent generated locale rebase conflicts (#109393)
* ci(ui): make locale refresh bot-owned

* test(ui): keep locale gate coverage scoped

* fix(ci): preserve generated PR merge policy

* fix(ci): wait for generated PR head convergence

* fix(ci): retry transient guard API failures

* fix(ci): enforce locale isolation across CI events

* fix(ci): harden generated PR publication

* fix(ci): validate release gate merge tree

* fix(ci): allow trusted main locale output
2026-07-16 18:48:20 -07:00
EVA 368941ae7a feat(workspaces): add secure preview widget (#101354)
* feat(workspaces): add secure preview widget

* fix(workspaces): type preview reload assertion

* fix(workspaces): harden preview widget

* fix(workspaces): honor preview URL binding ownership

* chore(workspaces): remove unused widget exports

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 18:21:54 -07:00
Peter Steinberger b78cf56349 improve(ci): persist warm Vitest and Node caches (#109425)
* perf(ci): harden persistent test caches

* ci: document trusted cache cleanup trigger

* ci: harden composite cache inputs

* perf(ci): isolate Node build bytecode cache
2026-07-16 17:22:28 -07:00
EVA 4a7abe1556 Workspaces: add trusted chart widgets (#101792)
* feat(workspaces): add trusted chart widgets

* fix(workspaces): keep chart helpers private

* test(workspaces): prove chart widgets in control UI

* fix(workspaces): validate empty chart bounds

* fix(workspaces): expand subnormal chart ranges

* fix(workspaces): normalize chart ranges

* fix(workspaces): keep zero bars at baseline

* fix(ui): sync chart widget locales

* fix(ui): translate chart widget locales

---------

Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 16:50:49 -07:00
Peter Steinberger d7fe43acc3 fix(ui): tolerate transient gateway stalls in terminal liveness probe (#109317) 2026-07-16 14:45:10 -07:00
Peter Steinberger 02adefa39a feat(ui): show the live plan checklist inside the chat thread (#109343)
The run-scoped plan snapshot already fed the sticky composer bar; it now
also renders as an always-expanded card inside the active run's work
group, so plan progress is visible in scroll context. The bar and card
share one extracted renderer (variant: bar | card) instead of duplicating
the template, and the card clears with the run through existing plan
lifecycle.
2026-07-16 14:41:09 -07:00
Peter Steinberger a9f82837a1 feat: inspect background tasks across web and mobile (#109150)
* feat: add background task details across clients

* fix: refresh background task clients and translations

* fix: keep background task details fresh

* fix: ignore deleted background task details

* refactor: split background task rendering

* fix: use canonical background task ids

* refactor: extract background task view types

* fix(apps): regenerate task localizations

* fix(ios): remove unused task screen import

* fix(apps): refresh task localization inventory
2026-07-16 13:08:42 -07:00
Peter Steinberger ce919593bf fix(ui): unblock rebases with generated i18n conflicts (#109279)
* fix(ui): automate i18n conflict resolution

* fix(ui): preserve i18n cache merge intent

* fix(ui): restrict resolver to generated locales

* fix(ui): prune stale locales before baseline

* fix(ui): handle removed locale conflicts
2026-07-16 12:52:28 -07:00
Peter Steinberger 761eabad25 fix(ui): show dead reattached terminals as exited (#109281)
* fix(ui): show dead terminal sessions as exited

* chore: leave changelog to release flow
2026-07-16 12:34:52 -07:00
Dallin Romney 9f0e35c233 test: stabilize UI and gateway auth timing (#109257) 2026-07-16 11:13:42 -07:00
Peter Steinberger 7b296ae266 feat(ui): verify-connection affordance and device-code wizard E2E for Model Setup (#109183)
* feat(ui): add verify-connection affordance and device-code wizard e2e to Model Setup

* fix(ui): drop unnecessary Boolean conversion in canVerify

* chore(ui): reconcile i18n baselines after rebase
2026-07-16 11:11:04 -07:00
Peter Steinberger cb84dc76fc feat(control-ui): approval attention chip + approval history page (#108776)
Adds the sidebar approval attention chip and a dedicated approval history
page backed by the new approval.history gateway RPC (30-day retention
window). Extracts buildSidebarAttentionItems into its own module so the Lit
component consumes it as a real cross-module dependency, and wires the strict
i18n catalog for the new strings (fallbacks=0).
2026-07-16 10:32:05 -07:00
Peter Steinberger e71ef76e8e feat(onboarding): offer detected Claude Code/Codex/Hermes memory imports across CLI, macOS, and Linux onboarding (#108977)
* feat(migrate): add Hermes memory-only import and a shared memory-import core

* feat(onboarding): offer detected memory imports during CLI setup and guided onboarding

* feat(ui): show a first-run memory-import offer in Control UI onboarding mode

* feat(linux-app): open the first-run dashboard in onboarding mode

* feat(macos): add the onboarding memory-import page

* docs: document the onboarding memory-import page across surfaces

* chore(i18n): translate onboarding memory-import strings for control-ui and native locales

* refactor: keep memory-import internals unexported for deadcode gates

* fix(ci): resolve lint findings in onboarding memory import

* chore(i18n): refresh native inventory after lint refactor

* fix(ci): skip updater artifacts in the unsigned Linux companion PR lane

* chore(i18n): reconcile locale artifacts after rebase
2026-07-16 10:10:01 -07:00
Peter Steinberger e37eed86b0 fix(ui): throttle usage refreshes on reconnect with focus/TTL policy (#108904)
* fix(ui): throttle usage refreshes on reconnect

* fix(ui): throttle profile usage refreshes

* fix(ci): satisfy test-type and knip gates

* test(ui): reconcile usage reconnect coverage

* refactor(ui): extract usage refresh runtime
2026-07-16 09:46:59 -07:00
Peter Steinberger b3301e3212 feat(clients): show live plan checklists in web, iOS, and Android chat (#108675)
The gateway already broadcasts stream:"plan" agent events with typed
{step, status} snapshots; all three clients dropped them. Control UI now
renders an expandable checklist bar above the composer (run-scoped,
cleared on run lifecycle); the shared iOS/macOS chat UI mounts a
Liquid Glass pill (iOS 26 glassEffect, material fallback) between the
message list and composer; Android adds an expandable pill above the
composer bridged through ChatController/NodeRuntime/MainViewModel.
All parsers accept typed and legacy string steps, enforce the
single-in_progress invariant, and scope snapshots and clears to the
owning run. Locale artifacts, Android resources, and the iOS string
catalog carry generated translations for the pill strings.
2026-07-16 09:33:52 -07:00
Peter Steinberger 20d748a4f0 feat(agents): agent-owned gateway terminals with operator co-attach 2026-07-16 09:12:50 -07:00
Peter Steinberger 4733a59f26 feat(ui): web delights — empty-state mascots, first-reply confetti, composer drag-catch (#109118)
* feat(ui): web delights — empty-state mascots, first-reply confetti, composer drag-catch

Three mascot-powered moments in the Control UI: the plugins page and
channels hub show a sleepy Clawd when truly empty and a curious one on
a search miss; the very first successful assistant reply in a browser
earns a single confetti burst in the mascot palette (localStorage
once-flag, reduced-motion aware); and dragging files over the new-
session composer makes the welcome mascot tease with an open mouth,
then snap a catch on drop — upload behavior untouched.

* fix(ui): satisfy strict types and knip for the confetti module

Tuple index under noUncheckedIndexedAccess gets an anchored fallback,
the once-flag helper stays module-internal (knip counts only production
consumers), and its coverage moves to the public fireFirstReplyConfetti
path in jsdom using the shared storage mock.
2026-07-16 09:02:32 -07:00
Peter Steinberger a0d6cd724a feat(ui): animated Clawd mascot on the new-session welcome hero (#108825)
* feat(ui): animated Clawd mascot on the new-session welcome hero

Ports the native mascot to the Control UI as a canvas-backed
<openclaw-mascot> Lit component: exact 120x120 vector geometry, mood
loops (idle/curious/thinking/working/happy/celebrating/sad/sleepy/
attentive), deterministic seeded animator, DPR-aware rendering,
visibility-paused rAF, theme-reactive palette, and a reduced-motion
static pose. The new-session welcome hero swaps its static lobster
sprite for the living mascot.

* fix(ui): cancel stale mascot gestures on mood change

* fix(ui): keep MascotEffect internal to the pose module

* test(lint): allowlist the canvas fill suppression for the web mascot
2026-07-16 07:38:14 -07:00
destire-mio ddb50fcfdb fix(ui): show Usage detail request failures (#108689)
* fix(ui): show Usage detail request failures

* fix(ui): surface stale panel refresh failures

Co-authored-by: destire-mio <248462155+destire-mio@users.noreply.github.com>

* ci: pick up periphery workflow fix

* chore(ui): regenerate panel status locales

* refactor(ui): split usage page helpers

* fix(ci): format drift + unused export

* style: format full changed set

* fix(ui): translate panel refresh errors

---------

Co-authored-by: destire-mio <248462155+destire-mio@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 07:33:05 -07:00
Paul Pitchford efa8075c68 fix: external plugin tabs fail under gateway auth (#107323)
* fix: load plugin tabs with gateway auth

* fix: harden plugin tab cookie signature compare

* fix(gateway): authenticate external plugin tabs

Co-authored-by: Paul Pitchford <paul@paulpitchford.co.uk>

* refactor(gateway): simplify plugin frame auth proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 07:26:00 -07:00
SymbolStar 990d673083 fix(control-ui): restore userAvatar wiring in Quick Settings (#107292) (#107327)
* fix(control-ui): restore userAvatar wiring in Quick Settings (#107292)

Between 2026.6.11 and 2026.7.1 the Quick Settings parent renderer stopped
passing userAvatar / onUserAvatarChange down to the avatar editor, while
the editor still calls onUserAvatarChange?.(...). As a result, choosing,
clearing, or entering an emoji/text avatar under Settings \u2192 Simple
silently no-ops and never persists.

Restore the wiring: ConfigPage now reads the browser-local user identity
via loadLocalUserIdentity(), tracks the avatar on a @state field, and
persists changes through applyLocalUserIdentity() (added to
ui/src/app/settings.ts). No behavior change vs 2026.6.11.

* chore: drop changelog edit (release-generation owns CHANGELOG)

* ci: pick up periphery workflow fix

* ci: pick up pinned xcodegen installer

* chore: restore merge-base CHANGELOG (release-owned file)

---------

Co-authored-by: SymbolStar <SymbolStar@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 06:28:10 -07:00
Peter Steinberger cf029ea29e feat(agents): screen tool drives Control UI layout 2026-07-16 05:43:02 -07:00
NIO ac3ec1d805 fix(ui): prevent agent-select avatar fetch hangs (#108368)
* fix(ui): prevent agent-select avatar fetch hangs

* fix(ui): harden avatar fetch rotation

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 05:11:26 -07:00
Peter Steinberger 2d9584ccda feat(canvas): interactive widgets can send follow-up prompts in web chat (#108889)
* feat(canvas): let widget buttons send prompts into web chat

Inline show_widget documents get a sendPrompt(text) bridge: a private
MessageChannel offered to the Control UI before widget code runs. The chat
adopts only the first offer per frame, requires transient user activation,
a visible focused frame, plain text (no slash commands), and rate limits
10 prompts/minute per widget. Accepted prompts run the normal user send
path of the owning chat pane.

* fix(canvas): appease lint/knip/docs gates for widget prompts

Split widget prompt tests into their own file, drive validation and rate
limits through the real port path instead of exported internals, use
addEventListener on the adopted port, and regenerate docs_map.

* fix(canvas): install widget listeners per window for non-isolated tests

Module-boolean listener flags broke in shared vitest workers where each test
file gets a fresh jsdom window; key installation by window instead and give
port flushing more headroom.
2026-07-16 04:52:26 -07:00
Wynne668 dd58667be8 fix(ui): avoid usage reloads on websocket reconnect (#108726)
* fix(ui): reuse usage data across reconnects

* test(ui): use valid profile cost summaries

* test(ui): prove usage reconnect lifecycle

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:40:13 -07:00
Peter Steinberger 68694599af fix(exec): resolve no-route approvals immediately (#108935)
Fixes #104413. Supersedes the implementation direction in #104923 after preserving its contributor work and extending route detection across approval clients.

Co-authored-by: RickLin <83101411+ObliviateRickLin@users.noreply.github.com>
2026-07-16 04:26:38 -07:00
Peter Steinberger 4b904e6ac8 feat(ui): guided Model Setup page — web/Linux equivalent of the macOS Connect-your-AI flow (#108868)
* feat(ui): add guided Model Setup page for inference onboarding

* fix(ui): regenerate i18n locale bundles and narrow model-setup exports for CI gates

* chore(ui): regenerate i18n baselines after rebase

* chore(ui): translate model-setup strings for all locales
2026-07-16 04:16:27 -07:00
Peter Steinberger d5eebf02e2 fix(workboard): record resolved runtime metadata instead of hardcoded codex engine (#108887)
* fix(workboard): record resolved runtime metadata instead of hardcoded codex engine

Workboard executions labeled every dispatched run engine=codex, model=default,
and id suffix :codex even for Claude/other harness agents. The gateway agent
admission phase now returns the resolved {harness, provider, model} for plugin
subagent runs; the dispatcher records it verbatim and omits engine/model when
unresolved. Engine becomes an open runtime identifier in the workboard
contract (built-in launch choices stay a closed list), store/UI normalizers
preserve historical labels as written instead of inventing codex, and new
execution ids use an :agent-session suffix. Fixes #108362

* fix(workboard): accept undefined engine in ui engineModel helper
2026-07-16 04:10:27 -07:00
xingzhou 0c067fbfa4 fix(ui): reject nondecimal cron repeat amounts (#107480)
* fix(ui): reject nondecimal cron repeat amounts

* fix(ui): satisfy cron LOC ratchet

* fix(ui): validate cron intervals exactly

Co-authored-by: xingzhou <zhang.guiping@xydigit.com>

* chore(pr): stage cron UI proof

Co-authored-by: xingzhou <zhang.guiping@xydigit.com>

* chore(pr): remove staged cron UI proof

Co-authored-by: xingzhou <zhang.guiping@xydigit.com>

* fix(ui): remove unused cron type export

Co-authored-by: xingzhou <zhang.guiping@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-16 04:04:01 -07:00
zhanxingxin1998 866050fc1c fix(ui): honor UTC in usage session detail timelines (#108579)
* fix(ui): honor timezone in usage detail timeline

Apply the selected local or UTC calendar boundaries to session detail points and keep the full final day.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(ui): make usage timezone regression deterministic

Model a non-UTC local calendar through Date getters instead of relying on runtime TZ mutation.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(ui): type local date getter mocks

Annotate Date receivers so the deterministic timezone regression passes strict test type checking.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(ui): complete usage timeline timezone handling

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:48:35 -07:00
Peter Steinberger 2488d794ca feat(ui): expand child sessions in sidebar (#108838)
* feat(ui): expand child sessions in sidebar

* test(ui): type child session list options

* refactor(ui): split child session data helpers

* fix(ui): preserve session link semantics

* fix(ui): retry incomplete child session loads

* chore: keep release changelog owner-only
2026-07-16 03:26:49 -07:00
zhanxingxin1998 4bc84db398 fix(cron): allow clearing failure alert routing fields (#108578)
* fix(cron): clear failure alert routing fields

Send explicit nulls for cleared Control UI failure-alert overrides and accept those clears only in cron update patches.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cron): satisfy serialized alert patch types

Narrow the serialized failure-alert fixture before asserting its cleared fields.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cron): clear failure alert overrides

Co-authored-by: 詹幸心0668001037 <zhan.xingxin@xydigit.com>

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:52:19 -07:00
snowzlmbot fdaae75645 fix(ui): expose derived session titles accessibly (#96267)
* fix(ui): improve accessible session history picker

* fix(ui): clean session picker ARIA semantics

* fix(ui): preserve derived titles after session patches

Reuse the most recent sessions.list options when refreshing after sessions.patch so derived-title hydration survives normal patch flows. Add unit and browser E2E coverage for patch refreshes retaining readable sidebar titles.

* test(ui): split session list option coverage

---------

Co-authored-by: snowzlmbot <snowzlmbot@users.noreply.github.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:53:37 -07:00
xingzhou f98de3fc25 fix(control-ui): preserve emoji in plugin fallback monograms (#105240)
* fix(control-ui): preserve emoji in plugin monograms

* test(ui): cover combining-mark monograms

Co-authored-by: zhang-guiping <zhang.guiping@xydigit.com>

---------

Co-authored-by: Colin Johnson <colin@solvely.net>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-16 00:59:37 -07:00