Skip to content

fix(dashboard): make Codex permission requests visible in the dashboard#38

Merged
lesquel merged 1 commit into
mainfrom
fix/codex-permission-dashboard
May 17, 2026
Merged

fix(dashboard): make Codex permission requests visible in the dashboard#38
lesquel merged 1 commit into
mainfrom
fix/codex-permission-dashboard

Conversation

@lesquel

@lesquel lesquel commented May 17, 2026

Copy link
Copy Markdown
Owner

Summary

Resolves the Codex permissions invisible in the dashboard item of #33 (Tier-1; verified by hand).

Native OpenCode permissions reach the dashboard as raw SDK permission.requested/permission.resolved events. The Codex bridge has no SDK passthrough — it emits pilot.permission.pending/pilot.permission.resolved, which matched nothing the dashboard listened for. Result: a Codex tool's approval banner never appeared, and would never clear.

Fix — conservative dashboard-side alias

Deliberately not changing the emitted event type: the notification pipeline (Telegram/push) consumes pilot.permission.pending; renaming it risks regressing those consumers. Fixed purely in the dashboard:

  • constants.js: add PERMISSION_PENDING_PILOT / PERMISSION_RESOLVED_PILOT (named constants — no bare literals).
  • sse.js: the PERMISSION_REQUESTED / PERMISSION_RESOLVED branches now also match the two pilot.* types — purely additive OR-extension, native event strings unchanged.
  • Extracted the inline normalization into a shared sse/permission-normalize.js used by both native and Codex paths. The fresh review verified the helpers are byte-equivalent to the original inline code via a field-by-field table (every field, ?? fallback order, and key name preserved) → native rendering is provably unchanged.

Verification highlights

  • Native byte-equivalence: fresh-context review's make-or-break check — PASS (exhaustive old-vs-new diff).
  • Codex payload parity: pending carries permissionID/title/sessionID/permissionType/metadata; missing pattern degrades safely. All Codex resolved exits (normal/timeout/client-disconnect) carry permissionID → clear path works for every outcome.
  • Path reachable: SSE is unnamed (data: only) so onmessage already receives these events; SSE_EVENTS is not a hard filter (the two types added there anyway for forward-compat).
  • .d.ts companions for the new JS follow the established in-repo pattern for testing vanilla dashboard JS from TS tests.

Testing

  • +11 tests (pilot events normalize identically to native; all 3 resolved variants; pattern-absent safe default)
  • bun test 635/0 · bunx tsc --noEmit clean
  • Independent fresh-context adversarial review: APPROVE, no blocking issues. The actionable nit (misleading FAILING: test-name prefixes) is fixed.

Independent off main, dashboard-only — no overlap with #34–37.

Refs #33 (Tier-1, partial — does not close).

Second-wave audit (#33 Tier-1), verified by hand.

Native OpenCode permissions reach the dashboard as raw SDK events typed
`permission.requested`/`permission.resolved`. The Codex bridge has no SDK
passthrough — it emits `pilot.permission.pending`/`pilot.permission.resolved`,
which matched NOTHING the dashboard listened for, so a Codex tool's
approval banner never appeared (and, if it had, never cleared).

Conservative dashboard-side alias (deliberately NOT changing the emitted
event type — the notification pipeline consumes pilot.permission.pending
for Telegram/push; renaming it would risk regressing those):

- constants.js: add PERMISSION_PENDING_PILOT / PERMISSION_RESOLVED_PILOT.
- sse.js: the PERMISSION_REQUESTED / PERMISSION_RESOLVED branches now
  also match the two pilot.* types (OR-extension, purely additive —
  native event strings unchanged).
- Extracted the inline normalization into a shared
  sse/permission-normalize.js used by BOTH native and codex paths. The
  helpers are byte-equivalent to the original inline code (every field,
  every ?? fallback, every key preserved — fresh review confirmed via a
  field-by-field diff), so native rendering is unchanged.

Codex payload parity verified: pending carries permissionID/title/
sessionID/permissionType/metadata; `pattern` is absent and degrades
safely. All four Codex resolved exit paths (normal/timeout/disconnect)
carry permissionID so the clear path works for every outcome. SSE is
unnamed (data: only) so onmessage already receives these — no filter
gate to widen.

+11 tests. bun test 635/0, tsc clean. Independent fresh-context review:
APPROVE, no blocking issues (native byte-equivalence proven). The one
actionable nit (misleading FAILING: test-name prefixes) is fixed here.

Refs #33
@lesquel lesquel merged commit d89e7f3 into main May 17, 2026
2 checks passed
@lesquel lesquel deleted the fix/codex-permission-dashboard branch May 17, 2026 20:14
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