Skip to content

Commit a55e2ee

Browse files
jvalin17claude
andcommitted
Add interactive mode to auto-continue — restarts in same terminal
Default is now interactive (claude --init-prompt) so the session reopens in the users terminal. Headless mode (claude -p) available via --headless flag or claude-auto wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b1a5a27 commit a55e2ee

5 files changed

Lines changed: 65 additions & 21 deletions

File tree

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,14 @@ cd /path/to/your-project && claude # hooks inject context; look for "AGEN
3636

3737
Natural language works: *"fix the login bug"* routes to `/debug`. Chain hands-off: `/requirements auto my-app`.
3838

39-
**Auto-continuation** is on by default (`"continue": true` in `gates.json`). When context is exhausted, the hook writes `HANDOFF.md` and automatically relaunches a fresh session. No wrapper needed. Set `"continue": false` to disable (session will warn but keep running).
39+
**Auto-continuation** — when context is exhausted, the session hands off via `HANDOFF.md` and restarts. Two ways to use it:
40+
41+
```bash
42+
agent-toolkit-continue "Build auth system" # interactive — restarts in same terminal
43+
claude-auto "Build auth system" # headless — for CI/background tasks
44+
```
45+
46+
Or set `"continue": true` in `gates.json` for in-hook restart (headless only). Set `"continue": false` to disable (session will warn but keep running).
4047

4148
Install details & updates: [docs/install-and-updates.md](docs/install-and-updates.md)
4249

@@ -277,7 +284,7 @@ agent-toolkit-setup --tdd off # toggle one setting
277284

278285
| Feature | Doc |
279286
|---------|-----|
280-
| Auto-continuation (long tasks) | [architecture/auto-continuation.md](architecture/auto-continuation.md) |
287+
| Auto-continuation (long tasks) | `agent-toolkit-continue` (interactive) / `claude-auto` (headless) · [architecture/auto-continuation.md](architecture/auto-continuation.md) |
281288
| TDD strict mode | `"tdd_mode": "strict"` in `gates.json` — blocks source edits until tests exist |
282289
| Strict mode (anti-fake) | [shared/strict-mode.md](shared/strict-mode.md) |
283290
| Signed gates (teams / CI) | [shared/gate-unlock.md](shared/gate-unlock.md) |

scripts/agent-toolkit-continue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#!/bin/bash
22
# agent-toolkit-continue — Session continuation wrapper for Claude Code
33
# Launches auto_continue.py which manages session lifecycle:
4-
# detect context exhaustion, write HANDOFF.md, relaunch.
4+
# detect context exhaustion, write HANDOFF.md, relaunch in the same terminal.
5+
#
6+
# Runs INTERACTIVE by default (you get a normal claude terminal).
7+
# Add --headless for non-interactive (claude -p) mode.
58
#
69
# Usage:
7-
# agent-toolkit-continue "Build auth system"
10+
# agent-toolkit-continue "Build auth system" # interactive
11+
# agent-toolkit-continue --headless "Build auth system" # headless
812
# agent-toolkit-continue --max-budget-usd 5.00 "Build auth system"
913
# agent-toolkit-continue --dry-run "Build auth system"
1014
# agent-toolkit-continue # resume from existing HANDOFF.md

scripts/auto_continue.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ def __init__(
3939
project_dir: Path,
4040
dry_run: bool = False,
4141
model: Optional[str] = None,
42+
headless: bool = False,
4243
):
4344
self.goal = goal
4445
self.max_budget = max_budget
4546
self.project_dir = project_dir
4647
self.dry_run = dry_run
48+
self.headless = headless
4749
self.handoff_file = project_dir / "HANDOFF.md"
4850
self.history_log = project_dir / "handoff-history.log"
4951
self.session_count = 0
@@ -127,17 +129,22 @@ def _build_prompt(self) -> str:
127129
)
128130

129131
def _launch_session(self, prompt: str) -> int:
130-
"""Launch a Claude Code session in headless mode. Returns process exit code.
132+
"""Launch a Claude Code session. Returns process exit code.
131133
132-
Uses `claude -p` (print mode) which runs non-interactively.
133-
--dangerously-skip-permissions allows autonomous file operations.
134-
--max-budget-usd caps spend per session.
134+
Headless mode: `claude -p` (non-interactive, JSON output).
135+
Interactive mode: `claude --resume` or `claude` with initial prompt,
136+
runs in the same terminal with full user interaction.
135137
"""
136-
cmd = [
137-
"claude", "-p", prompt,
138-
"--output-format", "json",
139-
"--dangerously-skip-permissions",
140-
]
138+
if self.headless:
139+
cmd = [
140+
"claude", "-p", prompt,
141+
"--output-format", "json",
142+
"--dangerously-skip-permissions",
143+
]
144+
else:
145+
# Interactive: launch claude normally, let user interact
146+
# First session uses --init-prompt, continuations use --resume
147+
cmd = ["claude", "--init-prompt", prompt]
141148

142149
if self.model and self.model != "auto":
143150
cmd.extend(["--model", self.model])
@@ -258,6 +265,12 @@ def parse_args(argv: Optional[list] = None) -> argparse.Namespace:
258265
default=None,
259266
help="Model to use (overrides gates.json). 'auto' = no override.",
260267
)
268+
parser.add_argument(
269+
"--headless",
270+
action="store_true",
271+
default=False,
272+
help="Run in headless mode (claude -p). Default is interactive.",
273+
)
261274
return parser.parse_args(argv)
262275

263276

@@ -270,6 +283,7 @@ def main() -> int:
270283
project_dir=Path(args.project_dir).resolve(),
271284
dry_run=args.dry_run,
272285
model=args.model,
286+
headless=args.headless,
273287
)
274288
return runner.run()
275289

scripts/claude-auto

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/bin/bash
2-
# claude-auto — Auto-continuation wrapper for Claude Code
3-
# Launches auto_continue.py which manages session lifecycle:
4-
# detect context exhaustion, write HANDOFF.md, relaunch.
2+
# claude-auto — Auto-continuation wrapper for Claude Code (headless)
3+
# Launches auto_continue.py in headless mode (claude -p).
4+
# For interactive mode, use agent-toolkit-continue instead.
55
#
66
# Usage:
7-
# claude-auto --headless "Build auth system"
8-
# claude-auto --headless --max-budget-usd 5.00 "Build auth"
9-
# claude-auto --headless # resume from existing HANDOFF.md
7+
# claude-auto "Build auth system"
8+
# claude-auto --max-budget-usd 5.00 "Build auth"
9+
# claude-auto # resume from existing HANDOFF.md
1010

1111
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
1212
# Headless sessions start with strict gate enforcement
1313
export AGENT_TOOLKIT_ENFORCEMENT=block
14-
exec python3 "$SCRIPT_DIR/auto_continue.py" "$@"
14+
exec python3 "$SCRIPT_DIR/auto_continue.py" --headless "$@"

tests/test_auto_continue.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,33 @@ def test_includes_timestamp(self, runner):
196196

197197

198198
class TestLaunchSession:
199-
def test_uses_claude_p(self, runner):
199+
def test_interactive_uses_init_prompt(self, runner):
200+
"""Default (interactive) mode uses --init-prompt, not -p."""
201+
with patch("subprocess.run") as mock_run:
202+
mock_run.return_value = MagicMock(returncode=0)
203+
runner._launch_session("test prompt")
204+
205+
cmd = mock_run.call_args[0][0]
206+
assert "claude" in cmd
207+
assert "--init-prompt" in cmd
208+
assert "test prompt" in cmd
209+
210+
def test_headless_uses_claude_p(self, project_dir):
211+
"""Headless mode uses claude -p with JSON output."""
212+
runner = AutoContinue(
213+
goal="Build it",
214+
max_budget=None,
215+
project_dir=project_dir,
216+
headless=True,
217+
)
200218
with patch("subprocess.run") as mock_run:
201219
mock_run.return_value = MagicMock(returncode=0)
202220
runner._launch_session("test prompt")
203221

204222
cmd = mock_run.call_args[0][0]
205223
assert "claude" in cmd
206224
assert "-p" in cmd
225+
assert "--output-format" in cmd
207226
assert "test prompt" in cmd
208227

209228
def test_budget_passthrough(self, project_dir):

0 commit comments

Comments
 (0)