Skip to content

feat: use interactive shell mode in JS isolation environments to source startup files#83

Merged
konard merged 6 commits intomainfrom
issue-79-48234c0f95fa
Mar 4, 2026
Merged

feat: use interactive shell mode in JS isolation environments to source startup files#83
konard merged 6 commits intomainfrom
issue-79-48234c0f95fa

Conversation

@konard
Copy link
Copy Markdown
Member

@konard konard commented Mar 4, 2026

Summary

Fixes #79 — JavaScript implementation was missing the -i (interactive) flag for bash/zsh in isolation environments.

The Rust implementation (merged in #82) already had this fix, but the JavaScript version was still at 0.23.0 without the interactive flag.

Root cause

Even though bash was correctly auto-detected over sh (added in 0.22.0/0.23.0), running nvm --version still failed because bash was started in non-interactive mode:

/usr/bin/bash: line 1: nvm: command not found

nvm is only available after .bashrc is sourced, which only happens in interactive mode (bash -i).

Changes

  • Added getShellInteractiveFlag() function in js/src/lib/isolation.js that returns '-i' for bash/zsh (mirrors Rust's get_shell_interactive_flag())
  • Applied the -i flag in Docker attached and detached modes
  • Applied the -i flag in SSH attached and detached modes
  • SSH attached mode now always uses the detected shell (previously only used when --shell was explicitly set), aligning with the Rust behaviour
  • Bumped JS version to 0.24.0

Result

# Now works correctly:
$ --isolated docker --image konard/sandbox:1.3.13 -- nvm --version
# → 0.40.3

Shell invocations become:

  • Docker: docker run <image> bash -i -c "nvm --version"
  • SSH: ssh <host> bash -i -c "nvm --version"

Test plan

  • All existing JS unit tests pass (bun test test/)
  • ESLint passes (bun run lint)
  • JS version bumped to 0.24.0 in package.json and CHANGELOG.md
  • Implementation matches the Rust version in rust/src/lib/isolation.rs

🤖 Generated with Claude Code

Adding CLAUDE.md with task information for AI processing.
This file will be removed when the task is complete.

Issue: #79
@konard konard self-assigned this Mar 4, 2026
Add getShellInteractiveFlag() to js/src/lib/isolation.js that returns
'-i' for bash and zsh, mirroring the existing Rust implementation.

Apply the interactive flag in Docker and SSH isolation environments so
that startup files (.bashrc, .zshrc) are sourced when running commands.
This makes tools like nvm, rbenv, and pyenv available in isolated commands.

Before this fix, even though bash was correctly detected over sh, running
`nvm --version` in a Docker container failed because bash was started in
non-interactive mode and did not source .bashrc.

With this fix:
- Docker: `docker run <image> bash -i -c "nvm --version"` sources .bashrc
- SSH: `ssh <host> bash -i -c "nvm --version"` sources .bashrc on remote
- SSH attached mode now always uses the detected shell (was only used when
  --shell was explicitly specified), matching the Rust behaviour

Also bump JS version to 0.24.0.

Fixes #79

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard konard changed the title [WIP] In docker/ssh and other applicable isolation environments instead of sh, we should first try to use bash if available, and only if it is not we should try zsh, sh feat: use interactive shell mode in JS isolation environments to source startup files Mar 4, 2026
@konard konard marked this pull request as ready for review March 4, 2026 09:26
@konard
Copy link
Copy Markdown
Member Author

konard commented Mar 4, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $1.580327
  • Calculated by Anthropic: $1.955979 USD
  • Difference: $0.375652 (+23.77%)
    📎 Log file uploaded as Gist (2758KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Member Author

konard commented Mar 4, 2026

🔄 Auto-restart triggered (attempt 1)

Reason: CI failures detected

Starting new session to address the issues.


Auto-restart-until-mergeable mode is active. Will continue until PR becomes mergeable.

konard and others added 3 commits March 4, 2026 09:35
… refactor file size

- Add changeset file (issue-79-interactive-shell-mode.md) describing the
  interactive shell mode feature for proper version management via CI pipeline
- Revert manual version bump in package.json from 0.24.0 to 0.23.0
  (versions are managed automatically by the CI/CD changeset workflow)
- Remove manually added CHANGELOG.md section (changeset workflow handles this)
- Refactor isolation.js to stay within 1000-line limit (was 1037 lines):
  - Condense shellInteractiveFlag if/else blocks using spread operator
  - Simplify getShellInteractiveFlag function and JSDoc comment
  - Remove redundant inline comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In auto mode (no explicit shell specified), SSH login shells already source
startup files like .bashrc through the login process. Wrapping commands with
bash -i in this mode caused bash to suppress exit codes in non-TTY CI
environments (bash -i -c "exit 42" returning 0 instead of 42).

The fix restores the original auto-mode behavior of passing the command
directly to SSH (ssh host command), while keeping the -i flag only when the
user explicitly requests bash or zsh as the shell. This preserves both
correct exit code propagation and the ability to source startup files when
an explicit shell is requested.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…atting

The JSDoc for getShellInteractiveFlag was expanded to 6 lines, causing the
file to exceed the 1000-line limit after prettier formatted the ternary
expressions in the SSH auto-mode fix. Compressed to a single-line JSDoc
to stay within the limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@konard
Copy link
Copy Markdown
Member Author

konard commented Mar 4, 2026

🔄 Auto-restart-until-mergeable Log (iteration 1)

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $12.454881
  • Calculated by Anthropic: $8.357259 USD
  • Difference: $-4.097621 (-32.90%)
    📎 Log file uploaded as Gist (9743KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Member Author

konard commented Mar 4, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard konard merged commit e9e182f into main Mar 4, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant