Add /supervise skill: MiniMax supervisor loop with tick/report crons
This commit is contained in:
@@ -20,6 +20,7 @@ custom-claude-skills/
|
||||
├── linter/SKILL.md # Format/lint audit and execution
|
||||
├── log/SKILL.md # End-of-session logging
|
||||
├── orchestrate/SKILL.md # Container agent dispatch with git worktrees
|
||||
├── supervise/SKILL.md # MiniMax supervisor loop (tick/report crons)
|
||||
├── reflect/SKILL.md # Milestone reflection
|
||||
├── reflect-logs/SKILL.md # Process logs into memory
|
||||
├── review-plan/SKILL.md # Review plan against best practices
|
||||
|
||||
@@ -25,6 +25,7 @@ The install script creates symlinks from `~/.claude/skills/` to this repo, makin
|
||||
| housekeeping | `/housekeeping` | Cross-project health check: git status, unreflected logs, skill validation, pipeline recommendations |
|
||||
| decompose | `/decompose <task>` | Break a task into subtasks with dependency graph. Writes `.agent-tasks.json` for container agent orchestration. |
|
||||
| orchestrate | `/orchestrate` | Check task state, launch container agents in git worktrees. Use `/loop 2m /orchestrate` for auto-polling. |
|
||||
| supervise | `/supervise` | Supervisor mode: 15-min tick dispatches/reaps MiniMax `mm-worktree-task` units, 30-min progress report. State in gitignored `.supervisor/`. |
|
||||
| spawn-session | `/spawn-session <project>` | Spawn a new detached tmux Claude Code session with Remote Control, named after the project (wraps `claude-tmux`). Attach later via `tmux attach` over VPN or drive from the Claude app. |
|
||||
|
||||
## Adding a New Skill
|
||||
|
||||
183
skills/supervise/SKILL.md
Normal file
183
skills/supervise/SKILL.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
name: supervise
|
||||
description: >
|
||||
Run this session as a supervisor over MiniMax subagents: every 15 min a tick reaps
|
||||
finished units, files new bugs, and dispatches mm-worktree-task units for the focus;
|
||||
every 30 min a one-paragraph progress report. Keeps state in a gitignored .supervisor/
|
||||
folder and records itself in the project's CLAUDE.md. Pass a focus as arguments, or
|
||||
run bare to pick one from the planner. Also: tick, report, focus, push, status, stop.
|
||||
user_invocable: true
|
||||
allowed-tools: Read, Write, Edit, Agent, SendMessage, ToolSearch, AskUserQuestion, Bash(date *), Bash(test *), Bash(ls *), Bash(cat *), Bash(mkdir *), Bash(python3 *), Bash(git status*), Bash(git rev-parse *), Bash(git log *), Bash(git diff *), Bash(git add *), Bash(git commit *), Bash(git merge *), Bash(git worktree *), Bash(git branch *), Bash(git -C *), Bash(mm-worktree-task *), Bash(review-minimax-run *), Bash(gac *)
|
||||
---
|
||||
|
||||
<command-name>supervise</command-name>
|
||||
|
||||
# /supervise Skill
|
||||
|
||||
You are the **supervisor**. You preserve context, exercise judgement, and schedule
|
||||
work. MiniMax subagents (via `mm-worktree-task`) do the implementation; you never
|
||||
write code a MiniMax unit should write. There is no cap on units in flight — but at
|
||||
most one per work item.
|
||||
|
||||
Requires a planner-backed project (a `cp-cli planner` reference in its CLAUDE.md),
|
||||
`mm-worktree-task` in `~/sbin`, and the MiniMax profile. Stop and say so if any is missing.
|
||||
|
||||
## Pre-gathered context
|
||||
|
||||
### Date
|
||||
!`date +%Y-%m-%dT%H:%M:%S`
|
||||
|
||||
### Repo
|
||||
!`git rev-parse --show-toplevel`
|
||||
!`git rev-parse --abbrev-ref HEAD`
|
||||
|
||||
### Supervisor state (if any)
|
||||
!`cat .supervisor/state.md 2>/dev/null || echo NO_STATE`
|
||||
|
||||
## Arguments
|
||||
|
||||
`$ARGUMENTS` — first word selects the mode:
|
||||
|
||||
| Mode | Meaning |
|
||||
|---|---|
|
||||
| *(empty)* | `start`, focus chosen via the picker |
|
||||
| `start [focus text]` or any other text | start with that focus |
|
||||
| `tick` | one 15-min supervision pass (fired by cron) |
|
||||
| `report` | one 30-min progress report (fired by cron) |
|
||||
| `focus [text]` | change the focus (picker if no text); loops untouched |
|
||||
| `push on\|off` | allow/forbid pushing merged work (default off) |
|
||||
| `status` | print state + cron list, change nothing |
|
||||
| `stop` | delete both crons, mark state stopped |
|
||||
|
||||
## State: `.supervisor/state.md`
|
||||
|
||||
Created at start, edited in place. The cron prompts carry no state, so this file is
|
||||
the memory — re-read it at the top of every mode. Shape:
|
||||
|
||||
```
|
||||
# Supervisor state
|
||||
started: <ISO time> # session start; report counts are relative to this
|
||||
status: running|stopped
|
||||
focus: <free text and/or item UUIDs>
|
||||
push: off|on
|
||||
suite: <command that runs the project's full test suite>
|
||||
cron_tick: <job id>
|
||||
cron_report: <job id>
|
||||
|
||||
## Ledger (every bug/feature item the supervisor has touched this session)
|
||||
| item (uuid8) | title | kind | stage | notes |
|
||||
stages: queued → in-flight → collected → gated → merged → closed | failed | blocked
|
||||
|
||||
## In-flight
|
||||
| item | slug | branch | worktree | dispatched | attempt |
|
||||
```
|
||||
|
||||
Counts for reports come from the ledger, with "resolved" **verified against the
|
||||
planner** (`items get <uuid>` state), not from the ledger's own claim.
|
||||
|
||||
## Mode: start
|
||||
|
||||
1. **State exists and `status: running`** → this is a resume. Keep focus and ledger;
|
||||
go to step 5 (re-create crons only if `CronList` lacks them; the old ids are dead
|
||||
after a restart). If `$ARGUMENTS` carries new focus text, treat it as `focus`.
|
||||
2. **Bootstrap `.supervisor/`**: `mkdir -p .supervisor`; write `state.md` from the
|
||||
shape above with `started` = now, `push: off`.
|
||||
3. **Gitignore**: Read `.gitignore` (create it if absent). If no line equals
|
||||
`.supervisor/` or `.supervisor`, append `.supervisor/`. Never use shell `grep`
|
||||
for this check (exit 1 on no match) — Read and Edit.
|
||||
4. **Amend the project CLAUDE.md** (repo root; create a minimal one if absent).
|
||||
If it does not already contain `<!-- supervisor:begin -->`, append:
|
||||
```
|
||||
<!-- supervisor:begin -->
|
||||
## Supervisor (`/supervise`)
|
||||
|
||||
This project may be worked under the `/supervise` skill: one session supervises
|
||||
MiniMax units dispatched with `mm-worktree-task`, on 15-min tick and 30-min report
|
||||
crons. Its working state lives in `.supervisor/` (gitignored — never commit it,
|
||||
never hand-edit `state.md` while a supervisor is running). If `.supervisor/state.md`
|
||||
says `status: running`, another session is supervising: do not dispatch units for
|
||||
the same items or touch their worktrees (`.claude/worktrees/mm-*`, branches `mm/*`).
|
||||
<!-- supervisor:end -->
|
||||
```
|
||||
Do not commit this edit; tell the user it is an uncommitted change to CLAUDE.md.
|
||||
5. **Focus**: if given, use it. Otherwise run the picker (see Mode: focus).
|
||||
6. **Suite command**: infer from the project's CLAUDE.md (test command). If unclear,
|
||||
ask the user once. Stored in `state.md` as `suite:`.
|
||||
7. **Crons**: load the tools with `ToolSearch select:CronCreate,CronList,CronDelete`,
|
||||
then `CronCreate` two recurring jobs (off-minute schedules on purpose):
|
||||
- `7,22,37,52 * * * *` → prompt `/supervise tick`
|
||||
- `14,44 * * * *` → prompt `/supervise report`
|
||||
Record both ids in `state.md`. Tell the user: crons are session-only and expire
|
||||
after 7 days; after a restart run `/supervise` again to resume from state.
|
||||
8. Run **one tick immediately** so work starts now, then say in one line what was
|
||||
dispatched and how to change focus / stop.
|
||||
|
||||
## Mode: tick (every 15 min)
|
||||
|
||||
Re-read `state.md`. If `status: stopped`, do nothing and say so. Then, in order:
|
||||
|
||||
1. **Reap.** For each In-flight row run `mm-worktree-task <uuid> --slug <slug> --collect`.
|
||||
- Still running → leave it.
|
||||
- Finished → adjudicate. Never trust the agent's own "green": re-run `suite` in the
|
||||
worktree **after the unit's last commit**; require a real-process test wherever
|
||||
the code shells out; check any wire-shape change against the live server model;
|
||||
inspect the diff. Optionally pre-filter with `/review-minimax` on large diffs.
|
||||
Pass → merge into the base branch locally (`git merge --no-ff mm/<slug>`), re-run
|
||||
`suite` on the merged tree, update the item in the planner, ledger → `merged`/`closed`.
|
||||
Fail → ledger `failed`, re-dispatch once with the failure appended as `--focus`
|
||||
(attempt 2); a second failure → `blocked`, surfaced in the next report.
|
||||
- A unit that hit a permission prompt or asked for one: mark `blocked`. Never
|
||||
work around it and never tell a unit to.
|
||||
- Push only if `push: on`, after the SSH pre-flight in the root CLAUDE.md. Otherwise
|
||||
leave merged work local and count it in the report as "merged, unpushed".
|
||||
2. **Discover.** If reaped units or your own reading surfaced new bugs, file each as a
|
||||
planner item (`items create`) and add it to the ledger as `queued`. New bugs join
|
||||
the current work automatically; do not ask.
|
||||
3. **Select.** Candidate items = unresolved items matching `focus` (planner `items list`
|
||||
with the right label/state, plus any UUIDs named in focus), minus items already
|
||||
In-flight, `blocked`, or `closed`. Skip an item whose likely files overlap an
|
||||
in-flight unit — queue it for the next tick instead of creating merge conflicts.
|
||||
4. **Dispatch.** For each selected item:
|
||||
`mm-worktree-task <uuid> --slug <short> --gate "<suite>"` (detached; it returns at
|
||||
once). Add an In-flight row. If nothing was in flight and nothing is dispatchable,
|
||||
say "nothing to dispatch" and why (no open items vs all blocked).
|
||||
5. **Write state.md**, then output **at most 4 lines**: reaped / dispatched / in-flight
|
||||
count / anything needing the user. No narration.
|
||||
|
||||
## Mode: report (every 30 min)
|
||||
|
||||
Re-read `state.md`, refresh each ledger item's planner state, then output a very brief
|
||||
summary and nothing else:
|
||||
|
||||
- Bugs worked this session: N total; resolved: M; in flight: K; blocked: B
|
||||
(merged-but-unpushed counted separately if `push: off`).
|
||||
- Progress on the focus feature/epic: percent or `done/total` child items from the
|
||||
planner, plus one phrase on the next blocker.
|
||||
|
||||
## Mode: focus
|
||||
|
||||
`focus <text>` → set `focus:` in `state.md`, done; the next tick uses it. With no text,
|
||||
run the **picker**: query the planner for non-closed bugs and in-progress
|
||||
features/epics (try `scripts/get_context` if the project has it; else
|
||||
`items list --label bug` and `--state` for open/in-progress; labels come from the
|
||||
project's planner schema). `AskUserQuestion`, multiSelect, header "Focus", up to 4
|
||||
options — e.g. "All open bugs (N)", the top feature/epic by activity, a cluster of
|
||||
related bugs — each description naming counts. "Other" covers free text. Join the
|
||||
answers into the `focus:` line.
|
||||
|
||||
## Mode: push / status / stop
|
||||
|
||||
- `push on|off` → edit `push:`. Turning it on: remind that pushes may trigger deploys.
|
||||
- `status` → print state.md and `CronList`; change nothing.
|
||||
- `stop` → `CronDelete` both ids, set `status: stopped`, print final totals as in
|
||||
`report`, and list any In-flight worktrees still running. Leave `.supervisor/` and
|
||||
the CLAUDE.md section in place.
|
||||
|
||||
## Rules
|
||||
|
||||
- Supervisor judges and schedules; MiniMax implements. No code-writing in-session
|
||||
except a trivial fix to a merge conflict.
|
||||
- One unit per item. Unlimited items in parallel.
|
||||
- Every claimed-green result is re-run by you after the unit's last commit.
|
||||
- Never put secrets in `.supervisor/` or in prompts to units.
|
||||
- Keep tick and report output terse — they fire unattended and land in the transcript.
|
||||
Reference in New Issue
Block a user