Skip to content

feat(grunt/tui): in-process wake listener — rip out daemon#7

Merged
terrxo merged 1 commit into
devfrom
grunt-feat/in-tui-wake-listener
May 26, 2026
Merged

feat(grunt/tui): in-process wake listener — rip out daemon#7
terrxo merged 1 commit into
devfrom
grunt-feat/in-tui-wake-listener

Conversation

@terrxo
Copy link
Copy Markdown

@terrxo terrxo commented May 26, 2026

Replaces the daemon + auto-attach dance (v1.15.10-grunt.2/.3) with an in-process HTTP wake listener bound by the TUI worker itself. Wakes land in the same process that owns the session — no SSE relay, no render bug.

  • pickFreePort() picks a free port pre-worker-spawn
  • Worker env gets OPENCODE_WAKE_PORT + OPENCODE_SERVER_URL stamped in
  • TUI calls client.call('server', {port, host}) post-worker-boot
  • Escape hatch: OPENCODE_DISABLE_WAKE_LISTENER=1

Deletes auto-serve.ts. Closes anomalyco#224 follow-up.

The daemon + auto-attach architecture was a workaround for stock opencode's
non-wakeable TUI. With this patch the TUI worker itself binds an HTTP
listener on a pre-picked free localhost port, exposing the same
/session/<id>/prompt_async endpoint used by 'opencode serve' but
in-process. Wake POSTs land directly in the same process that owns the
session, so rendering Just Works (no SSE relay, no attach client, no
display bug).

Concretely:
- New pickFreePort() helper picks a free port via node:net before spawning
  the worker.
- Worker spawn env gets OPENCODE_WAKE_PORT + OPENCODE_SERVER_URL stamped
  in so MCP children inherit them via sanitizedProcessEnv (hivemind-mcp
  auto-announce reads OPENCODE_WAKE_PORT to register peers as wakeable).
- Right after worker boot, TUI calls client.call('server', {port, host})
  which makes Server.listen() bind. Existing 'external' path (server, port
  flag) is preserved as before.
- Escape hatch: OPENCODE_DISABLE_WAKE_LISTENER=1 skips the bind (legacy
  non-wakeable mode, same as upstream).

Drops auto-serve.ts (the daemon-discovery module). The daemon mode is
gone. Closes anomalyco#224 follow-up.

bun typecheck clean.
@github-actions
Copy link
Copy Markdown

Hey! Your PR title feat(grunt/tui): in-process wake listener — rip out daemon doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions
Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@terrxo terrxo merged commit 3ff22ea into dev May 26, 2026
3 of 10 checks passed
@terrxo terrxo deleted the grunt-feat/in-tui-wake-listener branch May 26, 2026 22:17
terrxo added a commit that referenced this pull request May 28, 2026
)

The daemon + auto-attach architecture was a workaround for stock opencode's
non-wakeable TUI. With this patch the TUI worker itself binds an HTTP
listener on a pre-picked free localhost port, exposing the same
/session/<id>/prompt_async endpoint used by 'opencode serve' but
in-process. Wake POSTs land directly in the same process that owns the
session, so rendering Just Works (no SSE relay, no attach client, no
display bug).

Concretely:
- New pickFreePort() helper picks a free port via node:net before spawning
  the worker.
- Worker spawn env gets OPENCODE_WAKE_PORT + OPENCODE_SERVER_URL stamped
  in so MCP children inherit them via sanitizedProcessEnv (hivemind-mcp
  auto-announce reads OPENCODE_WAKE_PORT to register peers as wakeable).
- Right after worker boot, TUI calls client.call('server', {port, host})
  which makes Server.listen() bind. Existing 'external' path (server, port
  flag) is preserved as before.
- Escape hatch: OPENCODE_DISABLE_WAKE_LISTENER=1 skips the bind (legacy
  non-wakeable mode, same as upstream).

Drops auto-serve.ts (the daemon-discovery module). The daemon mode is
gone. Closes anomalyco#224 follow-up.

bun typecheck clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant