Skip to content

Latest commit

 

History

History
305 lines (228 loc) · 18.7 KB

File metadata and controls

305 lines (228 loc) · 18.7 KB

OpenSpec Instructions

These instructions are for AI assistants working in this project.

Always open @/openspec/AGENTS.md when the request:

  • Mentions planning or proposals (words like proposal, spec, change, plan)
  • Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
  • Sounds ambiguous and you need the authoritative spec before coding

Use @/openspec/AGENTS.md to learn:

  • How to create and apply change proposals
  • Spec format and conventions
  • Project structure and guidelines

Keep this managed block so 'openspec update' can refresh the instructions.

AGENTS.md

This file provides essential context for AI assistants working with the dots repository.

Quick Start

Build and run the CLI:

go install ./...
dots

Essential Commands for Development

Building & Testing

go install ./...                              # Build all binaries
revive -set_exit_status ./...                # Run linter

Core CLI Commands

dots install all                              # Full system setup
dots install <component>                      # Install specific component
dots update                                   # Update configuration
dots doctor                                   # Run diagnostics

Spec-Driven Development (OpenSpec)

Route every spec-worthy change through openspec/ before writing code. Any behavioral change — new CLI command or component, changed install/update behavior, new skill/custom agent/hook, an altered convention or invariant — gets a change folder first:

  1. Create openspec/changes/<name>/ with proposal.md, delta specs under specs/<capability>/spec.md, and tasks.md. Use a kebab-case, verb-led change-id (add-, update-, remove-, refactor-).
  2. Run openspec validate <name> --strict and get approval before implementing.
  3. Implement against the tasks, keeping deltas in sync as requirements shift.
  4. Archive within the same PR, before merge — run openspec archive <name> --yes (or apply it by hand: merge the delta requirements into the base specs under openspec/specs/<capability>/ and move the change folder to openspec/changes/archive/<YYYY-MM-DD>-<name>/) and commit the result on the change branch. Squash-merge applies the work immediately, so the base-spec update must land atomically with the PR — do NOT leave archiving as a separate post-merge step (that strands the base specs behind shipped code).

Skip the change folder only for genuinely non-behavioral work: docs, comments, formatting, test-only edits, mechanical refactors, non-breaking dependency bumps, config changes. When unsure, write the change.

See @/openspec/AGENTS.md for the full spec format, delta conventions, and CLI reference.

Specs are LOCAL DOCS only (see openspec/project.md → OpenSpec note): nothing in CI, the build, or the runtime reads them, and that stays true. Never wire openspec validate (or any spec tooling) into CI. The quality gate is and stays the Pre-Completion Checklist below (go install ./..., revive, go test ./..., the skill tests, the skill linter, and qlty).

Repository Structure

/Users/darrencheng/.dots/
├── main.go                    # Entry point → cli/commands.Execute()
├── cli/commands/              # All CLI commands (Cobra framework)
│   ├── install.go            # Install orchestration
│   └── install/              # Component installers
├── agents/
│   ├── skills/               # Cross-agent skills (SKILL.md per skill)
│   ├── hooks/                # Claude Code hooks (registered via dots install agents)
│   └── custom/               # Custom agent types (.md per agent → ~/.claude/agents/)
├── cmd/                      # 25 standalone utilities
└── pkg/                      # Shared utilities (log, run, cache, path)

Context Directory

context/ is a durable, cross-session store for project knowledge, checked into git so it persists across clones:

  • context/knowledge/index.md — knowledge graph index; one topic file per domain, indexed here
  • context/research/ — investigation notes and spike results
  • context/plans/ — strategic plans and proposals

Read context/knowledge/index.md when you need project history or domain context beyond what's in this file. Populated and maintained via the /improve skill.

Key Development Patterns

  1. Command Execution: Use pkg/run package

    • run.Verbose() - Show output
    • run.Silent() - Hide output
    • exec() helper in installers for error handling
  2. Adding Components:

    • Add to commands slice in cli/commands/install.go
    • Create method in cli/commands/install/<component>.go
  3. Logging: Use pkg/log for consistent output

  4. Testing: All new Go code must include tests

    • Pure logic functions must have unit tests (*_test.go in the same package)
    • Skill scripts with testable logic should have bash tests in .github/skill-tests/
    • CI runs go test ./... and bash .github/skill-tests/run_all.sh — both must pass

Component Reference

Component Installs
bin ~/bin utilities
git Git configuration
home Dotfiles in ~/
zsh ZSH configuration
fonts Developer fonts
homebrew System packages
npm Global NPM packages
languages asdf & runtimes
vim Vim configuration
hammerspoon Window management
tools Devbox, Claude Code, Codex
osx macOS defaults
agents Agent skills, custom agents, hooks, and status lines (symlinks agents/skills → ~/.claude/skills + ~/.agents/skills, agents/custom → ~/.claude/agents, agents/AGENTS.md → ~/.claude/CLAUDE.md, registers Claude hooks and status line in ~/.claude/settings.json, and configures Codex's native status line with model, context remaining, 5-hour usage, and weekly usage in $CODEX_HOME/config.toml or ~/.codex/config.toml)
pi pi.dev coding agent CLI + config (installs pi via curl pi.dev/install.sh, symlinks pi/agent/models.json → ~/.pi/agent/models.json, and seeds defaultProvider/defaultModel for Ollama qwen3:32b in ~/.pi/agent/settings.json; auth.json and sessions/ stay local)

Writing Skills / Slash Commands

All skills live in agents/skills/<name>/SKILL.md following the Agent Skills open standard. This directory is symlinked to both ~/.claude/skills/ (for Claude Code) and ~/.agents/skills/ (for Codex) via dots install agents.

Each skill is a directory with a SKILL.md entrypoint. Add supporting files (scripts, templates, examples) alongside the SKILL.md when needed.

Dynamic Context Rules

The !`command` syntax runs shell commands and injects output as context. Critical restrictions:

  • Avoid $() command substitution inside dynamic context expressions. Use plain commands instead — Claude Code blocks $() in these expansions for security reasons.
  • Avoid || and && operators — use separate commands or pipes instead. Claude Code's permission system treats these as multiple operations and blocks them.
  • Always pipe through | head -N after 2>/dev/null. The 2>/dev/null suppresses stderr but does not fix the exit code — a non-zero exit code breaks the skill loader. Piping through head neutralizes the exit code (pipeline exit code = last command = head = 0).
  • Never use origin/HEAD in dynamic context — it doesn't exist in repos that weren't git clone'd or where the ref wasn't fetched. Detect the base branch with git branch -r | grep -oE 'origin/(main|master)' | head -1, or provide both origin/main and origin/master variants so one always has output.
  • Keep output bounded with | head -N or | grep to avoid blowing up context.
  • No agent teams in Conductor. Do not use TeamCreate, TeamDelete, SendMessage, or CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS. Use parallel Task tool calls with sub-agents instead.
# BAD — $() blocked by permission system
!`DEFAULT=$(gh repo view ...) && git log origin/$DEFAULT..HEAD`

# BAD — || treated as multiple operations
!`git log origin/main..HEAD --oneline 2>/dev/null || echo "None"`

# BAD — 2>/dev/null alone does not fix exit code, breaks skill loader
!`git log origin/main..HEAD --oneline 2>/dev/null`

# BAD — origin/HEAD doesn't exist in many repos, returns empty context
!`git log origin/HEAD..HEAD --oneline 2>/dev/null | head -50`

# GOOD — detect base branch portably (no custom tools)
- Base ref: !`git branch -r 2>/dev/null | grep -oE 'origin/(main|master)' | head -1`

# GOOD — provide both branches, one will have output
- Commits vs main: !`git log origin/main..HEAD --oneline 2>/dev/null | head -50`
- Commits vs master: !`git log origin/master..HEAD --oneline 2>/dev/null | head -50`

See /write-skill for the full skill-authoring guide.

Agent Skills Spec Compliance

All skills must follow the Agent Skills specification. Key rules enforced by CI:

  • name must match the parent directory name (lowercase, hyphens only, no consecutive hyphens)
  • description must say what the skill does AND when to use it — include a "Use when..." or "Use for..." clause with trigger keywords for auto-activation
  • SKILL.md should be under 500 lines — extract detailed reference material to references/ files
  • File references use relative paths from the skill root, one level deep (e.g., references/CHECKLIST.md)
  • Progressive disclosure: metadata (~100 tokens) loads at startup; full SKILL.md loads on activation; references/ and scripts/ load on demand

CI runs agnix for schema validation and .github/lint-skills.sh for best-practice checks (name/dir match, description quality, line count).

Skill Auto-Activation

Claude Code auto-activates skills by matching keywords in each skill's description field against the user's message. Other agents (Codex, Copilot) do not have this mechanism, so use this routing table instead.

When the user's message matches a phrase below, read and follow the corresponding skill:

Trigger Phrases Skill
"last screenshot", "see screenshot", "recent screenshot", "show screenshot", "last N screenshots" agents/skills/screenshot/SKILL.md
"investigate CI failures", "find flaky tests", "why is CI failing", "diagnose test flakiness", "flaky CI" agents/skills/ci-investigate/SKILL.md
"create skill", "new skill", "write skill", "add a slash command", "improve skill" agents/skills/write-skill/SKILL.md
"add to PATH", "Bash tool PATH", "command not found in Claude Code", "works in terminal but not Claude Code", "CLAUDE_ENV_FILE", "env.PATH not working" agents/skills/bash-tool-path/SKILL.md
"prioritize", "RICE score", "backlog grooming", "sprint planning", "rank items" agents/skills/prioritize/SKILL.md
"swarm", "parallel agents", "agent team in conductor", "multi-agent", "spawn agents" agents/skills/swarm/SKILL.md
"orchestrate", "fable workflow", "dynamic workflow", "tiered workflow", "model-tiered build", "plan on fable implement with sonnet and opus" agents/skills/orchestrate/SKILL.md
"skill gap analysis", "missing skills", "missing agents", "equip project", "bootstrap skills from spec", "what skills do I need" agents/skills/equip/SKILL.md
"write a plan", "implementation plan", "plan from PRD", "plan from spike", "break down this spec", "planning" agents/skills/plan/SKILL.md
"slack", "channel history", "slack search", "slack messages", "find channel", "find user slack", any #channel-name reference (e.g. #app-reviews, #rnd-leadership, #general) agents/skills/slack/SKILL.md
"email", "gmail", "search email", "read email", "inbox", "email labels" agents/skills/email/SKILL.md
"notion", "read notion", "notion page", "notion database" agents/skills/notion/SKILL.md
"speak to me", "read to me", "read this aloud", "say this", "speak the summary" agents/skills/tts/SKILL.md
"loop", "poll", "recurring", "every N minutes", "babysit", "monitor periodically", "run on interval" agents/skills/loop/SKILL.md
"compare PRs", "combine PRs", "combine these PRs", "cherry-pick between PRs", "competing implementations", "competing PRs" agents/skills/combine-prs/SKILL.md
"open a PR", "address review comments", "address review feedback", "fix CI failures on the PR", "wait for CI", "address PR comments" agents/skills/pr/SKILL.md
"audit pending commits", "check deploy risk", "review what's shipping", "audit deploy risk", "deploy audit" agents/skills/deploy-audit/SKILL.md
"validate a deploy", "check post-deploy health", "confirm production rollout is healthy", "deploy validate", "post-deploy check" agents/skills/deploy-validate/SKILL.md
"just address comments", "only address comments", "resolve review threads", "reply to PR comments", "clear bot comments", "address comments without re-running CI" agents/skills/address-comments/SKILL.md
"improve skills", "capture learnings", "upgrade context", "learn from session" agents/skills/improve/SKILL.md
"amend", "amend commit", "rewrite commit message", "improve commit message", "fix commit message" agents/skills/amend/SKILL.md
"squash", "squash commits", "condense commits", "squash branch", "clean up commits" agents/skills/squash/SKILL.md
"wrapup", "wrap up", "session closeout", "anything else to capture", "end of session", "done for the day", "end of day" agents/skills/wrapup/SKILL.md
"explain like I'm 5", "eli5", "explain simply", "dumb it down", "explain in simple terms" agents/skills/eli5/SKILL.md
"skill usage", "which skills do I use", "unused skills", "skill stats", "skill suggestions" agents/skills/skill-usage/SKILL.md
"dream", "KB hygiene", "knowledge base cleanup", "memory hygiene", "audit KB", "dream consolidation" agents/skills/dream/SKILL.md
"create slides", "build a presentation", "make a deck", "turn talking points into a talk", "HTML slideshow", "presentation deck" agents/skills/slides/SKILL.md
"preview markdown", "render markdown", "how does this README render on GitHub", "GitHub-flavored markdown preview", "check that images render on GitHub", "markdown preview" agents/skills/markdown-preview/SKILL.md

Public Repo Policy

This is a public repository. Skills and configuration checked in here must be generic and reusable by anyone.

Never commit to tracked files:

  • Email addresses, usernames, account names, or other personal identifiers
  • Company names, internal tool names, proprietary patterns, or org-specific conventions
  • API keys, tokens, secrets, or credential paths that reveal identity
  • Hardcoded account lists or user-specific configuration — use dynamic lookups instead (e.g., gmail accounts instead of a static table)

Put personal or org-specific knowledge in private project-local CLAUDE.md files, ~/.dots/sys/, or gitignored directories instead.

Skill Handoffs from ~/.dots

When receiving a handoff for ~/.dots skill changes, apply them to this workspace under agents/skills/. This repo is the source of truth for skills — ~/.claude/skills/ is a symlink to agents/skills/ via dots install agents.

Global CLAUDE.md Sync

This repo controls the user's global Claude Code instructions: agents/AGENTS.md is the source of truth, symlinked to ~/.claude/CLAUDE.md via dots install agents (see cli/commands/install/agents.go). Whenever the user asks to update their global CLAUDE.md, make the same edit to agents/AGENTS.md here so the repo copy stays in sync — don't only edit the live ~/.claude/CLAUDE.md.

Apply the Public Repo Policy above when syncing: only mirror generic, reusable instructions into agents/AGENTS.md. If an instruction is personal or org-specific, leave it in the user's local ~/.claude/CLAUDE.md only.

README Maintenance

When making changes that affect user-facing features — adding/removing skills, custom agents, CLI commands, components, or utilities — always update README.md to reflect those changes. Keep counts, tables, and the project structure tree accurate.

Quality (qlty)

Configuration lives in .qlty/qlty.toml. CI runs qlty check and qlty smells on every PR.

Before finishing any change, run:

qlty fmt                                      # Auto-format
qlty check --fix --level=low                  # Fix lint findings
qlty smells --all --no-snippets               # Inspect maintainability (duplication, complexity, deep nesting)
qlty metrics --all --sort complexity --limit 10  # Hotspots

Filter to changed files only by replacing --all with --upstream=origin/master. When fixing a maintainability finding, prefer extracting a helper over disabling the rule. See https://docs.qlty.sh/cli/coding-with-ai-agents.

If qlty panics with failed to create initial log file ... PermissionDenied under a sandboxed agent, redirect its log dir by overriding HOME: HOME=/tmp/qlty-home qlty smells --all. The Claude Code sandbox blocks writes to ~/.qlty/logs even though the user owns the directory (com.apple.provenance xattr from a different process).

If instead you get command not found: qlty in the Bash tool despite qlty working in a normal terminal, its install dir (~/.qlty/bin) isn't on the Bash tool's PATH — invoke it by full path (~/.qlty/bin/qlty) or see /bash-tool-path to fix PATH for the session.

Pre-Completion Checklist

Before considering any task complete, run the full test suite:

go install ./...                              # Build all binaries
revive -set_exit_status ./...                 # Run linter
go test ./...                                 # Run Go tests
bash .github/skill-tests/run_all.sh           # Run skill script tests
bash .github/lint-skills.sh                   # Run skill linter
qlty check --all --no-fix --level=high        # Quality gate (same as CI)
qlty smells --all --no-snippets               # Maintainability scan (same as CI)

Do not skip any of these steps. If any command fails, fix the issue before finishing. This applies to all tasks — feature work, bug fixes, skill changes, and documentation updates.

If go install/go test/go vet fails with failed to initialize build cache ... mkdir ... operation not permitted under a sandboxed agent, redirect the build cache: export GOCACHE=/tmp/gocache-<worktree> before running the Go commands. The Claude Code sandbox can block writes to the default ~/.argus/cache/go-build, the same class of issue as the qlty HOME workaround above.

Critical Notes

  • Installation is destructive (no backups)
  • Requires macOS, Homebrew, Go 1.15+
  • Uses map-based dispatch for dynamic component installation
  • CI runs on GitHub Actions (macOS, Go 1.24.10)