Approve or reject agent actions
When an autonomous agent reaches a point it should not pass without a human, it pauses and asks for approval. SupaCloud surfaces that one pending decision as an interactive approval you can answer from any control surface — the web terminal, Telegram, or Discord. The agent stays blocked on exactly that decision until you respond (or its timeout policy resolves it for you).
There are four kinds of approval:
| Kind | What it is | Example |
|---|---|---|
| Tool | A dangerous tool call the agent wants to run | A Bash command, a deploy, a migration |
| Question | An open question the agent asks before continuing | “Which environment should I target?” |
| Visual | A before/after screenshot sign-off | UI change captured for human review |
| Model class change | The pinned model class ran out and SupaCloud wants to drop to a weaker one | “Premium quota exhausted — continue on the standard class?” |
Two of them can be raised by SupaCloud itself rather than by the agent: a safety hold (a Tool gate SupaCloud forces after the agent reached for something in the danger set — the run is interrupted and parked) and the model class change above. Both reach your chat with the same card and the same buttons; before, they were visible only in the web UI.


Approve from the web terminal
Section titled “Approve from the web terminal”In the web terminal at /cli, list every paused agent in the active workspace
and decide one by its short id.
# List the interactive approvals waiting across the workspacetool-approvals
# Approve or reject one by its (short) approval id; an optional note# is passed back to the agent as your reason / answerapprove-tool <id> [note]reject-tool <id> [note]The id is resolved by prefix the same way task ids are: a unique prefix decides the gate; an ambiguous or unknown prefix is reported rather than guessed.
You can also list both interactive and workflow approvals together. The filter is a plain word after the command — the same word on every surface:
approvals # both sources, each under its own headingapprovals all # the same thing, stated explicitlyapprovals tool # only the interactive tool/question/visual/model-class gatesapprovals workflow # only workflow human-gatesThe bare command answers the whole question, so all is never something you
must type. A word the command does not know (approvals wokflow) is reported as
unknown rather than quietly listing half the gates. The web terminal
additionally accepts the older --filter=<word> spelling, so
approvals --filter=tool is the same command as approvals tool.
After you follow (or run) a task and it pauses, the terminal renders the
gate inline — the kind, the tool name or question, and any before/after image
URLs — then waits for your next input line:
approve,yes,y, orokapproves. Anything after the verb is sent as your note.reject,no,n, ordenyrejects, with an optional reason.- For a question gate, a plain free-text line (no verb) is treated as the answer and approves the gate, carrying your text back to the agent.
Approve from Telegram or Discord
Section titled “Approve from Telegram or Discord”When a task you own pauses, SupaCloud posts an approval card to your linked chat — one message with the kind, the task title, the redacted detail, any before/after image previews, a direct link to the task, and inline Approve / Reject buttons. Tap a button to decide; you never type an id.
For a tool gate the card leads with the agent’s intent — the tool call’s own description, or the safety reason that held the run — then shows the actual command in monospace. A shell command whose every part only reads carries a small reads only chip as orientation; the raw call payload stays one tap away in a collapsed quote. After you decide, the card keeps the request visible and appends your verdict beneath it, so the chat history still says what was allowed or denied.
If the agent asks something that is not a gate — an open question mid-run — the
push carries the question itself and a Reply button. Press it and simply type
your answer: it is routed to that exact task, because the button carries the task
reference. /intervene <id> <message> still works for scripts and automation, but
it is no longer the only way to answer from a phone.
-
A paused task pushes the card automatically to the chat linked to the task owner. Tap Approve or Reject; the bot replies with a confirmation.
-
To review what is waiting at any time:
/approvals # both human-gate and interactive approvals/approvals all # the same thing, stated explicitly/approvals tool # only the interactive tool/question/visual/model-class gates/approvals workflow # only workflow human-gates
-
The same card is posted to the linked Discord identity, with Approve / Reject buttons. Visual gates embed the before/after screenshots inline.
-
List pending approvals with:
/approvals
The visual before/after card
Section titled “The visual before/after card”A visual approval is a sign-off on a UI change. The card carries:
- The before/after screenshots as signed, time-limited image links (Telegram previews them, Discord embeds them; in the web terminal they print as URLs).
- The machine judge verdict when one ran —
PASS,FAIL, or not run — human review — followed by the reasons the judge gave, so you can see why the automated check thinks the change passes or fails before you decide.
If the screenshot links cannot be built (the capture-serve secret is unset) the card degrades to text-only: it still lists what was captured and the judge verdict, so you can always make a decision.
What happens when an approval times out
Section titled “What happens when an approval times out”Every approval carries a timeout policy that decides what happens if no human responds:
| Policy | Behaviour | Used for |
|---|---|---|
| Hold | Blocks forever until a human decides — never auto-resolved | Deploys, migrations, and any action forced to wait on a human |
| Deny | Auto-denied after a deadline so the agent continues without the action | Optional questions and lower-risk gates |
The deny deadlines are per kind: a tool waits 5 minutes, a question 30
minutes, and a visual sign-off 1 hour. When a deny gate times out the
agent is unblocked with a denial and continues; a hold gate simply waits.
When a safety hold cannot be resumed
Section titled “When a safety hold cannot be resumed”A safety hold always stops the agent from getting past the flagged action, but whether deciding it can resume that run depends on the agent — and, for two of them, on how that particular run was launched. The card says which case you are in, in square brackets after the danger reason. Read it before you decide:
| What the card adds | What actually happened | Your next move |
|---|---|---|
| nothing | The agent paused and is waiting for you | Approve or reject — the run carries straight on |
| not resumable … restart the task | The agent was stopped, not paused | Decide the gate to record your verdict, then restart the task |
| not enforced … the run was NOT stopped | The interrupt reached nothing; the run is still executing | Cancel the task if it must stop |
| soft hold … deliberately NOT stopped | SupaCloud asked without stopping, because the only stop available would have killed a healthy run. The chat card is headed Agent keeps running (not paused) and offers only Allow / Deny — no always rules, because there is nothing to allow | Allow dismisses the hold and changes nothing else; Deny cancels the task |
A card whose gate was settled somewhere else — on the web inbox, on the other chat surface, by the coordinator, or because the agent ended before anyone decided — is edited in place: the buttons disappear and a line underneath says what happened (decided elsewhere, no longer applies, timed out). A card that still shows buttons is a gate that is still open.
Two agents answer differently from one run to the next, so the same agent name is not a reliable guide:
- Gemini pauses when the run uses an API key, and is stopped when it signs
in with Google OAuth — an OAuth run is driven by the
agycommand-line tool, which the interrupt can only kill. - opencode pauses when the run has interactive approvals armed, and is stopped otherwise.
Where SupaCloud cannot tell which of the two a run took, the card says so (cannot confirm …) and assumes the run was stopped. It never promises you a resumption it has not verified — so a hold that says restart the task may occasionally be a run that could in fact have been resumed, never the other way round.