Skip to content

feat(e2b): add sandbox templates for common workflows (v1.1) - #48

Merged
frankbria merged 5 commits into
mainfrom
feature/sandbox-templates
Jan 14, 2026
Merged

feat(e2b): add sandbox templates for common workflows (v1.1)#48
frankbria merged 5 commits into
mainfrom
feature/sandbox-templates

Conversation

@frankbria

@frankbria frankbria commented Jan 14, 2026

Copy link
Copy Markdown
Owner

Summary

Add a comprehensive template management system for E2B sandboxes that enables pre-configured development environments for common workflows.

  • TemplateManager class for CRUD operations on templates (create, read, update, delete, export, import)
  • 3 built-in templates: node-20-typescript, python-3.12-fastapi, full-stack-nextjs
  • 6 new CLI commands: templates-list, templates-show, templates-create, templates-delete, templates-export, templates-import
  • --use-template option for sandbox-run command to apply managed templates
  • Project type auto-detection for template suggestions based on package.json, pyproject.toml, etc.

Implementation Details

New Files

  • src/e2b/templates.ts - TemplateManager with validation, loading, and project detection
  • templates/*.json - Built-in template definitions
  • tests/e2b/templates.test.ts - 50 comprehensive tests

Modified Files

  • src/types.ts - Template type definitions (SandboxTemplate, TemplateListEntry, etc.)
  • src/e2b/sandbox-manager.ts - applyTemplate() method for executing setup commands
  • src/cli.ts - Template CLI commands and --use-template support for sandbox-run
  • CLAUDE.md - Documentation updates

Key Design Decisions

  • Built-in templates stored in templates/ directory (version controlled)
  • Custom templates stored in ~/.parallel-cc/templates/ (user-specific)
  • Template application is non-blocking (warns but continues on failure)
  • ES module compatible using import.meta.url for path resolution

Test Plan

  • 50 new template tests pass (TemplateManager, validation, detection)
  • 6 new applyTemplate tests pass in sandbox-manager
  • All 864 existing tests pass
  • Build succeeds with no TypeScript errors
  • CLI commands work: templates-list, templates-show node-20-typescript
  • Manual test: sandbox-run --use-template node-20-typescript (requires E2B API key)

Usage Examples

# List available templates
parallel-cc templates-list

# Show template details
parallel-cc templates-show node-20-typescript

# Use template with sandbox-run
parallel-cc sandbox-run --repo . --prompt "Build feature" --use-template node-20-typescript

# Create custom template
parallel-cc templates-create my-template --description "My setup" --setup-commands "npm install"

# Create from project detection
parallel-cc templates-create my-project --description "Auto-detected" --from-repo .

Summary by CodeRabbit

  • New Features

    • Sandbox Templates v1.1: built-in templates (Node/TypeScript, Python/FastAPI, full‑stack Next.js), template CRUD, import/export, project-type detection, and a --use-template option to apply templates during sandbox runs. Template application reports success/details and is non-blocking on failures.
    • New CLI template commands: list, show, create, delete, export, import with JSON output.
  • Documentation

    • Docs expanded with template usage, example workflows, CLI guidance, and version notes.
  • Tests

    • Comprehensive tests for the template manager and sandbox template application.

✏️ Tip: You can customize this high-level summary in your review settings.

Add a comprehensive template management system for E2B sandboxes that
enables pre-configured development environments.

New features:
- TemplateManager class for CRUD operations on templates
- Built-in templates: node-20-typescript, python-3.12-fastapi, full-stack-nextjs
- CLI commands: templates-list, templates-show, templates-create, templates-delete, templates-export, templates-import
- --use-template option for sandbox-run command
- Project type auto-detection for template suggestions
- Template validation and reserved name protection

Implementation details:
- Templates stored as JSON in templates/ (built-in) and ~/.parallel-cc/templates/ (custom)
- SandboxManager.applyTemplate() executes setup commands and sets environment variables
- Non-blocking template application (warns but continues on failure)
- ES module compatible with import.meta.url for path resolution

Test coverage:
- 50 new template tests (TemplateManager, validation, detection)
- 6 new applyTemplate tests in sandbox-manager
- All 864 tests passing

Documentation:
- Updated CLAUDE.md with new CLI commands and template usage
- Added version history entry for v1.1
@coderabbitai

coderabbitai Bot commented Jan 14, 2026

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds TemplateManager and template types, three built-in JSON templates, CLI template commands and a --use-template option, SandboxManager.applyTemplate to run setupCommands and set environment vars, and tests for template management and application.

Changes

Cohort / File(s) Summary
Template Management Core
src/e2b/templates.ts, src/e2b/sandbox-manager.ts
New TemplateManager (load/list/get/create/delete/import/export, validation, project-type detection) and SandboxManager.applyTemplate(sandboxId, template) which applies environment vars and runs setupCommands with per-command handling and structured result.
CLI Integration
src/cli.ts
Adds --use-template <name> option and templates subcommands (list/show/create/delete/export/import v1.1); integrates TemplateManager, enforces template precedence, applies templates during sandbox-run, and supports JSON output.
Type System
src/types.ts
New template-related public types: TemplateType, TemplateMetadata, SandboxTemplate, TemplateListEntry, TemplateOperationResult, TemplateValidationResult, ProjectTypeDetection.
Built-in Templates
templates/node-20-typescript.json, templates/python-3.12-fastapi.json, templates/full-stack-nextjs.json
Three built-in JSON templates added with metadata, e2bTemplate, setupCommands, and environment settings.
Tests
tests/e2b/templates.test.ts, tests/e2b/sandbox-manager.test.ts
New comprehensive tests for TemplateManager CRUD/import/export, validation, project detection, and SandboxManager.applyTemplate behavior using mocked filesystem and sandbox scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant CLI
    participant TemplateManager
    participant FileSystem
    participant SandboxManager
    participant Sandbox

    CLI->>TemplateManager: list/get/create/delete/import/export
    TemplateManager->>FileSystem: read/write template JSON (built-in/custom)
    FileSystem-->>TemplateManager: JSON / result
    TemplateManager-->>CLI: template list / object / status

    CLI->>SandboxManager: create sandbox / sandbox-run (--use-template)
    SandboxManager->>Sandbox: create/upload/check sandbox
    Sandbox-->>SandboxManager: sandbox ready
    SandboxManager->>TemplateManager: getTemplate(name)
    TemplateManager-->>SandboxManager: SandboxTemplate
    SandboxManager->>Sandbox: set environment variables
    loop setupCommands
      SandboxManager->>Sandbox: execute setupCommand
      Sandbox-->>SandboxManager: command exit status
    end
    SandboxManager-->>CLI: TemplateApplicationResult (success|failure, details)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

Possibly related PRs

Poem

🐇 I nibble JSON carrots, plant env leaves with care,

I hop through setup commands and curl the fresh air,
A CLI twitch, templates sprout, sandbox soil made neat,
New projects bloom where code and carrot paths meet. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a sandbox templates system for E2B with version 1.1, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/sandbox-templates

🧹 Recent nitpick comments
src/cli.ts (1)

36-36: Remove unused validateTemplate import from line 36.

validateTemplate is imported but never used in this file. The template validation is performed internally by TemplateManager.createTemplate().

♻️ Suggested fix
-import { TemplateManager, validateTemplateName, validateTemplate } from './e2b/templates.js';
+import { TemplateManager, validateTemplateName } from './e2b/templates.js';

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41fc4a2 and 21fa5a4.

📒 Files selected for processing (1)
  • src/cli.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Use TypeScript strict mode for all source files
Use ES modules (type: "module") for all TypeScript source files
Use async/await over callbacks for asynchronous operations in TypeScript source files
Implement explicit error handling for all async/await operations in TypeScript source files
Use meaningful and descriptive variable names throughout the codebase
Maintain >85% test coverage across all source files
Use better-sqlite3 via the SessionDB class in db.ts for all database operations
Validate all database inputs using db-validators.ts functions before database operations
Use the logger utility from logger.ts for all console output and logging
Wrap gtr CLI commands through GtrWrapper class in gtr.ts instead of direct subprocess calls
Automatically redact sensitive data (API keys, credentials, SSH keys) from all logs

Files:

  • src/cli.ts
src/cli.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Commander.js for CLI command definition and argument parsing in cli.ts

Files:

  • src/cli.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Use the logger utility from logger.ts for all console output and logging

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Automatically redact sensitive data (API keys, credentials, SSH keys) from all logs

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/claude-runner.ts : Implement autonomous Claude Code execution in src/e2b/claude-runner.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/ssh-key-injector.ts : Implement SSH key injection for private repository access in src/e2b/ssh-key-injector.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/cli.ts : Use Commander.js for CLI command definition and argument parsing in cli.ts

Applied to files:

  • src/cli.ts
🧬 Code graph analysis (1)
src/cli.ts (1)
src/e2b/templates.ts (2)
  • TemplateManager (134-534)
  • validateTemplateName (60-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: opencode-review
  • GitHub Check: Macroscope - Correctness Check
🔇 Additional comments (10)
src/cli.ts (10)

1399-1399: LGTM!

The --use-template option is correctly defined and the help text properly references the "templates list" subcommand (addressing the previous review feedback).


1415-1446: LGTM! Resource leak fix properly implemented.

The refactoring correctly:

  1. Declares sandboxManager outside the try block as nullable
  2. Moves template loading inside the try block to prevent coordinator resource leak if getTemplate() throws
  3. Implements correct precedence for sandbox image selection: --use-template > --template > E2B_TEMPLATE env var > default

1804-1829: LGTM! Template application implemented correctly.

The template application:

  1. Uses console.log/console.warn appropriately for user-facing CLI output (consistent with the rest of the file)
  2. Implements non-blocking failure behavior as intended - warns but continues execution
  3. Properly reports setup commands executed and environment variables set

2133-2140: LGTM! Proper null-safety for error cleanup.

The conditional correctly checks both sandboxId and sandboxManager before attempting cleanup, preventing null reference errors when the error occurs before SandboxManager initialization.


2556-2617: LGTM! Templates list subcommand implemented correctly.

The templates list command:

  1. Uses Commander.js subcommand pattern correctly
  2. Groups templates by type (built-in vs custom) for better UX
  3. Provides consistent JSON output with success field
  4. Handles errors with proper exit codes

2619-2709: LGTM! Credential redaction properly implemented.

The templates show command correctly:

  1. Redacts sensitive environment variable values by default using pattern /token|key|secret|password|credential|auth/i
  2. Applies redaction to both human-readable and JSON outputs
  3. Provides --show-secrets flag for explicit opt-in to reveal values
  4. Shows a helpful hint when values are hidden

This addresses the coding guideline to "automatically redact sensitive data from all logs."


2711-2821: LGTM! Fail-fast validation for --env entries implemented correctly.

The templates create command:

  1. Validates template name format upfront
  2. Implements fail-fast validation for --env entries - rejects missing = or empty keys with clear error messages
  3. Supports --from-repo for auto-detection of project type
  4. Properly exits with non-zero code on failure in both JSON and human modes

2823-2887: LGTM! Template existence check before confirmation prompt.

The templates delete command correctly:

  1. Checks if template is built-in first (cannot delete built-ins)
  2. Verifies template exists before prompting for confirmation (addresses previous review feedback)
  3. Supports --force to skip confirmation
  4. Properly exits with non-zero code on failure

2889-2917: LGTM! Export subcommand implemented correctly.

The templates export command appropriately outputs JSON (the natural format for exports) and supports optional file output via --output.


2919-2975: LGTM! Import subcommand with proper exit codes.

The templates import command:

  1. Supports reading from file (--file) or stdin
  2. Validates input is not empty before processing
  3. Properly exits with non-zero code when result.success is false in JSON mode (addresses previous review feedback)
  4. Consistent error handling in both JSON and human modes

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@frankbria frankbria linked an issue Jan 14, 2026 that may be closed by this pull request
5 tasks
@macroscopeapp

macroscopeapp Bot commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

Add sandbox templates for common workflows and integrate TemplateManager with CLI sandbox-run and templates subcommands in cli.ts

Introduce managed sandbox templates with built-in definitions, add CLI --use-template support and templates subcommands, implement SandboxManager.applyTemplate in sandbox-manager.ts, and add template management and validation in templates.ts.

📍Where to Start

Start with the sandbox-run handler and --use-template flow in cli.ts, then review TemplateManager in templates.ts and SandboxManager.applyTemplate in sandbox-manager.ts.


Macroscope summarized 21fa5a4.

Comment thread src/e2b/templates.ts
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

metadata is never validated. Consider adding shape checks (e.g., author/version strings, tags as array of strings, createdAt/updatedAt strings), or document why metadata is intentionally free-form.

🚀 Want me to fix this? Reply ex: "fix it for me".

Comment thread src/cli.ts
Comment thread src/e2b/sandbox-manager.ts
Comment thread src/e2b/templates.ts
Comment on lines +343 to +345
const filePath = path.join(this.config.customDir, `${name}.json`);
await fs.unlink(filePath);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

deleteTemplate derives ${name}.json, but files may not match the internal name. Delete the actual matched file or catch ENOENT and return not‑found.

Suggested change
const filePath = path.join(this.config.customDir, `${name}.json`);
await fs.unlink(filePath);
const filePath = path.join(this.config.customDir, `${name}.json`);
try {
await fs.unlink(filePath);
} catch (error: any) {
if (error.code === 'ENOENT') {
return {
success: false,
message: 'Template deletion failed',
error: `Template file for "${name}" not found`
};
}
throw error;
}

🚀 Want me to fix this? Reply ex: "fix it for me".

Comment thread src/e2b/sandbox-manager.ts Outdated
Comment thread src/e2b/templates.ts
Comment on lines +106 to +108
} else if (cmd.length > MAX_COMMAND_LENGTH) {
errors.push(`setupCommands[${i}] exceeds maximum length of ${MAX_COMMAND_LENGTH} characters`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Empty setupCommands strings pass validation. Consider rejecting blanks (e.g., cmd.trim() === '') to avoid executing empty commands.

Suggested change
} else if (cmd.length > MAX_COMMAND_LENGTH) {
errors.push(`setupCommands[${i}] exceeds maximum length of ${MAX_COMMAND_LENGTH} characters`);
}
} else if (cmd.trim() === '') {
errors.push(`setupCommands[${i}] cannot be empty`);
} else if (cmd.length > MAX_COMMAND_LENGTH) {
errors.push(`setupCommands[${i}] exceeds maximum length of ${MAX_COMMAND_LENGTH} characters`);
}

🚀 Want me to fix this? Reply ex: "fix it for me".

Comment thread src/e2b/templates.ts
await fs.access(path.join(repoPath, 'package.json'));
detectedFiles.push('package.json');

// Read package.json to check for specific frameworks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only record package.json after a successful parse and object check, and handle parse errors explicitly (e.g., report Node with a reason instead of falling through) to keep detection consistent.

🚀 Want me to fix this? Reply ex: "fix it for me".

Comment thread src/e2b/sandbox-manager.ts Outdated
@github-actions

Copy link
Copy Markdown

Review: feat(e2b): add sandbox templates for common workflows (v1.1)

Overview

This PR adds a comprehensive template management system for E2B sandboxes with built-in templates for common workflows. The implementation is well-designed with solid test coverage (914 tests passing).

✅ Strengths

Code Quality

  • Clean separation of concerns with dedicated TemplateManager class
  • Consistent error handling with descriptive error messages
  • Proper use of async/await for filesystem operations
  • Excellent ES module compatibility using import.meta.url

Validation & Safety

  • Thorough template name validation (regex + reserved names check)
  • Template structure validation prevents malformed templates
  • Built-in templates are protected from deletion/overwrite
  • Input validation for CLI commands

Testing

  • 50 tests for TemplateManager (100% passing)
  • 6 tests for applyTemplate() in SandboxManager
  • All 864 existing tests still pass
  • Comprehensive coverage of edge cases

Documentation

  • Updated CLAUDE.md with template commands
  • Built-in templates are well-documented
  • Usage examples provided

⚠️ Issues & Recommendations

1. Template Application Partial State (Medium Priority)

Location: src/e2b/sandbox-manager.ts:712-775

The applyTemplate method returns early on failure, potentially leaving partial state:

Risk: Inconsistent sandbox state that's hard to debug.

Recommendation: Consider adding a cleanup mode or rollback mechanism, or document that partial state is expected on failure.


2. Project Type Detection False Positives (Low Priority)

Location: src/e2b/templates.ts:479-486, 509-516

FastAPI detection uses simple string matching in pyproject.toml or requirements.txt:

Risk: False positive if fastapi appears in project metadata or comments.

Recommendation: Use TOML/INI parsing for pyproject.toml and line-by-line parsing for requirements.txt:


3. Performance: Template Loading (Low Priority)

Location: src/e2b/templates.ts:158-191

Templates are loaded from filesystem on every method call without caching:

Impact: Noticeable slowdown if listTemplates / getTemplate called frequently.

Recommendation: Add simple in-memory caching with TTL or cache invalidation:


4. Security: Template Command Execution (Informational)

Location: src/e2b/sandbox-manager.ts:745-761

Setup commands from templates are executed directly without additional validation:

Context: This is acceptable since templates are either:

  • Built-in (trusted by the project)
  • Created locally by the user
  • Imported (user-initiated action)

Recommendation: Document this behavior in security notes. Consider adding --dry-run mode for template application that shows what commands would run.


5. Race Condition: Template Creation (Low Priority)

Location: src/e2b/templates.ts:284-291

Template creation checks for existence then writes:

Risk: Race condition if two processes create the same template simultaneously.

Recommendation: Use fs.writeFile with { flag: 'wx' } (exclusive create):


📊 Test Coverage

  • ✅ TemplateManager: 50 tests (100% passing)
  • ✅ SandboxManager.applyTemplate: 6 tests (100% passing)
  • ✅ All existing tests: 814 tests (100% passing)
  • ✅ Integration: Manual test listed in checklist

🎯 Conclusion

This is a well-implemented feature that adds significant value to the parallel-cc project. The template system is well-designed, thoroughly tested, and follows project conventions.

Recommended Action: Approve with minor follow-ups

  • Address items 1-3 for production robustness
  • Items 4-5 are optional improvements for future releases

The implementation is production-ready for the v1.1 milestone. Great work!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/cli.ts`:
- Around line 1802-1827: The block handling managedTemplate (around the
sandboxManager.applyTemplate call and using templateResult and options.json)
must stop using console methods: replace console.log(...) with logger.info(...)
and replace console.warn(...) with logger.warn(...), keeping the same messages
and conditionals (including the chalk formatting and checks for
templateResult.commandsExecuted/environmentVarsSet) so all output uses the
existing logger utility.

In `@src/e2b/sandbox-manager.ts`:
- Around line 711-741: The code currently builds envExports by interpolating
template.environment values directly, which allows shell injection; update the
env export construction used before calling sandbox.commands.run to safely
escape values: for each [key,value] in template.environment produce export
KEY='escaped' where escaped is the value with all single quotes replaced by '\''
(i.e. close-quote, escaped single-quote, reopen-quote) so embedded single quotes
are handled and the whole value is single-quoted to prevent $, `, and other
expansions; keep the same join(' && ') and the sandbox.commands.run call (and
timeoutMs) but replace the envExports generation code to use this safe escaping
and then set environmentVarsSet as before on success.
- Around line 719-732: The template's environment variables are being exported
at applyTemplate() runtime (via sandbox.commands.run exports) which won't
persist; instead modify createSandbox() to accept and pass template.environment
to Sandbox.create() using its envs parameter (or add an envs arg to
createSandbox() if missing), remove the shell export logic and any assignment to
environmentVarsSet inside applyTemplate(), and ensure subsequent calls reuse the
created sandbox so those envs are available for all later sandbox.commands.run
invocations.

In `@templates/node-20-typescript.json`:
- Around line 2-8: The "description" field claims "Jest/Vitest" but the
"setupCommands" array doesn't install either and the generic "npm install" will
fail without a package.json; update the JSON so the description matches the
actual setup or add installs for testing frameworks and ensure package.json
exists: either remove "Jest/Vitest" from the "description" key, or add
appropriate install commands (e.g., add entries to "setupCommands" to install
jest or vitest and their types/configs) and/or ensure a package.json is created
before running "npm install" so the sandbox setup succeeds.
🧹 Nitpick comments (3)
templates/full-stack-nextjs.json (1)

5-8: Consider removing global Next.js installation.

Installing next@latest globally (line 6) is non-standard. Next.js is typically a local project dependency, and npx next works without a global install. The global version may also conflict with project-specific versions.

Additionally, npm install (line 7) will fail if no package.json exists yet, which may be the case for new sandboxes.

♻️ Suggested fix
  "setupCommands": [
-   "npm install -g next@latest",
-   "npm install",
+   "npm install || true",
    "npx playwright install --with-deps chromium"
  ],

Or if the intent is to scaffold a new Next.js project, consider:

"setupCommands": [
  "npx create-next-app@latest --typescript --tailwind --eslint --app --src-dir --import-alias '@/*' my-app || npm install",
  "npx playwright install --with-deps chromium"
]
CLAUDE.md (1)

544-550: Add blank line before table for markdown compliance.

The static analysis tool flagged MD058 (tables should be surrounded by blank lines). Add a blank line before the "Built-in Templates" table.

📝 Suggested fix
 **Built-in Templates:**
+
 | Template | Description | Setup |
 |----------|-------------|-------|
 | `node-20-typescript` | Node.js 20 with TypeScript tooling | TypeScript, ESLint, Prettier + npm install |
src/cli.ts (1)

1414-1433: Template loading handles errors correctly.

The error handling provides helpful feedback in both JSON and human-readable formats, including a hint to run templates-list.

Minor style note: Line 1415 uses dynamic type import import('./types.js').SandboxTemplate instead of importing the type at the top of the file. Consider adding SandboxTemplate to the existing type imports at line 43 for consistency.

📝 Suggested simplification
-import { SandboxStatus, type E2BSession, type StatusResult, type SessionInfo } from './types.js';
+import { SandboxStatus, type E2BSession, type StatusResult, type SessionInfo, type SandboxTemplate } from './types.js';

Then at line 1415:

-    let managedTemplate: import('./types.js').SandboxTemplate | null = null;
+    let managedTemplate: SandboxTemplate | null = null;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2f8230 and f965b5d.

📒 Files selected for processing (10)
  • CLAUDE.md
  • src/cli.ts
  • src/e2b/sandbox-manager.ts
  • src/e2b/templates.ts
  • src/types.ts
  • templates/full-stack-nextjs.json
  • templates/node-20-typescript.json
  • templates/python-3.12-fastapi.json
  • tests/e2b/sandbox-manager.test.ts
  • tests/e2b/templates.test.ts
🧰 Additional context used
📓 Path-based instructions (5)
tests/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.test.ts: Use Vitest as the testing framework for unit and integration tests
Write unit and integration tests for all new features and bug fixes

Files:

  • tests/e2b/templates.test.ts
  • tests/e2b/sandbox-manager.test.ts
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Use TypeScript strict mode for all source files
Use ES modules (type: "module") for all TypeScript source files
Use async/await over callbacks for asynchronous operations in TypeScript source files
Implement explicit error handling for all async/await operations in TypeScript source files
Use meaningful and descriptive variable names throughout the codebase
Maintain >85% test coverage across all source files
Use better-sqlite3 via the SessionDB class in db.ts for all database operations
Validate all database inputs using db-validators.ts functions before database operations
Use the logger utility from logger.ts for all console output and logging
Wrap gtr CLI commands through GtrWrapper class in gtr.ts instead of direct subprocess calls
Automatically redact sensitive data (API keys, credentials, SSH keys) from all logs

Files:

  • src/e2b/sandbox-manager.ts
  • src/types.ts
  • src/e2b/templates.ts
  • src/cli.ts
src/e2b/sandbox-manager.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts

Files:

  • src/e2b/sandbox-manager.ts
src/types.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Export type definitions from types.ts for all TypeScript interfaces and types

Files:

  • src/types.ts
src/cli.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Commander.js for CLI command definition and argument parsing in cli.ts

Files:

  • src/cli.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to tests/**/*.test.ts : Write unit and integration tests for all new features and bug fixes

Applied to files:

  • tests/e2b/templates.test.ts
  • tests/e2b/sandbox-manager.test.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Maintain >85% test coverage across all source files

Applied to files:

  • tests/e2b/templates.test.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to tests/**/*.test.ts : Use Vitest as the testing framework for unit and integration tests

Applied to files:

  • tests/e2b/templates.test.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts

Applied to files:

  • tests/e2b/sandbox-manager.test.ts
  • src/e2b/sandbox-manager.ts
  • src/types.ts
  • src/e2b/templates.ts
  • src/cli.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/cli.ts : Use Commander.js for CLI command definition and argument parsing in cli.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/claude-runner.ts : Implement autonomous Claude Code execution in src/e2b/claude-runner.ts

Applied to files:

  • src/cli.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/ssh-key-injector.ts : Implement SSH key injection for private repository access in src/e2b/ssh-key-injector.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Document all new CLI commands in the CLI Commands section of CLAUDE.md

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Update version history in CLAUDE.md when releasing new versions

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Document all new MCP tools in the MCP Server Tools section of CLAUDE.md

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/tools.ts : Implement tool logic in mcp/tools.ts with corresponding Zod schema validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/schemas.ts : Implement Zod schemas in mcp/schemas.ts for all MCP tool input/output validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/index.ts : Register all MCP tools in mcp/index.ts with proper error handling and input validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/hooks-installer.ts : Install shell hooks, aliases, and MCP configuration using hooks-installer.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Test all E2E workflows locally before committing using npm test with --coverage flag

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Ensure all end-to-end integration tests pass and coverage remains >85% before merging

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/merge-strategies.ts : Implement merge conflict resolution strategies in merge-strategies.ts

Applied to files:

  • CLAUDE.md
🧬 Code graph analysis (4)
tests/e2b/templates.test.ts (2)
src/types.ts (1)
  • SandboxTemplate (584-591)
src/e2b/templates.ts (3)
  • TemplateManager (134-534)
  • validateTemplateName (60-72)
  • validateTemplate (77-129)
src/e2b/sandbox-manager.ts (2)
src/types.ts (1)
  • SandboxTemplate (584-591)
src/logger.ts (1)
  • error (140-157)
src/e2b/templates.ts (2)
src/types.ts (5)
  • SandboxTemplate (584-591)
  • TemplateValidationResult (616-619)
  • TemplateListEntry (596-601)
  • TemplateOperationResult (606-611)
  • ProjectTypeDetection (624-629)
src/logger.ts (1)
  • error (140-157)
src/cli.ts (1)
src/e2b/templates.ts (2)
  • TemplateManager (134-534)
  • validateTemplateName (60-72)
🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md

545-545: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Macroscope - Correctness Check
  • GitHub Check: opencode-review
🔇 Additional comments (25)
templates/full-stack-nextjs.json (1)

10-20: LGTM!

The environment variables and metadata are well-structured and appropriate for a Next.js development environment. Disabling telemetry and increasing memory allocation are sensible defaults.

src/e2b/sandbox-manager.ts (3)

21-30: LGTM!

The TemplateApplicationResult interface is well-designed with appropriate fields for success status, message, counts, and error handling.


777-798: LGTM!

The success logging and return value provide good observability. The outer catch block ensures unexpected errors are handled gracefully and logged appropriately.


743-775: LGTM on sequential command execution with proper error handling and automatic sensitive data redaction.

The setup commands are executed sequentially with appropriate timeouts (5 minutes) and error handling. Non-zero exit codes are properly detected and reported with the failing command and stderr. The logger.info() method applies redactSensitive() to all logged messages, ensuring setup commands containing API keys, SSH keys, or other sensitive data are automatically redacted.

templates/node-20-typescript.json (1)

9-18: LGTM!

The environment variables and metadata are well-structured and appropriate for a Node.js/TypeScript development environment.

tests/e2b/sandbox-manager.test.ts (4)

905-911: LGTM!

The beforeEach properly sets up the sandbox.commands.run mock for testing template application. The mock returns a successful result by default, which is appropriate for positive test cases.


913-929: LGTM!

The test correctly verifies that setup commands are executed in order and that the success result is returned. The assertion for exactly 2 calls matches the template's 2 setup commands.


931-954: LGTM!

The test correctly verifies that environment variables are exported via shell commands. The assertion properly checks for the presence of export NODE_ENV in the command string.


956-1019: LGTM!

The remaining tests provide comprehensive coverage:

  • Error handling for nonexistent sandbox
  • Command failure detection and error propagation
  • Edge case of templates with no setup commands or environment variables
  • Logging verification for observability

Good test coverage for the applyTemplate method. As per coding guidelines, unit tests are written using Vitest for new features.

templates/python-3.12-fastapi.json (1)

1-19: LGTM!

This template is well-structured:

  • Upgrading pip before installing packages is a best practice
  • All dependencies mentioned in the description are installed
  • PYTHONUNBUFFERED=1 ensures real-time output in containerized environments
  • PYTHONDONTWRITEBYTECODE=1 prevents .pyc file clutter
src/types.ts (1)

560-629: Well-structured type definitions for the template system.

The new types follow consistent patterns established elsewhere in the file. Key observations:

  • SandboxTemplate correctly marks optional fields (setupCommands, environment, metadata)
  • TemplateOperationResult provides proper success/failure handling with optional error details
  • ProjectTypeDetection supports both detected and undetected cases with appropriate optional fields

As per coding guidelines, these type definitions are properly exported from types.ts for use across the codebase.

tests/e2b/templates.test.ts (4)

14-59: Test setup follows Vitest best practices.

Good use of:

  • vi.mock('fs/promises') for mocking the fs module
  • vi.resetAllMocks() in beforeEach/afterEach for test isolation
  • A helper factory createMockTemplate() for consistent test data

The mock defaults (empty directories, access denied) provide a clean baseline that individual tests override as needed.


76-118: Good coverage of template loading edge cases.

The tests properly verify:

  • Successful template loading from directory
  • Graceful handling of missing directories (ENOENT)
  • Filtering of non-JSON files
  • Graceful skipping of malformed JSON files

427-468: Thorough validation tests for template names.

Good coverage of the validateTemplateName function including edge cases for length constraints, special characters, and reserved names. The test at line 436 correctly validates that dots are allowed (e.g., python-3.12-fastapi).


573-631: Project type detection tests look correct.

The tests cover the main detection scenarios (Node.js/TypeScript, Python FastAPI, Next.js, unknown).

Minor observation: Line 586 uses mockResolvedValue instead of mockResolvedValueOnce, which means the same package.json content will be returned for any subsequent readFile calls in that test. This works for the current test but could cause subtle issues if the test logic changes.

CLAUDE.md (2)

115-131: Documentation updates are comprehensive and well-organized.

The source files section now properly documents:

  • src/e2b/templates.ts for template management
  • templates/ directory with built-in template JSON files

This aligns with the PR's goal of adding sandbox template functionality. Based on learnings, this follows the pattern of documenting new CLI commands in CLAUDE.md.


351-356: CLI commands properly documented in the commands table.

All six new template commands are documented with descriptions, maintaining consistency with the existing table format.

src/e2b/templates.ts (4)

24-55: ES module path resolution is correctly implemented.

The use of fileURLToPath(import.meta.url) and path.dirname is the correct pattern for ES modules. The getDefaultConfig function properly resolves the project root from the compiled location (dist/e2b/templates.js → project root).

The TEMPLATE_NAME_REGEX correctly allows dots (e.g., python-3.12-fastapi) while enforcing the 3-50 character limit.


158-191: Template loading implementation is solid.

The method correctly:

  • Filters to .json files only
  • Validates templates before adding them
  • Handles ENOENT gracefully while propagating other errors

Consider adding debug-level logging for skipped invalid templates to aid troubleshooting, but this is optional since silent skipping is the documented behavior.


283-314: Template creation logic is well-structured.

The validation order (name → structure → uniqueness → write) is correct. Timestamps are properly added to metadata.

Minor note: The exists check (line 284) and file write (line 308) are not atomic, so concurrent createTemplate calls with the same name could both succeed. This is low risk for CLI usage but could be a consideration if this API is used programmatically in parallel.


468-533: Project type detection covers common use cases.

The detection flow prioritizes Node.js projects (via package.json) before checking Python projects. The FastAPI detection at line 479 uses simple string matching (content.includes('fastapi')), which could produce false positives if "fastapi" appears in comments, but this is acceptable for a heuristic suggestion system.

The detectedFiles array provides useful context for why a particular template was suggested.

src/cli.ts (4)

1435-1442: Template precedence logic is correctly implemented.

The precedence chain --use-template > --template > E2B_TEMPLATE env var > default is clear and correctly uses optional chaining to handle the null case when no managed template is provided.


2558-2612: Well-implemented templates-list command.

The command follows established CLI patterns with:

  • JSON output support
  • Helpful grouping by template type (built-in vs custom)
  • Informative message when no templates exist
  • Consistent use of chalk for colorization

2710-2719: Environment variable parsing handles edge cases correctly.

The parsing at lines 2714-2718 correctly handles environment values containing = signs by joining the remaining parts:

const [key, ...valueParts] = envVar.split('=');
environment[key] = valueParts.join('=');

This allows values like DATABASE_URL=postgres://user:pass@host/db to be parsed correctly.


2852-2906: templates-import command handles both file and stdin input.

Good implementation that:

  • Supports --file for file input or stdin for piped input
  • Validates that input is not empty before attempting import
  • Provides clear error messages in both JSON and human-readable formats

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread src/cli.ts
Comment thread src/e2b/sandbox-manager.ts Outdated
Comment thread src/e2b/sandbox-manager.ts Outdated
Comment thread templates/node-20-typescript.json
Changed templates CLI from hyphenated commands to proper subcommands:
- templates-list → templates list
- templates-show → templates show <name>
- templates-create → templates create <name>
- templates-delete → templates delete <name>
- templates-export → templates export <name>
- templates-import → templates import

Added CLI naming convention note to CLAUDE.md explaining preference
for subcommands over hyphenated command names.
@github-actions

Copy link
Copy Markdown

Review Summary

This PR adds a comprehensive E2B sandbox template management system with built-in templates for Node.js, Python, and Next.js workflows. The implementation is well-designed with excellent test coverage (914 tests passing).

✅ Strengths

  • Clean architecture with dedicated class
  • Robust validation for template names and structure
  • Good separation between built-in and custom templates
  • Comprehensive test coverage (50 tests for TemplateManager, 6 for applyTemplate)
  • Clear CLI integration with 6 new template management commands

🔴 Critical Issues (Must Fix Before Merge)

1. Environment Variable Persistence (src/e2b/sandbox-manager.ts:732)
Environment variables are exported via shell commands, which don't persist across subsequent calls. The E2B SDK supports an parameter in that should be used instead.

Recommended Fix:

  • Pass template.environment to and use
  • Remove shell export logic from
  • This aligns with E2B SDK patterns and ensures env vars work with all setup commands

2. Shell Injection Risk (src/e2b/sandbox-manager.ts:741)
Environment variable values are directly interpolated without escaping, allowing potential shell injection.

Recommended Fix:

🟡 Medium Priority Issues

3. Use Logger Instead of Console (src/cli.ts:1804-1825)
Template application output uses / instead of the project's logger utility, violating coding standards.

Recommended Fix: Replace all console methods with /.

4. Template Description Mismatch (templates/node-20-typescript.json:8)
Description claims Jest/Vitest support but neither framework is installed in setupCommands.

Recommended Fix: Either remove Jest/Vitest from description or add vitest to setupCommands.

🟢 Low Priority / Nice to Have

5. Template Loading Performance (src/e2b/templates.ts:158-191)
Templates are loaded from filesystem on every call without caching. Consider adding in-memory caching for production use.

6. Project Type Detection (src/e2b/templates.ts:479-486)
FastAPI detection uses simple string matching which could produce false positives. Consider using TOML/INI parsing for more accuracy.

📊 Test Coverage

  • ✅ TemplateManager: 50 tests (100% passing)
  • ✅ SandboxManager.applyTemplate: 6 tests (100% passing)
  • ✅ All existing tests: 858 tests (100% passing)
  • ✅ Integration: Comprehensive coverage

🎯 Recommendation

Conditionally Approve - Address the two critical issues (env var persistence and shell injection) before merging. These are functional bugs that will impact user experience. The medium priority issues (logger usage, description accuracy) should also be fixed for consistency and documentation accuracy.

The implementation is solid overall and the template system adds significant value to the parallel-cc project. With the critical issues resolved, this is ready for v1.1 release.

Comment thread src/cli.ts Outdated
Comment thread src/cli.ts
@github-actions

Copy link
Copy Markdown

Review comment posted to PR #48 at #48 (comment)

New%20session%20-%202026-01-14T03%3A14%3A43.173Z
opencode session  |  github run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/cli.ts`:
- Line 1399: The .option('--use-template <name>', ...) help text references the
old command name "templates-list"; update the description string for the
'--use-template' option to mention the new command name "templates list" (e.g.,
"Use managed template from templates list (runs setup commands and sets
environment)"), editing the .option('--use-template <name>') call to reflect
this exact wording change.
- Around line 1414-1433: The hint text for the missing template uses the old
subcommand name "templates-list"; update both occurrences where the template not
found message is emitted (the JSON error object and the human-readable branch)
to reference the new subcommand "templates list" instead; look for the block
that creates TemplateManager, checks options.useTemplate, sets managedTemplate,
and emits the error (the JSON output with hint and the chalk.dim hint line) and
replace "templates-list" with "templates list".
- Around line 2883-2894: When running templateManager.importTemplate, the CLI
prints JSON when options.json is true but doesn't set a non-zero exit code on
failure; update the CLI logic around templateManager.importTemplate and
options.json so that after console.log(JSON.stringify(result...)) you check if
result.success is false and call process.exit(1) (or otherwise set
process.exitCode = 1) so both JSON and human-readable branches exit non-zero on
import failure.
♻️ Duplicate comments (3)
src/cli.ts (3)

1802-1827: Use logger utility for internal warnings; console for user output.

This was flagged in a previous review. The template application block at lines 1823-1824 uses console.warn() for internal warnings. Per coding guidelines, use logger.warn() for logging. However, lines 1804-1819 using console.log() for user-facing output with chalk formatting appears consistent with the rest of cli.ts.

📝 Suggested fix for warning messages
         } else {
           // Template application failure is non-blocking - warn but continue
-          if (!options.json) {
-            console.warn(chalk.yellow(`⚠ Template application failed: ${templateResult.error}`));
-            console.warn(chalk.dim('  Continuing without template setup'));
-          }
+          if (!options.json) {
+            logger.warn(`Template application failed: ${templateResult.error}`);
+            console.log(chalk.yellow(`⚠ Template application failed: ${templateResult.error}`));
+            console.log(chalk.dim('  Continuing without template setup'));
+          }
         }

2798-2809: --json mode should exit non-zero when operation fails.

This was flagged in a previous review. When result.success is false, the JSON output is printed but the process exits with code 0, making it difficult for scripts to detect failures.

📝 Suggested fix
       if (options.json) {
         console.log(JSON.stringify(result, null, 2));
+        if (!result.success) process.exit(1);
       } else {

2748-2757: --json mode should exit non-zero when creation fails.

Same pattern issue - when result.success is false, the process should exit with a non-zero code.

📝 Suggested fix
       if (options.json) {
         console.log(JSON.stringify(result, null, 2));
+        if (!result.success) process.exit(1);
       } else {
🧹 Nitpick comments (1)
CLAUDE.md (1)

540-568: Add blank line before the table for markdown compliance.

The static analysis tool flagged missing blank lines around the table at line 545.

📝 Suggested fix
 Pre-configured development environments that automatically set up tools and dependencies:
 
 **Built-in Templates:**
+
 | Template | Description | Setup |
 |----------|-------------|-------|
 | `node-20-typescript` | Node.js 20 with TypeScript tooling | TypeScript, ESLint, Prettier + npm install |
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f965b5d and 6371034.

📒 Files selected for processing (2)
  • CLAUDE.md
  • src/cli.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Use TypeScript strict mode for all source files
Use ES modules (type: "module") for all TypeScript source files
Use async/await over callbacks for asynchronous operations in TypeScript source files
Implement explicit error handling for all async/await operations in TypeScript source files
Use meaningful and descriptive variable names throughout the codebase
Maintain >85% test coverage across all source files
Use better-sqlite3 via the SessionDB class in db.ts for all database operations
Validate all database inputs using db-validators.ts functions before database operations
Use the logger utility from logger.ts for all console output and logging
Wrap gtr CLI commands through GtrWrapper class in gtr.ts instead of direct subprocess calls
Automatically redact sensitive data (API keys, credentials, SSH keys) from all logs

Files:

  • src/cli.ts
src/cli.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Commander.js for CLI command definition and argument parsing in cli.ts

Files:

  • src/cli.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts

Applied to files:

  • src/cli.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Use the logger utility from logger.ts for all console output and logging

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/claude-runner.ts : Implement autonomous Claude Code execution in src/e2b/claude-runner.ts

Applied to files:

  • src/cli.ts
  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/ssh-key-injector.ts : Implement SSH key injection for private repository access in src/e2b/ssh-key-injector.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/cli.ts : Use Commander.js for CLI command definition and argument parsing in cli.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Document all new CLI commands in the CLI Commands section of CLAUDE.md

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Update version history in CLAUDE.md when releasing new versions

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Document all new MCP tools in the MCP Server Tools section of CLAUDE.md

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/tools.ts : Implement tool logic in mcp/tools.ts with corresponding Zod schema validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/schemas.ts : Implement Zod schemas in mcp/schemas.ts for all MCP tool input/output validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/mcp/index.ts : Register all MCP tools in mcp/index.ts with proper error handling and input validation

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/hooks-installer.ts : Install shell hooks, aliases, and MCP configuration using hooks-installer.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to tests/**/*.test.ts : Use Vitest as the testing framework for unit and integration tests

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to tests/**/*.test.ts : Write unit and integration tests for all new features and bug fixes

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Maintain >85% test coverage across all source files

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Test all E2E workflows locally before committing using npm test with --coverage flag

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Ensure all end-to-end integration tests pass and coverage remains >85% before merging

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/merge-strategies.ts : Implement merge conflict resolution strategies in merge-strategies.ts

Applied to files:

  • CLAUDE.md
🧬 Code graph analysis (1)
src/cli.ts (1)
src/e2b/templates.ts (2)
  • TemplateManager (134-534)
  • validateTemplateName (60-72)
🪛 markdownlint-cli2 (0.18.1)
CLAUDE.md

545-545: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: opencode-review
  • GitHub Check: Macroscope - Correctness Check
🔇 Additional comments (10)
CLAUDE.md (3)

115-131: LGTM!

The source file structure documentation accurately reflects the new e2b/templates.ts module and the built-in templates directory structure.


351-356: LGTM!

The CLI commands table correctly documents the new template subcommands with proper descriptions matching the v1.1 implementation.


945-951: LGTM!

The CLI naming convention note is helpful for maintaining consistency. It clarifies when to use subcommands vs hyphenated names, which aligns with the v1.1 refactor from templates-list to templates list.

src/cli.ts (7)

36-36: LGTM!

The import correctly includes all required exports from the templates module.


2554-2560: LGTM!

The templates subcommand group is properly structured using Commander.js's .command() pattern for hierarchical commands.


2562-2615: LGTM!

The templates list command implementation is clean with proper error handling and consistent JSON/human-readable output patterns.


2617-2682: LGTM!

The templates show command provides comprehensive template details with proper null checks for optional fields like metadata, setupCommands, and environment variables.


2684-2767: LGTM!

The templates create command properly validates template names, parses environment variables (correctly handling values containing =), and supports project-type auto-detection via --from-repo.


2821-2849: LGTM!

The templates export command correctly outputs JSON directly (no --json flag needed) and supports writing to a file via --output.


1435-1439: LGTM!

The template precedence chain (--use-template > --template > E2B_TEMPLATE env var > default) is correctly implemented and well-documented in the comment.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread src/cli.ts Outdated
Comment thread src/cli.ts Outdated
Comment thread src/cli.ts
Critical fixes:
- Pass environment variables via E2B SDK envs parameter instead of shell
  exports, ensuring persistence across commands and preventing shell injection
- Remove shell export logic that didn't persist between commands.run() calls

Medium priority fixes:
- Replace console methods with logger in template application output
- Fix template description in node-20-typescript.json (remove Jest/Vitest claim)
- Update invalid name error message to include dots in allowed characters
- Check template existence before prompting for delete confirmation
- Update CLI help text and hints to reference 'templates list' subcommand
- Add exit code on JSON import failure

Test updates:
- Update sandbox-manager test to verify envs parameter usage instead of shell exports
@github-actions

Copy link
Copy Markdown

Review: feat(e2b): add sandbox templates for common workflows (v1.1)

This PR introduces a comprehensive template management system with well-architected code and excellent test coverage. However, there are several issues identified in previous reviews that need attention before merging.

Critical Issues (Must Fix)

1. Environment Variable Persistence (src/e2b/sandbox-manager.ts:736)
Environment variables are exported via shell commands which don't persist across sandbox.commands.run() calls. The E2B SDK supports passing envs to Sandbox.create() via the envs parameter. Refactor to pass template environment at sandbox creation time instead of via shell exports.

2. Shell Injection Risk (src/e2b/sandbox-manager.ts:714)
Environment variable values are directly interpolated without proper escaping, allowing potential shell injection. Values with special characters (", $, backticks) could break commands or execute arbitrary code. Use single quotes with embedded quote escaping.

Medium Priority Issues

3. Logger Usage (src/cli.ts:1804-1825)
Template application output uses console.log() and console.warn() instead of the project's logger utility, violating coding standards. Replace with logger.info() and logger.warn().

4. JSON Exit Codes (src/cli.ts:2748, 2798, 2908)
Template commands (create, delete, import) in --json mode don't exit with non-zero codes on failure, making it difficult for scripts to detect errors. Add proper exit code handling after JSON output.

5. Template Description Mismatch (templates/node-20-typescript.json:8)
Description claims "Jest/Vitest" support but neither is installed in setupCommands. Either remove from description or add vitest to setup commands.

Minor Issues

6. Outdated Command References (src/cli.ts:1399, 1425, 1429)
Help text and hint messages reference "templates-list" but should reference the new "templates list" subcommand per v1.1 refactor.

7. Markdown Formatting (CLAUDE.md:545)
Missing blank line before the "Built-in Templates" table (MD058 rule).

Strengths

  • Clean architecture with dedicated TemplateManager class
  • Robust validation for template names and structure
  • Excellent test coverage (50 tests for TemplateManager, 6 for applyTemplate)
  • Proper ES module compatibility using import.meta.url
  • Clear CLI integration with 6 new template commands

Recommendation

Request Changes - Please address the two critical issues (env var persistence and shell injection) before merging. These are functional bugs that will impact user experience and security. The medium priority issues should also be fixed for consistency.

The implementation is solid overall and the template system adds significant value to the project. With critical issues resolved, this is ready for v1.1 release.

Comment thread src/cli.ts Outdated
@github-actions

Copy link
Copy Markdown

Review comment posted successfully: #48 (comment)

New%20session%20-%202026-01-14T03%3A23%3A34.434Z
opencode session  |  github run

- Revert logger.info/warn back to console.log/warn for template output
  (logger.info is hidden at default LogLevel.WARN, making user feedback invisible)
- Add process.exit(1) for create/delete commands in JSON mode on failure
  (consistent with import command, enables scripts to detect errors)
@github-actions

Copy link
Copy Markdown

Review: feat(e2b): add sandbox templates for common workflows (v1.1)

Excellent work on the template management system! The implementation is well-designed with solid architecture. Most critical issues from previous reviews have been addressed.

✅ Strengths

Architecture & Design

  • Clean separation with dedicated TemplateManager class
  • Proper ES module compatibility using import.meta.url
  • Robust validation for template names and structure
  • Good separation between built-in and custom templates
  • Comprehensive test coverage (50 tests for TemplateManager, 6 for applyTemplate)

Critical Fixes Applied

  • Environment variable persistence: Now correctly uses E2B SDK's envs parameter in sandbox.commands.run(), ensuring env vars persist across all commands (src/e2b/sandbox-manager.ts:712-717, 727)
  • Shell injection risk: Fixed by removing shell export commands - no longer interpolating env values into shell strings
  • Template description mismatch: node-20-typescript.json no longer claims Jest/Vitest support
  • JSON exit codes: Added proper process.exit(1) on failures for templates create/delete/import (src/cli.ts:2750-2752, 2816-2818, 2904-2906)
  • Command references: Updated help text and hints to use "templates list" instead of "templates-list" (src/cli.ts:1399, 1425, 1429)

🟡 Minor Issues Remaining

1. Markdown formatting (Low Priority)
CLAUDE.md:545 - Missing blank line before the "Built-in Templates" table (MD058 rule). Add a blank line after line 544.

2. Console vs Logger usage (Informational)
Lines 1823-1824 in src/cli.ts use console.warn() for user-facing warnings with chalk formatting. This is actually consistent with the CLI pattern elsewhere - console methods are used for user-facing formatted output, while logger is used for internal debugging. No change needed here.

🎯 Overall Assessment

The template system is production-ready for v1.1. The implementation demonstrates:

  • Strong understanding of E2B SDK best practices (using envs parameter correctly)
  • Thoughtful security considerations (no shell injection vulnerabilities)
  • Consistent coding patterns with the existing codebase
  • Comprehensive test coverage

The two critical functional bugs (env var persistence and shell injection) have been properly fixed using the correct E2B SDK patterns. The remaining issues are minor documentation formatting points.

Recommendation: ✅ Approve with optional follow-up

  • Merge is safe and the feature adds significant value
  • Optional: Add blank line before table in CLAUDE.md for markdown compliance

Great work on this feature!

@github-actions

Copy link
Copy Markdown

Review comment posted to PR #48 at #48 (comment)

New%20session%20-%202026-01-14T03%3A30%3A10.030Z
opencode session  |  github run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cli.ts (1)

1399-1439: Move template loading and SandboxManager initialization inside the try block.

Template loading (line 1419) runs before the try/catch and if await templateManager.getTemplate() throws, the finally block containing coordinator.close() (line 2135) won't execute, causing a coordinator resource leak. Move lines 1417–1440 inside the try block to ensure proper cleanup.

Fix
   .action(async (options) => {
     const coordinator = new Coordinator();
     const templateManager = new TemplateManager();
     let managedTemplate: import('./types.js').SandboxTemplate | null = null;

-    // Load managed template if --use-template is specified
-    if (options.useTemplate) {
-      managedTemplate = await templateManager.getTemplate(options.useTemplate);
-      if (!managedTemplate) {
-        if (options.json) {
-          console.log(JSON.stringify({
-            success: false,
-            error: `Template "${options.useTemplate}" not found`,
-            hint: 'Run "parallel-cc templates list" to see available templates'
-          }));
-        } else {
-          console.error(chalk.red(`✗ Template "${options.useTemplate}" not found`));
-          console.log(chalk.dim('Run "parallel-cc templates list" to see available templates'));
-        }
-        process.exit(1);
-      }
-    }
-
-    // Precedence: --use-template > --template > E2B_TEMPLATE env var > default
-    const sandboxImage = managedTemplate?.e2bTemplate ||
-                         options.template ||
-                         (process.env.E2B_TEMPLATE?.trim() || '') ||
-                         'anthropic-claude-code';
-    const sandboxManager = new SandboxManager(logger, {
-      sandboxImage
-    });
-    let sandboxId: string | null = null;
-
     try {
+      // Load managed template if --use-template is specified
+      if (options.useTemplate) {
+        managedTemplate = await templateManager.getTemplate(options.useTemplate);
+        if (!managedTemplate) {
+          if (options.json) {
+            console.log(JSON.stringify({
+              success: false,
+              error: `Template "${options.useTemplate}" not found`,
+              hint: 'Run "parallel-cc templates list" to see available templates'
+            }));
+          } else {
+            console.error(chalk.red(`✗ Template "${options.useTemplate}" not found`));
+            console.log(chalk.dim('Run "parallel-cc templates list" to see available templates'));
+          }
+          process.exit(1);
+        }
+      }
+
+      // Precedence: --use-template > --template > E2B_TEMPLATE env var > default
+      const sandboxImage = managedTemplate?.e2bTemplate ||
+                           options.template ||
+                           (process.env.E2B_TEMPLATE?.trim() || '') ||
+                           'anthropic-claude-code';
+      const sandboxManager = new SandboxManager(logger, { sandboxImage });
+      let sandboxId: string | null = null;
+
       // Check schema version - E2B features require v1.0.0 migration
       const db = coordinator['db'];
       const currentVersion = db.getSchemaVersion();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35400f7 and 41fc4a2.

📒 Files selected for processing (1)
  • src/cli.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Use TypeScript strict mode for all source files
Use ES modules (type: "module") for all TypeScript source files
Use async/await over callbacks for asynchronous operations in TypeScript source files
Implement explicit error handling for all async/await operations in TypeScript source files
Use meaningful and descriptive variable names throughout the codebase
Maintain >85% test coverage across all source files
Use better-sqlite3 via the SessionDB class in db.ts for all database operations
Validate all database inputs using db-validators.ts functions before database operations
Use the logger utility from logger.ts for all console output and logging
Wrap gtr CLI commands through GtrWrapper class in gtr.ts instead of direct subprocess calls
Automatically redact sensitive data (API keys, credentials, SSH keys) from all logs

Files:

  • src/cli.ts
src/cli.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Commander.js for CLI command definition and argument parsing in cli.ts

Files:

  • src/cli.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/sandbox-manager.ts : Implement E2B sandbox lifecycle management in src/e2b/sandbox-manager.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/cli.ts : Use Commander.js for CLI command definition and argument parsing in cli.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/**/*.ts : Use the logger utility from logger.ts for all console output and logging

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/claude-runner.ts : Implement autonomous Claude Code execution in src/e2b/claude-runner.ts

Applied to files:

  • src/cli.ts
📚 Learning: 2026-01-13T09:16:25.976Z
Learnt from: CR
Repo: frankbria/parallel-cc PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T09:16:25.976Z
Learning: Applies to src/e2b/ssh-key-injector.ts : Implement SSH key injection for private repository access in src/e2b/ssh-key-injector.ts

Applied to files:

  • src/cli.ts
🧬 Code graph analysis (1)
src/cli.ts (1)
src/e2b/templates.ts (2)
  • TemplateManager (134-534)
  • validateTemplateName (60-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: opencode-review
  • GitHub Check: Macroscope - Correctness Check
🔇 Additional comments (3)
src/cli.ts (3)

36-36: Guard against import/export contract drift for templates module.
This new import is a CLI hard dependency; if ./e2b/templates.js throws on import (e.g., path resolution / fs access at module init), it will fail CLI startup globally. Ensure the templates module doesn’t do eager filesystem work at import-time (keep it inside TemplateManager methods).


1804-1825: Logging policy decision needed: console output vs logger output.
This PR uses console.log/warn for user-facing output (including template flows), while repo guidelines say “use logger utility from logger.ts for all console output”. Given the known UX issue where logger.info is hidden at default WARN, either (a) codify “CLI uses console; internal libs use logger” in guidelines, or (b) adjust logger to have a dedicated always-on “ui” channel.
As per coding guidelines, please confirm the intended standard and align accordingly.

Also applies to: 2558-2605


1802-1827: No changes required—template application is already properly non-blocking.

The applyTemplate() method is comprehensively designed to never throw exceptions. It wraps its entire execution in a try-catch block (outer) and all error paths—whether from command failures or unexpected errors—return a {success: false, error: message} result object rather than throwing. The calling code in cli.ts correctly handles this by checking templateResult.success and logging warnings without aborting execution. The current implementation already fulfills the non-blocking requirement.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread src/cli.ts
1. Move template loading inside try block (sandbox-run command)
   - Prevents coordinator resource leak if getTemplate() throws
   - SandboxManager declared outside try, initialized inside

2. Redact sensitive env var values in templates show
   - Pattern: /token|key|secret|password|credential|auth/i
   - Redacted by default, use --show-secrets to reveal
   - Applies to both human-readable and JSON output
   - Shows hint when sensitive values are hidden

3. Fail fast for malformed --env entries (templates create)
   - Validates KEY=value format
   - Rejects missing '=' or empty key
   - Provides clear error messages in both human and JSON modes
@github-actions

Copy link
Copy Markdown

Review Summary

Excellent work on the template management system! All critical issues from previous reviews have been properly addressed in the recent commits (21fa5a4, 41fc4a2, 35400f7).

✅ Critical Issues - All Resolved

1. Environment Variable Persistence (src/e2b/sandbox-manager.ts:712-717)

  • ✅ Fixed: Environment variables now correctly passed via parameter to , ensuring they persist across all commands
  • Shell export commands removed - no longer using incorrect pattern

2. Shell Injection Risk (src/e2b/sandbox-manager.ts:711-728)

  • ✅ Fixed: Shell injection vulnerability eliminated by removing export command interpolation
  • Environment variables are now safely passed via E2B SDK's parameter

3. Template Description Mismatch (templates/node-20-typescript.json:3)

  • ✅ Fixed: Description no longer claims Jest/Vitest support
  • Updated to: "Node.js 20 LTS with TypeScript, ESLint, Prettier"

4. JSON Exit Codes (src/cli.ts:2750-2752, 2816-2818, 2904-2906)

  • ✅ Fixed: Templates create/delete/import now exit with code 1 on failures in JSON mode
  • Enables proper script error detection

5. Command References (src/cli.ts:1399, 1425, 1429)

  • ✅ Fixed: Help text and hints updated from "templates-list" to "templates list"
  • Consistent with v1.1 subcommand refactor

6. Resource Leak (src/cli.ts:1417-1440)

  • ✅ Fixed: Template loading moved inside try block
  • Ensures coordinator.close() executes in finally block on errors

7. Secrets Redaction (src/cli.ts:2652-2684)

  • ✅ Added: Sensitive values in environment variables are redacted in templates show output
  • --show-secrets flag available to reveal values when needed

📊 Code Quality

Architecture:

  • Clean separation with dedicated TemplateManager class
  • Proper ES module compatibility using import.meta.url
  • Good separation between built-in and custom templates

Validation:

  • Robust template name validation (regex + reserved names check)
  • Template structure validation prevents malformed templates
  • Built-in templates protected from deletion/overwrite

Testing:

  • 914 tests passing (100%)
  • 50 tests for TemplateManager
  • 6 tests for SandboxManager.applyTemplate
  • Comprehensive edge case coverage

⚠️ Minor Issue

Markdown Formatting (CLAUDE.md:545)

  • Missing blank line before "Built-in Templates" table (MD058 rule)
  • Suggestion: Add blank line at line 544 for markdown compliance

🎯 Recommendation

✅ Approve with optional follow-up

This implementation is production-ready for v1.1. The template system is:

  • Well-designed with clean architecture
  • Properly tested with comprehensive coverage
  • Secure with no remaining injection vulnerabilities
  • Following project conventions

All critical functional bugs have been addressed using correct E2B SDK patterns. The remaining markdown issue is minor documentation formatting that doesn't affect functionality.

Great work on this feature!

@github-actions

Copy link
Copy Markdown

Perfect! The review has been posted successfully.

Summary

I've reviewed PR #48 and posted a comprehensive review comment. The review finds that all critical issues from previous reviews have been properly addressed in the recent commits:

✅ All Critical Issues Resolved:

  1. Environment Variable Persistence - Fixed by using E2B SDK's envs parameter correctly
  2. Shell Injection Risk - Fixed by removing shell export command interpolation
  3. Template Description Mismatch - Fixed (no longer claims Jest/Vitest)
  4. JSON Exit Codes - Fixed (now exits with code 1 on failures)
  5. Command References - Fixed (updated to "templates list")
  6. Resource Leak - Fixed (template loading moved inside try block)
  7. Secrets Redaction - Added for templates show output

📊 Overall Assessment:

  • Architecture: Clean, well-designed with proper separation of concerns
  • Security: No remaining injection vulnerabilities
  • Testing: 914 tests passing with comprehensive coverage
  • Code Quality: Follows project conventions and best practices

⚠️ Minor Remaining Issue:

Only one documentation formatting issue: Missing blank line before "Built-in Templates" table in CLAUDE.md (line 545, MD058 rule). This is optional cleanup, not blocking.

🎯 Recommendation:

✅ Approve - This implementation is production-ready for v1.1. The template system adds significant value with robust architecture, comprehensive testing, and proper security practices.

Review posted at: #48 (comment)

New%20session%20-%202026-01-14T04%3A00%3A42.708Z
opencode session  |  github run

Comment thread src/cli.ts
Comment on lines +2933 to +2939
// Read from stdin
const chunks: string[] = [];
for await (const chunk of process.stdin) {
chunks.push(chunk.toString());
}
jsonInput = chunks.join('');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

templates import silently waits on stdin when run in a TTY, which looks hung. Consider checking process.stdin.isTTY and immediately show a helpful message (or JSON) and exit, guiding users to use --file or pipe input.

Suggested change
// Read from stdin
const chunks: string[] = [];
for await (const chunk of process.stdin) {
chunks.push(chunk.toString());
}
jsonInput = chunks.join('');
}
// Read from stdin
if (process.stdin.isTTY) {
if (options.json) {
console.log(JSON.stringify({ success: false, error: 'No input provided; use --file or pipe JSON to stdin' }));
} else {
console.error(chalk.red('✗ No input provided'));
console.log(chalk.dim('Provide JSON via --file or pipe to stdin'));
}
process.exit(1);
}
const chunks: string[] = [];
for await (const chunk of process.stdin) {
chunks.push(chunk.toString());
}
jsonInput = chunks.join('');

🚀 Want me to fix this? Reply ex: "fix it for me".

@frankbria
frankbria merged commit a25f317 into main Jan 14, 2026
4 checks passed
@frankbria
frankbria deleted the feature/sandbox-templates branch January 14, 2026 04:09
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.

[v1.1] Sandbox templates for common workflows

1 participant