Enhance spec-driven coding workflow

This commit is contained in:
lpf
2026-03-09 13:24:55 +08:00
parent d1abd73e63
commit 6089f4e7c4
26 changed files with 1388 additions and 717 deletions

View File

@@ -53,6 +53,13 @@ At the start of work, load context in this order:
- For coding/debug/refactor:
- investigate and decide internally
- minimize interruptions
- only enable spec-driven docs when the user is clearly asking for code changes and the work is non-trivial
- skip spec-driven docs for small tweaks, one-line fixes, and other lightweight edits unless the user explicitly asks for the workflow
- for eligible work, maintain `spec.md`, `tasks.md`, and `checklist.md` in the current coding project root
- keep `spec.md` focused on scope / decisions / tradeoffs
- keep `tasks.md` as a live implementation plan with progress updates
- keep `checklist.md` as the final verification gate before declaring completion
- do not create or load these files for non-coding conversations unless the user explicitly asks
---
@@ -82,6 +89,7 @@ At the start of work, load context in this order:
- At task start, always load:
- `SOUL.md`, `USER.md`, todays `memory/YYYY-MM-DD.md`, plus `MEMORY.md` (direct chat only)
- Before responding, select **at most one** most relevant skill and read its `SKILL.md`.
- For non-trivial coding work, prefer the `spec-coding` skill.
- If multiple skills apply: pick the **most specific**; do not bulk-load.
- If no skill applies: proceed without loading skill files.
- Resolve relative paths relative to the skill directory.

View File

@@ -1,34 +0,0 @@
---
name: clawgo-node-child
description: Deploy and register a clawgo child node to a parent clawgo gateway without ad-hoc Python agents. Use when setting up sub-nodes, syncing provider settings from parent to child, enabling reverse tunnel fallback, and validating parent-dispatched nodes actions (describe/run/invoke/agent_task).
---
# Clawgo Node Child
Use built-in clawgo services only. Do not create `node_agent.py`.
## Execute
1. Run `scripts/deploy_child.sh` on the operator host with env vars:
- `PARENT_HOST` `PARENT_PASS`
- `CHILD_HOST` `CHILD_PASS`
- Optional: `PARENT_GATEWAY_PORT` (default `18790`), `RELAY_PORT` (default `17789`), `CHILD_PORT` (default `7789`), `NODE_ID` (default `node-child`)
2. Script will:
- Copy `/usr/local/bin/clawgo` from parent to child
- Sync `providers` + `agents.defaults` into child `/root/.clawgo/provider-sync.json`
- Create child gateway config `/root/.clawgo/config.child.json`
- Install/start child service `clawgo-child-gateway.service`
- Install/start reverse tunnel service `clawgo-child-revtunnel.service`
- Register child node to parent `/nodes/register`
- Install child heartbeat cron (`/nodes/heartbeat` every minute)
3. Validate from parent:
- Health: `curl http://127.0.0.1:${RELAY_PORT}/health`
- Task dispatch: `clawgo agent` + `nodes action=agent_task node=<NODE_ID> mode=relay ...`
## Notes
- Prefer direct endpoint if reachable; keep reverse tunnel as fallback.
- If parent and CLI visibility differ, ensure node state persistence is enabled (`memory/nodes-state.json`).
- If child service fails, check:
- `journalctl -u clawgo-child-gateway.service -n 100 --no-pager`
- `journalctl -u clawgo-child-revtunnel.service -n 100 --no-pager`

View File

@@ -1,95 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
: "${PARENT_HOST:?need PARENT_HOST}"
: "${PARENT_PASS:?need PARENT_PASS}"
: "${CHILD_HOST:?need CHILD_HOST}"
: "${CHILD_PASS:?need CHILD_PASS}"
PARENT_GATEWAY_PORT="${PARENT_GATEWAY_PORT:-18790}"
RELAY_PORT="${RELAY_PORT:-17789}"
CHILD_PORT="${CHILD_PORT:-7789}"
NODE_ID="${NODE_ID:-node-child}"
SSHP_PARENT=(sshpass -p "$PARENT_PASS" ssh -o StrictHostKeyChecking=no "root@${PARENT_HOST}")
SSHP_CHILD=(sshpass -p "$CHILD_PASS" ssh -o StrictHostKeyChecking=no "root@${CHILD_HOST}")
# 1) Copy clawgo binary parent -> local -> child
sshpass -p "$PARENT_PASS" scp -o StrictHostKeyChecking=no "root@${PARENT_HOST}:/usr/local/bin/clawgo" /tmp/clawgo_child
sshpass -p "$CHILD_PASS" scp -o StrictHostKeyChecking=no /tmp/clawgo_child "root@${CHILD_HOST}:/usr/local/bin/clawgo"
"${SSHP_CHILD[@]}" "chmod +x /usr/local/bin/clawgo"
# 2) Sync providers + agents.defaults from parent
"${SSHP_PARENT[@]}" "python3 - <<'PY'
import json
c=json.load(open('/root/.clawgo/config.json'))
p={'providers':c.get('providers',{}),'agents_defaults':c.get('agents',{}).get('defaults',{})}
print(json.dumps(p,ensure_ascii=False))
PY" > /tmp/provider-sync.json
cat /tmp/provider-sync.json | "${SSHP_CHILD[@]}" "mkdir -p /root/.clawgo && cat > /root/.clawgo/provider-sync.json"
# 3) Build child config (no ad-hoc python server)
"${SSHP_CHILD[@]}" "python3 - <<'PY'
import json
src='/root/.clawgo/provider-sync.json'
out='/root/.clawgo/config.child.json'
d=json.load(open(src))
cfg={
'gateway': {'host':'0.0.0.0','port': ${CHILD_PORT}},
'providers': d.get('providers',{}),
'agents': {'defaults': d.get('agents_defaults',{})},
'channels': {},
'tools': {'shell': {'enabled': True}},
'logging': {'level':'info'}
}
json.dump(cfg, open(out,'w'), ensure_ascii=False, indent=2)
print(out)
PY"
# 4) Install child gateway service
"${SSHP_CHILD[@]}" "cat > /etc/systemd/system/clawgo-child-gateway.service <<EOF
[Unit]
Description=Clawgo Child Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/clawgo gateway run --config /root/.clawgo/config.child.json
Restart=always
RestartSec=2
User=root
WorkingDirectory=/root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now clawgo-child-gateway.service"
# 5) Install reverse tunnel service (child -> parent)
"${SSHP_CHILD[@]}" "yum install -y sshpass >/dev/null 2>&1 || true"
"${SSHP_CHILD[@]}" "cat > /etc/systemd/system/clawgo-child-revtunnel.service <<EOF
[Unit]
Description=Clawgo Child Reverse Tunnel
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/sshpass -p ${PARENT_PASS} /usr/bin/ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=20 -o ServerAliveCountMax=3 -N -R ${RELAY_PORT}:127.0.0.1:${CHILD_PORT} root@${PARENT_HOST}
Restart=always
RestartSec=3
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now clawgo-child-revtunnel.service"
# 6) Register + heartbeat
"${SSHP_CHILD[@]}" "curl -s -X POST http://${PARENT_HOST}:${PARENT_GATEWAY_PORT}/nodes/register -H 'Content-Type: application/json' -d '{\"id\":\"${NODE_ID}\",\"name\":\"${NODE_ID}\",\"os\":\"linux\",\"arch\":\"amd64\",\"version\":\"clawgo-child\",\"endpoint\":\"http://127.0.0.1:${RELAY_PORT}\",\"capabilities\":{\"run\":true,\"invoke\":true,\"model\":true},\"actions\":[\"run\",\"invoke\",\"agent_task\"],\"models\":[\"local-sim\"]}'"
"${SSHP_CHILD[@]}" "(crontab -l 2>/dev/null; echo '*/1 * * * * curl -s -X POST http://${PARENT_HOST}:${PARENT_GATEWAY_PORT}/nodes/heartbeat -H \"Content-Type: application/json\" -d \"{\\\"id\\\":\\\"${NODE_ID}\\\"}\" >/dev/null 2>&1') | crontab -"
echo "DONE: ${NODE_ID} deployed"

View File

@@ -1,274 +0,0 @@
---
name: coding-agent
description: Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.
metadata: {"clawdbot":{"emoji":"🧩","requires":{"anyBins":["claude","codex","opencode","pi"]}}}
---
# Coding Agent (background-first)
Use **bash background mode** for non-interactive coding work. For interactive coding sessions, use the **tmux** skill (always, except very simple one-shot prompts).
## The Pattern: workdir + background
```bash
# Create temp space for chats/scratch work
SCRATCH=$(mktemp -d)
# Start agent in target directory ("little box" - only sees relevant files)
bash workdir:$SCRATCH background:true command:"<agent command>"
# Or for project work:
bash workdir:~/project/folder background:true command:"<agent command>"
# Returns sessionId for tracking
# Monitor progress
process action:log sessionId:XXX
# Check if done
process action:poll sessionId:XXX
# Send input (if agent asks a question)
process action:write sessionId:XXX data:"y"
# Kill if needed
process action:kill sessionId:XXX
```
**Why workdir matters:** Agent wakes up in a focused directory, doesn't wander off reading unrelated files (like your soul.md 😅).
---
## Codex CLI
**Model:** `gpt-5.3-codex` is the default (set in ~/.codex/config.toml)
### Building/Creating (use --full-auto or --yolo)
```bash
# --full-auto: sandboxed but auto-approves in workspace
bash workdir:~/project background:true command:"codex exec --full-auto \"Build a snake game with dark theme\""
# --yolo: NO sandbox, NO approvals (fastest, most dangerous)
bash workdir:~/project background:true command:"codex --yolo \"Build a snake game with dark theme\""
# Note: --yolo is a shortcut for --dangerously-bypass-approvals-and-sandbox
```
### Reviewing PRs (vanilla, no flags)
**⚠️ CRITICAL: Never review PRs in Clawdbot's own project folder!**
- Either use the project where the PR is submitted (if it's NOT ~/Projects/clawdbot)
- Or clone to a temp folder first
```bash
# Option 1: Review in the actual project (if NOT clawdbot)
bash workdir:~/Projects/some-other-repo background:true command:"codex review --base main"
# Option 2: Clone to temp folder for safe review (REQUIRED for clawdbot PRs!)
REVIEW_DIR=$(mktemp -d)
git clone https://github.com/clawdbot/clawdbot.git $REVIEW_DIR
cd $REVIEW_DIR && gh pr checkout 130
bash workdir:$REVIEW_DIR background:true command:"codex review --base origin/main"
# Clean up after: rm -rf $REVIEW_DIR
# Option 3: Use git worktree (keeps main intact)
git worktree add /tmp/pr-130-review pr-130-branch
bash workdir:/tmp/pr-130-review background:true command:"codex review --base main"
```
**Why?** Checking out branches in the running Clawdbot repo can break the live instance!
### Batch PR Reviews (parallel army!)
```bash
# Fetch all PR refs first
git fetch origin '+refs/pull/*/head:refs/remotes/origin/pr/*'
# Deploy the army - one Codex per PR!
bash workdir:~/project background:true command:"codex exec \"Review PR #86. git diff origin/main...origin/pr/86\""
bash workdir:~/project background:true command:"codex exec \"Review PR #87. git diff origin/main...origin/pr/87\""
bash workdir:~/project background:true command:"codex exec \"Review PR #95. git diff origin/main...origin/pr/95\""
# ... repeat for all PRs
# Monitor all
process action:list
# Get results and post to GitHub
process action:log sessionId:XXX
gh pr comment <PR#> --body "<review content>"
```
### Tips for PR Reviews
- **Fetch refs first:** `git fetch origin '+refs/pull/*/head:refs/remotes/origin/pr/*'`
- **Use git diff:** Tell Codex to use `git diff origin/main...origin/pr/XX`
- **Don't checkout:** Multiple parallel reviews = don't let them change branches
- **Post results:** Use `gh pr comment` to post reviews to GitHub
---
## Claude Code
```bash
bash workdir:~/project background:true command:"claude \"Your task\""
```
---
## OpenCode
```bash
bash workdir:~/project background:true command:"opencode run \"Your task\""
```
---
## Pi Coding Agent
```bash
# Install: npm install -g @mariozechner/pi-coding-agent
bash workdir:~/project background:true command:"pi \"Your task\""
```
---
## Pi flags (common)
- `--print` / `-p`: non-interactive; runs prompt and exits.
- `--provider <name>`: pick provider (default: google).
- `--model <id>`: pick model (default: gemini-2.5-flash).
- `--api-key <key>`: override API key (defaults to env vars).
Examples:
```bash
# Set provider + model, non-interactive
bash workdir:~/project background:true command:"pi --provider openai --model gpt-4o-mini -p \"Summarize src/\""
```
---
## tmux (interactive sessions)
Use the tmux skill for interactive coding sessions (always, except very simple one-shot prompts). Prefer bash background mode for non-interactive runs.
---
## Parallel Issue Fixing with git worktrees + tmux
For fixing multiple issues in parallel, use git worktrees (isolated branches) + tmux sessions:
```bash
# 1. Clone repo to temp location
cd /tmp && git clone git@github.com:user/repo.git repo-worktrees
cd repo-worktrees
# 2. Create worktrees for each issue (isolated branches!)
git worktree add -b fix/issue-78 /tmp/issue-78 main
git worktree add -b fix/issue-99 /tmp/issue-99 main
# 3. Set up tmux sessions
SOCKET="${TMPDIR:-/tmp}/codex-fixes.sock"
tmux -S "$SOCKET" new-session -d -s fix-78
tmux -S "$SOCKET" new-session -d -s fix-99
# 4. Launch Codex in each (after pnpm install!)
tmux -S "$SOCKET" send-keys -t fix-78 "cd /tmp/issue-78 && pnpm install && codex --yolo 'Fix issue #78: <description>. Commit and push.'" Enter
tmux -S "$SOCKET" send-keys -t fix-99 "cd /tmp/issue-99 && pnpm install && codex --yolo 'Fix issue #99: <description>. Commit and push.'" Enter
# 5. Monitor progress
tmux -S "$SOCKET" capture-pane -p -t fix-78 -S -30
tmux -S "$SOCKET" capture-pane -p -t fix-99 -S -30
# 6. Check if done (prompt returned)
tmux -S "$SOCKET" capture-pane -p -t fix-78 -S -3 | grep -q "" && echo "Done!"
# 7. Create PRs after fixes
cd /tmp/issue-78 && git push -u origin fix/issue-78
gh pr create --repo user/repo --head fix/issue-78 --title "fix: ..." --body "..."
# 8. Cleanup
tmux -S "$SOCKET" kill-server
git worktree remove /tmp/issue-78
git worktree remove /tmp/issue-99
```
**Why worktrees?** Each Codex works in isolated branch, no conflicts. Can run 5+ parallel fixes!
**Why tmux over bash background?** Codex is interactive — needs TTY for proper output. tmux provides persistent sessions with full history capture.
---
## ⚠️ Rules
1. **Respect tool choice** — if user asks for Codex, use Codex. NEVER offer to build it yourself!
2. **Be patient** — don't kill sessions because they're "slow"
3. **Monitor with process:log** — check progress without interfering
4. **--full-auto for building** — auto-approves changes
5. **vanilla for reviewing** — no special flags needed
6. **Parallel is OK** — run many Codex processes at once for batch work
7. **NEVER start Codex in ~/clawd/** — it'll read your soul docs and get weird ideas about the org chart! Use the target project dir or /tmp for blank slate chats
8. **NEVER checkout branches in ~/Projects/clawdbot/** — that's the LIVE Clawdbot instance! Clone to /tmp or use git worktree for PR reviews
---
## PR Template (The Razor Standard)
When submitting PRs to external repos, use this format for quality & maintainer-friendliness:
````markdown
## Original Prompt
[Exact request/problem statement]
## What this does
[High-level description]
**Features:**
- [Key feature 1]
- [Key feature 2]
**Example usage:**
```bash
# Example
command example
```
## Feature intent (maintainer-friendly)
[Why useful, how it fits, workflows it enables]
## Prompt history (timestamped)
- YYYY-MM-DD HH:MM UTC: [Step 1]
- YYYY-MM-DD HH:MM UTC: [Step 2]
## How I tested
**Manual verification:**
1. [Test step] - Output: `[result]`
2. [Test step] - Result: [result]
**Files tested:**
- [Detail]
- [Edge cases]
## Session logs (implementation)
- [What was researched]
- [What was discovered]
- [Time spent]
## Implementation details
**New files:**
- `path/file.ts` - [description]
**Modified files:**
- `path/file.ts` - [change]
**Technical notes:**
- [Detail 1]
- [Detail 2]
---
*Submitted by Razor 🥷 - Mariano's AI agent*
````
**Key principles:**
1. Human-written description (no AI slop)
2. Feature intent for maintainers
3. Timestamped prompt history
4. Session logs if using Codex/agent
**Example:** https://github.com/steipete/bird/pull/22

View File

@@ -0,0 +1,102 @@
---
name: spec-coding
description: Drive non-trivial coding work through spec.md, tasks.md, and checklist.md in the current project root. Use for feature delivery, multi-file refactors, architectural changes, or any implementation that needs scope control and explicit verification.
---
# Spec Coding
Use this skill for non-trivial coding work. The goal is to keep implementation aligned with a living spec, an explicit task breakdown, and a final verification gate.
Important:
- The files inside `workspace/skills/spec-coding/` are templates and workflow instructions only.
- Real project state must live in the coding target project itself.
- Do not treat the skill directory as shared runtime state across projects.
- Do not turn this on for small tweaks or lightweight edits unless the user explicitly asks for spec-driven workflow.
## Files
Maintain these files in the current coding project root by default:
- `spec.md`
- `tasks.md`
- `checklist.md`
If the user explicitly asks for a different location, follow that instead.
Do not create these files for non-coding tasks unless the user explicitly wants the workflow.
## Intent
- `spec.md` is the north-star document.
It explains what is being built, why it matters, what is in scope, what is out of scope, and which decisions / tradeoffs were made.
- `tasks.md` is the live implementation plan.
It breaks the spec into modules, tasks, and ordered execution steps. Update it as work progresses.
- `checklist.md` is the completion gate.
Only mark the project done after walking this file and confirming implementation, behavior, and validation are complete.
## Workflow
### 1) Bootstrap
If any of the three files are missing, scaffold them first.
Use:
```bash
skill_exec(spec="spec-coding", script="scripts/init.sh")
```
Optional target directory:
```bash
skill_exec(spec="spec-coding", script="scripts/init.sh", args=["/path/to/project"])
```
### 2) Write / refine the spec
Before substantial code changes:
- summarize the problem
- define desired outcome
- define in-scope / out-of-scope
- capture decisions and tradeoffs
- note risks / open questions
Keep it concrete and engineering-oriented.
### 3) Expand into tasks
Break the spec into:
- modules or workstreams
- sub-tasks
- ordered implementation steps
Update statuses as you progress. The task plan is expected to evolve.
### 4) Implement against the plan
As work changes:
- update `spec.md` when scope or key decisions shift
- update `tasks.md` as tasks are completed / deferred / added
- do not wait until the end to synchronize the docs
### 5) Verify before close-out
When implementation is done:
- walk `checklist.md`
- verify code changes
- verify tests / validation
- verify no obvious scope gaps remain
Do not declare completion until the checklist has been reviewed.
## Quality bar
- Prefer concise, structured markdown over long prose.
- Keep docs useful for resuming work in a later session.
- Avoid fake precision; if something is undecided, mark it explicitly.
- For small one-file edits, skip this workflow by default.
- For anything multi-step or multi-file, this workflow should be visible in the repo.

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
target_dir="${1:-$(pwd)}"
skill_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
templates_dir="$skill_dir/templates"
mkdir -p "$target_dir"
copy_template_if_missing() {
local target_path="$1"
local template_name="$2"
if [[ -f "$target_path" ]]; then
echo "exists: $target_path"
return
fi
cp "$templates_dir/$template_name" "$target_path"
echo "created: $target_path"
}
copy_template_if_missing "$target_dir/spec.md" "spec.md"
copy_template_if_missing "$target_dir/tasks.md" "tasks.md"
copy_template_if_missing "$target_dir/checklist.md" "checklist.md"

View File

@@ -0,0 +1,8 @@
# Verification Checklist (checklist.md)
- [ ] Scope implemented
- [ ] Edge cases reviewed
- [ ] Tests added or updated where needed
- [ ] Validation run
- [ ] Docs / prompts / config updated if required
- [ ] No known missing follow-up inside current scope

View File

@@ -0,0 +1,21 @@
# Project Scope (spec.md)
## Overview
- What is being built:
- Why this change is needed:
- Desired outcome:
## In Scope
-
## Out of Scope
-
## Decisions
-
## Tradeoffs
-
## Risks / Open Questions
-

View File

@@ -0,0 +1,12 @@
# Task Breakdown (tasks.md)
## Workstreams
### 1.
- [ ]
### 2.
- [ ]
## Progress Notes
-