From 85bdf26aa06f5e930fb6a2b12f8ddd349c0d14d1 Mon Sep 17 00:00:00 2001 From: Snider Date: Wed, 18 Mar 2026 12:18:40 +0000 Subject: [PATCH] feat: add orchestration skills + local dispatch scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - orchestrate skill: full plan→dispatch→review→fix→verify pipeline - prompts skill: browse/read personas, tasks, flows, templates - review-pipeline skill: multi-stage security→fix→simplify→architecture→verify - local-dispatch.sh: dispatch agents without MCP (clone, run CLI, capture) - workspace-status.sh: check all workspace statuses - main.go: fix ServiceFor removal (use c.Service() + type assert) Co-Authored-By: Virgil --- claude/core/scripts/local-dispatch.sh | 85 ++++++++++++++++ claude/core/scripts/workspace-status.sh | 50 +++++++++ claude/core/skills/orchestrate.md | 130 ++++++++++++++++++++++++ claude/core/skills/prompts.md | 41 ++++++++ claude/core/skills/review-pipeline.md | 75 ++++++++++++++ cmd/core-agent/main.go | 6 +- 6 files changed, 384 insertions(+), 3 deletions(-) create mode 100755 claude/core/scripts/local-dispatch.sh create mode 100755 claude/core/scripts/workspace-status.sh create mode 100644 claude/core/skills/orchestrate.md create mode 100644 claude/core/skills/prompts.md create mode 100644 claude/core/skills/review-pipeline.md diff --git a/claude/core/scripts/local-dispatch.sh b/claude/core/scripts/local-dispatch.sh new file mode 100755 index 0000000..a4f272d --- /dev/null +++ b/claude/core/scripts/local-dispatch.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Local agent dispatch without MCP/core-agent. +# Usage: local-dispatch.sh [agent] [persona-path] +# +# Creates workspace, clones repo, runs agent, captures output. + +set -euo pipefail + +REPO="${1:?repo required}" +TASK="${2:?task required}" +AGENT="${3:-claude:haiku}" +PERSONA="${4:-}" + +CODE_PATH="${CODE_PATH:-$HOME/Code}" +WS_ROOT="$CODE_PATH/.core/workspace" +PROMPTS="$CODE_PATH/core/agent/pkg/prompts/lib" +TIMESTAMP=$(date +%s) +WS_DIR="$WS_ROOT/${REPO}-${TIMESTAMP}" + +# Parse agent:model +IFS=':' read -r AGENT_TYPE MODEL <<< "$AGENT" +MODEL="${MODEL:-haiku}" + +# Map to CLI + model flag +case "$AGENT_TYPE" in + claude) + case "$MODEL" in + haiku) CLI="claude"; MODEL_FLAG="--model claude-haiku-4-5-20251001" ;; + sonnet) CLI="claude"; MODEL_FLAG="--model claude-sonnet-4-5-20241022" ;; + opus) CLI="claude"; MODEL_FLAG="" ;; + *) CLI="claude"; MODEL_FLAG="--model $MODEL" ;; + esac + ;; + gemini) CLI="gemini"; MODEL_FLAG="-p" ;; + codex) CLI="codex"; MODEL_FLAG="exec -p" ;; + *) echo "Unknown agent: $AGENT_TYPE"; exit 1 ;; +esac + +# Create workspace +mkdir -p "$WS_DIR" + +# Clone repo +REPO_PATH="$CODE_PATH/core/$REPO" +if [ ! -d "$REPO_PATH" ]; then + echo "ERROR: $REPO_PATH not found" + exit 1 +fi +git clone "$REPO_PATH" "$WS_DIR/src" 2>/dev/null + +# Build prompt +PROMPT="$TASK" + +# Add persona if provided +if [ -n "$PERSONA" ] && [ -f "$PROMPTS/persona/$PERSONA.md" ]; then + PERSONA_CONTENT=$(cat "$PROMPTS/persona/$PERSONA.md") + PROMPT="$PERSONA_CONTENT + +--- + +$TASK" +fi + +# Dispatch +LOG_FILE="$WS_DIR/agent-${AGENT}.log" +echo "Dispatching $AGENT to $WS_DIR..." + +case "$AGENT_TYPE" in + claude) + cd "$WS_DIR/src" + claude --dangerously-skip-permissions $MODEL_FLAG -p "$PROMPT" > "$LOG_FILE" 2>&1 & + PID=$! + ;; + gemini) + cd "$WS_DIR/src" + gemini -p "$PROMPT" > "$LOG_FILE" 2>&1 & + PID=$! + ;; + codex) + cd "$WS_DIR/src" + codex exec -p "$PROMPT" > "$LOG_FILE" 2>&1 & + PID=$! + ;; +esac + +echo "{\"workspace\":\"$WS_DIR\",\"pid\":$PID,\"agent\":\"$AGENT\",\"repo\":\"$REPO\"}" diff --git a/claude/core/scripts/workspace-status.sh b/claude/core/scripts/workspace-status.sh new file mode 100755 index 0000000..6b61484 --- /dev/null +++ b/claude/core/scripts/workspace-status.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Check status of all agent workspaces. +# Usage: workspace-status.sh [repo-filter] + +WS_ROOT="${CODE_PATH:-$HOME/Code}/.core/workspace" +FILTER="${1:-}" + +if [ ! -d "$WS_ROOT" ]; then + echo "No workspaces found" + exit 0 +fi + +for ws in "$WS_ROOT"/*; do + [ -d "$ws" ] || continue + + NAME=$(basename "$ws") + + # Apply filter + if [ -n "$FILTER" ] && [[ "$NAME" != *"$FILTER"* ]]; then + continue + fi + + # Check for agent log + LOG=$(ls "$ws"/agent-*.log 2>/dev/null | head -1) + AGENT=$(basename "$LOG" .log 2>/dev/null | sed 's/agent-//') + + # Check PID if running + PID_FILE="$ws/.pid" + STATUS="completed" + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null 2>&1; then + STATUS="running (PID $PID)" + fi + fi + + # Check for commits + COMMITS=0 + if [ -d "$ws/src/.git" ]; then + COMMITS=$(cd "$ws/src" && git rev-list --count HEAD 2>/dev/null || echo 0) + fi + + # Log size + LOG_SIZE=0 + if [ -f "$LOG" ]; then + LOG_SIZE=$(wc -c < "$LOG" | tr -d ' ') + fi + + echo "$NAME | $AGENT | $STATUS | ${LOG_SIZE}b log | $COMMITS commits" +done diff --git a/claude/core/skills/orchestrate.md b/claude/core/skills/orchestrate.md new file mode 100644 index 0000000..5af3aed --- /dev/null +++ b/claude/core/skills/orchestrate.md @@ -0,0 +1,130 @@ +--- +name: orchestrate +description: Run the full agent pipeline — plan, dispatch, monitor, review, fix, re-review, merge. Works locally without MCP. +arguments: + - name: repo + description: Target repo (e.g. go, go-process, mcp) + required: true + - name: goal + description: What needs to be achieved + required: true + - name: agent + description: Agent type (claude:haiku, claude:sonnet, gemini, codex) + default: claude:haiku + - name: stages + description: Comma-separated stages to run (plan,dispatch,review,fix,verify) + default: plan,dispatch,review,fix,verify +--- + +# Agent Orchestration Pipeline + +Run the full dispatch → review → fix → verify cycle for `$ARGUMENTS.repo`. + +## Stage 1: Plan + +Break `$ARGUMENTS.goal` into discrete tasks. For each task: +- Determine the best persona from `lib/persona/` +- Select the right prompt template from `lib/prompt/` +- Choose a task plan from `lib/task/` if one fits + +List tasks using the prompts library: +```bash +# Available personas +find ~/Code/core/agent/pkg/prompts/lib/persona -name "*.md" | sed 's|.*/lib/persona/||;s|\.md$||' + +# Available task plans +find ~/Code/core/agent/pkg/prompts/lib/task -name "*.md" -o -name "*.yaml" | sed 's|.*/lib/task/||;s|\.(md|yaml)$||' + +# Available prompt templates +find ~/Code/core/agent/pkg/prompts/lib/prompt -name "*.md" | sed 's|.*/lib/prompt/||;s|\.md$||' + +# Available flows +find ~/Code/core/agent/pkg/prompts/lib/flow -name "*.md" | sed 's|.*/lib/flow/||;s|\.md$||' +``` + +Output a task list with: task name, persona, template, estimated complexity. + +## Stage 2: Dispatch + +For each task from Stage 1, dispatch an agent. Prefer MCP tools if available: +``` +mcp__core__agentic_dispatch(repo, task, agent, template, persona) +``` + +If MCP is unavailable, dispatch locally: +```bash +cd ~/Code/core/$ARGUMENTS.repo +claude --dangerously-skip-permissions -p "[persona content] + +$TASK_DESCRIPTION" --model $MODEL +``` + +Track dispatched tasks: workspace dir, PID, status. + +## Stage 3: Review + +After agents complete, review their output: +```bash +# Check workspace status +ls ~/Code/.core/workspace/$REPO-*/ + +# Read agent logs +cat ~/Code/.core/workspace/$WORKSPACE/agent-*.log + +# Check for commits +cd ~/Code/.core/workspace/$WORKSPACE/src && git log --oneline -5 +``` + +Run the code-review agent on changes: +``` +Read lib/task/code/review.md and dispatch review agent +``` + +## Stage 4: Fix + +If review finds issues, dispatch a fix agent: +- Use `lib/task/code/review.md` findings as input +- Use `secops/developer` persona for security fixes +- Use `code/backend-architect` persona for structural fixes + +## Stage 5: Verify + +Final check: +```bash +# Build +cd ~/Code/.core/workspace/$WORKSPACE/src && go build ./... + +# Vet +go vet ./... + +# Run targeted tests if they exist +go test ./... -count=1 -timeout 60s 2>&1 | tail -20 +``` + +If verify passes → report success. +If verify fails → report failures and stop. + +## Output + +```markdown +## Orchestration Report: $ARGUMENTS.repo + +### Goal +$ARGUMENTS.goal + +### Tasks Dispatched +| # | Task | Agent | Status | +|---|------|-------|--------| + +### Review Findings +[Summary from Stage 3] + +### Fixes Applied +[Summary from Stage 4] + +### Verification +[PASS/FAIL from Stage 5] + +### Next Steps +[Any remaining work] +``` diff --git a/claude/core/skills/prompts.md b/claude/core/skills/prompts.md new file mode 100644 index 0000000..b6a7a2e --- /dev/null +++ b/claude/core/skills/prompts.md @@ -0,0 +1,41 @@ +--- +name: prompts +description: Browse and read from the prompts library — personas, tasks, flows, templates +arguments: + - name: action + description: list or read + required: true + - name: type + description: persona, task, flow, prompt + - name: slug + description: The slug to read (e.g. secops/developer, code/review, go) +--- + +# Prompts Library + +Access the embedded prompts at `~/Code/core/agent/pkg/prompts/lib/`. + +## List + +```bash +# List all of a type +find ~/Code/core/agent/pkg/prompts/lib/$ARGUMENTS.type -name "*.md" -o -name "*.yaml" | sed "s|.*/lib/$ARGUMENTS.type/||;s|\.\(md\|yaml\)$||" | sort +``` + +## Read + +```bash +# Read a specific prompt +cat ~/Code/core/agent/pkg/prompts/lib/$ARGUMENTS.type/$ARGUMENTS.slug.md 2>/dev/null || \ +cat ~/Code/core/agent/pkg/prompts/lib/$ARGUMENTS.type/$ARGUMENTS.slug.yaml 2>/dev/null || \ +echo "Not found: $ARGUMENTS.type/$ARGUMENTS.slug" +``` + +## Quick Reference + +| Type | Path | Examples | +|------|------|----------| +| persona | `lib/persona/` | `secops/developer`, `code/backend-architect`, `smm/tiktok-strategist` | +| task | `lib/task/` | `bug-fix`, `code/review`, `code/refactor`, `new-feature` | +| flow | `lib/flow/` | `go`, `php`, `ts`, `docker`, `release` | +| prompt | `lib/prompt/` | `coding`, `verify`, `conventions`, `security` | diff --git a/claude/core/skills/review-pipeline.md b/claude/core/skills/review-pipeline.md new file mode 100644 index 0000000..cbaa0bc --- /dev/null +++ b/claude/core/skills/review-pipeline.md @@ -0,0 +1,75 @@ +--- +name: review-pipeline +description: Run the multi-stage review pipeline — security, fix, simplify, architecture, verify +arguments: + - name: target + description: Directory or repo to review + default: . + - name: stages + description: Comma-separated stages (security,fix,simplify,architecture,verify) + default: security,fix,simplify,architecture,verify + - name: skip + description: Stages to skip +--- + +# Review Pipeline + +Multi-stage code review with specialist agents at each stage. + +## Stages + +### 1. Security Review +Dispatch agent with `secops/developer` persona: +```bash +cat ~/Code/core/agent/pkg/prompts/lib/persona/secops/developer.md +``` +Task: scan for OWASP top 10, injection, path traversal, race conditions. +Report findings as CRITICAL/HIGH/MEDIUM/LOW with file:line. + +### 2. Fix (conditional) +Only runs if Stage 1 found CRITICAL issues. +Dispatch agent with task from `lib/task/code/review.md`. +Fix ONLY critical findings, nothing else. + +### 3. Simplify +Dispatch code-simplifier agent: +```bash +cat ~/Code/core/agent/claude/core/agents/agent-task-code-simplifier.md +``` +Reduce complexity, remove dead code, improve naming. + +### 4. Architecture Review +Dispatch with `code/backend-architect` persona: +```bash +cat ~/Code/core/agent/pkg/prompts/lib/persona/code/backend-architect.md +``` +Check patterns, dependency direction, lifecycle correctness. + +### 5. Verify +```bash +cd $ARGUMENTS.target +go build ./... 2>&1 +go vet ./... 2>&1 +go test ./... -count=1 -timeout 60s 2>&1 | tail -20 +``` + +## Flow Control + +- If `--skip=fix` → skip Stage 2 +- If Stage 1 has 0 criticals → skip Stage 2 automatically +- If Stage 5 fails → report and stop +- Each stage output feeds into the next as context + +## Output + +```markdown +## Review Pipeline: $ARGUMENTS.target + +| Stage | Status | Findings | +|-------|--------|----------| +| Security | PASS/FAIL | X critical, Y high | +| Fix | APPLIED/SKIPPED | N fixes | +| Simplify | DONE | N changes | +| Architecture | PASS/FAIL | X violations | +| Verify | PASS/FAIL | build + vet + test | +``` diff --git a/cmd/core-agent/main.go b/cmd/core-agent/main.go index 018b58d..726b9a7 100644 --- a/cmd/core-agent/main.go +++ b/cmd/core-agent/main.go @@ -29,9 +29,9 @@ func main() { if err != nil { return nil, nil, cli.Wrap(err, "init core") } - procSvc, err := core.ServiceFor[*process.Service](c, "process") - if err != nil { - return nil, nil, cli.Wrap(err, "get process service") + procSvc, ok := c.Service("process").(*process.Service) + if !ok { + return nil, nil, cli.Wrap(core.E("core-agent", "process service not found", nil), "get process service") } process.SetDefault(procSvc)