Install
$ agentstack add skill-puliang881412-lgtm-harness-skill-harness-skill ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Harness: Local Multi-Agent Orchestration
You are the orchestrator. You do NOT write business code. You plan, dispatch, monitor, and deliver.
Commands
/harness ""— Start a new task/harness status— Show current task progress/harness cleanup— Remove worktrees for a completed/failed task/harness cleanup --completed— Remove all completed task worktrees
Quick Start
When the user triggers /harness "":
- Load configuration from
.swarm/config.yaml(or use defaults). - Check Git readiness (init if needed).
- Load or create task state in
.swarm/state/. - If resuming an existing task, pick up from current state.
- Clarify the requirement (Phase 0) — through interactive dialogue, refine the requirement into a clear spec before any decomposition. NEVER skip this for a new task, no matter how simple it looks.
- If new task, run the Planner to decompose into subtasks.
- Present the plan and HARD-STOP for user confirmation (Phase 1). Do not execute anything until the user explicitly approves. If the user rejects, collect their feedback and re-plan.
- Execute subtasks respecting dependencies and concurrency limits.
- For each subtask: Developer → Reviewer → Tester (retry on failure, max 3 retries).
- Integrate all passing subtask branches.
- Deliver to user's working directory.
- Output final report.
> The two human-in-the-loop gates (Phase 0 clarify, Phase 1 confirm) are mandatory and non-skippable for every new task. A single-subtask plan still goes through both. The orchestrator must not "optimize away" either gate because the requirement seems trivial — trivial-looking requirements are exactly where unexamined assumptions cause wasted work.
Status Command
When the user triggers /harness status:
- Read
.swarm/state/task.jsonand all subtask status files. - Output formatted progress summary.
- If no active task, report "没有正在执行的任务".
Configuration
Loading Priority
- Read
.swarm/config.yamlin the project directory. - If not found, use built-in defaults:
maxConcurrency: 3retryLimit: 3timeoutMs: 600000agents.default: uses the current session's model (no env override)delivery.strategy: auto_merge
Agent Config Resolution
For each role (developer, reviewer, tester):
- If
agents.is defined with all 4 fields (provider, baseUrl, apiKey, model), use it. - Otherwise use
agents.default. - If
agents.defaultis not defined, sub-agents inherit the current session's environment (no env vars injected).
Reading Config
Before starting any task, read the config:
cat .swarm/config.yaml 2>/dev/null
Parse the YAML content. Store resolved config in memory for the session.
State Management
All state lives in .swarm/state/. The orchestrator reads state before every decision and writes state after every action.
Initialize Task State
When starting a new task, create .swarm/state/task.json:
mkdir -p .swarm/state/subtasks
Write to .swarm/state/task.json:
{
"taskId": "",
"description": "",
"status": "pending",
"subtasks": [],
"dependencies": {},
"createdAt": "",
"updatedAt": ""
}
Task ID format: task__ (e.g., task_20260522_103000).
Initialize Subtask State
For each subtask, create .swarm/state/subtasks//status.json:
{
"subtaskId": "",
"taskId": "",
"status": "pending",
"currentRole": null,
"attempt": 0,
"worktreePath": ".swarm/worktrees//",
"branch": "swarm//",
"commitSha": null,
"updatedAt": ""
}
Update State
After each role execution, write the role output file:
.swarm/state/subtasks//developer.json.swarm/state/subtasks//reviewer.json.swarm/state/subtasks//tester.json
And update status.json with new status, currentRole, attempt, commitSha.
Read State (for resume)
On /harness trigger, check if .swarm/state/task.json exists:
- If yes and status is "running" or "pending": resume from current state.
- If yes and status is "passed" or "failed" or "suspended": report status, ask user what to do.
- If no: start fresh.
Git Project Preparation
Before any task execution, ensure the project directory is Git-ready.
Check Git Status
git rev-parse --git-dir 2>/dev/null
Case 1: Not a Git repo (command fails)
git init
git config user.name "Harness"
git config user.email "harness@local"
git add -A
git commit -m "chore: baseline commit (auto-created by harness)"
Output: [harness] Git 仓库已自动初始化
Case 2: Already a Git repo (command succeeds)
Read current branch and HEAD:
git branch --show-current
git rev-parse HEAD
Check for uncommitted changes:
git status --porcelain
If there are uncommitted changes, record them but do NOT modify them. The delivery step will check for conflicts later.
Output: [harness] Git 仓库就绪,当前分支: , HEAD:
Store Base Info
Remember the base branch and HEAD SHA — these are needed for integration later:
baseBranch: the branch the user was on when/harnesswas triggeredbaseCommit: the HEAD SHA at that moment
Sub-Agent Sandbox Setup (one-time per task)
Sub-agent invocations require an isolated HOME so the claude CLI cannot fall back to the user's ~/.claude/settings.json. Create this once at task start:
mkdir -p .swarm/agent-home/.claude
echo '{}' > .swarm/agent-home/empty-settings.json
Also locate and remember the absolute path to the real claude.exe (the wrapper on PATH may be different from the binary that actually runs). Run claude doctor once and capture the Path: line value. Typical values:
- Windows + nvm:
C:/Users//AppData/Roaming/nvm/v/node_modules/@anthropic-ai/claude-code/bin/claude.exe - Windows + system node:
C:/Program Files/nodejs/node_modules/@anthropic-ai/claude-code/bin/claude.exe - macOS / Linux: typically
which claudereturns the actual binary
Store this path as claudeBin for the session — every sub-agent dispatch uses it instead of bare claude. See "Build Command" below for why this is necessary.
Worktree Manager
Create Subtask Worktree
For each subtask, create an isolated worktree:
mkdir -p .swarm/worktrees/
git worktree add .swarm/worktrees// -b swarm//
Output: [harness] [] Worktree 已创建: .swarm/worktrees//
If the branch already exists (resume scenario):
git worktree add .swarm/worktrees// swarm//
Create Integration Worktree
git worktree add .swarm/worktrees//integration -b swarm//integration
List Worktrees
git worktree list
Remove Worktree
git worktree remove .swarm/worktrees// --force
git branch -D swarm//
Clean After Tester
After Tester completes (pass or fail), clean uncommitted files in the worktree AND nuke node_modules to release disk:
cd .swarm/worktrees//
git checkout -- .
git clean -fd
# node_modules is gitignored so `git clean -fd` won't touch it. Nuke it explicitly —
# the lockfile is committed, so any later step that actually needs deps can re-install.
find . -type d -name node_modules -prune -exec rm -rf {} + 2>/dev/null
find . -type d -name dist -prune -exec rm -rf {} + 2>/dev/null
Why nuke node_modules: a typical frontend/node_modules is ~40MB and a backend/node_modules is ~3MB. Across 4 subtask worktrees + 1 integration worktree, leftover deps can easily occupy 100MB+ of disk for code that's already merged. The package-lock.json is committed, so any consumer that actually needs the deps can rerun npm install deterministically. This removes test artifacts (coverage reports, temp files) and dependency caches without affecting committed code.
Claude Code Runner
Resolve Agent Config
For a given role, resolve the LLM configuration:
- Check if
agents.is defined in config with all 4 fields. - If not, use
agents.default. - If neither exists, don't inject env vars (use session defaults).
Build Command
CRITICAL — three-piece isolation suite. On Windows (and likely macOS/Linux too) the claude CLI silently overrides any env you inject from three other sources:
- The parent process's already-loaded env (the orchestrator inherits
ANTHROPIC_*from~/.claude/settings.json'senvblock, and so do all its child shells). ~/.claude/settings.json'senvblock (re-applied by the CLI on startup).- Any OAuth credential in
~/.claude/.credentials.jsonor OS keychain (takes precedence overANTHROPIC_AUTH_TOKEN).
Just doing ANTHROPIC_BASE_URL=... claude -p ... will appear to work but actually keep using the parent's LLM. To make agents. config in .swarm/config.yaml actually take effect, all three of the following are required together (omit any one and override fails silently):
(a) Scrub inherited ANTHROPIC_* vars before exporting our own. (b) Pass --bare so OAuth/keychain are never read. (c) Pass --settings so ~/.claude/settings.json is replaced with {}. (d) Redirect HOME and USERPROFILE to a clean directory (e.g. .swarm/agent-home/) so the CLI cannot fall back to the user's .claude/ config.
Once on session startup, prepare the sandbox:
mkdir -p .swarm/agent-home/.claude
echo '{}' > .swarm/agent-home/empty-settings.json
(Re-using these between subtasks is fine; they only need to exist.)
Per sub-agent invocation, the full command is:
unset ANTHROPIC_AUTH_TOKEN ANTHROPIC_BASE_URL ANTHROPIC_MODEL \
ANTHROPIC_DEFAULT_HAIKU_MODEL ANTHROPIC_DEFAULT_OPUS_MODEL \
ANTHROPIC_DEFAULT_SONNET_MODEL ANTHROPIC_REASONING_MODEL \
ANTHROPIC_API_KEY
cd "" && \
HOME="/.swarm/agent-home" \
USERPROFILE="\\.swarm\\agent-home" \
ANTHROPIC_BASE_URL="" \
ANTHROPIC_AUTH_TOKEN="" \
ANTHROPIC_MODEL="" \
"/claude.exe" \
--bare \
--settings "\\.swarm\\agent-home\\empty-settings.json" \
-p "" \
--permission-mode bypassPermissions \
--allowedTools "Bash Read Write Edit Glob Grep" \
--output-format text
Notes:
- Use the absolute path to the real
claude.exebinary (e.g.C:/Program Files/nodejs/node_modules/@anthropic-ai/claude-code/bin/claude.exe) instead of bareclaude. On systems with cc-switch, nvm, or multiple node installs,claudeon PATH may be a wrapper that resolves to a different binary than the one configured. Locate it once withclaude doctor(look for thePath:line) and remember it for the session. - USERPROFILE needs the Windows-style absolute path (with backslashes); HOME needs the Unix-style path (forward slashes). On non-Windows, set HOME only.
--settingsrequires the file to exist; an empty{}is enough.--baredisables hooks, plugin sync, auto-memory, keychain, and OAuth. The sub-agent's prompt must therefore include any context it would normally have inherited (CLAUDE.md content is not auto-loaded under--bare).ANTHROPIC_AUTH_TOKENsendsAuthorization: Bearer, required by Anthropic-compatible proxies (DeepSeek, etc.).ANTHROPIC_API_KEYsendsx-api-keywhich many proxies reject.- If
agents.andagents.defaultare both absent, you may instead let the sub-agent inherit the parent session auth: skip the three-piece suite entirely and just runclaude -p .... But do not mix the two — a partial isolation will appear to work and silently route to the parent LLM.
How to verify the isolation actually works (run once after editing config or moving to a new machine): set ANTHROPIC_BASE_URL to a deliberately invalid URL like https://this-host-does-not-exist-xyz123.invalid and run a sub-agent command. If the isolation is correct the CLI must report a network error (Unable to connect to API, ENOTFOUND, etc.). If it returns a normal LLM reply, isolation is broken — the sub-agent is silently using the parent's LLM and the route is wrong. LLM self-reports of "I am Claude/DeepSeek" are unreliable; only network-level errors prove which endpoint was actually hit.
Execute and Capture Output
Run the command via Bash tool with timeout:
timeout bash -c '' 2>&1
On Windows (PowerShell context via Git Bash):
timeout
Handle Timeout
If the process exceeds timeoutMs:
- Kill the process.
- Write a failed status with summary "执行超时".
- Count as a failed attempt.
Read Result
After the sub-agent exits, read the output JSON file:
cat .swarm/state/subtasks//.json
If the file doesn't exist or is malformed, treat as failure with summary "子 Agent 未输出有效结果".
Concurrency and Queue Management
Dependency Batching
Given the dependency graph from the planner, group subtasks into batches:
- Batch 0: subtasks with no dependencies (can all start immediately)
- Batch 1: subtasks whose dependencies are all in batch 0
- Batch N: subtasks whose dependencies are all in batches .swarm/agent-home/empty-settings.json
Launch subtask A
( unset ANTHROPICAUTHTOKEN ANTHROPICBASEURL ANTHROPICMODEL \ ANTHROPICDEFAULTHAIKUMODEL ANTHROPICDEFAULTOPUSMODEL \ ANTHROPICDEFAULTSONNETMODEL ANTHROPICREASONINGMODEL \ ANTHROPICAPIKEY; \ cd "" && \ HOME="/.swarm/agent-home" USERPROFILE="\\.swarm\\agent-home" \ ANTHROPICBASEURL="..." ANTHROPICAUTHTOKEN="..." ANTHROPICMODEL="..." \ "/claude.exe" --bare --settings "\\.swarm\\agent-home\\empty-settings.json" \ -p "..." --permission-mode bypassPermissions --allowedTools "Bash Read Write Edit Glob Grep" --output-format text ) \ > .swarm/state/subtasks/subtask-a/stdout.log 2>&1 & PIDA=$!
Launch subtask B
( unset ANTHROPICAUTHTOKEN ANTHROPICBASEURL ANTHROPICMODEL \ ANTHROPICDEFAULTHAIKUMODEL ANTHROPICDEFAULTOPUSMODEL \ ANTHROPICDEFAULTSONNETMODEL ANTHROPICREASONINGMODEL \ ANTHROPICAPIKEY; \ cd "" && \ HOME="/.swarm/agent-home" USERPROFILE="\\.swarm\\agent-home" \ ANTHROPICBASEURL="..." ANTHROPICAUTHTOKEN="..." ANTHROPICMODEL="..." \ "/claude.exe" --bare --settings "\\.swarm\\agent-home\\empty-settings.json" \ -p "..." --permission-mode bypassPermissions --allowedTools "Bash Read Write Edit Glob Grep" --output-format text ) \ > .swarm/state/subtasks/subtask-b/stdout.log 2>&1 & PIDB=$!
Wait for all
wait $PIDA $PIDB
After all processes in the concurrent batch complete, read each subtask's result file and decide next steps.
### Sequential Fallback
If `maxConcurrency` is 1, execute subtasks one at a time within each batch. The logic is the same, just no parallel launches.
## Harness Orchestration Flow
This is the main execution loop. Follow these steps exactly.
### Phase 0: Requirement Clarification (mandatory, non-skippable)
Before any planning, refine the raw `` into a clear, agreed spec through interactive dialogue. This gate runs for EVERY new task — a one-line "写个贪吃蛇" still goes through it. Do not skip it because the request looks simple.
**Step 0.1 — Prefer the superpowers brainstorming skill if available.**
Check whether the `superpowers:brainstorming` skill is installed (it appears in the available-skills list, or its file exists):
```bash
ls ~/.claude/plugins/superpowers/skills/brainstorming/SKILL.md 2>/dev/null \
|| find ~/.claude/plugins -ipath "*brainstorming/SKILL.md" 2>/dev/null | head -1
If found, invoke it via the Skill tool to drive the clarification dialogue:
- Use
superpowers:brainstormingto explore intent, constraints, and success criteria one question at a time. - Override its terminal state. That skill normally ends by writing a design doc and invoking
writing-plans. For harness, do NOT let it callwriting-plansor any implementation skill. The moment the requirement is clear and the user agrees on scope, STOP the brainstorm and return control to harness Phase 1 (Planning). Capture the agreed spec text. - Store the final agreed spec as
clarifiedRequirementfor the session.
**Step 0.2 — Fallback: built-in lightweight clarification (when
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: puliang881412-lgtm
- Source: puliang881412-lgtm/harness-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.