Skip to content

Answer an IRIS Desktop session's permission prompt or question from the Hive (#190649) - #38

Merged
mayoalexander merged 2 commits into
mainfrom
wt/190649-opencode-answer
Oct 23, 2026
Merged

mayoalexander merged 2 commits into
mainfrom
wt/190649-opencode-answer

Conversation

@mayoalexander

Copy link
Copy Markdown
Contributor

Atlas ticket

#190649. Stacked on #37: merge #37 first. This PR's diff includes #37's commit until then.

What

iris hive answer worked only for Claude Code sessions. Now an opencode / IRIS Desktop session waiting on a permission prompt or a question can be answered from the CLI, the phone, or Claude Code.

  • lib/opencode-pending.js reports the engine's pending requests (GET /permission, GET /question, per directory) in the same waiting shape Claude Code uses, so needs_you, the fleet view and iris hive answer work unchanged. A permission becomes one question with Allow once / Always allow / Reject.
  • POST /api/sessions/opencode/:id/answer replies to that exact pending request (with Desktop's engine password when it's published, via Bridge uses Desktop's engine password when it publishes one (#190647) #37). It returns 409 when the session isn't waiting and 400 when the choice doesn't fit.
  • The task executor now accepts answers for provider opencode.
  • It never auto-approves. An unrecognised choice for a permission is refused, never read as allow.

How verified

  • tests/opencode-pending.test.js: 5 pass on Node 18 and 22. That includes a fake engine over real HTTP that lists the pending permission, gets answered, and receives {reply: "reject"}.
  • Mutation-checked: making an unknown choice default to once fails the test.
  • Related session suites plus engine-auth: 52 pass.

Also needed

The CLI's iris hive answer still refuses non-Claude sessions. That's a one-line companion PR in iris-opencode, coming next.

Live check after deploy

In Desktop, ask the agent to run a command that needs permission, then:

iris hive sessions --status needs_you
iris hive answer <session> 3   # Reject

The Desktop prompt should close as rejected.

🤖 Generated with Claude Code

IRIS integrator and others added 2 commits October 23, 2026 00:57
…90647)

IRIS Desktop's engine listens on 127.0.0.1 with no password (GET /session -> 200 with no
credentials, measured on a Mac 2026-10-22), and this bridge depends on that: findLiveSessionServer
scans loopback ports and calls the engine unauthenticated for send-input, room delivery and page
replies; listing, activity and history fetch it the same way. Turning the password on in Desktop
alone would silently break all of them, so this lands first.

lib/engine-auth.js reads ~/.iris/desktop-engine.json — the file Desktop will write per launch:
{ version, port, username (default "opencode"), password, pid, data_home } — and adds
"Authorization: Basic" to requests for THAT port only (127.0.0.1 or localhost). The published
engine is tried first among session-server candidates. A file another user owns, or one group/
other can read, is ignored. No file (today's Desktop) = no header = exactly the old behaviour.

Applied at every engine call: fetchJsonFromSessionServer (listing, activity, history), the
session lookup, message delivery, and session-host's probe.

Tests: tests/engine-auth.test.js 6 pass on Node 18 and 22 — incl. a real password-protected HTTP
server that answers 401 without the header and 200 with it; the port boundary (4924 vs 49244);
0644/0640 and foreign-uid files ignored. Full suite vs main: no new failures (one loop-liveness
timing test is flaky — 2 of 3 passes when rerun alone, unrelated).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… question from the Hive (#190649)

`iris hive answer` worked only for Claude Code: an opencode / IRIS Desktop session paused on a
permission prompt or a question could be answered only by someone at that Desktop. The engine
exposes both per directory instance (GET /permission, GET /question; POST .../<id>/reply).

- lib/opencode-pending.js: pending prompts per session, in the SAME `waiting` shape Claude Code
  uses (kind 'question', labelled options, held: true) — a permission becomes one question with
  Allow once / Always allow / Reject. resolveAnswer translates a person's choice (number, label,
  plain word; free text only where the question allows it) into the engine reply. An unrecognised
  choice for a permission is REFUSED — never read as "allow".
- GET /api/sessions/opencode?live=1 attaches `waiting` for recently active directories, so
  needs_you and the fleet view show Desktop prompts.
- POST /api/sessions/opencode/:id/answer replies to the session's pending request (with Desktop's
  engine password when published, #37); 409 when not waiting, 400 when the choice does not fit.
- task-executor no longer refuses answers for provider opencode.

Stacked on #37 (engine-auth).

Tests: tests/opencode-pending.test.js 5 pass on Node 18 and 22, incl. a fake engine over real HTTP
that receives {reply: "reject"}; mutation-checked (unknown -> "once" fails the test). Related
session suites + engine-auth: 52 pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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