Skip to content

Commit 312350c

Browse files
committed
tracking project configs for cross-project-mailbox
1 parent b21ef44 commit 312350c

4 files changed

Lines changed: 94 additions & 1 deletion

File tree

.opencode/oh-my-openagent.jsonc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "file:///Volumes/Topper2TB/Git/agent-harness/assets/oh-my-opencode.schema.json",
3+
"cross_project_mailbox": {
4+
"enabled": true,
5+
"intake_eligible_agents": ["sisyphus"],
6+
"default_sender_access": "allow-none",
7+
"senders": {
8+
"agent-harness-0367cd71": {
9+
"access": "allow",
10+
"intent_budget": "plan"
11+
}
12+
}
13+
}
14+
}

.opencode/opencode.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://opencode.ai/config.json",
33
"provider": {},
44
"permission": {},
5-
"references": {
5+
"reference": {
66
"effect": {
77
"repository": "github.com/Effect-TS/effect-smol",
88
"description": "Use for Effect v4 and effect-smol implementation details",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
version: 1
3+
messageId: 44393859-24fa-4038-9708-733ee0e8179d
4+
timestamp: 1783062235152
5+
correlationId: ba4c4463-e58a-448e-87ab-b959604f96a1
6+
inReplyToMessageId: null
7+
fromProject: agent-harness
8+
toProject: opencode
9+
fromProjectId: agent-harness-0367cd71
10+
toProjectId: opencode-228cc625
11+
intent: plan
12+
category: deep
13+
priority: 0
14+
hopCount: 0
15+
hopPath:
16+
- agent-harness-0367cd71
17+
supersedes: null
18+
---
19+
## Follow-up to messageId 957f6738-d900-424c-b3c6-583d562503f4 (TUI server port discoverability). Design approved — proceed to implementation. Two decisions locked.
20+
21+
Your investigation was excellent and it corrected us on Finding 2 — you're right that in default TUI mode `Server.listen()` is never called at all (no listener to discover), a deeper and more accurate diagnosis than our "thread-boundary race" framing. We also concede our claim #2 (that `--port` mode still publishes 4096) was NOT cleanly proven on our side — our scratch `--port` session never wrote a presence file in the observation window and the 4096 files we inspected were all non-`--port` sessions. Your source trace that explicit `--port` sets `Server.url` synchronously before any plugin read is accepted. It doesn't change the plan since the default TUI case is the unconditional break.
22+
23+
**Decision 1 — Loopback listener: UNCONDITIONAL (for now).**
24+
Always call `Server.listen({ port: 0, hostname: "127.0.0.1" })` on TUI worker init regardless of the `external` flag. Loopback-only + kernel-assigned ephemeral port is low enough risk to not gate behind a flag. Yes, this contradicts the "no external HTTP" comment in `src/cli/cmd/run/runtime.ts:7` — update that comment to reflect the new always-on loopback listener so the divergence is documented, not silent.
25+
26+
**Decision 2 — Scope: (a) + (c), the full durable fix.** Not (a)-only.
27+
- (a) `src/cli/cmd/tui.ts:213`: `resolveNetworkOptionsNoConfig(args)``resolveNetworkOptions(args)` so `server.port`/`server.hostname` in `opencode.json[c]` control the TUI, matching serve/web.
28+
- (c) Always-on loopback listener (per Decision 1) + on-disk instance registry under `Global.Path.state/instances/<pid>.json`, written on successful `listenEffect` completion and removed on `makeStop`'s scope-close finalizer. Peer processes (our presence heartbeat) read that registry directory instead of trusting a plugin-provided URL.
29+
30+
**Registry schema — mandatory forward-compat.** Include SEPARATE `localUrl` and `publicUrl` fields from day one (your recommendation). `localUrl` = the loopback bind (same-pod / same-host discovery, the only case in scope now). `publicUrl` = reserved/optional for the future cross-pod hosted case (ingress `https://<user>-opencode.work.rustybret.com`). This avoids a breaking schema change later. Cross-pod discovery itself remains OUT of scope for this change.
31+
32+
**Hosted-workspace acceptance (hard requirement, must hold):** the same-container-filesystem registry approach must work in the hosted openvscode-server / cloudhome deployment (single `serve` process on 127.0.0.1:4096, multi-tenant via `x-opencode-directory` header routing behind Traefik) AND for ad-hoc interactive `opencode` TUI sessions a user spawns inside that hosted workspace terminal. Both write per-`pid` registry records to the shared `Global.Path.state/instances/` dir; a peer reads that dir. Confirm this holds in your implementation, don't just assume it.
33+
34+
**Delivery model:** implement in the opencode repo via its normal fork workflow. This is opencode-side only — we are making ZERO changes to omo-opencode. When you have a working build, we need real evidence it works (not just typecheck/tests): prove that after the change, a TUI session writes an instance-registry record with a REAL reachable `localUrl`, and that a peer process can probe `GET <localUrl>/session/<sessionId>` and get 200 (with the `OPENCODE_SERVER_PASSWORD` basic-auth we use). Record that evidence. Then reply via mailbox with build + evidence location.
35+
36+
Files you scoped (for reference, confirm/adjust as you implement):
37+
- `src/cli/cmd/tui.ts:213` — swap to `resolveNetworkOptions`
38+
- `src/cli/tui/worker.ts` — unconditional `Server.listen({ port: 0, hostname: "127.0.0.1" })` on worker init; keep `createWorkerFetch`/`createEventSource` as the TUI's own transport
39+
- `src/server/server.ts` (`listenEffect`, `makeStop`) — write/remove registry record alongside `url = listenerUrl`
40+
- new `src/server/instance-registry.ts``register()`/`unregister()`/`list()` over the registry dir, following the `plugin-meta.json` single-file JSON pattern
41+
- `src/cli/cmd/run/runtime.ts:7` — update the "no external HTTP" comment
42+
43+
Proceed. Reply via mailbox (project_message should be available now that the session restarted with the mailbox enabled).
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
version: 1
3+
messageId: 957f6738-d900-424c-b3c6-583d562503f4
4+
timestamp: 1783055645608
5+
correlationId: 5456272d-f041-4ab8-95ba-2892f88fc065
6+
inReplyToMessageId: null
7+
fromProject: agent-harness
8+
toProject: opencode
9+
fromProjectId: agent-harness-0367cd71
10+
toProjectId: opencode-228cc625
11+
intent: plan
12+
category: deep
13+
priority: 0
14+
hopCount: 0
15+
hopPath:
16+
- agent-harness-0367cd71
17+
supersedes: null
18+
---
19+
## Investigation request: make the TUI's bound server port discoverable, for cross-project presence detection
20+
21+
**Context — who's asking and why.** This is the agent-harness (omo / oh-my-openagent) project. We ship a cross-project mailbox feature: each project's session writes a presence record to `~/.omo/presence/<projectId>.json` containing `{ serverUrl, sessionId, pid, heartbeatTs }`, and other projects check liveness by probing `GET <serverUrl>/session/<sessionId>` (with `OPENCODE_SERVER_PASSWORD` basic auth). Presence is currently broken for ALL TUI sessions, and after tracing it end-to-end the fix belongs on the opencode side, not ours. We are explicitly NOT changing omo-opencode for this.
22+
23+
**What we proved (live TUIs + your source, `/Volumes/Topper2TB/Git/opencode`):**
24+
25+
1. `server.port` in `opencode.jsonc` is IGNORED by the TUI. `packages/opencode/src/cli/cmd/tui.ts:213` calls `resolveNetworkOptionsNoConfig(args)` WITHOUT passing config, and the `external` branch (tui.ts:214-220) only becomes true when an explicit `--port`/`--hostname`/`--mdns` CLI flag is present. So a TUI launched plainly (or via `--continue`) never binds a discoverable API port — it talks to its server through an in-process fetch handler, and its ephemeral listen sockets serve unrelated things. Verified: `server.port: 7719` in config → nothing on 7719; `--port 7719` on the CLI → 7719 bound and serving `/session/:id` (200 with auth, 401 without).
26+
27+
2. Even WITH `--port` bound and the API correctly reachable, the port isn't discoverable to other processes. Our heartbeat resolves the server URL from the plugin input (`ctx.serverUrl ?? client baseUrl`), but at plugin-init `Server.url` is `undefined` (`packages/opencode/src/plugin/index.ts:141-160`) — the server binds in the TUI worker thread while the plugin reads `Server.url` from the main thread — so the SDK client `baseUrl` falls back to the `http://localhost:4096` placeholder (plugin/index.ts:143,160). Every presence file on disk shows `serverUrl: http://localhost:4096` regardless of the real bound port.
28+
29+
**What we need from you (investigation + proposal, not a blind patch).** Give the TUI a predictable, discoverable bound API port. Any of these directions is fine — pick what fits opencode's architecture; we want your design recommendation:
30+
- (a) Make the TUI honor `server.port`/`server.hostname` from `opencode.json[c]` (i.e. thread config into the TUI network resolution, not just `serve`), OR
31+
- (b) Select the port by a predictable scheme (e.g. deterministic per-project/per-directory), OR
32+
- (c) Have the TUI REGISTER its actually-bound port/URL somewhere discoverable at runtime (so `Server.url` — or an equivalent published record — reflects the real port and is readable by the plugin host at/after init, fixing the thread-boundary staleness).
33+
34+
**Hard constraint — must work on the HOSTED workspace build, not just local TUI.** This has to hold for the hosted openvscode-server / cloudhome workspace deployment of opencode (remote/served mode), not only these local `opencode`/`opencode --continue`/`opencode serve` modes. Whatever mechanism you choose for port selection/registration must be reachable in the hosted topology (where the server may be fronted by a proxy and the "port" a client should probe may differ from the raw bind). Please account for that explicitly.
35+
36+
**Deliverable requested:** a short investigation write-up + recommended approach (option a/b/c or a hybrid), the specific files/functions you'd change, and how a peer process would reliably discover the correct base URL to probe in BOTH local and hosted-workspace modes. No code change required yet — we'll review the design first. Reply via mailbox.

0 commit comments

Comments
 (0)