shadow-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shadow Testing Skill

Shadow 测试技能

Purpose [LEVEL 1]

用途 [LEVEL 1]

Shadow testing creates isolated container environments where you can test local uncommitted changes without affecting your host system or pushing to remote repositories.
Key Principle: Test exactly what's on your machine (including uncommitted changes) in a clean, isolated environment that mirrors CI.
Shadow测试会创建隔离的容器环境,让你可以在不影响主机系统或推送到远程仓库的情况下,测试本地未提交的变更。
核心原则:在与CI环境一致的干净隔离环境中,测试你机器上的所有内容(包括未提交的变更)。

When to Use This Skill [LEVEL 1]

何时使用该技能 [LEVEL 1]

Perfect For

适用场景

  • Pre-Push Validation: Test changes before committing/pushing
  • Multi-Repo Coordination: Validate changes across multiple repositories work together
  • Clean-State Testing: "Does it work on a fresh machine?"
  • Library Development: Test library changes with dependent projects
  • CI Parity: See what CI will see before pushing
  • Destructive Testing: Tests that modify system state won't affect host
  • 推送前验证:在提交/推送前测试变更
  • 多仓库协同:验证跨多个仓库的变更能否协同工作
  • 干净状态测试:“在全新机器上能运行吗?”
  • 库开发:测试库变更与依赖项目的兼容性
  • CI一致性:在推送前查看CI环境的运行结果
  • 破坏性测试:避免修改系统状态的测试影响主机

Use This Skill When

建议使用场景

  • Making breaking changes to a library others depend on
  • Coordinating changes across multiple repositories
  • Unsure if your changes will work in CI
  • Need to test with specific dependency versions
  • Want to verify install/setup procedures work
  • Testing changes that require clean environment state
  • 对他人依赖的库进行破坏性变更时
  • 协调跨多个仓库的变更时
  • 不确定你的变更能否在CI中运行时
  • 需要使用特定依赖版本进行测试时
  • 想要验证安装/设置流程是否可行时
  • 测试需要干净环境状态的变更时

Don't Use This Skill When

不建议使用场景

  • Running unit tests on already-committed code (use local test runner)
  • Need to debug with live code changes (shadow captures snapshots)
  • Testing production deployment (use staging environments)
  • Simple single-file changes with good test coverage
  • 对已提交代码运行单元测试(使用本地测试运行器)
  • 需要调试实时代码变更(Shadow会捕获快照,无法实时同步)
  • 测试生产部署(使用预发布环境)
  • 简单单文件变更且已有完善测试覆盖时

Core Concepts [LEVEL 1]

核心概念 [LEVEL 1]

Shadow Environment Architecture

Shadow环境架构

A shadow environment is a Docker/Podman container with:
  1. Git Bundle Snapshots - Exact working tree state (including uncommitted changes)
  2. Embedded Gitea Server - Local git server at localhost:3000 inside container
  3. Selective URL Rewriting - Git
    insteadOf
    rules redirect specific repos to local Gitea
  4. Package Manager Isolation - UV, pip, npm, cargo, go caches isolated per shadow
  5. API Key Passthrough - Common API keys automatically forwarded to container
┌─────────────────────────────────────────────────────────┐
│  Shadow Container                                       │
│  ┌───────────────────────────────────────────────────┐  │
│  │  Gitea Server (localhost:3000)                    │  │
│  │  - myorg/my-library (your snapshot)               │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  Git URL Rewriting:                                     │
│  github.com/myorg/my-library → Gitea (local)           │
│  github.com/myorg/other-repo → Real GitHub             │
│                                                         │
│  /workspace (pre-cloned local sources)                 │
└─────────────────────────────────────────────────────────┘
Shadow环境是一个基于Docker/Podman的容器,包含:
  1. Git Bundle快照 - 精确的工作树状态(包括未提交的变更)
  2. 嵌入式Gitea服务器 - 容器内localhost:3000上的本地Git服务器
  3. 选择性URL重写 - Git
    insteadOf
    规则将特定仓库重定向到本地Gitea
  4. 包管理器隔离 - UV、pip、npm、cargo、go的缓存按Shadow实例隔离
  5. API密钥透传 - 常用API密钥会自动转发到容器内
┌─────────────────────────────────────────────────────────┐
│  Shadow Container                                       │
│  ┌───────────────────────────────────────────────────┐  │
│  │  Gitea Server (localhost:3000)                    │  │
│  │  - myorg/my-library (your snapshot)               │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  Git URL Rewriting:                                     │
│  github.com/myorg/my-library → Gitea (local)           │
│  github.com/myorg/other-repo → Real GitHub             │
│                                                         │
│  /workspace (pre-cloned local sources)                 │
└─────────────────────────────────────────────────────────┘

How Git URL Rewriting Works

Git URL重写的工作原理

When you create a shadow with
~/repos/my-lib:myorg/my-lib
:
  1. Your working directory is captured exactly as-is (uncommitted changes included)
  2. Snapshot is bundled with full git history
  3. Container starts with Gitea server
  4. Snapshot pushed to Gitea as
    myorg/my-lib
  5. Git config adds
    insteadOf
    rules:
    [url "http://shadow:shadow@localhost:3000/myorg/my-lib.git"]
        insteadOf = https://github.com/myorg/my-lib.git
  6. Any
    git clone https://github.com/myorg/my-lib
    → uses YOUR local snapshot
  7. All other GitHub URLs → fetch from real GitHub
Result: Only your specified repos are local; everything else uses production sources.
当你使用
~/repos/my-lib:myorg/my-lib
创建Shadow环境时:
  1. 精确捕获你的工作目录状态(包括未提交的变更)
  2. 将完整Git历史打包为快照
  3. 启动容器并运行Gitea服务器
  4. 将快照推送到Gitea,命名为
    myorg/my-lib
  5. Git配置添加
    insteadOf
    规则:
    [url "http://shadow:shadow@localhost:3000/myorg/my-lib.git"]
        insteadOf = https://github.com/myorg/my-lib.git
  6. 任何
    git clone https://github.com/myorg/my-lib
    操作都会使用你的本地快照
  7. 所有其他GitHub URL仍会从真实GitHub获取
结果:只有你指定的仓库使用本地源,其他所有依赖都使用生产环境源。

Quick Start [LEVEL 1]

快速开始 [LEVEL 1]

Installation

安装

For Amplifier Users (native integration):
bash
undefined
Amplifier用户(原生集成):
bash
undefined

Shadow tool is built-in - no installation needed

Shadow工具已内置 - 无需额外安装

amplifier run --bundle amplihack

**For Other Agents** (standalone CLI):
```bash
amplifier run --bundle amplihack

**其他Agent用户**(独立CLI):
```bash

Install via uvx (recommended)

推荐通过uvx安装

uvx amplifier-shadow --version
uvx amplifier-shadow --version

Or via pip

或通过pip安装

pip install amplifier-bundle-shadow
pip install amplifier-bundle-shadow

Verify installation

验证安装

amplifier-shadow --version

**Prerequisites**:
- Docker or Podman installed and running
- Git installed
amplifier-shadow --version

**前置要求**:
- 已安装并运行Docker或Podman
- 已安装Git

Your First Shadow (CLI)

你的第一个Shadow环境(CLI方式)

bash
undefined
bash
undefined

Create shadow with your local library changes

创建包含本地库变更的Shadow环境

amplifier-shadow create --local ~/repos/my-library:myorg/my-library --name test-lib
amplifier-shadow create --local ~/repos/my-library:myorg/my-library --name test-lib

Inside the shadow, install via git URL

在Shadow环境内通过Git URL安装依赖

→ my-library uses YOUR LOCAL snapshot

→ my-library会使用你的本地快照

→ all other dependencies fetch from REAL GitHub

→ 所有其他依赖从真实GitHub获取

amplifier-shadow exec test-lib "uv pip install git+https://github.com/myorg/my-library"
amplifier-shadow exec test-lib "uv pip install git+https://github.com/myorg/my-library"

Run tests

运行测试

amplifier-shadow exec test-lib "cd /workspace && pytest"
amplifier-shadow exec test-lib "cd /workspace && pytest"

See what changed

查看变更内容

amplifier-shadow diff test-lib
amplifier-shadow diff test-lib

Clean up when done

测试完成后清理

amplifier-shadow destroy test-lib
undefined
amplifier-shadow destroy test-lib
undefined

Your First Shadow (Amplifier Tool)

你的第一个Shadow环境(Amplifier工具方式)

python
undefined
python
undefined

Create shadow with local changes

创建包含本地变更的Shadow环境

shadow.create(local_sources=["~/repos/my-library:myorg/my-library"])
shadow.create(local_sources=["~/repos/my-library:myorg/my-library"])

Execute commands

执行命令

shadow.exec(shadow_id, "uv pip install git+https://github.com/myorg/my-library") shadow.exec(shadow_id, "pytest tests/")
shadow.exec(shadow_id, "uv pip install git+https://github.com/myorg/my-library") shadow.exec(shadow_id, "pytest tests/")

Extract results

提取测试结果

shadow.extract(shadow_id, "/workspace/test-results", "./results")
shadow.extract(shadow_id, "/workspace/test-results", "./results")

Cleanup

清理环境

shadow.destroy(shadow_id)
undefined
shadow.destroy(shadow_id)
undefined

Tool Reference by Agent Type [LEVEL 2]

按Agent类型划分的工具参考 [LEVEL 2]

Amplifier (Native Integration)

Amplifier(原生集成)

Best experience - shadow is a first-class tool with automatic setup:
python
undefined
最佳体验 - Shadow是一等公民工具,支持自动配置:
python
undefined

All operations via shadow tool

所有操作通过shadow工具完成

result = shadow.create( local_sources=["~/repos/lib:org/lib"], verify=True # Automatic smoke test )
result = shadow.create( local_sources=["~/repos/lib:org/lib"], verify=True # 自动执行冒烟测试 )

Integrated error handling and observability

集成错误处理和可观测性

if result.ready: shadow.exec(result.shadow_id, "pytest")

**Features**:
- Automatic API key passthrough
- Built-in smoke tests and health checks
- Integrated with other Amplifier tools
- Session-aware cleanup
if result.ready: shadow.exec(result.shadow_id, "pytest")

**特性**:
- 自动API密钥透传
- 内置冒烟测试和健康检查
- 与其他Amplifier工具集成
- 会话感知的自动清理

Claude Code Standalone

Claude Code独立使用

Use the CLI directly from bash tool:
bash
undefined
直接从bash工具调用CLI:
bash
undefined

All operations via amplifier-shadow CLI

所有操作通过amplifier-shadow CLI完成

uvx amplifier-shadow create --local ~/repos/my-lib:org/my-lib --name test
uvx amplifier-shadow exec test "pip install -e /workspace/org/my-lib" uvx amplifier-shadow exec test "pytest"
uvx amplifier-shadow destroy test
undefined
uvx amplifier-shadow create --local ~/repos/my-lib:org/my-lib --name test
uvx amplifier-shadow exec test "pip install -e /workspace/org/my-lib" uvx amplifier-shadow exec test "pytest"
uvx amplifier-shadow destroy test
undefined

GitHub Copilot

GitHub Copilot

Same CLI interface as Claude Code:
bash
undefined
与Claude Code使用相同的CLI接口:
bash
undefined

Install once

仅需安装一次

pip install amplifier-bundle-shadow
pip install amplifier-bundle-shadow

Use in workflow

在工作流中使用

amplifier-shadow create --local ~/repos/lib:org/lib amplifier-shadow exec shadow-xxx "npm install && npm test"
undefined
amplifier-shadow create --local ~/repos/lib:org/lib amplifier-shadow exec shadow-xxx "npm install && npm test"
undefined

Manual/DIY (Any Agent)

手动/DIY(任意Agent)

Use the provided shell scripts and Docker Compose examples (see Level 3).
使用提供的Shell脚本和Docker Compose示例(见Level 3)。

Common Patterns [LEVEL 2]

常见模式 [LEVEL 2]

Pattern: Test Library Changes Before Publishing

模式:发布前测试库变更

bash
undefined
bash
undefined

Test your library with its dependents

测试你的库与其依赖项目的兼容性

amplifier-shadow create --local ~/repos/my-library:myorg/my-library --name lib-test
amplifier-shadow create --local ~/repos/my-library:myorg/my-library --name lib-test

Clone dependent project and install

克隆依赖项目并安装

amplifier-shadow exec lib-test " cd /workspace && git clone https://github.com/myorg/dependent-app && cd dependent-app && uv venv && . .venv/bin/activate && uv pip install git+https://github.com/myorg/my-library && pytest "
undefined
amplifier-shadow exec lib-test " cd /workspace && git clone https://github.com/myorg/dependent-app && cd dependent-app && uv venv && . .venv/bin/activate && uv pip install git+https://github.com/myorg/my-library && pytest "
undefined

Pattern: Multi-Repo Changes

模式:多仓库变更测试

bash
undefined
bash
undefined

Testing changes across multiple repos

测试跨多个仓库的变更

amplifier-shadow create
--local ~/repos/core-lib:myorg/core-lib
--local ~/repos/cli-tool:myorg/cli-tool
--name multi-test
amplifier-shadow create
--local ~/repos/core-lib:myorg/core-lib
--local ~/repos/cli-tool:myorg/cli-tool
--name multi-test

Both local sources will be used

两个本地源都会被使用

amplifier-shadow exec multi-test "uv pip install git+https://github.com/myorg/cli-tool"
undefined
amplifier-shadow exec multi-test "uv pip install git+https://github.com/myorg/cli-tool"
undefined

Pattern: Iterate on Failures

模式:迭代修复失败用例

bash
undefined
bash
undefined

1. Create shadow and run tests

1. 创建Shadow环境并运行测试

amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" # Fails
amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" # 测试失败

2. Fix code locally on host

2. 在本地主机上修复代码

3. Destroy and recreate (picks up your local changes)

3. 销毁并重新创建Shadow环境(会拾取本地变更)

amplifier-shadow destroy test amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" # Passes
amplifier-shadow destroy test amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" # 测试通过

4. Commit with confidence!

4. 放心提交代码!

git commit -m "Fix issue"
undefined
git commit -m "Fix issue"
undefined

Pattern: Pre-Push CI Validation

模式:推送前CI验证

bash
undefined
bash
undefined

Run your CI script in shadow before pushing

在推送前在Shadow环境中运行CI脚本

amplifier-shadow create --local ~/repos/project:org/project --name ci-check
amplifier-shadow exec ci-check " cd /workspace/org/project && ./scripts/ci.sh "
amplifier-shadow create --local ~/repos/project:org/project --name ci-check
amplifier-shadow exec ci-check " cd /workspace/org/project && ./scripts/ci.sh "

If CI script passes, your push will likely succeed

如果CI脚本通过,你的推送大概率会成功

undefined
undefined

Verification Best Practices [LEVEL 2]

验证最佳实践 [LEVEL 2]

Always Verify Local Sources Are Used

始终验证本地源是否被使用

After creating a shadow, confirm your local code is actually being used:
bash
undefined
创建Shadow环境后,确认它确实在使用你的本地代码:
bash
undefined

Step 1: Check snapshot commits (from create output)

步骤1:查看快照提交记录(来自create命令的输出)

amplifier-shadow create --local ~/repos/lib:org/lib
amplifier-shadow create --local ~/repos/lib:org/lib

Output shows: snapshot_commits: {"org/lib": "abc1234..."}

输出会显示:snapshot_commits: {"org/lib": "abc1234..."}

Step 2: Compare with install output

步骤2:与安装输出对比

amplifier-shadow exec shadow-xxx "uv pip install git+https://github.com/org/lib"
amplifier-shadow exec shadow-xxx "uv pip install git+https://github.com/org/lib"

Look for: lib @ git+...@abc1234

查找:lib @ git+...@abc1234

If commits match, your local code is being used!

如果提交记录匹配,说明正在使用你的本地代码!

undefined
undefined

Pre-Cloned Repository Locations

预克隆仓库位置

Local sources are automatically cloned to
/workspace/{org}/{repo}
:
bash
undefined
本地源会自动克隆到
/workspace/{org}/{repo}
bash
undefined

Your local source microsoft/my-library is available at:

你的本地源microsoft/my-library会位于:

/workspace/microsoft/my-library
/workspace/microsoft/my-library

Use for editable installs (Python)

用于可编辑安装(Python)

amplifier-shadow exec shadow-xxx "pip install -e /workspace/microsoft/my-library"
amplifier-shadow exec shadow-xxx "pip install -e /workspace/microsoft/my-library"

Or for Node.js

或用于Node.js

amplifier-shadow exec shadow-xxx "cd /workspace/microsoft/my-package && npm install"

**Always check this location first** - the repo is already there.
amplifier-shadow exec shadow-xxx "cd /workspace/microsoft/my-package && npm install"

**优先检查此位置** - 仓库已经存在于此。

Environment Variable Verification

环境变量验证

bash
undefined
bash
undefined

Don't assume - verify API keys are present!

不要想当然 - 验证API密钥是否存在!

amplifier-shadow exec shadow-xxx "env | grep API_KEY"
amplifier-shadow exec shadow-xxx "env | grep API_KEY"

Check all passed variables

查看所有已传递的变量

amplifier-shadow status shadow-xxx
amplifier-shadow status shadow-xxx

Shows: env_vars_passed: ["ANTHROPIC_API_KEY", ...]

输出会显示:env_vars_passed: ["ANTHROPIC_API_KEY", ...]

undefined
undefined

Troubleshooting [LEVEL 2]

故障排除 [LEVEL 2]

Common Issues

常见问题

"UV tool install" uses cache instead of local source:
Problem: UV may bypass git URL rewriting for cached packages.
Solution:
bash
undefined
"UV工具安装"使用缓存而非本地源:
问题:UV可能会绕过Git URL重写,使用缓存的包。
解决方案:
bash
undefined

Option 1: Install from pre-cloned workspace (recommended)

选项1:从预克隆的工作区安装(推荐)

amplifier-shadow exec xxx "pip install -e /workspace/org/lib"
amplifier-shadow exec xxx "pip install -e /workspace/org/lib"

Option 2: Clear UV cache first

选项2:先清除UV缓存

amplifier-shadow exec xxx "rm -rf /tmp/uv-cache && uv tool install git+https://github.com/org/lib"

**"PEP 668: Externally-Managed Environment"**:

Solution: Always use virtual environments inside shadow:
```bash
amplifier-shadow exec xxx "
  cd /workspace &&
  uv venv &&
  . .venv/bin/activate &&
  uv pip install ...
"
"Container image not found":
Solution: Build the image locally:
bash
amplifier-shadow build
"/workspace permission denied":
Solution: Use
$HOME
or
/tmp
as alternatives:
bash
amplifier-shadow exec xxx "cd $HOME && git clone ..."
amplifier-shadow exec xxx "rm -rf /tmp/uv-cache && uv tool install git+https://github.com/org/lib"

**"PEP 668: Externally-Managed Environment"**:

解决方案:在Shadow环境内始终使用虚拟环境:
```bash
amplifier-shadow exec xxx "
  cd /workspace &&
  uv venv &&
  . .venv/bin/activate &&
  uv pip install ...
"
"容器镜像未找到":
解决方案:本地构建镜像:
bash
amplifier-shadow build
"/workspace权限被拒绝":
解决方案:使用
$HOME
/tmp
作为替代路径:
bash
amplifier-shadow exec xxx "cd $HOME && git clone ..."

Level 3: Advanced Topics [LEVEL 3]

Level 3:高级主题 [LEVEL 3]

Custom Docker Images

自定义Docker镜像

Build your own shadow image with additional tools:
dockerfile
FROM ghcr.io/microsoft/amplifier-shadow:latest
构建包含额外工具的自定义Shadow镜像:
dockerfile
FROM ghcr.io/microsoft/amplifier-shadow:latest

Add your tools

添加你的工具

RUN apt-get update && apt-get install -y
postgresql-client
redis-tools
RUN apt-get update && apt-get install -y
postgresql-client
redis-tools

Add custom scripts

添加自定义脚本

COPY my-test-script.sh /usr/local/bin/

Build and use:
```bash
docker build -t my-shadow:latest .
amplifier-shadow create --image my-shadow:latest --local ~/repos/lib:org/lib
COPY my-test-script.sh /usr/local/bin/

构建并使用:
```bash
docker build -t my-shadow:latest .
amplifier-shadow create --image my-shadow:latest --local ~/repos/lib:org/lib

Shell Scripts (DIY Shadow Setup)

Shell脚本(DIY Shadow环境搭建)

For agents without Amplifier access, use these standalone scripts:
Script 1: Create Git Bundle (
scripts/create-bundle.sh
):
bash
#!/bin/bash
对于无法访问Amplifier的Agent,使用以下独立脚本:
脚本1:创建Git Bundle (
scripts/create-bundle.sh
):
bash
#!/bin/bash

Create git bundle snapshot of working tree

Create git bundle snapshot of working tree

REPO_PATH=$1 OUTPUT_PATH=$2
cd "$REPO_PATH"
REPO_PATH=$1 OUTPUT_PATH=$2
cd "$REPO_PATH"

Fetch all refs to ensure complete history

Fetch all refs to ensure complete history

git fetch --all --tags --quiet 2>/dev/null || true
git fetch --all --tags --quiet 2>/dev/null || true

Check for uncommitted changes

Check for uncommitted changes

if [[ -n $(git status --porcelain) ]]; then # Create temp clone and commit changes TEMP_DIR=$(mktemp -d) git clone --quiet "$REPO_PATH" "$TEMP_DIR"
# Sync working tree (including deletions)
rsync -a --delete --exclude='.git' "$REPO_PATH/" "$TEMP_DIR/"

cd "$TEMP_DIR"
git add -A
git commit --allow-empty -m "Shadow snapshot" --author="Shadow <shadow@localhost>"

# Create bundle
git bundle create "$OUTPUT_PATH" --all

cd /
rm -rf "$TEMP_DIR"
else # Clean repo - just bundle it git bundle create "$OUTPUT_PATH" --all fi
echo "Bundle created: $OUTPUT_PATH"

**Script 2: Setup Shadow Container** (`scripts/setup-shadow.sh`):
```bash
#!/bin/bash
if [[ -n $(git status --porcelain) ]]; then # Create temp clone and commit changes TEMP_DIR=$(mktemp -d) git clone --quiet "$REPO_PATH" "$TEMP_DIR"
# Sync working tree (including deletions)
rsync -a --delete --exclude='.git' "$REPO_PATH/" "$TEMP_DIR/"

cd "$TEMP_DIR"
git add -A
git commit --allow-empty -m "Shadow snapshot" --author="Shadow <shadow@localhost>"

# Create bundle
git bundle create "$OUTPUT_PATH" --all

cd /
rm -rf "$TEMP_DIR"
else # Clean repo - just bundle it git bundle create "$OUTPUT_PATH" --all fi
echo "Bundle created: $OUTPUT_PATH"

**脚本2:搭建Shadow容器** (`scripts/setup-shadow.sh`):
```bash
#!/bin/bash

Start container with Gitea and configure git URL rewriting

Start container with Gitea and configure git URL rewriting

CONTAINER_NAME=$1 BUNDLE_PATH=$2 ORG=$3 REPO=$4
CONTAINER_NAME=$1 BUNDLE_PATH=$2 ORG=$3 REPO=$4

Start container

Start container

docker run -d
--name "$CONTAINER_NAME"
-v "$BUNDLE_PATH:/snapshots/bundle.git:ro"
ghcr.io/microsoft/amplifier-shadow:latest
docker run -d
--name "$CONTAINER_NAME"
-v "$BUNDLE_PATH:/snapshots/bundle.git:ro"
ghcr.io/microsoft/amplifier-shadow:latest

Wait for Gitea

Wait for Gitea

echo "Waiting for Gitea to start..." until docker exec "$CONTAINER_NAME" curl -sf http://localhost:3000/api/v1/version > /dev/null; do sleep 1 done
echo "Waiting for Gitea to start..." until docker exec "$CONTAINER_NAME" curl -sf http://localhost:3000/api/v1/version > /dev/null; do sleep 1 done

Create org and repo in Gitea

Create org and repo in Gitea

docker exec "$CONTAINER_NAME" bash -c " curl -s -u shadow:shadow
-H 'Content-Type: application/json'
-d '{"username":"$ORG"}'
http://localhost:3000/api/v1/orgs
curl -s -u shadow:shadow \
    -H 'Content-Type: application/json' \
    -d '{\"name\":\"$REPO\",\"private\":false}' \
    http://localhost:3000/api/v1/orgs/$ORG/repos
"
docker exec "$CONTAINER_NAME" bash -c " curl -s -u shadow:shadow
-H 'Content-Type: application/json'
-d '{"username":"$ORG"}'
http://localhost:3000/api/v1/orgs
curl -s -u shadow:shadow \
    -H 'Content-Type: application/json' \
    -d '{\"name\":\"$REPO\",\"private\":false}' \
    http://localhost:3000/api/v1/orgs/$ORG/repos
"

Push bundle to Gitea

Push bundle to Gitea

docker exec "$CONTAINER_NAME" bash -c " cd /tmp && git init --bare repo.git && cd repo.git && git fetch /snapshots/bundle.git refs/heads/:refs/heads/ && git remote add origin http://shadow:shadow@localhost:3000/$ORG/$REPO.git && git push origin --all --force "
docker exec "$CONTAINER_NAME" bash -c " cd /tmp && git init --bare repo.git && cd repo.git && git fetch /snapshots/bundle.git refs/heads/:refs/heads/ && git remote add origin http://shadow:shadow@localhost:3000/$ORG/$REPO.git && git push origin --all --force "

Configure git URL rewriting

Configure git URL rewriting

docker exec "$CONTAINER_NAME" bash -c " git config --global url.'http://shadow:shadow@localhost:3000/$ORG/$REPO.git'.insteadOf 'https://github.com/$ORG/$REPO.git' "
echo "Shadow container ready: $CONTAINER_NAME" echo "Local source: $ORG/$REPO"

**Usage**:
```bash
docker exec "$CONTAINER_NAME" bash -c " git config --global url.'http://shadow:shadow@localhost:3000/$ORG/$REPO.git'.insteadOf 'https://github.com/$ORG/$REPO.git' "
echo "Shadow container ready: $CONTAINER_NAME" echo "Local source: $ORG/$REPO"

**使用方法**:
```bash

Create bundle from your repo

从你的仓库创建bundle

./scripts/create-bundle.sh ~/repos/my-lib /tmp/my-lib.bundle
./scripts/create-bundle.sh ~/repos/my-lib /tmp/my-lib.bundle

Setup shadow container

搭建Shadow容器

./scripts/setup-shadow.sh shadow-test /tmp/my-lib.bundle myorg my-lib
./scripts/setup-shadow.sh shadow-test /tmp/my-lib.bundle myorg my-lib

Test

测试

docker exec shadow-test bash -c " git clone https://github.com/myorg/my-lib /tmp/test && cd /tmp/test && git log -1 --oneline "
undefined
docker exec shadow-test bash -c " git clone https://github.com/myorg/my-lib /tmp/test && cd /tmp/test && git log -1 --oneline "
undefined

Docker Compose Examples

Docker Compose示例

Example 1: Single Repository (
docker-compose/single-repo.yml
):
yaml
version: '3.8'

services:
  shadow:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: shadow-single
    volumes:
      - ./snapshots:/snapshots:ro
      - ./workspace:/workspace
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        tail -f /dev/null
      "
Example 2: Multi-Repository Testing (
docker-compose/multi-repo.yml
):
yaml
version: '3.8'

services:
  shadow-multi:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: shadow-multi
    volumes:
      # Mount multiple bundles
      - ./snapshots/core-lib.bundle:/snapshots/org/core-lib.bundle:ro
      - ./snapshots/cli-tool.bundle:/snapshots/org/cli-tool.bundle:ro
      - ./workspace:/workspace
    environment:
      # Pass API keys from host
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      # UV cache isolation
      - UV_CACHE_DIR=/tmp/uv-cache
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        /usr/local/bin/setup-repos.sh org/core-lib org/cli-tool &&
        tail -f /dev/null
      "
Usage:
bash
undefined
示例1:单仓库 (
docker-compose/single-repo.yml
):
yaml
version: '3.8'

services:
  shadow:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: shadow-single
    volumes:
      - ./snapshots:/snapshots:ro
      - ./workspace:/workspace
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        tail -f /dev/null
      "
示例2:多仓库测试 (
docker-compose/multi-repo.yml
):
yaml
version: '3.8'

services:
  shadow-multi:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: shadow-multi
    volumes:
      # 挂载多个bundle
      - ./snapshots/core-lib.bundle:/snapshots/org/core-lib.bundle:ro
      - ./snapshots/cli-tool.bundle:/snapshots/org/cli-tool.bundle:ro
      - ./workspace:/workspace
    environment:
      # 从主机传递API密钥
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      # UV缓存隔离
      - UV_CACHE_DIR=/tmp/uv-cache
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        /usr/local/bin/setup-repos.sh org/core-lib org/cli-tool &&
        tail -f /dev/null
      "
使用方法:
bash
undefined

Create bundles for your repos

为你的仓库创建bundle

git -C ~/repos/core-lib bundle create snapshots/core-lib.bundle --all git -C ~/repos/cli-tool bundle create snapshots/cli-tool.bundle --all
git -C ~/repos/core-lib bundle create snapshots/core-lib.bundle --all git -C ~/repos/cli-tool bundle create snapshots/cli-tool.bundle --all

Start shadow

启动Shadow环境

docker-compose -f docker-compose/multi-repo.yml up -d
docker-compose -f docker-compose/multi-repo.yml up -d

Run tests

运行测试

docker-compose exec shadow-multi bash -c " cd /workspace && git clone https://github.com/org/cli-tool && cd cli-tool && uv pip install -e . pytest "
docker-compose exec shadow-multi bash -c " cd /workspace && git clone https://github.com/org/cli-tool && cd cli-tool && uv pip install -e . pytest "

Cleanup

清理环境

docker-compose down

**Example 3: CI Integration** (`docker-compose/ci-shadow.yml`):

```yaml
version: '3.8'

services:
  ci-shadow:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: ci-shadow
    volumes:
      - ./snapshots:/snapshots:ro
      - ./test-results:/test-results
    environment:
      - CI=true
      - GITHUB_ACTIONS=true
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        /usr/local/bin/run-ci-tests.sh > /test-results/output.log 2>&1
      "
GitHub Actions Integration:
yaml
undefined
docker-compose down

**示例3:CI集成** (`docker-compose/ci-shadow.yml`):

```yaml
version: '3.8'

services:
  ci-shadow:
    image: ghcr.io/microsoft/amplifier-shadow:latest
    container_name: ci-shadow
    volumes:
      - ./snapshots:/snapshots:ro
      - ./test-results:/test-results
    environment:
      - CI=true
      - GITHUB_ACTIONS=true
    command: >
      bash -c "
        /usr/local/bin/gitea-init.sh &&
        /usr/local/bin/run-ci-tests.sh > /test-results/output.log 2>&1
      "
GitHub Actions集成:
yaml
undefined

.github/workflows/shadow-test.yml

.github/workflows/shadow-test.yml

name: Shadow Test
on: [push, pull_request]
jobs: shadow-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Create git bundle
    run: git bundle create snapshot.bundle --all
  
  - name: Run shadow tests
    run: |
      docker run --rm \
        -v $PWD/snapshot.bundle:/snapshots/bundle.git:ro \
        ghcr.io/microsoft/amplifier-shadow:latest \
        /usr/local/bin/test-in-shadow.sh org/repo
undefined
name: Shadow Test
on: [push, pull_request]
jobs: shadow-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Create git bundle
    run: git bundle create snapshot.bundle --all
  
  - name: Run shadow tests
    run: |
      docker run --rm \
        -v $PWD/snapshot.bundle:/snapshots/bundle.git:ro \
        ghcr.io/microsoft/amplifier-shadow:latest \
        /usr/local/bin/test-in-shadow.sh org/repo
undefined

Integration with Outside-In Testing

与Outside-In测试集成

Combine shadow environments with agentic outside-in tests:
bash
undefined
将Shadow环境与Agent化Outside-In测试结合使用:
bash
undefined

Create shadow with local changes

创建包含本地变更的Shadow环境

amplifier-shadow create --local ~/repos/lib:org/lib --name test
amplifier-shadow create --local ~/repos/lib:org/lib --name test

Run outside-in test scenarios inside shadow

在Shadow环境内运行Outside-In测试场景

amplifier-shadow exec test "gadugi-agentic-test run test-scenario.yaml"
amplifier-shadow exec test "gadugi-agentic-test run test-scenario.yaml"

Extract evidence

提取测试证据

amplifier-shadow extract test /evidence ./test-evidence

See the `outside-in-testing` skill for complete integration examples.
amplifier-shadow extract test /evidence ./test-evidence

完整集成示例请查看`outside-in-testing`技能文档。

Best Practices [LEVEL 2]

最佳实践 [LEVEL 2]

1. Always Verify Your Sources Are Used

1. 始终验证你的源是否被使用

Don't assume - verify that the shadow is actually using your local code:
bash
undefined
不要想当然 - 确认Shadow环境确实在使用你的本地代码:
bash
undefined

Check snapshot commits

查看快照提交记录

amplifier-shadow status shadow-xxx | grep snapshot_commit
amplifier-shadow status shadow-xxx | grep snapshot_commit

Verify install resolves to that commit

验证安装是否解析到该提交

amplifier-shadow exec shadow-xxx "pip install git+https://github.com/org/lib" | grep "org/lib @"
undefined
amplifier-shadow exec shadow-xxx "pip install git+https://github.com/org/lib" | grep "org/lib @"
undefined

2. Use Pre-Cloned Workspace

2. 使用预克隆工作区

Local sources are automatically at
/workspace/{org}/{repo}
:
bash
undefined
本地源会自动位于
/workspace/{org}/{repo}
bash
undefined

✅ FAST: Use pre-cloned repo

✅ 快速:使用预克隆仓库

amplifier-shadow exec xxx "pip install -e /workspace/org/lib"
amplifier-shadow exec xxx "pip install -e /workspace/org/lib"

❌ SLOWER: Clone again

❌ 较慢:重新克隆

amplifier-shadow exec xxx "git clone https://github.com/org/lib && pip install -e lib"
undefined
amplifier-shadow exec xxx "git clone https://github.com/org/lib && pip install -e lib"
undefined

3. Isolate Package Manager Caches

3. 隔离包管理器缓存

Shadow environments automatically isolate caches to prevent stale packages:
  • Python UV:
    /tmp/uv-cache
  • Python pip:
    /tmp/pip-cache
  • Node npm:
    /tmp/npm-cache
  • Rust cargo:
    /tmp/cargo-home
  • Go modules:
    /tmp/go-mod-cache
These are set automatically - no action needed.
Shadow环境会自动隔离缓存,避免依赖包过期:
  • Python UV:
    /tmp/uv-cache
  • Python pip:
    /tmp/pip-cache
  • Node npm:
    /tmp/npm-cache
  • Rust cargo:
    /tmp/cargo-home
  • Go modules:
    /tmp/go-mod-cache
这些配置会自动设置 - 无需手动操作。

4. Pass Required Environment Variables

4. 传递所需的环境变量

bash
undefined
bash
undefined

Amplifier (automatic for common API keys)

Amplifier(常用API密钥会自动传递)

shadow.create(local_sources=["~/repos/lib:org/lib"])
shadow.create(local_sources=["~/repos/lib:org/lib"])

CLI (explicit)

CLI(显式传递)

amplifier-shadow create
--local ~/repos/lib:org/lib
--env ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
--env CUSTOM_VAR=value
undefined
amplifier-shadow create
--local ~/repos/lib:org/lib
--env ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
--env CUSTOM_VAR=value
undefined

5. Clean Up After Testing

5. 测试完成后清理

bash
undefined
bash
undefined

Always destroy shadows when done

测试完成后务必销毁Shadow环境

amplifier-shadow destroy shadow-xxx
amplifier-shadow destroy shadow-xxx

Or destroy all

或销毁所有Shadow环境

amplifier-shadow destroy-all
undefined
amplifier-shadow destroy-all
undefined

6. Use Named Shadows for Clarity

6. 使用有意义的名称命名Shadow环境

bash
undefined
bash
undefined

✅ GOOD: Descriptive name

✅ 推荐:使用描述性名称

amplifier-shadow create --local ~/repos/lib:org/lib --name test-breaking-change
amplifier-shadow create --local ~/repos/lib:org/lib --name test-breaking-change

❌ BAD: Auto-generated

❌ 不推荐:自动生成的名称

amplifier-shadow create --local ~/repos/lib:org/lib
amplifier-shadow create --local ~/repos/lib:org/lib

Creates shadow-a3f2b8c1 (hard to remember)

会创建shadow-a3f2b8c1(难以记忆)

undefined
undefined

Integration Patterns [LEVEL 3]

集成模式 [LEVEL 3]

Pattern: Shadow + Outside-In Tests

模式:Shadow + Outside-In测试

Combine shadow isolation with declarative test scenarios:
yaml
undefined
将Shadow隔离环境与声明式测试场景结合:
yaml
undefined

test-scenario.yaml

test-scenario.yaml

scenario: name: "Library Integration Test" type: cli
steps: - action: launch target: "/workspace/org/lib/cli.py"
- action: verify_output
  contains: "Success"

Run in shadow:
```bash
amplifier-shadow create --local ~/repos/lib:org/lib --name test
amplifier-shadow exec test "gadugi-agentic-test run test-scenario.yaml"
scenario: name: "Library Integration Test" type: cli
steps: - action: launch target: "/workspace/org/lib/cli.py"
- action: verify_output
  contains: "Success"

在Shadow环境中运行:
```bash
amplifier-shadow create --local ~/repos/lib:org/lib --name test
amplifier-shadow exec test "gadugi-agentic-test run test-scenario.yaml"

Pattern: Shadow + pytest

模式:Shadow + pytest

bash
amplifier-shadow create --local ~/repos/lib:org/lib --name pytest-run

amplifier-shadow exec pytest-run "
  cd /workspace/org/lib &&
  uv venv && . .venv/bin/activate &&
  pip install -e '.[dev]' &&
  pytest --cov=src --cov-report=html
"
bash
amplifier-shadow create --local ~/repos/lib:org/lib --name pytest-run

amplifier-shadow exec pytest-run "
  cd /workspace/org/lib &&
  uv venv && . .venv/bin/activate &&
  pip install -e '.[dev]' &&
  pytest --cov=src --cov-report=html
"

Extract coverage report

提取覆盖率报告

amplifier-shadow extract pytest-run /workspace/org/lib/htmlcov ./coverage-report
undefined
amplifier-shadow extract pytest-run /workspace/org/lib/htmlcov ./coverage-report
undefined

Pattern: Shadow + npm test

模式:Shadow + npm test

bash
amplifier-shadow create --local ~/repos/pkg:org/pkg --name npm-test

amplifier-shadow exec npm-test "
  cd /workspace/org/pkg &&
  npm install &&
  npm test
"
bash
amplifier-shadow create --local ~/repos/pkg:org/pkg --name npm-test

amplifier-shadow exec npm-test "
  cd /workspace/org/pkg &&
  npm install &&
  npm test
"

Pattern: Shadow + cargo test

模式:Shadow + cargo test

bash
amplifier-shadow create --local ~/repos/crate:org/crate --name cargo-test

amplifier-shadow exec cargo-test "
  cd /workspace/org/crate &&
  cargo build &&
  cargo test
"
bash
amplifier-shadow create --local ~/repos/crate:org/crate --name cargo-test

amplifier-shadow exec cargo-test "
  cd /workspace/org/crate &&
  cargo build &&
  cargo test
"

Philosophy Alignment [LEVEL 2]

理念对齐 [LEVEL 2]

This skill follows amplihack's core principles:
本技能遵循amplihack的核心原则:

Ruthless Simplicity

极致简洁

  • Minimal abstraction: Shadow = container + gitea + URL rewriting
  • No frameworks: Pure Docker, git, and shell scripts
  • Essential only: Only captures what's needed (git bundle, not entire filesystems)
  • 最小抽象:Shadow = 容器 + gitea + URL重写
  • 无框架依赖:仅使用Docker、git和Shell脚本
  • 仅保留必要功能:仅捕获所需内容(Git Bundle,而非整个文件系统)

Modular Design (Bricks & Studs)

模块化设计(积木式)

  • Self-contained: Each shadow is independent
  • Clear contract: Git URLs in → local sources out
  • Composable: Combine with other testing tools
  • 独立封装:每个Shadow环境都是独立的
  • 清晰契约:输入Git URL,输出本地源
  • 可组合:可与其他测试工具结合使用

Zero-BS Implementation

零废话实现

  • No stubs: Every script works completely
  • Working defaults: Reasonable defaults for all operations
  • Clear errors: Actionable error messages with troubleshooting
  • 无存根:每个脚本都能完整运行
  • 合理默认配置:所有操作都有合理的默认值
  • 清晰错误提示:提供可操作的错误信息和故障排除指导

Outside-In Thinking

由外而内的思考

  • User perspective: Test what users will see
  • Implementation agnostic: Don't care how code works internally
  • Behavior-driven: Focus on outcomes
  • 用户视角:测试用户实际会看到的内容
  • 与实现无关:不关心代码内部如何工作
  • 行为驱动:关注最终结果

CLI Reference [LEVEL 3]

CLI参考 [LEVEL 3]

Commands

命令

bash
undefined
bash
undefined

Create shadow environment

创建Shadow环境

amplifier-shadow create [OPTIONS] --local, -l TEXT Local source mapping: /path/to/repo:org/name (repeatable) --name, -n TEXT Name for environment (auto-generated if not provided) --image, -i TEXT Container image (default: amplifier-shadow:local) --env, -e TEXT Environment variable: KEY=VALUE or KEY to inherit (repeatable) --env-file FILE File with environment variables (one per line) --pass-api-keys Auto-pass common API key env vars (default: enabled)
amplifier-shadow create [OPTIONS] --local, -l TEXT 本地源映射:/path/to/repo:org/name(可重复使用) --name, -n TEXT 环境名称(未提供则自动生成) --image, -i TEXT 容器镜像(默认:amplifier-shadow:local) --env, -e TEXT 环境变量:KEY=VALUE 或 KEY(继承主机值,可重复使用) --env-file FILE 包含环境变量的文件(每行一个) --pass-api-keys 自动传递常用API密钥环境变量(默认:启用)

Execute command in shadow

在Shadow环境中执行命令

amplifier-shadow exec SHADOW_ID COMMAND --timeout INTEGER Timeout in seconds (default: 300)
amplifier-shadow exec SHADOW_ID COMMAND --timeout INTEGER 超时时间(秒,默认:300)

Show changed files

显示变更文件

amplifier-shadow diff SHADOW_ID [PATH]
amplifier-shadow diff SHADOW_ID [PATH]

Extract file from shadow

从Shadow环境提取文件

amplifier-shadow extract SHADOW_ID CONTAINER_PATH HOST_PATH
amplifier-shadow extract SHADOW_ID CONTAINER_PATH HOST_PATH

Inject file into shadow

向Shadow环境注入文件

amplifier-shadow inject SHADOW_ID HOST_PATH CONTAINER_PATH
amplifier-shadow inject SHADOW_ID HOST_PATH CONTAINER_PATH

List all shadows

列出所有Shadow环境

amplifier-shadow list
amplifier-shadow list

Show shadow status

显示Shadow环境状态

amplifier-shadow status SHADOW_ID
amplifier-shadow status SHADOW_ID

Destroy shadow

销毁Shadow环境

amplifier-shadow destroy SHADOW_ID --force Force destruction even on errors
amplifier-shadow destroy SHADOW_ID --force 即使出错也强制销毁

Destroy all shadows

销毁所有Shadow环境

amplifier-shadow destroy-all --force Force destruction even on errors
amplifier-shadow destroy-all --force 即使出错也强制销毁

Build shadow image locally

本地构建Shadow镜像

amplifier-shadow build
amplifier-shadow build

Open interactive shell

打开交互式Shell

amplifier-shadow shell SHADOW_ID
undefined
amplifier-shadow shell SHADOW_ID
undefined

Quick Reference Card [LEVEL 1]

快速参考卡片 [LEVEL 1]

bash
undefined
bash
undefined

Typical workflow

典型工作流

amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" amplifier-shadow destroy test
amplifier-shadow create --local ~/repos/lib:org/lib --name test amplifier-shadow exec test "pytest" amplifier-shadow destroy test

Multi-repo

多仓库场景

amplifier-shadow create
--local ~/repos/lib1:org/lib1
--local ~/repos/lib2:org/lib2
--name multi
amplifier-shadow create
--local ~/repos/lib1:org/lib1
--local ~/repos/lib2:org/lib2
--name multi

With environment variables

传递环境变量

amplifier-shadow create
--local ~/repos/lib:org/lib
--env API_KEY=$API_KEY
--name test
amplifier-shadow create
--local ~/repos/lib:org/lib
--env API_KEY=$API_KEY
--name test

Interactive shell

交互式Shell

amplifier-shadow shell test
amplifier-shadow shell test

Extract results

提取结果

amplifier-shadow extract test /workspace/results ./local-results
undefined
amplifier-shadow extract test /workspace/results ./local-results
undefined

Related Skills [LEVEL 1]

相关技能 [LEVEL 1]

  • outside-in-testing: Run agentic tests in shadow environments
  • test-gap-analyzer: Find untested code paths (complement shadow testing)
  • philosophy-guardian: Verify shadow scripts follow ruthless simplicity
  • outside-in-testing:在Shadow环境中运行Agent化Outside-In测试
  • test-gap-analyzer:查找未测试的代码路径(与Shadow测试互补)
  • philosophy-guardian:验证Shadow脚本是否遵循极致简洁原则

Troubleshooting Checklist [LEVEL 2]

故障排除检查表 [LEVEL 2]

When shadow tests fail:
  • Verify local sources are being used (check snapshot commits)
  • Check pre-cloned repos exist at
    /workspace/{org}/{repo}
  • Verify environment variables are passed (run
    env
    inside shadow)
  • Clear package manager caches if stale
  • Check git URL rewriting is configured (
    git config --list
    )
  • Verify Gitea is accessible (
    curl http://localhost:3000/api/v1/version
    )
  • Use virtual environments (avoid PEP 668 errors)
  • Check container is running (
    amplifier-shadow status
    )
当Shadow测试失败时:
  • 验证本地源是否被使用(检查快照提交记录)
  • 检查预克隆仓库是否存在于
    /workspace/{org}/{repo}
  • 验证环境变量是否已传递(在Shadow环境内运行
    env
  • 如果依赖包过期,清除包管理器缓存
  • 检查Git URL重写是否已配置(
    git config --list
  • 验证Gitea是否可访问(
    curl http://localhost:3000/api/v1/version
  • 使用虚拟环境(避免PEP 668错误)
  • 检查容器是否正在运行(
    amplifier-shadow status

Changelog [LEVEL 3]

更新日志 [LEVEL 3]

Version 1.0.0 (2026-01-29)

版本1.0.0(2026-01-29)

  • Initial skill release
  • Support for Amplifier, Claude Code, GitHub Copilot, manual DIY
  • Shell scripts for standalone usage
  • Docker Compose examples for CI integration
  • Complete CLI reference and troubleshooting guide
  • Integration patterns with outside-in-testing
  • Philosophy alignment with ruthless simplicity

Remember: Shadow environments let you test exactly what's on your machine (uncommitted changes and all) in a clean, isolated environment that mirrors CI. Use them before every significant push to catch issues early.
  • 初始技能发布
  • 支持Amplifier、Claude Code、GitHub Copilot和手动DIY方式
  • 提供独立使用的Shell脚本
  • 提供用于CI集成的Docker Compose示例
  • 完整的CLI参考和故障排除指南
  • 与outside-in-testing的集成模式
  • 与极致简洁理念对齐

记住:Shadow环境让你可以在干净、隔离且与CI一致的环境中,测试你机器上的所有内容(包括未提交的变更)。在每次重要推送前使用它,提前发现问题。