Skip to content

Conversation

@rgarcia
Copy link
Contributor

@rgarcia rgarcia commented Nov 11, 2025

using the same approach that docker exec ... uses:

  • allow for allocating a tty when making a process
  • expose an http endpoint that is hijack-able to do pure tcp stuff

./cmd/shell contains a proof of concept for what would eventually land in the kernel CLI.

demo running against the image running in unikraft:

https://screen.studio/share/6imUEYCv


Note

Adds PTY/TTY support to process spawn with HTTP hijack attach and resize endpoints, updates OpenAPI/client, and introduces a shell CLI PoC to interactively attach.

  • API/Backend:
    • PTY support: POST /process/spawn can allocate a PTY (allocate_tty, rows, cols), switches to PTY I/O paths, and avoids stdout/stderr readers in PTY mode.
    • Attach (raw hijack): New non-OpenAPI route GET /process/{process_id}/attach for raw TCP attach with single-session guard and safe PTY->conn copy using readiness polling.
    • Resize: New POST /process/{process_id}/resize endpoint to change PTY size; OpenAPI and generated client/server updated.
    • Lifecycle/cleanup: Close PTY/pipes on exit; retain process handle briefly for status polling.
  • OpenAPI/Client:
    • Schemas and client methods for PTY spawn and resize; embedded swagger updated.
  • CLI:
    • New server/cmd/shell: spawns /bin/bash with TTY, HTTP/1.1 raw-hijack attach, terminal raw mode, SIGWINCH-driven resize; supports HTTP/HTTPS.
  • Images:
    • Wrapper scripts ensure a sensible hostname and export HOSTNAME early (headful/headless).
  • Deps:
    • Add github.com/creack/pty, golang.org/x/sys, golang.org/x/term.

Written by Cursor Bugbot for commit b4ff4e0. This will update automatically on new commits. Configure here.

@rgarcia rgarcia requested review from Sayan- and hiroTamada November 11, 2025 22:00
@mesa-dot-dev
Copy link

mesa-dot-dev bot commented Nov 11, 2025

Mesa Description

using the same approach that docker exec ... uses:

  • allow for allocating a tty when making a process
  • expose an http endpoint that is hijack-able to do pure tcp stuff

./cmd/shell contains a proof of concept for what would eventually land in the kernel CLI.

demo running against the image running in unikraft:

https://screen.studio/share/6imUEYCv


Note

This PR adds the ability to spawn processes with a pseudo-terminal (PTY) and attach to them for interactive sessions, similar to docker exec.

  • API & Process Management:
    • POST /process/spawn is extended to support TTY allocation with initial dimensions.
    • A new GET /process/{process_id}/attach endpoint uses an HTTP hijack to provide a raw TCP stream for PTY interaction.
    • A new POST /process/{process_id}/resize endpoint allows for resizing the PTY window.
  • Proof-of-Concept Shell:
    • A new server/cmd/shell command demonstrates the feature by spawning a remote /bin/bash process, attaching to it, and forwarding terminal resize events.
  • Supporting Changes:
    • The openapi.yaml specification and the generated oapi client have been updated to include the new API endpoints and request parameters.
    • New Go module dependencies (creack/pty, golang.org/x/term) were added to support PTY management.
    • The wrapper.sh scripts in the container images now ensure a valid HOSTNAME is always set.

Written by Cursor Bugbot for commit 55adbad. This will update automatically on new commits. Configure here.

Description generated by Mesa. Update settings

Copy link

@mesa-dot-dev mesa-dot-dev bot left a comment

Choose a reason for hiding this comment

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

Performed full review of 1d2d45e...7d69152

Analysis

  1. Goroutine and Connection Leaks: The HandleProcessAttach function creates multiple goroutines for I/O copying without proper cleanup mechanisms. There's no context-based cancellation, connection timeouts, or tracking to prevent resource exhaustion when clients disconnect improperly.

  2. PTY Process Cleanup Issues: If pty.Start(cmd) fails, there's no guaranteed cleanup of potentially started processes, which could lead to zombie process leaks.

  3. Security Vulnerabilities: The /attach endpoint lacks proper authentication beyond process ID validation, has no permission validation for process attachment, and allows multiple clients to attach to the same PTY which could cause output duplication and potential DoS attacks.

  4. Client Timeout Problems: While the client implementation handles terminal modes and resize events properly, it has indefinite blocking for I/O operations without proper timeout handling.

Tip

Help

Slash Commands:

  • /review - Request a full code review
  • /review latest - Review only changes since the last review
  • /describe - Generate PR description. This will update the PR body or issue comment depending on your configuration
  • /help - Get help with Mesa commands and configuration options

9 files reviewed | 0 comments | Edit Agent SettingsRead Docs


// Pipe: client -> process
go func() {
_, _ = io.Copy(processRW, clientConn)
Copy link

Choose a reason for hiding this comment

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

Bug: Hijack Loses Buffered Data

After hijacking the HTTP connection, the code reads from the raw clientConn instead of the buffered reader buf returned by Hijack(). If the HTTP server's buffered reader read ahead and buffered client data before the hijack, that data will be lost. Reading from buf ensures any buffered data is consumed first before reading from the underlying connection.

Fix in Cursor Fix in Web

if !h.isTTY || h.ptyFile == nil {
return oapi.ProcessResize400JSONResponse{BadRequestErrorJSONResponse: oapi.BadRequestErrorJSONResponse{Message: "process is not PTY-backed"}}, nil
}
ws := &pty.Winsize{Rows: uint16(rows), Cols: uint16(cols)}
Copy link

Choose a reason for hiding this comment

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

Bug: Silent Overflow Corrupts Terminal Size

In ProcessResize, the rows and cols values are converted from int to uint16 without checking for overflow. Values greater than 65535 will silently wrap around, causing incorrect terminal dimensions. For example, a value of 65537 becomes 1 after conversion. The function should validate that both values are within the valid uint16 range (1-65535) before conversion.

Fix in Cursor Fix in Web

cols = uint16(*request.Body.Cols)
}
if rows > 0 && cols > 0 {
_ = pty.Setsize(ptyFile, &pty.Winsize{Rows: rows, Cols: cols})
Copy link

Choose a reason for hiding this comment

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

Bug: Silent Overflow Corrupts Terminal Dimensions

In ProcessSpawn, when allocating a PTY, the initial rows and cols values are converted from int to uint16 without checking for overflow. Values greater than 65535 will silently wrap around, causing incorrect initial terminal dimensions. The code should validate that both values are within the valid uint16 range before conversion.

Fix in Cursor Fix in Web

Copy link
Contributor

@Sayan- Sayan- left a comment

Choose a reason for hiding this comment

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

overall lgtm! nothing blocking ^^

Comment on lines +121 to +125
// Raw attach endpoint (HTTP hijack) - not part of OpenAPI spec
r.Get("/process/{process_id}/attach", func(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "process_id")
apiService.HandleProcessAttach(w, r, id)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

from my understanding these routes will keep using all the router's middlewares. does that match yours? specifically curious on the stz implications

Comment on lines +652 to +653
_, _ = io.Copy(processRW, clientConn)
shutdown()
Copy link
Contributor

Choose a reason for hiding this comment

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

nice how simple this one gets to be

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.

3 participants