Skip to content

Add reject feedback to permission UI#499

Merged
pascalandr merged 6 commits into
NeuralNomadsAI:devfrom
OfflinePing:pr/496-reject-reason-ui-clean
May 25, 2026
Merged

Add reject feedback to permission UI#499
pascalandr merged 6 commits into
NeuralNomadsAI:devfrom
OfflinePing:pr/496-reject-reason-ui-clean

Conversation

@OfflinePing
Copy link
Copy Markdown
Contributor

@OfflinePing OfflinePing commented May 23, 2026

Summary

  • Adds a two-step deny flow for permission requests so users can provide optional feedback.
  • Passes reject feedback through sendPermissionResponse to client.permission.reply as message.
  • Hardens the flow by ignoring permission shortcuts while text inputs are focused and capping feedback length.

Validation

  • npm run typecheck --workspace @codenomad/ui
  • npm run build:ui
  • npm run build:linux --workspace @neuralnomads/codenomad-electron-app

Showcase

image

Related to #496

shantur and others added 4 commits May 3, 2026 20:09
…rkdown previews, Apps don't need Node installed and more (NeuralNomadsAI#387)

## Thanks for contributions

- [@pascalandr](https://github.com/pascalandr):
[NeuralNomadsAI#333](NeuralNomadsAI#333),
[NeuralNomadsAI#334](NeuralNomadsAI#334),
[NeuralNomadsAI#336](NeuralNomadsAI#336),
[NeuralNomadsAI#337](NeuralNomadsAI#337),
[NeuralNomadsAI#341](NeuralNomadsAI#341),
[NeuralNomadsAI#342](NeuralNomadsAI#342),
[NeuralNomadsAI#351](NeuralNomadsAI#351),
[NeuralNomadsAI#352](NeuralNomadsAI#352),
[NeuralNomadsAI#360](NeuralNomadsAI#360),
[NeuralNomadsAI#361](NeuralNomadsAI#361),
[NeuralNomadsAI#362](NeuralNomadsAI#362),
[NeuralNomadsAI#366](NeuralNomadsAI#366)
- [@VooDisss](https://github.com/VooDisss):
[NeuralNomadsAI#302](NeuralNomadsAI#302),
[NeuralNomadsAI#304](NeuralNomadsAI#304),
[NeuralNomadsAI#311](NeuralNomadsAI#311)
- [@jollyxenon](https://github.com/jollyxenon):
[NeuralNomadsAI#386](NeuralNomadsAI#386)

## Highlights

- **Remote HTTPS is much easier to trust and use**: Connect to
self-hosted CodeNomad instances over HTTPS more smoothly, including
setups that use self-signed certificates.
- **Git changes are much more capable inside the app**: Review diffs
with a redesigned Monaco-based experience and a stronger Git Changes
workflow that makes working with modified files and worktrees feel more
natural.
- **File viewing is more useful out of the box**: Markdown files can now
be previewed directly, so notes, docs, and READMEs are easier to inspect
without leaving CodeNomad.
- **Desktop setup is simpler**: CodeNomad no longer depends on a
separate Node install in the same way, reducing setup friction and
making desktop usage easier to get running.
- **Remote and local workflows are more upgrade-friendly**: There is now
a dedicated CLI upgrade command, making it easier to keep the underlying
tooling current.

## What’s Improved

- **Better remote-server integration**: Remote proxy configuration is
more flexible, OpenCode authentication is respected more consistently,
and remote session handling is easier to reason about.
- **Stronger workspace and folder flows**: Folder picking is smoother,
selected workspace roots are preserved more reliably, and
workspace-scoped session behavior is clearer.
- **More polished desktop packaging**: Linux AppImage distribution,
Linux icon integration, Windows ARM64 build support, and WSL/Windows
path handling all received improvements.
- **Cleaner prompt and file tooling UI**: Prompt composer actions are
laid out more clearly, file filters behave more predictably, and
apply-patch diagnostics are easier to understand.

## Fixes

- **More reliable live updates**: Closed SSE streams reconnect more
reliably, helping sessions recover more gracefully.
- **Less disruptive scrolling while replies stream**: Long responses and
streaming output are held more predictably so the view does not jump
around as much.
- **Better worktree behavior**: Delete-worktree failures now surface
clearer diagnostics, and Git/worktree state handling is more dependable
overall.
- **More stable desktop startup**: Managed server startup, shell
environment loading, package/runtime app IDs, and missing-runtime
reporting were all tightened up.
- **Better power behavior during long sessions**: Wake-lock handling now
allows the display to sleep while active work continues, avoiding a more
intrusive always-awake experience.

## Docs

- **Updated supporting docs**: README and internal documentation were
refreshed, including SideCars notes and wake-lock behavior
documentation.

### Contributors

-   [@pascalandr](https://github.com/pascalandr)
-   [@VooDisss](https://github.com/VooDisss)
-   [@shantur](https://github.com/shantur)
-   [@jollyxenon](https://github.com/jollyxenon)

**Full Changelog**:
[v0.14.0...dev](NeuralNomadsAI/CodeNomad@v0.14.0...dev)

## Merged Pull Requests

### @pascalandr

- PR [NeuralNomadsAI#333](NeuralNomadsAI#333)
“feat(tauri): support self-signed remote HTTPS via server-backed proxy”
- PR [NeuralNomadsAI#334](NeuralNomadsAI#334)
“fix(desktop): improve Linux desktop icon integration”
- PR [NeuralNomadsAI#336](NeuralNomadsAI#336)
“fix(desktop): show explicit missing Node errors”
- PR [NeuralNomadsAI#337](NeuralNomadsAI#337)
“fix(build): align Rollup native packages with supported platforms”
- PR [NeuralNomadsAI#341](NeuralNomadsAI#341) “Fix
WSL UNC OpenCode binaries on Windows”
- PR [NeuralNomadsAI#342](NeuralNomadsAI#342)
“fix(desktop): align Electron package and runtime app ids”
- PR [NeuralNomadsAI#351](NeuralNomadsAI#351)
“feat(server): expose opencode server proxy url env”
- PR [NeuralNomadsAI#352](NeuralNomadsAI#352)
“feat(ui): add markdown preview to file viewer”
- PR [NeuralNomadsAI#360](NeuralNomadsAI#360)
“fix(config): install opencode plugin workspace deps”
- PR [NeuralNomadsAI#361](NeuralNomadsAI#361)
“fix(server): preserve selected workspace root”
- PR [NeuralNomadsAI#362](NeuralNomadsAI#362)
“fix(ui): reconnect closed SSE streams”
- PR [NeuralNomadsAI#366](NeuralNomadsAI#366)
“fix(server): respect configured OpenCode auth”

### @VooDisss

- PR [NeuralNomadsAI#302](NeuralNomadsAI#302)
“improve delete worktree failure diagnostics”
- PR [NeuralNomadsAI#304](NeuralNomadsAI#304) “Git
diff monaco redesign”
- PR [NeuralNomadsAI#311](NeuralNomadsAI#311)
“Refactor Git Changes workflow and diff handling”

### @jollyxenon

- PR [NeuralNomadsAI#386](NeuralNomadsAI#386)
“fix(ui): scope session list by workspace folder”
…cloning, chat search and more (NeuralNomadsAI#443)

## Thanks for contributions

- [@pascalandr](https://github.com/pascalandr):
[NeuralNomadsAI#394](NeuralNomadsAI#394),
[NeuralNomadsAI#397](NeuralNomadsAI#397),
[NeuralNomadsAI#405](NeuralNomadsAI#405),
[NeuralNomadsAI#410](NeuralNomadsAI#410),
[NeuralNomadsAI#411](NeuralNomadsAI#411),
[NeuralNomadsAI#423](NeuralNomadsAI#423),
[NeuralNomadsAI#424](NeuralNomadsAI#424),
[NeuralNomadsAI#425](NeuralNomadsAI#425),
[NeuralNomadsAI#426](NeuralNomadsAI#426),
[NeuralNomadsAI#428](NeuralNomadsAI#428),
[NeuralNomadsAI#436](NeuralNomadsAI#436)
- [@jollyxenon](https://github.com/jollyxenon):
[NeuralNomadsAI#381](NeuralNomadsAI#381),
[NeuralNomadsAI#409](NeuralNomadsAI#409)
- [@OfflinePing](https://github.com/OfflinePing):
[NeuralNomadsAI#415](NeuralNomadsAI#415)

## Highlights

- **Web previews create a much tighter fix loop**: Open a live preview
from a session, highlight the exact part of the page that needs work,
and tell the model what to change right from the webpage. CodeNomad
sends that page and element context back into chat so the LLM can act on
specific visual feedback instead of vague descriptions.
- **Bringing repositories into CodeNomad is much easier**: You can now
clone a Git repository directly from the workspace picker, making it
faster to start work on a fresh project without leaving the app.
- **Searching inside long conversations is finally practical**: Session
history search can now find matches across messages, tool output, and
related content, helping you jump straight to the part of a conversation
you need.
- **Sessions are easier to manage at a glance**: Parent sessions now
show aggregated token and cost totals across subagents, the message
timeline can be hidden when you want more room, and tabs can be
reordered.
- **Mobile views and narrow screens feel much better**: Prompt controls,
message actions, timeline behavior, and other session UI pieces adapt
more cleanly when space gets tight.

## What’s Improved

- **Smoother workspace startup**: The home screen, empty states, and
startup flow are clearer, and returning between active projects and the
home view feels more natural.
- **More useful browsing and previewing**: Markdown now supports math
rendering, web previews are integrated into the session flow, and
unrestricted browsing respects the selected workspace root more
reliably.
- **Cleaner model and agent selection**: Models are grouped by provider,
and primary agent selection now follows OpenCode’s visibility rules more
closely.
- **Better prompt and attachment handling**: File attachment picking is
more consistent with drag-and-drop behavior, and prompt controls are
laid out more clearly in compact layouts.
- **More self-contained packaging**: Desktop builds do a better job
bundling the runtime, shipping the CodeNomad OpenCode plugin, and
producing more consistent release artifacts.

## Fixes

- **Permission flows are more reliable**: Stale permission events are
ignored after a reply, permission metadata is preserved more safely, and
attachment context survives more consistently.
- **Idle/session indicators behave more predictably**: Idle badges now
stay visible until they are actually seen, and session status behavior
is easier to understand across parent and child sessions.
- **Desktop and packaged builds are more dependable**: Bundled resources
refresh more reliably, packaged session storage is isolated correctly,
remote window titles are preserved, and Windows resource preparation
avoids a brittle shell path.
- **Compact layouts are less frustrating**: Message actions, tool-call
controls, timeline spacing, and prompt controls behave better in narrow
center panes and smaller screens.
- **Release/update navigation is clearer**: Update links stay visible
more reliably, making it easier to see and open release information when
an update is available.

### Contributors

-   [@pascalandr](https://github.com/pascalandr)
-   [@jollyxenon](https://github.com/jollyxenon)
-   [@OfflinePing](https://github.com/OfflinePing)

## Merged Pull Requests

### @shantur

- PR [NeuralNomadsAI#397](NeuralNomadsAI#397) “Add
clone repository workspace flow”
- PR [NeuralNomadsAI#399](NeuralNomadsAI#399)
“feat(ui): allow tab reordering”
- PR [NeuralNomadsAI#400](NeuralNomadsAI#400)
“feat(ui): add chat history search”
- PR [NeuralNomadsAI#430](NeuralNomadsAI#430) “Add
session web preview mode”
- PR [NeuralNomadsAI#432](NeuralNomadsAI#432)
“fix(ui): align prompt attachment picker with drop behavior”
- PR [NeuralNomadsAI#433](NeuralNomadsAI#433)
“Package CodeNomad OpenCode plugin”
- PR [NeuralNomadsAI#434](NeuralNomadsAI#434)
“Refactor workspace startup and empty session states”
- PR [NeuralNomadsAI#437](NeuralNomadsAI#437)
“Improve prompt layout for narrow session panes”
- PR [NeuralNomadsAI#438](NeuralNomadsAI#438)
“Improve messages layouts on narrow screens”

### @pascalandr

- PR [NeuralNomadsAI#394](NeuralNomadsAI#394)
“fix(tauri): refresh bundled resources on rebuild”
- PR [NeuralNomadsAI#405](NeuralNomadsAI#405)
“fix(tauri): prefer bundled server entry in release”
- PR [NeuralNomadsAI#410](NeuralNomadsAI#410)
“fix(ui): keep update release link visible”
- PR [NeuralNomadsAI#411](NeuralNomadsAI#411)
“fix(ui): return to active projects from home”
- PR [NeuralNomadsAI#423](NeuralNomadsAI#423)
“fix(ui): follow up idle badge behavior”
- PR [NeuralNomadsAI#424](NeuralNomadsAI#424)
“fix(ui): drain yolo permissions outside shell render”
- PR [NeuralNomadsAI#425](NeuralNomadsAI#425)
“fix(ui): ignore stale permission events after reply”
- PR [NeuralNomadsAI#426](NeuralNomadsAI#426)
“fix(ui): reconcile permission tool attachments”
- PR [NeuralNomadsAI#428](NeuralNomadsAI#428)
“feat(ui): make message timeline hideable”
- PR [NeuralNomadsAI#436](NeuralNomadsAI#436)
“fix(electron): avoid shell for resource prep”

### @OfflinePing

- PR [NeuralNomadsAI#415](NeuralNomadsAI#415)
“feat(ui): show aggregated total tokens and cost for parent sessions
including subagents”

### @jollyxenon

- PR [NeuralNomadsAI#381](NeuralNomadsAI#381)
“Fix(ui): Support Markdown Math Rendering”
- PR [NeuralNomadsAI#409](NeuralNomadsAI#409)
“fix(ui): align primary agent selection with OpenCode”
Adds a two-step deny flow for permission requests so users can provide optional feedback before rejecting. The feedback is trimmed and passed through sendPermissionResponse to the OpenCode permission.reply SDK call as the optional message field.

Updates both the permission approval modal fallback and the loaded tool-call permission block so deny actions consistently ask for a reason. Adds localized UI copy and shared styling for the textarea, confirm, and cancel controls.

Validation: npm run typecheck --workspace @codenomad/ui; npm run build:ui.
Prevents active permission keyboard shortcuts from firing while users type into inputs or textareas, so Enter and A cannot accidentally approve a request while entering rejection feedback.

Adds a shared maximum length for reject feedback textareas to bound the message sent through the permission reply flow, and removes the stale deny shortcut translations now that the D shortcut is no longer shown.

Validation: git diff --check; npm run typecheck --workspace @codenomad/ui; npm run build:ui; npm run build:linux --workspace @neuralnomads/codenomad-electron-app.
@OfflinePing OfflinePing requested a review from a team May 23, 2026 12:33
@OfflinePing OfflinePing changed the base branch from main to dev May 23, 2026 12:46
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/26333065811

Artifacts expire in 7 days.
Artifacts:

  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-tauri-macos
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-electron-macos
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-tauri-macos-arm64
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-tauri-windows
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-tauri-linux
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-electron-windows
  • pr-499-c9ff27c723ba55859670ce132d8b0260aa26cb43-electron-linux

@pascalandr
Copy link
Copy Markdown
Contributor

@CodeNomadBot

I want you to perform the gatekeeper checks for latest PR state

check for regressions
check for better possible implementations
Be the PR gatekeeper
Be ruthless about code quality

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 23, 2026

Understood request: perform a strict gatekeeper review of the latest PR #499 state, focused on regressions and implementation quality. Assumption: this is a review-only request, not a request to patch the branch.

Gatekeeper Result: Changes Requested

Blocking finding

  1. packages/ui/src/components/tool-call.tsx:246 and packages/ui/src/components/tool-call/permission-block.tsx:117 / 149

    Opening the new deny feedback step does not disable the existing document-level permission shortcuts. After clicking Deny, focus remains on a button, not the textarea. If the user presses Enter before focusing the textarea, the handler in tool-call.tsx still treats Enter as Allow once and submits an allow response. Similarly, pressing A while focus is on the reject-step buttons still submits Always allow.

    This is a permission safety regression: the UI is visually in a deny confirmation flow, but a keyboard action can approve the permission.

    Better implementation: while the reject-reason UI is open, either disable the global allow shortcuts for that permission or move the shortcut handling into PermissionToolBlock where it can see showRejectReason(). Autofocusing the textarea would help, but is not sufficient by itself because focus can still move to Confirm Deny / Cancel buttons where Enter/A remain dangerous.

Non-blocking quality notes

  1. The reject-reason form is duplicated between PermissionToolBlock and the permission center fallback in permission-approval-modal.tsx. This is manageable right now, but the duplicated trimming, max-length, labels, and button behavior make future regressions more likely. A small shared component would be cleaner if this UI continues evolving.

  2. There is no focused test coverage for forwarding the reject feedback as message or for omitting empty/whitespace-only feedback. Given this PR changes permission reply semantics, a narrow store-level test around the client.permission.reply payload would be valuable.

Validation attempted

  1. npm run typecheck --workspace @codenomad/ui could not complete in this local worktree because dependencies/types are not installed/resolved (solid-js, @opencode-ai/sdk, Node test types, etc.).

  2. npm run build:ui could not complete because Rollup's optional native package @rollup/rollup-darwin-arm64 is missing from the local install.

These validation failures look environment/dependency-install related rather than caused by this PR, but I could not use local commands to prove the branch is green.

Verdict

Do not merge as-is. Fix the keyboard shortcut regression before merging; it can turn an intended denial into an allow response.

--
Yours,
CodeNomadBot

Prevents document-level Allow Once and Always Allow shortcuts from firing while the reject feedback confirmation step is open. This avoids approving a permission when focus remains on Deny, Confirm Deny, or Cancel after entering the rejection flow.

Validation: git diff --check; npm run typecheck --workspace @codenomad/ui.
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/26337762777

Artifacts expire in 7 days.
Artifacts:

  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-electron-macos
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-tauri-macos
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-tauri-linux
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-tauri-windows
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-tauri-macos-arm64
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-electron-windows
  • pr-499-16cb45f64b6a0ace98335122548e0d330263c08a-electron-linux

@pascalandr
Copy link
Copy Markdown
Contributor

@CodeNomadBot
same review

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 25, 2026

Understood request: rerun the same strict gatekeeper review against the latest PR #499 state. Assumption: this is review-only; no code changes requested.

Gatekeeper Result: Approved With Caveats

Findings

No blocking regressions found in the latest state.

The previous blocking issue is addressed by commit 16cb45f:

  1. packages/ui/src/components/tool-call.tsx:247-250

    The document-level permission shortcuts now return early when either a text input is focused or permissionRejectReasonOpen() is true. This closes the safety hole where opening the deny feedback step could still allow Enter or A to approve the permission.

  2. packages/ui/src/components/tool-call/permission-block.tsx:28-35 and 123 / 163

    PermissionToolBlock now reports reject-reason visibility back up to ToolCallDetails, and resets it when the permission id changes or the reject step is cancelled. That is a reasonable, minimal fix for the shortcut regression.

Remaining non-blocking quality notes

  1. packages/ui/src/components/permission-approval-modal.tsx:416-458 duplicates most of the reject-reason form from packages/ui/src/components/tool-call/permission-block.tsx:139-170. This is acceptable for the current scope, but if this UI changes again, a small shared reject-reason form component would reduce drift risk.

  2. packages/ui/src/stores/instances.ts:1106-1110 forwards message only when truthy, which matches the callers trimming whitespace to undefined. I would still prefer a narrow unit test around the reply payload so regressions in the permission response contract are caught without relying on manual review.

Validation attempted

  1. npm run typecheck --workspace @codenomad/ui still cannot complete in this local worktree because dependencies/types are unresolved (solid-js, @opencode-ai/sdk, Node test types, etc.).

  2. npm run build:ui still cannot complete because Rollup's optional native package @rollup/rollup-darwin-arm64 is missing from the local install.

These look like local dependency-install/environment failures, not PR-specific failures. GitHub Actions artifacts for commit 16cb45f were posted in the thread, which is a better signal for build health here.

Verdict

The latest branch fixes the prior permission-safety blocker. From code review, I do not see a merge-blocking regression in this PR state. Keep the test coverage note as follow-up unless the team requires payload tests for permission reply changes before merge.

--
Yours,
CodeNomadBot

@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/26415938846

Artifacts expire in 7 days.
Artifacts:

  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-tauri-linux
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-tauri-macos
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-tauri-windows
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-electron-macos
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-tauri-macos-arm64
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-electron-windows
  • pr-499-16290474373a4101f531f5df16dd7a0a13838600-electron-linux

@pascalandr pascalandr merged commit d639b83 into NeuralNomadsAI:dev May 25, 2026
11 checks passed
@OfflinePing OfflinePing deleted the pr/496-reject-reason-ui-clean branch May 25, 2026 19:50
@pascalandr
Copy link
Copy Markdown
Contributor

@OfflinePing
Thanks !

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.

3 participants