Skip to content

feat(hub): stream a hub create's progress back to the PC - #276

Merged
madarco merged 3 commits into
nightlyfrom
feat/hub-create-progress
Jul 28, 2026
Merged

feat(hub): stream a hub create's progress back to the PC#276
madarco merged 3 commits into
nightlyfrom
feat/hub-create-progress

Conversation

@madarco

@madarco madarco commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Why

agentbox e2b claude (and create --via-hub, codex, opencode) routed to a control box showed one spinner line stuck on remote hub: running for the 5-10 minutes a cloud create takes. The job row (CreateJobRow) carries a status string and a terminal result — nothing else — so the poll loop could only ever report two transitions.

The progress already exists: the hub worker appends every step (lease, clone, seed overlay, the provider's own create output) to ~/.agentbox/logs/queue-<jobId>.log on the control box, which the hub web UI streams. The PC never fetched it, and ~/.agentbox/logs/<command>.log was effectively empty for hub runs.

What

  • relayGET /remote/boxes/:id/logs?offset=<bytes> on the same admin-bearer-gated dispatcher the create already uses. Returns { lines, offset }; the offset only ever advances past complete lines, so a read landing mid-line never truncates or drops one. The dispatcher stays fs-free: the daemon injects readJobLog (job-log-tail.ts), the serverless plane doesn't and answers 501. Job ids are validated before any path join.
  • CLIpollHubJob gains onLog, draining the tail between status checks (2s tick when tailing) and once more after the terminal status. A hub without the route (404/405/501) disables tailing silently and the create proceeds status-only.
  • renderingwithHubJobLine now uses makeProgressReporter, the same helper the local create path uses: collapsed self-updating line by default, full streamed lines under -v. Every line is teed to ~/.agentbox/logs/<command>.log; the background -i hub path passed no onLog at all before, so that log was empty.

Verification

  • pnpm build, pnpm typecheck, pnpm lint, full test suite green. New unit tests: route (offset, 501 without the reader, 401 before reading), readCreateJobLog (partial line held back, truncation restart, traversal refused), and the CLI poll (offset progression, graceful fallback on an old hub).
  • Live wire: a real relay daemon + the real CLI pollHubJob against a real job log written with deliberate partial lines — all lines delivered in order, none duplicated or truncated.
  • Live CLI: create --provider e2b --via-hub against a stand-in control box (relay daemon + a worker that writes the same per-job log). The spinner tracks the worker's lines through to box ready: e2b-7a1f; all 7 lines land in ~/.agentbox/logs/create.log; -v streams them unclamped.

Not run: a real cloud create through a deployed VPS hub — the worker-side log writing is unchanged code (the hub UI consumes the same file).

Docs

apps/web/content/docs/deployed-hub.mdx (what you see while waiting, -v, the local transcript) and docs/architecture.md (the new route).

https://claude.ai/code/session_01QUnCvB6dh6JWknXFi5pSzk


Note

Low Risk
Observability and UX around an existing admin-gated create queue; log read failures are non-fatal and job IDs are validated before any path join.

Overview
Hub-routed creates (create --via-hub, foreground/background claude/codex/opencode) no longer sit on a static remote hub: running line for minutes. The relay adds GET /remote/boxes/:id/logs?offset=<bytes> (admin-bearer, same surface as create) so the CLI can tail the worker’s per-step log; the daemon wires readCreateJobLog from job-log-tail.ts, while planes without a log file answer 501 and polling falls back to status-only.

pollHubJob gains onLog: it drains new lines between status ticks (2s when tailing), retries transient log errors, stops tailing only when the hub permanently lacks logs, and does a final drain when the job finishes. hubLogSink feeds the live status line (ISO timestamps stripped) and ~/.agentbox/logs/<command>.log (verbatim). withHubJobLine now uses makeProgressReporter with -v for full streamed output, matching local creates; agent hub paths that omitted onLog now tee worker output into the command log.

Reviewed by Cursor Bugbot for commit 58d401f. Configure here.

A cloud create routed to the control box showed one spinner line stuck on
"remote hub: running" for the whole build: the job row carries a status and
nothing else, while the worker's real per-step lines only existed as a file on
the VPS.

Tail that file over the same admin-gated surface the create already uses
(`GET /remote/boxes/:id/logs?offset=`), drain it from `pollHubJob` between
status checks, and render it on the same self-updating line a local create uses
(`-v` streams the full log). The whole transcript now also lands in
~/.agentbox/logs/<command>.log, which was empty for hub runs.

Claude-Session: https://claude.ai/code/session_01QUnCvB6dh6JWknXFi5pSzk
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
agentbox-web Skipped Skipped Jul 28, 2026 10:31pm

Request Review

Comment thread packages/relay/src/remote-boxes.ts
`readJobLog` is injectable, so the route is the trust boundary: an
implementation that forgot the check would inherit a path traversal straight off
the URL. Gate there (400) and keep the reader's own check.

Claude-Session: https://claude.ai/code/session_01QUnCvB6dh6JWknXFi5pSzk
@madarco

madarco commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

bugbot run

Comment thread apps/cli/src/control-plane/hub-enqueue.ts
Any non-ok response killed tailing for the rest of the wait, so one proxy 502 or
connection reset dropped a minutes-long create back to a static status line.
Only 404/405/501 (a hub that has no log route at all) is permanent now; anything
else skips the tick and retries from the same offset.

Claude-Session: https://claude.ai/code/session_01QUnCvB6dh6JWknXFi5pSzk
@madarco

madarco commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 58d401f. Configure here.

@madarco
madarco merged commit 4c5e554 into nightly Jul 28, 2026
5 checks passed
@madarco
madarco deleted the feat/hub-create-progress branch July 28, 2026 22:52
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant