Skip to content

fix(webui): approval buttons did nothing — active id was nulled during render - #142

Merged
jkyberneees merged 1 commit into
mainfrom
fix/webui-approval-buttons
Aug 22, 2026
Merged

fix(webui): approval buttons did nothing — active id was nulled during render#142
jkyberneees merged 1 commit into
mainfrom
fix/webui-approval-buttons

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Problem

The WebUI approval decision card rendered, but the approve / deny / trust buttons (and keyboard shortcuts) did nothing. The agent side then sat blocked until the 60s approval timeout and denied the operation.

Root cause

renderApprovalCard() called removeActiveApprovalCard() as its first line, and that helper unconditionally reset S.activeApprovalId = null. Every freshly rendered card therefore had a null id, and sendApproval's guard (if (!S.activeApprovalId) return;) silently dropped every response.

This survived review because #135 rewrote everything around approvals.js without exercising its DOM behavior — there was no test driving clicks through the real module.

Fixes

  • approvals.jsremoveActiveApprovalCard removes only the card; S.activeApprovalId is owned exclusively by showNextApproval (set to the shown request, null when the queue empties).
  • approvals.js — new clearApprovals() owns full teardown (queue + card + id); sessions.js uses it on new/switch session. The old per-site pair left a stale id that suppressed all later cards after a session switch.
  • approvals.js — stale "request 1 of N" hint fixed: a card rendered at queue depth 1 never gained the indicator when further requests arrived; updateQueuePosition() refreshes it live on arrival/dismissal (without re-rendering, preserving friction-mode typing).

Test coverage

New cmd/odek/ui/js/approvals.test.js (17 tests) drives the real module through a minimal DOM shim:

  • render contract (card in DOM, active id set — regression guard for this bug)
  • exact WS wire format {type,id,action} as parsed by approvalResponse in wsapprover.go
  • approve / deny / trust button dispatch; FIFO queueing across cards
  • keyboard shortcuts (a/d/t), ignored while typing in inputs, trust shortcut suppressed when allow_trust === false
  • approval_ack dismissal from another client sends nothing
  • clearApprovals() regression guard: post-teardown requests still render and answer
  • friction gate: approve disabled until gate elapses + word typed; disabled clicks dispatch nothing; Enter path
  • live queue-position indicator updates

Validation

  • node --test cmd/odek/ui/js/*.test.js → 68 pass (51 existing + 17 new)
  • go test -count=1 ./cmd/odek/ → ok (incl. WebUI asset-contract/E2E suites)
  • go vet clean, golangci-lint 0 issues

…g render

removeActiveApprovalCard reset S.activeApprovalId, and renderApprovalCard
called it as its first line. Every freshly rendered card therefore had a
null id, so sendApproval's guard silently dropped every button click and
keyboard shortcut: the approval form rendered but never answered (the
agent side then timed out after 60s and denied).

- approvals.js: removeActiveApprovalCard now removes only the card; the
  id is owned exclusively by showNextApproval (set to the shown request,
  null when the queue empties)
- approvals.js: new clearApprovals() owns the full teardown (queue +
  card + id); sessions.js uses it on new/switch session — the old
  per-site pair left a stale id that suppressed later cards
- approvals.js: fix stale "request 1 of N" hint — a card rendered at
  depth 1 never gained the indicator when further requests arrived;
  updateQueuePosition now refreshes it live on arrival/dismissal

Tests (cmd/odek/ui/js/approvals.test.js): DOM-shim suite driving the real
module — render contract, approve/deny/trust wire format ({type,id,
action} as parsed by wsapprover.go), keyboard shortcuts incl. input/
trust-suppression guards, FIFO queueing, approval_ack dismissal,
clearApprovals regression guard, friction gate (typed word, disabled
clicks, Enter path), and live queue-position updates.

node --test cmd/odek/ui/js/*.test.js → 68 pass; go test ./cmd/odek/ ok.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
odek af6542a Commit Preview URL

Branch Preview URL
Aug 22 2026, 01:37 PM

@jkyberneees
jkyberneees merged commit b8e80cc into main Aug 22, 2026
10 checks passed
@jkyberneees
jkyberneees deleted the fix/webui-approval-buttons branch August 22, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant