Skip to content

feat(terminal): real Ctrl-C, wait_for regex, screen diff - #2537

Merged
chaliy merged 2 commits into
mainfrom
claude/project-thread-vu3h37
Oct 7, 2026
Merged

chaliy merged 2 commits into
mainfrom
claude/project-thread-vu3h37

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Ctrl-C interrupts immediately. In a terminal session, Ctrl-C now drops the running command right away, even inside sleep or a busy loop. Before, it waited for the next command boundary. $? is set to 130. An interactive session also keeps $? across lines (false, then echo $? on the next line prints 1).
  • TerminalTool wait_for. This optional regex makes the call return as soon as command output printed during the call matches it, even while the command keeps running. The reply then carries matched. It matches command stdout/stderr only, never typed keys or prompts, so echo ready<Enter> does not match itself. ^ and $ match at line ends.
  • TerminalTool screen. "full" (the default) keeps the current behavior. "changes" returns screen_changes: [{row, text}] with only the rows that changed since the previous call, plus cursor. "none" omits the screen.
  • Python Terminal.call(input, wait_ms, wait_for, screen) gains the same arguments; call(**tool_args) forwards a model call as is. JS Terminal.call() also accepts an args object ({input, wait_ms, wait_for, screen}).

Why

These are agent-loop features. Long-running commands (servers, builds) can now be awaited by their output instead of fixed sleeps. Ctrl-C actually stops work, and long sessions no longer resend a full 24-row screen on every call. This lifts L-TERM-003.

Before / After

$ sleep 30; echo after      # then Ctrl-C
Before: ^C appears after sleep finishes (30 s); echo $? -> 0
After:  ^C at once;                        echo $? -> 130
call({"input": "for i in 1 2 3; do echo tick$i; sleep 1; done<Enter>", "wait_for": "tick2", "wait_ms": 10000})
After: returns after ~1 s with matched=true, activity="running"

Tests: terminal::tests::{ctrl_c_interrupts_a_running_command, ctrl_c_interrupts_a_busy_loop, exit_status_carries_across_lines}, terminal::tool::tests::{wait_for_*, screen_changes_returns_only_changed_rows, strip_ansi_keeps_visible_text}, plus Python and JS terminal tests. Locally, all 2840 bashkit lib tests (--features terminal) pass, Python test_terminal.py gives 12 passed, and the JS terminal.spec.ts gives 12 passed.

Risk

  • Low. All changes sit behind the terminal feature, which is off by default.
  • Interrupting reuses the execution-timeout path: the command future is dropped, then clear_cancelled_execution_state runs. A stale notify permit is ignored unless the cancel flag is set.
  • The wait_for pattern is model-supplied. It is capped at 1 KiB with a 1 MiB compiled-regex limit, and the tap of command output keeps only the newest 256 KiB (TM-DOS-119 updated).
  • The JS native __callJson now takes a JSON args string. This is internal and the wrapper is updated.

Checklist

  • Tests added or updated
  • Backward compatibility considered (screen defaults to full; output schema no longer requires screen)

Generated by Claude Code

Ctrl-C drops the running command mid-way (sleep included) and sets $? to
130; $? now carries across terminal lines. TerminalTool gains wait_for
(regex over command output, returns early) and screen=changes|none.
Python and JS bindings forward the new arguments. Lifts L-TERM-003.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 918773b Commit Preview URL

Branch Preview URL
Oct 07 2026, 04:41 AM

@chaliy
chaliy merged commit ee84473 into main Oct 7, 2026
49 checks passed
@chaliy
chaliy deleted the claude/project-thread-vu3h37 branch October 7, 2026 05:00
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