Repository navigation
fix(console): Create Agent shows its own busy state - #2898
Conversation
Create's pending flag was shared with Check credential registration, removal, repository reload and provisioning retry, so Create could not be marked busy without also looking busy during those requests. Create now keeps its own in-flight flag: while its request runs the button sets aria-busy (progress cursor), and every way the request ends clears it, a navigation away included. Finding 1961.
The Create request is held, so Create Agent shows aria-busy and the progress pointer (finding 1961).
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
Review fixes: the uncertain-registration step waits for its outcome text, the navigation step checks the busy state before the held request is answered, and the Create pending story holds only the provisioning request and names the client's 15 s timeout.
freeqaz-openai
left a comment
There was a problem hiding this comment.
Free's clanker here. The navigation-test gap is fixed in 4e542698. Moving the assertion before the held response is released was sufficient; no new timeout or production change needed.
Both new browser tests passed unchanged. When I deliberately made validation outlive the page, the old test still passed, but this head failed at the intended assertion (line 413), at 10 seconds, before the client's 15-second timeout could make it pass accidentally. That proves browser-side abandonment, not server-side cancellation. I corrected my private checkout's workspace links before these runs. Hosted Browser 2 passed all 362 cases on a tested tree identical to this head.
Pending-state screenshot · Six-second ready → pending → refused recording. Real Console, local browser fixture, controlled refusal; production bytes are unchanged since capture at c440849c. Measured busy false → true → false, cursor pointer → progress → pointer. The recording does not claim to capture the OS pointer or screen-reader speech. I added both native attachments to Verification and downloaded and byte-verified them; a subsequent body edit removed those links, so please preserve them when finalizing the description. I will not overwrite concurrent edits.
No further source change requested from this review; ClawSweeper and the ordinary review protections still apply.
|
Codex review: needs maintainer review before merge. What this changesCreate Agent now reports busy only while its own submission runs and clears that state when the request ends. Example: A user selects Create Agent while its validation request is delayed.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep this PR open: it completes an intentional accessibility follow-up with a focused implementation and meaningful regression coverage; no actionable defect was found. Priority: P3 Before mergeNone. FindingsNone. Agent review detailsHow this fits togetherThe console creation form submits validation and resource requests through the existing API client; its local presentation state determines the Create button's accessibility attributes and cursor. flowchart LR
User[Console user] --> Form[Create Agent form]
Form --> Request[Existing API client]
Request --> API[Validation and creation APIs]
Form --> State[Create busy state]
State --> Button[Button accessibility and cursor]
Technical reviewBest possible solution: Use the existing creation form's submission lifecycle to maintain Create-specific busy presentation, as this PR does. Do we have a high-confidence way to reproduce the issue? Current main disables Create through shared pending state without assigning its own aria-busy value; the existing CSS requires aria-busy="true" for the progress cursor, and the supplied regression comparison reports both added tests fail on main. Is this the best way to solve the issue? The separate flag is appropriate because shared pending also represents other controls, and cleanup covers both preflight and mutation lifecycles without adding a parallel request owner. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 90c63bf8e7c2. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Likely related people:
Review metrics
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 18, 2026, 10:59 PM ET / October 19, 2026, 02:59 UTC. |
Problem
Create Agent has no busy state while its request runs (finding 1961, the remainder of finding 1927). The form's
pendingflag is shared with other controls' requests: Check credential registration, Remove failed credential registration, Reload repository choices and Retry provisioning request. Marking Create busy frompendingwould make it look busy while one of those runs, so #2896 left Create disabled but not busy: it showed thenot-allowedcursor, and assistive technology heard "unavailable" instead of "working".Change
agents/create.mjs: Create keeps its own in-flight flag,createPending. It is set where the submit handler starts its request.updateControls()writesaria-busyon Create from that flag, so the B4 rule shows theprogresscursor.endCreate()clears the flag and the attribute on every way the request ends:finally, which covers success, refusal, an uncertain outcome and a provisioning hand-off;pending. They disable Create but do not mark it busy.aria-busy="true"with the progress pointer.Verification
Two new tests in
tests/browser/console-button-hierarchy.test.mjs(already mapped tochecks-browser-2.json). Both fail on main:aria-busy="true"with theprogresscursor while the request is held, and"false"afterwards. For success and navigation, the check is on the button the page left.aria-busy="false"and no progress cursor. A refused registration (400) ends the busy state.Mutants, run one at a time:
create.mjsaria-busyfrom the sharedpendingendCreate()in the mainfinallyendCreate()in the preflightcatchendCreate()on the "view no longer current after a successful preflight" pathThe survivor is a defensive path. Leaving the page aborts the preflight, so the browser ends up in the
catch, which the navigation case covers. The path is reached only when a response and a navigation land in the same tick.console-button-hierarchy.test.mjsran 20/20 at 2 CPUs (taskset -c 6-7).Prettier and eslint are clean on the touched files.
The Storybook story was checked in Chromium at 1440 and 390: Create reads
aria-busy="true",disabled,cursor: progress.Native browser evidence, from the real Console with a local test fixture, captured on
c440849c. All production code is byte-identical at4e542698; that commit changed only the test and the story.aria-busyfalse → true → false, and cursor pointer → progress → pointer.ready-pending-refused.mp4
Hosted Console Browser 2 tested the exact
4e542698tree: 362 passed, including both new cases; none skipped.Open PRs: I ran a 3-way
git merge-treeagainst every open PR touching the console,create.mjsor the Storybook scenarios (fix(console): Agents list wraps long names on wide screens; phone sheets stay above the keyboard #2893, test(console): kill surviving mutants in the harness lock, JSON scan and recovery card #2892, fix(console): keep a focused workspace caret on reread and quiet plugin live regions #2860, fix(console): let the create preflight carry any configuration both creates accept #2833, feat: add per-agent sandbox network policies and denial review #2599, feat(console): show the authorized native Gateway people roster #2596, feat(console): stop and delete Agents from the Agents list #2524, Draft implementation: managed outbound HTTPS for dedicated Gateways #2518, fix(console): distinguish stale runtime status from loss of access #2505, fix(console): keep followed logs steady and report the first output #2502, Add OCE policy simulation and tester for network and plugin actions #2445, fix: preserve native plugin permissions across Harness selection and admission #2258, fix(console): grant Agent access to accepted Configuration Secrets #2255, Support custom Installation profiles and readable Preset starters #2253, feat(auth): sign people in to occ with a device code (rfc-0019) #1619, feat: assign configured OpenClaw roles to Agent users #906, docs(specs): propose rfc-0019 for repository options without a repository driver #878, feat: add Agent workload tags #115). Each PR's conflict-hunk count is the same against this head as against main. This branch adds no new conflict hunk.Risks
Low. It changes only Create's busy attribute and adds one story. Create's disabled logic and request flow are unchanged.