Skip to content

Add remote attach CLI - #116

Merged
delete-cloud merged 4 commits into
mainfrom
feat/adr-0019-remote-attach
May 7, 2026
Merged

delete-cloud merged 4 commits into
mainfrom
feat/adr-0019-remote-attach

Conversation

@delete-cloud

@delete-cloud delete-cloud commented May 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add named remote endpoint management via coding-agent remote add/list/remove.
  • Add coding-agent remote repl and coding-agent attach for creating/attaching remote HTTP sessions and streaming prompt SSE events.
  • Add CLI regressions for remote config, session creation payloads, attach streaming, and HTTP error reporting.

Verification

  • uv run pytest tests/cli/ -k "remote or attach" -q
  • uv run pytest tests/cli/ -q
  • uv run python -m compileall -q src/coding_agent/remote src/coding_agent/__main__.py
  • lsp_diagnostics clean for changed files
  • Manual ASGI Docker-cloud remote CLI smoke: manual remote CLI cloud-session smoke ok
  • Pre-slice synced-main Docker HTTP cloud workspace smoke: real docker HTTP cloud workspace smoke ok

Summary by CodeRabbit

  • New Features
    • Manage named remote endpoints (add/list/remove) with token-based auth, start remote REPLs, and attach to existing remote sessions with streamed prompts and approvals.
  • Bug Fixes
    • Improved error handling for session creation/streaming, repo-flag validation, URL normalization, and config file permission handling.
  • Tests
    • Added comprehensive CLI tests for remote management, session create/attach flows, streaming, approvals, and failure cases.

@coderabbitai

coderabbitai Bot commented May 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a2f12bc9-e3e9-4e24-9baa-63d8d202febd

📥 Commits

Reviewing files that changed from the base of the PR and between abdb4f5 and 900bea6.

📒 Files selected for processing (2)
  • coding-agent/src/coding_agent/remote/client.py
  • coding-agent/tests/cli/test_remote_client.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • coding-agent/tests/cli/test_remote_client.py
  • coding-agent/src/coding_agent/remote/client.py

📝 Walkthrough

Walkthrough

Adds CLI commands and a client library to manage named remote endpoints, create/attach to remote sessions, and stream prompts over SSE. Implements persistent remotes storage, session creation via HTTP, SSE event parsing (including approval flow), and tests covering CRUD, session flows, errors, and permissions.

Changes

Remote Session Management

Layer / File(s) Summary
Data Shape
coding-agent/src/coding_agent/remote/__init__.py, coding-agent/src/coding_agent/remote/client.py
Adds module docstring and RemoteEndpoint dataclass with name, url, and optional token.
Remote Storage & Retrieval
coding-agent/src/coding_agent/remote/client.py
remotes_file_path(), load_remotes(), save_remotes(), add_remote(), remove_remote(), get_remote() manage JSON-backed remotes with URL normalization, atomic write, and file-permission handling.
Auth & HTTP Session Creation
coding-agent/src/coding_agent/remote/client.py
auth_headers() builds Authorization header; create_remote_session() POSTs to {base}/sessions, validates session_id, and surfaces HTTP errors with helpers.
SSE Streaming & Event Handling
coding-agent/src/coding_agent/remote/client.py
stream_prompt() opens SSE to /sessions/{id}/prompt and dispatches events to handle_sse_event() which parses payloads, prints deltas, handles tool events, approval prompts (via click.confirm) and posts approvals, raises on remote errors, and returns turn-end status codes.
CLI Wiring
coding-agent/src/coding_agent/__main__.py
Adds remote Click group with remote add/list/remove and remote repl (creates session then streams goal); adds top-level attach to stream a single prompt to an existing session.
Tests
coding-agent/tests/cli/test_remote_client.py
New/updated tests for remote add/list/remove, REPL flow with mocked HTTP/SSE, attach, session-creation errors and connection failures, approval request handling, remotes file permission checks, and stream failure cases.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as "Coding Agent CLI"
    participant Client as "Remote Client"
    participant API as "Remote API Server"
    participant SSE as "SSE Stream"

    User->>CLI: remote repl --name myremote --goal "fix bug"
    CLI->>Client: get_remote("myremote")
    Client-->>CLI: RemoteEndpoint
    CLI->>Client: create_remote_session(endpoint, repo?, empty_workspace?)
    Client->>API: POST /sessions (Authorization header)
    API-->>Client: { "session_id": "sess123" }
    CLI->>Client: stream_prompt(base_url, session_id, prompt)
    Client->>API: GET /sessions/sess123/prompt (SSE)
    activate SSE
    API-->>SSE: event: StreamDelta (data)
    SSE-->>Client: data
    Client->>User: print delta
    API-->>SSE: event: ApprovalRequest (data)
    SSE-->>Client: approval request
    Client->>User: prompt confirm
    User-->>Client: confirm/no
    Client->>API: POST /sessions/sess123/approve
    API-->>Client: approval ack
    API-->>SSE: event: TurnEnd (status)
    SSE-->>Client: turn end
    deactivate SSE
    Client-->>CLI: exit code
    CLI-->>User: exit
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A twitch, a hop, a tiny cheer,
Remotes now whisper in my ear,
Streams that spark and approvals that dance,
CLI commands give prompts a chance,
I nibble bugs and ship with cheer!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Add remote attach CLI' is somewhat vague and incomplete. While it mentions 'attach', the PR actually adds significantly more: remote endpoint management (add, list, remove), remote REPL, and attach commands. The title focuses on only one aspect of a multi-feature change. Consider a more comprehensive title like 'Add remote session management and attach CLI commands' or 'Add remote endpoints and attach commands' to better reflect the full scope of the changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/adr-0019-remote-attach

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@coding-agent/src/coding_agent/remote/client.py`:
- Around line 36-38: When parsing remotes.json (the expression raw =
cast(object, json.loads(path.read_text(encoding="utf-8"))) ) and the other
json.loads usage around lines 262-264, wrap the json.loads call in a try/except
that catches json.JSONDecodeError and re-raises a click.ClickException with a
clear message including the path or context and the original error text; import
json.JSONDecodeError if needed and use "raise click.ClickException(f'Invalid
remotes file: {path}: {e}') from e" (and the analogous message for the
SSE/payload parse) so malformed/truncated JSON produces Click errors instead of
tracebacks.
- Around line 59-62: The code in save_remotes uses path.parent.chmod(0o700)
unconditionally which may change permissions on an arbitrary existing directory
(e.g., /tmp); change the logic to only set permissions when we actually created
the parent directory. In save_remotes (and using remotes_file_path()), check
whether path.parent.exists() (or is_dir()) before creating it; if it does not
exist, create it (mkdir(parents=True, exist_ok=False) or create and catch
exceptions) and then call chmod(0o700); if it already exists, do not chmod the
existing directory. Ensure any race conditions are handled with appropriate
try/except so we only mutate permissions for directories we created.
- Around line 117-128: create_remote_session, stream_prompt, and related remote
calls currently let httpx.RequestError and indefinite connection waits leak to
callers and don't validate SSE responses; wrap all httpx network operations
(e.g., in create_remote_session and stream_prompt) in try/except that catches
httpx.RequestError and re-raises a ClickException with a clear message, replace
timeout=None in stream_prompt with an httpx.Timeout instance that has finite
connect/write/pool timeouts and read=None (so only read/inactivity is
unlimited), and before iterating SSE events call
event_source.response.raise_for_status() to validate the HTTP response; finally,
change the stream_prompt end-of-stream handling so that if no TurnEnd event is
observed it raises a ClickException (or returns a non-zero error indicator)
instead of returning 0 to avoid silently treating truncated streams as success.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9135ab82-7776-477c-bfd6-cd2e18150b3f

📥 Commits

Reviewing files that changed from the base of the PR and between 52ccc92 and abdb4f5.

📒 Files selected for processing (4)
  • coding-agent/src/coding_agent/__main__.py
  • coding-agent/src/coding_agent/remote/__init__.py
  • coding-agent/src/coding_agent/remote/client.py
  • coding-agent/tests/cli/test_remote_client.py

Comment thread coding-agent/src/coding_agent/remote/client.py Outdated
Comment thread coding-agent/src/coding_agent/remote/client.py Outdated
Comment thread coding-agent/src/coding_agent/remote/client.py Outdated
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