Add PM breakdown skill: feature -> milestone + sub-issues (plan/approve/create gate)
@pm proposes a milestone + sub-tasks and asks for approval; on 'yes' it emits a BEGIN_SUBTASKS block, and the workflow creates the milestone + one sub-issue per line (each 'Part of #<feature>'). Sub-issues are not auto-started — maintainer @mentions an agent on each when ready. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f6df3f24af
commit
c594080ffc
@@ -219,7 +219,17 @@ jobs:
|
||||
'yes' / 'go' / 'proceed' / 'start building' answering your ready-to-build question) do you end
|
||||
your reply with a 'DELEGATE: @<agent>' line to hand off.
|
||||
Never present a plan and delegate on the same turn. If anything is unclear or needs a decision,
|
||||
START your reply with '@ffaerber', ask specific questions, and do NOT delegate."
|
||||
START your reply with '@ffaerber', ask specific questions, and do NOT delegate.
|
||||
BREAKDOWN (for a feature too big for one PR): first PLAN — propose a milestone name and the list
|
||||
of sub-tasks (title + one line each), then ask '@ffaerber create these N sub-issues? reply yes.'
|
||||
Do NOT emit the block yet. ONLY after the maintainer approves, end your reply with EXACTLY:
|
||||
BEGIN_SUBTASKS
|
||||
milestone: <feature name>
|
||||
- <task title> :: <one-line description>
|
||||
- <task title> :: <one-line description>
|
||||
END_SUBTASKS
|
||||
The automation creates the milestone + one sub-issue per line (each linked to this issue). It
|
||||
does NOT auto-start any dev — the maintainer @mentions an agent on each sub-issue when ready."
|
||||
fi
|
||||
else
|
||||
ACTION="You start on git branch '${BRANCH}', with git and push credentials already configured.
|
||||
@@ -302,8 +312,14 @@ jobs:
|
||||
post() { curl -sS -w 'comment -> HTTP %{http_code}\n' -X POST "${hdr[@]}" \
|
||||
"$API/issues/$NUM/comments" -d "$(jq -nc --arg b "$1" '{body:$b}')"; }
|
||||
|
||||
# drop the machine-readable marker lines (DELEGATE / CLOSE_ISSUE) from the human-facing reply
|
||||
reply=$(grep -viE '^[[:space:]]*(DELEGATE:[[:space:]]*@|CLOSE_ISSUE[[:space:]]*$)' /tmp/agent_out.md 2>/dev/null)
|
||||
# drop machine-readable markers (DELEGATE / CLOSE_ISSUE / the BEGIN_SUBTASKS..END_SUBTASKS block)
|
||||
reply=$(awk '
|
||||
/^[[:space:]]*BEGIN_SUBTASKS/{s=1}
|
||||
/^[[:space:]]*DELEGATE:[[:space:]]*@/{next}
|
||||
/^[[:space:]]*CLOSE_ISSUE[[:space:]]*$/{next}
|
||||
s{ if(/^[[:space:]]*END_SUBTASKS/){s=0}; next }
|
||||
{print}
|
||||
' /tmp/agent_out.md 2>/dev/null)
|
||||
[ -z "$reply" ] && reply="_(Made changes without a text summary — see the diff below.)_"
|
||||
# Prefer the agent's clean delimited PR description; fall back to the whole reply.
|
||||
prdesc=$(awk '/BEGIN_PR_DESCRIPTION/{f=1;next} /END_PR_DESCRIPTION/{f=0} f' /tmp/agent_out.md)
|
||||
@@ -324,6 +340,37 @@ jobs:
|
||||
curl -sS -X PATCH "${hdr[@]}" "$API/issues/$NUM" \
|
||||
-d '{"state":"closed"}' -w '\nclose -> HTTP %{http_code}\n' || true
|
||||
fi
|
||||
# BREAKDOWN: from a BEGIN_SUBTASKS block, create a milestone + one sub-issue per line
|
||||
# (linked to this issue). Sub-issues are NOT auto-started — maintainer mentions agents later.
|
||||
if grep -qiE '^[[:space:]]*BEGIN_SUBTASKS' /tmp/agent_out.md; then
|
||||
block=$(awk '/^[[:space:]]*BEGIN_SUBTASKS/{f=1;next} /^[[:space:]]*END_SUBTASKS/{f=0} f' /tmp/agent_out.md)
|
||||
ms=$(printf '%s\n' "$block" | sed -nE 's/^[[:space:]]*milestone:[[:space:]]*//Ip' | head -1)
|
||||
msid=""
|
||||
if [ -n "$ms" ]; then
|
||||
msid=$(curl -sS "${hdr[@]}" "$API/milestones?state=open&limit=100" | jq -r --arg t "$ms" 'if type=="array" then ([.[]|select(.title==$t)][0].id // empty) else empty end')
|
||||
[ -z "$msid" ] && msid=$(curl -sS -X POST "${hdr[@]}" "$API/milestones" -d "$(jq -nc --arg t "$ms" '{title:$t}')" | jq -r '.id // empty')
|
||||
echo "milestone '$ms' -> id ${msid:-?}"
|
||||
fi
|
||||
printf '%s\n' "$block" | grep -E '^[[:space:]]*-[[:space:]]' > /tmp/subtasks.txt || true
|
||||
links=""
|
||||
while IFS= read -r line; do
|
||||
item=$(printf '%s' "$line" | sed -E 's/^[[:space:]]*-[[:space:]]*//')
|
||||
title=${item%%::*}; body=${item#*::}; [ "$body" = "$item" ] && body=""
|
||||
title=$(printf '%s' "$title" | sed -E 's/[[:space:]]*$//')
|
||||
body=$(printf '%s' "$body" | sed -E 's/^[[:space:]]*//')
|
||||
[ -z "$title" ] && continue
|
||||
ibody=$(printf 'Part of #%s\n\n%s' "$NUM" "$body")
|
||||
if [ -n "$msid" ]; then
|
||||
payload=$(jq -nc --arg t "$title" --arg b "$ibody" --argjson m "$msid" '{title:$t,body:$b,milestone:$m}')
|
||||
else
|
||||
payload=$(jq -nc --arg t "$title" --arg b "$ibody" '{title:$t,body:$b}')
|
||||
fi
|
||||
n=$(curl -sS -X POST "${hdr[@]}" "$API/issues" -d "$payload" | jq -r '.number // empty')
|
||||
echo "created sub-issue #${n:-?}: $title"
|
||||
[ -n "$n" ] && links="$links\n- #$n — $title"
|
||||
done < /tmp/subtasks.txt
|
||||
post "$(printf '🤖 **@%s** — created sub-issues%s (mention an agent on each when ready):%b' "$NAME" "${ms:+ under milestone **$ms**}" "$links")"
|
||||
fi
|
||||
# Auto-delegate: if the plan names a teammate, trigger them via AGENT_TOKEN (a PAT, so it
|
||||
# fires a new workflow run — the built-in token cannot). Never targets @pm or self, so the
|
||||
# chain always terminates at a dev. The '🤖' guard on the trigger stops status-comment loops.
|
||||
|
||||
Reference in New Issue
Block a user