Feedback to fix
The widget isn’t only for your customers. When one of your admins is looking at a broken page in your own app, they can file feedback about it from the same chat window — with the page, the element and the render trail already attached — and hand it straight to a coding agent.
This is a loop: notice it, file it, dispatch it, get a PR.
Filing feedback
Section titled “Filing feedback”The feedback controls only appear for admins. On your own site, the
Ruby gem loads an in-page inspector when the
identified user’s role is one of config.admin_roles (admin and
owner by default). Where the inspector isn’t present, the feedback
menu stays hidden and the slash commands refuse. The Node, Python and
WordPress packages don’t load the inspector.
With it loaded, there are three ways in:
The 💡 menu in the widget’s header, with two items:
- 🎯 Inspect an element — collapses the panel and turns the page into an element picker. Click the thing that’s wrong, add a note, optionally capture a screenshot, submit.
- 📝 Send a note — opens the note panel for a page-level comment with no element picked.
/inspect — same as the menu item. /inspect the button is misaligned pre-fills the note.
/note — files a page-level note. /note the total is wrong on mobile submits immediately; /note on its own opens the panel.
Filing switches the widget to the feedback’s own conversation, so any reply — from a teammate or from a dispatch agent — lands in the same window you filed from.
What gets captured
Section titled “What gets captured”A note is capped at 4,000 characters. Alongside it:
- Where you were — the full page URL, the path, and the controller#action that rendered it.
- What rendered — the ordered list of partials Rails rendered for that request. This is the single most useful field when you’re hunting for which file to open, and it’s why the Rails gem captures it server-side rather than guessing from the DOM.
- The viewport — width and height, so “only broken on mobile” is visible rather than guessed.
- The element, when you picked one — a short CSS selector path, the tag name, its visible text (up to 500 characters) and its outer HTML (up to 4,000).
- Screenshots, if you captured or pasted any. They’re attached to the ticket and shown on its page.
- Who filed it — the visitor identity your
identify()call supplied: name, email and role.
Everything lands as a ticket on your workspace’s Feedback page, with a
linked conversation. Tickets move open → triaged → resolved, or
are dismissed. Seeing them needs feedback.read; changing status or
dispatching needs feedback.manage.
Two ways to act on it
Section titled “Two ways to act on it”1. A dispatch agent you run
Section titled “1. A dispatch agent you run”You can run an agent on your own machine that connects to your workspace, receives feedback the moment it’s filed, works the problem with a coding assistant, and streams the result back into the conversation.
To wire one up, provision a token: API tokens → New token, with the
platform:dispatch scope. The raw token is shown exactly once, on
the page right after you create it — there’s no way to recover it
later, only to revoke and issue a new one. Put it in the agent’s
environment.
Once it’s connected, a Dispatch card on your Dashboard and on the API tokens page shows live status: online with the age of its last heartbeat and what it’s currently doing, or “Not connected”. The agent pings every 20 seconds, and the card polls, so you can see it drop without refreshing.
What you see in the conversation while it works: progress chips as the agent uses tools, and its replies as normal messages. A reply can carry a proposed code change, which renders as a read-only badge (“quick fix” or “PR”) with a summary. Applying a proposal isn’t a workspace control today — the badge tells you one was made, and the agent’s own operator decides what happens with it.
Revoking the token cuts the agent off on its next reconnect.
Like the server libraries, the dispatch agent isn’t publicly distributed yet — ask us and we’ll get you a copy.
2. GitHub Copilot’s coding agent
Section titled “2. GitHub Copilot’s coding agent”The other path needs no daemon of your own: link a GitHub repository and hand a feedback ticket to GitHub’s Copilot coding agent, which works the issue and opens a pull request.
Setup lives at Settings → GitHub (or /w/<workspace-id>/<slug>/ github) and needs settings.read to view, settings.write to change.
If the deployment doesn’t have the Vroxy GitHub App configured, the
page says so and the whole feature stays dark.
Be aware of what this path actually requires, because it’s more than a checkbox:
- Install the Vroxy GitHub App on the account or organization that owns your repositories, and grant it the repos you care about. You’re returned to the picker.
- Authorize Copilot access for your own GitHub account. This is a separate step and it is not optional: Copilot’s agent APIs reject app-installation tokens outright, so dispatch has to run on a personal authorization.
- Then link repositories. Linking verifies that your GitHub account can actually see the installation, which is why step 2 has to come first. A repo you can’t access won’t link.
The account that authorizes is the account that pays. Copilot tasks run on the authorizing user’s Copilot plan and bill to it. That account needs write access to the repository and an active Copilot seat. If the person who authorized leaves, or revokes their authorization, dispatch stops until someone else authorizes.
Each linked repo has a base branch that agent work starts from, and an enabled/disabled toggle so you can pause dispatch to a repo without unlinking it. Repos are kept in sync with GitHub: uninstalling or suspending the App disables its repos, removing a repo from the installation disables that repo, and pull-request activity is recorded against it.
Dispatching. On a feedback ticket, pick a linked, enabled repo and send it. Vroxy then:
- Opens a GitHub issue in that repo containing the feedback context, filed with the App’s installation token.
- Starts a Copilot agent task on that repo against its base branch, asking for a pull request — using your personal authorization.
- If the agent-task API isn’t available to that account, falls back to assigning the issue to Copilot, which is the same work by a different door.
- Marks the ticket
triaged.
Progress comes back into the feedback’s conversation as messages: when Copilot opens a PR (with the link), when the task completes, when it fails and why, and when it’s waiting on you.
Only one dispatch to the same repo can be in flight for a given ticket at a time — sending it twice tells you it’s already running.
What leaves your database. The issue body contains the feedback note, the reporter’s label, role and email, the page URL, path and controller#action, the viewport, the ordered list of rendered partials (up to 40), the picked element’s selector, tag, text and the first 400 characters of its outer HTML, and the linked conversation’s title. Screenshots are not sent. Nothing beyond what the feedback page already shows goes to GitHub — but the issue does land in your repo, so treat it as you’d treat any issue your team can read.
Which one should you use?
Section titled “Which one should you use?”The Copilot path is the one to reach for if your code is on GitHub and your team already has Copilot: nothing to run, nothing to keep alive, and the output is a PR in the normal place. The dispatch-agent path suits a repository that isn’t on GitHub, or a workflow where you want the agent running against a working tree you control.
Neither replaces reading the ticket. Both give you a starting point with the page, the element and the render trail already attached — the context that usually costs you ten minutes of “which page was this again?”.