Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ Go CLI that keeps skills, MCP servers, hooks, and agent roles in one `~/.agents`
**Full setup** (all harnesses):

```bash
# curl installer (macOS/Linux, no Go required)
curl -fsSL https://raw.githubusercontent.com/yourconscience/dotagents/main/scripts/install.sh | sh
Comment on lines +19 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not advertise no-Go setup path

For users following this new curl path specifically because they do not have Go installed, the next documented step (git clone ... ~/.agents then dotagents setup) still fails: runSetup calls installDotagentsBinary, and for the cloned dotagents source repo that function immediately requires exec.LookPath("go") before syncing. Either setup needs to skip rebuilding when a dotagents binary is already on PATH, or the README should not claim the full setup is "no Go required".

Useful? React with 👍 / 👎.


# or via mise
mise use -g github:yourconscience/dotagents

# or with Go
go install github.com/yourconscience/dotagents/cmd/dotagents@latest
```

Then clone and initialize:

```bash
git clone https://github.com/yourconscience/dotagents ~/.agents
dotagents setup
```
Expand All @@ -38,9 +50,9 @@ Prebuilt binaries for macOS and Linux (amd64/arm64) on [Releases](https://github

## Skills

16 skills ship with this repo:
19 skills ship with this repo:

`spawn` `cmux` `tmux` `remote-access` `repo-eval` `tech-search` `x-sim` `grill-me` `humanizer` `spec` `jobs` `pr-triage` `gws` `tg` `x-cli` `dotagents`
`spawn` `cmux` `tmux` `remote-access` `repo-eval` `review` `tech-search` `x-sim` `grill-me` `humanizer` `spec` `jobs` `pr-triage` `gws` `tg` `x-cli` `spotify` `lila` `dotagents`

A skill is a `SKILL.md` in a directory under `skills/`. Add one, run `dotagents sync`, it shows up everywhere.

Expand Down Expand Up @@ -88,6 +100,6 @@ Private additions go in `dotagents.local.yaml` (gitignored).
| Agent roles | yes | 23 built-in | 20 built-in | no |
| Security audit | yes | no | no | yes |
| Multi-harness | 5 managed + 3 compat | Claude Code | Claude Code | 60+ |
| Install | plugin or `go install` | CC plugin | pipx | `go install` |
| Install | plugin, curl, or `go install` | CC plugin | pipx | `go install` |

gstack and SuperClaude are content packs for Claude Code. skillshare syncs skills broadly but not MCP, hooks, or roles. dotagents is the full config layer across harnesses.
1 change: 0 additions & 1 deletion agents/architect.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: "architect"
description: "Designs system architecture, telemetry schemas, and technical plans. Use for design docs, architecture reviews, and API surface decisions. Delegates implementation to builders."
model: "sonnet"
effort: "high"
tools: Read, Glob, Grep, Bash, Write, Edit
color: "blue"
Expand Down
1 change: 0 additions & 1 deletion agents/architect.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: architect
description: Designs system architecture, telemetry schemas, and technical plans. Use for design docs, architecture reviews, and API surface decisions. Delegates implementation to builders.
model: sonnet
effort: high
tools: [Read, Glob, Grep, Bash, Write, Edit]
color: blue
Expand Down
1 change: 0 additions & 1 deletion agents/builder.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: "builder"
description: "Implements code changes following specs or architect designs. Use for feature implementation, bug fixes, and script writing. Focused on writing correct, minimal code."
model: "sonnet"
effort: "high"
tools: Read, Glob, Grep, Bash, Write, Edit
color: "yellow"
Expand Down
1 change: 0 additions & 1 deletion agents/builder.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: builder
description: Implements code changes following specs or architect designs. Use for feature implementation, bug fixes, and script writing. Focused on writing correct, minimal code.
model: sonnet
effort: high
tools: [Read, Glob, Grep, Bash, Write, Edit]
color: yellow
Expand Down
1 change: 0 additions & 1 deletion agents/researcher.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: "researcher"
description: "Investigates codebases, APIs, repos, and web sources to produce findings reports. Use for technical research, competitive analysis, and feasibility studies."
model: "sonnet"
effort: "high"
tools: Read, Glob, Grep, Bash, WebFetch, WebSearch, Write
color: "green"
Expand Down
1 change: 0 additions & 1 deletion agents/researcher.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: researcher
description: Investigates codebases, APIs, repos, and web sources to produce findings reports. Use for technical research, competitive analysis, and feasibility studies.
model: sonnet
effort: high
tools: [Read, Glob, Grep, Bash, WebFetch, WebSearch, Write]
color: green
Expand Down
1 change: 0 additions & 1 deletion agents/reviewer.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
name: "reviewer"
description: "Reviews code changes, PRs, and implementations against specs and best practices. Use for code review, quality gates, and pre-merge checks. Read-only."
model: "sonnet"
effort: "high"
tools: Read, Glob, Grep, Bash
color: "purple"
Expand Down
1 change: 0 additions & 1 deletion agents/reviewer.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: reviewer
description: Reviews code changes, PRs, and implementations against specs and best practices. Use for code review, quality gates, and pre-merge checks. Read-only.
model: sonnet
effort: high
tools: [Read, Glob, Grep, Bash]
color: purple
Expand Down
22 changes: 22 additions & 0 deletions dotagents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,28 @@ sources:
enabled: true
- name: ra
enabled: false
# external_skills: third-party skill libraries fetched by dotagents sync.
# Entries here are opt-in: uncomment or copy to dotagents.local.yaml to enable.
#
# mattpocock/skills (github.com/mattpocock/skills, MIT)
# Selected skills from skills/engineering/:
# tdd - test-driven development workflow
# diagnosing-bugs - structured bug isolation process
# domain-modeling - domain model design sessions
# grill-with-docs - drill a topic using its own documentation
# Note: handoff (in skills/productivity/) requires a separate entry at the same URL,
# which the current config format does not support. Add it manually if needed by
# pointing skill_dir: skills/productivity with skills: [handoff].
#
# external_skills:
# - url: https://github.com/mattpocock/skills
# branch: main
# skill_dir: skills/engineering
# skills:
# - tdd
# - diagnosing-bugs
# - domain-modeling
# - grill-with-docs
hooks:
- name: memory-session-start
enabled: true
Expand Down
136 changes: 136 additions & 0 deletions plugins/dotagents/skills/review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
name: review
description: Multi-persona code review with structured findings. Use when the user says /review, asks for a code review, wants to review a diff/PR/branch before merging, or needs a pre-submit quality check.
---

# review

Proactive multi-persona code review. Produces structured findings before a PR is submitted or merged.

Not the same as `/pr-triage`, which reacts to existing PR comments and CI failures. Use `/review` when you want fresh review findings on a diff.

## Usage

```
/review # review staged + unstaged changes
/review HEAD~3..HEAD # review last 3 commits
/review main..HEAD # review current branch vs base
/review --fix # review and fix findings (iterative)
/review --persona security # single-persona review
```

## Phase 1: Scope

Determine the diff to review.

If the user provided a range, use it. Otherwise detect:

```bash
# If there are staged/unstaged changes, review those
git diff HEAD

# If clean working tree, review current branch vs default base
BASE="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')"
BASE="${BASE:-main}"
git log --oneline "${BASE}..HEAD"
git diff "${BASE}...HEAD"
```

Identify relevant context files: CONTRIBUTING.md, coding standards, project CLAUDE.md/AGENTS.md, any spec or PRD referenced in recent commit messages.

If the diff is large (>2000 lines), ask the user whether to review everything or focus on specific files/directories.

## Phase 2: Parallel Persona Review

Spawn 2+ reviewer sub-agents in parallel. Each persona writes free-form prose -- do not constrain their output format.

### Default personas

**Standards reviewer:** Does the code follow project conventions? Check naming, error handling patterns, test coverage expectations, import ordering, existing abstractions. Reference CONTRIBUTING.md and project style if available. Ignore style issues that a linter would catch.

**Correctness reviewer:** Are there bugs, edge cases, race conditions, or logic errors? Does the code handle failures correctly? Are there security issues (injection, auth bypass, secret leaks)? Does it do what the commit messages claim?

### Optional personas (user-requested or auto-detected)

**Security reviewer:** Activated when the diff touches auth, crypto, user input handling, or API endpoints. Focus on OWASP top 10, secret leaks, permission checks.

**Performance reviewer:** Activated when the diff touches hot paths, database queries, or algorithms. Focus on complexity, unnecessary allocations, N+1 queries.

Each persona prompt should include:
- The full diff
- Relevant context files (standards, spec)
- Instruction to write freely, be specific (file:line), and focus on what matters

## Phase 3: Normalize Findings

After all persona reviews return, extract structured findings from each persona's prose. Use a separate, cheaper model call for this extraction when possible.

For each finding, extract:

```
File: <path>
Lines: <start>-<end>
Severity: critical | high | medium | low
Confidence: <0.0-1.0>
Problem: <one paragraph -- what is wrong and why it matters>
Fix: <one paragraph -- concrete fix, not "add tests" or "consider refactoring">
```

Normalization rules:
- Do not invent findings that the reviewer did not mention
- Do not fabricate line numbers -- if the reviewer was vague, mark lines as "unknown"
- Vague fix text ("add tests", "consider refactoring", "improve error handling") must be expanded to a concrete action or the finding is downgraded to low severity
- If a reviewer flagged the same issue multiple times, deduplicate

## Phase 4: Aggregate

Combine findings from all personas. Deduplicate findings that reference the same file:line range with overlapping descriptions.

Upgrade severity when multiple personas independently flag the same issue. Downgrade when only one persona flagged it and confidence is below 0.5.

### Output format

```
## Review: <range or description>

### Must Fix (<count>)
Critical severity. Each with file:line, problem, fix.

### Major Issues (<count>)
High severity. Each with file:line, problem, fix.

### Review Carefully (<count>)
Medium severity. Collapsed unless user asks for detail.

### Minor (<count>)
Low severity. One-line summaries only.

### Summary
- Total findings: <N> (<critical> critical, <high> high, <medium> medium, <low> low)
- Personas used: <list>
- Files reviewed: <count>
```

## Phase 5: Fix Loop (only with --fix)

Only runs when the user passes `--fix` or explicitly asks to fix findings.

For each finding rated critical or high with a concrete fix:

1. Apply the fix (use the builder role if available, otherwise fix directly)
2. Run tests or build if available to catch regressions before re-review
3. Re-run the persona that originally flagged the finding on the changed file
3. If the reviewer confirms the fix, mark as resolved
4. If the reviewer finds a new issue with the fix, iterate (max 3 rounds per finding)

After all fixes, re-run all personas on the final diff to catch issues introduced by fixes. The final aggregate uses only fresh findings from this re-run, not stale output from the original review.

## Rules

- Review is read-only by default. Only modify files in `--fix` mode.
- Do not post review comments to GitHub. Output findings to the conversation. The user decides what to do with them.
- When spawning persona sub-agents, use the `reviewer` role if available. Sub-agents inherit the parent model unless the user specifies otherwise.
- If the harness does not support sub-agents, run personas sequentially instead of in parallel.
- Be specific. Every finding must reference a file and ideally a line range. Findings without file references are noise.
- Do not nitpick formatting, whitespace, or style issues that a linter handles. Focus on correctness, security, and spec compliance.
- Large diffs (>5000 lines): warn the user that review quality degrades with size. Suggest splitting by directory or concern.
123 changes: 123 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/bin/sh
# Install dotagents binary from GitHub Releases.
# Usage: curl -fsSL https://raw.githubusercontent.com/yourconscience/dotagents/main/scripts/install.sh | sh

set -e

REPO="yourconscience/dotagents"
BINARY="dotagents"
INSTALL_DIR="${DOTAGENTS_INSTALL_DIR:-$HOME/.local/bin}"

# Detect OS
OS="$(uname -s)"
case "$OS" in
Darwin) OS="darwin" ;;
Linux) OS="linux" ;;
*)
echo "error: unsupported OS: $OS" >&2
exit 1
;;
esac

# Detect arch
ARCH="$(uname -m)"
case "$ARCH" in
x86_64) ARCH="amd64" ;;
arm64|aarch64) ARCH="arm64" ;;
*)
echo "error: unsupported architecture: $ARCH" >&2
exit 1
;;
esac

# Resolve latest release tag
echo "Fetching latest release..."
LATEST_URL="https://api.github.com/repos/${REPO}/releases/latest"
if command -v curl >/dev/null 2>&1; then
TAG="$(curl -fsSL "$LATEST_URL" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
elif command -v wget >/dev/null 2>&1; then
TAG="$(wget -qO- "$LATEST_URL" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
else
echo "error: curl or wget is required" >&2
exit 1
fi

if [ -z "$TAG" ]; then
echo "error: could not determine latest release tag" >&2
exit 1
fi

# Strip leading v for archive filename (goreleaser convention)
VERSION="${TAG#v}"

echo "Installing ${BINARY} ${VERSION} (${OS}/${ARCH})..."

ARCHIVE="${BINARY}_${VERSION}_${OS}_${ARCH}.tar.gz"
BASE_URL="https://github.com/${REPO}/releases/download/${TAG}"
ARCHIVE_URL="${BASE_URL}/${ARCHIVE}"
CHECKSUM_URL="${BASE_URL}/checksums.txt"

# Create temp dir, cleaned up on exit
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

# Download archive and checksums
download() {
url="$1"
dest="$2"
if command -v curl >/dev/null 2>&1; then
curl -fsSL -o "$dest" "$url"
else
wget -qO "$dest" "$url"
fi
}

echo "Downloading ${ARCHIVE}..."
download "$ARCHIVE_URL" "${TMP_DIR}/${ARCHIVE}"

echo "Downloading checksums.txt..."
download "$CHECKSUM_URL" "${TMP_DIR}/checksums.txt"

# Verify checksum
echo "Verifying checksum..."
EXPECTED="$(grep "${ARCHIVE}" "${TMP_DIR}/checksums.txt" | awk '{print $1}')"
if [ -z "$EXPECTED" ]; then
echo "error: archive not found in checksums.txt" >&2
exit 1
elif command -v sha256sum >/dev/null 2>&1; then
ACTUAL="$(sha256sum "${TMP_DIR}/${ARCHIVE}" | awk '{print $1}')"
if [ "$ACTUAL" != "$EXPECTED" ]; then
echo "error: checksum mismatch (expected ${EXPECTED}, got ${ACTUAL})" >&2
exit 1
fi
elif command -v shasum >/dev/null 2>&1; then
ACTUAL="$(shasum -a 256 "${TMP_DIR}/${ARCHIVE}" | awk '{print $1}')"
if [ "$ACTUAL" != "$EXPECTED" ]; then
echo "error: checksum mismatch (expected ${EXPECTED}, got ${ACTUAL})" >&2
exit 1
fi
else
echo "warning: no sha256sum or shasum found; skipping checksum verification" >&2
fi

# Extract binary
echo "Extracting..."
tar -xzf "${TMP_DIR}/${ARCHIVE}" -C "$TMP_DIR"

# Install
mkdir -p "$INSTALL_DIR"
mv "${TMP_DIR}/${BINARY}" "${INSTALL_DIR}/${BINARY}"
chmod +x "${INSTALL_DIR}/${BINARY}"

echo ""
echo "${BINARY} ${VERSION} installed to ${INSTALL_DIR}/${BINARY}"

# PATH hint if needed
case ":$PATH:" in
*":${INSTALL_DIR}:"*) ;;
*)
echo ""
echo "Add ${INSTALL_DIR} to your PATH:"
echo " export PATH=\"${INSTALL_DIR}:\$PATH\""
;;
esac
Loading
Loading