agentleFS
paskypasky/pi-side-agents/skills/agent-setup/SKILL.md

agent-setup

Skill196 starsChanged 57 days agoMITView on GitHub

Initialize or update setup for pi-side-agents (running asynchronous agents spawned/controlled from main session)

  • Reads credentials
  • Installs packages
  • Commits and pushes

4 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions4 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 4

    1. hass-energy/haeo★ 77same name
    2. calebnewtonusc/Chewbacca★ 8same name
    3. Shad0wMazt3r/The-Scaffolding★ 3same name
    4. NoatToan/claude-code-plugins★ 1same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repositoryOne other file it gives its agents.

The file

We split this skill into the rules it gives an agent

12 rules. 0 are common, 8 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 8

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Update setup: Chat with the user about what needs changing, use file examples below as reference for comparison.

    line 13
  2. Distinctive:

    Ask the user the following questions.

    line 22
  3. Distinctive:

    Open a pull request: instead?

    line 30
  4. Distinctive:

    Before asking the questions, autonomously try to answer questions 1, 2 and 4, and propose project-specific answers to the user.

    line 34
  5. Distinctive:

    Create the three files below.

    line 48
  6. Very specific:

    Write this file and make it executable (chmod +x).

    line 54
  7. Distinctive:

    If the user wants no custom bootstrap: append the optional hook block:

    line 91
  8. Distinctive:

    If the user gave specific bootstrap commands: append them directly instead, e.g.:

    line 99
  9. Very specific:

    Use MAIN_BRANCH set to whatever the user specified (or main by default).

    line 113
  10. Very specific:

    For PR policy: write a finish script that pushes the branch and opens a PR via the gh CLI:

    line 239
  11. Very specific:

    Start an agent: /agent <task description>

    line 339
  12. Distinctive:

    Ask you to set up and manage a flock of multiple side agents on your own to solve a task (you have the tools)

    line 341

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Parallel Agent Setup

Set up the pi-side-agents lifecycle scripts for this project.

Initial first time setup (no .pi/side-agent* yet): Work through two phases: interview, then file creation. Finish by backing up this agent-setup SKILL.md to .pi/side-agents/agent-start~/ for easy future upgrades.

Update setup: Chat with the user about what needs changing, use file examples below as reference for comparison.

Upgrade setup to new pi-side-agents version: Diff this file with the current backup .pi/side-agents/agent-start~/ and discuss the changes to apply (or not) with the user. When upgrade is finished, update the backup to the current version.

Important (local-only files): everything this skill creates is under .pi/ and is runtime/local configuration. Do not git add, git add -f, or commit these files. They should remain untracked. If they were accidentally committed, remove them from git tracking while keeping them locally.

Phase 1: Interview

Ask the user the following questions. You may ask them all at once or one at a time — use your judgment based on how they engage.

  1. Main branch name – What is the primary integration branch? (default: main)
  2. Bootstrap steps – Does each agent worktree need custom setup before work begins? For example: npm install, copying .env files, running migrations. If yes, what commands specifically?
  3. Finish policy – When an agent finishes, should it:
    • Rebase locally, then fast-forward into the main branch in the parent checkout (default), or
    • Open a pull request instead?
  4. Overwrite existing files – If .pi/side-agent-start.sh or similar already exist, overwrite them? (default: no — skip existing files)

Before asking the questions, autonomously try to answer questions 1, 2 and 4, and propose project-specific answers to the user.

Collect all answers before proceeding to Phase 2.


Phase 2: Create Setup Files

Determine the git repo root:

GIT_ROOT=$(git rev-parse --show-toplevel)

Create the three files below. For each file, check whether it already exists before writing — if it exists and the user said not to overwrite, skip it and tell the user. Otherwise write (or overwrite) it.


File 1: $GIT_ROOT/.pi/side-agent-start.sh

Write this file and make it executable (chmod +x).

Use MAIN_BRANCH set to whatever the user specified in question 1 (or main by default). The start script validates the branch but does not reset HEAD — the TypeScript extension already sets the worktree to the parent's HEAD. Do not force-update the local MAIN_BRANCH ref (e.g. git branch -f) because that branch is often checked out in the parent worktree.

Default content — substitute MAIN_BRANCH_VALUE with the actual branch name, then append bootstrap steps based on question 2. Keep the ${PI_SIDE_PARENT_BRANCH:-...} fallback verbatim: for a nested side agent (one spawned by another side agent) the extension sets PI_SIDE_PARENT_BRANCH to the spawning agent's branch, which is that agent's integration target instead of the main branch.

#!/usr/bin/env bash
set -euo pipefail

PARENT_ROOT="${1:-}"
WORKTREE="${2:-$(pwd)}"
AGENT_ID="${3:-unknown}"
# Nested side agents integrate into their parent agent's branch, not main.
MAIN_BRANCH="${PI_SIDE_PARENT_BRANCH:-MAIN_BRANCH_VALUE}"

BRANCH="$(git -C "$WORKTREE" rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
if [[ "$BRANCH" == "HEAD" ]]; then
  BRANCH=""
fi
if [[ -z "$BRANCH" ]]; then
  echo "[side-agent-start] Could not determine current branch in $WORKTREE."
  exit 1
fi

echo "[side-agent-start] agent=$AGENT_ID branch=$BRANCH main=$MAIN_BRANCH"

if [[ "$BRANCH" == "$MAIN_BRANCH" ]]; then
  echo "[side-agent-start] ERROR: child worktree is on $MAIN_BRANCH; expected a dedicated agent branch."
  exit 1
fi

# The worktree is already set to the parent's HEAD by the TypeScript extension.
# Just verify it's on the right branch.
echo "[side-agent-start] Worktree based on parent HEAD ($(git -C "$WORKTREE" rev-parse --short HEAD))."
  • If the user wants no custom bootstrap: append the optional hook block:
    # Optional project bootstrap hook — create .pi/side-agent-bootstrap.sh to use.
    if [[ -x "$WORKTREE/.pi/side-agent-bootstrap.sh" ]]; then
      "$WORKTREE/.pi/side-agent-bootstrap.sh"
    fi
  • If the user gave specific bootstrap commands: append them directly instead, e.g.:
    # Project bootstrap
    cd "$WORKTREE"
    npm install
    cp .env.example .env 2>/dev/null || true

File 2: $GIT_ROOT/.pi/side-agent-finish.sh

Write this file and make it executable (chmod +x).

Use MAIN_BRANCH set to whatever the user specified (or main by default).

For local rebase policy (default), use this content — substituting MAIN_BRANCH_VALUE with the actual branch name:

#!/usr/bin/env bash
set -euo pipefail

PARENT_ROOT="${PI_SIDE_PARENT_REPO:-${1:-}}"
AGENT_ID="${PI_SIDE_AGENT_ID:-${2:-unknown}}"
# Nested side agents integrate into their parent agent's branch (checked out in
# PARENT_ROOT, which is then the parent agent's worktree), not main.
MAIN_BRANCH="${PI_SIDE_PARENT_BRANCH:-MAIN_BRANCH_VALUE}"
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
if [[ "$BRANCH" == "HEAD" ]]; then
  BRANCH=""
fi

if [[ -z "$PARENT_ROOT" ]]; then
  echo "[side-agent-finish] Missing parent checkout path."
  echo "Usage: PI_SIDE_PARENT_REPO=/path/to/parent .pi/side-agent-finish.sh"
  exit 1
fi

if [[ -z "$BRANCH" ]]; then
  echo "[side-agent-finish] Could not determine current branch."
  exit 1
fi

LOCK_DIR="$PARENT_ROOT/.pi/side-agents"
LOCK_FILE="$LOCK_DIR/merge.lock"
mkdir -p "$LOCK_DIR"

MERGE_LOCK_TIMEOUT=120

iso_now() {
  date -u +"%Y-%m-%dT%H:%M:%SZ"
}

acquire_lock() {
  local payload started elapsed
  payload="{\"agentId\":\"$AGENT_ID\",\"pid\":$$,\"acquiredAt\":\"$(iso_now)\"}"
  started=$(date +%s)
  while true; do
    if ( set -o noclobber; printf '%s\n' "$payload" > "$LOCK_FILE" ) 2>/dev/null; then
      return 0
    fi
    elapsed=$(( $(date +%s) - started ))

    # Check if the lock holder is still alive (stale lock after crash/reboot)
    if [[ -f "$LOCK_FILE" ]]; then
      local holder_pid
      holder_pid="$(grep -o '"pid":[0-9]*' "$LOCK_FILE" 2>/dev/null | head -n 1 | grep -o '[0-9]*' || true)"
      if [[ -n "$holder_pid" ]] && ! kill -0 "$holder_pid" 2>/dev/null; then
        echo "[side-agent-finish] Removing stale merge lock (pid $holder_pid no longer running)."
        rm -f "$LOCK_FILE"
        continue
      fi
    fi

    if [[ "$elapsed" -ge "$MERGE_LOCK_TIMEOUT" ]]; then
      echo "[side-agent-finish] Timed out after ${MERGE_LOCK_TIMEOUT}s waiting for merge lock."
      echo "[side-agent-finish] Stale lock? Inspect: $LOCK_FILE"
      exit 3
    fi
    echo "[side-agent-finish] Waiting for merge lock... (${elapsed}s / ${MERGE_LOCK_TIMEOUT}s)"
    sleep 1
  done
}

release_lock() {
  rm -f "$LOCK_FILE" || true
}

trap 'release_lock' EXIT

while true; do
  echo "[side-agent-finish] Reconciling child branch: git rebase $MAIN_BRANCH"
  if ! git rebase "$MAIN_BRANCH"; then
    echo "[side-agent-finish] Conflict while rebasing $BRANCH onto $MAIN_BRANCH."
    echo "Resolve conflicts (git status / git rebase --continue), then rerun .pi/side-agent-finish.sh"
    exit 2
  fi

  acquire_lock

  set +e
  (
    cd "$PARENT_ROOT" || exit 1
    current="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
    if [[ "$current" != "$MAIN_BRANCH" ]]; then
      if [[ -n "${PI_SIDE_PARENT_BRANCH:-}" ]]; then
        # Nested agent: the parent checkout is another agent's worktree. If it is
        # no longer on the parent branch, the parent quit and the slot may belong
        # to someone else now - never switch branches under them.
        echo "[side-agent-finish] Parent checkout $PARENT_ROOT is on '$current', not '$MAIN_BRANCH' (parent agent gone / slot reused?)."
        echo "[side-agent-finish] Refusing to touch it. Escalate: the parent's work must be integrated by hand."
        exit 4
      fi
      git checkout "$MAIN_BRANCH" >/dev/null 2>&1 || exit 1
    fi
    git merge --ff-only "$BRANCH"
  )
  merge_status=$?
  set -e

  if [[ "$merge_status" -eq 4 ]]; then
    release_lock
    exit 4
  fi

  release_lock

  if [[ "$merge_status" -eq 0 ]]; then
    echo "[side-agent-finish] Success: fast-forwarded $MAIN_BRANCH to include $BRANCH in parent checkout."
    rm -f "$(pwd)/.pi/active.lock" || true
    exit 0
  fi

  echo "[side-agent-finish] Parent fast-forward failed (likely $MAIN_BRANCH moved)."
  echo "[side-agent-finish] Retrying rebase reconcile loop..."

  sleep 1
done

For PR policy: write a finish script that pushes the branch and opens a PR via the gh CLI:

#!/usr/bin/env bash
set -euo pipefail

AGENT_ID="${PI_SIDE_AGENT_ID:-${1:-unknown}}"
# Nested side agents open their PR against their parent agent's branch, not main.
MAIN_BRANCH="${PI_SIDE_PARENT_BRANCH:-MAIN_BRANCH_VALUE}"
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
if [[ "$BRANCH" == "HEAD" ]]; then
  BRANCH=""
fi

if [[ -n "${PI_SIDE_PARENT_BRANCH:-}" ]]; then
  # Nested agent: stacked PR onto the parent agent's branch, which is normally
  # unpublished at this point - push it first so GitHub accepts it as a base.
  echo "[side-agent-finish] Publishing parent branch $MAIN_BRANCH for a stacked PR..."
  git push origin "$MAIN_BRANCH"
fi

echo "[side-agent-finish] Pushing $BRANCH..."
git push -u origin "$BRANCH"

echo "[side-agent-finish] Opening pull request against $MAIN_BRANCH..."
gh pr create --base "$MAIN_BRANCH" --head "$BRANCH" --fill

File 3: $GIT_ROOT/.pi/side-agent-skills/finish/SKILL.md

This is a skill for the child agent (not this session) that tells it how to finalize its work.

For local rebase policy, write:

---
name: finish
description: Rebase the branch with current work onto upstream and fast-forward it after explicit user sign-off (e.g. "LGTM")
---

# Parallel-agent finish workflow

When the user explicitly approves the work (e.g. says "LGTM", "ship it", "merge it"):

1. Make sure the user's intent is clear (you received an explicit "merge" instruction) before doing anything.

2. Run the finish script:

```bash
PI_SIDE_PARENT_REPO="$PI_SIDE_PARENT_REPO" .pi/side-agent-finish.sh
  1. If the finish script exits with code 2 (conflict rebasing child branch onto MAIN_BRANCH_VALUE — or onto $PI_SIDE_PARENT_BRANCH, your parent agent's branch, if you are a nested side agent):
    • Stay in this worktree
    • Resolve conflicts (git status, then git rebase --continue)
    • Re-run the finish script after the rebase completes
  2. If the parent-side fast-forward fails because MAIN_BRANCH_VALUE moved ahead:
    • The finish script retries the rebase reconcile loop automatically
    • Parent-side integration is a bit sensitive operation as it can make big mess; solve simple issues yourself, but escalate to the user with major issues (such as dirty parent worktree)
    • Exit code 4 (nested agents only): the parent agent's checkout is no longer on its branch — the parent has quit or its slot was reused. Do not force anything; report that your branch is ready and needs manual integration.
  3. After success: report the landed commit(s). Suggest /quit if no further work is needed.

**For PR policy**, write a simpler finish skill:

```markdown
---
name: finish
description: Open a PR for the branch with current work to upstream after explicit user sign-off (e.g. "LGTM")
---

# Parallel-agent finish workflow

When the user explicitly approves the work (e.g. says "LGTM", "ship it"):

1. **Confirm** with user before pushing.

2. Run the finish script to push the branch and open a PR automatically:

```bash
.pi/side-agent-finish.sh
  1. Suggest /quit if no further work is needed.

---

## Phase 3: Report

Tell the user which files were created, updated, or skipped, including backup/reference files, and how to proceed.

Explicitly remind the user that `.pi/side-agent-*` files are local runtime setup and should stay untracked (not committed to git).


- Backup reference for future diffs
- Start an agent: `/agent <task description>`
- Watch status: statusline shows active agents, ...@<number> is the tmux window to switch to; `/agents` lists all
- Ask you to set up and manage a flock of multiple side agents on your own to solve a task (you have the tools)
- Side agents can spawn their own side agents (one extra level). A nested agent branches off its parent agent's branch, merges back into it via the same finish script (`PI_SIDE_PARENT_BRANCH`), and its status notices go to the parent agent, not to this session.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.