Skip to content

feat(runtime): add shell detach and reattach - #2199

Draft
aidandaly24 wants to merge 6 commits into
aidandaly/runtime-shellfrom
aidandaly/runtime-shell-detach
Draft

feat(runtime): add shell detach and reattach#2199
aidandaly24 wants to merge 6 commits into
aidandaly/runtime-shellfrom
aidandaly/runtime-shell-detach

Conversation

@aidandaly24

@aidandaly24 aidandaly24 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Stacked on #2198.

Adds explicit detach and reattach behavior to Runtime Shell:

  • Ctrl+] detaches the local client while preserving the remote shell.
  • The connected banner includes both the Runtime session ID and shell ID.
  • Detach prints the exact command needed to reattach.
  • --session-id with --shell-id reattaches to an existing shell.
  • Validation requires --session-id whenever --shell-id is supplied.

The same ownership boundaries remain in place:

  • Handler: target/auth policy and orchestration.
  • Core: remote shell connection.
  • IO: local terminal ownership.

Command

agentcore runtime shell \
  --id <runtimeId> \
  --qualifier DEFAULT \
  --session-id <runtimeSessionId> \
  --shell-id <shellId>

Validation

  • CI=true bun test --coverage --coverage-reporter=lcov
  • Focused detach/reattach suite
  • bun run typecheck
  • bun run lint:check
  • bun run format:check
  • bun run secrets:check
  • bun run build

Live detach/reattach validation used the TypeScript SDK PR #249 implementation
and covered:

  • Ctrl+] detach
  • buffered screen replay after reattach
  • process and working-directory persistence
  • clean exit after reattachment

Merge blocker

Keep this PR in draft until the corrected TypeScript SDK shell lifecycle is
published and this branch is updated to that release.

The current npm release (bedrock-agentcore 0.4.3) exposes the API required to
compile this branch, but ShellSession.close() terminates the remote PTY. This
PR's CLI detach() adapter currently delegates to that method, so shipping it
on 0.4.3 would present detach as successful while destroying the shell that
the user expects to reattach to.

The required SDK behavior is tracked by
aws/bedrock-agentcore-sdk-typescript#249.

@github-actions github-actions Bot added the size/m PR size: M label Sep 3, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 3, 2026
@aidandaly24 aidandaly24 changed the title aidandaly/runtime shell detach feat(runtime): add shell detach and reattach Sep 3, 2026
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.48387% with 9 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (aidandaly/runtime-shell@afbfd61). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/handlers/runtime/shell/operation.ts 60.00% 6 Missing ⚠️
src/core/runtimeShell.ts 50.00% 3 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##             aidandaly/runtime-shell    #2199   +/-   ##
==========================================================
  Coverage                           ?   97.02%           
==========================================================
  Files                              ?      551           
  Lines                              ?    38370           
  Branches                           ?        0           
==========================================================
  Hits                               ?    37227           
  Misses                             ?     1143           
  Partials                           ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation agentcore-devx-automation 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.

AgentCore Harness Review

Verdict: Changes requested

Ctrl+] does not actually detach — it kills the shell

RuntimeShellSessionAdapter.detach() (in src/core/runtimeShell.ts, line 146‑148) is implemented as:

detach(): Promise<void> {
  return this.session.close();
}

But per the published bedrock-agentcore 0.4.3 SDK (ShellSession.close(), runtime/shell/session.d.ts line 159‑162):

Send a CLOSE frame (0xFF) to permanently kill the shell, then close the WebSocket. The server kills the shell process (SIGHUP → SIGKILL) and responds with its own [0xFF]. Unlike dropping the WebSocket (which detaches and allows reconnection), this is permanent.

So the new "detach" path — Ctrl+] in InteractiveTerminal.onDatapeer.detach() → adapter → ShellSession.close() → 0xFF CLOSE — actually terminates the remote shell. The follow-up message emitted in src/handlers/runtime/shell/operation.ts (lines 55‑61):

Detached.
To reattach:
  agentcore runtime shell --id ... --session-id ... --shell-id ...

will be a lie: by the time it prints, the server has already SIGKILL'd the shell, and re-running with the printed --shell-id won't reattach. The user-facing README change also promises "Ctrl+] detaches the client while leaving the shell available for reattachment," which is not what actually happens.

The existing tests don't catch this because they mock at the RuntimeShellSdkSession/FakePeer level and only assert that detach() was called, not that the underlying wire behavior is a detach rather than a close.

Possible fixes:

  1. Wait for a real SDK detach method. bedrock-agentcore@0.4.3 doesn't expose a public detach — the only comparable capability is _terminateConnection(), which is marked @internal. If AWS is planning to ship one (e.g. a detach() on ShellSession that drops the socket without sending 0xFF), gate this PR on that release and switch the adapter to call it.
  2. Use the currently-internal _terminateConnection() as a stopgap, with a comment/TODO — it does exactly what's needed (drops the socket without CLOSE). Not ideal since it's @internal, but at least it matches the advertised behavior.
  3. Drop the socket manually — e.g. call the internal WebSocket's terminate()/close() without going through ShellSession.close(). Also fragile.
  4. Remove Ctrl+] detach and the reattach messaging from this PR and land only the --session-id / --shell-id reattach inputs plus the shellId echo, so the reattach UX doesn't ship broken. Ctrl+] can be re-added once the SDK supports a real detach.

Also worth adding, once the semantics are fixed: an integration/handler-level test that exercises the full detach path (Ctrl+]terminal.run returns {detached: true} → operation prints reattach hint) against something more faithful than a peer/session that just increments counters, so this class of regression is caught next time.

Minor

  • The finally in operation.ts unconditionally calls session.detach() even after a clean shell exit. Today that's benign because the SDK's close() is idempotent, but once (1) above is fixed, double-check the natural-exit branch still tears the socket down cleanly.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 3, 2026
@aidandaly24
aidandaly24 force-pushed the aidandaly/runtime-shell-detach branch from 75c462d to cdcd304 Compare September 3, 2026 21:22
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@aidandaly24
aidandaly24 force-pushed the aidandaly/runtime-shell-detach branch from cdcd304 to 4670d78 Compare September 3, 2026 21:37
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@aidandaly24
aidandaly24 force-pushed the aidandaly/runtime-shell-detach branch from 4670d78 to ce13f83 Compare September 3, 2026 23:50
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@aidandaly24
aidandaly24 force-pushed the aidandaly/runtime-shell-detach branch from ce13f83 to f81db77 Compare September 3, 2026 23:55
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 3, 2026
@aidandaly24
aidandaly24 force-pushed the aidandaly/runtime-shell-detach branch from f81db77 to 4a4289a Compare September 4, 2026 00:00
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants