Skip to content

fix: exit view attach on first Ctrl-C#1353

Open
willwashburn wants to merge 7 commits into
mainfrom
codex/fix-view-ctrl-c
Open

fix: exit view attach on first Ctrl-C#1353
willwashburn wants to merge 7 commits into
mainfrom
codex/fix-view-ctrl-c

Conversation

@willwashburn

@willwashburn willwashburn commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

  • make the first Ctrl-C immediately detach node agent attach --mode view
  • retain the normal close request while terminating the local WebSocket handle
  • add regression coverage for raw-input and signal-driven detach paths

Why

View mode consumes Ctrl-C as raw terminal input to suppress terminal input-report noise. Its graceful WebSocket shutdown could leave the Node process alive while waiting for the broker to acknowledge the close, requiring a second Ctrl-C.

User impact

Detaching a read-only view now exits on the first Ctrl-C. The viewed agent is not stopped.

Validation

  • npm exec vitest -- run packages/cli/src/cli/lib/attach-view.test.ts
  • npx tsc --noEmit -p packages/cli/tsconfig.json

Review in cubic

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b7375600-3e3b-40b2-ac19-06d2ecc9db95

📥 Commits

Reviewing files that changed from the base of the PR and between bd51782 and 5c9db4c.

📒 Files selected for processing (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

The view-session WebSocket now supports immediate termination after graceful close attempts. Related tests and changelog text reflect first-Ctrl-C exit behavior, provider shutdown timing is refined, and standalone smoke tests wait for broker readiness.

Changes

View socket teardown

Layer / File(s) Summary
Shutdown termination contract and validation
packages/cli/src/cli/lib/attach-view.ts, packages/cli/src/cli/lib/attach-view.test.ts, CHANGELOG.md
ViewWebSocket adds optional terminate(), shutdown invokes it after graceful close handling, tests assert termination, and the changelog records first-Ctrl-C exit behavior.

Provider shutdown timing

Layer / File(s) Summary
Graceful shutdown delay coverage
packages/cli/src/cli/lib/node-provider-child.test.ts
The force-kill test reduces only the 5-second graceful-shutdown delay while preserving other wait durations.

Standalone smoke readiness

Layer / File(s) Summary
Broker readiness gate
scripts/ci-standalone-smoke.sh
Startup polling now waits for Broker started., uses a configurable timeout, and fails with startup-log diagnostics when readiness is not reached.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: khaliqgant

Poem

I’m a rabbit hopping by the wire,
Terminating sockets before they tire.
One Ctrl-C, then off I go,
No handshake wait, swift as snow,
Back to my burrow I hop.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: exiting view attach on first Ctrl-C.
Description check ✅ Passed The description is mostly complete with summary, rationale, impact, and validation, though it doesn't use the exact Test Plan template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-view-ctrl-c

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.

@willwashburn
willwashburn marked this pull request as ready for review July 22, 2026 18:19
@willwashburn
willwashburn requested a review from khaliqgant as a code owner July 22, 2026 18:19

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd8244ac1f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// while waiting for the broker's close acknowledgement. A local
// detach has no state to flush, so terminate it immediately rather
// than requiring another Ctrl-C to make Node leave the event loop.
socket.terminate?.();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Document the user-visible attach fix

This changes agent-relay agent attach --mode view behavior for users by making Ctrl-C detach on the first press, but the commit leaves CHANGELOG.md's [Unreleased] section empty. Release notes will omit this shipped CLI fix unless this adds a concise Fixed entry and, while [Unreleased] is empty, bumps the heading to [Unreleased - Patch].

AGENTS.md reference: AGENTS.md:L31-L38

Useful? React with 👍 / 👎.

@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: 1

🤖 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 `@packages/cli/src/cli/lib/attach-view.test.ts`:
- Line 536: Update the raw-input detach test assertion near
sockets[0].terminated to also assert that sockets[0].closed is true, preserving
coverage for both the graceful close request and termination behavior.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c818296c-f952-4542-851f-b551216c2bf0

📥 Commits

Reviewing files that changed from the base of the PR and between 58f0568 and ab77b77.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • packages/cli/src/cli/lib/attach-view.test.ts
  • packages/cli/src/cli/lib/attach-view.ts

Comment thread packages/cli/src/cli/lib/attach-view.test.ts
@willwashburn
willwashburn force-pushed the codex/fix-view-ctrl-c branch from d3aac21 to f9e3f19 Compare July 22, 2026 19:38

@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: 1

🤖 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 `@scripts/ci-standalone-smoke.sh`:
- Around line 131-132: Validate AGENT_RELAY_STANDALONE_STARTUP_TIMEOUT_SECONDS
as a non-negative decimal before assigning STARTUP_TIMEOUT_SECONDS or evaluating
STARTUP_DEADLINE arithmetic. Reject values such as 30s, 08, abc, and empty
input, then apply the existing safe/default timeout behavior; only perform the
deadline calculation after validation.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dbd2cd80-ec08-4d00-9e0f-204f92067ac4

📥 Commits

Reviewing files that changed from the base of the PR and between 003534b and f9e3f19.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • packages/cli/src/cli/lib/attach-view.test.ts
  • packages/cli/src/cli/lib/attach-view.ts
  • packages/cli/src/cli/lib/node-provider-child.test.ts
  • scripts/ci-standalone-smoke.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • packages/cli/src/cli/lib/attach-view.test.ts

Comment on lines +131 to +132
STARTUP_TIMEOUT_SECONDS="${AGENT_RELAY_STANDALONE_STARTUP_TIMEOUT_SECONDS:-30}"
STARTUP_DEADLINE=$((SECONDS + STARTUP_TIMEOUT_SECONDS))

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '120,145p' scripts/ci-standalone-smoke.sh 2>/dev/null || true

echo
echo "== bash arithmetic behavior for timeout values =="
python3 - <<'PY'
import subprocess, shlex

cases = ["30s", "08", "0", "-5", "abc", "", "30"]
for val in cases:
    script = f'startup_timeout_seconds="{val}"; if [[ "$startup_timeout_seconds" =~ ^(0|[1-9][0-9]*)$ ]]; then echo "regex ok"; else echo "regex fail"; fi; STARTUP_DEADLINE=$((SECONDS + startup_timeout_seconds)); echo deadline $STARTUP_DEADLINE'
    cp= subprocess.run(["bash","-c",script], text=True, capture_output=True)
    print(f"{val!r}: rc={cp.returncode}; out={cp.stdout.rstrip()}");
    if cp.stderr:
        print(f"  err={cp.stderr.rstrip()}")
PY

Repository: AgentWorkforce/relay

Length of output: 1423


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '120,145p' scripts/ci-standalone-smoke.sh 2>/dev/null || true

echo
echo "== bash arithmetic behavior for timeout values =="
python3 - <<'PY'
import subprocess

cases = ["30s", "08", "0", "-5", "abc", "", "30"]
for val in cases:
    script = f'''
startup_timeout_seconds="{val}"
if [[ "$startup_timeout_seconds" =~ ^(0|[1-9][0-9]*)$ ]]; then
  echo "regex ok"
else
  echo "regex fail"
fi
STARTUP_DEADLINE=$((SECONDS + startup_timeout_seconds))
echo deadline $STARTUP_DEADLINE
'''
    cp = subprocess.run(["bash", "-c", script], text=True, capture_output=True)
    print(f"{val!r}: rc={cp.returncode}; out={cp.stdout.rstrip()}")
    if cp.stderr:
        print(f"  err={cp.stderr.rstrip()}")
PY

Repository: AgentWorkforce/relay

Length of output: 1441


Validate the configurable timeout before arithmetic evaluation.

AGENT_RELAY_STANDALONE_STARTUP_TIMEOUT_SECONDS is used in Bash arithmetic, so values like 30s or 08 fail with value too great for base, and non-decimal values such as abc or an empty value default to 0, causing an immediate readiness deadline. Add a non-negative decimal guard before computing STARTUP_DEADLINE.

🤖 Prompt for 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.

In `@scripts/ci-standalone-smoke.sh` around lines 131 - 132, Validate
AGENT_RELAY_STANDALONE_STARTUP_TIMEOUT_SECONDS as a non-negative decimal before
assigning STARTUP_TIMEOUT_SECONDS or evaluating STARTUP_DEADLINE arithmetic.
Reject values such as 30s, 08, abc, and empty input, then apply the existing
safe/default timeout behavior; only perform the deadline calculation after
validation.

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