Skip to content

feat(examples): add interactive Claude Code box example#209

Merged
DorianZheng merged 5 commits intomainfrom
feat/interactive-claude-example
Feb 6, 2026
Merged

feat(examples): add interactive Claude Code box example#209
DorianZheng merged 5 commits intomainfrom
feat/interactive-claude-example

Conversation

@yingjunwu
Copy link
Copy Markdown
Contributor

Summary

  • add an interactive Claude Code install example using a persistent box
  • default to a smaller Debian slim image with env overrides
  • document the new example in the Python examples README

Test plan

  • python examples/python/interactive_claude_ubuntu_example.py

Made with Cursor

Provide a persistent interactive terminal example for installing Claude Code and document it in the examples README.

Co-authored-by: Cursor <[email protected]>
Copilot AI review requested due to automatic review settings February 6, 2026 03:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new interactive example for installing Claude Code in a persistent containerized environment. The example demonstrates how to create and reuse boxes across sessions, allowing users to interactively install and configure Claude Code within a container.

Changes:

  • Adds interactive_claude_ubuntu_example.py showing persistent box usage with manual Claude Code installation
  • Implements PTY-based interactive shell with manual I/O forwarding for reattached boxes
  • Updates Python examples README to document the new example

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.

File Description
examples/python/interactive_claude_ubuntu_example.py New example demonstrating persistent box creation, interactive shell sessions, and box reattachment patterns
examples/python/README.md Documents the new interactive Claude Code example in the examples list and adds detailed description

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,207 @@
#!/usr/bin/env python3
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The filename contains "ubuntu" but the script actually uses "debian:bookworm-slim" by default (line 27). Consider renaming the file to "interactive_claude_debian_example.py" or "interactive_claude_example.py" to match the actual default behavior, or change the default image to Ubuntu to match the filename.

Copilot uses AI. Check for mistakes.
Comment on lines +162 to +167
if BOX_ID:
box = await runtime.get(BOX_ID)
if box is None:
raise RuntimeError(f"Box not found: {BOX_ID}")
print(f"Reattached to box id: {BOX_ID}")
await run_interactive_shell(box, env, shell="/bin/bash")
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

When reattaching to an existing box by BOX_ID (line 163), the code passes the 'env' variable to run_interactive_shell, but this 'env' is constructed fresh each time (lines 145-148). However, when calling runtime.get(BOX_ID), the box may have been created with different environment variables. Consider whether the environment variables should be reapplied to the box when reattaching, or document that the env parameter here only affects the shell session, not the box's persistent environment.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +180
existing = await runtime.get(BOX_NAME)
if existing is not None:
print("Found existing box with same name.")
print(f"Set BOXLITE_CLAUDE_BOX_ID={existing.id} to reattach.")
print("Or remove it and re-run to create a new one.")
await run_interactive_shell(existing, env, shell="/bin/bash")
await existing.stop()
print("Box stopped (data persisted). Re-run to continue.")
return
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

When an existing box is found by name (line 172), the code uses the freshly created BoxOptions (lines 154-160) but never applies them to the existing box. This means the memory_mib, disk_size_gb, and env settings defined in the options won't be used. The existing box will retain its original configuration. Either remove the unused options construction or clarify in the code comments that these settings only apply to new boxes.

Copilot uses AI. Check for mistakes.
Comment on lines +115 to +120
### interactive_claude_ubuntu_example.py
Interactive terminal for Claude Code:
- Persistent box with a bash shell
- Install Claude Code directly in the terminal
- Reuse the same box across sessions

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The documentation refers to "Claude Code" but the filename says "ubuntu" while the actual default image is Debian. Consider updating the description to clarify the actual default OS or make it OS-agnostic (e.g., "Interactive terminal for Claude Code on Linux").

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +191
async with InteractiveBox(
image=IMAGE,
shell="/bin/bash",
name=BOX_NAME,
auto_remove=False,
env=env,
memory_mib=2048,
disk_size_gb=8,
) as itbox:
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The configuration parameters (image, memory_mib, disk_size_gb, auto_remove, env) are duplicated between the unused BoxOptions (lines 154-160) and the InteractiveBox creation (lines 183-191). This violates the DRY principle and creates a maintenance burden. If you keep the BoxOptions, pass them to InteractiveBox; otherwise, remove the unused BoxOptions entirely.

Copilot uses AI. Check for mistakes.
print()

try:
import boxlite
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

Module 'boxlite' is imported with both 'import' and 'import from'.

Copilot uses AI. Check for mistakes.
@yingjunwu
Copy link
Copy Markdown
Contributor Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 6, 2026

@yingjunwu I've opened a new pull request, #210, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI review requested due to automatic review settings February 6, 2026 07:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings February 6, 2026 07:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings February 6, 2026 07:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings February 6, 2026 07:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@DorianZheng DorianZheng merged commit 86cc923 into main Feb 6, 2026
6 checks passed
@DorianZheng DorianZheng deleted the feat/interactive-claude-example branch February 6, 2026 07:39
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.

4 participants