All skills
av avatar

/sandcastle

@b676141
by Ivan Charapanauav/skills16 stars
2

Orchestrate AI coding agents (Claude Code, Codex, OpenCode) in isolated sandboxes using the @ai-hero/sandcastle SDK. Use when the user needs to (1) run agents AFK in Docker/Podman containers, (2) build multi-agent pipelines with plan-execute-review patterns, (3) run parallel agents on separate worktrees, (4) create iterative agent loops with maxIterations, (5) extract structured output from agent runs, (6) set up sandcastle in a new or existing project, or (7) write prompt files with template args and shell expressions.

Use this Skill: https://skilld.dev/gh/av/skills/sandcastle

This session only. Nothing lands on disk.

referencesprompt-system.md

≈1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Prompt System Reference

Prompt Modes

Inline Prompts

Pass a string directly via prompt:

await run({
  agent: claudeCode(),
  sandbox: docker(),
  prompt: "Refactor the auth module to use dependency injection",
});

Inline prompts are passed to the agent verbatim. No substitution, no shell expansion. Passing promptArgs with an inline prompt is a runtime error.

Prompt Files

Pass a file path via promptFile:

await run({
  agent: claudeCode(),
  sandbox: docker(),
  promptFile: "./.sandcastle/prompt.md",
  promptArgs: { ISSUE_TITLE: "Fix login bug" },
});

Prompt files support template arguments and shell expressions.

Template Arguments

Use {{KEY}} placeholders in prompt files:

# Task

Fix the following issue:

**Title:** {{ISSUE_TITLE}}
**Body:** {{ISSUE_BODY}}
**Priority:** {{PRIORITY}}

Arguments are provided via promptArgs:

promptArgs: {
  ISSUE_TITLE: "Login page crashes on mobile",
  ISSUE_BODY: "When tapping the login button on iOS Safari...",
  PRIORITY: "high",
}

Values can be string, number, or boolean.

Built-in Arguments

Two arguments are auto-injected and cannot be overridden:

Argument Value
{{SOURCE_BRANCH}} The branch the agent is working on
{{TARGET_BRANCH}} The branch to merge into (for branch strategies)

Attempting to override these via promptArgs is a runtime error.

Shell Expressions

Use !`command` in prompt files to run commands inside the sandbox before each iteration:

# Current State

The test output is:
!`npm test 2>&1 | tail -50`

The current diff is:
!`git diff`

Files in src/:
!`find src -name "*.ts" | head -20`

Shell expressions:

  • Run inside the sandbox, not on the host
  • Run per iteration, so each iteration sees fresh state (e.g., updated test results)
  • Have a 30-second timeout
  • Are evaluated after template argument substitution

Processing Order

1. Prompt file read from disk
2. {{KEY}} substitution (host-side, once)
3. !`command` expansion (sandbox-side, per iteration)
4. Final prompt sent to agent

Interactive Mode

In interactive() mode, if prompt files contain {{KEY}} placeholders without matching promptArgs, the user is prompted interactively to provide values.

Writing Good Prompts

Structure

# Role / Context

You are working on {{REPO_NAME}}. Your task is to {{TASK}}.

# Current State

!`git log --oneline -5`
!`npm test 2>&1 | tail -30`

# Instructions

1. Step one
2. Step two
3. Step three

# Constraints

- Do not modify files in src/core/
- All tests must pass before completing
- Follow the existing code style

# Completion

When finished, output <promise>COMPLETE</promise>.

Completion Signal

For iteration loops, instruct the agent when to signal completion:

When you have fixed all issues and all tests pass, output:
<promise>COMPLETE</promise>

If you cannot fix an issue, still output the completion signal and explain what blocked you.

The default signal is <promise>COMPLETE</promise>. Custom signals are set via completionSignal.

Structured Output Tag

For structured output, include the XML tag in the prompt:

Analyze the codebase and produce a plan. Output your plan as JSON inside a <plan> tag:

<plan>
{
  "issues": [
    { "title": "...", "priority": "high" }
  ]
}
</plan>

The tag name must match the tag in Output.object({ tag: "plan", schema }) or Output.string({ tag: "plan" }). Sandcastle validates that the tag appears in the resolved prompt text at startup.

Per-Iteration Prompts

Shell expressions make iteration loops powerful — each iteration sees updated state:

# Iteration Context

Remaining lint errors:
!`npx eslint src/ --format compact 2>&1 | head -20`

Failing tests:
!`npm test 2>&1 | grep "FAIL" | head -10`

# Instructions

Fix the next batch of errors shown above. Focus on one file at a time.

When all errors are resolved (both sections above are empty), output:
<promise>COMPLETE</promise>

Source: SKILL.md on GitHub

1 warning1d3 checks · Risk SAFE
  • Gen Agent Trust Hub1d

    The skill provides documentation and configuration for the Sandcastle SDK, which orchestrates AI coding agents in isolated environments. It includes features for lifecycle hooks, prompt-based shell expressions, and sandbox management.

  • Socket1d

    1 alert: gptSecurity

  • Snyk1d

    Risk: LOW · No issues

Signed by skilld at b676141. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated 5 months ago

README badge

README badge for av/skills/sandcastle