Skip to content

Fix shell launch restart loop with persistent interactive shell#49

Merged
jancurn merged 2 commits into
version-1from
claude/sweet-dirac-G894E
May 31, 2026
Merged

Fix shell launch restart loop with persistent interactive shell#49
jancurn merged 2 commits into
version-1from
claude/sweet-dirac-G894E

Conversation

@jancurn
Copy link
Copy Markdown
Member

@jancurn jancurn commented May 31, 2026

Summary

Fixes a restart loop when launching commands via the ?launch= parameter by wrapping the command in a persistent interactive shell. Previously, commands would exit immediately after completion, causing ttyd to respawn the process repeatedly. Now the shell stays alive after command execution, keeping output visible on screen.

Key Changes

  • Shell launch wrapper redesign: Replaced simple command execution with a multi-step wrapper that:

    • Sources the sandbox rcfile for consistent environment and tool wrappers
    • Echoes the command to show what's being executed (like a typed prompt)
    • Captures and displays non-zero exit status
    • Execs an interactive shell to keep the terminal alive after command completion
  • Simplified launch parameter syntax: Updated actor.json templates to use the cleaner ?launch=<cmd> form instead of manually constructing ?arg=-c&arg=... parameters

  • Tool auto-approval configuration:

    • Added Claude Code wrapper function to pass --dangerously-skip-permissions flag
    • Pre-accepted Claude Code onboarding to skip first-run dialogs
    • Configured Codex CLI auto-approval via config.toml
    • Added OpenClaw tool execution policy and exec-approvals.json
  • Shell environment improvements:

    • Changed prompt username from "apify" to "actor"
    • Added guard to prevent welcome message from displaying twice (since rcfile is sourced twice in the launch wrapper)
    • Added comprehensive comments explaining the launch wrapper behavior and tool approval strategy
  • OpenCode configuration: Simplified permission model from granular per-tool settings to a single "allow" policy

Implementation Details

The new buildLaunchCommand() function constructs a bash command string that:

  1. Sources /app/sandbox_bashrc to set up environment and tool wrappers
  2. Echoes the command with a $ prompt prefix for visibility
  3. Executes the command with || echo "[command exited with status $?]" to surface failures
  4. Execs an interactive bash shell to maintain the terminal session

This approach prevents the restart loop while maintaining a seamless user experience where commands appear to run interactively and any errors remain visible.

https://claude.ai/code/session_01Fr9fjpNTprHnrU5JbUnrmp

claude added 2 commits May 30, 2026 23:09
Update the PS1 prompt in the sandbox shell template so the terminal
shows actor@sandbox instead of apify@sandbox.
- /shell?launch=<cmd> now runs in a persistent interactive shell that
  echoes the command and surfaces a non-zero exit, instead of a bash -c
  that exits and makes ttyd respawn it in a restart loop.
- Claude: wrap the command with --dangerously-skip-permissions (settings
  bypass mode shows a blocking confirmation dialog); pre-accept onboarding.
- Codex: ~/.codex/config.toml with approval_policy=never + danger-full-access.
- OpenCode: permission "allow" so nothing prompts.
- OpenClaw: open both YOLO policy layers (tools.exec + exec-approvals.json).
- Point the wrapper actors' launch URLs at ?launch= so they get the fix.
@jancurn jancurn merged commit 21915e6 into version-1 May 31, 2026
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.

3 participants