fix: contribution setup#224
Closed
Dizzzmas wants to merge 1 commit into
Closed
Conversation
Member
|
hey appreciate this but i just removed the weird config file for now |
5 tasks
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 26, 2026
…ommand wakeable TUI) (#5) ## Goal Bare `gruntcode` (no subcommand) should Just Work — the launched TUI is automatically wakeable. No `serve` + `attach` two-command dance, no shell wrapper. Nik framing 2026-05-26: "like i run gruntcode and things can get woken up via hivemind". ## Behavior of bare `gruntcode` now 1. Probes http://127.0.0.1:4096/session — if a daemon is already serving there, attach to it. 2. If no daemon: spawns one as a detached child (`gruntcode serve --port 4096 --hostname 127.0.0.1 --print-logs`), waits up to 10s for readiness. 3. Re-execs into `gruntcode attach <url>` with all the relevant args passed through (--peer-id, --dir, --continue, --session, --fork). The user sees an unchanged TUI; implementation detail (the daemon) is hidden behind the bare command. 4. Daemon survives the TUI exit — second bare `gruntcode` invocation reuses it. ## Escape hatches - `OPENCODE_DISABLE_AUTO_SERVE=1` skips the auto-serve and uses the legacy in-process worker (the path used today by upstream opencode). - `OPENCODE_AUTO_SERVE_PORT` / `OPENCODE_AUTO_SERVE_HOST` override the defaults (4096 / 127.0.0.1). ## Implementation - New `packages/opencode/src/cli/cmd/tui/auto-serve.ts` exports `ensureServeDaemon()`. Returns `{ok: true, url, bin}` or `{ok: false, reason}`. Logic: - Resolves gruntcode binary path (argv0 if compiled binary; `which gruntcode` if running via `bun run` in dev mode; fallback to `which opencode`). - Probes /session with 1.5s timeout. - If 200 → returns the URL. - If connection refused → spawns daemon as detached child, polls /session every 200ms until ready or 10s timeout. - `packages/opencode/src/cli/cmd/tui/thread.ts` handler calls `ensureServeDaemon()` early. On success: builds attach argv from current args and re-execs via child_process.spawn with stdio inherited. On failure: logs the reason and falls through to the existing in-process worker path. ## Verification End-to-end manual test: 1. Killed existing daemon. Confirmed `curl :4096/session` returns connection refused. 2. Launched bare TUI from patched source: `bun run src/index.ts --peer-id nik-test --project /tmp`. 3. Process tree showed: bun run → child `gruntcode serve --port 4096 ...` AND child `gruntcode attach http://127.0.0.1:4096 --dir /tmp --peer-id nik-test`. 4. `curl :4096/session` returned 200 with the active session. 5. `curl -X POST :4096/session/<id>/prompt_async` accepted (204) and the daemon log showed the LLM running. The wake response 'BARE-CMD-WORKS' was written to opencode.db (verified via `/session/<id>/message`). ## Known follow-up The wake response sometimes doesn't render visually in the TUI even though it's persisted server-side. This is a separate refinement of patch 2c (SSE subscription) that needs investigation — the wake is audit-complete and the system works for autonomous coordination, but human-watcher UX needs polish. Tracked in hivemind anomalyco#221. Refs hivemind anomalyco#224.
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 26, 2026
#6) When patch 2e spawns the serve daemon, explicitly set OPENCODE_SERVER_URL in the daemon's env. This propagates to all MCP children the daemon spawns (via sanitizedProcessEnv in opencode's MCP layer), so hivemind-mcp + similar coordination MCPs can discover the daemon's HTTP endpoint at boot to query session info. Without this, the MCP child has no way to know what port the daemon is on (other than guessing :4096), and no way to find its session-id. OPENCODE_PEER_ID was already inheriting via default env (set by setPeerID() in the wrapper); making it explicit alongside SERVER_URL for clarity isn't needed (the {...process.env, OPENCODE_SERVER_URL} pattern keeps PEER_ID flowing naturally). Refs hivemind anomalyco#224 wakeable-without-typing follow-up.
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 26, 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.
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 26, 2026
… + 'gruntcode' branding (#11) The session slug is now derived from the launch context instead of a random adjective-noun pair: - If --peer-id (or OPENCODE_PEER_ID env) is set, slug = '<peer-id>-<5-char-hash>' (e.g. 'nik-test-a3f9k') - Otherwise slug = '<cwd-basename>-<5-char-hash>' (e.g. 'gruntcode-x7p2n') - Fallback to the random 'crisp-meadow' style only when neither is available The slug is now rendered in the session sidebar under the title so Nik can tell parallel tabs apart at a glance (and in screenshots) — previously the only visible identifier was 'opencode <version>' in the footer. Also rebrands the footer 'Open Code' -> 'grunt' (green) + 'code' (default text) to match the GRUNTCODE splash. New core API: - Slug.createNamed(base: string): produces '<sanitized-base>-<5-char-hex>' - getPeerID(): explicit getter to mirror setPeerID() Sites changed: - packages/core/src/util/slug.ts: new createNamed helper - packages/core/src/util/opencode-process.ts: new getPeerID() getter - packages/opencode/src/session/session.ts: derive slug from peer-id / cwd - packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx: render slug + rebrand footer Refs hivemind anomalyco#224 (sessions need visible names + must only show as wake targets while their TUI is alive).
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 28, 2026
…ommand wakeable TUI) (#5) ## Goal Bare `gruntcode` (no subcommand) should Just Work — the launched TUI is automatically wakeable. No `serve` + `attach` two-command dance, no shell wrapper. Nik framing 2026-05-26: "like i run gruntcode and things can get woken up via hivemind". ## Behavior of bare `gruntcode` now 1. Probes http://127.0.0.1:4096/session — if a daemon is already serving there, attach to it. 2. If no daemon: spawns one as a detached child (`gruntcode serve --port 4096 --hostname 127.0.0.1 --print-logs`), waits up to 10s for readiness. 3. Re-execs into `gruntcode attach <url>` with all the relevant args passed through (--peer-id, --dir, --continue, --session, --fork). The user sees an unchanged TUI; implementation detail (the daemon) is hidden behind the bare command. 4. Daemon survives the TUI exit — second bare `gruntcode` invocation reuses it. ## Escape hatches - `OPENCODE_DISABLE_AUTO_SERVE=1` skips the auto-serve and uses the legacy in-process worker (the path used today by upstream opencode). - `OPENCODE_AUTO_SERVE_PORT` / `OPENCODE_AUTO_SERVE_HOST` override the defaults (4096 / 127.0.0.1). ## Implementation - New `packages/opencode/src/cli/cmd/tui/auto-serve.ts` exports `ensureServeDaemon()`. Returns `{ok: true, url, bin}` or `{ok: false, reason}`. Logic: - Resolves gruntcode binary path (argv0 if compiled binary; `which gruntcode` if running via `bun run` in dev mode; fallback to `which opencode`). - Probes /session with 1.5s timeout. - If 200 → returns the URL. - If connection refused → spawns daemon as detached child, polls /session every 200ms until ready or 10s timeout. - `packages/opencode/src/cli/cmd/tui/thread.ts` handler calls `ensureServeDaemon()` early. On success: builds attach argv from current args and re-execs via child_process.spawn with stdio inherited. On failure: logs the reason and falls through to the existing in-process worker path. ## Verification End-to-end manual test: 1. Killed existing daemon. Confirmed `curl :4096/session` returns connection refused. 2. Launched bare TUI from patched source: `bun run src/index.ts --peer-id nik-test --project /tmp`. 3. Process tree showed: bun run → child `gruntcode serve --port 4096 ...` AND child `gruntcode attach http://127.0.0.1:4096 --dir /tmp --peer-id nik-test`. 4. `curl :4096/session` returned 200 with the active session. 5. `curl -X POST :4096/session/<id>/prompt_async` accepted (204) and the daemon log showed the LLM running. The wake response 'BARE-CMD-WORKS' was written to opencode.db (verified via `/session/<id>/message`). ## Known follow-up The wake response sometimes doesn't render visually in the TUI even though it's persisted server-side. This is a separate refinement of patch 2c (SSE subscription) that needs investigation — the wake is audit-complete and the system works for autonomous coordination, but human-watcher UX needs polish. Tracked in hivemind anomalyco#221. Refs hivemind anomalyco#224.
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 28, 2026
#6) When patch 2e spawns the serve daemon, explicitly set OPENCODE_SERVER_URL in the daemon's env. This propagates to all MCP children the daemon spawns (via sanitizedProcessEnv in opencode's MCP layer), so hivemind-mcp + similar coordination MCPs can discover the daemon's HTTP endpoint at boot to query session info. Without this, the MCP child has no way to know what port the daemon is on (other than guessing :4096), and no way to find its session-id. OPENCODE_PEER_ID was already inheriting via default env (set by setPeerID() in the wrapper); making it explicit alongside SERVER_URL for clarity isn't needed (the {...process.env, OPENCODE_SERVER_URL} pattern keeps PEER_ID flowing naturally). Refs hivemind anomalyco#224 wakeable-without-typing follow-up.
terrxo
added a commit
to grunt-it/gruntcode
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.
terrxo
added a commit
to grunt-it/gruntcode
that referenced
this pull request
May 28, 2026
… + 'gruntcode' branding (#11) The session slug is now derived from the launch context instead of a random adjective-noun pair: - If --peer-id (or OPENCODE_PEER_ID env) is set, slug = '<peer-id>-<5-char-hash>' (e.g. 'nik-test-a3f9k') - Otherwise slug = '<cwd-basename>-<5-char-hash>' (e.g. 'gruntcode-x7p2n') - Fallback to the random 'crisp-meadow' style only when neither is available The slug is now rendered in the session sidebar under the title so Nik can tell parallel tabs apart at a glance (and in screenshots) — previously the only visible identifier was 'opencode <version>' in the footer. Also rebrands the footer 'Open Code' -> 'grunt' (green) + 'code' (default text) to match the GRUNTCODE splash. New core API: - Slug.createNamed(base: string): produces '<sanitized-base>-<5-char-hex>' - getPeerID(): explicit getter to mirror setPeerID() Sites changed: - packages/core/src/util/slug.ts: new createNamed helper - packages/core/src/util/opencode-process.ts: new getPeerID() getter - packages/opencode/src/session/session.ts: derive slug from peer-id / cwd - packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx: render slug + rebrand footer Refs hivemind anomalyco#224 (sessions need visible names + must only show as wake targets while their TUI is alive).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On fresh clone when following the Contributing section of the README
bun run packages/opencode/src/index.tsfails with:This seems to happen because of
opencode.jsonin the root of the repo having emptykeybindsobject:{ "$schema": "https://opencode.ai/config.json", "keybinds": {}, "mcp": {} }Another way to fix it would be to change that json structure, but wasn't sure what the change should be there, so went with checking for null pointer