diff --git a/.agents/.dot-agents.json b/.agents/.dot-agents.json deleted file mode 100644 index c4f4f00..0000000 --- a/.agents/.dot-agents.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "upstream": "https://github.com/colmarius/dot-agents", - "ref": "main", - "installedAt": "2026-01-31T12:34:28Z" -} diff --git a/.agents/.gitignore b/.agents/.gitignore index ef2496a..ce68b55 100644 --- a/.agents/.gitignore +++ b/.agents/.gitignore @@ -1,6 +1,7 @@ # External reference repositories cloned for analysis # These are typically large and should not be committed -reference/ +references/* +!references/.gitkeep # Backup directory created during install --force -../.dot-agents-backup/ +.dot-agents-backup/ diff --git a/.agents/plans/TEMPLATE.md b/.agents/plans/TEMPLATE.md deleted file mode 100644 index 12dfc70..0000000 --- a/.agents/plans/TEMPLATE.md +++ /dev/null @@ -1,39 +0,0 @@ -# Plan: [Feature Name] - -| Field | Value | -|-------|-------| -| PRD | `../../prds/[prd-name].md` or N/A | -| Research | `../../research/[topic].md` or N/A | -| Status | todo | -| Created | YYYY-MM-DD | - -## Overview - -[Brief description of what this plan implements and why.] - -## Tasks - -- [ ] **Task 1: [Short descriptive title]** - - Scope: `path/to/affected/files` or module name - - Depends on: none - - Acceptance: - - Specific, verifiable criterion 1 - - Specific, verifiable criterion 2 - - Notes: Optional implementation hints - -- [ ] **Task 2: [Short descriptive title]** - - Scope: `path/to/affected/files` - - Depends on: Task 1 - - Acceptance: - - Specific, verifiable criterion - - Notes: Optional notes - -## Verification - -After all tasks complete, run: - -```bash -# Add project-specific verification commands -``` - -All checks must pass before marking plan complete. diff --git a/.agents/plans/completed/.gitkeep b/.agents/plans/completed/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/.agents/plans/in-progress/.gitkeep b/.agents/plans/in-progress/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/.agents/plans/todo/.gitkeep b/.agents/plans/todo/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/.agents/plans/todo/documentation-troubleshooting.md b/.agents/plans/todo/documentation-troubleshooting.md deleted file mode 100644 index 786d59e..0000000 --- a/.agents/plans/todo/documentation-troubleshooting.md +++ /dev/null @@ -1,99 +0,0 @@ -# Plan: Troubleshooting Documentation - -| Field | Value | -|-------|-------| -| PRD | N/A | -| Research | `../../research/documentation-troubleshooting.md` | -| Status | todo | -| Created | 2026-02-03 | - -## Overview - -Create a dedicated troubleshooting guide covering common issues from CHANGELOG and anticipated user problems, making solutions easily discoverable. - -## Tasks - -- [ ] **Task 1: Create docs/troubleshooting.md with installation issues** - - Scope: `docs/troubleshooting.md` - - Depends on: none - - Acceptance: - - File exists at docs/troubleshooting.md - - Has "Installation Issues" section - - Documents "BASH_SOURCE[0]: unbound variable" fix - - Documents bash 5.3+ script exit issue - - Each issue has: symptoms, cause, solution - - Notes: Issues from CHANGELOG commits 455019a and 4d97cce - -- [ ] **Task 2: Add skill issues section to troubleshooting** - - Scope: `docs/troubleshooting.md` - - Depends on: Task 1 - - Acceptance: - - "Skill Issues" section exists - - Documents "skill not loading" with checks - - Documents "custom skill not found" with SKILL.md format requirements - - Solutions include directory verification steps - - Notes: Common anticipated issues - -- [ ] **Task 3: Add sync issues section to troubleshooting** - - Scope: `docs/troubleshooting.md` - - Depends on: Task 1 - - Acceptance: - - "Sync Issues" section exists - - Documents "sync overwrote my changes" with backup locations - - Documents "sync reports conflicts" with --dry-run and --force options - - Clarifies what is/isn't overwritten - - Notes: Sync behavior is confusing for users - -- [ ] **Task 4: Add Ralph issues section to troubleshooting** - - Scope: `docs/troubleshooting.md` - - Depends on: Task 1 - - Acceptance: - - "Ralph Issues" section exists - - Documents "Ralph not finding tasks" with checklist - - Documents "Ralph stops unexpectedly" with context/blocking explanations - - Includes resume command example - - Notes: Ralph issues are common for new users - -- [ ] **Task 5: Add permission issues and getting help sections** - - Scope: `docs/troubleshooting.md` - - Depends on: Task 1 - - Acceptance: - - "Permission Issues" section with chmod fix - - "Getting Help" section with GitHub Issues link - - Link to CHANGELOG for known fixes - - Notes: Complete the troubleshooting guide - -- [ ] **Task 6: Add quick troubleshooting reference to QUICKSTART.md** - - Scope: `QUICKSTART.md` - - Depends on: Task 5 - - Acceptance: - - "Troubleshooting" section at end of QUICKSTART - - Table with 3-4 common problems and quick fixes - - Links to docs/troubleshooting.md for details - - Notes: Keep brief, just top issues - -- [ ] **Task 7: Link troubleshooting from docs/index.html** - - Scope: `docs/index.html` - - Depends on: Task 5 - - Acceptance: - - Link to troubleshooting.md on GitHub - - Placed in footer or support section - - Notes: Helps users find help from landing page - -## Verification - -After all tasks complete: - -```bash -# Verify troubleshooting.md exists with all sections -test -f docs/troubleshooting.md -grep -q "Installation Issues" docs/troubleshooting.md -grep -q "Skill Issues" docs/troubleshooting.md -grep -q "Sync Issues" docs/troubleshooting.md -grep -q "Ralph Issues" docs/troubleshooting.md - -# Verify QUICKSTART links to troubleshooting -grep -q "troubleshooting" QUICKSTART.md -``` - -All checks must pass before marking plan complete. diff --git a/.agents/prds/AGENTS.md b/.agents/prds/AGENTS.md deleted file mode 100644 index 91a2997..0000000 --- a/.agents/prds/AGENTS.md +++ /dev/null @@ -1,39 +0,0 @@ -# PRD Guidelines - -Lightweight product requirements for solo development with AI agent execution. - -## Workflow - -```text -Research → PRD → Plan → Ralph executes -``` - -1. **Draft PRD** (15-30 min timebox) — use TEMPLATE.md -2. **Generate plan** — create `.agents/plans/todo/PLAN-XXX.md` with Ralph task format -3. **Execute** — ralph runs the plan -4. **Close** — update PRD status, move plan to completed - -## Rules - -- Keep PRD under 1 page (~400-700 words) -- Timebox to 30 minutes max -- Acceptance criteria must be testable -- Always include non-goals -- Link PRD ↔ Plan bidirectionally - -## PRD vs Plan - -| PRD | Plan | -|-----|------| -| Why / What | How / Tasks | -| Stable context | Execution checklist | -| Problem + goals | File scopes + acceptance | - -## Naming - -```text -PRD-YYYYMMDD-short-title.md -PLAN-YYYYMMDD-short-title.md -``` - -Keep titles aligned between PRD and Plan. diff --git a/.agents/prds/TEMPLATE.md b/.agents/prds/TEMPLATE.md deleted file mode 100644 index bb7ae6b..0000000 --- a/.agents/prds/TEMPLATE.md +++ /dev/null @@ -1,45 +0,0 @@ -# PRD: - -| Field | Value | -|-------|-------| -| Status | draft / ready / in-progress / done | -| Date | YYYY-MM-DD | -| Plan | `../plans/todo/PLAN-XXX.md` | - -## Problem - -What user pain or product gap? (2-4 sentences) - -## Goal - -One sentence describing success. - -## Non-goals - -- What we will NOT do - -## Users / Use case - -- Who uses it + primary scenario - -## Proposed change - -What changes? (bullets, no implementation detail) - -## Acceptance criteria - -- [ ] Testable outcome 1 -- [ ] Testable outcome 2 - -## UX notes - -Optional: sketches, screen states, interactions - -## Open questions / Risks - -- Unanswered questions -- Known risks - -## Research - -- `../research/doc.md` — key takeaway diff --git a/.agents/reference/.gitkeep b/.agents/reference/.gitkeep deleted file mode 100644 index 8b13789..0000000 --- a/.agents/reference/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/.agents/references/.gitkeep b/.agents/references/.gitkeep new file mode 100644 index 0000000..8000e38 --- /dev/null +++ b/.agents/references/.gitkeep @@ -0,0 +1 @@ +# Keep .agents/references/ present on fresh installs. diff --git a/.agents/scripts/sync.sh b/.agents/scripts/sync.sh index 7fcdaef..bcef7cf 100755 --- a/.agents/scripts/sync.sh +++ b/.agents/scripts/sync.sh @@ -54,7 +54,9 @@ All options are passed through to the upstream install.sh script. Options: --dry-run Show what would happen without making changes + --diff Preview pending changes without writing; exit 1 if pending --force Overwrite conflicts (creates backup first) + --write-conflicts Create file.dot-agents.md/file.ext.dot-agents.new conflicts --interactive Prompt for each conflict --yes Skip confirmation prompts --version Show version and installation info @@ -62,7 +64,7 @@ Options: Examples: # Preview changes - .agents/scripts/sync.sh --dry-run + .agents/scripts/sync.sh --diff # Force update with backup .agents/scripts/sync.sh --force diff --git a/.agents/skills/AGENTS.md b/.agents/skills/AGENTS.md index 04e2f91..55305db 100644 --- a/.agents/skills/AGENTS.md +++ b/.agents/skills/AGENTS.md @@ -48,6 +48,8 @@ The description determines when the skill gets loaded: 3. **Define workflows** - Step-by-step processes work best 4. **Add checklists** - Help ensure nothing is missed 5. **Reference patterns** - Point to existing code/files +6. **Keep workflow skills durable** - Put reusable templates in `assets/` and runnable helpers in `scripts/` +7. **Avoid runner-specific concepts** - Prefer work items and handoff prompts over assuming a specific agent runtime ## Testing Skills @@ -63,6 +65,7 @@ Verify your skill by loading it and checking: | Skill | Purpose | | ----- | ------- | | `adapt` | Analyze project and fill in AGENTS.md after installation | -| `ralph` | Autonomous multi-iteration implementation using handoff loops | -| `research` | Deep research on technical topics, saves to `.agents/research/` | +| `agent-work` | Create and maintain `.agents/work/` work items | +| `feature-planning` | Turn context into plans and paste-ready handoff prompts | +| `research` | Research technical topics, saving work-local or reusable findings | | `tmux` | Manage background processes using tmux windows for servers and long-running tasks | diff --git a/.agents/skills/adapt/SKILL.md b/.agents/skills/adapt/SKILL.md index 9202b42..ee2d113 100644 --- a/.agents/skills/adapt/SKILL.md +++ b/.agents/skills/adapt/SKILL.md @@ -1,6 +1,6 @@ --- name: adapt -description: "Analyze project and fill in AGENTS.md. Use when adapting dot-agents to a new project, after initial installation." +description: "Analyzes a project and fills in AGENTS.md. Use after installing dot-agents or when project commands and conventions change. Triggers on: adapt, setup AGENTS, customize AGENTS." --- # Adapt Skill @@ -28,12 +28,13 @@ Run this skill after installing dot-agents into a new project to customize the c - List detected tech stack - Extract commands from package.json scripts, Cargo.toml, Makefile, etc. - Note any project-specific conventions observed + - Keep the `.agents/work/` and handoff-prompt workflow guidance intact ## Example Output After running, AGENTS.md should have these sections filled in: -```markdown +````markdown ## Overview my-awesome-app - A Next.js web application with PostgreSQL backend @@ -72,6 +73,13 @@ pnpm format - Components in src/components/ - API routes in src/app/api/ +## Agent Work + +- Durable work lives in `.agents/work///` +- Use `.agents/research/` only for reusable findings +- Ask for a handoff prompt before starting a fresh implementation thread +```` + ## Checklist - [ ] Read package.json/Cargo.toml/go.mod for project name and scripts @@ -80,3 +88,4 @@ pnpm format - [ ] Check for Makefile, Justfile, or task runners - [ ] Look for .eslintrc, .prettierrc, rustfmt.toml for style configs - [ ] Update AGENTS.md with findings +- [ ] Preserve the dot-agents work-item workflow unless the user asks for a custom one diff --git a/.agents/skills/agent-work/SKILL.md b/.agents/skills/agent-work/SKILL.md new file mode 100644 index 0000000..c3b0e57 --- /dev/null +++ b/.agents/skills/agent-work/SKILL.md @@ -0,0 +1,100 @@ +--- +name: agent-work +description: "Creates and curates .agents/work/ work items. Use for durable indexes, artifacts, progress, migration, and new-thread handoffs. Triggers on: work item, agent work, new work item, list active work, handoff prompt." +--- + +# Agent Work + +Create and maintain work items under `.agents/work///` so context, plans, progress, decisions, and handoff prompts stay together for one piece of multi-session work. + +A "work item" is a folder; entries inside `plan.md` or focused files under `plans/` are the executable tasks. + +## Workflow + +1. **Check existing context** + - Run `.agents/skills/agent-work/scripts/list-work.sh --all` or search `.agents/work/` before creating a new work item. + - Read a work item's `index.md` first when continuing existing work. +2. **Create the work item** + - Run `.agents/skills/agent-work/scripts/new-work.sh --category --slug --title ""` from the repo root. + - Create only `index.md` at first; do not add empty support folders. +3. **Place artifacts deliberately** + - Use `research.md` for findings specific to this work item. + - Use `research/` for multiple focused research notes specific to this work item. + - Use `.agents/research/` for reusable cross-work findings. + - Use `prd.md` as a short requirements brief only when alignment is needed. + - Use `plan.md` for the primary implementation-ready task plan; copy `.agents/skills/agent-work/assets/plan-template.md` as a starting point. + - Use `plans/` for multiple focused implementation plans when one plan file would be too large or when separate phases need independent handoffs. + - Use `progress.md` for implementation notes, verification results, blockers, and next action. + - Add `decisions/` only when durable decision records are worth linking. +4. **Keep `index.md` current** + - Update `Status:`, `Updated:`, `Artifacts`, `Next Action`, and material `Open Questions` as the work item evolves. + - When `plans/` exists, point `index.md` and handoff prompts to the active plan file. + - Keep status in `index.md`; do not move work folders between status directories. +5. **Prepare handoffs when needed** + - Use `feature-planning` to refine a stale or ambiguous plan. + - Ask for a paste-ready handoff prompt before starting a new implementation thread. + - A good handoff prompt names the work item path, active plan slice, scope limits, expected artifact updates, verification, stop conditions, and expected final response. + +## Paths And Statuses + +- Canonical path: `.agents/work///` +- Category values: `feature`, `bugfix`, `tech-debt`, `docs`, `tooling`, `research`, `other` +- Categories are intentionally closed; use `other` when none fit. +- Required file: `index.md` +- Status values: `researching`, `planned`, `in-progress`, `blocked`, `completed` +- Optional files: `research.md`, `prd.md`, `plan.md`, `progress.md` +- Optional folders: `research/`, `plans/`, `decisions/` + +Status meanings: + +- `researching`: context exists, but no implementation-ready plan exists yet. +- `planned`: `plan.md` or `plans/.md` exists and is ready for a handoff prompt or implementation. +- `in-progress`: implementation has started. +- `blocked`: progress needs input, access, or plan changes before continuing. +- `completed`: implementation and verification are done. + +See `.agents/work/AGENTS.md` for conventions automatically applied inside work items. + +## Scripts + +Run commands from the repository root. + +```bash +.agents/skills/agent-work/scripts/new-work.sh \ + --category feature \ + --slug user-authentication \ + --title "User authentication" +``` + +```bash +.agents/skills/agent-work/scripts/list-work.sh +.agents/skills/agent-work/scripts/list-work.sh --all +.agents/skills/agent-work/scripts/list-work.sh --status blocked +``` + +## Legacy Plans + +Existing legacy `.agents/plans/` and `.agents/prds/` documents are user content. Do not auto-migrate or delete them. + +When the user asks to migrate one legacy plan: + +1. Create `.agents/work///index.md`. +2. Copy the old plan to `plan.md`, preserving task checkboxes. +3. Copy a matching progress file to `progress.md` if it exists. +4. Copy or summarize a linked PRD into `prd.md` if still relevant. +5. Update `index.md` with status, artifacts, next action, and open questions. +6. Leave legacy files in place unless the user explicitly asks to delete them. + +Full upstream guide: [migration-v0.3](https://github.com/colmarius/dot-agents/blob/main/docs/migration-v0.3.md). + +## Templates + +- `assets/work-index-template.md`: starting point for `index.md` +- `assets/plan-template.md`: implementation-ready `plan.md` contract +- `assets/prd-template.md`: optional requirements brief (`prd.md`) structure +- `assets/work-decision-template.md`: optional decision record template + +## Verification + +- Confirm new work items contain `index.md` and no empty support folders. +- Run `.agents/skills/agent-work/scripts/list-work.sh --all` and confirm the work item appears with the expected status. diff --git a/.agents/skills/agent-work/assets/plan-template.md b/.agents/skills/agent-work/assets/plan-template.md new file mode 100644 index 0000000..6b2f80b --- /dev/null +++ b/.agents/skills/agent-work/assets/plan-template.md @@ -0,0 +1,86 @@ +# Plan Template + +Use this template when creating `.agents/work///plan.md` or a focused plan under `.agents/work///plans/.md`. Plans following this format are implementation-ready and easy to hand off to a fresh agent thread. + +## Template + +```markdown +# [Plan Title] + +[Brief description of what this plan accomplishes.] + +## Goals + +- Goal 1 +- Goal 2 + +## Tasks + +- [ ] **Task 1: Short descriptive title** + - Scope: `path/to/affected/files` or module name + - Depends on: none + - Acceptance: + - Specific, verifiable criterion 1 + - Specific, verifiable criterion 2 + - Notes: Optional implementation hints + +- [ ] **Task 2: Another task title** + - Scope: `path/to/affected/files` + - Depends on: Task 1 + - Acceptance: + - Specific, verifiable criterion + - Notes: None + +## Implementation Notes + +[Key principles, pitfalls to avoid, testing strategy, and scope limits.] + +## Constraints / Decisions + +- Constraint or decision 1 +- Constraint or decision 2 + +## Acceptance Criteria + +- Overall criterion 1 +- Overall criterion 2 + +## Verification + +- Command or manual check 1 +- Command or manual check 2 +``` + +## Task Format Rules + +Each task must include: + +| Field | Required | Description | +| --- | --- | --- | +| **Title** | Yes | `**Task N: Short descriptive title**` | +| **Scope** | Yes | File path, module, package, or subsystem affected | +| **Depends on** | Yes | Task ID or `none` | +| **Acceptance** | Yes | Specific, verifiable criteria | +| **Notes** | No | Implementation hints, commands, or risks | + +Split a task if it cannot be described in 2-3 sentences or cannot be reviewed independently. + +## Task Status Markers + +| Marker | Meaning | +| --- | --- | +| `- [ ]` | Not started | +| `- [x]` | Completed | +| `- [ ] (blocked)` | Blocked, needs intervention | +| `- [ ] (manual-verify)` | Requires manual verification | + +## Handoff-Ready Checklist + +Before asking for an implementation handoff prompt, confirm: + +- [ ] The plan lives at `.agents/work///plan.md` or `.agents/work///plans/.md`. +- [ ] `index.md` links the active plan file and has the correct `Status:`. +- [ ] Every task has `Scope`, `Depends on`, and verifiable `Acceptance`. +- [ ] The next task or phase is clear. +- [ ] External blockers and human-only steps are explicit. +- [ ] The intended verification commands are named when not obvious. diff --git a/.agents/skills/agent-work/assets/prd-template.md b/.agents/skills/agent-work/assets/prd-template.md new file mode 100644 index 0000000..a93b955 --- /dev/null +++ b/.agents/skills/agent-work/assets/prd-template.md @@ -0,0 +1,61 @@ +# Requirements Brief Template + +Use this template only when work needs durable requirements alignment before planning. For small, scoped changes with clear behavior and acceptance criteria, create `plan.md` directly instead. + +Keep this brief. If technical discovery dominates, use `research.md` instead. + +## Template + +```markdown +# [Work Item] Requirements Brief + +## Problem + +What problem are we solving? Why now? + +## Desired Outcome + +What should be true when this is done? + +## Goals + +- Goal 1 +- Goal 2 + +## Non-Goals + +- What we are explicitly not doing + +## Users / Use Cases + +- Primary user or system actor and scenario + +## Requirements + +### Must Have + +- [ ] Requirement 1 +- [ ] Requirement 2 + +### Optional + +- [ ] Optional requirement + +## Constraints / Decisions + +- Constraint or decision 1 +- Constraint or decision 2 + +## Acceptance Criteria + +- Criterion 1 +- Criterion 2 + +## Open Questions + +- [ ] Question that materially affects scope, sequence, or architecture +``` + +## Handoff To Planning + +Once the brief is aligned, create `plan.md` in the same work item using the [agent-work plan template](plan-template.md). Do not create new `.agents/plans/` files. diff --git a/.agents/skills/agent-work/assets/work-decision-template.md b/.agents/skills/agent-work/assets/work-decision-template.md new file mode 100644 index 0000000..2ba0ba2 --- /dev/null +++ b/.agents/skills/agent-work/assets/work-decision-template.md @@ -0,0 +1,26 @@ +# Decision: [Short Title] + +Date: YYYY-MM-DD +Status: proposed | accepted | superseded + +## Context + +[What forced this decision? Link work item artifacts and evidence.] + +## Decision + +[What are we doing?] + +## Rationale + +[Why this option over alternatives?] + +## Consequences + +- Positive consequence +- Trade-off or risk + +## Links + +- Work item: `../index.md` +- Related plan/research/PRD: `../plan.md` diff --git a/.agents/skills/agent-work/assets/work-index-template.md b/.agents/skills/agent-work/assets/work-index-template.md new file mode 100644 index 0000000..68d297b --- /dev/null +++ b/.agents/skills/agent-work/assets/work-index-template.md @@ -0,0 +1,25 @@ +# {{TITLE}} + +Status: {{STATUS}} +Category: {{CATEGORY}} +Updated: {{UPDATED}} + +## Summary + +[2-4 sentences describing the work item and why it exists.] + +## Artifacts + +- Research: none +- PRD: none +- Plan: none +- Progress: none +- Decisions: none + +## Next Action + +- [The next concrete action for a future agent thread.] + +## Open Questions + +- [ ] [Only questions that materially affect scope, sequence, or architecture.] diff --git a/.agents/skills/agent-work/scripts/list-work.sh b/.agents/skills/agent-work/scripts/list-work.sh new file mode 100755 index 0000000..3a11b7e --- /dev/null +++ b/.agents/skills/agent-work/scripts/list-work.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'USAGE' +Usage: + list-work.sh [--all] [--status ] + +Lists agent work items from .agents/work/. By default, completed work items are hidden. +USAGE +} + +show_all=0 +status_filter="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --all) + show_all=1 + shift + ;; + --status) + status_filter="${2:-}" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage >&2 + exit 2 + ;; + esac +done + +if [[ ! -d .agents/work ]]; then + exit 0 +fi + +printf '%-12s %-14s %-12s %s\n' "Status" "Category" "Updated" "Work Item" +printf '%-12s %-14s %-12s %s\n' "------------" "--------------" "------------" "---------" + +find .agents/work -mindepth 3 -maxdepth 3 -name index.md -type f | sort | while IFS= read -r index_file; do + title=$(sed -n '1s/^# //p' "$index_file") + status=$(sed -n 's/^Status: //p' "$index_file" | head -1) + category=$(sed -n 's/^Category: //p' "$index_file" | head -1) + updated=$(sed -n 's/^Updated: //p' "$index_file" | head -1) + + [[ -n "$status" ]] || status="unknown" + [[ -n "$category" ]] || category="unknown" + [[ -n "$updated" ]] || updated="unknown" + [[ -n "$title" ]] || title="$(basename "$(dirname "$index_file")")" + + if [[ -n "$status_filter" && "$status" != "$status_filter" ]]; then + continue + fi + + if [[ "$show_all" -eq 0 && "$status" == "completed" ]]; then + continue + fi + + printf '%-12s %-14s %-12s %s (%s)\n' "$status" "$category" "$updated" "$title" "$index_file" +done diff --git a/.agents/skills/agent-work/scripts/new-work.sh b/.agents/skills/agent-work/scripts/new-work.sh new file mode 100755 index 0000000..c2059c0 --- /dev/null +++ b/.agents/skills/agent-work/scripts/new-work.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'USAGE' +Usage: + new-work.sh --category --slug --title [--status <status>] + +Creates .agents/work/<category>/<work-slug>/index.md from the work index template. +Default status: researching +Categories: feature, bugfix, tech-debt, docs, tooling, research, other +USAGE +} + +category="" +slug="" +title="" +status="researching" + +while [[ $# -gt 0 ]]; do + case "$1" in + --category) + category="${2:-}" + shift 2 + ;; + --slug) + slug="${2:-}" + shift 2 + ;; + --title) + title="${2:-}" + shift 2 + ;; + --status) + status="${2:-}" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage >&2 + exit 2 + ;; + esac +done + +if [[ -z "$category" || -z "$slug" || -z "$title" ]]; then + usage >&2 + exit 2 +fi + +case "$status" in + researching|planned|in-progress|blocked|completed) ;; + *) + echo "Invalid status: $status" >&2 + echo "Expected one of: researching, planned, in-progress, blocked, completed" >&2 + exit 2 + ;; +esac + +is_kebab_case() { + [[ "$1" =~ ^[abcdefghijklmnopqrstuvwxyz0123456789]+(-[abcdefghijklmnopqrstuvwxyz0123456789]+)*$ ]] +} + +if ! is_kebab_case "$category"; then + echo "Invalid category: $category" >&2 + echo "Expected one of: feature, bugfix, tech-debt, docs, tooling, research, other" >&2 + exit 2 +fi + +case "$category" in + feature|bugfix|tech-debt|docs|tooling|research|other) ;; + *) + echo "Invalid category: $category" >&2 + echo "Expected one of: feature, bugfix, tech-debt, docs, tooling, research, other" >&2 + exit 2 + ;; +esac + +if ! is_kebab_case "$slug"; then + echo "Invalid slug: $slug" >&2 + echo "Use lowercase kebab-case." >&2 + exit 2 +fi + +work_dir=".agents/work/$category/$slug" +index_file="$work_dir/index.md" +template=".agents/skills/agent-work/assets/work-index-template.md" + +if [[ -e "$index_file" ]]; then + echo "Work item index already exists: $index_file" >&2 + exit 1 +fi + +if [[ ! -f "$template" ]]; then + echo "Missing template: $template" >&2 + exit 1 +fi + +mkdir -p "$work_dir" + +escape_sed_replacement() { + printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g' +} + +escaped_title=$(escape_sed_replacement "$title") +escaped_category=$(escape_sed_replacement "$category") +escaped_status=$(escape_sed_replacement "$status") +updated=$(date +%F) + +sed \ + -e "s|{{TITLE}}|$escaped_title|g" \ + -e "s|{{STATUS}}|$escaped_status|g" \ + -e "s|{{CATEGORY}}|$escaped_category|g" \ + -e "s|{{UPDATED}}|$updated|g" \ + "$template" > "$index_file" + +echo "$index_file" diff --git a/.agents/skills/feature-planning/SKILL.md b/.agents/skills/feature-planning/SKILL.md new file mode 100644 index 0000000..bee0384 --- /dev/null +++ b/.agents/skills/feature-planning/SKILL.md @@ -0,0 +1,146 @@ +--- +name: feature-planning +description: "Turns work-item context into plans and paste-ready handoff prompts. Use for planning, requirements briefs, plan refinement, and new-thread prompts. Triggers on: plan, requirements, PRD, feature planning, handoff prompt." +--- + +# Feature Planning + +Manage work-item planning from rough intent through optional context, implementation-ready plan, and paste-ready prompt for a fresh implementation thread. + +## Workflow Overview + +```text +Work Item → Context as needed → Plan → Refine → Handoff Prompt → Implement → Record Progress +``` + +1. **Work item**: Use `agent-work` to create or locate `.agents/work/<category>/<work-slug>/`. +2. **Context**: Add `research.md` for technical facts, `research/` for multiple focused notes, or `prd.md` as a short requirements brief only when needed. +3. **Plan**: Create or update the active plan file (`plan.md` by default, or `plans/<name>.md` for focused plans) with scoped tasks, dependencies, and acceptance criteria. +4. **Refine**: Validate assumptions against current repo reality before implementation. +5. **Handoff prompt**: Produce a paste-ready prompt for the next implementation thread. +6. **Progress**: The implementation thread updates active plan task checkboxes, `progress.md`, and `index.md`. + +## Plan Locations + +New plans live inside work items: + +```text +.agents/work/<category>/<work-slug>/ +├── index.md +├── research.md +├── research/ +├── prd.md +├── plan.md +├── plans/ +├── progress.md +└── decisions/ +``` + +Legacy standalone plan and PRD documents are user content. Migrate one at a time into `.agents/work/` only when requested. Retired Ralph guidance/templates may be backed up and removed by sync. + +## Requirements Brief Guidance + +Most work does not need a PRD. Create `prd.md` only when the missing context is requirements alignment: users, behavior, goals, non-goals, acceptance, rollout, or stakeholder decisions. Use the [agent-work requirements brief template](../agent-work/assets/prd-template.md). + +Use `research.md` or `research/` for technical discovery. If acceptance criteria fit naturally in the active plan file, skip `prd.md`. + +## Plan Guidance + +Use the [agent-work plan template](../agent-work/assets/plan-template.md). Keep plans implementation-ready: + +- Each task has `Scope`, `Depends on`, and verifiable `Acceptance`. +- The next task or phase is obvious. +- Scope limits and verification commands are explicit when not obvious. +- Blockers, manual steps, and risky assumptions are called out. +- Tasks are small enough to review independently. + +For larger work, prefer an early thin slice that proves the end-to-end path before broad hardening. + +## Pre-Implementation Refinement + +Use this before writing a handoff prompt when work is multi-phase, ambiguous, or stale. + +1. Read the work item's `index.md` and active plan file (`plan.md` or `plans/<name>.md` as linked from `index.md`). +2. Read relevant `research.md`, requirements brief (`prd.md`), and decisions only as needed. +3. Validate key assumptions against current code, dependencies, and test setup. +4. Resolve material open questions with repo evidence where possible; ask the user only for decisions the repo cannot answer. +5. If a planned task is already satisfied, record evidence and update the active plan file instead of creating no-op work. +6. Update the active plan file, `progress.md`, and `index.md` when refinement changes the next action or known constraints. + +Skip the full pass for small, obvious changes where the plan and repo state are already aligned. + +## New-Thread Handoff Prompt + +Use this mode when asked to write a prompt for a new thread, implementation handoff, or continuation. Produce a paste-ready prompt; do not implement the work yourself unless the user explicitly asks. + +The prompt should include: + +1. Work item path. +2. Files to read first. +3. Goal and current state. +4. Exact task, phase, or slice to implement. +5. Scope limits and non-goals. +6. Artifact update contract for the active plan file, `progress.md`, and `index.md`. +7. Verification commands or manual checks. +8. Stop conditions. +9. Expected final response format. + +Use this template: + +```text +You are continuing the work item at: + +.agents/work/<category>/<slug>/ + +Read first: +1. .agents/work/<category>/<slug>/index.md +2. <active plan file linked from index.md: .agents/work/<category>/<slug>/plan.md or .agents/work/<category>/<slug>/plans/<name>.md> +3. Relevant artifacts linked from index.md + +Goal: +<one-paragraph goal> + +Current state: +<what is already done, plus branch/commit/thread anchors if useful> + +Implement only this slice: +- <Task N / phase / exact acceptance criteria> + +Scope limits: +- Touch only <paths/modules> unless the plan proves the scope is wrong. +- Do not broaden the feature. +- If the plan is stale, update the plan and explain why before implementing. + +Progress contract: +- Update completed task checkboxes in the active plan file. +- Append or update progress.md with changes, verification, blockers, and next action. +- Update index.md Status, Updated, Artifacts, and Next Action when they change. + +Verification: +- Run <commands>. +- If verification cannot run, record why and what remains unverified. + +Stop conditions: +- Stop and report if blocked by missing decisions, credentials, unsafe migrations, unrelated failing tests, or scope expansion. + +Expected final response: +- Summary of changes +- Files changed +- Verification results +- Work item updates made +- Remaining next action +``` + +## Stress-Test Mode + +Use this only when the user explicitly asks to stress-test, grill, or walk decision branches. + +1. Inspect the existing PRD, plan, repo docs, and relevant code first. +2. Ask one highest-leverage unresolved question at a time. +3. Provide a recommended default answer and brief rationale for each question. +4. Capture outcomes in `prd.md`, the active plan file, or `index.md`. +5. Exit once remaining ambiguity no longer materially changes scope, sequencing, or architecture. + +## Definition Of Done + +Planning is done when the work item has a current `index.md`, required context artifacts, an implementation-ready active plan file, and either a clear next action or a paste-ready handoff prompt. diff --git a/.agents/skills/ralph/SKILL.md b/.agents/skills/ralph/SKILL.md deleted file mode 100644 index 88804fb..0000000 --- a/.agents/skills/ralph/SKILL.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -name: ralph -description: Autonomous multi-iteration feature implementation using handoff loops. Use when asked to "run ralph", "execute autonomously", "implement this plan autonomously", or for hands-free feature development from structured plans. ---- - -# Ralph Autonomous Agent - -Orchestrates autonomous code generation through repeated iterations using fresh agent instances until all tasks are complete. - -## Execution Contract - -### Inputs - -When invoking ralph, provide: - -- **Plan file path**: Absolute or workspace-relative path to the plan markdown file -- **Starting task** (optional): Task ID to resume from (e.g., "Task 3") -- **Max tasks** (optional): Maximum tasks to complete before pausing for review (default: 5) - -### State Files - -Ralph creates a companion progress file alongside the plan: - -```text -.agents/plans/in-progress/ -├── my-feature.md # The plan -└── my-feature.progress.md # Progress log (auto-created) -``` - -### Task Status Markers - -In plan files, tasks use checkbox status with optional annotations: - -| Marker | Meaning | -|--------|---------| -| `- [ ]` | Not started | -| `- [x]` | Completed | -| `- [ ] (blocked)` | Blocked, needs intervention | -| `- [ ] (manual-verify)` | Requires manual verification | - -### Stop Conditions - -The loop exits when ANY of these occur: - -1. **All tasks complete**: Every task checkbox is `[x]` -2. **Max tasks reached**: Completed N tasks this session (default: 5) — pause for user review -3. **Blocked encountered**: A task is marked `(blocked)` -4. **Only manual-verify remaining**: All incomplete tasks require manual verification -5. **Explicit stop**: User interrupts - -### Handoff Payload - -When handing off to fresh iteration, include: - -```text -Continue ralph execution for: [plan file path] - -Current task: [Task ID and title] -Tasks completed this session: [N of max_tasks] -Last progress: [Most recent progress entry summary] -Next action: [Specific next step] - -Load the ralph skill and continue execution. -``` - -### Pause for Review - -When max tasks is reached (before all tasks complete): - -1. **Update progress file**: Log "Paused after N tasks for review" -2. **Commit all work**: Ensure all completed tasks are committed -3. **Report to user**: List completed tasks and next task to resume from -4. **Do NOT handoff**: Wait for user to review and continue - -**Resume command:** - -```text -Continue ralph from Task X on [plan file path] -``` - -## Phases - -### Phase 1: Setup - -Before running the loop, ensure the plan has proper structure. - -**Required task format:** - -```markdown -- [ ] **Task N: Short descriptive title** - - Scope: `path/to/affected/files` or package name - - Depends on: Task M (or "none") - - Acceptance: - - Specific criterion 1 - - Specific criterion 2 - - Notes: Optional implementation hints -``` - -**Task sizing rule:** If you can't describe the task in 2-3 sentences, it's too big. Split it. - -**Dependency ordering:** Schema → Service → API → UI → Tests - -### Phase 2: Execution Loop - -Each iteration follows this workflow: - -1. **Load context**: Read plan file, identify next incomplete task, track tasks completed this session -2. **Check dependencies**: Ensure all `Depends on` tasks are complete -3. **Implement**: Complete the task following its scope and acceptance criteria -4. **Verify**: Run verification commands (see Verification section) -5. **Update progress**: Append entry to `.progress.md` -6. **Update plan**: Check off completed task `[x]` -7. **Commit**: One task = one commit with proper footers -8. **Increment counter**: tasks_completed++ -9. **Check stop conditions**: - - If tasks_completed >= max_tasks → pause for review (do NOT handoff) - - If all tasks complete → exit with success - - Otherwise → handoff to next iteration - -**Git discipline:** - -- One task = one commit -- Never push to main branch -- Include footers: `Amp-Thread-ID` and `Co-authored-by: Amp <amp@ampcode.com>` -- Commit format: `feat: [Task ID] - [Task Title]` - -## Verification Strategy - -Run verification commands appropriate for the project. Check `AGENTS.md` for project-specific commands. - -| Situation | Action | -|-----------|--------| -| Every task | Run typecheck/build command | -| After code changes | Run linter | -| Logic changes | Run tests | -| Pre-commit | Run full CI check | - -**Examples by language:** - -```bash -# TypeScript/Node -npm run check && npm run lint && npm test - -# Rust -cargo check && cargo clippy && cargo test - -# Go -go build ./... && go test ./... - -# Python -mypy . && ruff check . && pytest -``` - -## Stuck Detection & Safety - -### Limits - -- **Max retries per task**: 2 attempts before marking blocked -- **Scope control**: Only modify files in declared `Scope` - -### Blocking a Task - -When a task cannot proceed: - -1. Add `(blocked)` annotation to the task checkbox -2. Add blocker details to progress file -3. Stop the loop and surface to user - -**Example blocked task:** - -```markdown -- [ ] (blocked) **Task 5: Integrate payment API** - - Scope: `cloud/functions/payments` - - Depends on: Task 4 - - Acceptance: Payment webhook handler works - - Notes: Blocked - need API credentials from finance team -``` - -### Manual Verification Tasks - -Tasks marked `(manual-verify)` require human interaction: - -- Don't retry these automatically -- Stop loop when only manual-verify tasks remain -- Surface verification instructions to user - -## Guardrails - -1. **Scope control**: Only touch files in declared `Scope` -2. **No scope creep**: Expanding scope requires explicit plan edit -3. **No prod commands**: Never run production deployments -4. **No secrets**: Never commit credentials or API keys -5. **Branch safety**: Never push to main - -## Usage - -### Starting Fresh - -```text -Run ralph on .agents/plans/in-progress/my-feature.md -``` - -### Resuming - -```text -Continue ralph from Task 5 on .agents/plans/in-progress/my-feature.md -``` - -### Checking Status - -```text -Show ralph progress for .agents/plans/in-progress/my-feature.md -``` - -## Integration with Plans - -Ralph works with plans in the standard directory structure: - -- Plans live in `.agents/plans/in-progress/` -- Create plans manually following the task format above -- Use ralph to execute plans autonomously diff --git a/.agents/skills/ralph/references/progress-format.md b/.agents/skills/ralph/references/progress-format.md deleted file mode 100644 index b8efc59..0000000 --- a/.agents/skills/ralph/references/progress-format.md +++ /dev/null @@ -1,137 +0,0 @@ -# Progress File Format - -Progress files track work across iterations. They are append-only logs. - -## File Location - -Progress files live alongside their plan: - -```text -.agents/plans/in-progress/ -├── my-feature.md # Plan file -└── my-feature.progress.md # Progress log -``` - -## Entry Format - -Each completed task gets one entry: - -```markdown -## Task N: [Task Title] - -**Thread**: [Amp thread URL] -**Status**: completed | blocked | partial -**Iteration**: N - -### Changes - -- `src/module.rs` - Added X -- `src/lib.rs` - Modified Y - -### Commands Run - -- `just check` ✓ -- `just test` ✓ - -### Learnings - -- [Any patterns discovered or gotchas encountered] - -### Next - -- [What the next iteration should do] - ---- -``` - -## Required Fields - -| Field | Description | -| ----- | ----------- | -| Task ID | Task number and title from plan | -| Thread | Amp thread URL for traceability | -| Status | `completed`, `blocked`, or `partial` | -| Iteration | Which loop iteration this was | -| Changes | Files modified with brief description | -| Commands Run | Verification commands and pass/fail | -| Next | What the next iteration should focus on | - -## Optional Fields - -| Field | Description | -| ----- | ----------- | -| Learnings | Patterns discovered, gotchas, or tips for future | -| Blockers | For blocked status, describe the blocker | - -## Example Progress File - -```markdown -# Progress: My Feature - -## Task 1: Add investor type enum - -**Thread**: https://ampcode.com/threads/T-abc123 -**Status**: completed -**Iteration**: 1 - -### Changes - -- `src/protocol.rs` - Added new command enum variant -- `src/lib.rs` - Exported new command - -### Commands Run - -- `just check` ✓ - -### Next - -- Task 2: Implement command handler - ---- - -## Task 2: Implement command handler - -**Thread**: https://ampcode.com/threads/T-def456 -**Status**: completed -**Iteration**: 2 - -### Changes - -- `src/protocol.rs` - Added handler function - -### Commands Run - -- `just check` ✓ -- `just test` ✓ - -### Learnings - -- Protocol requires proper byte alignment for display commands - -### Next - -- Task 3: Add CLI integration - ---- -``` - -## Blocked Entry Example - -```markdown -## Task 5: Integrate payment API - -**Thread**: https://ampcode.com/threads/T-xyz789 -**Status**: blocked -**Iteration**: 5 - -### Blockers - -- Need API credentials from finance team -- Contact: finance@company.com - -### Next - -- Wait for credentials, then resume from Task 5 - ---- -``` diff --git a/.agents/skills/research/SKILL.md b/.agents/skills/research/SKILL.md index 03d3f69..d0ed065 100644 --- a/.agents/skills/research/SKILL.md +++ b/.agents/skills/research/SKILL.md @@ -1,139 +1,129 @@ --- name: research -description: Deep research on technical topics, libraries, APIs, or concepts. Use when asked to research, investigate, explore deeply, or gather comprehensive information on a topic. Saves learnings to .agents/research/. +description: "Researches technical questions with authoritative sources and saves work-local or reusable findings. Use for docs, comparisons, APIs, and architecture references. Triggers on: research, investigate, compare, gather references." --- # Research Skill -Conducts deep research on technical topics, saving findings for future reference. - -## Capabilities - -- Web search for documentation, articles, and examples -- Deep analysis using Oracle for complex reasoning -- Cross-reference multiple sources -- Save structured learnings to `.agents/research/` +Research a technical question, synthesize reliable evidence, and save findings either work-locally or as reusable notes in `.agents/research/`. ## Workflow -### 1. Clarify Scope - -Before starting, confirm: +### 0. Check Existing Context -- **Topic**: What exactly needs researching? -- **Depth**: Quick overview or comprehensive deep-dive? -- **Focus**: Implementation details, best practices, comparisons, or concepts? +Before doing new research: -### 2. Research Phase +- If the work belongs to an active work item, read `.agents/work/<category>/<work-slug>/index.md` and prefer work-local `research.md` or `research/` for task-specific findings. +- Search `.agents/research/` for an existing reusable topic note. +- Check repo docs, attached files, and skill `references/` first. +- If an existing note already answers the question, update it only when stale or incomplete. -Use these tools in combination: +### 1. Define the Research Brief -| Tool | Use For | -|------|---------| -| `web_search` | Find documentation, articles, tutorials | -| `read_web_page` | Extract detailed content from URLs | -| `oracle` | Deep analysis, synthesizing findings, reasoning about trade-offs | -| `librarian` | Explore open-source implementations | -| `gh` (via Bash) | Fetch repo content, issues, PRs, releases when you have a direct GitHub URL | +Capture these before researching: -> **Note:** `librarian` accesses GitHub repositories (public repos and private repos you've authorized). For local codebase searches, use `finder` or `Grep` instead. Use `gh` CLI for targeted queries like `gh repo view`, `gh issue list`, or `gh release list`. +- **Question**: What exact question must be answered? +- **Depth**: Default to a targeted answer unless a deep-dive is explicitly requested. +- **Focus**: Implementation details, comparisons, best practices, or conceptual overview. -**Research strategy:** +If the request is ambiguous but actionable, state assumptions and proceed. Ask follow-up questions only when ambiguity would materially change the recommendation. -1. Start with `web_search` to find authoritative sources -2. Use `read_web_page` to extract key information -3. Consult `oracle` for analysis and synthesis -4. Use `librarian` to find real-world implementations +### 2. Gather Evidence -### 3. Document Findings +Use the smallest toolset that can answer the question. -Save research to `.agents/research/[topic-slug].md`: - -```markdown -# Research: [Topic Name] +| Tool | Use for | +| --- | --- | +| Web search | Find authoritative sources when local docs are insufficient | +| Web page reading | Extract relevant details from specific URLs | +| Oracle or another reasoning model | Synthesize trade-offs after evidence is gathered | +| Repository search | Inspect local implementations and patterns | +| GitHub tooling | Inspect issues, PRs, releases, or external repository examples | -**Date:** YYYY-MM-DD -**Status:** Draft | Complete -**Tags:** [relevant, tags] +Guidelines: -## Summary +1. Prefer local docs and existing research before external search. +2. Prefer official docs, specs, release notes, and maintainer-authored sources. +3. Use community posts only to fill gaps in official guidance. +4. Target 2-5 high-quality sources instead of broad source dumps. +5. Use deeper reasoning after collecting evidence, not as a substitute for evidence. +6. If the user asks for latest or recent information, force a fresh fetch when your tools support it. -[2-3 sentence overview of key findings] +### 3. Synthesize Recommendation -## Key Learnings +Produce: -- Learning 1 -- Learning 2 -- Learning 3 +1. The best current recommendation. +2. Key trade-offs. +3. Confidence level and uncertainty. +4. Unresolved risks or follow-up validations. -## Details +### 4. Save or Update Findings -### [Subtopic 1] +Use work-local `.agents/work/<category>/<work-slug>/research.md` when: -[Detailed findings] +- The research mainly supports one implementation task or work item. +- The findings explain task-specific constraints, alternatives, or plan decisions. +- A future agent should find the research beside `plan.md`, `prd.md`, or `progress.md`. -### [Subtopic 2] +Use work-local `.agents/work/<category>/<work-slug>/research/<topic-slug>.md` when one work item needs multiple focused research notes. -[Detailed findings] +Create or update `.agents/research/<topic-slug>.md` when: -## Sources +- Findings are likely to be reused across unrelated work. +- The topic needs multiple sources or non-obvious trade-offs. +- The user explicitly asks to document reusable research. -- [Source Title](url) - Brief description of what was learned -- [Source Title](url) - Brief description +If work-local findings later become broadly reusable, add a concise promoted synthesis to `.agents/research/` and link between the files. -## Open Questions +Use this template: -- [ ] Question that needs further research -- [ ] Another question +```markdown +# Research: [Topic Name] -## Related Research +**Date:** YYYY-MM-DD +**Status:** draft | complete +**Question:** [What was researched] -- [[other-topic.md]] - How it relates -``` +## Recommendation -### 4. Synthesize & Report +[Best current answer in 2-4 sentences] -Provide the user with: +## Key Findings -1. **Executive summary** (3-5 bullet points) -2. **Recommendations** based on findings -3. **Link to saved research file** +- Finding 1 +- Finding 2 +- Finding 3 -## File Naming Convention +## Evidence -Use kebab-case slugs: `.agents/research/[topic-slug].md` +### [Source or Subtopic] -Examples: +[Relevant facts only] -- `react-server-components.md` -- `firebase-auth-patterns.md` -- `zod-vs-yup-comparison.md` +## Sources -## Deep Research Mode +- [Source Title](url) — What this source established -For comprehensive research, use Oracle with focused prompts: +## Open Questions -```text -task: "Analyze [topic] considering: -- Current best practices -- Common pitfalls -- Performance implications -- Security considerations" +- [ ] Include only unresolved questions that materially affect the answer ``` -## Quick Reference +Status definitions: -**Start research:** +- `draft`: Useful findings exist, but material questions remain. +- `complete`: Evidence is sufficient to answer the stated question with confidence. -```text -Research [topic] - [specific focus] -``` +### 5. Report Back -**Check existing research:** +Provide the user with: -```bash -ls -la .agents/research/ -``` +1. A concise summary. +2. A clear recommendation. +3. Link to the saved research file, if saved. +4. Explicit unknowns or open questions. + +## Definition Of Done -**Update existing research:** -Add new sections or update status from Draft to Complete. +Research is complete when the question has a clear answer or recommendation, supporting evidence is cited, reusable findings are saved when warranted, and the user receives the summary plus any saved file path. diff --git a/.agents/skills/tmux/SKILL.md b/.agents/skills/tmux/SKILL.md index e20fea8..656be02 100644 --- a/.agents/skills/tmux/SKILL.md +++ b/.agents/skills/tmux/SKILL.md @@ -1,6 +1,6 @@ --- name: tmux -description: Instructions for using tmux to spawn multiple processes, inspect them, and capture their output. Use when running servers, long-running tasks, or background processes. +description: "Manages background processes in tmux windows. Use when running servers, watchers, long checks, or other non-blocking commands. Triggers on: tmux, background process, dev server, long-running task." --- # tmux diff --git a/.agents/work/AGENTS.md b/.agents/work/AGENTS.md new file mode 100644 index 0000000..0400e3f --- /dev/null +++ b/.agents/work/AGENTS.md @@ -0,0 +1,69 @@ +# Agent Work Guide + +Guidance for durable work-item context under `.agents/work/`. + +## Scope + +Each work item lives at: + +```text +.agents/work/<category>/<work-slug>/ +``` + +Use work items for multi-session work where context, plans, progress, decisions, and handoff prompts should stay together. Keep `.agents/research/` for reusable cross-work findings. + +A work item is a *container of tasks*; task checklists live inside `plan.md` or focused plan files under `plans/`. + +## Required Entrypoint + +Every work item must have `index.md` with these metadata lines near the top: + +```markdown +Status: researching | planned | in-progress | blocked | completed +Category: feature | bugfix | tech-debt | docs | tooling | research | other +Updated: YYYY-MM-DD +``` + +Read `index.md` first when entering a work item, then load only the artifacts needed for the current step. + +## Status Rules + +- Use `researching`, `planned`, `in-progress`, `blocked`, or `completed`: + - `researching`: context exists, but no implementation-ready plan exists yet. + - `planned`: `plan.md` or `plans/<name>.md` exists and is ready for a handoff prompt or implementation. + - `in-progress`: implementation has started. + - `blocked`: progress needs input, access, or plan changes before continuing. + - `completed`: implementation and verification are done. +- Update `Updated:` whenever `Status:` or `Next Action` changes. +- Keep status in `index.md`; do not move folders between status directories. + +## Artifact Rules + +- `index.md`: required work-item landing page and current summary. +- `research.md`: work-local synthesis when investigation mainly supports this work item. +- `research/`: optional indexed folder for multiple focused research notes. +- `prd.md`: optional short requirements brief for user-facing, ambiguous, or cross-team work. +- `plan.md`: primary implementation-ready task plan. +- `plans/`: optional indexed folder for multiple focused implementation plans. +- `progress.md`: running implementation log, verification notes, blockers, and next actions. +- `decisions/`: optional one-file-per-decision records when a decision should outlive chat context. + +Do not create empty support folders by default. Add `research/`, `plans/`, `decisions/`, or other subfolders only when they hold useful files. + +## Research Placement + +Use work-local `research.md` when findings mainly explain this work item's implementation choices. Promote or duplicate a concise reusable synthesis to `.agents/research/` only when the findings are likely to guide future unrelated work. + +## Planning And Progress + +Work-local plans live at `plan.md` or under `plans/` and use the canonical agent-work plan contract. A new implementation thread should update task checkboxes, append to `progress.md`, and refresh `index.md` when status, artifacts, or next action changes. When `plans/` exists, keep `index.md` pointed at the active plan file. + +One active implementation thread should own a work item at a time. If `progress.md` conflicts, preserve both entries in chronological order and recompute the current `index.md` summary. + +## Handoff Prompts + +When preparing a new implementation thread, ask for a paste-ready handoff prompt that names the work item path, the active plan task or phase, scope limits, expected artifact updates, verification commands, stop conditions, and expected final response. + +## Decisions + +Create a file under `decisions/` only when a decision would otherwise be repeated across research, requirements brief, plan, and chat. Link to the decision file from other artifacts instead of restating the full rationale. diff --git a/.gitignore b/.gitignore index bec93c2..e7590ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ # External reference repositories -.agents/reference/* -!.agents/reference/.gitkeep +.agents/references/* +!.agents/references/.gitkeep diff --git a/AGENTS.md b/AGENTS.md index d34a54a..a4b1054 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Overview -dot-agents is an AI-ready `.agents/` workspace scaffold for any project. It provides plans, PRDs, research folders, and skills for agent-assisted development workflows. +dot-agents is an AI-ready `.agents/` workspace scaffold for any project. It provides durable work items, reusable research, and skills for planning, handoff prompts, and agent-assisted development across threads. ## Tech Stack @@ -12,85 +12,62 @@ dot-agents is an AI-ready `.agents/` workspace scaffold for any project. It prov ## Workflow ```text -Research → PRD → Plan → Execute +Work Item → Context as needed → Plan → Handoff Prompt → Implement → Record Progress ``` -1. **Research:** Investigate problem space, save findings to `.agents/research/` -2. **PRD:** Define requirements and acceptance criteria in `.agents/prds/` -3. **Plan:** Break PRD into executable tasks with Ralph-ready format -4. **Execute:** Ralph runs tasks autonomously, commits after each +1. **Work Item:** Create `.agents/work/<category>/<slug>/index.md` as the durable entrypoint. +2. **Context:** Add `research.md` or `research/` for technical facts, or `prd.md` as a short requirements brief only when needed. +3. **Plan:** Break work into implementation-ready tasks in the active plan file (`plan.md` by default, or `plans/<name>.md` for focused plans). +4. **Handoff Prompt:** Generate a paste-ready prompt for a fresh implementation thread. +5. **Progress:** Implementation threads update `progress.md`, task checkboxes, and `index.md`. ## Project Structure ```text dot-agents/ -├── AGENTS.md # This file - project instructions +├── AGENTS.md # This file - contributor instructions ├── AGENTS.template.md # Template copied to user projects ├── install.sh # Main installation script ├── .agents/ -│ ├── skills/ # Agent skills (adapt, ralph, research, tmux) -│ ├── plans/ # Implementation plans -│ ├── prds/ # Product requirements documents -│ └── research/ # Research and reference material +│ ├── work/ # Work-item guidance installed into projects +│ ├── skills/ # adapt, agent-work, feature-planning, research, tmux +│ ├── research/ # Reusable research notes +│ ├── references/ # External reference repos (gitignored) +│ └── scripts/ # sync.sh ├── docs/ # Full documentation ├── site/ # Landing page source ├── scripts/ # Development scripts └── test/ # Bats integration tests - ├── integration/ # install.bats, sync.bats - ├── fixtures/ # Test fixtures (sample-archive.tar.gz) - ├── mocks/ # Mock curl for offline testing - └── test_helper/ # Bats support libraries ``` ## Using Skills | Command | Effect | -|---------|--------| -| `Run adapt` | Analyze project and fill in AGENTS.md sections | -| `Research [topic]` | Deep investigation, saves to `.agents/research/` | -| `Run ralph on [plan.md]` | Autonomous execution of plan tasks | +| --- | --- | +| `Run adapt` | Analyze project and fill in `AGENTS.md` sections | +| `Create a new work item for ...` | Create durable `.agents/work/` context | +| `Research ...` | Investigate and save work-local or reusable findings | +| `Create/refine a plan for ...` | Produce implementation-ready tasks in the active plan file | +| `Write a handoff prompt for ...` | Produce a paste-ready prompt for a new implementation thread | -Skills are loaded via natural language. See each skill's SKILL.md in `.agents/skills/` for details. +Skills are loaded via natural language. See each skill's `SKILL.md` in `.agents/skills/` for details. -## Plan Management +## Work Item Management -Plans in `.agents/plans/` follow this workflow: +Work items live under: -| Status | Location | -|--------|----------| -| **TODO** | `plans/todo/` | -| **IN-PROGRESS** | `plans/in-progress/` | -| **COMPLETED** | `plans/completed/` | - -**Completing plans:** When moving a plan to `completed/`, also move its corresponding `.progress.md` file if one exists. - -**Archive command:** When asked to "archive completed plans", delete each plan from `completed/` with its own commit. Git history preserves them. - -### Writing Ralph-Ready Plans - -```markdown -- [ ] **Task N: Short descriptive title** - - Scope: `path/to/affected/files` or module name - - Depends on: Task M (or "none") - - Acceptance: - - Specific, verifiable criterion 1 - - Specific, verifiable criterion 2 - - Notes: Optional implementation hints +```text +.agents/work/<category>/<slug>/ ``` -**Task markers:** +Every work item has `index.md` with status, category, updated date, artifact links, next action, and open questions. Optional artifacts include `research.md`, `research/`, `prd.md`, `plan.md`, `plans/`, `progress.md`, and `decisions/` records. -| Marker | Meaning | -|--------|---------| -| `- [ ]` | Not started | -| `- [x]` | Completed | -| `- [ ] (blocked)` | Blocked, needs intervention | -| `- [ ] (manual-verify)` | Requires manual verification | +Legacy `.agents/plans/` and `.agents/prds/` paths may exist in older installs. Preserve legacy plan and PRD documents as user content, but allow sync to retire stale Ralph guidance/templates. Migrate one plan at a time into `.agents/work/` only when requested. ## Commands ```bash -# Run all tests (lint + BATS) +# Run all tests (lint + Bats) ./scripts/test.sh # Run tests with filter @@ -120,52 +97,45 @@ git push ### Commit Guidelines -- Write clear, descriptive commit messages -- Reference plan numbers in commits (e.g., "Plan 001: Initial setup") -- Commit after each logical step +- Write clear, descriptive commit messages. +- Commit after each logical step. +- Do not push directly to the default branch unless the repository maintainer explicitly requests it. ### Release Workflow ```bash # 1. Update VERSION file with new version -echo "1.0.0" > VERSION +echo "0.3.0" > VERSION # 2. Update CHANGELOG.md - move [Unreleased] items to new version section # 3. Commit changes -git add -A && git commit -m "Release v1.0.0" +git add -A && git commit -m "Release v0.3.0" # 4. Create and push release ./scripts/release.sh --push ``` -The release script: - -- Reads version from `VERSION` file -- Extracts release notes from `CHANGELOG.md` -- Creates git tag `vX.Y.Z` -- Pushes tag and creates GitHub release (requires `gh` CLI) - ## Maintenance After making changes: -1. **Update AGENTS.md** - Keep project structure and commands current -2. **Update README.md** - Reflect user-facing changes -3. **Update plan status** - Move completed plans to `completed/` -4. **Rebuild test fixture** - Run `./scripts/build-test-fixture.sh` if `.agents/` or `AGENTS.template.md` changed +1. **Update AGENTS.md** - Keep contributor structure and commands current. +2. **Update README.md / QUICKSTART.md / docs** - Reflect user-facing workflow changes. +3. **Update tests** - Preserve install/sync behavior in Bats. +4. **Rebuild test fixture** - Run `./scripts/build-test-fixture.sh` if `.agents/` or `AGENTS.template.md` changed. ## Conventions -- Shell scripts use `set -euo pipefail` -- Skills use YAML frontmatter with `name` and `description` -- Documentation in Markdown +- Shell scripts use `set -euo pipefail`. +- Skills use YAML frontmatter with quoted `description` values and `Triggers on:` phrases. +- Documentation uses Markdown with fenced code blocks. ## Architecture Notes The installer (`install.sh`) downloads a tarball from GitHub, extracts it to a temp directory, and copies: -- `AGENTS.template.md` → `./AGENTS.md` (only on fresh install, skipped on sync) -- `.agents/` contents (skills, empty directories for plans/prds/research) +- `AGENTS.template.md` → `./AGENTS.md` on fresh install only. +- Upstream-owned `.agents/` files such as skills, `.agents/work/AGENTS.md`, and `sync.sh`. -User content in `.agents/research/`, `.agents/plans/`, and `.agents/prds/` is preserved during sync. The `AGENTS.md` file is treated as user content after initial install. +User content under `.agents/work/<category>/<slug>/`, `.agents/research/`, and legacy plan/PRD documents is preserved during sync. Retired upstream skills and stale legacy guidance/templates may be backed up and removed during sync. diff --git a/AGENTS.template.md b/AGENTS.template.md index d08f3e9..6a32311 100644 --- a/AGENTS.template.md +++ b/AGENTS.template.md @@ -1,6 +1,5 @@ -> **📝 TEMPLATE:** This is the dot-agents AGENTS.md template. -> Customize it for your project by filling in the sections below. -> Delete this banner when done. +> **📝 TEMPLATE:** This is the dot-agents `AGENTS.md` template. +> Customize it for your project, then delete this banner. # Project Instructions @@ -17,13 +16,14 @@ ## Workflow ```text -Research → PRD → Plan → Execute +Work Item → Context as needed → Plan → Handoff Prompt → Implement → Record Progress ``` -1. **Research:** Investigate problem space, save findings to `.agents/research/` -2. **PRD:** Define requirements and acceptance criteria in `.agents/prds/` -3. **Plan:** Break PRD into executable tasks with Ralph-ready format -4. **Execute:** Ralph runs tasks autonomously, commits after each +1. **Work Item:** Create durable context in `.agents/work/<category>/<slug>/`. +2. **Context:** Add `research.md` or `research/` for technical facts, or `prd.md` as a short requirements brief only when needed. +3. **Plan:** Break work into implementation-ready tasks in the active plan file (`plan.md` by default, or `plans/<name>.md` for focused plans). +4. **Handoff Prompt:** Generate a paste-ready prompt for a fresh implementation thread. +5. **Progress:** Implementation threads update `progress.md`, task checkboxes, and `index.md`. ## Project Structure @@ -31,66 +31,80 @@ Research → PRD → Plan → Execute project/ ├── AGENTS.md # This file - project instructions ├── .agents/ -│ ├── reference/ # External repos (gitignored) -│ ├── research/ # Research and reference material -│ ├── prds/ # Product requirements documents -│ ├── plans/ # Implementation plans -│ │ ├── todo/ # Planned but not started -│ │ ├── in-progress/ # Currently being worked on -│ │ └── completed/ # Finished and verified +│ ├── work/ # Durable work items +│ │ └── <category>/<slug>/ +│ │ ├── index.md # Required entrypoint +│ │ ├── research.md # Optional work-specific findings +│ │ ├── research/ # Optional focused research notes +│ │ ├── prd.md # Optional requirements brief +│ │ ├── plan.md # Optional primary implementation plan +│ │ ├── plans/ # Optional focused implementation plans +│ │ ├── progress.md # Optional implementation log +│ │ └── decisions/ # Optional durable decisions +│ ├── research/ # Reusable cross-work research notes +│ ├── references/ # External repos or docs checkouts (gitignored) +│ ├── scripts/ # dot-agents helper scripts │ └── skills/ # Agent skills -│ ├── adapt/ # Project analysis and AGENTS.md setup -│ ├── ralph/ # Autonomous implementation loops -│ ├── research/ # Deep research workflow -│ └── tmux/ # Background process management +│ ├── adapt/ +│ ├── agent-work/ +│ ├── feature-planning/ +│ ├── research/ +│ └── tmux/ └── src/ # Source code ``` ## Using Skills | Command | Effect | -|---------|--------| -| `Run adapt` | Analyze project and fill in AGENTS.md sections | -| `Research [topic]` | Deep investigation, saves to `.agents/research/` | -| `Run ralph on [plan.md]` | Autonomous execution of plan tasks | +| --- | --- | +| `Run adapt` | Analyze project and fill in `AGENTS.md` sections | +| `Create a new work item for ...` | Create durable `.agents/work/` context | +| `Research [topic]` | Investigate and save work-local or reusable findings | +| `Create a plan for ...` | Produce implementation-ready tasks in the active plan file | +| `Write a handoff prompt for ...` | Produce a paste-ready prompt for a new implementation thread | -Skills are loaded via natural language. See each skill's SKILL.md in `.agents/skills/` for details. +Skills are loaded via natural language. See each skill's `SKILL.md` in `.agents/skills/` for details. -## Plan Management +## Work Items -Plans in `.agents/plans/` follow this workflow: +Work items live at: -| Status | Location | -|--------|----------| -| **TODO** | `plans/todo/` | -| **IN-PROGRESS** | `plans/in-progress/` | -| **COMPLETED** | `plans/completed/` | +```text +.agents/work/<category>/<slug>/ +``` + +Every work item has `index.md` with: -**Completing plans:** When moving a plan to `completed/`, also move its corresponding `.progress.md` file if one exists. +```markdown +Status: researching | planned | in-progress | blocked | completed +Category: feature | bugfix | tech-debt | docs | tooling | research | other +Updated: YYYY-MM-DD +``` -**Archive command:** When asked to "archive completed plans", delete each plan from `completed/` with its own commit. Git history preserves them. +Use optional files only when useful: -### Writing Ralph-Ready Plans +- `research.md` - work-specific investigation notes +- `research/` - optional indexed folder for multiple focused research notes +- `prd.md` - short requirements brief when alignment is needed +- `plan.md` - primary implementation-ready task checklist +- `plans/` - optional indexed folder for multiple focused plans +- `progress.md` - implementation log, verification, blockers, and next action +- `decisions/` - durable decision records + +Do not create empty support folders by default. Add `research/`, `plans/`, or `decisions/` only when they hold useful files. + +### Task Format ```markdown - [ ] **Task N: Short descriptive title** - Scope: `path/to/affected/files` or module name - - Depends on: Task M (or "none") + - Depends on: Task M or `none` - Acceptance: - Specific, verifiable criterion 1 - Specific, verifiable criterion 2 - Notes: Optional implementation hints ``` -**Task markers:** - -| Marker | Meaning | -|--------|---------| -| `- [ ]` | Not started | -| `- [x]` | Completed | -| `- [ ] (blocked)` | Blocked, needs intervention | -| `- [ ] (manual-verify)` | Requires manual verification | - ## Commands ```bash @@ -112,17 +126,17 @@ git push ### Commit Guidelines -- Write clear, descriptive commit messages -- Reference plan numbers in commits (e.g., "Plan 001: Initial setup") -- Commit after each logical step +- Write clear, descriptive commit messages. +- Commit after each logical step. +- Do not push directly to the default branch unless project policy allows it. ## Maintenance After making changes: -1. **Update AGENTS.md** - Keep project structure and commands current -2. **Update README.md** - Reflect user-facing changes -3. **Update plan status** - Move completed plans to `completed/` +1. **Update AGENTS.md** - Keep project commands and conventions current. +2. **Update work items** - Keep `index.md`, the active plan file, and `progress.md` in sync with implementation state. +3. **Update docs** - Reflect user-facing behavior changes. ## Conventions diff --git a/CHANGELOG.md b/CHANGELOG.md index 09b67b1..fc7ed30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,30 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [0.3.0] - 2026-06-22 + +### Changed + +- **BREAKING:** Replaced the Ralph-centered `.agents/plans/` / `.agents/prds/` workflow with durable work items under `.agents/work/<category>/<slug>/`. +- **BREAKING:** Fresh installs now ship `adapt`, `agent-work`, `feature-planning`, `research`, and `tmux` as core skills. +- Research guidance now distinguishes work-local `research.md` from reusable `.agents/research/` notes. +- Documentation, quickstart, and landing page now describe prompt-based implementation handoffs instead of autonomous runner execution. +- `--diff` now exits non-zero for any pending sync change, including missing files, retired skills, retired guidance, and `.gitignore` updates. + +### Removed + +- **BREAKING:** Removed the `ralph` skill from core installs. Sync backs up and removes retired upstream `ralph` skill directories. +- Fresh installs no longer create legacy `.agents/plans/` or `.agents/prds/` directories. +- Sync backs up and removes retired legacy guidance/templates such as `.agents/prds/AGENTS.md` and old plan/PRD templates. +- Dropped support for the deprecated singular `.agents/reference/` path. External reference checkouts now live under `.agents/references/`; rename any existing `.agents/reference/` checkout, which is no longer gitignored. + +### Added + +- Work-item guidance at `.agents/work/AGENTS.md`. +- `agent-work` skill with templates and scripts for creating and listing work items. +- `feature-planning` skill for PRDs, implementation-ready plans, plan refinement, and paste-ready new-thread prompts. +- Legacy migration guide for moving old plans into `.agents/work/`. + ## [0.2.0] - 2026-06-22 ### Added @@ -64,7 +88,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Installer skip logic now correctly includes plans/TEMPLATE.md - Postfix increment operators causing script exit on bash 5.3+ with `set -e` ([#1](https://github.com/colmarius/dot-agents/issues/1)) -[Unreleased]: https://github.com/colmarius/dot-agents/compare/v0.2.0...HEAD +[Unreleased]: https://github.com/colmarius/dot-agents/compare/v0.3.0...HEAD +[0.3.0]: https://github.com/colmarius/dot-agents/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/colmarius/dot-agents/compare/v0.1.1...v0.2.0 [0.1.1]: https://github.com/colmarius/dot-agents/compare/v0.1.0...v0.1.1 [0.1.0]: https://github.com/colmarius/dot-agents/releases/tag/v0.1.0 diff --git a/QUICKSTART.md b/QUICKSTART.md index 7d2e799..0942386 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -17,106 +17,144 @@ Get productive with dot-agents in 5 minutes. ## 1. Install -**cmd:** +Run the installer from the root of the repository you want to equip with dot-agents: + ```bash curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash ``` -### What Gets Installed +Fresh installs create `AGENTS.md` and `.agents/`. Re-running the installer later updates dot-agents while preserving work items, research, and your customized `AGENTS.md`. -After running the install command, you'll have: +### What Gets Installed -``` +```text your-project/ -├── AGENTS.md # Template - customize for your project +├── AGENTS.md └── .agents/ - ├── plans/ - │ ├── todo/ - │ ├── in-progress/ - │ └── completed/ - ├── prds/ - │ └── TEMPLATE.md + ├── work/ + │ └── AGENTS.md ├── research/ - ├── reference/ # gitignored - for external repos + ├── references/ ├── scripts/ │ └── sync.sh └── skills/ ├── adapt/ - ├── ralph/ + ├── agent-work/ + ├── feature-planning/ ├── research/ └── tmux/ ``` -If the project already has a `.claude/` directory, dot-agents also links skills into `.claude/skills/` so Claude Code can discover them as project skills and invoke them with slash commands such as `/adapt`. +If the project already has a `.claude/` directory, dot-agents also links skills into `.claude/skills/` so Claude Code can discover them as project skills. ### Verify Installation -**cmd:** ```bash ls -la .agents/ cat AGENTS.md | head -20 ``` -For Claude Code projects, you can also check: +## 2. Adapt `AGENTS.md` -**cmd:** -```bash -ls -la .claude/skills/ +Ask your agent: + +```text +Run adapt ``` -## 2. Adapt AGENTS.md +This analyzes your project and fills in the `AGENTS.md` template with tech stack, commands, and conventions. You can also customize it manually. + +If your agent does not auto-discover skills, tell it: -**prompt:** ```text -Run adapt +Read .agents/skills/adapt/SKILL.md and follow it. ``` -This analyzes your project and fills in the AGENTS.md template with your tech stack, commands, and conventions. You can also customize it manually. +## 3. Create a Work Item -## 3. Research +Use work items for multi-session or context-heavy work. For a tiny one-shot edit, you may not need one. -Before building, research the problem space: +Ask your agent: -**prompt:** ```text -Research authentication patterns for Express.js APIs +Create a new work item for user authentication. ``` -Findings are saved to `.agents/research/` for reference. +If your agent does not auto-discover skills, tell it to read `.agents/skills/agent-work/SKILL.md` first. + +Or run the helper directly: -## 4. Create PRD +```bash +.agents/skills/agent-work/scripts/new-work.sh \ + --category feature \ + --slug user-authentication \ + --title "User authentication" +``` + +The work item starts at: + +```text +.agents/work/feature/user-authentication/index.md +``` -Turn research into a product requirements document: +A minimal work item looks like: -**prompt:** ```text -Create a PRD for user authentication based on .agents/research/authentication-patterns.md +.agents/work/feature/user-authentication/ +├── index.md # status, summary, next action +└── plan.md # added when you ask for a plan ``` -PRDs go to `.agents/prds/` with acceptance criteria. +Future threads start by reading `index.md`, then load only the plan, research, or progress they need. -## 5. Generate Plan +## 4. Add Context Only If Needed, Then Plan -Convert PRD into implementation tasks: +If the unknowns are technical, ask for work-local research: -**prompt:** ```text -Create a plan from .agents/prds/user-authentication.md +Research authentication patterns for this work item. ``` -Plans use Ralph-ready task format with scope, dependencies, and acceptance criteria. +If the desired behavior is ambiguous, ask for a short requirements brief: -## 6. Execute with Ralph +```text +Create a short requirements brief for this work item. +``` -Run autonomous implementation: +If the goal is already clear, skip extra context and ask for a plan: -**prompt:** ```text -Run ralph on .agents/plans/in-progress/user-authentication.md +Create an implementation-ready plan in .agents/work/feature/user-authentication/plan.md. ``` -Ralph iterates through tasks, commits after each, and pauses for review. +Plans use tasks with scope, dependencies, and acceptance criteria. + +## 5. Generate a Handoff Prompt + +When the plan is ready, ask: + +```text +Review .agents/work/feature/user-authentication and write a paste-ready handoff prompt for the next implementation thread. +``` + +Paste the generated prompt into a fresh agent thread. The new thread should read `index.md`, implement the requested slice, update the active plan file, append to `progress.md`, refresh `index.md`, and report verification results. + +## 6. Continue Later + +List active work: + +```bash +.agents/skills/agent-work/scripts/list-work.sh +``` + +Then ask for a continuation prompt from the next action in the work item. + +## Outcome + +At the end of the quickstart, you have a work item with a current next action and a paste-ready prompt for a fresh implementation thread. + +## Upgrading from v0.2? ---- +See the [v0.3 migration guide](./docs/migration-v0.3.md) for legacy `.agents/plans/` and `.agents/prds/` projects. **Next:** [Concepts](./docs/concepts.md) · [Skills Reference](./docs/skills.md) · [dot-agents.dev](https://dot-agents.dev) diff --git a/README.md b/README.md index f208795..f950a30 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # dot-agents -AI-ready `.agents/` workspace for any project—plans, PRDs, research, and skills for agent-assisted workflows. +AI-ready `.agents/` workspace for any project — durable work items, reusable research, planning skills, and paste-ready handoff prompts for agent-assisted development across threads. ## Install +Run the installer from the root of the repository you want to equip with dot-agents: + ```bash curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash ``` @@ -11,46 +13,52 @@ curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.s Pin a version: ```bash -curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0 +curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.3.0 ``` ## Documentation -- **[Quickstart](./QUICKSTART.md)** — Step-by-step guide from install to autonomous execution -- **[Full Docs](./docs/README.md)** — Concepts, skills reference +- **[Quickstart](./QUICKSTART.md)** — Install, create a work item, and generate a handoff prompt +- **[Full Docs](./docs/README.md)** — Concepts, skills, and migration notes - **[Website](https://dot-agents.dev)** — Landing page (source: [site/](./site/)) ## Agent Support -dot-agents works with any AI coding agent that reads markdown instructions. When a project already has a `.claude/` directory, install/sync also links dot-agents skills into `.claude/skills/` so Claude Code can discover them as project skills. +dot-agents works with any AI coding agent that reads Markdown instructions. When a project already has a `.claude/` directory, install/sync also links dot-agents skills into `.claude/skills/` so Claude Code can discover them as project skills. + +If an agent does not auto-discover skills, ask it to read the relevant `.agents/skills/<skill>/SKILL.md` file before starting that workflow. ## Next Steps -Then: +After install: -1. Customize `AGENTS.md` for your project — run `adapt` to auto-fill or edit manually -2. Sync updates later: `.agents/scripts/sync.sh` +1. Customize `AGENTS.md` for your project — run `adapt` to auto-fill or edit manually. +2. Create a work item under `.agents/work/<category>/<slug>/`. +3. Ask for research, a plan, or a paste-ready handoff prompt. +4. Sync updates later with `.agents/scripts/sync.sh`. ## Sync Behavior Re-running `install.sh` updates dot-agents from upstream while preserving your work: | What | Behavior | -|------|----------| -| Skills, scripts | Updated from upstream | -| AGENTS.md | Skipped (your customizations preserved) | -| PRDs, plans | Skipped (your content preserved) | -| Research | Skipped (your content preserved) | +| --- | --- | +| Skills, scripts, `.agents/work/AGENTS.md` | Updated from upstream | +| Retired upstream skills and legacy guidance/templates | Backed up and removed on sync | +| `AGENTS.md` | Skipped after fresh install | +| Work items | Preserved under `.agents/work/<category>/<slug>/` | +| Reusable research | Preserved under `.agents/research/` | +| Legacy plan/PRD documents | Preserved if present | The installer copies `AGENTS.template.md` → `AGENTS.md` on fresh install only. **Sync options:** | Flag | Behavior | -|------|----------| -| (default) | Overwrite conflicts with backup | -| `--diff` | Preview changes without modifying files | -| `--write-conflicts` | Create `.dot-agents.new` files for manual review | +| --- | --- | +| default | Overwrite upstream-owned conflicts with backup during sync | +| `--diff` | Preview pending installs, updates, removals, and conflicts without modifying files; exits 1 if any change is pending | +| `--write-conflicts` | Create conflict files for manual review: Markdown writes `file.dot-agents.md`; other files write `file.ext.dot-agents.new` | | `--dry-run` | Show what would happen without changes | ## Versioning diff --git a/VERSION b/VERSION index 0ea3a94..0d91a54 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.0 +0.3.0 diff --git a/docs/README.md b/docs/README.md index 7b9a7dd..8741e58 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,12 +9,13 @@ - [Workflow Overview](./concepts.md#workflow) - [Glossary](./concepts.md#glossary) +- [v0.3 Migration](./migration-v0.3.md) ## Reference - [Skills](./skills.md) - [Claude Code Project Skill Discovery](./skills.md#claude-code-project-skill-discovery) -- [AGENTS.md Template](../AGENTS.md) +- [AGENTS.md Template](../AGENTS.template.md) ## For Contributors diff --git a/docs/concepts.md b/docs/concepts.md index 5663891..a1bd599 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -3,21 +3,90 @@ ## Workflow ```text -Research → PRD → Plan → Execute +Work Item → Context as needed → Plan → Handoff Prompt → Implement → Record Progress ``` -1. **Research:** Investigate problem space, save findings to `.agents/research/` -2. **PRD:** Define requirements and acceptance criteria in `.agents/prds/` -3. **Plan:** Break PRD into executable tasks with Ralph-ready format -4. **Execute:** Ralph runs tasks autonomously, commits after each +1. **Work Item:** Create `.agents/work/<category>/<slug>/index.md` as the durable context entrypoint. +2. **Context:** Add optional context only when it helps: `research.md` or `research/` for technical facts, or `prd.md` as a short requirements brief when behavior needs alignment. +3. **Plan:** Break work into implementation-ready tasks in the active plan file (`plan.md` by default, or `plans/<name>.md` for focused plans) with scope, dependencies, and acceptance criteria. +4. **Handoff Prompt:** Ask an agent to write a paste-ready prompt for a fresh implementation thread. +5. **Implement:** Paste the prompt into the new thread and let that agent do the scoped work. +6. **Record Progress:** Update `progress.md`, active plan task checkboxes, and `index.md` so future threads can resume. + +Use work items for multi-session or context-heavy work. For a tiny one-shot edit, you may not need one. + +Context is optional. Use `research.md` when the question is "what is true?" Use `research/` when multiple focused research notes are useful. Use `prd.md` as a requirements brief when the question is "what should be true?" Skip both when the plan can state the goal and acceptance criteria clearly. + +## Work Item Shape + +```text +.agents/work/<category>/<slug>/ +├── index.md # required landing page +├── research.md # optional, work-specific findings +├── research/ # optional focused research notes +├── prd.md # optional requirements brief +├── plan.md # optional primary implementation-ready tasks +├── plans/ # optional focused implementation plans +├── progress.md # optional implementation log +└── decisions/ # optional durable decisions +``` + +Create optional files only when they hold useful context. The required `index.md` should stay short and point to the current next action. +Create optional folders like `research/`, `plans/`, and `decisions/` only when they contain useful files. + +## Example Work Item + +```text +.agents/work/feature/user-authentication/ +├── index.md # status, summary, next action +└── plan.md # implementation tasks, when useful +``` + +```markdown +# User authentication + +Status: planned +Category: feature +Updated: 2026-06-22 + +## Summary + +Add auth flows and session persistence. + +## Next Action + +Implement Task 1 from plan.md. +``` + +New threads start by reading `index.md`, then load only the plan, research, or progress they need. + +## Handoff Prompts + +A handoff prompt is a paste-ready prompt for a new agent thread. It should name: + +- Work item path and files to read first. +- Goal, current state, and exact implementation slice. +- Scope limits and non-goals. +- Required updates to the active plan file, `progress.md`, and `index.md`. +- Verification commands and stop conditions. +- Expected final response shape. + +dot-agents does not assume a specific execution runtime. The work item is the continuity layer. + +## Legacy Content + +Older dot-agents installs used `.agents/plans/` and `.agents/prds/`. v0.3.0 preserves legacy plan and PRD documents as user content but no longer creates those paths on fresh install. See [migration guide](./migration-v0.3.md) for how to move active work into `.agents/work/`. ## Glossary | Term | Definition | -|------|------------| -| adapt | Skill that analyzes your project and fills in AGENTS.md | -| Ralph | Autonomous execution skill that works through plans task-by-task | -| PRD | Product Requirements Document defining what to build | -| Plan | List of tasks in Ralph-ready format with scope, dependencies, acceptance criteria | -| Skills | Specialized agent instructions loaded via natural language | -| sync | Script that updates dot-agents from upstream while preserving your customizations | +| --- | --- | +| adapt | Skill that analyzes your project and fills in `AGENTS.md` | +| work item | Durable folder under `.agents/work/<category>/<slug>/` for one multi-session effort | +| task | Checkbox entry inside `plan.md` or a focused plan under `plans/` | +| PRD | Optional short requirements brief defining what should be true | +| plan | Implementation-ready task list with scope, dependencies, and acceptance criteria | +| handoff prompt | Paste-ready prompt for a fresh implementation thread | +| progress log | `progress.md`, the implementation log for changes, verification, blockers, and next action | +| skills | Specialized agent instructions loaded via natural language | +| sync | Script that updates dot-agents from upstream while preserving user work | diff --git a/docs/migration-v0.3.md b/docs/migration-v0.3.md new file mode 100644 index 0000000..1dd82ed --- /dev/null +++ b/docs/migration-v0.3.md @@ -0,0 +1,64 @@ +# Migration Guide: Work Items and Handoff Prompts + +dot-agents v0.3.0 replaces the old `.agents/plans/` / `.agents/prds/` / Ralph workflow with durable work items and paste-ready handoff prompts. + +## What Changed + +Fresh installs now create: + +```text +.agents/work/ +.agents/research/ +.agents/references/ +.agents/skills/{adapt,agent-work,feature-planning,research,tmux}/ +``` + +Fresh installs no longer create: + +```text +.agents/plans/ +.agents/prds/ +.agents/skills/ralph/ +``` + +Existing legacy plan and PRD documents and `.agents/research/` content are preserved on sync. Retired Ralph support is backed up and removed so stale guidance does not conflict with the new workflow. This includes `.agents/skills/ralph`, `.agents/plans/AGENTS.md`, `.agents/prds/AGENTS.md`, and old plan/PRD templates. Any `.agents/skills/ralph` directory is treated as retired upstream content, even if it was locally edited; restore it from `.agents/.dot-agents-backup/` and rename it only if you intentionally want to keep a custom skill with that behavior. + +v0.3.0 does not ship a Ralph compatibility layer, alias, or stub skill. Pin to `v0.2.0` only if you need the old runner workflow for an existing project. + +Use `--diff` before syncing to preview pending installs, updates, removals, and conflicts without modifying files; it exits non-zero when any change is pending. Use `--write-conflicts` to write conflicts beside the original: Markdown conflicts use `file.dot-agents.md`, while other files use `file.ext.dot-agents.new`. + +External reference checkouts now live under `.agents/references/`. The deprecated singular `.agents/reference/` path is no longer ignored, so rename any existing `.agents/reference/` checkout to `.agents/references/` to keep large local clones out of version control. + +## Migrate One Legacy Plan + +Ask your agent: + +```text +Migrate legacy plan .agents/plans/in-progress/<plan>.md into a new work item. + +Create .agents/work/<category>/<slug>/index.md. +Copy the old plan to plan.md, preserving task checkboxes. +If there is a matching .progress.md file, copy it to progress.md. +If the plan links a PRD under .agents/prds/, copy or summarize it into prd.md. +Update index.md with Status, Artifacts, Next Action, and Open Questions. +Do not delete the legacy files unless I explicitly ask. +``` + +## Status Mapping + +| Legacy location | New `index.md` status | +| --- | --- | +| `.agents/plans/todo/` | `planned` | +| `.agents/plans/in-progress/` | `in-progress` | +| `.agents/plans/completed/` | `completed` | +| PRD only | `researching` or `planned`, depending whether a plan exists | + +## After Migration + +Ask for a handoff prompt: + +```text +Review .agents/work/<category>/<slug> and write a paste-ready handoff prompt for the next implementation thread. +``` + +Paste the generated prompt into a fresh thread. The implementation thread should update `plan.md`, `progress.md`, and `index.md` as it works. diff --git a/docs/skills.md b/docs/skills.md index 323a883..b8a419a 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -1,56 +1,71 @@ # Skills -Skills are specialized instructions that agents load for specific workflows. When you invoke a skill, the agent receives detailed guidance for that particular task type. +Skills are specialized instructions that agents load for specific workflows. dot-agents keeps them under `.agents/skills/` and, for Claude Code projects, links them into `.claude/skills/` when `.claude/` already exists. ## Available Skills | Skill | Trigger | Purpose | -|-------|---------|---------| -| [adapt](#adapt) | `Run adapt` | Analyze project, fill in AGENTS.md | -| [ralph](#ralph) | `Run ralph on [plan]` | Autonomous task execution | -| [research](#research) | `Research [topic]` | Deep investigation workflow | -| [tmux](#tmux) | (auto-loaded) | Background process management | +| --- | --- | --- | +| [adapt](#adapt) | `Run adapt` | Analyze project, fill in `AGENTS.md` | +| [agent-work](#agent-work) | `Create a work item` | Create and maintain `.agents/work/` context | +| [feature-planning](#feature-planning) | `Create a plan`, `write a handoff prompt` | Turn context into plans and new-thread prompts | +| [research](#research) | `Research [topic]` | Investigate and save work-local or reusable findings | +| [tmux](#tmux) | `tmux`, `background process` | Manage background processes | ## adapt -Analyzes your project and fills in AGENTS.md with: +Analyzes your project and fills in `AGENTS.md` with: - Project overview and tech stack - Build/test/lint commands - Code conventions - Project structure +- dot-agents work-item workflow guidance **Invoke:** `Run adapt` **Details:** [.agents/skills/adapt/SKILL.md](../.agents/skills/adapt/SKILL.md) -## ralph +## agent-work -Executes plans autonomously, iterating through tasks: +Creates and curates durable work item folders: -- Reads plan from `.agents/plans/` -- Completes tasks one by one -- Commits after each task -- Hands off to new thread when context fills +```text +.agents/work/<category>/<slug>/index.md +``` + +Use it to create work items, list active work, place artifacts deliberately, and migrate legacy plans when requested. + +**Invoke:** `Create a new work item for user authentication` + +**Details:** [.agents/skills/agent-work/SKILL.md](../.agents/skills/agent-work/SKILL.md) + +## feature-planning -**Invoke:** `Run ralph on .agents/plans/in-progress/my-plan.md` +Turns work-item context into implementation-ready plans and paste-ready handoff prompts. -**Options:** +Use it to: -- Start from specific task: `Continue ralph from Task 5 on [plan]` -- Default max tasks per session: 5 +- Create or refine a short requirements brief (`prd.md`) only when alignment is needed +- Create or refine the active plan file +- Validate stale assumptions before implementation +- Generate a new-thread handoff prompt +- Stress-test a plan when explicitly asked -**Details:** [.agents/skills/ralph/SKILL.md](../.agents/skills/ralph/SKILL.md) +**Invoke:** `Write a handoff prompt for .agents/work/feature/user-authentication` + +**Details:** [.agents/skills/feature-planning/SKILL.md](../.agents/skills/feature-planning/SKILL.md) ## research -Deep investigation workflow: +Investigates technical questions using available local, web, and repository evidence. + +Research is saved: -- Web search and documentation reading -- Explores libraries, APIs, patterns -- Saves findings to `.agents/research/` +- Work-locally at `.agents/work/<category>/<slug>/research.md` or `.agents/work/<category>/<slug>/research/<topic>.md` when it supports one work item +- Reusably at `.agents/research/<topic>.md` when it should guide future unrelated work -**Invoke:** `Research [topic]` +**Invoke:** `Research authentication patterns for this work item` **Details:** [.agents/skills/research/SKILL.md](../.agents/skills/research/SKILL.md) @@ -58,11 +73,11 @@ Deep investigation workflow: Background process management: -- Spawns long-running processes (servers, watchers) +- Spawns long-running processes such as servers or watchers - Captures output for review -- Auto-loaded by other skills when needed +- Sends interrupts or kills background windows when needed -**Note:** This skill is typically loaded automatically when background processes are required. +**Invoke:** `Use tmux to run the dev server in the background` **Details:** [.agents/skills/tmux/SKILL.md](../.agents/skills/tmux/SKILL.md) @@ -70,31 +85,29 @@ Background process management: Create a new skill by adding a directory under `.agents/skills/`: -``` +```text .agents/skills/my-skill/ └── SKILL.md ``` -### SKILL.md Format +### `SKILL.md` Format ```markdown --- name: my-skill -description: Brief description for skill discovery +description: "Brief description. Use when relevant context applies. Triggers on: keyword1, keyword2." --- # My Skill -Instructions for the agent when this skill is loaded... +Instructions for the agent when this skill is loaded. ``` -The `name` and `description` in the frontmatter are used for skill discovery. The agent matches user requests against skill descriptions to determine which skill to load. - -**Invocation:** Skills are loaded via natural language matching. If your description mentions "deploy" or "deployment", saying "help me deploy" will load your skill. +The `name` and `description` fields are used for skill discovery. Keep descriptions quoted, concise, and trigger-rich. ### Preserving Custom Skills -Custom skills in `.agents/skills/` are preserved during `sync.sh` updates. Only upstream skills (adapt, ralph, research, tmux) are updated—your custom skills remain untouched. +Custom skills in `.agents/skills/` are preserved during `sync.sh` updates. Only upstream core skills are updated or retired by dot-agents. ## Claude Code Project Skill Discovery @@ -102,7 +115,7 @@ Claude Code discovers project skills in `.claude/skills/<skill>/SKILL.md`. dot-a ```text .claude/skills/adapt -> ../../.agents/skills/adapt -.claude/skills/ralph -> ../../.agents/skills/ralph +.claude/skills/agent-work -> ../../.agents/skills/agent-work ``` -Directory symlinks expose the whole skill, including optional supporting files like `references/` and `scripts/`. The installer skips user-owned Claude Code skills and only removes dot-agents-managed symlinks during uninstall. +Directory symlinks expose the whole skill, including optional supporting files like `assets/`, `references/`, and `scripts/`. The installer skips user-owned Claude Code skills and only removes dot-agents-managed symlinks during uninstall or retired-skill cleanup. diff --git a/install.sh b/install.sh index 7698e5f..b9dbd94 100755 --- a/install.sh +++ b/install.sh @@ -36,9 +36,9 @@ Install dot-agents into the current project. Options: --dry-run Show what would happen without making changes - --diff Show unified diff for conflicts instead of overwriting + --diff Preview pending changes without writing; exit 1 if pending --force Overwrite conflicts (creates backup first, default on sync) - --write-conflicts Create .dot-agents.new files for conflicts + --write-conflicts Create file.dot-agents.md/file.ext.dot-agents.new conflicts --ref <ref> Git ref to install (branch, tag, commit). Default: main --yes Skip confirmation prompts --uninstall Remove dot-agents @@ -51,10 +51,10 @@ Examples: curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash # Install specific version - curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0 + curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.3.0 # Preview changes first - curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --dry-run + curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --diff # Force update (backup + overwrite) curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --force @@ -190,9 +190,22 @@ do_uninstall() { installed_count=0 skipped_count=0 conflict_count=0 +pending_change_count=0 backup_count=0 BACKUP_DIR="" CLAUDE_SKILL_SYMLINKS_REMOVED=0 +AGENTS_GITIGNORE_PENDING=false + +is_agents_gitignore_path() { + local path="${1#./}" + [[ "$path" == ".agents/.gitignore" ]] +} + +mark_agents_gitignore_pending() { + if is_agents_gitignore_path "$1"; then + AGENTS_GITIGNORE_PENDING=true + fi +} is_dot_agents_claude_skill_symlink() { local path="$1" @@ -209,6 +222,11 @@ remove_claude_code_skill_symlinks() { CLAUDE_SKILL_SYMLINKS_REMOVED=0 + [[ -e "$claude_skills_dir" || -L "$claude_skills_dir" ]] || return 0 + if [[ -L "$claude_skills_dir" ]]; then + log_info "${YELLOW}[SKIP]${NC} $claude_skills_dir (user-owned symlink)" + return 0 + fi [[ -d "$claude_skills_dir" ]] || return 0 for skill_link in "$claude_skills_dir"/*; do @@ -233,7 +251,7 @@ create_backup_dir() { if [[ -z "$BACKUP_DIR" ]]; then local timestamp timestamp="$(date -u +%Y-%m-%dT%H%M%SZ)" - BACKUP_DIR=".dot-agents-backup/${timestamp}" + BACKUP_DIR=".agents/.dot-agents-backup/${timestamp}" if [[ "$DRY_RUN" != "true" ]]; then mkdir -p "$BACKUP_DIR" fi @@ -251,12 +269,39 @@ backup_file() { log_info " ${BLUE}[BACKUP]${NC} $file → $backup_path" else mkdir -p "$backup_dir" - cp "$file" "$backup_path" + if [[ -L "$file" ]]; then + cp -Pp "$file" "$backup_path" + else + cp -p "$file" "$backup_path" + fi log_info " ${BLUE}[BACKUP]${NC} $file" fi backup_count=$((backup_count + 1)) } +backup_item() { + local path="$1" + create_backup_dir + local backup_path="${BACKUP_DIR}/${path}" + local backup_dir + backup_dir="$(dirname "$backup_path")" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${BLUE}[BACKUP]${NC} $path → $backup_path" + else + mkdir -p "$backup_dir" + if [[ -d "$path" && ! -L "$path" ]]; then + cp -Rp "$path" "$backup_path" + elif [[ -L "$path" ]]; then + cp -Pp "$path" "$backup_path" + else + cp -p "$path" "$backup_path" + fi + log_info " ${BLUE}[BACKUP]${NC} $path" + fi + backup_count=$((backup_count + 1)) +} + detect_stack() { local detected="" @@ -334,44 +379,60 @@ log_info() { echo -e "$1"; } INTERACTIVE_SKIP_ALL=false INTERACTIVE_OVERWRITE_ALL=false +PROMPT_ACTION="" prompt_conflict() { local src="$1" local dest="$2" + local response="" if [[ "$INTERACTIVE_SKIP_ALL" == "true" ]]; then - echo "skip" + PROMPT_ACTION="skip" return fi if [[ "$INTERACTIVE_OVERWRITE_ALL" == "true" ]]; then - echo "overwrite" + PROMPT_ACTION="overwrite" return fi - echo "" - echo -e "${YELLOW}CONFLICT:${NC} $dest differs from upstream" + echo "" >&2 + echo -e "${YELLOW}CONFLICT:${NC} $dest differs from upstream" >&2 if command -v diff >/dev/null 2>&1; then - echo "--- $dest (yours)" - echo "+++ upstream" - diff -u "$dest" "$src" 2>/dev/null | head -20 || true - echo "" + echo "--- $dest (yours)" >&2 + echo "+++ upstream" >&2 + diff -u "$dest" "$src" 2>/dev/null | head -20 >&2 || true + echo "" >&2 + fi + + echo -n "[k]eep / [o]verwrite / [n]ew file / [s]kip all / [O]verwrite all? " >&2 + if [[ -n "${DOT_AGENTS_INTERACTIVE_RESPONSE:-}" ]]; then + response="$DOT_AGENTS_INTERACTIVE_RESPONSE" + DOT_AGENTS_INTERACTIVE_RESPONSE="" + elif [[ -r /dev/tty ]]; then + read -r response < /dev/tty || response="" + else + echo "" >&2 + log_info " ${YELLOW}[SKIP]${NC} no terminal available; writing conflict file for manual review" + PROMPT_ACTION="new" + return fi - echo -n "[k]eep / [o]verwrite / [n]ew file / [s]kip all / [O]verwrite all? " - read -r response case "$response" in - k|K) echo "keep" ;; - o) echo "overwrite" ;; - n|N) echo "new" ;; - s|S) INTERACTIVE_SKIP_ALL=true; echo "skip" ;; - O) INTERACTIVE_OVERWRITE_ALL=true; echo "overwrite" ;; - *) echo "new" ;; + k|K) PROMPT_ACTION="keep" ;; + o) PROMPT_ACTION="overwrite" ;; + n|N) PROMPT_ACTION="new" ;; + s|S) INTERACTIVE_SKIP_ALL=true; PROMPT_ACTION="skip" ;; + O) INTERACTIVE_OVERWRITE_ALL=true; PROMPT_ACTION="overwrite" ;; + *) PROMPT_ACTION="new" ;; esac } files_identical() { local file1="$1" local file2="$2" + + [[ -f "$file1" && -f "$file2" ]] || return 1 + if command -v md5sum >/dev/null 2>&1; then [[ "$(md5sum "$file1" | cut -d' ' -f1)" == "$(md5sum "$file2" | cut -d' ' -f1)" ]] elif command -v md5 >/dev/null 2>&1; then @@ -419,8 +480,23 @@ format_version_string() { fi } -# Core skills that come from upstream (sample-skill is for testing) -CORE_SKILLS="adapt ralph research tmux sample-skill" +# Core skills that come from upstream +CORE_SKILLS="adapt agent-work feature-planning research tmux" +RETIRED_CORE_SKILLS="ralph" +RETIRED_LEGACY_GUIDANCE_FILES=".agents/plans/AGENTS.md .agents/prds/AGENTS.md .agents/plans/TEMPLATE.md .agents/prds/TEMPLATE.md" + +is_retired_core_skill() { + local skill_name="$1" + local retired + + for retired in $RETIRED_CORE_SKILLS; do + if [[ "$skill_name" == "$retired" ]]; then + return 0 + fi + done + + return 1 +} detect_custom_skills() { local skills_dir=".agents/skills" @@ -437,7 +513,7 @@ detect_custom_skills() { # Skip if it's a core skill local is_core=false - for core in $CORE_SKILLS; do + for core in $CORE_SKILLS $RETIRED_CORE_SKILLS; do if [[ "$skill_name" == "$core" ]]; then is_core=true break @@ -467,11 +543,59 @@ report_custom_skills() { fi } +cleanup_retired_core_skills() { + local retired skill_dir + + [[ -d ".agents/skills" ]] || return 0 + + for retired in $RETIRED_CORE_SKILLS; do + skill_dir=".agents/skills/$retired" + [[ -e "$skill_dir" || -L "$skill_dir" ]] || continue + + if [[ "$DIFF_ONLY" == "true" ]]; then + log_info " ${RED}[REMOVE]${NC} $skill_dir (retired core skill, preview only)" + pending_change_count=$((pending_change_count + 1)) + continue + fi + + backup_item "$skill_dir" + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${RED}[REMOVE]${NC} $skill_dir (retired core skill)" + else + rm -rf "$skill_dir" + log_info " ${RED}[REMOVE]${NC} $skill_dir (retired core skill)" + fi + done +} + +cleanup_retired_legacy_guidance() { + local path + + for path in $RETIRED_LEGACY_GUIDANCE_FILES; do + [[ -e "$path" || -L "$path" ]] || continue + + if [[ "$DIFF_ONLY" == "true" ]]; then + log_info " ${RED}[REMOVE]${NC} $path (retired legacy guidance, preview only)" + pending_change_count=$((pending_change_count + 1)) + continue + fi + + backup_item "$path" + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${RED}[REMOVE]${NC} $path (retired legacy guidance)" + else + rm -rf "$path" + log_info " ${RED}[REMOVE]${NC} $path (retired legacy guidance)" + fi + done +} + cleanup_stale_claude_code_skill_symlinks() { local agents_skills_dir="$1" local claude_skills_dir="$2" local skill_link skill_name + [[ ! -L "$claude_skills_dir" ]] || return 0 [[ -d "$claude_skills_dir" ]] || return 0 for skill_link in "$claude_skills_dir"/*; do @@ -479,10 +603,15 @@ cleanup_stale_claude_code_skill_symlinks() { is_dot_agents_claude_skill_symlink "$skill_link" || continue skill_name="$(basename "$skill_link")" - [[ -f "$agents_skills_dir/$skill_name/SKILL.md" ]] && continue + if [[ -f "$agents_skills_dir/$skill_name/SKILL.md" ]] && ! is_retired_core_skill "$skill_name"; then + continue + fi - if [[ "$DRY_RUN" == "true" ]]; then + if [[ "$DRY_RUN" == "true" || "$DIFF_ONLY" == "true" ]]; then log_info " ${RED}[REMOVE]${NC} $skill_link (stale)" + if [[ "$DIFF_ONLY" == "true" ]]; then + pending_change_count=$((pending_change_count + 1)) + fi else rm -f "$skill_link" log_info " ${RED}[REMOVE]${NC} $skill_link (stale)" @@ -491,6 +620,7 @@ cleanup_stale_claude_code_skill_symlinks() { } setup_claude_code_integration() { + local source_agents_skills_dir="${1:-.agents/skills}" local agents_skills_dir=".agents/skills" local claude_skills_dir=".claude/skills" local linked=0 @@ -498,17 +628,25 @@ setup_claude_code_integration() { local skill_dir skill_name dest link_target existing_target [[ -d ".claude" ]] || return 0 + if [[ "$DRY_RUN" == "true" || "$DIFF_ONLY" == "true" ]]; then + agents_skills_dir="$source_agents_skills_dir" + fi [[ -d "$agents_skills_dir" ]] || return 0 log_info "" log_info "Detected ${BLUE}.claude/${NC} directory — linking dot-agents skills for Claude Code..." + if [[ -L "$claude_skills_dir" ]]; then + log_info " ${YELLOW}[SKIP]${NC} $claude_skills_dir (user-owned symlink)" + return 0 + fi + if [[ ( -e "$claude_skills_dir" || -L "$claude_skills_dir" ) && ! -d "$claude_skills_dir" ]]; then log_info " ${YELLOW}[SKIP]${NC} $claude_skills_dir (user-owned)" return 0 fi - if [[ "$DRY_RUN" != "true" ]]; then + if [[ "$DRY_RUN" != "true" && "$DIFF_ONLY" != "true" ]]; then if ! mkdir -p "$claude_skills_dir"; then log_info " ${YELLOW}[SKIP]${NC} $claude_skills_dir (could not create directory)" return 0 @@ -520,6 +658,10 @@ setup_claude_code_integration() { [[ -f "$skill_dir/SKILL.md" ]] || continue skill_name="$(basename "$skill_dir")" + if is_retired_core_skill "$skill_name"; then + continue + fi + dest="$claude_skills_dir/$skill_name" link_target="../../.agents/skills/$skill_name" @@ -529,9 +671,12 @@ setup_claude_code_integration() { continue fi if is_dot_agents_claude_skill_symlink "$dest"; then - if [[ "$DRY_RUN" == "true" ]]; then - log_info " ${GREEN}[LINK]${NC} $dest → $link_target" + if [[ "$DRY_RUN" == "true" || "$DIFF_ONLY" == "true" ]]; then + log_info " ${GREEN}[LINK]${NC} $dest → $link_target (preview only)" linked=$((linked + 1)) + if [[ "$DIFF_ONLY" == "true" ]]; then + pending_change_count=$((pending_change_count + 1)) + fi continue fi rm -f "$dest" @@ -546,9 +691,12 @@ setup_claude_code_integration() { continue fi - if [[ "$DRY_RUN" == "true" ]]; then - log_info " ${GREEN}[LINK]${NC} $dest → $link_target" + if [[ "$DRY_RUN" == "true" || "$DIFF_ONLY" == "true" ]]; then + log_info " ${GREEN}[LINK]${NC} $dest → $link_target (preview only)" linked=$((linked + 1)) + if [[ "$DIFF_ONLY" == "true" ]]; then + pending_change_count=$((pending_change_count + 1)) + fi continue fi @@ -570,13 +718,23 @@ setup_claude_code_integration() { ensure_gitignore_entry() { local gitignore_file=".agents/.gitignore" - local backup_entry="../.dot-agents-backup/" + local backup_entry=".dot-agents-backup/" - if [[ "$DRY_RUN" == "true" ]]; then + if [[ "$AGENTS_GITIGNORE_PENDING" == "true" ]]; then + return 0 + fi + + if [[ "$DRY_RUN" == "true" || "$DIFF_ONLY" == "true" ]]; then if [[ ! -f "$gitignore_file" ]]; then log_info " ${GREEN}[CREATE]${NC} $gitignore_file" + if [[ "$DIFF_ONLY" == "true" ]]; then + pending_change_count=$((pending_change_count + 1)) + fi elif ! grep -qxF "$backup_entry" "$gitignore_file" 2>/dev/null; then log_info " ${GREEN}[UPDATE]${NC} $gitignore_file (add backup entry)" + if [[ "$DIFF_ONLY" == "true" ]]; then + pending_change_count=$((pending_change_count + 1)) + fi fi return 0 fi @@ -598,7 +756,15 @@ install_file() { local dest_dir dest_dir="$(dirname "$dest")" - if [[ ! -e "$dest" ]]; then + if [[ ! -e "$dest" && ! -L "$dest" ]]; then + if [[ "$DIFF_ONLY" == "true" ]]; then + log_install "$dest (would install)" + installed_count=$((installed_count + 1)) + pending_change_count=$((pending_change_count + 1)) + mark_agents_gitignore_pending "$dest" + return 0 + fi + if [[ "$DRY_RUN" == "true" ]]; then log_install "$dest" else @@ -631,7 +797,8 @@ install_file() { # Interactive mode if [[ "$INTERACTIVE" == "true" ]] && [[ "$DRY_RUN" != "true" ]]; then local action - action="$(prompt_conflict "$src" "$dest")" + prompt_conflict "$src" "$dest" + action="$PROMPT_ACTION" case "$action" in keep|skip) log_skip "$dest (kept yours)" @@ -654,6 +821,8 @@ install_file() { diff -u "$dest" "$src" 2>/dev/null || true echo "" conflict_count=$((conflict_count + 1)) + pending_change_count=$((pending_change_count + 1)) + mark_agents_gitignore_pending "$dest" return 0 fi @@ -663,9 +832,12 @@ install_file() { else conflict_file="${dest}.dot-agents.new" fi + mark_agents_gitignore_pending "$dest" if [[ "$DRY_RUN" == "true" ]]; then log_conflict "$dest (would write ${conflict_file})" + elif [[ -e "$conflict_file" || -L "$conflict_file" ]]; then + log_conflict "$dest differs. Kept existing ${conflict_file}; remove it to regenerate." else cp -p "$src" "$conflict_file" log_conflict "$dest differs. Wrote ${conflict_file} for review." @@ -682,13 +854,13 @@ process_directory() { local rel_path="${file#$src_dir/}" local dest_path="${dest_dir}/${rel_path}" - # Skip *.md files in user content directories (research, plans, prds) - if [[ "$rel_path" == research/*.md || "$rel_path" == plans/*.md || "$rel_path" == plans/**/*.md || "$rel_path" == prds/*.md ]]; then + # Skip user content directories. Fresh installs get guidance files, not sample work. + if [[ "$rel_path" == research/*.md || "$rel_path" == research/**/*.md || "$rel_path" == work/*/*/* || "$rel_path" == plans/* || "$rel_path" == prds/* ]]; then continue fi - # Skip metadata file in diff mode (it's auto-generated and will always differ) - if [[ "$DIFF_ONLY" == "true" ]] && [[ "$rel_path" == ".dot-agents.json" ]]; then + # Metadata is generated locally by write_metadata. + if [[ "$rel_path" == ".dot-agents.json" ]]; then continue fi @@ -763,13 +935,16 @@ main() { process_directory "${extracted_dir}/.agents" "./.agents" fi + if [[ "$IS_FRESH_INSTALL" != "true" ]]; then + cleanup_retired_core_skills + cleanup_retired_legacy_guidance + fi + # Ensure .agents/.gitignore includes backup directory ensure_gitignore_entry # Link dot-agents skills into Claude Code's project skill directory when present. - if [[ "$DIFF_ONLY" != "true" ]]; then - setup_claude_code_integration - fi + setup_claude_code_integration "${extracted_dir}/.agents/skills" # Skip metadata write in diff-only mode if [[ "$DIFF_ONLY" != "true" ]]; then @@ -781,6 +956,9 @@ main() { log_info " Installed: ${installed_count}" log_info " Skipped: ${skipped_count}" log_info " Conflicts: ${conflict_count}" + if [[ "$DIFF_ONLY" == "true" ]]; then + log_info " Pending changes: ${pending_change_count}" + fi if [[ $backup_count -gt 0 ]]; then log_info " Backed up: ${backup_count}" @@ -802,8 +980,8 @@ main() { fi fi - # In diff mode, exit 1 if conflicts exist - if [[ "$DIFF_ONLY" == "true" ]] && [[ $conflict_count -gt 0 ]]; then + # In diff mode, exit 1 if any change would be applied. + if [[ "$DIFF_ONLY" == "true" ]] && [[ $pending_change_count -gt 0 ]]; then return 1 fi @@ -812,7 +990,7 @@ main() { log_info "" log_info "${GREEN}Next steps:${NC}" log_info " 1. Run 'adapt' to customize AGENTS.md for your project" - log_info " 2. See QUICKSTART.md for workflow guidance" + log_info " 2. Read the quickstart: https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/main/QUICKSTART.md" fi # Show sync update hint on sync (not fresh install) diff --git a/scripts/build-test-fixture.sh b/scripts/build-test-fixture.sh index 0dc98e8..35c74e0 100755 --- a/scripts/build-test-fixture.sh +++ b/scripts/build-test-fixture.sh @@ -32,29 +32,24 @@ if [[ -d "$REPO_ROOT/.agents" ]]; then echo " Added: .agents/" fi -# Add sample files for testing user content preservation +# Add sample files for testing user content preservation and skip rules mkdir -p "$ARCHIVE_DIR/.agents/research" mkdir -p "$ARCHIVE_DIR/.agents/plans/todo" mkdir -p "$ARCHIVE_DIR/.agents/prds" +mkdir -p "$ARCHIVE_DIR/.agents/work/feature/example-work" echo "# Example research" > "$ARCHIVE_DIR/.agents/research/example.md" echo "# Example plan" > "$ARCHIVE_DIR/.agents/plans/todo/plan-001.md" echo "# Example PRD" > "$ARCHIVE_DIR/.agents/prds/feature.md" -echo " Added: sample user content files for testing" - -# Add a sample skill for testing -mkdir -p "$ARCHIVE_DIR/.agents/skills/sample-skill" -cat > "$ARCHIVE_DIR/.agents/skills/sample-skill/SKILL.md" << 'EOF' ---- -name: sample-skill -description: A sample skill for testing ---- - -# Sample Skill - -This is a sample skill used for testing the installation process. +echo "# Example work item" > "$ARCHIVE_DIR/.agents/work/feature/example-work/index.md" +cat > "$ARCHIVE_DIR/.agents/.dot-agents.json" <<'EOF' +{ + "upstream": "https://github.com/example/bogus-dot-agents", + "ref": "bogus-archive-metadata", + "installedAt": "2000-01-01T00:00:00Z" +} EOF -echo " Added: sample-skill for testing" +echo " Added: sample user content files for testing" # Create the archive tar -czf "$FIXTURES_DIR/sample-archive.tar.gz" -C "$TMP_DIR" dot-agents-main diff --git a/scripts/lint.sh b/scripts/lint.sh index afcc23d..6b73f07 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -13,7 +13,11 @@ cd "$ROOT_DIR" SCRIPTS=( install.sh .agents/scripts/sync.sh + .agents/skills/agent-work/scripts/list-work.sh + .agents/skills/agent-work/scripts/new-work.sh + scripts/build-test-fixture.sh scripts/lint.sh + scripts/serve-docs.sh scripts/test.sh test/mocks/curl ) diff --git a/scripts/serve-docs.sh b/scripts/serve-docs.sh index 145c6cc..8f29758 100755 --- a/scripts/serve-docs.sh +++ b/scripts/serve-docs.sh @@ -9,7 +9,7 @@ # ./scripts/serve-docs.sh --docs # Serve docs on port 8000 # -set -e +set -euo pipefail PORT="8000" DIR="site" diff --git a/site/index.html b/site/index.html index f93d6ae..09ea8eb 100644 --- a/site/index.html +++ b/site/index.html @@ -4,19 +4,19 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>dot-agents — AI-ready agent workspace - + - + - + @@ -29,22 +29,23 @@ -

AI-ready workspace for any project

+

Durable context for AI coding agents

-

Ship faster with structured AI workflows

-

One command to set up PRDs, plans, and an execution loop—so you can start building, not just planning.

+

Make AI coding work survive the next thread

+

dot-agents adds a small .agents/ workspace to any repo: durable work items, research notes, plans, and handoff prompts your agents can reuse.

+

Run from your repo root. Fresh installs create AGENTS.md and .agents/; syncs later preserve your work items, research, and customized project instructions.

@@ -58,145 +59,72 @@

Ship faster with structured AI workflows

Review first: curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | less

-

Then point your agent at a real problem and iterate.

-
- Pin a version - curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0 -
-

What you get

+

What it adds

your-project/
-├── AGENTS.md           # Customize for your project
+├── AGENTS.md        # project instructions for agents
 └── .agents/
-    ├── plans/          # todo → in-progress → completed
-    ├── prds/           # Product requirements
-    ├── research/       # Discoveries and context
-    └── skills/         # adapt, ralph, research, tmux
+ ├── work/ # durable work items + ├── research/ # reusable findings + ├── references/ # local reference repos + ├── skills/ # adapt, work items, planning, research + └── scripts/ # sync updates safely
-

Using Claude Code? If .claude/ already exists, install/sync links these skills into .claude/skills/ for project skill discovery.

+

Use work items for multi-session or context-heavy work. Tiny one-shot edits may not need one.

-
-
-
-
-

Instant Setup

-

One command creates .agents/ with plans, PRDs, skills, and research directories.

+
+

Example work item

+

After asking Create a new work item for user authentication, future threads have a durable starting point.

+
+
+
.agents/work/feature/user-authentication/
+├── index.md      # status, summary, next action
+└── plan.md       # implementation tasks, when useful
-
-
📋
-

Structured Plans

-

Task format with dependencies, scopes, and acceptance criteria for autonomous execution.

-
-
-
🤖
-

Autonomous Execution (Ralph)

-

Multi-iteration execution with handoff between agent threads.

-
-
-
🔬
-

Built-in Research

-

Save discoveries to .agents/research/ for persistent project knowledge.

-
-
-
+
+
# User authentication
 
-      
-

The workflow

-
-
-
1
-
- Research - Deep dive into requirements and constraints -
-
-
-
-
2
-
- PRD - Define features and acceptance criteria -
-
-
-
-
3
-
- Plan - Break down into executable tasks -
-
-
-
-
4
-
- Execute - Ralph runs autonomously -
+Status: planned +Category: feature +Updated: 2026-06-22 + +## Summary +Add auth flows and session persistence. + +## Next Action +Implement Task 1 from plan.md.
+

A new thread starts by reading index.md, then loads only the plan, research, or progress it needs.

-
-

Get started in 5 steps

-
-
-
1
-
- Install - curl -fsSL .../install.sh | bash -
+
+

How it works

+

Use natural-language prompts to create only the context each task needs.

+
+
+ Run adapt + Adapt once by filling AGENTS.md with project commands, structure, and conventions.
-
-
2
-
- Adapt - Run adapt -
+
+ Create a new work item for ... + Start durable context under .agents/work/<category>/<slug>/.
-
-
3
-
- Research - Research [topic] -
+
+ Add only needed context + Ask for research, a short requirements brief, or an implementation plan only when it helps.
-
-
4
-
- PRD - Create PRD for [feature] -
-
-
-
5
-
- Execute - Run ralph on [plan] -
+
+ Write a handoff prompt for ... + Generate a scoped prompt for a fresh implementation thread that records progress as it works.
-
-

Inspiration

-

- A mindset we like: doing the thing is doing the thing — ship, observe, iterate. -

- -
-
Quickstart diff --git a/site/style.css b/site/style.css index 976e19a..c1881ad 100644 --- a/site/style.css +++ b/site/style.css @@ -3,7 +3,7 @@ --bg-secondary: #12121a; --bg-card: #16161f; --text: #e8e8ed; - --text-muted: #8b8b9e; + --text-muted: #a0a0b4; --accent: #00d9ff; --accent-glow: rgba(0, 217, 255, 0.15); --border: #2a2a3a; @@ -125,13 +125,42 @@ header { margin: 0 auto; } +.hero-desc code { + font-family: "SF Mono", "Fira Code", "Consolas", monospace; + font-size: 1rem; + color: var(--text); + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 4px; + padding: 0.1rem 0.35rem; +} + /* Install section */ .install { margin: 1rem 0 3rem; } +.install-note { + max-width: 640px; + margin: 0 auto 1rem; + color: var(--text-muted); + font-size: 0.9375rem; + text-align: center; +} + +.install-note code { + font-family: "SF Mono", "Fira Code", "Consolas", monospace; + font-size: 0.875rem; + color: var(--text); + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 4px; + padding: 0.15rem 0.35rem; +} + .code-block { position: relative; + max-width: 100%; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 12px; @@ -164,11 +193,12 @@ header { .terminal-dot.green { background: #27c93f; } .code-block pre { - padding: 1.25rem 3.5rem 1.25rem 1.25rem; + padding: 1.25rem 4.75rem 1.25rem 1.25rem; font-family: "SF Mono", "Fira Code", "Consolas", monospace; font-size: 0.9rem; line-height: 1.6; overflow-x: auto; + -webkit-overflow-scrolling: touch; } .code-block code { @@ -236,54 +266,57 @@ header { } .install-hint code { + display: inline-block; + max-width: 100%; font-family: "SF Mono", "Fira Code", "Consolas", monospace; font-size: 0.8125rem; background: var(--bg-secondary); padding: 0.2rem 0.4rem; border-radius: 4px; border: 1px solid var(--border); + overflow-wrap: anywhere; } -.install-details { - margin-top: 0.5rem; - font-size: 0.875rem; +.section-intro { + max-width: 640px; + margin: 0 auto 1.25rem; color: var(--text-muted); + font-size: 0.9375rem; text-align: center; } -.install-details summary { - cursor: pointer; - color: var(--accent); -} - -.install-details summary:hover { - text-decoration: underline; -} - -.install-details code { - display: block; - margin-top: 0.5rem; +.section-intro code { font-family: "SF Mono", "Fira Code", "Consolas", monospace; - font-size: 0.8125rem; + font-size: 0.875rem; + color: var(--text); background: var(--bg-secondary); - padding: 0.5rem 0.75rem; - border-radius: 4px; border: 1px solid var(--border); + border-radius: 4px; + padding: 0.15rem 0.35rem; } /* What you get */ -.what-you-get { +.what-you-get, +.example-work-item { margin: 2rem 0 3rem; text-align: center; } -.what-you-get h2 { +.what-you-get h2, +.example-work-item h2 { font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; color: var(--text-muted); } +.example-grid { + display: grid; + gap: 0.75rem; + max-width: 720px; + margin: 0 auto 1rem; +} + .tree-block { text-align: left; box-shadow: none; @@ -297,320 +330,57 @@ header { color: var(--text-muted); } -/* Features */ -.features { +/* How it works */ +.how-it-works { margin: 3rem 0; -} - -.feature-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 1rem; -} - -.feature-card { - background: var(--bg-secondary); - border: 1px solid var(--border); - border-radius: 12px; - padding: 1.5rem; - transition: - transform var(--t-med) var(--ease-out), - border-color var(--t-med) var(--ease-out), - box-shadow var(--t-med) var(--ease-out), - background var(--t-med) var(--ease-out); -} - -.feature-card:hover { - transform: translateY(-2px); - border-color: rgba(0, 217, 255, 0.25); - box-shadow: 0 0 0 1px rgba(0, 217, 255, 0.08), 0 16px 32px rgba(0, 0, 0, 0.35); - background: linear-gradient(180deg, rgba(0, 217, 255, 0.04), transparent 55%); -} - -.feature-icon { - font-size: 1.5rem; - margin-bottom: 0.75rem; - transition: transform var(--t-med) var(--ease-out); -} - -.feature-card:hover .feature-icon { - transform: translateY(-2px); -} - -.feature-card h3 { - font-size: 1rem; - font-weight: 600; - margin-bottom: 0.5rem; -} - -.feature-card p { - font-size: 0.875rem; - color: var(--text-muted); - line-height: 1.5; -} - -.feature-card .term { - font-size: 0.85rem; - font-weight: 400; -} - -.feature-card .term a { - color: var(--accent); - text-decoration: none; -} - -.feature-card .term a:hover { - text-decoration: underline; -} - -/* Workflow - Timeline/Flow style */ -.workflow { - margin: 4rem 0 3rem; text-align: center; } -.workflow h2 { +.how-it-works h2 { font-size: 1.25rem; font-weight: 600; - margin-bottom: 2rem; - color: var(--text-muted); -} - -.workflow-steps { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 1.5rem; - position: relative; - padding: 0 1rem; -} - -/* Connector line behind steps (desktop) */ -.workflow-steps::before { - content: ""; - position: absolute; - left: 4rem; - right: 4rem; - top: 6px; - height: 2px; - background: linear-gradient(90deg, var(--accent), var(--border) 50%, var(--accent)); - opacity: 0.6; -} - -.step { - display: flex; - flex-direction: column; - align-items: center; - gap: 0.75rem; - background: transparent; - border: none; - padding: 0; - position: relative; - z-index: 1; - transition: transform var(--t-med) var(--ease-out); -} - -.step:hover { - transform: translateY(-2px); -} - -.step-num { - width: 14px; - height: 14px; - background: var(--accent); - border-radius: 50%; - font-size: 0; - color: transparent; - box-shadow: 0 0 0 4px rgba(0, 217, 255, 0.15), 0 0 12px rgba(0, 217, 255, 0.3); - flex-shrink: 0; - transition: - box-shadow var(--t-med) var(--ease-out), - transform var(--t-med) var(--ease-out); -} - -.step:hover .step-num { - transform: scale(1.15); - box-shadow: - 0 0 0 6px rgba(0, 217, 255, 0.18), - 0 0 20px rgba(0, 217, 255, 0.5); -} - -.step-content { - display: flex; - flex-direction: column; - text-align: center; - gap: 0.25rem; -} - -.step-content strong { - font-size: 1rem; - font-weight: 600; - color: var(--text); -} - -.step-content span { - font-size: 0.875rem; - color: var(--text-muted); - line-height: 1.5; -} - -.step-arrow { - display: none; -} - -/* Quickstart - Terminal checklist style */ -.quickstart { - margin: 3rem 0; - text-align: center; - padding: 2rem 1.5rem; - border: 1px solid rgba(42, 42, 58, 0.6); - border-radius: 16px; - background: linear-gradient(180deg, rgba(0, 217, 255, 0.04) 0%, transparent 60%); -} - -.quickstart h2 { - font-size: 1.25rem; - font-weight: 600; - margin-bottom: 1.5rem; + margin-bottom: 0.75rem; color: var(--text-muted); } -.quickstart-steps { +.command-list { display: flex; flex-direction: column; gap: 0.6rem; - max-width: 480px; + max-width: 720px; margin: 0 auto; } -.qs-step { - display: flex; - align-items: center; +.command-row { + display: grid; + grid-template-columns: minmax(190px, 240px) 1fr; gap: 1rem; + align-items: start; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 10px; - padding: 0.9rem 1.25rem; - position: relative; + padding: 0.95rem 1.1rem; text-align: left; - transition: - transform var(--t-med) var(--ease-out), - border-color var(--t-med) var(--ease-out), - box-shadow var(--t-med) var(--ease-out); -} - -.qs-step:hover { - transform: translateY(-2px); - border-color: rgba(0, 217, 255, 0.3); - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); -} - -/* Cyan accent bar on left */ -.qs-step::before { - content: ""; - position: absolute; - left: 0; - top: 10px; - bottom: 10px; - width: 3px; - background: var(--accent); - border-radius: 999px; - opacity: 0.8; - transition: opacity var(--t-med) var(--ease-out), filter var(--t-med) var(--ease-out); -} - -.qs-step:hover::before { - opacity: 1; - filter: brightness(1.2); -} - -.qs-num { - width: auto; - height: auto; - background: transparent; - color: var(--text-muted); - border: 1px solid var(--border); - border-radius: 999px; - padding: 0.15rem 0.6rem; - font-size: 0.75rem; - font-weight: 600; - flex-shrink: 0; -} - -.qs-content { - display: flex; - flex-direction: column; - gap: 0.35rem; -} - -.qs-content strong { - font-size: 1rem; - font-weight: 600; - color: var(--text); } -.qs-content code { +.command-row code { font-family: "SF Mono", "Fira Code", "Consolas", monospace; - font-size: 0.875rem; + font-size: 0.8125rem; color: var(--accent); - background: var(--bg-card); - border: 1px solid var(--border); - padding: 0.25rem 0.5rem; - border-radius: 5px; - display: inline-block; -} - -/* Inspiration */ -.inspiration { - margin: 3rem 0; - text-align: center; - padding: 2rem 1.5rem; - border: 1px solid rgba(42, 42, 58, 0.6); - border-radius: 16px; - background: linear-gradient(180deg, rgba(124, 58, 237, 0.06) 0%, transparent 60%); } -.inspiration h2 { - font-size: 1.25rem; - font-weight: 600; - margin-bottom: 0.75rem; +.command-row span { color: var(--text-muted); + font-size: 0.875rem; + line-height: 1.5; } -.inspiration-desc { - max-width: 560px; - margin: 0 auto 1rem; - color: var(--text-muted); - font-size: 1rem; -} - -.inspiration-desc em { +.command-row span code { color: var(--text); - font-style: italic; -} - -.inspiration-links { - list-style: none; - padding: 0; - margin: 0; -} - -.inspiration-links li { - font-size: 0.9375rem; -} - -.inspiration-links a { - color: var(--accent); - text-decoration: none; - transition: color var(--t-fast); -} - -.inspiration-links a:hover { - text-decoration: underline; -} - -.muted { - color: var(--text-muted); - font-size: 0.875rem; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 4px; + padding: 0.1rem 0.3rem; } /* CTA */ @@ -696,20 +466,21 @@ footer a:hover { font-size: 1rem; } - .feature-grid { + .command-row { grid-template-columns: 1fr; + gap: 0.5rem; } - .workflow-steps { - grid-template-columns: 1fr 1fr; - gap: 1.5rem 1rem; + .code-block pre { + font-size: 0.8rem; } - .workflow-steps::before { + .tree-comment { display: none; } - .code-block pre { - font-size: 0.8rem; + .tree-block pre { + padding: 1rem; + font-size: 0.75rem; } } diff --git a/test/fixtures/sample-archive.tar.gz b/test/fixtures/sample-archive.tar.gz index 1e73744..ad61b71 100644 Binary files a/test/fixtures/sample-archive.tar.gz and b/test/fixtures/sample-archive.tar.gz differ diff --git a/test/integration/install.bats b/test/integration/install.bats index a681e64..d7e975d 100755 --- a/test/integration/install.bats +++ b/test/integration/install.bats @@ -55,6 +55,17 @@ teardown() { [ -f "AGENTS.md" ] [ -d ".agents" ] [ -d ".agents/skills" ] + [ -f ".agents/work/AGENTS.md" ] + [ -d ".agents/references" ] + [ -f ".agents/references/.gitkeep" ] + [ -f ".agents/skills/adapt/SKILL.md" ] + [ -f ".agents/skills/agent-work/SKILL.md" ] + [ -f ".agents/skills/feature-planning/SKILL.md" ] + [ -f ".agents/skills/research/SKILL.md" ] + [ -f ".agents/skills/tmux/SKILL.md" ] + [ ! -d ".agents/skills/ralph" ] + [ ! -d ".agents/plans" ] + [ ! -d ".agents/prds" ] } @test "fresh install creates .agents/.dot-agents.json with valid JSON" { @@ -68,6 +79,8 @@ teardown() { run cat ".agents/.dot-agents.json" assert_output --partial "upstream" assert_output --partial "installedAt" + refute_output --partial "bogus-archive-metadata" + refute_output --partial "example/bogus-dot-agents" } @test "identical files are skipped on re-install" { @@ -106,7 +119,7 @@ teardown() { bash "$INSTALL_SCRIPT" --yes # Modify a skill file (not AGENTS.md which is skipped on sync) - echo "# Modified skill" > .agents/skills/sample-skill/SKILL.md + echo "# Modified skill" > .agents/skills/research/SKILL.md # Force re-install run bash "$INSTALL_SCRIPT" --force --yes @@ -115,6 +128,8 @@ teardown() { # Should create backup directory run find . -type d -name ".dot-agents-backup*" assert_output --partial ".dot-agents-backup" + [ -d ".agents/.dot-agents-backup" ] + [ ! -d ".dot-agents-backup" ] } @test "--uninstall removes installed files" { @@ -189,25 +204,144 @@ teardown() { [ -d ".agents" ] } -@test "md files in research/plans/prds are not installed" { +@test "user content samples are not installed" { run bash "$INSTALL_SCRIPT" --yes assert_success # Skills should be installed - [ -f ".agents/skills/sample-skill/SKILL.md" ] + [ -f ".agents/skills/agent-work/SKILL.md" ] + [ -f ".agents/work/AGENTS.md" ] # User content directories should NOT have md files from upstream [ ! -f ".agents/research/example.md" ] + [ ! -f ".agents/work/feature/example-work/index.md" ] [ ! -f ".agents/plans/todo/plan-001.md" ] [ ! -f ".agents/prds/feature.md" ] + [ ! -d ".agents/plans" ] + [ ! -d ".agents/prds" ] } -@test "--write-conflicts creates .dot-agents.new files for conflicts" { +@test "agent-work helpers create and list work items" { + bash "$INSTALL_SCRIPT" --yes + + run .agents/skills/agent-work/scripts/new-work.sh \ + --category feature \ + --slug demo-work \ + --title "Demo work" \ + --status planned + assert_success + assert_output ".agents/work/feature/demo-work/index.md" + + [ -f ".agents/work/feature/demo-work/index.md" ] + [ ! -d ".agents/work/feature/demo-work/decisions" ] + + run .agents/skills/agent-work/scripts/list-work.sh --status planned + assert_success + assert_output --partial "Demo work" + assert_output --partial "planned" + + run .agents/skills/agent-work/scripts/list-work.sh --status blocked + assert_success + refute_output --partial "Demo work" +} + +@test "agent-work helper rejects invalid status" { + bash "$INSTALL_SCRIPT" --yes + + run .agents/skills/agent-work/scripts/new-work.sh \ + --category feature \ + --slug invalid-status \ + --title "Invalid status" \ + --status unknown + assert_failure + assert_output --partial "Invalid status" +} + +@test "agent-work helper rejects invalid category" { + bash "$INSTALL_SCRIPT" --yes + + run .agents/skills/agent-work/scripts/new-work.sh \ + --category custom-category \ + --slug invalid-category \ + --title "Invalid category" + assert_failure + assert_output --partial "Invalid category" + assert_output --partial "Expected one of" +} + +@test "sync preserves existing work item content" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/work/feature/demo-work + echo "# Demo Work" > .agents/work/feature/demo-work/index.md + echo "- [ ] Keep this task" > .agents/work/feature/demo-work/plan.md + echo "progress stays" > .agents/work/feature/demo-work/progress.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + run cat .agents/work/feature/demo-work/index.md + assert_output "# Demo Work" + + run cat .agents/work/feature/demo-work/plan.md + assert_output "- [ ] Keep this task" + + run cat .agents/work/feature/demo-work/progress.md + assert_output "progress stays" +} + +@test "sync preserves legacy plans and PRDs as user content" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/plans/in-progress .agents/prds + echo "# Legacy plan" > .agents/plans/in-progress/demo.md + echo "# Legacy PRD" > .agents/prds/demo.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + run cat .agents/plans/in-progress/demo.md + assert_output "# Legacy plan" + + run cat .agents/prds/demo.md + assert_output "# Legacy PRD" +} + +@test "sync removes retired legacy guidance and templates with backup" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/plans .agents/prds + echo "Use Ralph for plans" > .agents/plans/AGENTS.md + echo "# Old plan template" > .agents/plans/TEMPLATE.md + echo "Use Ralph for PRDs" > .agents/prds/AGENTS.md + echo "# Old PRD template" > .agents/prds/TEMPLATE.md + echo "# Real PRD" > .agents/prds/demo.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "retired legacy guidance" + assert_output --partial "BACKUP" + + [ ! -e ".agents/plans/AGENTS.md" ] + [ ! -e ".agents/plans/TEMPLATE.md" ] + [ ! -e ".agents/prds/AGENTS.md" ] + [ ! -e ".agents/prds/TEMPLATE.md" ] + [ -f ".agents/prds/demo.md" ] + + run find .agents/.dot-agents-backup -path '*/.agents/prds/AGENTS.md' -type f + assert_output --partial ".agents/prds/AGENTS.md" + + run find .agents/.dot-agents-backup -path '*/.agents/plans/TEMPLATE.md' -type f + assert_output --partial ".agents/plans/TEMPLATE.md" +} + +@test "--write-conflicts creates .dot-agents.md files for Markdown conflicts" { # First install bash "$INSTALL_SCRIPT" --yes # Modify a skill file to create conflict - echo "# Modified skill" > .agents/skills/sample-skill/SKILL.md + echo "# Modified skill" > .agents/skills/research/SKILL.md # Re-install with --write-conflicts should create conflict files run bash "$INSTALL_SCRIPT" --write-conflicts --yes @@ -215,7 +349,78 @@ teardown() { assert_output --partial "CONFLICT" # Should create conflict file for the skill - [ -f ".agents/skills/sample-skill/SKILL.dot-agents.md" ] + [ -f ".agents/skills/research/SKILL.dot-agents.md" ] +} + +@test "--write-conflicts creates .dot-agents.new files for non-Markdown conflicts" { + bash "$INSTALL_SCRIPT" --yes + + printf '# Custom ignore\n.dot-agents-backup/\n' > .agents/.gitignore + + run bash "$INSTALL_SCRIPT" --write-conflicts --yes + assert_success + assert_output --partial "CONFLICT" + + [ -f ".agents/.gitignore.dot-agents.new" ] +} + +@test "--write-conflicts does not mutate conflicted .agents/.gitignore" { + bash "$INSTALL_SCRIPT" --yes + + printf '# Custom ignore\n' > .agents/.gitignore + local original_gitignore + original_gitignore=$(cat .agents/.gitignore) + + run bash "$INSTALL_SCRIPT" --write-conflicts --yes + assert_success + assert_output --partial "CONFLICT" + + [ -f ".agents/.gitignore.dot-agents.new" ] + run cat .agents/.gitignore + assert_output "$original_gitignore" +} + +@test "--write-conflicts preserves an existing conflict sidecar" { + bash "$INSTALL_SCRIPT" --yes + + echo "# Modified skill" > .agents/skills/research/SKILL.md + echo "review notes stay" > .agents/skills/research/SKILL.dot-agents.md + + run bash "$INSTALL_SCRIPT" --write-conflicts --yes + assert_success + assert_output --partial "Kept existing ./.agents/skills/research/SKILL.dot-agents.md" + + run cat .agents/skills/research/SKILL.dot-agents.md + assert_output "review notes stay" +} + +@test "--interactive overwrite applies selected conflict action" { + bash "$INSTALL_SCRIPT" --yes + + echo "# Modified skill" > .agents/skills/research/SKILL.md + + run env DOT_AGENTS_INTERACTIVE_RESPONSE=o bash "$INSTALL_SCRIPT" --interactive --yes + assert_success + assert_output --partial "overwritten" + assert_output --partial "BACKUP" + + run head -1 .agents/skills/research/SKILL.md + assert_output "---" + [ ! -f ".agents/skills/research/SKILL.dot-agents.md" ] +} + +@test "--interactive keep preserves selected local conflict" { + bash "$INSTALL_SCRIPT" --yes + + echo "# Modified skill" > .agents/skills/research/SKILL.md + + run env DOT_AGENTS_INTERACTIVE_RESPONSE=k bash "$INSTALL_SCRIPT" --interactive --yes + assert_success + assert_output --partial "kept yours" + + run cat .agents/skills/research/SKILL.md + assert_output "# Modified skill" + [ ! -f ".agents/skills/research/SKILL.dot-agents.md" ] } @test "sync defaults to force mode (overwrites with backup)" { @@ -223,7 +428,7 @@ teardown() { bash "$INSTALL_SCRIPT" --yes # Modify a skill file to create conflict - echo "# Modified skill" > .agents/skills/sample-skill/SKILL.md + echo "# Modified skill" > .agents/skills/research/SKILL.md # Re-install (sync) should default to force mode run bash "$INSTALL_SCRIPT" @@ -236,12 +441,56 @@ teardown() { assert_output --partial ".dot-agents-backup" } +@test "sync backs up symlinked managed files without following them" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p external + echo "custom skill link target" > external/research-skill.md + rm .agents/skills/research/SKILL.md + ln -s ../../../external/research-skill.md .agents/skills/research/SKILL.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + assert_output --partial "force overwrite" + assert_output --partial "BACKUP" + + [ ! -L ".agents/skills/research/SKILL.md" ] + local backup_link + backup_link=$(find .agents/.dot-agents-backup -path '*/.agents/skills/research/SKILL.md' -type l | head -1) + [ -n "$backup_link" ] + + local target + target="$(readlink "$backup_link")" + [ "$target" = "../../../external/research-skill.md" ] +} + +@test "sync backs up broken symlinked managed files without following them" { + bash "$INSTALL_SCRIPT" --yes + + rm .agents/skills/research/SKILL.md + ln -s ../../../missing-research-skill.md .agents/skills/research/SKILL.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + assert_output --partial "force overwrite" + assert_output --partial "BACKUP" + + [ ! -L ".agents/skills/research/SKILL.md" ] + local backup_link + backup_link=$(find .agents/.dot-agents-backup -path '*/.agents/skills/research/SKILL.md' -type l | head -1) + [ -n "$backup_link" ] + + local target + target="$(readlink "$backup_link")" + [ "$target" = "../../../missing-research-skill.md" ] +} + @test "--diff shows unified diff for conflicts" { # First install bash "$INSTALL_SCRIPT" --yes # Modify a skill file to create conflict - echo "# Modified skill" > .agents/skills/sample-skill/SKILL.md + echo "# Modified skill" > .agents/skills/research/SKILL.md # --diff should show diff output run bash "$INSTALL_SCRIPT" --diff @@ -251,7 +500,7 @@ teardown() { assert_output --partial "+++" # Diff header # Should NOT create conflict files - [ ! -f ".agents/skills/sample-skill/SKILL.dot-agents.md" ] + [ ! -f ".agents/skills/research/SKILL.dot-agents.md" ] } @test "--diff exits 0 when no conflicts" { @@ -273,7 +522,7 @@ teardown() { original_meta=$(cat .agents/.dot-agents.json) # Modify a skill file - echo "# Modified skill" > .agents/skills/sample-skill/SKILL.md + echo "# Modified skill" > .agents/skills/research/SKILL.md # --diff should not update metadata run bash "$INSTALL_SCRIPT" --diff @@ -284,6 +533,147 @@ teardown() { assert_output "$original_meta" } +@test "--diff exits 1 when core files are missing without installing them" { + bash "$INSTALL_SCRIPT" --yes + + rm -rf .agents/skills/agent-work + + local original_meta + original_meta=$(cat .agents/.dot-agents.json) + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "would install" + assert_output --partial "Pending changes:" + + [ ! -d ".agents/skills/agent-work" ] + [ ! -d ".agents/.dot-agents-backup" ] + + run cat .agents/.dot-agents.json + assert_output "$original_meta" +} + +@test "--diff exits 1 for retired Ralph without removing it" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/skills/ralph + echo "# Legacy Ralph" > .agents/skills/ralph/SKILL.md + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "retired core skill, preview only" + assert_output --partial "Pending changes:" + + [ -f ".agents/skills/ralph/SKILL.md" ] + [ ! -d ".agents/.dot-agents-backup" ] +} + +@test "--diff exits 1 for retired legacy guidance without removing it" { + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/prds + echo "Use Ralph" > .agents/prds/AGENTS.md + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "retired legacy guidance, preview only" + assert_output --partial "Pending changes:" + + [ -f ".agents/prds/AGENTS.md" ] + [ ! -d ".agents/.dot-agents-backup" ] +} + +@test "--diff counts .agents/.gitignore once when the file is missing" { + bash "$INSTALL_SCRIPT" --yes + rm .agents/.gitignore + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "./.agents/.gitignore (would install)" + assert_output --partial "Pending changes: 1" +} + +@test "--diff exits 1 for pending Claude Code skill links without creating them" { + bash "$INSTALL_SCRIPT" --yes + mkdir -p .claude + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "Claude Code skills linked" + assert_output --partial ".claude/skills/agent-work" + assert_output --partial "Pending changes:" + + [ ! -e ".claude/skills" ] +} + +@test "--diff previews Claude Code skill links on fresh install without creating them" { + mkdir -p .claude + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial "Claude Code skills linked" + assert_output --partial ".claude/skills/agent-work" + assert_output --partial "Pending changes:" + + [ ! -e ".claude/skills" ] + [ ! -d ".agents" ] +} + +@test "--dry-run previews Claude Code skill links on fresh install without creating them" { + mkdir -p .claude + + run bash "$INSTALL_SCRIPT" --dry-run + assert_success + assert_output --partial "Claude Code skills linked" + assert_output --partial ".claude/skills/agent-work" + + [ ! -e ".claude/skills" ] + [ ! -d ".agents" ] +} + +@test "--diff exits 1 for stale retired Ralph Claude Code symlink without removing it" { + mkdir -p .claude + bash "$INSTALL_SCRIPT" --yes + + mkdir -p .agents/skills/ralph + echo "# Legacy Ralph" > .agents/skills/ralph/SKILL.md + ln -s ../../.agents/skills/ralph .claude/skills/ralph + + run bash "$INSTALL_SCRIPT" --diff + assert_failure + assert_output --partial ".claude/skills/ralph (stale)" + assert_output --partial "Pending changes:" + + [ -L ".claude/skills/ralph" ] +} + +@test "clean sync does not create backup for generated metadata" { + bash "$INSTALL_SCRIPT" --yes + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + [ ! -d ".agents/.dot-agents-backup" ] +} + +@test "sync drops deprecated singular reference ignore but preserves content" { + bash "$INSTALL_SCRIPT" --yes + mkdir -p .agents/reference/legacy-repo + echo "legacy" > .agents/reference/legacy-repo/file.txt + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + # Sync never deletes user files; the legacy checkout stays on disk. + [ -f ".agents/reference/legacy-repo/file.txt" ] + + # The deprecated singular path is no longer ignored; only references/ is. + run cat .agents/.gitignore + refute_line "reference/" + assert_line "references/*" + assert_line "!references/.gitkeep" +} + # ===== Task 1: .gitignore entry tests ===== @test "fresh install creates .agents/.gitignore with backup entry" { @@ -293,7 +683,7 @@ teardown() { # .gitignore should exist and contain backup entry [ -f ".agents/.gitignore" ] run cat ".agents/.gitignore" - assert_output --partial "../.dot-agents-backup/" + assert_output --partial ".dot-agents-backup/" } @test "sync overwrites .agents/.gitignore and adds backup entry" { @@ -311,7 +701,7 @@ teardown() { # Should contain backup entry (custom content overwritten by upstream) run cat ".agents/.gitignore" - assert_output --partial "../.dot-agents-backup/" + assert_output --partial ".dot-agents-backup/" } # ===== Task 2: Post-install guidance tests ===== @@ -323,7 +713,7 @@ teardown() { # Should show next steps assert_output --partial "Next steps:" assert_output --partial "Run 'adapt'" - assert_output --partial "QUICKSTART.md" + assert_output --partial "https://github.com/colmarius/dot-agents/blob/main/QUICKSTART.md" } @test "sync does not show next steps guidance" { @@ -425,7 +815,8 @@ teardown() { assert_output --partial "Claude Code skills linked" [ -L ".claude/skills/adapt" ] - [ -L ".claude/skills/ralph" ] + [ -L ".claude/skills/agent-work" ] + [ -L ".claude/skills/feature-planning" ] [ -L ".claude/skills/research" ] [ -L ".claude/skills/tmux" ] @@ -434,7 +825,7 @@ teardown() { [ "$target" = "../../.agents/skills/adapt" ] # Directory symlinks expose supporting skill files, not just SKILL.md. - [ -f ".claude/skills/ralph/references/progress-format.md" ] + [ -f ".claude/skills/agent-work/assets/plan-template.md" ] } @test "install does not create .claude when absent" { @@ -456,6 +847,20 @@ teardown() { assert_output "user file" } +@test "install skips Claude Code integration when .claude/skills is user-owned symlink" { + mkdir -p .claude external-skills + ln -s ../external-skills .claude/skills + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial ".claude/skills (user-owned symlink)" + [ -L ".claude/skills" ] + + run find external-skills -mindepth 1 -maxdepth 1 -print + assert_output "" +} + @test "install preserves existing Claude Code user skill directory" { mkdir -p .claude/skills/adapt echo "# User adapt skill" > .claude/skills/adapt/SKILL.md @@ -497,6 +902,76 @@ teardown() { [ ! -L ".claude/skills/old-skill" ] } +@test "sync preserves symlinked Claude Code skills directory" { + mkdir -p .claude external-skills + ln -s ../external-skills .claude/skills + + bash "$INSTALL_SCRIPT" --yes + ln -s ../../.agents/skills/old-skill external-skills/old-skill + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial ".claude/skills (user-owned symlink)" + [ -L ".claude/skills" ] + [ -L "external-skills/old-skill" ] +} + +@test "sync removes retired Ralph Claude Code skill symlink" { + mkdir -p .claude + + bash "$INSTALL_SCRIPT" --yes + mkdir -p .agents/skills/ralph + echo "# Legacy Ralph" > .agents/skills/ralph/SKILL.md + ln -s ../../.agents/skills/ralph .claude/skills/ralph + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + [ ! -L ".claude/skills/ralph" ] +} + +@test "sync removes retired ralph core skill with backup" { + bash "$INSTALL_SCRIPT" --yes + mkdir -p .agents/skills/ralph + echo "# Legacy Ralph" > .agents/skills/ralph/SKILL.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "retired core skill" + assert_output --partial "BACKUP" + [ ! -d ".agents/skills/ralph" ] + + run find .agents/.dot-agents-backup -path '*/.agents/skills/ralph/SKILL.md' -type f + assert_output --partial ".agents/skills/ralph/SKILL.md" + + local backup_file + backup_file=$(find .agents/.dot-agents-backup -path '*/.agents/skills/ralph/SKILL.md' -type f | head -1) + run cat "$backup_file" + assert_output "# Legacy Ralph" +} + +@test "sync backs up symlinked retired ralph core skill without following it" { + bash "$INSTALL_SCRIPT" --yes + ln -s ../missing-ralph .agents/skills/ralph + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "retired core skill" + assert_output --partial "BACKUP" + [ ! -L ".agents/skills/ralph" ] + + local backup_link + backup_link=$(find .agents/.dot-agents-backup -path '*/.agents/skills/ralph' -type l | head -1) + [ -n "$backup_link" ] + + local target + target="$(readlink "$backup_link")" + [ "$target" = "../missing-ralph" ] +} + @test "--uninstall removes only dot-agents Claude Code skill symlinks" { mkdir -p .claude @@ -508,6 +983,22 @@ teardown() { assert_success [ ! -L ".claude/skills/adapt" ] - [ ! -L ".claude/skills/ralph" ] + [ ! -L ".claude/skills/agent-work" ] + [ ! -L ".claude/skills/feature-planning" ] [ -f ".claude/skills/my-custom-skill/SKILL.md" ] } + +@test "--uninstall preserves symlinked Claude Code skills directory" { + mkdir -p .claude external-skills + ln -s ../external-skills .claude/skills + + bash "$INSTALL_SCRIPT" --yes + ln -s ../../.agents/skills/adapt external-skills/adapt + + run bash "$INSTALL_SCRIPT" --uninstall --yes + assert_success + + assert_output --partial ".claude/skills (user-owned symlink)" + [ -L ".claude/skills" ] + [ -L "external-skills/adapt" ] +}