Skip to content

feat(cli): background server for codework tui with prebuilt TUI binaries - #68

Merged
sanchitrk merged 4 commits into
canaryfrom
feature/tui-launch
Oct 11, 2026
Merged

sanchitrk merged 4 commits into
canaryfrom
feature/tui-launch

Conversation

@sanchitrk

@sanchitrk sanchitrk commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

codework tui now reuses or starts a background server, then attaches the Rust TUI. Merging into canary builds the TUI for every platform and publishes the full chain, so it can be installed and tested from npm.

Server + CLI

  • Discovery through <home>/service.json, verified over the wire (server.info, pid must match). A server from another CLI version is replaced.
  • The background server is codework serve --service, detached, logging to <home>/log/server.log. A failed start reports the reason from that log within a second or two.
  • Concurrent starts converge on one server. A registered server rewrites a missing service.json and shuts down if another server takes it over.
  • While the TUI runs, a server that dies is restarted on the same port.
  • The TUI is spawned in the CLI's Effect scope, so SIGINT/SIGTERM stop it instead of orphaning it.
  • New codework service start|restart|status|stop.
  • The RPC route moves to /rpc/v1.

CI + publishing

  • .github/workflows/tui.yml (reusable) builds macOS arm64/x64 and Linux arm64/x64. Linux builds are static musl.
  • Platform packages @codeworksh/tui-<os>-<arch> (under packages/tui/npm) are optional dependencies of @codeworksh/tui. npm installs only the one matching the user's machine.
  • canary.yml builds first, then publishes aikit → plugin → harness → platform packages → tui → cli.
  • dev.yml adds cargo check for the TUI.

Before merging: set up npm (one-time)

The five new package names don't exist on npm yet, and trusted publishing (OIDC) can only be configured on a package that exists. For each of @codeworksh/tui, @codeworksh/tui-darwin-arm64, @codeworksh/tui-darwin-x64, @codeworksh/tui-linux-arm64 and @codeworksh/tui-linux-x64:

  1. Create the package with one manual publish (e.g. a 0.0.0 placeholder).
  2. Add a trusted publisher: repo codeworksh/codework, workflow canary.yml.

Test plan

  • vp check, vp run typecheck, cargo check --locked
  • E2E: 72/72 across the tui, server and cli suites, including managed start, reuse, concurrent start, registration takeover, keep-alive restart, startup failure and the service lifecycle
  • Local dry-run publish of @codeworksh/tui-darwin-arm64 (binary with its executable bit) and @codeworksh/tui (platform packages pinned to the canary version)
  • Canary run: four binaries built (Linux reported as static), all packages published
  • npm i -g @codeworksh/cli@canary && codework tui on macOS and Linux

🤖 Generated with Claude Code

sanchitrk and others added 3 commits October 11, 2026 23:47
Run the Rust TUI from the CLI against a server the CLI owns:

  codework tui

The CLI ensures a healthy local server before launching the UI, reusing
a registered one or starting a detached `codework serve` and waiting for
it to become reachable. It then hands the endpoint to the TUI and
forwards arguments, environment, the terminal, signals and exit status.

Server lifecycle:
- A new `server.info` RPC returns the live `{ pid, version }`, the
  health probe. Health rides the RPC channel rather than a separate HTTP
  surface, and a registration is only trusted when the live pid and
  version match what it names.
- A running server writes `<home>/service.json` (atomic, 0600) and
  removes it on clean shutdown if still its own. Discovery reads it as a
  hint, not proof: it verifies over the wire and retires a stale file
  before starting a replacement.
- Startup is bounded and reported clearly; a failure names the port and
  the `--server` escape hatch.

Launcher (`@codeworksh/tui`):
- Resolves a prebuilt binary per OS/arch from an optional platform
  package, falling back to `CODEWORK_TUI_BIN` and a source-tree build.
  Nothing is downloaded at runtime.
- `launch()` runs the binary with inherited stdio, forwards signals and
  maps its exit status onto the command.

TUI:
- Reads the endpoint from `CODEWORK_RPC_SERVER`; it no longer spawns a
  server, since process startup belongs to the CLI alone.
- Reconnects after a dropped socket and shows a reconnecting state
  instead of failing the turn.

Adds an E2E suite covering dispatch, help, `--server` validation,
managed start + registration, reuse, exit-status forwarding, home
propagation and startup failure.
`codework tui` now finds or starts a background server and attaches the
Rust TUI to it:

- Discovery reads <home>/service.json and trusts it only when the
  endpoint answers `server.info` with the registered pid. A server from
  another CLI version is replaced. Otherwise a detached
  `codework serve --service` is started, logging to
  <home>/log/server.log, and startup fails fast with the reason from
  that log.
- Concurrent starts converge on one server: the loser adopts the
  winner, and a contender that is not adopted is stopped with the
  caller's scope.
- A registered server rewrites a missing service.json and shuts down
  when another server takes it over, so no server runs undiscoverable.
- While the TUI runs, the CLI restarts a server that dies on the same
  port so the TUI's reconnect lands.
- The TUI is spawned through Effect's ChildProcessSpawner in the CLI's
  scope, so SIGINT/SIGTERM to `codework tui` now stop the UI instead of
  orphaning it.

Adds `codework service start|restart|status|stop`, moves the RPC route
to /rpc/v1, and shows the cause of a failed `serve` (e.g. EADDRINUSE)
instead of a bare tag. The TUI launcher package now only resolves the
binary, Unix only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`@codeworksh/cli` depends on `@codeworksh/tui`, which nothing
published, so canary could not release the CLI.

- `.github/workflows/tui.yml` (reusable) builds the TUI for macOS
  arm64/x64 and Linux arm64/x64, Linux as static musl binaries, and
  uploads one artifact per platform package.
- Four platform packages, `@codeworksh/tui-<os>-<arch>`, live under
  packages/tui/npm as workspace packages with `os`/`cpu` set; their
  build stages the downloaded binary. `@codeworksh/tui` depends on them
  as optional workspace dependencies, so publish pins them like any
  other workspace dependency.
- canary.yml runs the build first, then publishes in order
  aikit, plugin, harness, the platform packages, tui, cli.
- dev.yml runs `cargo check` on the TUI.
- `publish.mjs` knows the tui targets and carries `os`/`cpu`;
  `pnpm bump:tui` moves all five versions together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sanchitrk sanchitrk changed the title feat(cli): opencode-style codework tui with prebuilt TUI binaries feat(cli): background server for codework tui with prebuilt TUI binaries Oct 11, 2026
@sanchitrk sanchitrk changed the title feat(cli): background server for codework tui with prebuilt TUI binaries feat(cli): opencode-style codework tui with prebuilt TUI binaries Oct 11, 2026
@sanchitrk sanchitrk changed the title feat(cli): opencode-style codework tui with prebuilt TUI binaries feat(cli): background server for codework tui with prebuilt TUI binaries Oct 11, 2026
Run the platform build matrix on pull requests into canary and dev that
touch the TUI, so a broken target shows up in review instead of when
canary publishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sanchitrk
sanchitrk merged commit 4dc5063 into canary Oct 11, 2026
4 checks passed
@sanchitrk
sanchitrk deleted the feature/tui-launch branch October 11, 2026 19:36
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