aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/templates
diff options
context:
space:
mode:
Diffstat (limited to 'templates')
-rw-r--r--templates/CLAUDE.md21
-rw-r--r--templates/TASKS.md12
-rw-r--r--templates/archive.md1
-rw-r--r--templates/batch-prompt.md1
-rw-r--r--templates/cloud-prompt.md38
-rw-r--r--templates/prep-prompt.md1
-rw-r--r--templates/workflow.toml36
7 files changed, 110 insertions, 0 deletions
diff --git a/templates/CLAUDE.md b/templates/CLAUDE.md
new file mode 100644
index 0000000..88f70b4
--- /dev/null
+++ b/templates/CLAUDE.md
@@ -0,0 +1,21 @@
+# CLAUDE.md — {name}
+
+Project rules; win over the shared /projects/CLAUDE.md on conflict. Terse. Update when you re-learn something.
+
+## Layout
+- <dirs / entry points, one line each>
+
+## Loop additions
+- Verify: <command>
+
+## Gotchas
+- <env / layout / tool surprise, found at cost>
+
+## Areas
+### <area>
+- Code map: <grep anchors: function / class / string names, no line numbers>
+- Test recipe: <command for this area, fixture / data notes>
+- Tools: <scripts / CLIs, one line each: what, how to run>
+- Worktree setup: <steps a fresh worktree needs: venv, submodules, data links>
+- Paths: <globs the area's code lives in; none = whole repo>
+- Checked: <short sha: wf areas --mark <area> after a refresh>
diff --git a/templates/TASKS.md b/templates/TASKS.md
new file mode 100644
index 0000000..2148242
--- /dev/null
+++ b/templates/TASKS.md
@@ -0,0 +1,12 @@
+# Tasks — {name}
+
+Format and rules: /projects/CLAUDE.md. Done history: [`tasks/archive.md`](tasks/archive.md).
+Look and change with `wf` (`wf -h`), not by hand.
+
+## Awaiting your decision
+
+## Pending
+
+## Needs human
+
+## Deferred
diff --git a/templates/archive.md b/templates/archive.md
new file mode 100644
index 0000000..14e4146
--- /dev/null
+++ b/templates/archive.md
@@ -0,0 +1 @@
+# Task archive (newest first)
diff --git a/templates/batch-prompt.md b/templates/batch-prompt.md
new file mode 100644
index 0000000..1a0f338
--- /dev/null
+++ b/templates/batch-prompt.md
@@ -0,0 +1 @@
+You are a batch orchestrator. Follow {here}/docs/orchestrator.md 'One worker' for up to {n} tasks (lanes: {lanes}), never implement. Before EVERY spawn (each round, a lane's P0 fix, a recovery worker) run `test -e {stop}`: it exists → spawn nothing, let running workers finish (never kill one), post-check them, append 'stopped: stop file' to {out}, delete the stop file, exit. Else, before each round run `wf batch --time-left {deadline}`: its line ends in ': stop' (less time left than a task takes, p90) → spawn nothing new, let running workers finish, post-check them, append 'stopped: deadline (<that line>)' to {out}, exit. Else each round: `wf orch pick <lane>` per lane, spawn one wf-worker per picked lane in ONE message (model and prompt: as printed), foreground (not background), wait for all, post-check each with `wf orch post <id> <lane> --result "<result line>" --commit <sha> --agent <agent id> --duration <s> --no-pick`, append one line per task to {out} (it exists with its '# wf-batch' header: only append, never rewrite) (time, lane, id, outcome, commit), repeat. If the project has `cloud = true`, the virtual lane cloud also runs each round (nothing to spawn): `wf orch pick cloud` until a `stop lane cloud` / `none fit` / `max parallel` line; never run `wf cloud pull` or `wf orch post <id> cloud` yourself: the batch job's sidecar pulls every 10 min (`wf cloud pull --all` → `wf orch post <id> cloud … --no-pick`, a 'cloud <id> <state> … (sidecar pull)' line in {out}), also while you wait on workers; a cloud stop never stops the local lanes. Stop a lane on its first stop outcome, and keep it stopped (never resume because some other task is pickable) until the task/fix that stopped it is done or the owner says so; done+gate-red <culprit> <fix-id> is not one (post-check as done, the lane picks the P0 fix next). Never ask the owner: follow-ups → wf add -p 2 --model <model>, decisions → wf add -s awaiting. At batch start note `git branch --list 'fast/*' 'slow/*'` (and worktrees): a branch already there is pre-existing; report it ONCE in {out} as 'pre-existing branch <name>' (+ the awaiting id when a task/awaiting names it), never per round or per task. End with the ids added in that file, then exit.
diff --git a/templates/cloud-prompt.md b/templates/cloud-prompt.md
new file mode 100644
index 0000000..6020e90
--- /dev/null
+++ b/templates/cloud-prompt.md
@@ -0,0 +1,38 @@
+You are a remote worker for one task in a snapshot repo (branch main, base commit {{base}}).
+Rules (they override CLAUDE.md where they differ):
+- The task tool `wf` is absent: ignore wf / TASKS / lane / worktree / gate rules in CLAUDE.md; never create or edit TASKS.md or the archive.
+- Never ask questions. Blocked on a decision you cannot make: end with result awaiting and the one-line question as the report.
+- Work: test red -> implement -> green (test recipe below); commit on main, one-line messages; never rewrite {{base}}.
+- A needed network source is blocked: say so in the report, continue with what the repo has.
+- When done, measure your usage with the usage script at the end of this prompt (it sums your own transcript).
+- Commit only what the task needs: `git add <paths>`, never -A or `.`; no build output (__pycache__, bin, obj).
+- Then build the patch block: git format-patch --binary {{base}}..HEAD --stdout | gzip -9 > /tmp/wf.patch.gz; echo "WF-PATCH-BEGIN sha256=$(sha256sum < /tmp/wf.patch.gz | cut -c1-64) bytes=$(wc -c < /tmp/wf.patch.gz)"; base64 -w 76 /tmp/wf.patch.gz; echo WF-PATCH-END
+- Your final message is plain text (not a tool call, no code fences, no other text), first line = the result line.
+ Every line keeps its key word (WF-RESULT, WF-REPORT, WF-USAGE, then the patch block) literally; replace only <...>:
+ WF-RESULT <done, awaiting or handback>
+ WF-REPORT <one or two lines: what changed, tests run + result, open questions>
+ <the WF-USAGE line the usage script printed>
+ <the patch block: its WF-PATCH-BEGIN line, the base64 lines, WF-PATCH-END>
+ No commits (awaiting / handback without work): still write the patch block, for the empty patch.
+
+Task {{id}}:
+{{task}}
+
+Test recipe (area notes):
+{{recipe}}
+{{note}}
+Usage script (run as is):
+python3 - <<'PY'
+import json, glob, os
+f = max(glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")), key=os.path.getmtime)
+m = {}
+for line in open(f):
+ try:
+ j = json.loads(line); x = j.get("message") or {}
+ if x.get("usage"): m[x.get("id") or j.get("uuid")] = x
+ except Exception: pass
+t = [sum(x["usage"].get(k) or 0 for x in m.values()) for k in
+ ("input_tokens", "cache_creation_input_tokens", "cache_read_input_tokens", "output_tokens")]
+model = next((x["model"] for x in m.values() if x.get("model")), "?")
+print("WF-USAGE in=%d cw=%d cr=%d out=%d model=%s" % (*t, model))
+PY
diff --git a/templates/prep-prompt.md b/templates/prep-prompt.md
new file mode 100644
index 0000000..a503e7a
--- /dev/null
+++ b/templates/prep-prompt.md
@@ -0,0 +1 @@
+You are a prep batch orchestrator: make not-runner-ready tasks runner-ready; never implement, never edit files yourself. wf = python3 {here}/wf.py, project {root}. Tasks: {ids}. First, if out/wf-batch.stop exists → append 'stopped: stop file' to {out}, delete the stop file, exit. Else spawn sonnet workers (Agent tool, general-purpose, model sonnet, foreground, not background), up to 3 tasks each, all in ONE message, and wait for all. Worker prompt (fill in its ids): "Prep wf tasks <ids> in project {root} (cd there; wf = python3 {here}/wf.py). Read only task text: wf show <id> (wf ctx <id> for its refs, ~40-line reads). Never implement, never edit files, never commit. Per task: goal clear → wf set <id> --done "<one checkable line: command or observable result that proves it>". Done = observable check of the task text; never invert recorded original behaviour unless the task is a bug fix. Done names concrete files/runs, not 'each listed X'. Effort > slice_above (default 1h) → no Done on it: wf add --parent <id> slices (each with Done + Model), parent Done = all slices done. Also --model haiku|sonnet|opus if it has no Model line (haiku = mechanical, exact steps; sonnet = exact Done + existing pattern to copy; opus = design forks, debugging, anything unclear; any model above sonnet must be justified in the reply). Unclear (real fork, info only the owner has) → wf add -s awaiting "<id>: <question>", then wf status <id> blocked <a-id>. Reply one line per task: <id> → Done: <text> [Model: <m>] (model above sonnet: [opus: <why>]) | <id> → awaiting <a-id>." Then check each task with wf show <id> and append one line per task to {out} (it exists with its '# wf-batch' header: only append, never rewrite): <id> → Done: <text> | <id> → awaiting <a-id> | <id> → unchanged <why>. Finally commit only the task file: git -C {root} commit -m "prep batch: <ids changed>" -- {tasks}. Never ask the owner: questions → wf add -s awaiting. Then exit.
diff --git a/templates/workflow.toml b/templates/workflow.toml
new file mode 100644
index 0000000..b8b05cd
--- /dev/null
+++ b/templates/workflow.toml
@@ -0,0 +1,36 @@
+# wf project config. Design: docs/design.md. Unknown keys are errors.
+format = 1
+tasks = "TASKS.md"
+archive = "tasks/archive.md"
+docs = [] # files/folders whose [[id]] links `wf check` validates, e.g. ["DESIGN.md", "docs/"]
+verify = [] # commands `wf done` reminds of (never runs), e.g. ["make test"]
+done = [] # extra checklist lines `wf done` prints
+# ledgers = ".superpowers/sdd" # in-flight plan ledgers shown by `wf next`
+# ctx_hint = 100000 # tokens: `wf next`/`done` suggest /clear above it (0 = off)
+# worktree_setup = ["mkdir -p out && ln -sfn \"$WF_MAIN/out/data\" out/data"]
+# # `wf setup` in a lane worktree: cwd = worktree, env WF_MAIN = main tree;
+# # git-ignored inputs; idempotent (workers run it every start)
+# quick_gate = ["make quick-test"] # `wf gate`: fast regression check workers run before `wf done`
+# # (cwd = this tree's project folder, env WF_MAIN; red = exit 1)
+
+# [anchors] # optional: every task Ref anchor into `index` must be a heading there
+# index = "DESIGN.md"
+# index_section = "Subsystems"
+# specs = "docs/superpowers/specs"
+
+# slice_above = "1h" # effort above this → slice job on the slices lane (never implemented whole)
+# [lanes.fast] # default lanes = fast + slow below; defining any [lanes.*] replaces both
+# efforts = ["<1h"] # efforts this lane implements (disjoint, cover every effort ≤ slice_above)
+# order = "unblock" # unblock = tasks others wait on first · priority = inherited priority first
+# slices = true # takes slice jobs (one lane; default: the lane with "<1h")
+# [lanes.slow]
+# efforts = ["1h"]
+# order = "priority"
+# fallback = "fast" # nothing pickable here → pick from that lane
+# areas = "CLAUDE.md" # area notes (## Areas / ### <area>): wf areas checks their code maps
+# code_root = "../tool" # repo the areas' anchors / Paths / Checked refer to (default: this project); no uncovered nudge then
+# area_stale_commits = 20 # commits touching an area's Paths since Checked → stale
+# area_ignore = ["tests", "test", "docs", "doc"] # folders never nudged as uncovered (default shown)
+# cloud = true # cloud lane opt-in (wf cloud send)
+# cloud_include = ["out/pack"] # git-ignored inputs force-added to the cloud snapshot
+# cloud_note = "Game data: out/pack" # appended to the cloud prompt