SuperAPI AI Directory

cursor-do

General & other

View repository

Updated 10-15 17:33

About this skill

cursor:do — Single-Task Write Delegate to Cursor Composer

A skill that delegates 1 implementation task to Cursor Composer (composer-2.5-fast) in a dedicated worktree, has the Lead review the diff, then cherry-picks to main. It does not spin up breezing's team flow, and runs 1 task 1 cherry-pick via the shortest path.

Containment does not exist on the Cursor side (references/cursor-cli-only.md)。dedicated .git holding worktree + Lead diff review + cherry-pick (R01-R13 path) are the only 3 effective boundaries. cursor's output is treated as untrusted until Lead review.

Step 0 — NARRATION RULES (UX Contract)

The enemy is verbosity , not progress reporting. Same contract as breezing.At startup, briefly state the banner + execution plan, then execute. Readable progress reports are welcome; only verbose repetition is forbidden.

What must always be output at startup (banner + plan, 5 lines or fewer total)

🚀 cursor / composer-2.5-fast / feat/foo-bar / Add login form validation
これから:
1. pre-check (branch / cursor-agent) → 専用 worktree 作成
2. composer に実装委譲 (--write)
3. diff レビュー → cherry-pick → Plans.md 更新

1 line for the banner (🚀 cursor / composer-2.5-fast / <branch> / <task>) + 2-4 lines for the plan. Output within 1 second, then immediately go to Step 1.

Progress reports may be output (within a readable range)

  • Start and completion of each step as a 1-line status (✓ worktree 作成: .claude/worktrees/cursor-do-...)
  • key points of pre-check / resolve, the cherry-picked SHA
  • the reason for taking this branch in 1 line

Forbidden (= verbosity)

  • Restating the same fact twice: do not re-explain the pre-check result later
  • Empty preambles: lines that are just self-evident declarations for tool calls
  • A retrospective of 3 or more lines: compress to 1 line if needed
  • ★ Insight blocks during the startup sequence: Insight only once in the final report

Violation example (verbose):

× 「composer 2.5 で実装する流れですね、まず確認します」(中身のない前置き)
× 「Cursor を呼ぶ前に branch を見ます」 → bash → 「branch を確認しました」(言い換え)
× ★ Insight ──── Cursor の強みは…

Good example (concise + explicit plan):

🚀 cursor / composer-2.5-fast / feat/foo-bar / Add login form validation
これから: worktree 作成 → composer に実装委譲 → diff レビュー → cherry-pick

Step 1 — Output the banner + plan fully (within 1 second)

Argument $ARGUMENTS is received as the task description. If the argument is empty, output the following marker, ask the user for a 1-line task, and after input proceed to Step 2:

CURSOR_DO_AWAITING_TASK: provide a one-line task description as $ARGUMENTS

If there is an argument, immediately echo 1 line:

🚀 cursor / composer-2.5-fast / <current-branch> / <task-first-60-chars>

<current-branch> is a value obtained in Step 2, but in Step 1 it has not been obtained yet, so … is also acceptable. Immediately after Step 2, re-output the finalized value in 1 line. Output the Step 0 banner + execution plan (5 lines or fewer) fully here, and after that show progress with 1-line statuses for each step. Avoid only verbose repetition.

Step 2 — Parallel pre-check (1 bash)

In 1 bash call, obtain the following in parallel and receive only the results in 1 block. Do not output individual explanations.

bash -c '
  set +e
  echo "==BRANCH=="; git branch --show-current
  echo "==VERSION=="; cat VERSION 2>/dev/null
  echo "==PLANS_TAIL=="; tail -n 12 Plans.md 2>/dev/null
  echo "==CURSOR_AGENT=="
  CURSOR_AGENT_BIN="${CURSOR_AGENT_BIN:-}"
  if [ -z "$CURSOR_AGENT_BIN" ]; then
    # `agent`(公式の新表記)→ `cursor-agent`(legacy alias)の順に探す。
    # `agent` は汎用的な名前なので、symlink 解決後の実パスの「成分」に
    # cursor-agent が完全一致で現れる場合だけ採用する(部分文字列一致だと
    # /x/cursor-agent-not-really/agent のようなディレクトリ名で突破される)。
    for _c in agent cursor-agent; do
      _p="$(command -v "$_c" 2>/dev/null)" || continue
      [ -n "$_p" ] || continue
      _r="$(realpath "$_p" 2>/dev/null || readlink -f "$_p" 2>/dev/null || echo "$_p")"
      case "/$_r/" in */cursor-agent/*) CURSOR_AGENT_BIN="$_p"; break ;; esac
    done
    if [ -z "$CURSOR_AGENT_BIN" ] && [ -x "$HOME/.local/bin/cursor-agent" ]; then
      CURSOR_AGENT_BIN="$HOME/.local/bin/cursor-agent"
    fi
  fi
  if [ -z "$CURSOR_AGENT_BIN" ]; then
    echo "NOT_INSTALLED"
  else
    "$CURSOR_AGENT_BIN" --version 2>/dev/null || echo "NOT_INSTALLED"
  fi
'

Judgment:

  • CURSOR_AGENT=NOT_INSTALLED → ERROR: cursor-agent not found (exit 3 expected from companion). Install via setup-cursor.sh. and exit.
  • BRANCH が main / master → WARN: on protected branch — cherry-pick target is HEAD of this branch. Confirm intent or switch. and continue.

Step 3 — plugin root + backend + model resolve (1 bash)

HARNESS_PLUGIN_ROOT / CLAUDE_PLUGIN_ROOT is unset, the :-. fallback resolves to the consumer repo's cwd,scripts/cursor-companion.sh is not visible and startup fails (Issue #193 §2). Resolve robustly with the same valid_root pattern as hooks.json.

bash -c '
  set -euo pipefail
  valid_root() {
    [ -n "${1:-}" ] && [ -f "$1/scripts/cursor-companion.sh" ] && { [ -f "$1/.claude-plugin/plugin.json" ] || [ -f "$1/.codex-plugin/plugin.json" ] || [ -f "$1/.cursor-plugin/plugin.json" ]; }
  }
  HARNESS_PLUGIN_ROOT="${HARNESS_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-}}"
  ROOT="$HARNESS_PLUGIN_ROOT"
  if ! valid_root "$ROOT"; then
    ROOT=""
    if [ -n "${CLAUDE_SKILL_DIR:-}" ]; then
      probe="$(cd "${CLAUDE_SKILL_DIR}" && pwd)"
      while [ "$probe" != "/" ] && ! valid_root "$probe"; do
        probe="$(cd "$probe/.." && pwd)"
      done
      valid_root "$probe" && ROOT="$probe"
    fi
  fi
  if ! valid_root "$ROOT"; then
    ROOT=""
    for c in "${CLAUDE_PROJECT_DIR:-}" "$PWD" \
             "$HOME/.claude/plugins/marketplaces/claude-code-harness-marketplace" \
             "$HOME/.claude/plugins/cache/claude-code-harness-marketplace/claude-code-harness/"*; do
      if valid_root "$c"; then ROOT="$c"; break; fi
    done
  fi
  if ! valid_root "$ROOT"; then
    echo "ERROR: claude-code-harness plugin root not found (no scripts/cursor-companion.sh)" >&2
    exit 2
  fi
  HARNESS_PLUGIN_ROOT="$ROOT"
  BACKEND=$(bash "${HARNESS_PLUGIN_ROOT}/scripts/resolve-impl-backend.sh" --backend cursor --role worker)
  MODEL=$(bash "${HARNESS_PLUGIN_ROOT}/scripts/model-routing.sh" --host cursor --role worker --field model)
  echo "PLUGIN_ROOT=${HARNESS_PLUGIN_ROOT}"
  echo "BACKEND=$BACKEND"
  echo "MODEL=$MODEL"
'

Return values: PLUGIN_ROOT (used in Step 5) / BACKEND (always cursor) / MODEL (normally composer-2.5-fast)。BACKEND or MODEL is empty, output ERROR: backend/model resolution failed in 1 line and exit.PLUGIN_ROOT Resolution failure is reported by the above script with exit 2.

Step 4 — Create dedicated worktree

Create a non-colliding id and cut a worktree.main tree や $HOME must not point to (this results in exit 2 via the companion-side guard).WT_DIR must be created as an absolute path (because the --workspace は companion の is not a directory guard in Step 5 may make relative paths exit 2; Issue #193 §4).

bash -c '
  set -euo pipefail
  REPO_ROOT="$(git rev-parse --show-toplevel)"
  cd "$REPO_ROOT"
  ID="$(date +%Y%m%d-%H%M%S)-$$"
  WT_DIR="$REPO_ROOT/.claude/worktrees/cursor-do-${ID}"
  BASE_REF="$(git rev-parse HEAD)"
  BASE_BRANCH="$(git branch --show-current)"
  WT_BRANCH="cursor-do/${ID}"
  mkdir -p "$REPO_ROOT/.claude/worktrees"
  git worktree add -b "${WT_BRANCH}" "${WT_DIR}" "${BASE_REF}"
  echo "REPO_ROOT=${REPO_ROOT}"
  echo "WT_DIR=${WT_DIR}"
  echo "WT_BRANCH=${WT_BRANCH}"
  echo "BASE_REF=${BASE_REF}"
  echo "BASE_BRANCH=${BASE_BRANCH}"
'

Use the returned WT_DIR / WT_BRANCH / BASE_REF / BASE_BRANCH in subsequent Steps. On failure (branch name collision, etc.), recreate ID and retry only once. On two consecutive failures, output ERROR: worktree creation failed and exit.

Step 5 — Delegate via cursor-companion.sh task --write

The Lead calls companion directly (references/cursor-cli-only.md Topology section — no Worker intermediation for non-claude backends). The prompt is the argument task as-is plus only necessary supplements. Do not add redundant preamble.

bash -c '
  set -euo pipefail
  valid_root() {
    [ -n "${1:-}" ] && [ -f "$1/scripts/cursor-companion.sh" ] && { [ -f "$1/.claude-plugin/plugin.json" ] || [ -f "$1/.codex-plugin/plugin.json" ] || [ -f "$1/.cursor-plugin/plugin.json" ]; }
  }
  HARNESS_PLUGIN_ROOT="${HARNESS_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-}}"
  ROOT="${PLUGIN_ROOT:-$HARNESS_PLUGIN_ROOT}"
  if ! valid_root "$ROOT"; then
    ROOT=""
    if [ -n "${CLAUDE_SKILL_DIR:-}" ]; then
      probe="$(cd "${CLAUDE_SKILL_DIR}" && pwd)"
      while [ "$probe" != "/" ] && ! valid_root "$probe"; do
        probe="$(cd "$probe/.." && pwd)"
      done
      valid_root "$probe" && ROOT="$probe"
    fi
  fi
  if ! valid_root "$ROOT"; then
    ROOT=""
    for c in "${CLAUDE_PROJECT_DIR:-}" "$PWD" \
             "$HOME/.claude/plugins/marketplaces/claude-code-harness-marketplace" \
             "$HOME/.claude/plugins/cache/claude-code-harness-marketplace/claude-code-harness/"*; do
      if valid_root "$c"; then ROOT="$c"; break; fi
    done
  fi
  if ! valid_root "$ROOT"; then
    echo "ERROR: claude-code-harness plugin root not found (no scripts/cursor-companion.sh)" >&2
    exit 2
  fi
  HARNESS_PLUGIN_ROOT="$ROOT"
  PROMPT="<task-description>

Constraints:
- Modify only files relevant to the task.
- Keep existing tests green. Add tests when the task is verifiable.
- Match existing code style and naming.
- Create exactly one git commit if your environment supports it; otherwise leave one dirty changeset for Lead auto-commit.
- Do not touch .claude-plugin/settings*, .claude/settings*, .eslintrc*, biome.json, tsconfig*.json."
  bash "${HARNESS_PLUGIN_ROOT}/scripts/cursor-companion.sh" task \
    --write \
    --workspace "${WT_DIR}" \
    "${PROMPT}"
' 2>&1

Judgment:

  • exit 0 + result text → Step 6 へ
  • exit 1 (result-error) → summarize companion stderr in 1 line, output ERROR: cursor returned is_error/empty result and exit. The worktree is deleted in the Step 8 cleanup
  • exit 2 (bad-guard) → configuration defect. Indicate the cause (such as wrong workspace specification) in 1 line and exit
  • exit 3 (not-found) → should have been detected in Step 2, but if encountered again, exit in the same way

Step 6 — Lead diff review

Read the changes created by the Composer in the worktree and pass the two-stage gate of visual review + contract grep (harness-work same contract as "Lead's pre-cherry-pick gate").

Note (Issue #193 §1): Cursor Composer は --write edits files, but may not create a commit. If the worktree is left dirty, it will be missed from the Step 7 cherry-pick target, resulting in a state from the user's perspective where "it completed but nothing goes into main." If it is dirty at the beginning of this Step, amend if there is an existing commit, or if there is no commit, combine into 1 commit on the Lead side.

bash -c '
  set -euo pipefail
  cd "${WT_DIR}"
  # Composer は dirty changeset を返すことがあるため、既存 commit に fold する
  if [ -n "$(git status --porcelain)" ]; then
    git add -A
    if [ "$(git rev-list --count "${BASE_REF}..HEAD")" -gt 0 ]; then
      git -c user.name="cursor-composer" -c user.email="cursor-composer@local" \
        commit --amend --no-edit --no-verify
      echo "==AUTO_AMENDED=="
    else
      git -c user.name="cursor-composer" -c user.email="cursor-composer@local" \
        commit --no-verify -m "cursor: ${TASK_SUMMARY:-cursor-do delegated change}"
      echo "==AUTO_COMMITTED=="
    fi
    git log -1 --oneline
  fi
  echo "==LOG=="
  git log --oneline "${BASE_REF}..HEAD"
  echo "==STAT=="
  git diff --stat "${BASE_REF}..HEAD"
  echo "==DIFF=="
  git diff "${BASE_REF}..HEAD"
'

TASK_SUMMARY the Lead exports in advance a string compressed to within the first 60 characters of the argument task (example: TASK_SUMMARY="Add login form validation"). If unset, use the fallback message cursor-do delegated change .--no-verify is added in order to treat edits in the worktree as an "intermediate commit before Lead review" (R01-R13 and pre-commit hook are passed in the main commit after cherry-pick).

The Lead Reads the full diff and confirms the following:

  • Whether the changes are within the scope of the requested task (whether unrelated files were touched)
  • protected path (.claude-plugin/settings*, .eslintrc*, etc.) have not been changed
  • secret / .env / does not contain credentials
  • Whether the public support tier notation has not been destroyed. Contract gates must always be executed within the candidate worktree (WT_DIR):
    [ ! -f "${WT_DIR}/tests/test-support-claim-wording.sh" ] || (cd "${WT_DIR}" && bash tests/test-support-claim-wording.sh)
    [ ! -f "${WT_DIR}/scripts/ci/check-consistency.sh" ] || (cd "${WT_DIR}" && bash scripts/ci/check-consistency.sh)
    [ ! -f "${WT_DIR}/tests/validate-plugin.sh" ] || (cd "${WT_DIR}" && bash tests/validate-plugin.sh)
    

Judgment:

  • No problem → go to Step 7
  • Out-of-scope changes present → either roll back the relevant commit with git reset or redelegate to Cursor (retry Step 5 only once). On two failures, output REQUEST_CHANGES: <理由> and exit while leaving the worktree
  • protected path / secret detected → abort immediately.ABORT: protected path violation output and delete worktree

Step 7 — cherry-pick + Plans.md cc:done update

Cherry-pick from the worktree to the main tree. The Cursor prompt is under an exactly one commit contract, but since Composer may return a dirty changeset, commit/amend in Step 6. If multiple commits remain, stop before touching the main tree. Also, before cherry-picking, Plans.md verify that there are no staged / unstaged diffs. Reason: if subsequent git add Plans.md && git commit --amend is performed while existing diffs are present, plan/status edits unrelated to the task get dragged into Cursor's code commit. Direct SHA specification (not via branch name) to avoid reviewer state drift (MEMORY: reviewer_state_drift).

bash -c '
  set -euo pipefail
  COMMIT_COUNT="$(cd "${WT_DIR}" && git rev-list --count "${BASE_REF}..HEAD")"
  if [ "${COMMIT_COUNT}" -eq 0 ]; then
    echo "ERROR: no commits to cherry-pick"
    exit 1
  fi
  if [ "${COMMIT_COUNT}" -ne 1 ]; then
    echo "ERROR: cursor returned ${COMMIT_COUNT} commits; expected exactly one. Keep worktree for manual review: ${WT_DIR}"
    exit 1
  fi
  if ! git diff --quiet -- Plans.md || ! git diff --cached --quiet -- Plans.md; then
    echo "ERROR: Plans.md has pre-existing local edits; refusing to cherry-pick before the cursor:do marker amend"
    exit 1
  fi
  SHA="$(cd "${WT_DIR}" && git rev-parse HEAD)"
  git cherry-pick "${SHA}"
  echo "==CHERRY_PICKED=="
  git log --oneline -n 1
'

If a conflict occurs during cherry-pick, git cherry-pick --abort し、CHERRY_PICK_CONFLICT: <files> show in one line and exit (leave the worktree, user decision).

After cherry-pick, if there is a corresponding line in Plans.md, update the marker for the relevant task. Since the clean precondition above has been passed, the Plans.md diff that occurs here is treated as a marker-only diff:

| <task> | ... | cc:done [<merged-sha>] |

Locating the relevant line: grep with the first 40 characters of the argument task string, and replace the first cc:TODO / cc:WIP / cc:todo line that hits with cc:done [<sha>] . If there is no hit, skip the update (treat it as a task outside Plans.md).

If the marker is updated, include that edit in the cherry-pick commit. Do not proceed to cleanup / completion report leaving an uncommitted Plans.md . The following amend block targets only the marker-only diff performed after passing the precondition above:

bash -c '
  set -euo pipefail
  if git diff --quiet -- Plans.md; then
    echo "PLANS_UPDATED=0"
  else
    git add Plans.md
    git commit --amend --no-edit
    echo "PLANS_UPDATED=1"
    echo "MERGED_SHA=$(git rev-parse HEAD)"
  fi
'

Step 8 — worktree cleanup + completion report (1 block)

After a successful cherry-pick, delete the worktree. Not called on the failure path (leave the worktree, user decision).

bash -c '
  set -euo pipefail
  git worktree remove --force "${WT_DIR}"
  git branch -D "${WT_BRANCH}" 2>/dev/null || true
  echo "==CLEANUP=="
  git worktree list | grep -v "cursor-do-" || true
'

The completion report is produced with 1 block . No intermediate narration:

cursor:do completed
   task: <task-first-60-chars>
   commits: <count>
   base: <BASE_REF> → cherry-picked into <BASE_BRANCH>
   plans: <updated|skipped (no match)>
   files: <changed-file-count> changed, +<inserts> -<deletes>

Full Containment (write mode required)

Layer Role Skip allowed?
Dedicated .git worktree Isolate cursor writes from the main tree Not allowed (required)
Lead diff review Quality gate for untrusted cursor output Not allowed (required)
contract-grep gate Protection of docs / locale / matrix fixed strings Not allowed (required)
cherry-pick → main The only path through the R01-R13 guard rails Not allowed (required)
Plans.md cc:done update Sync with the ledger Skip allowed if there is no relevant line

Prohibited

  • --force / --yolo pass to companion (Cursor official "Never use")
  • Commit cursor output directly to main before Lead review
  • protected path (.claude-plugin/settings*, .eslintrc*, tsconfig*.json, etc.) in the Step 5 prompt
  • $HOME / / / main tree を --workspace specify in
  • Plans.md の cc:* rewrite markers regardless of the task

Related Skills / Rules

  • cursor:ask — read-only questions, investigation, adversarial viewpoint (worktree not needed)
  • breezing --cursor — when delegating multiple tasks to cursor via the team flow
  • harness-work — default flow of the claude backend (via Worker agent)
  • references/cursor-cli-only.md — Cursor backend governance + Topology (formerly .claude/rules/cursor-cli-only.md 's full text has been relocated here)