mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -06:00
fix/qa-profile-script-tail
12 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
64853b1a9d |
improve(control-ui): restructure the composer as a multiline surface (#124301)
* improve(control-ui): align composer stack with current main
* refactor(ui): isolate new-session permission state
* fix(ui): close composer CI regressions
* test(ui): align composer presentation contracts
* test(ui): fix composer browser contracts
* test(ui): stabilize composer browser ownership
* test(ui): target presented mobile composer
* test(ui): select accessible mobile composer
* test(ui): open mobile rail session directly
* fix(ui): keep mobile composer content laid out
* fix(ui): address composer review findings
* fix(ui): close composer interaction gaps
* fix(ui): bound swarm task popover
* fix(ui): restore progress-card docking beside the wide composer
The multiline restructure dropped the .session-progress-card--dock
placement shipped in #129141 and left the completed marker inside the
collapsed-only summary span, so it vanished when the disclosure opened.
Restore the dock positioning block and hoist the marker into the
always-visible summary grid.
* fix(ui): bound swarm task popover by its composer anchor
The popover capped its height against the raw viewport, so on short
mobile viewports its top rendered above the screen. Register the swarm
group with the existing composer popover anchor observer and consume the
measured --chat-composer-popover-max-height, keeping the viewport calc
only as fallback. The new actual-tree mobile regression failed with
-71px top clipping before the fix.
* fix(ui): restore Draft capability controls and split the new-session composer
Restores the Draft option and selected-state indicators the capability
menu lost in the restructure, and moves the capability/visibility
controls into composer-capability-controls.ts so composer.ts drops back
under the 700-line lint gate (677 lines) without a suppression.
* test(ui): prove permission-mode final effect before session creation
Adds mocked-gateway proof that an admin's Full selection reaches
sessions.create as permissionMode:"full" exactly once, and that a
write-scoped operator's retained Full selection is rejected before
creation with a visible status notice and zero create requests. Also
aligns the mobile footer reading-order assertion with the shipped
attachments-draft-model order.
* test(ui): register swarm popover layout test as node-driven
chat-swarm-progress.browser.test.ts drives its own Playwright chromium
from node, but
|
||
|
|
8fe2c1b83c |
perf(ui): consolidate Control UI boot chunk graph for HTTP/1.1 gateways (#128514)
* perf(ui): consolidate Control UI boot chunk graph for HTTP/1.1 gateways The Control UI boot flow (app shell + sidebar + chat route) lazily loaded ~124 automatic chunks in one burst after the gateway handshake, which the gateway's HTTP/1.1 transport serializes into ~24 six-connection round-trips on high-latency links (Tailscale, remote gateways). Add a measured boot-module manifest (ui/config/control-ui-boot-modules.json, regenerated via pnpm ui:boot-manifest:gen) and a control-ui-boot codeSplitting group that merges exactly that module set into a handful of chunks with recursive dependency inclusion. Lazy islands (locales, ghostty-web, novnc, non-default routes) keep their own chunks; stale manifest entries degrade gracefully back to automatic chunking. Measured on the built dist with the mocked gateway (chat route, 3 runs): unique boot JS requests 140 -> 45, raw boot JS 3751 -> 3717 KiB, chat composer interactive at simulated 50 ms RTT ~1600 ms -> ~575 ms. Largest-CSS budget rises 45 -> 47 KiB for the merged boot CSS; startup JS gzip baseline ratchets down (345049 -> 339214 B) as consolidation shrinks the startup graph. * chore(ui): refresh boot module manifest after rebase onto current main * fix(ui): stop the pending lazy shell action replay loop starving boot When a pending lazy shell action (command palette open, panel toggle) replayed while the shell was still splash-gated, the dispatched event had no rendered element to consume it and re-entered requestLazyElement in a microtask cycle: request -> load -> replay -> dispatch -> request. The cycle starved tasks (Gateway WebSocket messages included), so the boot never finished and the recovery e2e froze on the splash screen. Gate replay on the element actually being rendered: the controller skips the action after load until the host's render root contains the tag, and restorePendingLazyAction skips dispatch while a defined element is still render-gated. The host retries after every completed update, so the replay fires on the update that first renders the element. Regression test fails on the pre-fix controller. * fix(ui): re-anchor the scope-upgrade details popover before opening wa-popover resolves its `for` target once per property change and never re-resolves a missing or replaced anchor. The trigger with the shared id can render after the popover's first update (the header trigger ships with the lazy chat chunk), leaving the opened popover permanently invisible: active popup with a native [popover] part stuck at UA display:none because showPopover() never ran without an anchor. Re-arm the watcher when opening while the anchor is missing or disconnected. * test(ui): compare settled layouts in device-scope stability assertions The 0.5px no-move assertions sampled geometry that later reflowed when the details surface's first render fetched glyph subsets, reporting sub-pixel drift the open never caused. Burn in the one-time open per context and sample the baseline adjacent to the click. * fix(ui): map the keyboard shortcuts dialog in lazy replay gating Current main added the keyboard-shortcuts lazy shell event; the replay gate's exhaustive event-to-element record needs its entry. * chore(ui): refresh startup budget baseline after rebase onto current main |
||
|
|
ee7146a282 |
fix(ui): make startup gzip runtime-independent (#126795)
Host zlib versions compress identical startup assets into different bytes, causing false Linux budget failures. Emit canonical shipped pako gzip sidecars, restore the 512 B ratchet tolerance, and lower the startup baseline from 348351 B to 344531 B. |
||
|
|
8668aeb969 |
fix(discord): bind transcript capture to source account [AI] (#118579)
* fix(discord): bind transcript capture to source account * style(agents): keep transcript tool wiring compact * fix(transcripts): declare account binding channels * fix(transcripts): report effective capture account * fix(transcripts): enforce account lifecycle ownership * fix(transcripts): preserve cross-surface control * fix(copilot): preserve transcript channel context * fix(transcripts): fail closed for legacy channel owners * fix(transcripts): add trusted legacy recovery * fix(transcripts): preserve auto-start cleanup ownership * fix(transcripts): reject untrusted account starts * fix(transcripts): keep persisted ownership authoritative * fix(transcripts): harden legacy recovery * fix(transcripts): preserve agent ownership boundary * fix(transcripts): scope account binding to source channel * fix(transcripts): preserve unattributed owner isolation * fix(transcripts): own configured captures by account * docs(plugins): clarify transcript auto-start ownership * test(transcripts): cover account-less recovery * docs(transcripts): scope legacy recovery by provider * fix(discord): reuse eligible account ordering for transcripts * test(discord): use neutral transcript account fixtures * fix(transcripts): keep accountless recovery local * fix(discord): resolve transcript accounts by voice capability * fix(transcripts): bound account resolution failures * fix(transcripts): bound account tool output * fix(transcripts): honor unresolved provider accounts * fix(transcripts): preserve binding when providers are missing * fix(transcripts): fail closed on unknown binding provenance * fix(transcripts): qualify account lifecycle capability * fix(transcripts): normalize provable legacy owners * fix(transcripts): bind scheduled capture to caller authority * fix(transcripts): preserve scheduled caller identity tuple * fix(transcripts): preserve channel-less scheduled authority * fix(plugin-sdk): publish transcript provider types * fix(transcripts): use exact lifecycle ownership tokens * fix(transcripts): preserve local ownerless lifecycle access * fix(transcripts): allow local configured capture control * fix(transcripts): preserve scheduled caller channel * fix(transcripts): retain named-agent legacy recovery * fix(transcripts): deny unrelated remote channels * fix(doctor): validate transcript owner inference * fix(transcripts): restrict legacy remote recovery * fix(ci): align transcript Doctor checks * fix(transcripts): require Doctor-owned legacy metadata * fix(transcripts): reject unowned remote capture starts * fix(transcripts): reject unbound Discord lifecycle calls * fix(transcripts): distinguish legacy owner rows * test(discord): keep unavailable account fixture typed * fix(transcripts): mark current imports for Doctor * fix(transcripts): complete account ownership validation * fix(discord): restore transcript package boundary * fix(discord): preserve bundled transcript entry boundary * docs(transcripts): clarify Discord auto-start account * fix(transcripts): bind account-owned imports * fix: preserve transcript and cron policy state * fix(cron): preserve scheduled transcript authority * fix(discord): keep legacy transcript rows local * fix(transcripts): narrow account ownership boundary * fix(transcripts): preserve trusted caller ownership * fix(discord): enforce transcript source authorization * fix(ci): bound Control UI gzip build variance * test(qa): align transcript scenario contracts * fix(agents): repair rebased caller context * fix(discord): restore rebased account ownership * test(discord): restore voice account fixtures --------- Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com> |
||
|
|
e7ba2e1f6b |
fix(ui): give the Gateway update a visible, truthful outcome (#121686)
* fix(ui): give the Gateway update a visible, truthful outcome Confirming an update in the Control UI could end in nothing the operator could see. The sidebar card only knew `updateRunning`, which clears as soon as `update.run` answers, so a dev-channel handoff — git pull, install, full build, restart — spent minutes back on the stale "N commits behind" call to action. A verified install then published a null banner, so success was never announced at all, and the reload that a verified install triggers would have destroyed any in-memory notice anyway. The lifecycle was already recorded; nothing rendered it. Feed the sidebar the reconciliation fact the settings page already uses, narrate the wait in the shell callout that survives the restart, and record the verified result so it outlives the reload it causes. Failures now name their cause. The updater already stores the failing step and its captured output in the restart sentinel and `update.status` returns it whole, so a disk-full install reads "The update failed at install: ENOSPC: no space left on device" instead of a reason slug plus "see the gateway logs". Missing handoff-reason guidance is filled in, and the duplicate post-restart banner resolver is folded into the shared one. Also fixes a callout clipped by the fixed shell chrome controls, and the "Available 246 commits behind" double framing in the confirmation. * fix(ui): report the Gateway update in the dialog that starts it Follow-up to the first pass: the shell-top callout was the wrong surface for this. The dialog the operator clicked is now the one that reports the whole update, and the ambient surfaces are the fallback for anyone who leaves it. Confirming no longer closes the dialog. It becomes stateful — the danger button turns into a disabled "Updating…" with a spinner, and the body narrates the phases in place: installing, then "The Gateway is restarting. This page disconnects and reconnects on its own." The dialog is mounted on document.body, outside the shell, so losing the connection cannot unmount the only surface still reporting. A request the Gateway never accepts stops spinning after a bounded grace and says so. A failure lands in the dialog with its recorded cause and next step. Success still arrives after the reload a verified install triggers, so it stays a toast — no dialog exists by then. The shell-top status callout is gone. The same outcome now renders beside the sidebar update card that started the update, and stays hidden while the dialog owns the report so the two surfaces never duplicate each other. Splits the wire-payload readers out of update-overlay-helpers into update-schedule-dto and moves update.run answer classification next to them, keeping both owners under the file-size budget. * fix(ui): keep the update dialog open through the install in E2E and use a defined warn token * refactor(ui): wire the update progress stream into the floating card and drop unused video capture * fix(ui): report the current update, not the previous failure The dialog subscribed to progress before starting the update. Producers replay their current snapshot synchronously on subscribe, so a retry still carrying the previous attempt's failure banner painted that old error as this update's outcome. Start the request first, and treat a failure present on the subscribe emit as the previous attempt's: an accepted run clears the banner before its first await, so a failure that survives means the request was refused, which the accept timer already reports truthfully. * fix(ui): keep update helpers internal * chore(perf): raise startup-JS budget to 350 KiB Approved by maintainer Vyctor on 2026-08-11. Trigger: after #121734, main measured 326650 B—6 B below the prior 319 KiB hard ceiling. Current main subsequently moved the ceiling to 320 KiB; this records the authorized final 350 KiB decision for #121686. * fix(ui): announce update success without session storage Show the verified install identity directly when the current document does not reload, so denied session storage cannot suppress the operator-visible outcome. * test(ui): isolate update toast in overlay tests The Node-only overlay suite now reaches the direct non-reload success toast. Mock the DOM-owned toast boundary so reconciliation assertions can complete without a browser document. |
||
|
|
8d3f3377da | fix(ci): make Control UI artifact validation consistent (#122086) | ||
|
|
db73b59c04 |
refactor: burn wrapper shadowing baseline entries (#122040)
* refactor: burn wrapper shadowing entries * chore: refresh wrapper shadowing baselines * test: update secrets runtime state mocks * fix(ci): absorb Control UI build identity variance |
||
|
|
8dace97c2e |
perf(test): cut workflow guard overhead (#122038)
Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
fa03d9b913 |
refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers * fix: remove duplicate coercion imports * fix: preserve serialized coercion guard * chore: ratchet coercion helper carve-outs * fix(test): keep gauntlet subprocess startup lean * fix: preserve imported session timestamp semantics * fix: preserve catalog timestamp string semantics * chore: align plugin SDK surface ratchet * fix: preserve trajectory and SDK string contracts * fix(test): preserve QA record assertion semantics * fix: complete standalone record guard rename * refactor(cron): use canonical string coercion * fix(acpx): preserve Pi timestamp parsing * test(channels): adapt custody test harnesses * test(telegram): classify media harness as test support * test(acpx): split timestamp contract coverage * test(channels): support generated custody contracts * chore: ban the full coercion helper name set Extends the declaration guard to all eleven consolidated helper names and renames the cron schedule-identity readNumber wrapper to readScheduleInteger so the banned generic name cannot regrow. * fix(scripts): repair release-validation guard drift and lint cause Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after main added isRecord call sites in parallel, and attaches the caught YAML error as the thrown error cause (preserve-caught-error was red on main). * fix: preserve Claude timestamp string semantics * fix: preserve persisted timestamp string semantics * fix: preserve date-first timestamp contracts * fix(openai): harden delegation failure formatting * chore: close coercion helper guard gaps * test(openai): model non-error delegation rejection * chore: refresh plugin SDK API contract * fix(tasks): use canonical string field reader * fix(ai): use canonical provider error field coercion * fix(browser): migrate native bootstrap coercion * docs(plugin-sdk): clarify text record export compatibility * fix(gateway): normalize approval execution identity * test(outbound): isolate message action poll harness |
||
|
|
a6a464f4c0 |
feat(terminal): fullscreen /terminal route and dot-matrix claw intro (#121451)
* feat(ui): add fullscreen /terminal route and open button * feat(terminal): dot-matrix claw intro banner and CLI mascot * fix(terminal): satisfy lint and wizard-header assertions for the new mascot * ci: account for fullscreen terminal startup bytes * test(terminal): split session manager coverage |
||
|
|
5207c4765d |
feat(ui): float task-suggestion cards top-right with copy-prompt action (#121259)
* feat(ui): float task-suggestion cards top-right with copy-prompt action - Float a compact tray in .chat-main__conversation with absolute positioning, min(400px, 100% - margins) sizing, elevation, and internal scrolling. - Remove the icon column, keep dismiss in the header row, and move a compact split button to the bottom-right. - Add Copy prompt to the menu via shared copyToClipboard, copying the raw prompt while display-only sanitization remains documented inline. Release note: Suggested-task cards now float as compact cards at the chat top-right and offer Copy prompt in the action menu. * style(ui): neutral grey task-suggestion card and actions Drop the accent-tinted card border/background, mute the eyebrow, and use default grey button treatment for the split control per operator direction. * fix(ui): ungate copy-prompt and surface clipboard outcomes - Menu now always renders with the client-local Copy prompt while acceptance-mode items stay capability+scope gated (addresses ClawSweeper finding 1). - Copy success shows a transient Copied label and failures surface through the pane error path (finding 2). - Task-suggestion pane logic extracted to chat-pane-task-suggestions.ts and the tray adapter moved into the component to keep files under the 700-line cap. * fix(ui): test task suggestions through tray adapter * test(ui): cover task-suggestion clipboard failure * test(ui): split task-suggestion pane coverage * chore(ui): raise startup JS budget for task-suggestion card feature QA-profile measurement was 324617-324620 B versus the 324608 B effective budget; this owner-directed PR #121259 bump follows the baseline file’s documented feature-growth precedent. * chore(ui): raise startup JS ceiling to 318 KiB for task-suggestion cards The fixed 317 KiB ceiling (324608 B) was within ~20 B of CI-measured startup bytes after accumulated main drift; the task-suggestion card feature crossed it. Ceiling raised with in-file maintainer-approval comment per its own convention; ratchet baseline set to CI-measured 324626 B. * fix(ui): keep task-suggestion copy available read-only Remove the stale accept-or-dismiss tray guard now that Copy prompt is a client-local action. Keep Gateway-backed accept and dismiss controls independently gated, with a regression for operators who can only list suggestions. * test(ui): cover list-only task-suggestion copy Update the mocked-Gateway E2E to match the repaired read-only behavior: the suggestion remains visible, its mutating Start action is disabled, and Copy prompt stays available. |
||
|
|
c70aee247e |
refactor(scripts): migrate JavaScript tools to TypeScript (#121005)
* refactor(scripts): migrate JavaScript tools to TypeScript * fix(ci): keep changed-scope preflight zero-install * fix(ci): preserve zero-install script owners * fix(ci): complete script migration follow-through * fix(release): keep stable closeout zero-install * fix(scripts): preserve standalone execution boundaries * fix(scripts): repair standalone loader boundaries * fix(scripts): normalize gateway observation ids * fix(scripts): keep Docker packager standalone * test(scripts): preserve rebase cleanup helpers * test(sessions): use tracked temp directory |