main ac756a267c5e cached
376 files
2.4 MB
637.2k tokens
559 symbols
1 requests
Download .txt
Showing preview only (2,542K chars total). Download the full file or copy to clipboard to get everything.
Repository: EveryInc/compound-engineering-plugin
Branch: main
Commit: ac756a267c5e
Files: 376
Total size: 2.4 MB

Directory structure:
gitextract_7sovbsfr/

├── .claude/
│   └── commands/
│       └── triage-prs.md
├── .claude-plugin/
│   └── marketplace.json
├── .cursor-plugin/
│   ├── CHANGELOG.md
│   └── marketplace.json
├── .github/
│   ├── .release-please-manifest.json
│   ├── release-please-config.json
│   └── workflows/
│       ├── ci.yml
│       ├── deploy-docs.yml
│       ├── release-pr.yml
│       └── release-preview.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── LICENSE
├── PRIVACY.md
├── README.md
├── SECURITY.md
├── docs/
│   ├── brainstorms/
│   │   ├── 2026-02-14-copilot-converter-target-brainstorm.md
│   │   ├── 2026-02-17-copilot-skill-naming-brainstorm.md
│   │   ├── 2026-03-14-ce-plan-rewrite-requirements.md
│   │   ├── 2026-03-15-ce-ideate-skill-requirements.md
│   │   ├── 2026-03-16-issue-grounded-ideation-requirements.md
│   │   ├── 2026-03-17-release-automation-requirements.md
│   │   └── 2026-03-18-auto-memory-integration-requirements.md
│   ├── plans/
│   │   ├── 2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md
│   │   ├── 2026-02-08-feat-pr-triage-and-merge-plan.md
│   │   ├── 2026-02-08-feat-simplify-plugin-settings-plan.md
│   │   ├── 2026-02-08-refactor-reduce-plugin-context-token-usage-plan.md
│   │   ├── 2026-02-09-refactor-dspy-ruby-skill-update-plan.md
│   │   ├── 2026-02-12-feat-add-cursor-cli-target-provider-plan.md
│   │   ├── 2026-02-14-feat-add-copilot-converter-target-plan.md
│   │   ├── 2026-02-14-feat-add-gemini-cli-target-provider-plan.md
│   │   ├── 2026-02-14-feat-auto-detect-install-and-gemini-sync-plan.md
│   │   ├── 2026-02-25-feat-windsurf-global-scope-support-plan.md
│   │   ├── 2026-03-01-feat-ce-command-aliases-backwards-compatible-deprecation-plan.md
│   │   ├── 2026-03-01-fix-setup-skill-non-claude-llm-fallback-plan.md
│   │   ├── 2026-03-03-feat-sync-claude-mcp-all-supported-providers-plan.md
│   │   ├── 2026-03-15-001-feat-ce-ideate-skill-plan.md
│   │   ├── 2026-03-16-001-feat-issue-grounded-ideation-plan.md
│   │   ├── 2026-03-17-001-feat-release-automation-migration-beta-plan.md
│   │   ├── 2026-03-18-001-feat-auto-memory-integration-beta-plan.md
│   │   └── feature_opencode-commands-as-md-and-config-merge.md
│   ├── solutions/
│   │   ├── adding-converter-target-providers.md
│   │   ├── codex-skill-prompt-entrypoints.md
│   │   ├── plugin-versioning-requirements.md
│   │   ├── skill-design/
│   │   │   ├── beta-skills-framework.md
│   │   │   ├── claude-permissions-optimizer-classification-fix.md
│   │   │   ├── compound-refresh-skill-improvements.md
│   │   │   └── script-first-skill-architecture.md
│   │   └── workflow/
│   │       └── manual-release-please-github-releases.md
│   └── specs/
│       ├── claude-code.md
│       ├── codex.md
│       ├── copilot.md
│       ├── cursor.md
│       ├── gemini.md
│       ├── kiro.md
│       ├── opencode.md
│       └── windsurf.md
├── package.json
├── plugins/
│   ├── coding-tutor/
│   │   ├── .claude-plugin/
│   │   │   └── plugin.json
│   │   ├── .cursor-plugin/
│   │   │   └── plugin.json
│   │   ├── README.md
│   │   ├── commands/
│   │   │   ├── quiz-me.md
│   │   │   ├── sync-tutorials.md
│   │   │   └── teach-me.md
│   │   └── skills/
│   │       └── coding-tutor/
│   │           ├── SKILL.md
│   │           └── scripts/
│   │               ├── create_tutorial.py
│   │               ├── index_tutorials.py
│   │               ├── quiz_priority.py
│   │               └── setup_tutorials.py
│   └── compound-engineering/
│       ├── .claude-plugin/
│       │   └── plugin.json
│       ├── .cursor-plugin/
│       │   └── plugin.json
│       ├── .mcp.json
│       ├── AGENTS.md
│       ├── CHANGELOG.md
│       ├── CLAUDE.md
│       ├── LICENSE
│       ├── README.md
│       ├── agents/
│       │   ├── design/
│       │   │   ├── design-implementation-reviewer.md
│       │   │   ├── design-iterator.md
│       │   │   └── figma-design-sync.md
│       │   ├── docs/
│       │   │   └── ankane-readme-writer.md
│       │   ├── research/
│       │   │   ├── best-practices-researcher.md
│       │   │   ├── framework-docs-researcher.md
│       │   │   ├── git-history-analyzer.md
│       │   │   ├── issue-intelligence-analyst.md
│       │   │   ├── learnings-researcher.md
│       │   │   └── repo-research-analyst.md
│       │   ├── review/
│       │   │   ├── agent-native-reviewer.md
│       │   │   ├── architecture-strategist.md
│       │   │   ├── code-simplicity-reviewer.md
│       │   │   ├── data-integrity-guardian.md
│       │   │   ├── data-migration-expert.md
│       │   │   ├── deployment-verification-agent.md
│       │   │   ├── dhh-rails-reviewer.md
│       │   │   ├── julik-frontend-races-reviewer.md
│       │   │   ├── kieran-python-reviewer.md
│       │   │   ├── kieran-rails-reviewer.md
│       │   │   ├── kieran-typescript-reviewer.md
│       │   │   ├── pattern-recognition-specialist.md
│       │   │   ├── performance-oracle.md
│       │   │   ├── schema-drift-detector.md
│       │   │   └── security-sentinel.md
│       │   └── workflow/
│       │       ├── bug-reproduction-validator.md
│       │       ├── lint.md
│       │       ├── pr-comment-resolver.md
│       │       └── spec-flow-analyzer.md
│       └── skills/
│           ├── agent-browser/
│           │   ├── SKILL.md
│           │   ├── references/
│           │   │   ├── authentication.md
│           │   │   ├── commands.md
│           │   │   ├── profiling.md
│           │   │   ├── proxy-support.md
│           │   │   ├── session-management.md
│           │   │   ├── snapshot-refs.md
│           │   │   └── video-recording.md
│           │   └── templates/
│           │       ├── authenticated-session.sh
│           │       ├── capture-workflow.sh
│           │       └── form-automation.sh
│           ├── agent-native-architecture/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── action-parity-discipline.md
│           │       ├── agent-execution-patterns.md
│           │       ├── agent-native-testing.md
│           │       ├── architecture-patterns.md
│           │       ├── dynamic-context-injection.md
│           │       ├── files-universal-interface.md
│           │       ├── from-primitives-to-domain-tools.md
│           │       ├── mcp-tool-design.md
│           │       ├── mobile-patterns.md
│           │       ├── product-implications.md
│           │       ├── refactoring-to-prompt-native.md
│           │       ├── self-modification.md
│           │       ├── shared-workspace-architecture.md
│           │       └── system-prompt-design.md
│           ├── agent-native-audit/
│           │   └── SKILL.md
│           ├── andrew-kane-gem-writer/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── database-adapters.md
│           │       ├── module-organization.md
│           │       ├── rails-integration.md
│           │       ├── resources.md
│           │       └── testing-patterns.md
│           ├── ce-brainstorm/
│           │   └── SKILL.md
│           ├── ce-compound/
│           │   └── SKILL.md
│           ├── ce-compound-refresh/
│           │   └── SKILL.md
│           ├── ce-ideate/
│           │   └── SKILL.md
│           ├── ce-plan/
│           │   └── SKILL.md
│           ├── ce-plan-beta/
│           │   └── SKILL.md
│           ├── ce-review/
│           │   └── SKILL.md
│           ├── ce-work/
│           │   └── SKILL.md
│           ├── changelog/
│           │   └── SKILL.md
│           ├── claude-permissions-optimizer/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── extract-commands.mjs
│           ├── compound-docs/
│           │   ├── SKILL.md
│           │   ├── assets/
│           │   │   ├── critical-pattern-template.md
│           │   │   └── resolution-template.md
│           │   ├── references/
│           │   │   └── yaml-schema.md
│           │   └── schema.yaml
│           ├── create-agent-skill/
│           │   └── SKILL.md
│           ├── create-agent-skills/
│           │   ├── SKILL.md
│           │   ├── references/
│           │   │   ├── api-security.md
│           │   │   ├── be-clear-and-direct.md
│           │   │   ├── best-practices.md
│           │   │   ├── common-patterns.md
│           │   │   ├── core-principles.md
│           │   │   ├── executable-code.md
│           │   │   ├── iteration-and-testing.md
│           │   │   ├── official-spec.md
│           │   │   ├── recommended-structure.md
│           │   │   ├── skill-structure.md
│           │   │   ├── using-scripts.md
│           │   │   ├── using-templates.md
│           │   │   └── workflows-and-validation.md
│           │   ├── templates/
│           │   │   ├── router-skill.md
│           │   │   └── simple-skill.md
│           │   └── workflows/
│           │       ├── add-reference.md
│           │       ├── add-script.md
│           │       ├── add-template.md
│           │       ├── add-workflow.md
│           │       ├── audit-skill.md
│           │       ├── create-domain-expertise-skill.md
│           │       ├── create-new-skill.md
│           │       ├── get-guidance.md
│           │       ├── upgrade-to-router.md
│           │       └── verify-skill.md
│           ├── deepen-plan/
│           │   └── SKILL.md
│           ├── deepen-plan-beta/
│           │   └── SKILL.md
│           ├── deploy-docs/
│           │   └── SKILL.md
│           ├── dhh-rails-style/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── architecture.md
│           │       ├── controllers.md
│           │       ├── frontend.md
│           │       ├── gems.md
│           │       ├── models.md
│           │       └── testing.md
│           ├── document-review/
│           │   └── SKILL.md
│           ├── dspy-ruby/
│           │   ├── SKILL.md
│           │   ├── assets/
│           │   │   ├── config-template.rb
│           │   │   ├── module-template.rb
│           │   │   └── signature-template.rb
│           │   └── references/
│           │       ├── core-concepts.md
│           │       ├── observability.md
│           │       ├── optimization.md
│           │       ├── providers.md
│           │       └── toolsets.md
│           ├── every-style-editor/
│           │   ├── SKILL.md
│           │   └── references/
│           │       └── EVERY_WRITE_STYLE.md
│           ├── feature-video/
│           │   └── SKILL.md
│           ├── file-todos/
│           │   ├── SKILL.md
│           │   └── assets/
│           │       └── todo-template.md
│           ├── frontend-design/
│           │   └── SKILL.md
│           ├── gemini-imagegen/
│           │   ├── SKILL.md
│           │   ├── requirements.txt
│           │   └── scripts/
│           │       ├── compose_images.py
│           │       ├── edit_image.py
│           │       ├── gemini_images.py
│           │       ├── generate_image.py
│           │       └── multi_turn_chat.py
│           ├── generate_command/
│           │   └── SKILL.md
│           ├── git-worktree/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── worktree-manager.sh
│           ├── heal-skill/
│           │   └── SKILL.md
│           ├── lfg/
│           │   └── SKILL.md
│           ├── orchestrating-swarms/
│           │   └── SKILL.md
│           ├── proof/
│           │   └── SKILL.md
│           ├── rclone/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── check_setup.sh
│           ├── report-bug/
│           │   └── SKILL.md
│           ├── reproduce-bug/
│           │   └── SKILL.md
│           ├── resolve-pr-parallel/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       ├── get-pr-comments
│           │       └── resolve-pr-thread
│           ├── resolve-todo-parallel/
│           │   └── SKILL.md
│           ├── resolve_parallel/
│           │   └── SKILL.md
│           ├── setup/
│           │   └── SKILL.md
│           ├── slfg/
│           │   └── SKILL.md
│           ├── test-browser/
│           │   └── SKILL.md
│           ├── test-xcode/
│           │   └── SKILL.md
│           └── triage/
│               └── SKILL.md
├── scripts/
│   └── release/
│       ├── preview.ts
│       ├── sync-metadata.ts
│       └── validate.ts
├── src/
│   ├── commands/
│   │   ├── convert.ts
│   │   ├── install.ts
│   │   ├── list.ts
│   │   └── sync.ts
│   ├── converters/
│   │   ├── claude-to-codex.ts
│   │   ├── claude-to-copilot.ts
│   │   ├── claude-to-droid.ts
│   │   ├── claude-to-gemini.ts
│   │   ├── claude-to-kiro.ts
│   │   ├── claude-to-openclaw.ts
│   │   ├── claude-to-opencode.ts
│   │   ├── claude-to-pi.ts
│   │   ├── claude-to-qwen.ts
│   │   └── claude-to-windsurf.ts
│   ├── index.ts
│   ├── parsers/
│   │   ├── claude-home.ts
│   │   └── claude.ts
│   ├── release/
│   │   ├── components.ts
│   │   ├── config.ts
│   │   ├── metadata.ts
│   │   └── types.ts
│   ├── sync/
│   │   ├── codex.ts
│   │   ├── commands.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── json-config.ts
│   │   ├── kiro.ts
│   │   ├── mcp-transports.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   ├── registry.ts
│   │   ├── skills.ts
│   │   └── windsurf.ts
│   ├── targets/
│   │   ├── codex.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── index.ts
│   │   ├── kiro.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   └── windsurf.ts
│   ├── templates/
│   │   └── pi/
│   │       └── compat-extension.ts
│   ├── types/
│   │   ├── claude.ts
│   │   ├── codex.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── kiro.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   └── windsurf.ts
│   └── utils/
│       ├── codex-agents.ts
│       ├── codex-content.ts
│       ├── detect-tools.ts
│       ├── files.ts
│       ├── frontmatter.ts
│       ├── resolve-home.ts
│       ├── resolve-output.ts
│       ├── secrets.ts
│       └── symlink.ts
├── tests/
│   ├── claude-home.test.ts
│   ├── claude-parser.test.ts
│   ├── cli.test.ts
│   ├── codex-agents.test.ts
│   ├── codex-converter.test.ts
│   ├── codex-writer.test.ts
│   ├── converter.test.ts
│   ├── copilot-converter.test.ts
│   ├── copilot-writer.test.ts
│   ├── detect-tools.test.ts
│   ├── droid-converter.test.ts
│   ├── droid-writer.test.ts
│   ├── fixtures/
│   │   ├── custom-paths/
│   │   │   ├── .claude-plugin/
│   │   │   │   └── plugin.json
│   │   │   ├── agents/
│   │   │   │   └── default-agent.md
│   │   │   ├── commands/
│   │   │   │   └── default-command.md
│   │   │   ├── custom-agents/
│   │   │   │   └── custom-agent.md
│   │   │   ├── custom-commands/
│   │   │   │   └── custom-command.md
│   │   │   ├── custom-hooks/
│   │   │   │   └── hooks.json
│   │   │   ├── custom-skills/
│   │   │   │   └── custom-skill/
│   │   │   │       └── SKILL.md
│   │   │   ├── hooks/
│   │   │   │   └── hooks.json
│   │   │   └── skills/
│   │   │       └── default-skill/
│   │   │           └── SKILL.md
│   │   ├── invalid-command-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── invalid-hooks-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── invalid-mcp-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── mcp-file/
│   │   │   ├── .claude-plugin/
│   │   │   │   └── plugin.json
│   │   │   └── .mcp.json
│   │   └── sample-plugin/
│   │       ├── .claude-plugin/
│   │       │   └── plugin.json
│   │       ├── agents/
│   │       │   ├── agent-one.md
│   │       │   └── security-reviewer.md
│   │       ├── commands/
│   │       │   ├── command-one.md
│   │       │   ├── disabled-command.md
│   │       │   ├── model-command.md
│   │       │   ├── nested/
│   │       │   │   └── command-two.md
│   │       │   ├── pattern-command.md
│   │       │   ├── skill-command.md
│   │       │   └── todo-command.md
│   │       ├── hooks/
│   │       │   └── hooks.json
│   │       └── skills/
│   │           ├── disabled-skill/
│   │           │   └── SKILL.md
│   │           └── skill-one/
│   │               └── SKILL.md
│   ├── frontmatter.test.ts
│   ├── gemini-converter.test.ts
│   ├── gemini-writer.test.ts
│   ├── kiro-converter.test.ts
│   ├── kiro-writer.test.ts
│   ├── openclaw-converter.test.ts
│   ├── openclaw-writer.test.ts
│   ├── opencode-writer.test.ts
│   ├── pi-converter.test.ts
│   ├── pi-writer.test.ts
│   ├── qwen-converter.test.ts
│   ├── release-components.test.ts
│   ├── release-config.test.ts
│   ├── release-metadata.test.ts
│   ├── release-preview.test.ts
│   ├── resolve-output.test.ts
│   ├── sync-codex.test.ts
│   ├── sync-copilot.test.ts
│   ├── sync-droid.test.ts
│   ├── sync-gemini.test.ts
│   ├── sync-kiro.test.ts
│   ├── sync-openclaw.test.ts
│   ├── sync-pi.test.ts
│   ├── sync-qwen.test.ts
│   ├── sync-windsurf.test.ts
│   ├── windsurf-converter.test.ts
│   └── windsurf-writer.test.ts
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/commands/triage-prs.md
================================================
---
name: triage-prs
description: Triage all open PRs with parallel agents, label, group, and review one-by-one
argument-hint: "[optional: repo owner/name or GitHub PRs URL]"
disable-model-invocation: true
allowed-tools: Bash(gh *), Bash(git log *)
---

# Triage Open Pull Requests

Review, label, and act on all open PRs for a repository using parallel review agents. Produces a grouped triage report, applies labels, cross-references with issues, and walks through each PR for merge/comment decisions.

## Step 0: Detect Repository

Detect repo context:
- Current repo: !`gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo "no repo detected"`
- Current branch: !`git branch --show-current 2>/dev/null`

If `$ARGUMENTS` contains a GitHub URL or `owner/repo`, use that instead. Confirm the repo with the user if ambiguous.

## Step 1: Gather Context (Parallel)

Run these in parallel:

1. **List all open PRs:**
   ```bash
   gh pr list --repo OWNER/REPO --state open --limit 50
   ```

2. **List all open issues:**
   ```bash
   gh issue list --repo OWNER/REPO --state open --limit 50
   ```

3. **List existing labels:**
   ```bash
   gh label list --repo OWNER/REPO --limit 50
   ```

4. **Check recent merges** (to detect duplicate/superseded PRs):
   ```bash
   git log --oneline -20 main
   ```

## Step 2: Batch PRs by Theme

Group PRs into review batches of 4-6 based on apparent type:

- **Bug fixes** - titles with `fix`, `bug`, error descriptions
- **Features** - titles with `feat`, `add`, new functionality
- **Documentation** - titles with `docs`, `readme`, terminology
- **Configuration/Setup** - titles with `config`, `setup`, `install`
- **Stale/Old** - PRs older than 30 days

## Step 3: Parallel Review (Team of Agents)

Spawn one review agent per batch using the Task tool. Each agent should:

For each PR in their batch:
1. Run `gh pr view --repo OWNER/REPO <number> --json title,body,files,additions,deletions,author,createdAt`
2. Run `gh pr diff --repo OWNER/REPO <number>` (pipe to `head -200` for large diffs)
3. Determine:
   - **Description:** 1-2 sentence summary of the change
   - **Label:** Which existing repo label fits best
   - **Action:** merge / request changes / close / needs discussion
   - **Related PRs:** Any PRs in this or other batches that touch the same files or feature
   - **Quality notes:** Code quality, test coverage, staleness concerns

Instruct each agent to:
- Flag PRs that touch the same files (potential merge conflicts)
- Flag PRs that duplicate recently merged work
- Flag PRs that are part of a group solving the same problem differently
- Report findings as a markdown table
- Send findings back via message when done

## Step 4: Cross-Reference Issues

After all agents report, match issues to PRs:

- Check if any PR title/body mentions `Fixes #X` or `Closes #X`
- Check if any issue title matches a PR's topic
- Look for duplicate issues (same bug reported twice)

Build a mapping table:
```
| Issue | PR | Relationship |
|-------|-----|--------------|
| #158  | #159 | PR fixes issue |
```

## Step 5: Identify Themes

Group all issues into themes (3-6 themes):
- Count issues per theme
- Note which themes have PRs addressing them and which don't
- Flag themes with competing/overlapping PRs

## Step 6: Compile Triage Report

Present a single report with:

1. **Summary stats:** X open PRs, Y open issues, Z themes
2. **PR groups** with recommended actions:
   - Group name and related PRs
   - Per-PR: #, title, author, description, label, action
3. **Issue-to-PR mapping**
4. **Themes across issues**
5. **Suggested cleanup:** spam issues, duplicates, stale items

## Step 7: Apply Labels

After presenting the report, ask user:

> "Apply these labels to all PRs on GitHub?"

If yes, run `gh pr edit --repo OWNER/REPO <number> --add-label "<label>"` for each PR.

## Step 8: One-by-One Review

Use **AskUserQuestion** to ask:

> "Ready to walk through PRs one-by-one for merge/comment decisions?"

Then for each PR, ordered by priority (bug fixes first, then docs, then features, then stale):

### Show the PR:

```
### PR #<number> - <title>
Author: <author> | Files: <count> | +<additions>/-<deletions> | <age>
Label: <label>

<1-2 sentence description>

Fixes: <linked issues if any>
Related: <related PRs if any>
```

Show the diff (trimmed to key changes if large).

### Ask for decision:

Use **AskUserQuestion**:
- **Merge** - Merge this PR now
- **Comment & skip** - Leave a comment explaining why not merging, keep open
- **Close** - Close with a comment
- **Skip** - Move to next without action

### Execute decision:

- **Merge:** `gh pr merge --repo OWNER/REPO <number> --squash`
  - If PR fixes an issue, close the issue too
- **Comment & skip:** `gh pr comment --repo OWNER/REPO <number> --body "<comment>"`
  - Ask user what to say, or generate a grateful + specific comment
- **Close:** `gh pr close --repo OWNER/REPO <number> --comment "<reason>"`
- **Skip:** Move on

## Step 9: Post-Merge Cleanup

After all PRs are reviewed:

1. **Close resolved issues** that were fixed by merged PRs
2. **Close spam/off-topic issues** (confirm with user first)
3. **Summary of actions taken:**
   ```
   ## Triage Complete

   Merged: X PRs
   Commented: Y PRs
   Closed: Z PRs
   Skipped: W PRs

   Issues closed: A
   Labels applied: B
   ```

## Step 10: Post-Triage Options

Use **AskUserQuestion**:

1. **Run `/release-docs`** - Update documentation site if components changed
2. **Run `/changelog`** - Generate changelog for merged PRs
3. **Commit any local changes** - If version bumps needed
4. **Done** - Wrap up

## Important Notes

- **DO NOT merge without user approval** for each PR
- **DO NOT force push or destructive actions**
- Comments on declined PRs should be grateful and constructive
- When PRs conflict with each other, note this and suggest merge order
- When multiple PRs solve the same problem differently, flag for user to pick one
- Use Haiku model for review agents to save cost (they're doing read-only analysis)


================================================
FILE: .claude-plugin/marketplace.json
================================================
{
  "name": "compound-engineering-plugin",
  "owner": {
    "name": "Kieran Klaassen",
    "url": "https://github.com/kieranklaassen"
  },
  "metadata": {
    "description": "Plugin marketplace for Claude Code extensions",
    "version": "1.0.2"
  },
  "plugins": [
    {
      "name": "compound-engineering",
      "description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last.",
      "author": {
        "name": "Kieran Klaassen",
        "url": "https://github.com/kieranklaassen",
        "email": "kieran@every.to"
      },
      "homepage": "https://github.com/EveryInc/compound-engineering-plugin",
      "tags": [
        "ai-powered",
        "compound-engineering",
        "workflow-automation",
        "code-review",
        "quality",
        "knowledge-management",
        "image-generation"
      ],
      "source": "./plugins/compound-engineering"
    },
    {
      "name": "coding-tutor",
      "description": "Personalized coding tutorials that build on your existing knowledge and use your actual codebase for examples. Includes spaced repetition quizzes to reinforce learning. Includes 3 commands and 1 skill.",
      "author": {
        "name": "Nityesh Agarwal"
      },
      "homepage": "https://github.com/EveryInc/compound-engineering-plugin",
      "tags": [
        "coding",
        "programming",
        "tutorial",
        "learning",
        "spaced-repetition",
        "education"
      ],
      "source": "./plugins/coding-tutor"
    }
  ]
}


================================================
FILE: .cursor-plugin/CHANGELOG.md
================================================
# Changelog

## [1.0.1](https://github.com/EveryInc/compound-engineering-plugin/compare/cursor-marketplace-v1.0.0...cursor-marketplace-v1.0.1) (2026-03-19)


### Bug Fixes

* add cursor-marketplace as release-please component ([#315](https://github.com/EveryInc/compound-engineering-plugin/issues/315)) ([838aeb7](https://github.com/EveryInc/compound-engineering-plugin/commit/838aeb79d069b57a80d15ff61d83913919b81aef))


================================================
FILE: .cursor-plugin/marketplace.json
================================================
{
  "name": "compound-engineering",
  "owner": {
    "name": "Kieran Klaassen",
    "email": "kieran@every.to",
    "url": "https://github.com/kieranklaassen"
  },
  "metadata": {
    "description": "Cursor plugin marketplace for Every Inc plugins",
    "version": "1.0.1",
    "pluginRoot": "plugins"
  },
  "plugins": [
    {
      "name": "compound-engineering",
      "source": "compound-engineering",
      "description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last."
    },
    {
      "name": "coding-tutor",
      "source": "coding-tutor",
      "description": "Personalized coding tutorials with spaced repetition quizzes using your real codebase."
    }
  ]
}


================================================
FILE: .github/.release-please-manifest.json
================================================
{
  ".": "2.46.0",
  "plugins/compound-engineering": "2.46.0",
  "plugins/coding-tutor": "1.2.1",
  ".claude-plugin": "1.0.2",
  ".cursor-plugin": "1.0.1"
}


================================================
FILE: .github/release-please-config.json
================================================
{
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
  "include-component-in-tag": true,
  "release-search-depth": 20,
  "commit-search-depth": 50,
  "packages": {
    ".": {
      "release-type": "simple",
      "package-name": "cli",
      "extra-files": [
        {
          "type": "json",
          "path": "package.json",
          "jsonpath": "$.version"
        }
      ]
    },
    "plugins/compound-engineering": {
      "release-type": "simple",
      "package-name": "compound-engineering",
      "extra-files": [
        {
          "type": "json",
          "path": ".claude-plugin/plugin.json",
          "jsonpath": "$.version"
        },
        {
          "type": "json",
          "path": ".cursor-plugin/plugin.json",
          "jsonpath": "$.version"
        }
      ]
    },
    "plugins/coding-tutor": {
      "release-type": "simple",
      "package-name": "coding-tutor",
      "extra-files": [
        {
          "type": "json",
          "path": ".claude-plugin/plugin.json",
          "jsonpath": "$.version"
        },
        {
          "type": "json",
          "path": ".cursor-plugin/plugin.json",
          "jsonpath": "$.version"
        }
      ]
    },
    ".claude-plugin": {
      "release-type": "simple",
      "package-name": "marketplace",
      "extra-files": [
        {
          "type": "json",
          "path": "marketplace.json",
          "jsonpath": "$.metadata.version"
        }
      ]
    },
    ".cursor-plugin": {
      "release-type": "simple",
      "package-name": "cursor-marketplace",
      "extra-files": [
        {
          "type": "json",
          "path": "marketplace.json",
          "jsonpath": "$.metadata.version"
        }
      ]
    }
  }
}


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  pr-title:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    permissions:
      pull-requests: read

    steps:
      - name: Validate PR title
        uses: amannn/action-semantic-pull-request@v6.1.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          requireScope: false
          types: |
            feat
            fix
            docs
            refactor
            chore
            test
            ci
            build
            perf
            revert

  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install

      - name: Validate release metadata
        run: bun run release:validate

      - name: Run tests
        run: bun test


================================================
FILE: .github/workflows/deploy-docs.yml
================================================
name: Deploy Documentation to GitHub Pages

on:
  push:
    branches: [main]
    paths:
      - 'plugins/compound-engineering/docs/**'
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup Pages
        uses: actions/configure-pages@v5

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v4
        with:
          path: 'plugins/compound-engineering/docs'

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .github/workflows/release-pr.yml
================================================
name: Release PR

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: write
  pull-requests: write
  issues: write

concurrency:
  group: release-pr-${{ github.ref }}
  cancel-in-progress: true

jobs:
  release-pr:
    runs-on: ubuntu-latest
    outputs:
      cli_release_created: ${{ steps.release.outputs.release_created }}
      cli_tag_name: ${{ steps.release.outputs.tag_name }}

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Detect release PR merge
        id: detect
        run: |
          MSG=$(git log -1 --format=%s)
          if [[ "$MSG" == chore:\ release* ]]; then
            echo "is_release_merge=true" >> "$GITHUB_OUTPUT"
          else
            echo "is_release_merge=false" >> "$GITHUB_OUTPUT"
          fi

      - name: Validate release metadata scripts
        if: steps.detect.outputs.is_release_merge == 'false'
        run: bun run release:validate

      - name: Maintain release PR
        id: release
        uses: googleapis/release-please-action@v4.4.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          config-file: .github/release-please-config.json
          manifest-file: .github/.release-please-manifest.json
          skip-labeling: false

  publish-cli:
    needs: release-pr
    if: needs.release-pr.outputs.cli_release_created == 'true'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write

    concurrency:
      group: publish-${{ needs.release-pr.outputs.cli_tag_name }}
      cancel-in-progress: false

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
          ref: ${{ needs.release-pr.outputs.cli_tag_name }}

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Run tests
        run: bun test

      - name: Setup Node.js for release
        uses: actions/setup-node@v4
        with:
          node-version: "24"
          registry-url: https://registry.npmjs.org

      - name: Publish package
        run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}


================================================
FILE: .github/workflows/release-preview.yml
================================================
name: Release Preview

on:
  workflow_dispatch:
    inputs:
      title:
        description: "Conventional title to evaluate (defaults to the latest commit title on this ref)"
        required: false
        type: string
      cli_bump:
        description: "CLI bump override"
        required: false
        type: choice
        options: [auto, patch, minor, major]
        default: auto
      compound_engineering_bump:
        description: "compound-engineering bump override"
        required: false
        type: choice
        options: [auto, patch, minor, major]
        default: auto
      coding_tutor_bump:
        description: "coding-tutor bump override"
        required: false
        type: choice
        options: [auto, patch, minor, major]
        default: auto
      marketplace_bump:
        description: "marketplace bump override"
        required: false
        type: choice
        options: [auto, patch, minor, major]
        default: auto
      cursor_marketplace_bump:
        description: "cursor-marketplace bump override"
        required: false
        type: choice
        options: [auto, patch, minor, major]
        default: auto

jobs:
  preview:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Determine title and changed files
        id: inputs
        shell: bash
        run: |
          TITLE="${{ github.event.inputs.title }}"
          if [ -z "$TITLE" ]; then
            TITLE="$(git log -1 --pretty=%s)"
          fi

          FILES="$(git diff --name-only HEAD~1...HEAD | tr '\n' ' ')"

          echo "title=$TITLE" >> "$GITHUB_OUTPUT"
          echo "files=$FILES" >> "$GITHUB_OUTPUT"

      - name: Add preview note
        run: |
          echo "This preview currently evaluates the selected ref from its latest commit title and changed files." >> "$GITHUB_STEP_SUMMARY"
          echo "It is side-effect free, but it does not yet reconstruct the full accumulated open release PR state." >> "$GITHUB_STEP_SUMMARY"

      - name: Validate release metadata
        run: bun run release:validate

      - name: Preview release
        shell: bash
        run: |
          TITLE='${{ steps.inputs.outputs.title }}'
          FILES='${{ steps.inputs.outputs.files }}'

          args=(--title "$TITLE" --json)
          for file in $FILES; do
            args+=(--file "$file")
          done

          args+=(--override "cli=${{ github.event.inputs.cli_bump || 'auto' }}")
          args+=(--override "compound-engineering=${{ github.event.inputs.compound_engineering_bump || 'auto' }}")
          args+=(--override "coding-tutor=${{ github.event.inputs.coding_tutor_bump || 'auto' }}")
          args+=(--override "marketplace=${{ github.event.inputs.marketplace_bump || 'auto' }}")
          args+=(--override "cursor-marketplace=${{ github.event.inputs.cursor_marketplace_bump || 'auto' }}")

          bun run scripts/release/preview.ts "${args[@]}" | tee /tmp/release-preview.txt

      - name: Publish preview summary
        shell: bash
        run: cat /tmp/release-preview.txt >> "$GITHUB_STEP_SUMMARY"


================================================
FILE: .gitignore
================================================
.DS_Store
*.log
node_modules/
.codex/
todos/
.worktrees


================================================
FILE: AGENTS.md
================================================
# Agent Instructions

This repository primarily houses the `compound-engineering` coding-agent plugin and the Claude Code marketplace/catalog metadata used to distribute it.

It also contains:
- the Bun/TypeScript CLI that converts Claude Code plugins into other agent platform formats
- additional plugins under `plugins/`, such as `coding-tutor`
- shared release and metadata infrastructure for the CLI, marketplace, and plugins

`AGENTS.md` is the canonical repo instruction file. Root `CLAUDE.md` exists only as a compatibility shim for tools and conversions that still look for it.

## Quick Start

```bash
bun install
bun test                  # full test suite
bun run release:validate  # check plugin/marketplace consistency
```

## Working Agreement

- **Branching:** Create a feature branch for any non-trivial change. If already on the correct branch for the task, keep using it; do not create additional branches or worktrees unless explicitly requested.
- **Safety:** Do not delete or overwrite user data. Avoid destructive commands.
- **Testing:** Run `bun test` after changes that affect parsing, conversion, or output.
- **Release versioning:** Releases are prepared by release automation, not normal feature PRs. The repo now has multiple release components (`cli`, `compound-engineering`, `coding-tutor`, `marketplace`). GitHub release PRs and GitHub Releases are the canonical release-notes surface for new releases; root `CHANGELOG.md` is only a pointer to that history. Use conventional titles such as `feat:` and `fix:` so release automation can classify change intent, but do not hand-bump release-owned versions or hand-author release notes in routine PRs.
- **Output Paths:** Keep OpenCode output at `opencode.json` and `.opencode/{agents,skills,plugins}`. For OpenCode, command go to `~/.config/opencode/commands/<name>.md`; `opencode.json` is deep-merged (never overwritten wholesale).
- **ASCII-first:** Use ASCII unless the file already contains Unicode.

## Directory Layout

```
src/              CLI entry point, parsers, converters, target writers
plugins/          Plugin workspaces (compound-engineering, coding-tutor)
.claude-plugin/   Claude marketplace catalog metadata
tests/            Converter, writer, and CLI tests + fixtures
docs/             Requirements, plans, solutions, and target specs
```

## Repo Surfaces

Changes in this repo may affect one or more of these surfaces:

- `compound-engineering` under `plugins/compound-engineering/`
- the Claude marketplace catalog under `.claude-plugin/`
- the converter/install CLI in `src/` and `package.json`
- secondary plugins such as `plugins/coding-tutor/`

Do not assume a repo change is "just CLI" or "just plugin" without checking which surface owns the affected files.

## Plugin Maintenance

When changing `plugins/compound-engineering/` content:

- Update substantive docs like `plugins/compound-engineering/README.md` when the plugin behavior, inventory, or usage changes.
- Do not hand-bump release-owned versions in plugin or marketplace manifests.
- Do not hand-add release entries to `CHANGELOG.md` or treat it as the canonical source for new releases.
- Run `bun run release:validate` if agents, commands, skills, MCP servers, or release-owned descriptions/counts may have changed.

Useful validation commands:

```bash
bun run release:validate
cat .claude-plugin/marketplace.json | jq .
cat plugins/compound-engineering/.claude-plugin/plugin.json | jq .
```

## Coding Conventions

- Prefer explicit mappings over implicit magic when converting between platforms.
- Keep target-specific behavior in dedicated converters/writers instead of scattering conditionals across unrelated files.
- Preserve stable output paths and merge semantics for installed targets; do not casually change generated file locations.
- When adding or changing a target, update fixtures/tests alongside implementation rather than treating docs or examples as sufficient proof.

## Commit Conventions

- Use conventional titles such as `feat: ...`, `fix: ...`, `docs: ...`, and `refactor: ...`.
- Component scope is optional. Example: `feat(coding-tutor): add quiz reset`.
- Breaking changes must be explicit with `!` or a breaking-change footer so release automation can classify them correctly.

## Adding a New Target Provider

Only add a provider when the target format is stable, documented, and has a clear mapping for tools/permissions/hooks. Use this checklist:

1. **Define the target entry**
   - Add a new handler in `src/targets/index.ts` with `implemented: false` until complete.
   - Use a dedicated writer module (e.g., `src/targets/codex.ts`).

2. **Define types and mapping**
   - Add provider-specific types under `src/types/`.
   - Implement conversion logic in `src/converters/` (from Claude → provider).
   - Keep mappings explicit: tools, permissions, hooks/events, model naming.

3. **Wire the CLI**
   - Ensure `convert` and `install` support `--to <provider>` and `--also`.
   - Keep behavior consistent with OpenCode (write to a clean provider root).

4. **Tests (required)**
   - Extend fixtures in `tests/fixtures/sample-plugin`.
   - Add spec coverage for mappings in `tests/converter.test.ts`.
   - Add a writer test for the new provider output tree.
   - Add a CLI test for the provider (similar to `tests/cli.test.ts`).

5. **Docs**
   - Update README with the new `--to` option and output locations.

## Agent References in Skills

When referencing agents from within skill SKILL.md files (e.g., via the `Agent` or `Task` tool), always use the **fully-qualified namespace**: `compound-engineering:<category>:<agent-name>`. Never use the short agent name alone.

Example:
- `compound-engineering:research:learnings-researcher` (correct)
- `learnings-researcher` (wrong - will fail to resolve at runtime)

This prevents resolution failures when the plugin is installed alongside other plugins that may define agents with the same short name.

## Repository Docs Convention

- **Requirements** live in `docs/brainstorms/` — requirements exploration and ideation.
- **Plans** live in `docs/plans/` — implementation plans and progress tracking.
- **Solutions** live in `docs/solutions/` — documented decisions and patterns.
- **Specs** live in `docs/specs/` — target platform format specifications.


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## [2.46.0](https://github.com/EveryInc/compound-engineering-plugin/compare/cli-v2.45.0...cli-v2.46.0) (2026-03-20)


### Features

* add optional high-level technical design to plan-beta skills ([#322](https://github.com/EveryInc/compound-engineering-plugin/issues/322)) ([3ba4935](https://github.com/EveryInc/compound-engineering-plugin/commit/3ba4935926b05586da488119f215057164d97489))


### Bug Fixes

* **ci:** add npm registry auth to release publish job ([#319](https://github.com/EveryInc/compound-engineering-plugin/issues/319)) ([3361a38](https://github.com/EveryInc/compound-engineering-plugin/commit/3361a38108991237de51050283e781be847c6bd3))

## [2.45.0](https://github.com/EveryInc/compound-engineering-plugin/compare/cli-v2.44.0...cli-v2.45.0) (2026-03-19)


### Features

* edit resolve_todos_parallel skill for complete todo lifecycle ([#292](https://github.com/EveryInc/compound-engineering-plugin/issues/292)) ([88c89bc](https://github.com/EveryInc/compound-engineering-plugin/commit/88c89bc204c928d2f36e2d1f117d16c998ecd096))
* integrate claude code auto memory as supplementary data source for ce:compound and ce:compound-refresh ([#311](https://github.com/EveryInc/compound-engineering-plugin/issues/311)) ([5c1452d](https://github.com/EveryInc/compound-engineering-plugin/commit/5c1452d4cc80b623754dd6fe09c2e5b6ae86e72e))


### Bug Fixes

* add cursor-marketplace as release-please component ([#315](https://github.com/EveryInc/compound-engineering-plugin/issues/315)) ([838aeb7](https://github.com/EveryInc/compound-engineering-plugin/commit/838aeb79d069b57a80d15ff61d83913919b81aef))

## [2.44.0](https://github.com/EveryInc/compound-engineering-plugin/compare/cli-v2.43.2...cli-v2.44.0) (2026-03-18)


### Features

* **plugin:** add execution posture signaling to ce:plan-beta and ce:work ([#309](https://github.com/EveryInc/compound-engineering-plugin/issues/309)) ([748f72a](https://github.com/EveryInc/compound-engineering-plugin/commit/748f72a57f713893af03a4d8ed69c2311f492dbd))

## [2.43.2](https://github.com/EveryInc/compound-engineering-plugin/compare/cli-v2.43.1...cli-v2.43.2) (2026-03-18)


### Bug Fixes

* enable release-please labeling so it can find its own PRs ([a7d6e3f](https://github.com/EveryInc/compound-engineering-plugin/commit/a7d6e3fbba862d4e8b4e1a0510f0776e9e274b89))
* re-enable changelogs so release PRs accumulate correctly ([516bcc1](https://github.com/EveryInc/compound-engineering-plugin/commit/516bcc1dc4bf4e4756ae08775806494f5b43968a))
* reduce release-please search depth from 500 to 50 ([f1713b9](https://github.com/EveryInc/compound-engineering-plugin/commit/f1713b9dcd0deddc2485e8cf0594266232bf0019))
* remove close-stale-PR step that broke release creation ([178d6ec](https://github.com/EveryInc/compound-engineering-plugin/commit/178d6ec282512eaee71ab66d45832d22d75353ec))

## Changelog

Release notes now live in GitHub Releases for this repository:

https://github.com/EveryInc/compound-engineering-plugin/releases

Multi-component releases are published under component-specific tags such as:

- `cli-vX.Y.Z`
- `compound-engineering-vX.Y.Z`
- `coding-tutor-vX.Y.Z`
- `marketplace-vX.Y.Z`

Do not add new release entries here. New release notes are managed by release automation in GitHub.


================================================
FILE: CLAUDE.md
================================================
@AGENTS.md


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Every

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: PRIVACY.md
================================================
# Privacy & Data Handling

This repository contains:
- a plugin package (`plugins/compound-engineering`) made of markdown/config content
- a CLI (`@every-env/compound-plugin`) that converts and installs plugin content for different AI coding tools

## Summary

- The plugin package does not include telemetry or analytics code.
- The plugin package does not run a background service that uploads repository/workspace contents automatically.
- Data leaves your machine only when your host/tooling or an explicitly invoked integration performs a network request.

## What May Send Data

1. AI host/model providers

If you run the plugin in tools like Claude Code, Cursor, Gemini CLI, Copilot, Kiro, Windsurf, etc., those tools may send prompts/context/code to their configured model providers. This behavior is controlled by those tools and providers, not by this plugin repository.

2. Optional integrations and tools

The plugin includes optional capabilities that can call external services when explicitly used, for example:
- Context7 MCP (`https://mcp.context7.com/mcp`) for documentation lookup
- Proof (`https://www.proofeditor.ai`) when using share/edit flows
- Other opt-in skills (for example image generation or cloud upload workflows) that call their own external APIs/services

If you do not invoke these integrations, they do not transmit your project data.

3. Package/installer infrastructure

Installing dependencies or packages (for example `npm`, `bunx`) communicates with package registries/CDNs according to your package manager configuration.

## Data Ownership and Retention

This repository does not operate a backend service for collecting or storing your project/workspace data. Data retention and processing for model prompts or optional integrations are governed by the external services you use.

## Security Reporting

If you identify a security issue in this repository, follow the disclosure process in [SECURITY.md](SECURITY.md).


================================================
FILE: README.md
================================================
# Compound Marketplace

[![Build Status](https://github.com/EveryInc/compound-engineering-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/EveryInc/compound-engineering-plugin/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/@every-env/compound-plugin)](https://www.npmjs.com/package/@every-env/compound-plugin)

A Claude Code plugin marketplace featuring the **Compound Engineering Plugin** — tools that make each unit of engineering work easier than the last.

## Claude Code Install

```bash
/plugin marketplace add EveryInc/compound-engineering-plugin
/plugin install compound-engineering
```

## Cursor Install

```text
/add-plugin compound-engineering
```

## OpenCode, Codex, Droid, Pi, Gemini, Copilot, Kiro, Windsurf, OpenClaw & Qwen (experimental) Install

This repo includes a Bun/TypeScript CLI that converts Claude Code plugins to OpenCode, Codex, Factory Droid, Pi, Gemini CLI, GitHub Copilot, Kiro CLI, Windsurf, OpenClaw, and Qwen Code.

```bash
# convert the compound-engineering plugin into OpenCode format
bunx @every-env/compound-plugin install compound-engineering --to opencode

# convert to Codex format
bunx @every-env/compound-plugin install compound-engineering --to codex

# convert to Factory Droid format
bunx @every-env/compound-plugin install compound-engineering --to droid

# convert to Pi format
bunx @every-env/compound-plugin install compound-engineering --to pi

# convert to Gemini CLI format
bunx @every-env/compound-plugin install compound-engineering --to gemini

# convert to GitHub Copilot format
bunx @every-env/compound-plugin install compound-engineering --to copilot

# convert to Kiro CLI format
bunx @every-env/compound-plugin install compound-engineering --to kiro

# convert to OpenClaw format
bunx @every-env/compound-plugin install compound-engineering --to openclaw

# convert to Windsurf format (global scope by default)
bunx @every-env/compound-plugin install compound-engineering --to windsurf

# convert to Windsurf workspace scope
bunx @every-env/compound-plugin install compound-engineering --to windsurf --scope workspace

# convert to Qwen Code format
bunx @every-env/compound-plugin install compound-engineering --to qwen

# auto-detect installed tools and install to all
bunx @every-env/compound-plugin install compound-engineering --to all
```

### Local Development

When developing and testing local changes to the plugin:

**Claude Code** — add a shell alias so your local copy loads alongside your normal plugins:

```bash
# add to ~/.zshrc or ~/.bashrc
alias claude-dev-ce='claude --plugin-dir ~/code/compound-engineering-plugin/plugins/compound-engineering'
```

One-liner to append it:

```bash
echo "alias claude-dev-ce='claude --plugin-dir ~/code/compound-engineering-plugin/plugins/compound-engineering'" >> ~/.zshrc
```

Then run `claude-dev-ce` instead of `claude` to test your changes. Your production install stays untouched.

**Codex** — point the install command at your local path:

```bash
bun run src/index.ts install ./plugins/compound-engineering --to codex
```

**Other targets** — same pattern, swap the target:

```bash
bun run src/index.ts install ./plugins/compound-engineering --to opencode
```

<details>
<summary>Output format details per target</summary>

| Target | Output path | Notes |
|--------|------------|-------|
| `opencode` | `~/.config/opencode/` | Commands as `.md` files; `opencode.json` MCP config deep-merged; backups made before overwriting |
| `codex` | `~/.codex/prompts` + `~/.codex/skills` | Claude commands become prompt + skill pairs; canonical `ce:*` workflow skills also get prompt wrappers; deprecated `workflows:*` aliases are omitted |
| `droid` | `~/.factory/` | Tool names mapped (`Bash`→`Execute`, `Write`→`Create`); namespace prefixes stripped |
| `pi` | `~/.pi/agent/` | Prompts, skills, extensions, and `mcporter.json` for MCPorter interoperability |
| `gemini` | `.gemini/` | Skills from agents; commands as `.toml`; namespaced commands become directories (`workflows:plan` → `commands/workflows/plan.toml`) |
| `copilot` | `.github/` | Agents as `.agent.md` with Copilot frontmatter; MCP env vars prefixed with `COPILOT_MCP_` |
| `kiro` | `.kiro/` | Agents as JSON configs + prompt `.md` files; only stdio MCP servers supported |
| `openclaw` | `~/.openclaw/extensions/<plugin>/` | Entry-point TypeScript skill file; `openclaw-extension.json` for MCP servers |
| `windsurf` | `~/.codeium/windsurf/` (global) or `.windsurf/` (workspace) | Agents become skills; commands become flat workflows; `mcp_config.json` merged |
| `qwen` | `~/.qwen/extensions/<plugin>/` | Agents as `.yaml`; env vars with placeholders extracted as settings; colon separator for nested commands |

All provider targets are experimental and may change as the formats evolve.

</details>

## Sync Personal Config

Sync your personal Claude Code config (`~/.claude/`) to other AI coding tools. Omit `--target` to sync to all detected supported tools automatically:

```bash
# Sync to all detected tools (default)
bunx @every-env/compound-plugin sync

# Sync skills and MCP servers to OpenCode
bunx @every-env/compound-plugin sync --target opencode

# Sync to Codex
bunx @every-env/compound-plugin sync --target codex

# Sync to Pi
bunx @every-env/compound-plugin sync --target pi

# Sync to Droid
bunx @every-env/compound-plugin sync --target droid

# Sync to GitHub Copilot (skills + MCP servers)
bunx @every-env/compound-plugin sync --target copilot

# Sync to Gemini (skills + MCP servers)
bunx @every-env/compound-plugin sync --target gemini

# Sync to Windsurf
bunx @every-env/compound-plugin sync --target windsurf

# Sync to Kiro
bunx @every-env/compound-plugin sync --target kiro

# Sync to Qwen
bunx @every-env/compound-plugin sync --target qwen

# Sync to OpenClaw (skills only; MCP is validation-gated)
bunx @every-env/compound-plugin sync --target openclaw

# Sync to all detected tools
bunx @every-env/compound-plugin sync --target all
```

This syncs:
- Personal skills from `~/.claude/skills/` (as symlinks)
- Personal slash commands from `~/.claude/commands/` (as provider-native prompts, workflows, or converted skills where supported)
- MCP servers from `~/.claude/settings.json`

Skills are symlinked (not copied) so changes in Claude Code are reflected immediately.

Supported sync targets:
- `opencode`
- `codex`
- `pi`
- `droid`
- `copilot`
- `gemini`
- `windsurf`
- `kiro`
- `qwen`
- `openclaw`

Notes:
- Codex sync preserves non-managed `config.toml` content and now includes remote MCP servers.
- Command sync reuses each provider's existing Claude command conversion, so some targets receive prompts or workflows while others receive converted skills.
- Copilot sync writes personal skills to `~/.copilot/skills/` and MCP config to `~/.copilot/mcp-config.json`.
- Gemini sync writes MCP config to `~/.gemini/` and avoids mirroring skills that Gemini already discovers from `~/.agents/skills`, which prevents duplicate-skill warnings.
- Droid, Windsurf, Kiro, and Qwen sync merge MCP servers into the provider's documented user config.
- OpenClaw currently syncs skills only. Personal command sync is skipped because this repo does not yet have a documented user-level OpenClaw command surface, and MCP sync is skipped because the current official OpenClaw docs do not clearly document an MCP server config contract.

## Workflow

```
Brainstorm → Plan → Work → Review → Compound → Repeat
    ↑
  Ideate (optional — when you need ideas)
```

| Command | Purpose |
|---------|---------|
| `/ce:ideate` | Discover high-impact project improvements through divergent ideation and adversarial filtering |
| `/ce:brainstorm` | Explore requirements and approaches before planning |
| `/ce:plan` | Turn feature ideas into detailed implementation plans |
| `/ce:work` | Execute plans with worktrees and task tracking |
| `/ce:review` | Multi-agent code review before merging |
| `/ce:compound` | Document learnings to make future work easier |

The `/ce:ideate` skill proactively surfaces strong improvement ideas, and `/ce:brainstorm` then clarifies the selected one before committing to a plan.

Each cycle compounds: brainstorms sharpen plans, plans inform future plans, reviews catch more issues, patterns get documented.

> **Beta:** Experimental versions of `/ce:plan` and `/deepen-plan` are available as `/ce:plan-beta` and `/deepen-plan-beta`. See the [plugin README](plugins/compound-engineering/README.md#beta-skills) for details.

## Philosophy

**Each unit of engineering work should make subsequent units easier—not harder.**

Traditional development accumulates technical debt. Every feature adds complexity. The codebase becomes harder to work with over time.

Compound engineering inverts this. 80% is in planning and review, 20% is in execution:
- Plan thoroughly before writing code
- Review to catch issues and capture learnings
- Codify knowledge so it's reusable
- Keep quality high so future changes are easy

## Learn More

- [Full component reference](plugins/compound-engineering/README.md) - all agents, commands, skills
- [Compound engineering: how Every codes with agents](https://every.to/chain-of-thought/compound-engineering-how-every-codes-with-agents)
- [The story behind compounding engineering](https://every.to/source-code/my-ai-had-already-fixed-the-code-before-i-saw-it)


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Security fixes are applied to the latest version on `main`.

## Reporting a Vulnerability

Please do not open a public issue for undisclosed vulnerabilities.

Instead, report privately by emailing:
- `kieran@every.to`

Include:
- A clear description of the issue
- Reproduction steps or proof of concept
- Impact assessment (what an attacker can do)
- Any suggested mitigation

We will acknowledge receipt as soon as possible and work with you on validation, remediation, and coordinated disclosure timing.

## Scope Notes

This repository primarily contains plugin instructions/configuration plus a conversion/install CLI.

- Plugin instruction content itself does not run as a server process.
- Security/privacy behavior also depends on the host AI tool and any external integrations you explicitly invoke.

For data-handling details, see [PRIVACY.md](PRIVACY.md).


================================================
FILE: docs/brainstorms/2026-02-14-copilot-converter-target-brainstorm.md
================================================
---
date: 2026-02-14
topic: copilot-converter-target
---

# Add GitHub Copilot Converter Target

## What We're Building

A new converter target that transforms the compound-engineering Claude Code plugin into GitHub Copilot's native format. This follows the same established pattern as the existing converters (Cursor, Codex, OpenCode, Droid, Pi) and outputs files that Copilot can consume directly from `.github/` (repo-level) or `~/.copilot/` (user-wide).

Copilot's customization system (as of early 2026) supports: custom agents (`.agent.md`), agent skills (`SKILL.md`), prompt files (`.prompt.md`), custom instructions (`copilot-instructions.md`), and MCP servers (via repo settings).

## Why This Approach

The repository already has a robust multi-target converter infrastructure with a consistent `TargetHandler` pattern. Adding Copilot as a new target follows this proven pattern rather than inventing something new. Copilot's format is close enough to Claude Code's that the conversion is straightforward, and the SKILL.md format is already cross-compatible.

### Approaches Considered

1. **Full converter target (chosen)** — Follow the existing pattern with types, converter, writer, and target registration. Most consistent with codebase conventions.
2. **Minimal agent-only converter** — Only convert agents, skip commands/skills. Too limited; users would lose most of the plugin's value.
3. **Documentation-only approach** — Just document how to manually set up Copilot. Doesn't compound — every user would repeat the work.

## Key Decisions

### Component Mapping

| Claude Code Component | Copilot Equivalent | Notes |
|----------------------|-------------------|-------|
| **Agents** (`.md`) | **Custom Agents** (`.agent.md`) | Full frontmatter mapping: description, tools, target, infer |
| **Commands** (`.md`) | **Agent Skills** (`SKILL.md`) | Commands become skills since Copilot has no direct command equivalent. `allowed-tools` dropped silently. |
| **Skills** (`SKILL.md`) | **Agent Skills** (`SKILL.md`) | Copy as-is — format is already cross-compatible |
| **MCP Servers** | **Repo settings JSON** | Generate a `copilot-mcp-config.json` users paste into GitHub repo settings |
| **Hooks** | **Skipped with warning** | Copilot doesn't have a hooks equivalent |

### Agent Frontmatter Mapping

| Claude Field | Copilot Field | Mapping |
|-------------|--------------|---------|
| `name` | `name` | Direct pass-through |
| `description` | `description` (required) | Direct pass-through, generate fallback if missing |
| `capabilities` | Body text | Fold into body as "## Capabilities" section (like Cursor) |
| `model` | `model` | Pass through (works in IDE, may be ignored on github.com) |
| — | `tools` | Default to `["*"]` (all tools). Claude agents have unrestricted tool access, so Copilot agents should too. |
| — | `target` | Omit (defaults to `both` — IDE + github.com) |
| — | `infer` | Set to `true` (auto-selection enabled) |

### Output Directories

- **Repository-level (default):** `.github/agents/`, `.github/skills/`
- **User-wide (with --personal flag):** `~/.copilot/skills/` (only skills supported at this level)

### Content Transformation

Apply transformations similar to Cursor converter:

1. **Task agent calls:** `Task agent-name(args)` → `Use the agent-name skill to: args`
2. **Slash commands:** `/workflows:plan` → `/plan` (flatten namespace)
3. **Path rewriting:** `.claude/` → `.github/` (Copilot's repo-level config path)
4. **Agent references:** `@agent-name` → `the agent-name agent`

### MCP Server Handling

Generate a `copilot-mcp-config.json` file with the structure Copilot expects:

```json
{
  "mcpServers": {
    "server-name": {
      "type": "local",
      "command": "npx",
      "args": ["package"],
      "tools": ["*"],
      "env": {
        "KEY": "COPILOT_MCP_KEY"
      }
    }
  }
}
```

Note: Copilot requires env vars to use the `COPILOT_MCP_` prefix. The converter should transform env var names accordingly and include a comment/note about this.

## Files to Create/Modify

### New Files

- `src/types/copilot.ts` — Type definitions (CopilotAgent, CopilotSkill, CopilotBundle, etc.)
- `src/converters/claude-to-copilot.ts` — Converter with `transformContentForCopilot()`
- `src/targets/copilot.ts` — Writer with `writeCopilotBundle()`
- `docs/specs/copilot.md` — Format specification document

### Modified Files

- `src/targets/index.ts` — Register copilot target handler
- `src/commands/sync.ts` — Add "copilot" to valid sync targets

### Test Files

- `tests/copilot-converter.test.ts` — Converter tests following existing patterns

### Character Limit

Copilot imposes a 30,000 character limit on agent body content. If an agent body exceeds this after folding in capabilities, the converter should truncate with a warning to stderr.

### Agent File Extension

Use `.agent.md` (not plain `.md`). This is the canonical Copilot convention and makes agent files immediately identifiable.

## Open Questions

- Should the converter generate a `copilot-setup-steps.yml` workflow file for MCP servers that need special dependencies (e.g., `uv`, `pipx`)?
- Should `.github/copilot-instructions.md` be generated with any base instructions from the plugin?

## Next Steps

→ `/workflows:plan` for implementation details


================================================
FILE: docs/brainstorms/2026-02-17-copilot-skill-naming-brainstorm.md
================================================
---
date: 2026-02-17
topic: copilot-skill-naming
---

# Copilot Skill Naming: Preserve Namespace

## What We're Building

Change the Copilot converter to preserve command namespaces when converting commands to skills. Currently `workflows:plan` flattens to `plan`, which is too generic and clashes with Copilot's own features in the chat suggestion UI.

## Why This Approach

The `flattenCommandName` function strips everything before the last colon, producing names like `plan`, `review`, `work` that are too generic for Copilot's skill discovery UI. Replacing colons with hyphens (`workflows:plan` -> `workflows-plan`) preserves context while staying within valid filename characters.

## Key Decisions

- **Replace colons with hyphens** instead of stripping the prefix: `workflows:plan` -> `workflows-plan`
- **Copilot only** — other converters (Cursor, Droid, etc.) keep their current flattening behavior
- **Content transformation too** — slash command references in body text also use hyphens: `/workflows:plan` -> `/workflows-plan`

## Changes Required

1. `src/converters/claude-to-copilot.ts` — change `flattenCommandName` to replace colons with hyphens
2. `src/converters/claude-to-copilot.ts` — update `transformContentForCopilot` slash command rewriting
3. `tests/copilot-converter.test.ts` — update affected tests

## Next Steps

-> Implement directly (small, well-scoped change)


================================================
FILE: docs/brainstorms/2026-03-14-ce-plan-rewrite-requirements.md
================================================
---
date: 2026-03-14
topic: ce-plan-rewrite
---

# Rewrite `ce:plan` to Separate Planning from Implementation

## Problem Frame

`ce:plan` sits between `ce:brainstorm` and `ce:work`, but the current skill mixes issue authoring, technical planning, and pseudo-implementation. That makes plans brittle and pushes the planning phase to predict details that are often only discoverable during implementation. PR #246 intensifies this by asking plans to include complete code, exact commands, and micro-step TDD and commit choreography. The rewrite should keep planning strong enough for a capable agent or engineer to execute, while moving code-writing, test-running, and execution-time learning back into `ce:work`.

## Requirements

- R1. `ce:plan` must accept either a raw feature description or a requirements document produced by `ce:brainstorm` as primary input.
- R2. `ce:plan` must preserve compound-engineering's planning strengths: repo pattern scan, institutional learnings, conditional external research, and requirements-gap checks when warranted.
- R3. `ce:plan` must produce a durable implementation plan focused on decisions, sequencing, file paths, dependencies, risks, and test scenarios, not implementation code.
- R4. `ce:plan` must not instruct the planner to run tests, generate exact implementation snippets, or learn from execution-time results. Those belong to `ce:work`.
- R5. Plan tasks and subtasks must be right-sized for implementation handoff, but sized as logical units or atomic commits rather than 2-5 minute copy-paste steps.
- R6. Plans must remain shareable and portable as documents or issues without tool-specific executor litter such as TodoWrite instructions, `/ce:work` choreography, or git command recipes in the artifact itself.
- R7. `ce:plan` must carry forward product decisions, scope boundaries, success criteria, and deferred questions from `ce:brainstorm` without re-inventing them.
- R8. `ce:plan` must explicitly distinguish what gets resolved during planning from what is intentionally deferred to implementation-time discovery.
- R9. `ce:plan` must hand off cleanly to `ce:work`, giving enough information for task creation without pre-writing code.
- R10. If detail levels remain, they must change depth of analysis and documentation, not the planning philosophy. A small plan can be terse while still staying decision-first.
- R11. If an upstream requirements document contains unresolved `Resolve Before Planning` items, `ce:plan` must classify whether they are true product blockers or misfiled technical questions before proceeding.
- R12. `ce:plan` must not plan past unresolved product decisions that would change behavior, scope, or success criteria, but it may absorb technical or research questions by reclassifying them into planning-owned investigation.
- R13. When true blockers remain, `ce:plan` must pause helpfully: surface the blockers, allow the user to convert them into explicit assumptions or decisions, or route them back to `ce:brainstorm`.

## Success Criteria

- A fresh implementer can start work from the plan without needing clarifying questions, but the plan does not contain implementation code.
- `ce:work` can derive actionable tasks from the plan without relying on micro-step commands or embedded git/test instructions.
- Plans stay accurate longer as repo context changes because they capture decisions and boundaries rather than speculative code.
- A requirements document from `ce:brainstorm` flows into planning without losing decisions, scope boundaries, or success criteria.
- Plans do not proceed past unresolved product blockers unless the user explicitly converts them into assumptions or decisions.
- For the same feature, the rewritten `ce:plan` produces output that is materially shorter and less brittle than the current skill or PR #246's proposed format while remaining execution-ready.

## Scope Boundaries

- Do not redesign `ce:brainstorm`'s product-definition role.
- Do not remove decomposition, file paths, verification, or risk analysis from `ce:plan`.
- Do not move planning into a vague, under-specified artifact that leaves execution to guess.
- Do not change `ce:work` in this phase beyond possible follow-up clarification of what plan structure it should prefer.
- Do not require heavyweight PRD ceremony for small or straightforward work.

## Key Decisions

- Use a hybrid model: keep compound-engineering's research and handoff strengths, but adopt iterative-engineering's "decisions, not code" boundary.
- Planning stops before execution: no running tests, no fail/pass learning, no exact implementation snippets, and no commit shell commands in the plan.
- Use logical tasks and subtasks sized around atomic changes or commit units rather than 2-5 minute micro-steps.
- Keep explicit verification and test scenarios, but express them as expected coverage and validation outcomes rather than commands with predicted output.
- Preserve `ce:brainstorm` as the preferred upstream input when available, with clear handling for deferred technical questions.
- Treat `Resolve Before Planning` as a classification gate: planning first distinguishes true product blockers from technical questions, then investigates only the latter.

## High-Level Direction

- Phase 0: Resume existing plan work when relevant, detect brainstorm input, and assess scope.
- Phase 1: Gather context through repo research, institutional learnings, and conditional external research.
- Phase 2: Resolve planning-time technical questions and capture implementation-time unknowns separately.
- Phase 3: Structure the plan around components, dependencies, files, test targets, risks, and verification.
- Phase 4: Write a right-sized plan artifact whose depth varies by scope, but whose boundary stays planning-only.
- Phase 5: Review and hand off to refinement, deeper research, issue sharing, or `ce:work`.

## Alternatives Considered

- Keep the current `ce:plan` and only reject PR #246.
  Rejected because the underlying issue remains: the current skill already drifts toward issue-template output plus pseudo-implementation.
- Adopt Superpowers `writing-plans` nearly wholesale.
  Rejected because it is intentionally execution-script-oriented and collapses planning into detailed code-writing and command choreography.
- Adopt iterative-engineering `tech-planning` wholesale.
  Rejected because it would lose useful compound-engineering behaviors such as brainstorm-origin integration, institutional learnings, and richer post-plan handoff options.

## Dependencies / Assumptions

- `ce:work` can continue creating its own actionable task list from a decision-first plan.
- If `ce:work` later benefits from an explicit section such as `## Implementation Units` or `## Work Breakdown`, that should be a separate follow-up designed around execution needs rather than micro-step code generation.

## Resolved During Planning

- [Affects R10][Technical] Replaced `MINIMAL` / `MORE` / `A LOT` with `Lightweight` / `Standard` / `Deep` to align `ce:plan` with `ce:brainstorm`'s scope model.
- [Affects R9][Technical] Updated `ce:work` to explicitly consume decision-first plan sections such as `Implementation Units`, `Requirements Trace`, `Files`, `Test Scenarios`, and `Verification`.
- [Affects R2][Needs research] Kept SpecFlow as a conditional planning aid: use it for `Standard` or `Deep` plans when flow completeness is unclear rather than making it mandatory for every plan.

## Next Steps

-> Review, refine, and commit the `ce:plan` and `ce:work` rewrite


================================================
FILE: docs/brainstorms/2026-03-15-ce-ideate-skill-requirements.md
================================================
---
date: 2026-03-15
topic: ce-ideate-skill
---

# ce:ideate — Open-Ended Ideation Skill

## Problem Frame

The ce:brainstorm skill is reactive — the user brings an idea, and the skill helps refine it through collaborative dialogue. There is no workflow for the opposite direction: having the AI proactively generate ideas by deeply understanding the project and then filtering them through critical self-evaluation. Users currently achieve this through ad-hoc prompting (e.g., "come up with 100 ideas and give me your best 10"), but that approach has no codebase grounding, no structured output, no durable artifact, and no connection to the ce:* workflow pipeline.

## Requirements

- R1. ce:ideate is a standalone skill, separate from ce:brainstorm, with its own SKILL.md in `plugins/compound-engineering/skills/ce-ideate/`
- R2. Accepts an optional freeform argument that serves as a focus hint — can be a concept ("DX improvements"), a path ("plugins/compound-engineering/skills/"), a constraint ("low-complexity quick wins"), or empty for fully open ideation
- R3. Performs a deep codebase scan before generating ideas, grounding ideation in the actual project state rather than abstract speculation
- R4. Preserves the user's proven prompt mechanism as the core workflow: generate many ideas first, then systematically and critically reject weak ones, then explain only the surviving ideas in detail
- R5. Self-critiques the full list, rejecting weak ideas with explicit reasoning — the adversarial filtering step is the core quality mechanism
- R6. Presents the top 5-7 surviving ideas with structured analysis: description, rationale, downsides, confidence score (0-100%), estimated complexity
- R7. Includes a brief rejection summary — one-line per rejected idea with the reason — so the user can see what was considered and why it was cut
- R8. Writes a durable ideation artifact to `docs/ideation/YYYY-MM-DD-<topic>-ideation.md` (or `YYYY-MM-DD-open-ideation.md` when no focus area). This compounds — rejected ideas prevent re-exploring dead ends, and un-acted-on ideas remain available for future sessions.
- R9. The default volume (~30 ideas, top 5-7 presented) can be overridden by the user's argument (e.g., "give me your top 3" or "go deep, 100 ideas")
- R10. Handoff options after presenting ideas: brainstorm a selected idea (feeds into ce:brainstorm), refine the ideation (dig deeper, re-evaluate, explore new angles), share to Proof, or end the session
- R11. Always routes to ce:brainstorm when the user wants to act on an idea — ideation output is never detailed enough to skip requirements refinement
- R12. Session completion: when ending, offer to commit the ideation doc to the current branch. If the user declines, leave the file uncommitted. Do not create branches or push — just the local commit.
- R13. Resume behavior: when ce:ideate is invoked, check `docs/ideation/` for ideation docs created within the last 30 days. If a relevant one exists, offer to continue from it (add new ideas, revisit rejected ones, act on un-explored ideas) or start fresh.
- R14. Present the surviving candidates to the user before writing the durable ideation artifact, so the user can ask questions or lightly reshape the candidate set before it is archived
- R15. The ideation artifact must be written or updated before any downstream handoff, Proof sharing, or session end, even though the initial survivor presentation happens first
- R16. Refine routes based on intent: "add more ideas" or "explore new angles" returns to generation (Phase 2), "re-evaluate" or "raise the bar" returns to critique (Phase 3), "dig deeper on idea #N" expands that idea's analysis in place. The ideation doc is updated after each refinement when the refined state is being preserved
- R17. Uses agent intelligence to improve ideation quality, but only as support for the core prompt mechanism rather than as a replacement for it
- R18. Uses existing research agents for codebase grounding, but ideation and critique sub-agents are prompt-defined roles with distinct perspectives rather than forced reuse of existing named review agents
- R19. When sub-agents are used for ideation, each one receives the same grounding summary, the user focus hint, and the current volume target
- R20. Focus hints influence both candidate generation and final filtering; they are not only an evaluation-time bias
- R21. Ideation sub-agents return ideas in a standardized structured format so the orchestrator can merge, dedupe, and reason over them consistently
- R22. The orchestrator owns final scoring, ranking, and survivor decisions across the merged idea set; sub-agents may emit lightweight local signals, but they do not authoritatively rank their own ideas
- R23. Distinct ideation perspectives should be created through prompt framing methods that encourage creative spread without over-constraining the workflow; examples include friction, unmet need, inversion, assumption-breaking, leverage, and extreme-case prompts
- R24. The skill does not hardcode a fixed number of sub-agents for all runs; it should use the smallest useful set that preserves diversity without overwhelming the orchestrator's context window
- R25. When the user picks an idea to brainstorm, the ideation doc is updated to mark that idea as "explored" with a reference to the resulting brainstorm session date, so future revisits show which ideas have been acted on.

## Success Criteria

- A user can invoke `/ce:ideate` with no arguments on any project and receive genuinely surprising, high-quality improvement ideas grounded in the actual codebase
- Ideas that survive the filter are meaningfully better than what the user would get from a naive "give me 10 ideas" prompt
- The workflow uses agent intelligence to widen the candidate pool without obscuring the core generate -> reject -> survivors mechanism
- The user sees and can question the surviving candidates before they are written into the durable artifact
- The ideation artifact persists and provides value when revisited weeks later
- The skill composes naturally with the existing pipeline: ideate → brainstorm → plan → work

## Scope Boundaries

- ce:ideate does NOT produce requirements, plans, or code — it produces ranked ideas
- ce:ideate does NOT modify ce:brainstorm's behavior — discovery of ce:ideate is handled through the skill description and catalog, not by altering other skills
- The skill does not do external research (competitive analysis, similar projects) in v1 — this could be a future enhancement but adds cost and latency without proven need
- No configurable depth modes in v1 — fixed volume with argument-based override is sufficient

## Key Decisions

- **Standalone skill, not a mode within ce:brainstorm**: The workflows are fundamentally different cognitive modes (proactive/divergent vs. reactive/convergent) with different phases, outputs, and success criteria. Combining them would make ce:brainstorm harder to maintain and blur its identity.
- **Durable artifact in docs/ideation/**: Discarding ideation results is anti-compounding. The file is cheap to write and provides value when revisiting un-acted-on ideas or avoiding re-exploration of rejected ones.
- **Artifact written after candidate review, not before initial presentation**: The first survivor presentation is collaborative review, not archival finalization. The artifact should be written only after the candidate set is good enough to preserve, but always before handoff, sharing, or session end.
- **Always route to ce:brainstorm for follow-up**: At ideation depth, ideas are one-paragraph concepts — never detailed enough to skip requirements refinement.
- **Survivors + rejection summary output format**: Full transparency on what was considered without overwhelming with detailed analysis of rejected ideas.
- **Freeform optional argument**: A concept, a path, or nothing at all — the skill interprets whatever it gets as context. No artificial distinction between "focus area" and "target path."
- **Agent intelligence as support, not replacement**: The value comes from the proven ideation-and-rejection mechanism. Parallel sub-agents help produce a richer candidate pool and stronger critique, but the orchestrator remains responsible for synthesis, scoring, and final ranking.

## Outstanding Questions

### Deferred to Planning

- [Affects R3][Technical] Which research agents should always run for codebase grounding in v1 beyond `repo-research-analyst` and `learnings-researcher`, if any?
- [Affects R21][Technical] What exact structured output schema should ideation sub-agents return so the orchestrator can merge and score consistently without overfitting the format too early?
- [Affects R6][Technical] Should the structured analysis per surviving idea include "suggested next steps" or "what this would unlock" beyond the current fields (description, rationale, downsides, confidence, complexity)?
- [Affects R2][Technical] How should the skill detect volume overrides in the freeform argument vs. focus-area hints? Simple heuristic or explicit parsing?

## Next Steps

→ `/ce:plan` for structured implementation planning


================================================
FILE: docs/brainstorms/2026-03-16-issue-grounded-ideation-requirements.md
================================================
---
date: 2026-03-16
topic: issue-grounded-ideation
---

# Issue-Grounded Ideation Mode for ce:ideate

## Problem Frame

When a team wants to ideate on improvements, their issue tracker holds rich signal about real user pain, recurring failures, and severity patterns — but ce:ideate currently only looks at the codebase and past learnings. Teams have to manually synthesize issue patterns before ideating, or they ideate without that context and miss what their users are actually hitting.

The goal is not "fix individual bugs" but "generate strategic improvement ideas grounded in the patterns your issue tracker reveals." 25 duplicate bugs about the same failure mode is a signal about collaboration reliability, not 25 separate problems.

## Requirements

- R1. When the user's argument indicates they want issue-tracker data as input (e.g., "bugs", "github issues", "open issues", "what users are reporting", "issue patterns"), ce:ideate activates an issue intelligence step alongside the existing Phase 1 scans
- R2. A new **issue intelligence agent** fetches, clusters, deduplicates, and analyzes issues, returning structured theme analysis — not a list of individual issues
- R3. The agent fetches **open issues** plus **recently closed issues** (approximately 30 days), filtering out issues closed as duplicate, won't-fix, or not-planned. Recently fixed issues are included because they show which areas had enough pain to warrant action.
- R4. Issue clusters drive the ideation frames in Phase 2 using a **hybrid strategy**: derive frames from clusters, pad with default frames (e.g., "assumption-breaking", "leverage/compounding") when fewer than 4 clusters exist. This ensures ideas are grounded in real pain patterns while maintaining ideation diversity.
- R5. The existing Phase 1 scans (codebase context + learnings search) still run in parallel — issue analysis is additive context, not a replacement
- R6. The issue intelligence agent detects the repository from the current directory's git remote
- R7. Start with GitHub issues via `gh` CLI. Design the agent prompt and output structure so Linear or other trackers can be added later without restructuring the ideation flow.
- R8. The issue intelligence agent is independently useful outside of ce:ideate — it can be dispatched directly by a user or other workflows to summarize issue themes, understand the current landscape, or reason over recent activity. Its output should be self-contained, not coupled to ideation-specific context.
- R9. The agent's output must communicate at the **theme level**, not the individual-issue level. Each theme should convey: what the pattern is, why it matters (user impact, severity, frequency, trend direction), and what it signals about the system. The output should help a human or agent fully understand the importance and shape of each theme without needing to read individual issues.

## Success Criteria

- Running `/ce:ideate bugs` on a repo with noisy/duplicate issues (like proof's 25+ LIVE_DOC_UNAVAILABLE variants) produces clustered themes, not a rehash of individual issues
- Surviving ideas are strategic improvements ("invest in collaboration reliability infrastructure") not bug fixes ("fix LIVE_DOC_UNAVAILABLE")
- The issue intelligence agent's output is structured enough that ideation sub-agents can engage with themes meaningfully
- Ideation quality is at least as good as the default mode, with the added benefit of issue grounding

## Scope Boundaries

- GitHub issues only in v1 (Linear is a future extension)
- No issue triage or management — this is read-only analysis for ideation input
- No changes to Phase 3 (adversarial filtering) or Phase 4 (presentation) — only Phase 1 and Phase 2 frame derivation are affected
- The issue intelligence agent is a new agent file, not a modification to an existing research agent
- The agent is designed as a standalone capability that ce:ideate composes, not an ideation-internal module
- Assumes `gh` CLI is available and authenticated in the environment
- When a repo has too few issues to cluster meaningfully (e.g., < 5 open+recent), the agent should report that and ce:ideate should fall back to default ideation with a note to the user

## Key Decisions

- **Pattern-first, not issue-first**: The output is improvement ideas grounded in bug patterns, not a prioritized bug list. The ideation instructions already prevent "just fix bug #534" thinking.
- **Hybrid frame strategy**: Clusters derive ideation frames, padded with defaults when thin. Pure cluster-derived frames risk too few frames; pure default frames risk ignoring the issue signal.
- **Flexible argument detection**: Use intent-based parsing ("reasonable interpretation rather than formal parsing") consistent with the existing volume hint system. No rigid keyword matching.
- **Open + recently closed**: Including recently fixed issues provides richer pattern data — shows which areas warranted action, not just what's currently broken.
- **Additive to Phase 1**: Issue analysis runs as a third parallel agent alongside codebase scan and learnings search. All three feed the grounding summary.
- **Titles + labels + sample bodies**: Read titles and labels for all issues (cheap), then read full bodies for 2-3 representative issues per emerging cluster. This handles both well-labeled repos (labels drive clustering, bodies confirm) and poorly-labeled repos (bodies drive clustering). Avoids reading all bodies which is expensive at scale.

## Outstanding Questions

### Deferred to Planning

- [Affects R2][Technical] What structured output format should the issue intelligence agent return? Likely theme clusters with: theme name, issue count, severity distribution, representative issue titles, and a one-line synthesis.
- [Affects R3][Technical] How to detect GitHub close reasons (completed vs not-planned vs duplicate) via `gh` CLI? May need `gh issue list --state closed --json stateReason` or label-based filtering.
- [Affects R4][Technical] What's the threshold for "too few clusters"? Current thinking: pad with default frames when fewer than 4 clusters, but this may need tuning.
- [Affects R6][Technical] How to extract the GitHub repo from git remote? Standard `gh repo view --json nameWithOwner` or parse the remote URL.
- [Affects R7][Needs research] What would a Linear integration look like? Just swapping the fetch mechanism, or does Linear's project/cycle structure change the clustering approach?
- [Affects R2][Technical] Exact number of sample bodies per cluster to read (starting point: 2-3 per cluster).

## Next Steps

→ `/ce:plan` for structured implementation planning


================================================
FILE: docs/brainstorms/2026-03-17-release-automation-requirements.md
================================================
---
date: 2026-03-17
topic: release-automation
---

# Release Automation and Changelog Ownership

## Problem Frame

The repository currently has one automated release flow for the npm CLI, but the broader release story is split across CI, manual maintainer workflows, stale docs, and multiple version surfaces. That makes it hard to batch releases intentionally, hard for multiple maintainers to share release responsibility, and easy for changelogs, plugin manifests, and derived metadata like component counts to drift out of sync. The goal is to move to a release model that supports intentional batching, independent component versioning, centralized history, and CI-owned release authority without forcing version bumps for untouched plugins.

## Requirements

- R1. The release process must be manually triggered; merging to `main` must not automatically publish a release.
- R2. The release system must support batching: releasable merges may accumulate on `main` until maintainers decide to cut a release.
- R3. The release system must maintain a single release PR for the whole repo that stays open until merged and automatically accumulates additional releasable changes merged to `main`.
- R4. The release system must support independent version bumps for these components: `cli`, `compound-engineering`, `coding-tutor`, and `marketplace`.
- R5. The release system must not bump untouched plugins or unrelated components.
- R6. The release system must preserve one centralized root `CHANGELOG.md` as the canonical changelog for the repository.
- R7. The root changelog must record releases as top-level entries per component version, rather than requiring separate changelog files per plugin.
- R8. Existing root changelog history must be preserved during the migration; the new release model must not discard or rewrite historical entries in a way that loses continuity.
- R9. `plugins/compound-engineering/CHANGELOG.md` must no longer be treated as the canonical changelog after the migration.
- R10. The release process must replace the current `release-docs` workflow; `release-docs` must no longer act as a release authority or required release step.
- R11. Narrow scripts must replace `release-docs` responsibilities, including metadata synchronization, count calculation, docs generation where still needed, and validation.
- R12. Release automation must be the sole authority for version bumps, changelog writes, and computed metadata updates such as counts of agents, skills, commands, or similar release-owned descriptions.
- R13. The release flow must support a dry-run mode that summarizes what would happen without publishing, tagging, or committing release changes.
- R14. Dry run output must clearly summarize which components would release, the proposed version bumps, the changelog entries that would be added, and any blocking validation failures.
- R15. Marketplace version bumps must happen only for marketplace-level changes, such as marketplace metadata changes or adding/removing plugins from the catalog.
- R16. Updating a plugin version alone must not require a marketplace version bump.
- R17. Plugin-only content changes must be releasable without requiring a CLI version bump when the CLI code itself has not changed.
- R18. The release model must remain compatible with the current install behavior where `bunx @every-env/compound-plugin install ...` runs the npm CLI but fetches named plugin content from the GitHub repository at runtime.
- R19. The release process must be triggerable by a maintainer or an AI agent through CI without requiring a local maintainer-only skill.
- R20. The resulting model must scale to future plugins without requiring the repo to special-case `compound-engineering` forever.
- R21. The release model must continue to rely on conventional release intent signals (`feat`, `fix`, breaking changes, etc.), but component scopes in commit or PR titles must remain optional rather than required.
- R22. Release automation must infer component ownership primarily from changed files, not from commit or PR title scopes alone.
- R23. The repo should enforce parseable conventional PR or merge titles strongly enough for release tooling to classify change type, while avoiding mandatory component scoping on every change.
- R24. The manual CI-driven release workflow must support explicit bump overrides for exceptional cases, at least `patch`, `minor`, and `major`, without requiring maintainers to create fake or empty commits purely to coerce a release.
- R25. Bump overrides must be expressible per component rather than only as a repo-wide override.
- R26. Dry run output must clearly show both the inferred bump and any applied manual override for each affected component.

## Success Criteria

- Maintainers can let multiple PRs merge to `main` without immediately cutting a release.
- At any point, maintainers can inspect a release PR or dry run and understand what would ship next.
- A change to `coding-tutor` does not force a version bump to `compound-engineering`.
- A plugin version bump does not force a marketplace version bump unless marketplace-level files changed.
- Release-owned metadata and counts stay in sync without relying on a local slash command.
- The root changelog remains readable and continuous before and after the migration.

## Scope Boundaries

- This work does not require changing how Claude Code itself consumes plugin and marketplace versions.
- This work does not require solving end-user auto-update discovery for non-Claude harnesses in v1.
- This work does not require adding dedicated per-plugin changelog files as the canonical history model.
- This work does not require immediate future automation of release timing; manual release remains the default.

## Key Decisions

- **Use `release-please` rather than a single release-line flow**: The repo now has multiple independently versioned components, and the release PR model matches the need to batch merges on `main` until a release is intentionally cut.
- **One release PR for the whole repo**: Centralized release visibility matters more than separate PRs per component, and a single release PR can still carry multiple component bumps.
- **Manual release timing**: The release process should prepare and accumulate the next release automatically, but the decision to cut that release should remain explicit.
- **Root changelog stays canonical**: Centralized history is more important than per-plugin changelog isolation for the current repo shape.
- **Top-level changelog entries per component version**: This preserves one changelog file while keeping independent component version history readable.
- **Retire `release-docs`**: Its responsibilities are too broad, stale, and conflated. Release logic, docs logic, and metadata synchronization should be separated.
- **Scripts for narrow responsibilities**: Explicit scripts are easier to validate, automate, and reuse from CI than a local repo-maintenance skill.
- **Marketplace version is catalog-scoped**: Plugin version bumps alone should not imply a marketplace release.
- **Conventional type required, component scope optional**: Release intent should still come from conventional commit semantics, but requiring `(compound-engineering)` on most repo changes would add unnecessary wording overhead. Component detection should remain file-driven.
- **Manual bump override is an explicit escape hatch**: Automatic bump inference remains the default, but maintainers should be able to override a component's release level in CI for exceptional cases without awkward synthetic commits.

## Dependencies / Assumptions

- The current install flow for named plugins continues to fetch plugin content from GitHub at runtime, so plugin content releases can remain independent from CLI releases unless CLI behavior also changes.
- Claude Code already respects marketplace and plugin versions, so those version surfaces remain meaningful release signals.

## Outstanding Questions

### Deferred to Planning

- [Affects R3][Technical] Should the release PR be updated automatically on every push to `main`, or via a manually triggered maintenance workflow that refreshes the release PR state on demand?
- [Affects R7][Technical] What exact root changelog format best balances readability and automation for multiple component-version entries in one file?
- [Affects R11][Technical] Which responsibilities should become distinct scripts versus steps embedded directly in the CI workflow?
- [Affects R12][Technical] Which release-owned metadata fields should be computed automatically versus validated and left untouched when no count change is needed?
- [Affects R9][Technical] Should `plugins/compound-engineering/CHANGELOG.md` be deleted, frozen, or replaced with a short pointer note after the migration?
- [Affects R21][Technical] Should conventional-format enforcement happen on PR titles, squash-merge titles, commits, or some combination of them?
- [Affects R24][Technical] Should manual bump overrides be implemented as workflow inputs that shape the generated release PR directly, or as an internal generated release-control commit on the release branch only?

## Next Steps

→ `/ce:plan` for structured implementation planning


================================================
FILE: docs/brainstorms/2026-03-18-auto-memory-integration-requirements.md
================================================
---
date: 2026-03-18
topic: auto-memory-integration
---

# Auto Memory Integration for ce:compound and ce:compound-refresh

## Problem Frame

Claude Code's Auto Memory feature passively captures debugging insights, fix patterns, and preferences across sessions in `~/.claude/projects/<project>/memory/`. The ce:compound and ce:compound-refresh skills currently don't leverage this data source, even though it contains exactly the kind of raw material these workflows need: notes about problems solved, approaches tried, and patterns discovered.

After long sessions or compaction, auto memory may preserve insights that conversation context has lost. For ce:compound-refresh, auto memory may contain newer observations that signal drift in existing docs/solutions/ learnings without anyone explicitly flagging it.

## Requirements

- R1. **ce:compound uses auto memory as supplementary evidence.** The orchestrator reads MEMORY.md before launching Phase 1 subagents, scans for entries related to the problem being documented, and passes relevant memory content as additional context to the Context Analyzer and Solution Extractor subagents. Those subagents treat memory notes as supplementary evidence alongside conversation history.
- R2. **ce:compound-refresh investigation subagents check auto memory.** When investigating a candidate learning's staleness, investigation subagents also check auto memory for notes in the same problem domain. A memory note describing a different approach than what the learning recommends is treated as a drift signal.
- R3. **Graceful absence handling.** If auto memory doesn't exist for the project (no memory directory or empty MEMORY.md), all skills proceed exactly as they do today with no errors or warnings.

## Success Criteria

- ce:compound produces richer documentation when auto memory contains relevant notes about the fix, especially after sessions involving compaction
- ce:compound-refresh surfaces staleness signals that would otherwise require manual discovery
- No regression when auto memory is absent or empty

## Scope Boundaries

- **Not changing auto memory's output location or format** -- these skills consume it as-is
- **Read-only** -- neither skill writes to auto memory; ce:compound writes to docs/solutions/ (team-shared, structured), which serves a different purpose than machine-local auto memory
- **Not adding a new subagent** -- existing subagents are augmented with memory-checking instructions
- **Not changing the structure of docs/solutions/ output** -- the final artifacts are the same

## Dependencies / Assumptions

- Claude knows its auto memory directory path from the system prompt context in every session -- no path discovery logic needed in the skills

## Key Decisions

- **Augment existing subagents, not a new one**: ce:compound-refresh investigation subagents need memory context during their own investigation (not as a separate report), so a dedicated Memory Scanner subagent would be awkward. For ce:compound, the orchestrator pre-reads MEMORY.md once and passes relevant excerpts to subagents, avoiding redundant reads while keeping the same subagent count.

## Outstanding Questions

### Deferred to Planning

- [Affects R1][Technical] How should the orchestrator determine which MEMORY.md entries are "related" to the current problem? Keyword matching against the problem description, or broader heuristic?
- [Affects R2][Technical] Should ce:compound-refresh investigation subagents read the full MEMORY.md or only topic files matching the learning's domain? The 200-line MEMORY.md is small enough to read in full, but topic files may be more targeted.

## Next Steps

-> `/ce:plan` for structured implementation planning


================================================
FILE: docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md
================================================
---
title: Convert .local.md Settings for OpenCode and Codex
type: feat
date: 2026-02-08
---

# Convert .local.md Settings for OpenCode and Codex

## Overview

PR #124 introduces `.claude/compound-engineering.local.md` — a YAML frontmatter settings file that workflow commands (`review.md`, `work.md`) read at runtime to decide which agents to run. The conversion script already handles agents, commands, skills, hooks, and MCP servers. It does **not** handle `.local.md` settings files.

The question: can OpenCode and Codex support this same pattern? And what does the converter need to do?

## Analysis: What `.local.md` Actually Does

The settings file does two things:

1. **YAML frontmatter** with structured config: `review_agents: [list]`, `plan_review_agents: [list]`
2. **Markdown body** with free-text instructions passed to review agents as context

The commands (`review.md`, `work.md`) read this file at runtime using the Read tool and use the values to decide which Task agents to spawn. This is **prompt-level logic** — it's instructions in the command body telling the AI "read this file, parse it, act on it."

## Key Insight: This Already Works

The converter already converts `review.md` and `work.md` command bodies verbatim (for OpenCode) or as generated skills (for Codex). The instructions that say "Read `.claude/compound-engineering.local.md`" are just markdown text inside the command body. When the converter outputs them:

- **OpenCode**: The command template includes the full body. The AI reads it, follows the instructions, reads the settings file.
- **Codex**: The command becomes a prompt + generated skill. The skill body includes the instructions. The AI reads it, follows the instructions, reads the settings file.

**The `.local.md` file itself is not a plugin component** — it's a runtime artifact created per-project by the user (via `/compound-engineering-setup`). The converter doesn't need to bundle it.

## What Needs Attention

### 1. Setup Command Has `disable-model-invocation: true`

`setup.md` has `disable-model-invocation: true`. The converter already handles this correctly:

- **OpenCode** (`claude-to-opencode.ts:117`): Skips commands with `disableModelInvocation`
- **Codex** (`claude-to-codex.ts:22`): Filters them out of prompts and generated skills

This means `/compound-engineering-setup` won't be auto-invocable in either target. That's correct — it's a deliberate user action. But it also means users of the converted plugin have **no way to run setup**. They'd need to manually create the `.local.md` file.

### 2. The `.local.md` File Path Is Claude-Specific

The commands reference `.claude/compound-engineering.local.md`. In OpenCode, the equivalent directory is `.opencode/`. In Codex, it's `.codex/`. The converter currently does **no text rewriting** of file paths inside command bodies.

### 3. Slash Command References in Config-Aware Sections

The commands say things like "Run `/compound-engineering-setup` to create a settings file." The Codex converter already transforms `/command-name` → `/prompts:command-name`, but since setup has `disable-model-invocation`, there's no matching prompt. This reference becomes a dead link.

### 4. `Task {agent-name}(...)` Syntax in Review Commands

`review.md` uses `Task {agent-name}(PR content)` — the Codex converter already transforms these to `$skill-name` references. OpenCode passes them through as template text.

## Proposed Solution

### Phase 1: Add Settings File Path Rewriting to Converters

Both converters should rewrite `.claude/` paths inside command bodies to the target-appropriate directory.

**File:** `src/converters/claude-to-opencode.ts`

Add a `transformContentForOpenCode(body)` function that replaces:
- `.claude/compound-engineering.local.md` → `.opencode/compound-engineering.local.md`
- `~/.claude/compound-engineering.local.md` → `~/.config/opencode/compound-engineering.local.md`

Apply it in `convertCommands()` to the command body before storing as template.

**File:** `src/converters/claude-to-codex.ts`

Extend `transformContentForCodex(body)` to also replace:
- `.claude/compound-engineering.local.md` → `.codex/compound-engineering.local.md`
- `~/.claude/compound-engineering.local.md` → `~/.codex/compound-engineering.local.md`

### Phase 2: Generate Setup Equivalent for Each Target

Since `setup.md` is excluded by `disable-model-invocation`, the converter should generate a **target-native setup instruction** that tells users how to create the settings file.

**Option A: Include setup as a non-auto-invocable command anyway** (recommended)

Change the converters to include `disable-model-invocation` commands but mark them appropriately:
- **OpenCode**: Include in command map but add a `manual: true` flag or comment
- **Codex**: Include as a prompt (user can still invoke it manually via `/prompts:compound-engineering-setup`)

This is the simplest approach — the setup instructions are useful even if not auto-triggered.

**Option B: Generate a README/instructions file**

Create a `compound-engineering-settings.md` file in the output that documents how to create the settings file for the target platform. More complex, less useful.

**Recommendation: Option A** — just stop filtering out `disable-model-invocation` commands entirely. Both OpenCode and Codex support user-invoked commands/prompts. The flag exists to prevent Claude from auto-invoking during conversation, not to hide the command entirely.

### Phase 3: Update Tests

**File:** `tests/converter.test.ts`

- Add test that `.claude/` paths in command bodies are rewritten to `.opencode/` paths
- Update existing `disable-model-invocation` test to verify the command IS included (if Option A)

**File:** `tests/codex-converter.test.ts`

- Add test that `.claude/` paths are rewritten to `.codex/` paths
- Add test that setup command is included as a prompt (if Option A)
- Add test that slash command references to setup are preserved correctly

### Phase 4: Add Fixture for Settings-Aware Command

**File:** `tests/fixtures/sample-plugin/commands/settings-aware-command.md`

```markdown
---
name: workflows:review
description: Run comprehensive code reviews
---

Read `.claude/compound-engineering.local.md` for agent config.
If not found, use defaults.
Run `/compound-engineering-setup` to create settings.
```

Test that the converter rewrites the paths and command references correctly.

## Acceptance Criteria

- [ ] OpenCode converter rewrites `.claude/` → `.opencode/` in command bodies
- [ ] Codex converter rewrites `.claude/` → `.codex/` in command/skill bodies
- [ ] Global path `~/.claude/` rewritten to target-appropriate global path
- [ ] `disable-model-invocation` commands are included (not filtered) in both targets
- [ ] Tests cover path rewriting for both targets
- [ ] Tests cover setup command inclusion
- [ ] Existing tests still pass

## What We're NOT Doing

- Not bundling the `.local.md` file itself (it's user-created per-project)
- Not converting YAML frontmatter format (both targets can read `.md` files with YAML)
- Not adding target-specific setup wizards (the instructions in the command body work across all targets)
- Not rewriting `AskUserQuestion` tool references (all three platforms support equivalent interactive tools)

## Complexity Assessment

This is a **small change** — mostly string replacement in the converters plus updating the `disable-model-invocation` filter. The `.local.md` pattern is prompt-level instructions, not a proprietary API. It works anywhere an AI can read a file and follow instructions.


================================================
FILE: docs/plans/2026-02-08-feat-pr-triage-and-merge-plan.md
================================================
---
title: PR Triage, Review & Merge
type: feat
date: 2026-02-08
---

# PR Triage, Review & Merge

## Overview

Review all 17 open PRs one-by-one. Merge the ones that look good, leave constructive comments on the ones we won't take (keeping them open for contributors to address). Close duplicates/spam.

## Approach

Show the diff for each PR, get a go/no-go, then either merge or comment. PRs are ordered by priority group.

## Group 1: Bug Fixes (high confidence merges)

### PR #159 - fix(git-worktree): detect worktrees where .git is a file
- **Author:** dalley | **Files:** 1 | **+2/-2**
- **What:** Changes `-d` to `-e` check in `worktree-manager.sh` so `list` and `cleanup` detect worktrees (`.git` is a file in worktrees, not a dir)
- **Fixes:** Issue #158
- **Action:** Review diff → merge

### PR #144 - Remove confirmation prompt when creating git worktrees
- **Author:** XSAM | **Files:** 1 | **+0/-8**
- **What:** Removes interactive `read -r` confirmation that breaks Claude's ability to create worktrees
- **Related:** Same file as #159 (merge #159 first)
- **Action:** Review diff → merge

### PR #150 - fix(compound): prevent subagents from writing intermediary files
- **Author:** tmchow | **Files:** 1 | **+64/-27**
- **What:** Restructures `/workflows:compound` into 2-phase orchestration to prevent subagents from writing temp files
- **Action:** Review diff → merge

### PR #148 - Fix: resolve_pr_parallel uses non-existent scripts
- **Author:** ajrobertsonio | **Files:** 1 | **+20/-7**
- **What:** Replaces references to non-existent `bin/get-pr-comments` with standard `gh` CLI commands
- **Fixes:** Issues #147, #54
- **Action:** Review diff → merge

## Group 2: Documentation (clean, low-risk)

### PR #133 - Fix terminology: third person → passive voice
- **Author:** FauxReal9999 | **Files:** 13 | docs-only
- **What:** Corrects "third person" to "passive voice" across docs (accurate fix)
- **Action:** Review diff → merge

### PR #108 - Note new repository URL
- **Author:** akx | **Files:** 5 | docs-only
- **What:** Updates URLs from `kieranklaassen/compound-engineering-plugin` to `EveryInc/compound-engineering-plugin`
- **Action:** Review diff → merge

### PR #113 - docs: add brainstorm command to workflow documentation
- **Author:** tmchow | docs-only
- **What:** Adds brainstorming skill and learnings-researcher agent to README, fixes component counts
- **Action:** Review diff → merge

### PR #80 - docs: Add LSP prioritization guidance
- **Author:** kevinold | **Files:** 1 | docs-only
- **What:** Adds docs showing users how to customize agent behavior via project CLAUDE.md to prioritize LSP
- **Action:** Review diff → merge

## Group 3: Enhancements (likely merge)

### PR #119 - fix: backup existing config files before overwriting
- **Author:** jzw | **Files:** 5 | **+90/-3** | has tests
- **What:** Adds `backupFile()` utility to create timestamped backups before overwriting Codex/OpenCode configs
- **Fixes:** Issue #125
- **Action:** Review diff → merge

### PR #112 - feat(skills): add document-review skill
- **Author:** tmchow | enhancement
- **What:** Adds document-review skill for brainstorm/plan refinement, renames `/plan_review` → `/technical_review`
- **Note:** Breaking rename - needs review
- **Action:** Review diff → decide

## Group 4: Needs Discussion (comment and leave open)

### PR #157 - Rewrite workflows:review with context-managed map-reduce
- **Author:** Drewx-Design | large rewrite
- **What:** Complete rewrite of review command with file-based map-reduce architecture
- **Comment:** Acknowledge quality, note it's a big change that needs dedicated review session

### PR #131 - feat: add vmark-mcp plugin
- **Author:** xiaolai | new plugin
- **What:** Adds entirely new VMark markdown editor plugin to marketplace
- **Comment:** Ask for more context on fit with marketplace scope

### PR #124 - feat(commands): add /compound-engineering-setup
- **Author:** internal | config
- **What:** Interactive setup command for configuring review agents per project
- **Comment:** Note overlap with #103, needs unified config strategy

### PR #123 - feat: Add sync command for Claude Code personal config
- **Author:** terry-li-hm | config
- **What:** Sync personal Claude config across machines/editors
- **Comment:** Note overlap with #124 and #103, needs unified config strategy

### PR #103 - Add /compound:configure with persistent user preferences
- **Author:** aviflombaum | **+36,866** lines
- **What:** Massive architectural change adding persistent config with build system
- **Comment:** Too large, suggest breaking into smaller PRs

## Group 5: Close

### PR #122 - [EXPERIMENTAL] add /slfg and /swarm-status
- **Label:** duplicate
- **What:** Already merged in v2.30.0 (commit e4ff6a8)
- **Action:** Comment explaining it's been superseded, close

### PR #68 - Improve all 13 skills to 90%+ grades
- **Label:** wontfix
- **What:** Massive stale PR (Jan 6), based on 13 skills when we now have 16+
- **Action:** Comment thanking contributor, suggest fresh PR against current main, close

## Post-Merge Cleanup

After merging:
- [ ] Close issues fixed by merged PRs (#158, #147, #54, #125)
- [ ] Close spam issues (#98, #56)
- [ ] Run `/release-docs` to update documentation site with new component counts
- [ ] Bump version in plugin.json if needed

## References

- PR list: https://github.com/EveryInc/compound-engineering-plugin/pulls
- Issues: https://github.com/EveryInc/compound-engineering-plugin/issues


================================================
FILE: docs/plans/2026-02-08-feat-simplify-plugin-settings-plan.md
================================================
---
title: Simplify Plugin Settings with .local.md Pattern
type: feat
date: 2026-02-08
---

# Simplify Plugin Settings

## Overview

Replace the 486-line `/compound-engineering-setup` wizard and JSON config with the `.local.md` plugin-settings pattern. Make agent configuration dead simple: a YAML frontmatter file users edit directly, with a lightweight setup command that generates the template.

## Problem Statement

The current branch (`feat/compound-engineering-setup`) has:
- A 486-line setup command with Quick/Advanced/Minimal modes, add/remove loops, custom agent discovery
- JSON config file (`.claude/compound-engineering.json`) — not the plugin-settings convention
- Config-loading boilerplate that would be duplicated across 4 workflow commands
- Over-engineered for "which agents should review my code?"

Meanwhile, the workflow commands on main have hardcoded agent lists that can't be customized per-project.

## Proposed Solution

Use `.claude/compound-engineering.local.md` with YAML frontmatter. Three simple changes:

1. **Rewrite `setup.md`** (486 → ~60 lines) — detect project type, create template file
2. **Add config reading to workflow commands** (~5 lines each) — read file, fall back to defaults
3. **Config is optional** — everything works without it via auto-detection

### Settings File Format

```markdown
---
review_agents: [kieran-rails-reviewer, code-simplicity-reviewer, security-sentinel]
plan_review_agents: [kieran-rails-reviewer, code-simplicity-reviewer]
---

# Review Context

Any extra instructions for review agents go here.
Focus on N+1 queries — we've had issues in the brief system.
Skip agent-native checks for internal admin pages.
```

That's it. No `conditionalAgents`, no `options`, no `customAgents` mapping. Conditional agents (migration, frontend, architecture, data) stay hardcoded in the review command — they trigger based on file patterns, not config.

## Implementation Plan

### Phase 1: Rewrite setup.md

**File:** `plugins/compound-engineering/commands/setup.md`
**From:** 486 lines → **To:** ~60 lines

The setup command should:

- [x] Detect project type (Gemfile+Rails, tsconfig, pyproject.toml, etc.)
- [x] Check if `.claude/compound-engineering.local.md` already exists
- [x] If exists: show current config, ask if user wants to regenerate
- [x] If not: create `.claude/compound-engineering.local.md` with smart defaults for detected type
- [x] Display the file path and tell user they can edit it directly
- [x] No wizard, no multi-step AskUserQuestion flows, no modify loops

**Default agents by project type:**

| Type | review_agents | plan_review_agents |
|------|--------------|-------------------|
| Rails | kieran-rails-reviewer, dhh-rails-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle | kieran-rails-reviewer, code-simplicity-reviewer |
| Python | kieran-python-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle | kieran-python-reviewer, code-simplicity-reviewer |
| TypeScript | kieran-typescript-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle | kieran-typescript-reviewer, code-simplicity-reviewer |
| General | code-simplicity-reviewer, security-sentinel, performance-oracle | code-simplicity-reviewer, architecture-strategist |

### Phase 2: Update review.md

**File:** `plugins/compound-engineering/commands/workflows/review.md`
**Change:** Replace hardcoded agent list (lines 64-81) with config-aware section

Add before the parallel agents section (~5 lines):

```markdown
#### Load Review Agents

Read `.claude/compound-engineering.local.md` (project) or `~/.claude/compound-engineering.local.md` (global).
If found, use `review_agents` from YAML frontmatter. If not found, auto-detect project type and use defaults:
- Rails: kieran-rails-reviewer, dhh-rails-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle
- Python: kieran-python-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle
- TypeScript: kieran-typescript-reviewer, code-simplicity-reviewer, security-sentinel, performance-oracle
- General: code-simplicity-reviewer, security-sentinel, performance-oracle

Run all review agents in parallel using Task tool.
```

**Keep conditional agents hardcoded** — they trigger on file patterns (db/migrate, *.ts, etc.), not user preference. This is correct behavior.

**Add `schema-drift-detector` as a conditional agent** — currently exists as an agent but isn't wired into any command. Add it to the migrations conditional block:

```markdown
**MIGRATIONS: If PR contains database migrations or schema.rb changes:**

- Task schema-drift-detector(PR content) - Detects unrelated schema.rb changes (run FIRST)
- Task data-migration-expert(PR content) - Validates ID mappings, rollback safety
- Task deployment-verification-agent(PR content) - Go/No-Go deployment checklist

**When to run:** PR includes `db/migrate/*.rb` OR `db/schema.rb`
```

`schema-drift-detector` should run first per its own docs — catches drift before other DB reviewers waste time on unrelated changes.

### Phase 3: Update work.md

**File:** `plugins/compound-engineering/commands/workflows/work.md`
**Change:** Replace hardcoded agent list in "Consider Reviewer Agents" section (lines 180-193)

Replace with:

```markdown
If review agents are needed, read from `.claude/compound-engineering.local.md` frontmatter (`review_agents`).
If no config, use project-appropriate defaults. Run in parallel with Task tool.
```

### Phase 4: Update compound.md

**File:** `plugins/compound-engineering/commands/workflows/compound.md`
**Change:** Update Phase 3 "Optional Enhancement" (lines 92-98) and "Applicable Specialized Agents" section (lines 214-234)

The specialized agents in compound.md are problem-type-based (performance → performance-oracle, security → security-sentinel). These should stay hardcoded — they're not "review agents", they're domain experts triggered by problem category. No config needed.

**Only change:** Add a note that users can customize review agents via `/compound-engineering-setup`, but don't add config-reading logic here.

## Acceptance Criteria

- [ ] `setup.md` is under 80 lines
- [ ] Running `/compound-engineering-setup` creates `.claude/compound-engineering.local.md` with correct defaults
- [ ] Running `/compound-engineering-setup` when config exists shows current config and asks before overwriting
- [ ] `/workflows:review` reads agents from `.local.md` when present
- [ ] `/workflows:review` falls back to auto-detected defaults when no config
- [ ] `/workflows:work` reads agents from `.local.md` when present
- [ ] `compound.md` unchanged except for a reference to the setup command
- [ ] No JSON config files — only `.local.md`
- [ ] Config file is optional — everything works without it
- [ ] Conditional agents (migrations, frontend, architecture, data) remain hardcoded in review.md

### Phase 5: Structural Cleanup

**5a. Delete `technical_review.md`**

`commands/technical_review.md` is a one-line command (`Have @agent-dhh-rails-reviewer @agent-kieran-rails-reviewer @agent-code-simplicity-reviewer review...`) with `disable-model-invocation: true`. It duplicates the `/plan_review` skill. Delete it.

- [x] Delete `plugins/compound-engineering/commands/technical_review.md`

**5b. Add `disable-model-invocation: true` to `setup.md`**

The setup command is deliberate — users run it explicitly. It should not be auto-invoked.

- [x] Add `disable-model-invocation: true` to `setup.md` frontmatter

**5c. Update component counts**

After changes: 29 agents, 24 commands (25 - 1 deleted technical_review), 18 skills, 1 MCP.

Wait — with setup.md added and technical_review.md deleted: 25 - 1 = 24. Same as main. Verify actual count after changes.

- [x] Update `plugin.json` description with correct counts
- [x] Update `marketplace.json` description with correct counts
- [x] Update `README.md` component counts table

**5d. Update CHANGELOG.md**

- [x] Add entry for v2.32.0 documenting: settings support, schema-drift-detector wired in, technical_review removed

## Acceptance Criteria

- [ ] `setup.md` is under 80 lines
- [ ] `setup.md` has `disable-model-invocation: true`
- [ ] Running `/compound-engineering-setup` creates `.claude/compound-engineering.local.md` with correct defaults
- [ ] Running `/compound-engineering-setup` when config exists shows current config and asks before overwriting
- [ ] `/workflows:review` reads agents from `.local.md` when present
- [ ] `/workflows:review` falls back to auto-detected defaults when no config
- [ ] `/workflows:review` runs `schema-drift-detector` for PRs with migrations or schema.rb
- [ ] `/workflows:work` reads agents from `.local.md` when present
- [ ] `compound.md` unchanged except for a reference to the setup command
- [ ] `technical_review.md` deleted
- [ ] No JSON config files — only `.local.md`
- [ ] Config file is optional — everything works without it
- [ ] Conditional agents (migrations, frontend, architecture, data) remain hardcoded in review.md
- [ ] Component counts match across plugin.json, marketplace.json, and README.md

## What We're NOT Doing

- No multi-step wizard (users edit the file directly)
- No custom agent discovery (users add agent names to the YAML list)
- No `conditionalAgents` config (stays hardcoded by file pattern)
- No `options` object (agentNative, parallelReviews — not needed)
- No global vs project distinction in the command (just check both paths)
- No config-loading boilerplate duplicated across commands


================================================
FILE: docs/plans/2026-02-08-refactor-reduce-plugin-context-token-usage-plan.md
================================================
---
title: Reduce compound-engineering plugin context token usage
type: refactor
date: 2026-02-08
---

# Reduce compound-engineering Plugin Context Token Usage

## Overview

The compound-engineering plugin is **overflowing the default context budget by ~3x**, causing Claude Code to silently drop components. The plugin consumes ~50,500 characters in always-loaded descriptions against a default budget of 16,000 characters (2% of context window). This means Claude literally doesn't know some agents/skills exist during sessions.

## Problem Statement

### How Context Loading Works

Claude Code uses progressive disclosure for plugin content:

| Level | What Loads | When |
|-------|-----------|------|
| **Always in context** | `description` frontmatter from skills, commands, and agents | Session startup (unless `disable-model-invocation: true`) |
| **On invocation** | Full SKILL.md / command body / agent body | When triggered |
| **On demand** | Reference files in skill directories | When Claude reads them |

The total budget for ALL descriptions combined is **2% of context window** (~16,000 chars fallback). When exceeded, components are **silently excluded**.

### Current State: 316% of Budget

| Component | Count | Always-Loaded Chars | % of 16K Budget |
|-----------|------:|--------------------:|----------------:|
| Agent descriptions | 29 | ~41,400 | 259% |
| Skill descriptions | 16 | ~5,450 | 34% |
| Command descriptions | 24 | ~3,700 | 23% |
| **Total** | **69** | **~50,500** | **316%** |

### Root Cause: Bloated Agent Descriptions

Agent `description` fields contain full `<example>` blocks with user/assistant dialog. These examples belong in the agent body (system prompt), not the description. The description's only job is **discovery** — helping Claude decide whether to delegate.

Examples of the problem:

- `design-iterator.md`: 2,488 chars in description (should be ~200)
- `spec-flow-analyzer.md`: 2,289 chars in description
- `security-sentinel.md`: 1,986 chars in description
- `kieran-rails-reviewer.md`: 1,822 chars in description
- Average agent description: ~1,400 chars (should be 100-250)

Compare to Anthropic's official examples at 100-200 chars:

```yaml
# Official (140 chars)
description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code.

# Current plugin (1,822 chars)
description: "Use this agent when you need to review Rails code changes with an extremely high quality bar...\n\nExamples:\n- <example>\n  Context: The user has just implemented..."
```

### Secondary Cause: No `disable-model-invocation` on Manual Commands

Zero commands set `disable-model-invocation: true`. Commands like `/deploy-docs`, `/lfg`, `/slfg`, `/triage`, `/feature-video`, `/test-browser`, `/xcode-test` are manual workflows with side effects. Their descriptions consume budget unnecessarily.

The official docs explicitly state:
> Use `disable-model-invocation: true` for workflows with side effects: `/deploy`, `/commit`, `/triage-prs`. You don't want Claude deciding to deploy because your code looks ready.

---

## Proposed Solution

Three changes, ordered by impact:

### Phase 1: Trim Agent Descriptions (saves ~35,600 chars)

For all 29 agents: move `<example>` blocks from the `description` field into the agent body markdown. Keep descriptions to 1-2 sentences (100-250 chars).

**Before** (agent frontmatter):
```yaml
---
name: kieran-rails-reviewer
description: "Use this agent when you need to review Rails code changes with an extremely high quality bar. This agent should be invoked after implementing features, modifying existing code, or creating new Rails components. The agent applies Kieran's strict Rails conventions and taste preferences to ensure code meets exceptional standards.\n\nExamples:\n- <example>\n  Context: The user has just implemented a new controller action with turbo streams.\n  user: \"I've added a new update action to the posts controller\"\n  ..."
---

Detailed system prompt...
```

**After** (agent frontmatter):
```yaml
---
name: kieran-rails-reviewer
description: Review Rails code with Kieran's strict conventions. Use after implementing features, modifying code, or creating new Rails components.
---

<examples>
<example>
Context: The user has just implemented a new controller action with turbo streams.
user: "I've added a new update action to the posts controller"
...
</example>
</examples>

Detailed system prompt...
```

The examples move into the body (which only loads when the agent is actually invoked).

**Impact:** ~41,400 chars → ~5,800 chars (86% reduction)

### Phase 2: Add `disable-model-invocation: true` to Manual Commands (saves ~3,100 chars)

Commands that should only run when explicitly invoked by the user:

| Command | Reason |
|---------|--------|
| `/deploy-docs` | Side effect: deploys |
| `/release-docs` | Side effect: regenerates docs |
| `/changelog` | Side effect: generates changelog |
| `/lfg` | Side effect: autonomous workflow |
| `/slfg` | Side effect: swarm workflow |
| `/triage` | Side effect: categorizes findings |
| `/resolve_parallel` | Side effect: resolves TODOs |
| `/resolve_todo_parallel` | Side effect: resolves todos |
| `/resolve_pr_parallel` | Side effect: resolves PR comments |
| `/feature-video` | Side effect: records video |
| `/test-browser` | Side effect: runs browser tests |
| `/xcode-test` | Side effect: builds/tests iOS |
| `/reproduce-bug` | Side effect: runs reproduction |
| `/report-bug` | Side effect: creates bug report |
| `/agent-native-audit` | Side effect: runs audit |
| `/heal-skill` | Side effect: modifies skill files |
| `/generate_command` | Side effect: creates files |
| `/create-agent-skill` | Side effect: creates files |

Keep these **without** the flag (Claude should know about them):
- `/workflows:plan` — Claude might suggest planning
- `/workflows:work` — Claude might suggest starting work
- `/workflows:review` — Claude might suggest review
- `/workflows:brainstorm` — Claude might suggest brainstorming
- `/workflows:compound` — Claude might suggest documenting
- `/deepen-plan` — Claude might suggest deepening a plan

**Impact:** ~3,700 chars → ~600 chars for commands in context

### Phase 3: Add `disable-model-invocation: true` to Manual Skills (saves ~1,000 chars)

Skills that are manual workflows:

| Skill | Reason |
|-------|--------|
| `skill-creator` | Only invoked manually |
| `orchestrating-swarms` | Only invoked manually |
| `git-worktree` | Only invoked manually |
| `resolve-pr-parallel` | Side effect |
| `compound-docs` | Only invoked manually |
| `file-todos` | Only invoked manually |

Keep without the flag (Claude should auto-invoke):
- `dhh-rails-style` — Claude should use when writing Rails code
- `frontend-design` — Claude should use when building UI
- `brainstorming` — Claude should suggest before implementation
- `agent-browser` — Claude should use for browser tasks
- `gemini-imagegen` — Claude should use for image generation
- `create-agent-skills` — Claude should use when creating skills
- `every-style-editor` — Claude should use for editing
- `dspy-ruby` — Claude should use for DSPy.rb
- `agent-native-architecture` — Claude should use for agent-native design
- `andrew-kane-gem-writer` — Claude should use for gem writing
- `rclone` — Claude should use for cloud uploads
- `document-review` — Claude should use for doc review

**Impact:** ~5,450 chars → ~4,000 chars for skills in context

---

## Projected Result

| Component | Before (chars) | After (chars) | Reduction |
|-----------|---------------:|-------------:|-----------:|
| Agent descriptions | ~41,400 | ~5,800 | -86% |
| Command descriptions | ~3,700 | ~600 | -84% |
| Skill descriptions | ~5,450 | ~4,000 | -27% |
| **Total** | **~50,500** | **~10,400** | **-79%** |
| **% of 16K budget** | **316%** | **65%** | -- |

From 316% of budget (components silently dropped) to 65% of budget (room for growth).

---

## Acceptance Criteria

- [x] All 29 agent description fields are under 250 characters
- [x] All `<example>` blocks moved from description to agent body
- [x] 18 manual commands have `disable-model-invocation: true`
- [x] 6 manual skills have `disable-model-invocation: true`
- [x] Total always-loaded description content is under 16,000 characters
- [ ] Run `/context` to verify no "excluded skills" warnings
- [x] All agents still function correctly (examples are in body, not lost)
- [x] All commands still invocable via `/command-name`
- [x] Update plugin version in plugin.json and marketplace.json
- [x] Update CHANGELOG.md

## Implementation Notes

- Agent examples should use `<examples><example>...</example></examples>` tags in the body — Claude understands these natively
- Description format: "[What it does]. Use [when/trigger condition]." — two sentences max
- The `lint` agent at 115 words shows compact agents work great
- Test with `claude --plugin-dir ./plugins/compound-engineering` after changes
- The `SLASH_COMMAND_TOOL_CHAR_BUDGET` env var can override the default budget for testing

## References

- [Skills docs](https://code.claude.com/docs/en/skills) — "Skill descriptions are loaded into context... If you have many skills, they may exceed the character budget"
- [Subagents docs](https://code.claude.com/docs/en/sub-agents) — description field used for automatic delegation
- [Skills troubleshooting](https://code.claude.com/docs/en/skills#claude-doesnt-see-all-my-skills) — "The budget scales dynamically at 2% of the context window, with a fallback of 16,000 characters"


================================================
FILE: docs/plans/2026-02-09-refactor-dspy-ruby-skill-update-plan.md
================================================
---
title: "refactor: Update dspy-ruby skill to DSPy.rb v0.34.3 API"
type: refactor
date: 2026-02-09
---

# Update dspy-ruby Skill to DSPy.rb v0.34.3 API

## Problem

The `dspy-ruby` skill uses outdated API patterns (`.forward()`, `result[:field]`, inline `T.enum([...])`, `DSPy::Tool`) and is missing 10+ features (events, lifecycle callbacks, GEPA, evaluation framework, BAML/TOON, storage, etc.).

## Solution

Use the engineering skill as base (already has correct API), enhance with official docs content, rewrite all reference files and templates.

### Source Priority (when conflicts arise)

1. **Official docs** (`../dspy.rb/docs/src/`) — source of truth for API correctness
2. **Engineering skill** (`../engineering/.../dspy-rb/SKILL.md`) — source of truth for structure/style
3. **NavigationContext brainstorm** — for Typed Context pattern only

## Files to Update

### Core (SKILL.md)

1. **`skills/dspy-ruby/SKILL.md`** — Copy from engineering base, then:
   - Fix frontmatter: `name: dspy-rb` → `name: dspy-ruby`, keep long description format
   - Add sections before "Guidelines for Claude": Events System, Lifecycle Callbacks, Fiber-Local LM Context, Evaluation Framework, GEPA Optimization, Typed Context Pattern, Schema Formats (BAML/TOON)
   - Update Resources section with 5 references + 3 assets using markdown links
   - Fix any backtick references to markdown link format

### References (rewrite from themed doc batches)

2. **`references/core-concepts.md`** — Rewrite
   - Source: `core-concepts/signatures.md`, `modules.md`, `predictors.md`, `advanced/complex-types.md`
   - Cover: signatures (Date/Time types, T::Enum, defaults, field descriptions, BAML/TOON, recursive types), modules (.call() API, lifecycle callbacks, instruction update contract), predictors (all 4 types, concurrent predictions), type system (discriminators, union types)

3. **`references/toolsets.md`** — NEW
   - Source: `core-concepts/toolsets.md`, `toolsets-guide.md`
   - Cover: Tools::Base, Tools::Toolset DSL, type safety with Sorbet sigs, schema generation, built-in toolsets, testing

4. **`references/providers.md`** — Rewrite
   - Source: `llms.txt.erb`, engineering SKILL.md, `core-concepts/module-runtime-context.md`
   - Cover: per-provider adapters, RubyLLM unified adapter, Rails initializer, fiber-local LM context (`DSPy.with_lm`), feature-flagged model selection, compatibility matrix

5. **`references/optimization.md`** — Rewrite
   - Source: `optimization/miprov2.md`, `gepa.md`, `evaluation.md`, `production/storage.md`
   - Cover: MIPROv2 (dspy-miprov2 gem, AutoMode presets), GEPA (dspy-gepa gem, feedback maps), Evaluation (DSPy::Evals, built-in metrics, DSPy::Example), Storage (ProgramStorage)

6. **`references/observability.md`** — NEW
   - Source: `production/observability.md`, `core-concepts/events.md`, `advanced/observability-interception.md`
   - Cover: event system (module-scoped + global), dspy-o11y gems, Langfuse (env vars), score reporting (DSPy.score()), observation types, DSPy::Context.with_span

### Assets (rewrite to current API)

7. **`assets/signature-template.rb`** — T::Enum classes, `description:` kwarg, Date/Time types, defaults, union types, `.call()` / `result.field` usage examples

8. **`assets/module-template.rb`** — `.call()` API, `result.field`, Tools::Base, lifecycle callbacks, `DSPy.with_lm`, `configure_predictor`

9. **`assets/config-template.rb`** — RubyLLM adapter, `structured_outputs: true`, `after_initialize` Rails pattern, dspy-o11y env vars, feature-flagged model selection

### Metadata

10. **`.claude-plugin/plugin.json`** — Version `2.31.0` → `2.31.1`

11. **`CHANGELOG.md`** — Add `[2.31.1] - 2026-02-09` entry under `### Changed`

## Verification

```bash
# No old API patterns
grep -n '\.forward(\|result\[:\|T\.enum(\[\|DSPy::Tool[^s]' plugins/compound-engineering/skills/dspy-ruby/SKILL.md

# No backtick references
grep -E '`(references|assets|scripts)/' plugins/compound-engineering/skills/dspy-ruby/SKILL.md

# Frontmatter correct
head -4 plugins/compound-engineering/skills/dspy-ruby/SKILL.md

# JSON valid
cat plugins/compound-engineering/.claude-plugin/plugin.json | jq .

# All files exist
ls plugins/compound-engineering/skills/dspy-ruby/{references,assets}/
```

## Success Criteria

- [x] All API patterns updated (`.call()`, `result.field`, `T::Enum`, `Tools::Base`)
- [x] New features covered: events, callbacks, fiber-local LM, GEPA, evals, BAML/TOON, storage, score API, RubyLLM, typed context
- [x] 5 reference files present (core-concepts, toolsets, providers, optimization, observability)
- [x] 3 asset templates updated to current API
- [x] YAML frontmatter: `name: dspy-ruby`, description has "what" and "when"
- [x] All reference links use `[file.md](./references/file.md)` format
- [x] Writing style: imperative form, no "you should"
- [x] Version bumped to `2.31.1`, CHANGELOG updated
- [x] Verification commands all pass

## Source Materials

- Engineering skill: `/Users/vicente/Workspaces/vicente.services/engineering/plugins/engineering-skills/skills/dspy-rb/SKILL.md`
- Official docs: `/Users/vicente/Workspaces/vicente.services/dspy.rb/docs/src/`
- NavigationContext brainstorm: `/Users/vicente/Workspaces/vicente.services/observo/observo-server/docs/brainstorms/2026-02-09-typed-navigation-context-brainstorm.md`


================================================
FILE: docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md
================================================
---
title: Add Cursor CLI as a Target Provider
type: feat
date: 2026-02-12
---

# Add Cursor CLI as a Target Provider

## Overview

Add `cursor` as a fourth target provider in the converter CLI, alongside `opencode`, `codex`, and `droid`. This enables `--to cursor` for both `convert` and `install` commands, converting Claude Code plugins into Cursor-compatible format.

Cursor CLI (`cursor-agent`) launched in August 2025 and supports rules (`.mdc`), commands (`.md`), skills (`SKILL.md` standard), and MCP servers (`.cursor/mcp.json`). The mapping from Claude Code is straightforward because Cursor adopted the open SKILL.md standard and has a similar command format.

## Component Mapping

| Claude Code | Cursor Equivalent | Notes |
|---|---|---|
| `agents/*.md` | `.cursor/rules/*.mdc` | Agents become "Agent Requested" rules (`alwaysApply: false`, `description` set) so the AI activates them on demand rather than flooding context |
| `commands/*.md` | `.cursor/commands/*.md` | Plain markdown files; Cursor commands have no frontmatter support -- description becomes a markdown heading |
| `skills/*/SKILL.md` | `.cursor/skills/*/SKILL.md` | **Identical standard** -- copy directly |
| MCP servers | `.cursor/mcp.json` | Same JSON structure (`mcpServers` key), compatible format |
| `hooks/` | No equivalent | Cursor has no hook system; emit `console.warn` and skip |
| `.claude/` paths | `.cursor/` paths | Content rewriting needed |

### Key Design Decisions

**1. Agents use `alwaysApply: false` (Agent Requested mode)**

With 29 agents, setting `alwaysApply: true` would flood every Cursor session's context. Instead, agents become "Agent Requested" rules: `alwaysApply: false` with a populated `description` field. Cursor's AI reads the description and activates the rule only when relevant -- matching how Claude Code agents are invoked on demand.

**2. Commands are plain markdown (no frontmatter)**

Cursor commands (`.cursor/commands/*.md`) are simple markdown files where the filename becomes the command name. Unlike Claude Code commands, they do not support YAML frontmatter. The converter emits the description as a leading markdown comment, then the command body.

**3. Flattened command names with deduplication**

Cursor uses flat command names (no namespaces). `workflows:plan` becomes `plan`. If two commands flatten to the same name, the `uniqueName()` pattern from the codex converter appends `-2`, `-3`, etc.

### Rules (`.mdc`) Frontmatter Format

```yaml
---
description: "What this rule does and when it applies"
globs: ""
alwaysApply: false
---
```

- `description` (string): Used by the AI to decide relevance -- maps from agent `description`
- `globs` (string): Comma-separated file patterns for auto-attachment -- leave empty for converted agents
- `alwaysApply` (boolean): Set `false` for Agent Requested mode

### MCP Servers (`.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "server-name": {
      "command": "npx",
      "args": ["-y", "package-name"],
      "env": { "KEY": "value" }
    }
  }
}
```

Supports both local (command-based) and remote (url-based) servers. Pass through `headers` for remote servers.

## Acceptance Criteria

- [x] `bun run src/index.ts convert --to cursor ./plugins/compound-engineering` produces valid Cursor config
- [x] Agents convert to `.cursor/rules/*.mdc` with `alwaysApply: false` and populated `description`
- [x] Commands convert to `.cursor/commands/*.md` as plain markdown (no frontmatter)
- [x] Flattened command names that collide are deduplicated (`plan`, `plan-2`, etc.)
- [x] Skills copied to `.cursor/skills/` (identical format)
- [x] MCP servers written to `.cursor/mcp.json` with backup of existing file
- [x] Content transformation rewrites `.claude/` and `~/.claude/` paths to `.cursor/` and `~/.cursor/`
- [x] `/workflows:plan` transformed to `/plan` (flat command names)
- [x] `Task agent-name(args)` transformed to natural-language skill reference
- [x] Plugins with hooks emit `console.warn` about unsupported hooks
- [x] Writer does not double-nest `.cursor/.cursor/` (follows droid writer pattern)
- [x] `model` and `allowedTools` fields silently dropped (no Cursor equivalent)
- [x] Converter and writer tests pass
- [x] Existing tests still pass (`bun test`)

## Implementation

### Phase 1: Types

**Create `src/types/cursor.ts`**

```typescript
export type CursorRule = {
  name: string
  content: string  // Full .mdc file with YAML frontmatter
}

export type CursorCommand = {
  name: string
  content: string  // Plain markdown (no frontmatter)
}

export type CursorSkillDir = {
  name: string
  sourceDir: string
}

export type CursorBundle = {
  rules: CursorRule[]
  commands: CursorCommand[]
  skillDirs: CursorSkillDir[]
  mcpServers?: Record<string, {
    command?: string
    args?: string[]
    env?: Record<string, string>
    url?: string
    headers?: Record<string, string>
  }>
}
```

### Phase 2: Converter

**Create `src/converters/claude-to-cursor.ts`**

Core functions:

1. **`convertClaudeToCursor(plugin, options)`** -- main entry point
   - Convert each agent to a `.mdc` rule via `convertAgentToRule()`
   - Convert each command (including `disable-model-invocation` ones) via `convertCommand()`
   - Pass skills through as directory references
   - Convert MCP servers to JSON-compatible object
   - Emit `console.warn` if `plugin.hooks` has entries

2. **`convertAgentToRule(agent, usedNames)`** -- agent -> `.mdc` rule
   - Frontmatter fields: `description` (from agent description), `globs: ""`, `alwaysApply: false`
   - Body: agent body with content transformations applied
   - Prepend capabilities section if present
   - Deduplicate names via `uniqueName()`
   - Silently drop `model` field (no Cursor equivalent)

3. **`convertCommand(command, usedNames)`** -- command -> plain `.md`
   - Flatten namespace: `workflows:plan` -> `plan`
   - Deduplicate flattened names via `uniqueName()`
   - Emit as plain markdown: description as `<!-- description -->` comment, then body
   - Include `argument-hint` as a `## Arguments` section if present
   - Body: apply `transformContentForCursor()` transformations
   - Silently drop `allowedTools` (no Cursor equivalent)

4. **`transformContentForCursor(body)`** -- content rewriting
   - `.claude/` -> `.cursor/` and `~/.claude/` -> `~/.cursor/`
   - `Task agent-name(args)` -> `Use the agent-name skill to: args` (same as codex)
   - `/workflows:command` -> `/command` (flatten slash commands)
   - `@agent-name` references -> `the agent-name rule` (use codex's suffix-matching pattern)
   - Skip file paths (containing `/`) and common non-command patterns

5. **`convertMcpServers(servers)`** -- MCP config
   - Map each `ClaudeMcpServer` entry to Cursor-compatible JSON
   - Pass through: `command`, `args`, `env`, `url`, `headers`
   - Drop `type` field (Cursor infers transport from `command` vs `url`)

### Phase 3: Writer

**Create `src/targets/cursor.ts`**

Output structure:

```
.cursor/
├── rules/
│   ├── agent-name-1.mdc
│   └── agent-name-2.mdc
├── commands/
│   ├── command-1.md
│   └── command-2.md
├── skills/
│   └── skill-name/
│       └── SKILL.md
└── mcp.json
```

Core function: `writeCursorBundle(outputRoot, bundle)`

- `resolveCursorPaths(outputRoot)` -- detect if path already ends in `.cursor` to avoid double-nesting (follow droid writer pattern at `src/targets/droid.ts:31-50`)
- Write rules to `rules/` as `.mdc` files
- Write commands to `commands/` as `.md` files
- Copy skill directories to `skills/` via `copyDir()`
- Write `mcp.json` via `writeJson()` with `backupFile()` for existing files

### Phase 4: Wire into CLI

**Modify `src/targets/index.ts`**

```typescript
import { convertClaudeToCursor } from "../converters/claude-to-cursor"
import { writeCursorBundle } from "./cursor"
import type { CursorBundle } from "../types/cursor"

// Add to targets:
cursor: {
  name: "cursor",
  implemented: true,
  convert: convertClaudeToCursor as TargetHandler<CursorBundle>["convert"],
  write: writeCursorBundle as TargetHandler<CursorBundle>["write"],
},
```

**Modify `src/commands/convert.ts`**

- Update `--to` description: `"Target format (opencode | codex | droid | cursor)"`
- Add to `resolveTargetOutputRoot`: `if (targetName === "cursor") return path.join(outputRoot, ".cursor")`

**Modify `src/commands/install.ts`**

- Same two changes as convert.ts

### Phase 5: Tests

**Create `tests/cursor-converter.test.ts`**

Test cases (use inline `ClaudePlugin` fixtures, following codex converter test pattern):

- Agent converts to rule with `.mdc` frontmatter (`alwaysApply: false`, `description` populated)
- Agent with empty description gets default description text
- Agent with capabilities prepended to body
- Agent `model` field silently dropped
- Agent with empty body gets default body text
- Command converts with flattened name (`workflows:plan` -> `plan`)
- Command name collision after flattening is deduplicated (`plan`, `plan-2`)
- Command with `disable-model-invocation` is still included
- Command `allowedTools` silently dropped
- Command with `argument-hint` gets Arguments section
- Skills pass through as directory references
- MCP servers convert to JSON config (local and remote)
- MCP `headers` pass through for remote servers
- Content transformation: `.claude/` paths -> `.cursor/`
- Content transformation: `~/.claude/` paths -> `~/.cursor/`
- Content transformation: `Task agent(args)` -> natural language
- Content transformation: slash commands flattened
- Hooks present -> `console.warn` emitted
- Plugin with zero agents produces empty rules array
- Plugin with only skills works correctly

**Create `tests/cursor-writer.test.ts`**

Test cases (use temp directories, following droid writer test pattern):

- Full bundle writes rules, commands, skills, mcp.json
- Rules written as `.mdc` files in `rules/` directory
- Commands written as `.md` files in `commands/` directory
- Skills copied to `skills/` directory
- MCP config written as valid JSON `mcp.json`
- Existing `mcp.json` is backed up before overwrite
- Output root already ending in `.cursor` does NOT double-nest
- Empty bundle (no rules, commands, skills, or MCP) produces no output

### Phase 6: Documentation

**Create `docs/specs/cursor.md`**

Document the Cursor CLI spec as a reference, following `docs/specs/codex.md` pattern:

- Rules format (`.mdc` with `description`, `globs`, `alwaysApply` frontmatter)
- Commands format (plain markdown, no frontmatter)
- Skills format (identical SKILL.md standard)
- MCP server configuration (`.cursor/mcp.json`)
- CLI permissions (`.cursor/cli.json` -- for reference, not converted)
- Config file locations (project-level vs global)

**Update `README.md`**

Add `cursor` to the supported targets in the CLI usage section.

## What We're NOT Doing

- Not converting hooks (Cursor has no hook system -- warn and skip)
- Not generating `.cursor/cli.json` permissions (user-specific, not plugin-scoped)
- Not creating `AGENTS.md` (Cursor reads it natively, but not part of plugin conversion)
- Not using `globs` field intelligently (would require analyzing agent content to guess file patterns)
- Not adding sync support (follow-up task)
- Not transforming content inside copied SKILL.md files (known limitation -- skills may reference `.claude/` paths internally)
- Not clearing old output before writing (matches existing target behavior -- re-runs accumulate)

## Complexity Assessment

This is a **medium change**. The converter architecture is well-established with three existing targets, so this is mostly pattern-following. The key novelties are:

1. The `.mdc` frontmatter format (different from all other targets)
2. Agents map to "rules" rather than a direct equivalent
3. Commands are plain markdown (no frontmatter) unlike other targets
4. Name deduplication needed for flattened command namespaces

Skills being identical across platforms simplifies things significantly. MCP config is nearly 1:1.

## References

- Cursor Rules: `.cursor/rules/*.mdc` with `description`, `globs`, `alwaysApply` frontmatter
- Cursor Commands: `.cursor/commands/*.md` (plain markdown, no frontmatter)
- Cursor Skills: `.cursor/skills/*/SKILL.md` (open standard, identical to Claude Code)
- Cursor MCP: `.cursor/mcp.json` with `mcpServers` key
- Cursor CLI: `cursor-agent` command (launched August 2025)
- Existing codex converter: `src/converters/claude-to-codex.ts` (has `uniqueName()` deduplication pattern)
- Existing droid writer: `src/targets/droid.ts` (has double-nesting guard pattern)
- Existing codex plan: `docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md`
- Target provider checklist: `AGENTS.md` section "Adding a New Target Provider"


================================================
FILE: docs/plans/2026-02-14-feat-add-copilot-converter-target-plan.md
================================================
---
title: "feat: Add GitHub Copilot converter target"
type: feat
date: 2026-02-14
status: complete
---

# feat: Add GitHub Copilot Converter Target

## Overview

Add GitHub Copilot as a converter target following the established `TargetHandler` pattern. This converts the compound-engineering Claude Code plugin into Copilot's native format: custom agents (`.agent.md`), agent skills (`SKILL.md`), and MCP server configuration JSON.

**Brainstorm:** `docs/brainstorms/2026-02-14-copilot-converter-target-brainstorm.md`

## Problem Statement

The CLI tool (`compound`) already supports converting Claude Code plugins to 5 target formats (OpenCode, Codex, Droid, Cursor, Pi). GitHub Copilot is a widely-used AI coding assistant that now supports custom agents, skills, and MCP servers — but there's no converter target for it.

## Proposed Solution

Follow the existing converter pattern exactly:

1. Define types (`src/types/copilot.ts`)
2. Implement converter (`src/converters/claude-to-copilot.ts`)
3. Implement writer (`src/targets/copilot.ts`)
4. Register target (`src/targets/index.ts`)
5. Add sync support (`src/sync/copilot.ts`, `src/commands/sync.ts`)
6. Write tests and documentation

### Component Mapping

| Claude Code | Copilot | Output Path |
|-------------|---------|-------------|
| Agents (`.md`) | Custom Agents (`.agent.md`) | `.github/agents/{name}.agent.md` |
| Commands (`.md`) | Agent Skills (`SKILL.md`) | `.github/skills/{name}/SKILL.md` |
| Skills (`SKILL.md`) | Agent Skills (`SKILL.md`) | `.github/skills/{name}/SKILL.md` |
| MCP Servers | Config JSON | `.github/copilot-mcp-config.json` |
| Hooks | Skipped | Warning to stderr |

## Technical Approach

### Phase 1: Types

**File:** `src/types/copilot.ts`

```typescript
export type CopilotAgent = {
  name: string
  content: string // Full .agent.md content with frontmatter
}

export type CopilotGeneratedSkill = {
  name: string
  content: string // SKILL.md content with frontmatter
}

export type CopilotSkillDir = {
  name: string
  sourceDir: string
}

export type CopilotMcpServer = {
  type: string
  command?: string
  args?: string[]
  url?: string
  tools: string[]
  env?: Record<string, string>
  headers?: Record<string, string>
}

export type CopilotBundle = {
  agents: CopilotAgent[]
  generatedSkills: CopilotGeneratedSkill[]
  skillDirs: CopilotSkillDir[]
  mcpConfig?: Record<string, CopilotMcpServer>
}
```

### Phase 2: Converter

**File:** `src/converters/claude-to-copilot.ts`

**Agent conversion:**
- Frontmatter: `description` (required, fallback to `"Converted from Claude agent {name}"`), `tools: ["*"]`, `infer: true`
- Pass through `model` if present
- Fold `capabilities` into body as `## Capabilities` section (same as Cursor)
- Use `formatFrontmatter()` utility
- Warn if body exceeds 30,000 characters (`.length`)

**Command → Skill conversion:**
- Convert to SKILL.md format with frontmatter: `name`, `description`
- Flatten namespaced names: `workflows:plan` → `plan`
- Drop `allowed-tools`, `model`, `disable-model-invocation` silently
- Include `argument-hint` as `## Arguments` section in body

**Skill pass-through:**
- Map to `CopilotSkillDir` as-is (same as Cursor)

**MCP server conversion:**
- Transform env var names: `API_KEY` → `COPILOT_MCP_API_KEY`
- Skip vars already prefixed with `COPILOT_MCP_`
- Add `type: "local"` for command-based servers, `type: "sse"` for URL-based
- Set `tools: ["*"]` for all servers

**Content transformation (`transformContentForCopilot`):**

| Pattern | Input | Output |
|---------|-------|--------|
| Task calls | `Task repo-research-analyst(desc)` | `Use the repo-research-analyst skill to: desc` |
| Slash commands | `/workflows:plan` | `/plan` |
| Path rewriting | `.claude/` | `.github/` |
| Home path rewriting | `~/.claude/` | `~/.copilot/` |
| Agent references | `@security-sentinel` | `the security-sentinel agent` |

**Hooks:** Warn to stderr if present, skip.

### Phase 3: Writer

**File:** `src/targets/copilot.ts`

**Path resolution:**
- If `outputRoot` basename is `.github`, write directly into it (avoid `.github/.github/` double-nesting)
- Otherwise, nest under `.github/`

**Write operations:**
- Agents → `.github/agents/{name}.agent.md` (note: `.agent.md` extension)
- Generated skills (from commands) → `.github/skills/{name}/SKILL.md`
- Skill dirs → `.github/skills/{name}/` (copy via `copyDir`)
- MCP config → `.github/copilot-mcp-config.json` (backup existing with `backupFile`)

### Phase 4: Target Registration

**File:** `src/targets/index.ts`

Add import and register:

```typescript
import { convertClaudeToCopilot } from "../converters/claude-to-copilot"
import { writeCopilotBundle } from "./copilot"

// In targets record:
copilot: {
  name: "copilot",
  implemented: true,
  convert: convertClaudeToCopilot as TargetHandler<CopilotBundle>["convert"],
  write: writeCopilotBundle as TargetHandler<CopilotBundle>["write"],
},
```

### Phase 5: Sync Support

**File:** `src/sync/copilot.ts`

Follow the Cursor sync pattern (`src/sync/cursor.ts`):
- Symlink skills to `.github/skills/` using `forceSymlink`
- Validate skill names with `isValidSkillName`
- Convert MCP servers with `COPILOT_MCP_` prefix transformation
- Merge MCP config into existing `.github/copilot-mcp-config.json`

**File:** `src/commands/sync.ts`

- Add `"copilot"` to `validTargets` array
- Add case in `resolveOutputRoot()`: `case "copilot": return path.join(process.cwd(), ".github")`
- Add import and switch case for `syncToCopilot`
- Update meta description to include "Copilot"

### Phase 6: Tests

**File:** `tests/copilot-converter.test.ts`

Test cases (following `tests/cursor-converter.test.ts` pattern):

```
describe("convertClaudeToCopilot")
  ✓ converts agents to .agent.md with Copilot frontmatter
  ✓ agent description is required, fallback generated if missing
  ✓ agent with empty body gets default body
  ✓ agent capabilities are prepended to body
  ✓ agent model field is passed through
  ✓ agent tools defaults to ["*"]
  ✓ agent infer defaults to true
  ✓ warns when agent body exceeds 30k characters
  ✓ converts commands to skills with SKILL.md format
  ✓ flattens namespaced command names
  ✓ command name collision after flattening is deduplicated
  ✓ command allowedTools is silently dropped
  ✓ command with argument-hint gets Arguments section
  ✓ passes through skill directories
  ✓ skill and generated skill name collision is deduplicated
  ✓ converts MCP servers with COPILOT_MCP_ prefix
  ✓ MCP env vars already prefixed are not double-prefixed
  ✓ MCP servers get type field (local vs sse)
  ✓ warns when hooks are present
  ✓ no warning when hooks are absent
  ✓ plugin with zero agents produces empty agents array
  ✓ plugin with only skills works

describe("transformContentForCopilot")
  ✓ rewrites .claude/ paths to .github/
  ✓ rewrites ~/.claude/ paths to ~/.copilot/
  ✓ transforms Task agent calls to skill references
  ✓ flattens slash commands
  ✓ transforms @agent references to agent references
```

**File:** `tests/copilot-writer.test.ts`

Test cases (following `tests/cursor-writer.test.ts` pattern):

```
describe("writeCopilotBundle")
  ✓ writes agents, generated skills, copied skills, and MCP config
  ✓ agents use .agent.md file extension
  ✓ writes directly into .github output root without double-nesting
  ✓ handles empty bundles gracefully
  ✓ writes multiple agents as separate .agent.md files
  ✓ backs up existing copilot-mcp-config.json before overwriting
  ✓ creates skill directories with SKILL.md
```

**File:** `tests/sync-copilot.test.ts`

Test cases (following `tests/sync-cursor.test.ts` pattern):

```
describe("syncToCopilot")
  ✓ symlinks skills to .github/skills/
  ✓ skips skills with invalid names
  ✓ merges MCP config with existing file
  ✓ transforms MCP env var names to COPILOT_MCP_ prefix
  ✓ writes MCP config with restricted permissions (0o600)
```

### Phase 7: Documentation

**File:** `docs/specs/copilot.md`

Follow `docs/specs/cursor.md` format:
- Last verified date
- Primary sources (GitHub Docs URLs)
- Config locations table
- Agents section (`.agent.md` format, frontmatter fields)
- Skills section (`SKILL.md` format)
- MCP section (config structure, env var prefix requirement)
- Character limits (30k agent body)

**File:** `README.md`

- Add "copilot" to the list of supported targets
- Add usage example: `compound convert --to copilot ./plugins/compound-engineering`
- Add sync example: `compound sync copilot`

## Acceptance Criteria

### Converter
- [x] Agents convert to `.agent.md` with `description`, `tools: ["*"]`, `infer: true`
- [x] Agent `model` passes through when present
- [x] Agent `capabilities` fold into body as `## Capabilities`
- [x] Missing description generates fallback
- [x] Empty body generates fallback
- [x] Body exceeding 30k chars triggers stderr warning
- [x] Commands convert to SKILL.md format
- [x] Command names flatten (`workflows:plan` → `plan`)
- [x] Name collisions deduplicated with `-2`, `-3` suffix
- [x] Command `allowed-tools` dropped silently
- [x] Skills pass through as `CopilotSkillDir`
- [x] MCP env vars prefixed with `COPILOT_MCP_`
- [x] Already-prefixed env vars not double-prefixed
- [x] MCP servers get `type` field (`local` or `sse`)
- [x] Hooks trigger warning, skip conversion
- [x] Content transformation: Task calls, slash commands, paths, @agent refs

### Writer
- [x] Agents written to `.github/agents/{name}.agent.md`
- [x] Generated skills written to `.github/skills/{name}/SKILL.md`
- [x] Skill dirs copied to `.github/skills/{name}/`
- [x] MCP config written to `.github/copilot-mcp-config.json`
- [x] Existing MCP config backed up before overwrite
- [x] No double-nesting when outputRoot is `.github`
- [x] Empty bundles handled gracefully

### CLI Integration
- [x] `compound convert --to copilot` works
- [x] `compound sync copilot` works
- [x] Copilot registered in `src/targets/index.ts`
- [x] Sync resolves output to `.github/` in current directory

### Tests
- [x] `tests/copilot-converter.test.ts` — all converter tests pass
- [x] `tests/copilot-writer.test.ts` — all writer tests pass
- [x] `tests/sync-copilot.test.ts` — all sync tests pass

### Documentation
- [x] `docs/specs/copilot.md` — format specification
- [x] `README.md` — updated with copilot target

## Files to Create

| File | Purpose |
|------|---------|
| `src/types/copilot.ts` | Type definitions |
| `src/converters/claude-to-copilot.ts` | Converter logic |
| `src/targets/copilot.ts` | Writer logic |
| `src/sync/copilot.ts` | Sync handler |
| `tests/copilot-converter.test.ts` | Converter tests |
| `tests/copilot-writer.test.ts` | Writer tests |
| `tests/sync-copilot.test.ts` | Sync tests |
| `docs/specs/copilot.md` | Format specification |

## Files to Modify

| File | Change |
|------|--------|
| `src/targets/index.ts` | Register copilot target |
| `src/commands/sync.ts` | Add copilot to valid targets, output root, switch case |
| `README.md` | Add copilot to supported targets |

## References

- [Custom agents configuration - GitHub Docs](https://docs.github.com/en/copilot/reference/custom-agents-configuration)
- [About Agent Skills - GitHub Docs](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills)
- [MCP and coding agent - GitHub Docs](https://docs.github.com/en/copilot/concepts/agents/coding-agent/mcp-and-coding-agent)
- Existing converter: `src/converters/claude-to-cursor.ts`
- Existing writer: `src/targets/cursor.ts`
- Existing sync: `src/sync/cursor.ts`
- Existing tests: `tests/cursor-converter.test.ts`, `tests/cursor-writer.test.ts`


================================================
FILE: docs/plans/2026-02-14-feat-add-gemini-cli-target-provider-plan.md
================================================
---
title: Add Gemini CLI as a Target Provider
type: feat
status: completed
completed_date: 2026-02-14
completed_by: "Claude Opus 4.6"
actual_effort: "Completed in one session"
date: 2026-02-14
---

# Add Gemini CLI as a Target Provider

## Overview

Add `gemini` as a sixth target provider in the converter CLI, alongside `opencode`, `codex`, `droid`, `cursor`, and `pi`. This enables `--to gemini` for both `convert` and `install` commands, converting Claude Code plugins into Gemini CLI-compatible format.

Gemini CLI ([google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli)) is Google's open-source AI agent for the terminal. It supports GEMINI.md context files, custom commands (TOML format), agent skills (SKILL.md standard), MCP servers, and extensions -- making it a strong conversion target with good coverage of Claude Code plugin concepts.

## Component Mapping

| Claude Code | Gemini Equivalent | Notes |
|---|---|---|
| `agents/*.md` | `.gemini/skills/*/SKILL.md` | Agents become skills -- Gemini activates them on demand via `activate_skill` tool based on description matching |
| `commands/*.md` | `.gemini/commands/*.toml` | TOML format with `prompt` and `description` fields; namespaced via directory structure |
| `skills/*/SKILL.md` | `.gemini/skills/*/SKILL.md` | **Identical standard** -- copy directly |
| MCP servers | `settings.json` `mcpServers` | Same MCP protocol; different config location (`settings.json` vs `.mcp.json`) |
| `hooks/` | `settings.json` hooks | Gemini has hooks (`BeforeTool`, `AfterTool`, `SessionStart`, etc.) but different format; emit `console.warn` and skip for now |
| `.claude/` paths | `.gemini/` paths | Content rewriting needed |

### Key Design Decisions

**1. Agents become skills (not GEMINI.md context)**

With 29 agents, dumping them into GEMINI.md would flood every session's context. Instead, agents convert to skills -- Gemini autonomously activates them based on the skill description when relevant. This matches how Claude Code agents are invoked on demand via the Task tool.

**2. Commands use TOML format with directory-based namespacing**

Gemini CLI commands are `.toml` files where the path determines the command name: `.gemini/commands/git/commit.toml` becomes `/git:commit`. This maps cleanly from Claude Code's colon-namespaced commands (`workflows:plan` -> `.gemini/commands/workflows/plan.toml`).

**3. Commands use `{{args}}` placeholder**

Gemini's TOML commands support `{{args}}` for argument injection, mapping from Claude Code's `argument-hint` field. Commands with `argument-hint` get `{{args}}` appended to the prompt.

**4. MCP servers go into project-level settings.json**

Gemini CLI reads MCP config from `.gemini/settings.json` under the `mcpServers` key. The format is compatible -- same `command`, `args`, `env` fields, plus Gemini-specific `cwd`, `timeout`, `trust`, `includeTools`, `excludeTools`.

**5. Skills pass through unchanged**

Gemini adopted the same SKILL.md standard (YAML frontmatter with `name` and `description`, markdown body). Skills copy directly.

### TOML Command Format

```toml
description = "Brief description of the command"
prompt = """
The prompt content that will be sent to Gemini.

User request: {{args}}
"""
```

- `description` (string): One-line description shown in `/help`
- `prompt` (string): The prompt sent to the model; supports `{{args}}`, `!{shell}`, `@{file}` placeholders

### Skill (SKILL.md) Format

```yaml
---
name: skill-name
description: When and how Gemini should use this skill
---

# Skill Title

Detailed instructions...
```

Identical to Claude Code's format. The `description` field is critical -- Gemini uses it to decide when to activate the skill.

### MCP Server Format (settings.json)

```json
{
  "mcpServers": {
    "server-name": {
      "command": "npx",
      "args": ["-y", "package-name"],
      "env": { "KEY": "value" }
    }
  }
}
```

## Acceptance Criteria

- [x] `bun run src/index.ts convert --to gemini ./plugins/compound-engineering` produces valid Gemini config
- [x] Agents convert to `.gemini/skills/*/SKILL.md` with populated `description` in frontmatter
- [x] Commands convert to `.gemini/commands/*.toml` with `prompt` and `description` fields
- [x] Namespaced commands create directory structure (`workflows:plan` -> `commands/workflows/plan.toml`)
- [x] Commands with `argument-hint` include `{{args}}` placeholder in prompt
- [x] Commands with `disable-model-invocation: true` are still included (TOML commands are prompts, not code)
- [x] Skills copied to `.gemini/skills/` (identical format)
- [x] MCP servers written to `.gemini/settings.json` under `mcpServers` key
- [x] Existing `.gemini/settings.json` is backed up before overwrite, and MCP config is merged (not clobbered)
- [x] Content transformation rewrites `.claude/` and `~/.claude/` paths to `.gemini/` and `~/.gemini/`
- [x] `/workflows:plan` transformed to `/workflows:plan` (Gemini preserves colon namespacing via directories)
- [x] `Task agent-name(args)` transformed to `Use the agent-name skill to: args`
- [x] Plugins with hooks emit `console.warn` about format differences
- [x] Writer does not double-nest `.gemini/.gemini/`
- [x] `model` and `allowedTools` fields silently dropped (no Gemini equivalent in skills/commands)
- [x] Converter and writer tests pass
- [x] Existing tests still pass (`bun test`)

## Implementation

### Phase 1: Types

**Create `src/types/gemini.ts`**

```typescript
export type GeminiSkill = {
  name: string
  content: string // Full SKILL.md with YAML frontmatter
}

export type GeminiSkillDir = {
  name: string
  sourceDir: string
}

export type GeminiCommand = {
  name: string       // e.g. "plan" or "workflows/plan"
  content: string    // Full TOML content
}

export type GeminiBundle = {
  generatedSkills: GeminiSkill[]     // From agents
  skillDirs: GeminiSkillDir[]         // From skills (pass-through)
  commands: GeminiCommand[]
  mcpServers?: Record<string, {
    command?: string
    args?: string[]
    env?: Record<string, string>
    url?: string
    headers?: Record<string, string>
  }>
}
```

### Phase 2: Converter

**Create `src/converters/claude-to-gemini.ts`**

Core functions:

1. **`convertClaudeToGemini(plugin, options)`** -- main entry point
   - Convert each agent to a skill via `convertAgentToSkill()`
   - Convert each command via `convertCommand()`
   - Pass skills through as directory references
   - Convert MCP servers to settings-compatible object
   - Emit `console.warn` if `plugin.hooks` has entries

2. **`convertAgentToSkill(agent)`** -- agent -> SKILL.md
   - Frontmatter: `name` (from agent name), `description` (from agent description, max ~300 chars)
   - Body: agent body with content transformations applied
   - Prepend capabilities section if present
   - Silently drop `model` field (no Gemini equivalent)
   - If description is empty, generate from agent name: `"Use this skill for ${agent.name} tasks"`

3. **`convertCommand(command, usedNames)`** -- command -> TOML file
   - Preserve namespace structure: `workflows:plan` -> path `workflows/plan`
   - `description` field from command description
   - `prompt` field from command body with content transformations
   - If command has `argument-hint`, append `\n\nUser request: {{args}}` to prompt
   - Body: apply `transformContentForGemini()` transformations
   - Silently drop `allowedTools` (no Gemini equivalent)

4. **`transformContentForGemini(body)`** -- content rewriting
   - `.claude/` -> `.gemini/` and `~/.claude/` -> `~/.gemini/`
   - `Task agent-name(args)` -> `Use the agent-name skill to: args`
   - `@agent-name` references -> `the agent-name skill`
   - Skip file paths (containing `/`) and common non-command patterns

5. **`convertMcpServers(servers)`** -- MCP config
   - Map each `ClaudeMcpServer` entry to Gemini-compatible JSON
   - Pass through: `command`, `args`, `env`, `url`, `headers`
   - Drop `type` field (Gemini infers transport)

6. **`toToml(description, prompt)`** -- TOML serializer
   - Escape TOML strings properly
   - Use multi-line strings (`"""`) for prompt field
   - Simple string for description

### Phase 3: Writer

**Create `src/targets/gemini.ts`**

Output structure:

```
.gemini/
├── commands/
│   ├── plan.toml
│   └── workflows/
│       └── plan.toml
├── skills/
│   ├── agent-name-1/
│   │   └── SKILL.md
│   ├── agent-name-2/
│   │   └── SKILL.md
│   └── original-skill/
│       └── SKILL.md
└── settings.json          (only mcpServers key)
```

Core function: `writeGeminiBundle(outputRoot, bundle)`

- `resolveGeminiPaths(outputRoot)` -- detect if path already ends in `.gemini` to avoid double-nesting (follow droid writer pattern)
- Write generated skills to `skills/<name>/SKILL.md`
- Copy original skill directories to `skills/` via `copyDir()`
- Write commands to `commands/` as `.toml` files, creating subdirectories for namespaced commands
- Write `settings.json` with `{ "mcpServers": {...} }` via `writeJson()` with `backupFile()` for existing files
- If settings.json exists, read it first and merge `mcpServers` key (don't clobber other settings)

### Phase 4: Wire into CLI

**Modify `src/targets/index.ts`**

```typescript
import { convertClaudeToGemini } from "../converters/claude-to-gemini"
import { writeGeminiBundle } from "./gemini"
import type { GeminiBundle } from "../types/gemini"

// Add to targets:
gemini: {
  name: "gemini",
  implemented: true,
  convert: convertClaudeToGemini as TargetHandler<GeminiBundle>["convert"],
  write: writeGeminiBundle as TargetHandler<GeminiBundle>["write"],
},
```

**Modify `src/commands/convert.ts`**

- Update `--to` description: `"Target format (opencode | codex | droid | cursor | pi | gemini)"`
- Add to `resolveTargetOutputRoot`: `if (targetName === "gemini") return path.join(outputRoot, ".gemini")`

**Modify `src/commands/install.ts`**

- Same two changes as convert.ts

### Phase 5: Tests

**Create `tests/gemini-converter.test.ts`**

Test cases (use inline `ClaudePlugin` fixtures, following existing converter test patterns):

- Agent converts to skill with SKILL.md frontmatter (`name` and `description` populated)
- Agent with empty description gets default description text
- Agent with capabilities prepended to body
- Agent `model` field silently dropped
- Agent with empty body gets default body text
- Command converts to TOML with `prompt` and `description` fields
- Namespaced command creates correct path (`workflows:plan` -> `workflows/plan`)
- Command with `disable-model-invocation` is still included
- Command `allowedTools` silently dropped
- Command with `argument-hint` gets `{{args}}` placeholder in prompt
- Skills pass through as directory references
- MCP servers convert to settings.json-compatible config
- Content transformation: `.claude/` paths -> `.gemini/`
- Content transformation: `~/.claude/` paths -> `~/.gemini/`
- Content transformation: `Task agent(args)` -> natural language skill reference
- Hooks present -> `console.warn` emitted
- Plugin with zero agents produces empty generatedSkills array
- Plugin with only skills works correctly
- TOML output is valid (description and prompt properly escaped)

**Create `tests/gemini-writer.test.ts`**

Test cases (use temp directories, following existing writer test patterns):

- Full bundle writes skills, commands, settings.json
- Generated skills written as `skills/<name>/SKILL.md`
- Original skills copied to `skills/` directory
- Commands written as `.toml` files in `commands/` directory
- Namespaced commands create subdirectories (`commands/workflows/plan.toml`)
- MCP config written as valid JSON `settings.json` with `mcpServers` key
- Existing `settings.json` is backed up before overwrite
- Output root already ending in `.gemini` does NOT double-nest
- Empty bundle produces no output

### Phase 6: Documentation

**Create `docs/specs/gemini.md`**

Document the Gemini CLI spec as reference, following existing `docs/specs/codex.md` pattern:

- GEMINI.md context file format
- Custom commands format (TOML with `prompt`, `description`)
- Skills format (identical SKILL.md standard)
- MCP server configuration (`settings.json`)
- Extensions system (for reference, not converted)
- Hooks system (for reference, format differences noted)
- Config file locations (user-level `~/.gemini/` vs project-level `.gemini/`)
- Directory layout conventions

**Update `README.md`**

Add `gemini` to the supported targets in the CLI usage section.

## What We're NOT Doing

- Not converting hooks (Gemini has hooks but different format -- `BeforeTool`/`AfterTool` with matchers -- warn and skip)
- Not generating full `settings.json` (only `mcpServers` key -- user-specific settings like `model`, `tools.sandbox` are out of scope)
- Not creating extensions (extension format is for distributing packages, not for converted plugins)
- Not using `@{file}` or `!{shell}` placeholders in converted commands (would require analyzing command intent)
- Not transforming content inside copied SKILL.md files (known limitation -- skills may reference `.claude/` paths internally)
- Not clearing old output before writing (matches existing target behavior)
- Not merging into existing settings.json intelligently beyond `mcpServers` key (too risky to modify user config)

## Complexity Assessment

This is a **medium change**. The converter architecture is well-established with five existing targets, so this is mostly pattern-following. The key novelties are:

1. The TOML command format (unique among all targets -- need simple TOML serializer)
2. Agents map to skills rather than a direct 1:1 concept (but this is the same pattern as codex)
3. Namespaced commands use directory structure (new approach vs flattening in cursor/codex)
4. MCP config goes into a broader `settings.json` file (need to merge, not clobber)

Skills being identical across platforms simplifies things significantly. The TOML serialization is simple (only two fields: `description` string and `prompt` multi-line string).

## References

- [Gemini CLI Repository](https://github.com/google-gemini/gemini-cli)
- [Gemini CLI Configuration](https://geminicli.com/docs/get-started/configuration/)
- [Custom Commands (TOML)](https://geminicli.com/docs/cli/custom-commands/)
- [Agent Skills](https://geminicli.com/docs/cli/skills/)
- [Creating Skills](https://geminicli.com/docs/cli/creating-skills/)
- [Extensions](https://geminicli.com/docs/extensions/writing-extensions/)
- [MCP Servers](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html)
- Existing cursor plan: `docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md`
- Existing codex converter: `src/converters/claude-to-codex.ts` (has `uniqueName()` and skill generation patterns)
- Existing droid writer: `src/targets/droid.ts` (has double-nesting guard pattern)
- Target registry: `src/targets/index.ts`

## Completion Summary

### What Was Delivered
- [x] Phase 1: Types (`src/types/gemini.ts`)
- [x] Phase 2: Converter (`src/converters/claude-to-gemini.ts`)
- [x] Phase 3: Writer (`src/targets/gemini.ts`)
- [x] Phase 4: CLI wiring (`src/targets/index.ts`, `src/commands/convert.ts`, `src/commands/install.ts`)
- [x] Phase 5: Tests (`tests/gemini-converter.test.ts`, `tests/gemini-writer.test.ts`)
- [x] Phase 6: Documentation (`docs/specs/gemini.md`, `README.md`)

### Implementation Statistics
- 10 files changed
- 27 new tests added (129 total, all passing)
- 148 output files generated from compound-engineering plugin conversion
- 0 dependencies added

### Git Commits
- `201ad6d` feat(gemini): add Gemini CLI as sixth target provider
- `8351851` docs: add Gemini CLI spec and update README with gemini target

### Completion Details
- **Completed By:** Claude Opus 4.6
- **Date:** 2026-02-14
- **Session:** Single session


================================================
FILE: docs/plans/2026-02-14-feat-auto-detect-install-and-gemini-sync-plan.md
================================================
---
title: Auto-detect install targets and add Gemini sync
type: feat
status: completed
date: 2026-02-14
completed_date: 2026-02-14
completed_by: "Claude Opus 4.6"
actual_effort: "Completed in one session"
---

# Auto-detect Install Targets and Add Gemini Sync

## Overview

Two related improvements to the converter CLI:

1. **`install --to all`** — Auto-detect which AI coding tools are installed and convert to all of them in one command
2. **`sync --target gemini`** — Add Gemini CLI as a sync target (currently missing), then add `sync --target all` to sync personal config to every detected tool

## Problem Statement

Users currently must run 6 separate commands to install to all targets:

```bash
bunx @every-env/compound-plugin install compound-engineering --to opencode
bunx @every-env/compound-plugin install compound-engineering --to codex
bunx @every-env/compound-plugin install compound-engineering --to droid
bunx @every-env/compound-plugin install compound-engineering --to cursor
bunx @every-env/compound-plugin install compound-engineering --to pi
bunx @every-env/compound-plugin install compound-engineering --to gemini
```

Similarly, sync requires separate commands per target. And Gemini sync doesn't exist yet.

## Acceptance Criteria

### Auto-detect install

- [x]`install --to all` detects installed tools and installs to each
- [x]Detection checks config directories and/or binaries for each tool
- [x]Prints which tools were detected and which were skipped
- [x]Tools with no detection signal are skipped (not errored)
- [x]`convert --to all` also works (same detection logic)
- [x]Existing `--to <target>` behavior unchanged
- [x]Tests for detection logic and `all` target handling

### Gemini sync

- [x]`sync --target gemini` symlinks skills and writes MCP servers to `.gemini/settings.json`
- [x]MCP servers merged into existing `settings.json` (same pattern as writer)
- [x]`gemini` added to `validTargets` in `sync.ts`
- [x]Tests for Gemini sync

### Sync all

- [x]`sync --target all` syncs to all detected tools
- [x]Reuses same detection logic as install
- [x]Prints summary of what was synced where

## Implementation

### Phase 1: Tool Detection Utility

**Create `src/utils/detect-tools.ts`**

```typescript
import os from "os"
import path from "path"
import { pathExists } from "./files"

export type DetectedTool = {
  name: string
  detected: boolean
  reason: string // e.g. "found ~/.codex/" or "not found"
}

export async function detectInstalledTools(): Promise<DetectedTool[]> {
  const home = os.homedir()
  const cwd = process.cwd()

  const checks: Array<{ name: string; paths: string[] }> = [
    { name: "opencode", paths: [path.join(home, ".config", "opencode"), path.join(cwd, ".opencode")] },
    { name: "codex", paths: [path.join(home, ".codex")] },
    { name: "droid", paths: [path.join(home, ".factory")] },
    { name: "cursor", paths: [path.join(cwd, ".cursor"), path.join(home, ".cursor")] },
    { name: "pi", paths: [path.join(home, ".pi")] },
    { name: "gemini", paths: [path.join(cwd, ".gemini"), path.join(home, ".gemini")] },
  ]

  const results: DetectedTool[] = []
  for (const check of checks) {
    let detected = false
    let reason = "not found"
    for (const p of check.paths) {
      if (await pathExists(p)) {
        detected = true
        reason = `found ${p}`
        break
      }
    }
    results.push({ name: check.name, detected, reason })
  }
  return results
}

export async function getDetectedTargetNames(): Promise<string[]> {
  const tools = await detectInstalledTools()
  return tools.filter((t) => t.detected).map((t) => t.name)
}
```

**Detection heuristics:**

| Tool | Check paths | Notes |
|------|------------|-------|
| OpenCode | `~/.config/opencode/`, `.opencode/` | XDG config or project-local |
| Codex | `~/.codex/` | Global only |
| Droid | `~/.factory/` | Global only |
| Cursor | `.cursor/`, `~/.cursor/` | Project-local or global |
| Pi | `~/.pi/` | Global only |
| Gemini | `.gemini/`, `~/.gemini/` | Project-local or global |

### Phase 2: Gemini Sync

**Create `src/sync/gemini.ts`**

Follow the Cursor sync pattern (`src/sync/cursor.ts`) since both use JSON config with `mcpServers` key:

```typescript
import path from "path"
import { symlinkSkills } from "../utils/symlink"
import { backupFile, pathExists, readJson, writeJson } from "../utils/files"
import type { ClaudeMcpServer } from "../types/claude"

export async function syncToGemini(
  skills: { name: string; sourceDir: string }[],
  mcpServers: Record<string, ClaudeMcpServer>,
  outputRoot: string,
): Promise<void> {
  const geminiDir = path.join(outputRoot, ".gemini")

  // Symlink skills
  if (skills.length > 0) {
    const skillsDir = path.join(geminiDir, "skills")
    await symlinkSkills(skills, skillsDir)
  }

  // Merge MCP servers into settings.json
  if (Object.keys(mcpServers).length > 0) {
    const settingsPath = path.join(geminiDir, "settings.json")
    let existing: Record<string, unknown> = {}
    if (await pathExists(settingsPath)) {
      await backupFile(settingsPath)
      try {
        existing = await readJson<Record<string, unknown>>(settingsPath)
      } catch {
        console.warn("Warning: existing settings.json could not be parsed and will be replaced.")
      }
    }

    const existingMcp = (existing.mcpServers && typeof existing.mcpServers === "object")
      ? existing.mcpServers as Record<string, unknown>
      : {}

    const merged = { ...existing, mcpServers: { ...existingMcp, ...convertMcpServers(mcpServers) } }
    await writeJson(settingsPath, merged)
  }
}

function convertMcpServers(servers: Record<string, ClaudeMcpServer>) {
  const result: Record<string, Record<string, unknown>> = {}
  for (const [name, server] of Object.entries(servers)) {
    const entry: Record<string, unknown> = {}
    if (server.command) {
      entry.command = server.command
      if (server.args?.length) entry.args = server.args
      if (server.env && Object.keys(server.env).length > 0) entry.env = server.env
    } else if (server.url) {
      entry.url = server.url
      if (server.headers && Object.keys(server.headers).length > 0) entry.headers = server.headers
    }
    result[name] = entry
  }
  return result
}
```

**Update `src/commands/sync.ts`:**

- Add `"gemini"` to `validTargets` array
- Import `syncToGemini` from `../sync/gemini`
- Add case in switch for `"gemini"` calling `syncToGemini(skills, mcpServers, outputRoot)`

### Phase 3: Wire `--to all` into Install and Convert

**Modify `src/commands/install.ts`:**

```typescript
import { detectInstalledTools } from "../utils/detect-tools"

// In args definition, update --to description:
to: {
  type: "string",
  default: "opencode",
  description: "Target format (opencode | codex | droid | cursor | pi | gemini | all)",
},

// In run(), before the existing target lookup:
if (targetName === "all") {
  const detected = await detectInstalledTools()
  const activeTargets = detected.filter((t) => t.detected)

  if (activeTargets.length === 0) {
    console.log("No AI coding tools detected. Install at least one tool first.")
    return
  }

  console.log(`Detected ${activeTargets.length} tools:`)
  for (const tool of detected) {
    console.log(`  ${tool.detected ? "✓" : "✗"} ${tool.name} — ${tool.reason}`)
  }

  // Install to each detected target
  for (const tool of activeTargets) {
    const handler = targets[tool.name]
    const bundle = handler.convert(plugin, options)
    if (!bundle) continue
    const root = resolveTargetOutputRoot(tool.name, outputRoot, codexHome, piHome, hasExplicitOutput)
    await handler.write(root, bundle)
    console.log(`Installed ${plugin.manifest.name} to ${tool.name} at ${root}`)
  }

  // Codex post-processing
  if (activeTargets.some((t) => t.name === "codex")) {
    await ensureCodexAgentsFile(codexHome)
  }
  return
}
```

**Same change in `src/commands/convert.ts`** with its version of `resolveTargetOutputRoot`.

### Phase 4: Wire `--target all` into Sync

**Modify `src/commands/sync.ts`:**

```typescript
import { detectInstalledTools } from "../utils/detect-tools"

// Update validTargets:
const validTargets = ["opencode", "codex", "pi", "droid", "cursor", "gemini", "all"] as const

// In run(), handle "all":
if (targetName === "all") {
  const detected = await detectInstalledTools()
  const activeTargets = detected.filter((t) => t.detected).map((t) => t.name)

  if (activeTargets.length === 0) {
    console.log("No AI coding tools detected.")
    return
  }

  console.log(`Syncing to ${activeTargets.length} detected tools...`)
  for (const name of activeTargets) {
    // call existing sync logic for each target
  }
  return
}
```

### Phase 5: Tests

**Create `tests/detect-tools.test.ts`**

- Test detection with mocked directories (create temp dirs, check detection)
- Test `getDetectedTargetNames` returns only detected tools
- Test empty detection returns empty array

**Create `tests/gemini-sync.test.ts`**

Follow `tests/sync-cursor.test.ts` pattern:

- Test skills are symlinked to `.gemini/skills/`
- Test MCP servers merged into `settings.json`
- Test existing `settings.json` is backed up
- Test empty skills/servers produce no output

**Update `tests/cli.test.ts`**

- Test `--to all` flag is accepted
- Test `sync --target all` is accepted
- Test `sync --target gemini` is accepted

### Phase 6: Documentation

**Update `README.md`:**

Add to install section:
```bash
# auto-detect installed tools and install to all
bunx @every-env/compound-plugin install compound-engineering --to all
```

Add to sync section:
```bash
# Sync to Gemini
bunx @every-env/compound-plugin sync --target gemini

# Sync to all detected tools
bunx @every-env/compound-plugin sync --target all
```

## What We're NOT Doing

- Not adding binary detection (`which cursor`, `which gemini`) — directory checks are sufficient and don't require shell execution
- Not adding interactive prompts ("Install to Cursor? y/n") — auto-detect is fire-and-forget
- Not adding `--exclude` flag for skipping specific targets — can use `--to X --also Y` for manual selection
- Not adding Gemini to the `sync` symlink watcher (no watcher exists for any target)

## Complexity Assessment

**Low-medium change.** All patterns are established:
- Detection utility is new but simple (pathExists checks)
- Gemini sync follows cursor sync pattern exactly
- `--to all` is plumbing — iterate detected tools through existing handlers
- No new dependencies needed

## References

- Cursor sync (reference pattern): `src/sync/cursor.ts`
- Gemini writer (merge pattern): `src/targets/gemini.ts`
- Install command: `src/commands/install.ts`
- Sync command: `src/commands/sync.ts`
- File utilities: `src/utils/files.ts`
- Symlink utilities: `src/utils/symlink.ts`

## Completion Summary

### What Was Delivered
- Tool detection utility (`src/utils/detect-tools.ts`) with `detectInstalledTools()` and `getDetectedTargetNames()`
- Gemini sync (`src/sync/gemini.ts`) following cursor sync pattern — symlinks skills, merges MCP servers into `settings.json`
- `install --to all` and `convert --to all` auto-detect and install to all detected tools
- `sync --target gemini` added to sync command
- `sync --target all` syncs to all detected tools with summary output
- 8 new tests across 2 test files (detect-tools + sync-gemini)

### Implementation Statistics
- 4 new files, 3 modified files
- 139 tests passing (8 new + 131 existing)
- No new dependencies

### Git Commits
- `e4d730d` feat: add detect-tools utility and Gemini sync with tests
- `bc655f7` feat: wire --to all into install/convert and --target all/gemini into sync
- `877e265` docs: add auto-detect and Gemini sync to README, bump to 0.8.0

### Completion Details
- **Completed By:** Claude Opus 4.6
- **Date:** 2026-02-14
- **Session:** Single session, TDD approach


================================================
FILE: docs/plans/2026-02-25-feat-windsurf-global-scope-support-plan.md
================================================
---
title: Windsurf Global Scope Support
type: feat
status: completed
date: 2026-02-25
deepened: 2026-02-25
prior: docs/plans/2026-02-23-feat-add-windsurf-target-provider-plan.md (removed — superseded)
---

# Windsurf Global Scope Support

## Post-Implementation Revisions (2026-02-26)

After auditing the implementation against `docs/specs/windsurf.md`, two significant changes were made:

1. **Agents → Skills (not Workflows)**: Claude agents map to Windsurf Skills (`skills/{name}/SKILL.md`), not Workflows. Skills are "complex multi-step tasks with supporting resources" — a better conceptual match for specialized expertise/personas. Workflows are "reusable step-by-step procedures" — a better match for Claude Commands (slash commands).

2. **Workflows are flat files**: Command workflows are written to `global_workflows/{name}.md` (global scope) or `workflows/{name}.md` (workspace scope). No subdirectories — the spec requires flat files.

3. **Content transforms updated**: `@agent-name` references are kept as-is (Windsurf skill invocation syntax). `/command` references produce `/{name}` (not `/commands/{name}`). `Task agent(args)` produces `Use the @agent-name skill: args`.

### Final Component Mapping (per spec)

| Claude Code | Windsurf | Output Path | Invocation |
|---|---|---|---|
| Agents (`.md`) | Skills | `skills/{name}/SKILL.md` | `@skill-name` or automatic |
| Commands (`.md`) | Workflows (flat) | `global_workflows/{name}.md` (global) / `workflows/{name}.md` (workspace) | `/{workflow-name}` |
| Skills (`SKILL.md`) | Skills (pass-through) | `skills/{name}/SKILL.md` | `@skill-name` |
| MCP servers | `mcp_config.json` | `mcp_config.json` | N/A |
| Hooks | Skipped with warning | N/A | N/A |
| CLAUDE.md | Skipped | N/A | N/A |

### Files Changed in Revision

- `src/types/windsurf.ts` — `agentWorkflows` → `agentSkills: WindsurfGeneratedSkill[]`
- `src/converters/claude-to-windsurf.ts` — `convertAgentToSkill()`, updated content transforms
- `src/targets/windsurf.ts` — Skills written as `skills/{name}/SKILL.md`, flat workflows
- Tests updated to match

---

## Enhancement Summary

**Deepened on:** 2026-02-25
**Research agents used:** architecture-strategist, kieran-typescript-reviewer, security-sentinel, code-simplicity-reviewer, pattern-recognition-specialist
**External research:** Windsurf MCP docs, Windsurf tutorial docs

### Key Improvements from Deepening
1. **HTTP/SSE servers should be INCLUDED** — Windsurf supports all 3 transport types (stdio, Streamable HTTP, SSE). Original plan incorrectly skipped them.
2. **File permissions: use `0o600`** — `mcp_config.json` contains secrets and must not be world-readable. Add secure write support.
3. **Extract `resolveTargetOutputRoot` to shared utility** — both commands duplicate this; adding scope makes it worse. Extract first.
4. **Bug fix: missing `result[name] = entry`** — all 5 review agents caught a copy-paste bug in the `buildMcpConfig` sample code.
5. **`hasPotentialSecrets` to shared utility** — currently in sync.ts, would be duplicated. Extract to `src/utils/secrets.ts`.
6. **Windsurf `mcp_config.json` is global-only** — per Windsurf docs, no per-project MCP config support. Workspace scope writes it for forward-compatibility but emit a warning.
7. **Windsurf supports `${env:VAR}` interpolation** — consider writing env var references instead of literal values for secrets.

### New Considerations Discovered
- Backup files accumulate with secrets and are never cleaned up — cap at 3 backups
- Workspace `mcp_config.json` could be committed to git — warn about `.gitignore`
- `WindsurfMcpServerEntry` type needs `serverUrl` field for HTTP/SSE servers
- Simplicity reviewer recommends handling scope as windsurf-specific in CLI rather than generic `TargetHandler` fields — but brainstorm explicitly chose "generic with windsurf as first adopter". **Decision: keep generic approach** per user's brainstorm decision, with JSDoc documenting the relationship between `defaultScope` and `supportedScopes`.

---

## Overview

Add a generic `--scope global|workspace` flag to the converter CLI with Windsurf as the first adopter. Global scope writes to `~/.codeium/windsurf/`, making workflows, skills, and MCP servers available across all projects. This also upgrades MCP handling from a human-readable setup doc (`mcp-setup.md`) to a proper machine-readable config (`mcp_config.json`), and removes AGENTS.md generation (the plugin's CLAUDE.md contains development-internal instructions, not user-facing content).

## Problem Statement / Motivation

The current Windsurf converter (v0.10.0) writes everything to project-level `.windsurf/`, requiring re-installation per project. Windsurf supports global paths for skills (`~/.codeium/windsurf/skills/`) and MCP config (`~/.codeium/windsurf/mcp_config.json`). Users should install once and get capabilities everywhere.

Additionally, the v0.10.0 MCP output was a markdown setup guide — not an actual integration. Windsurf reads `mcp_config.json` directly, so we should write to that file.

## Breaking Changes from v0.10.0

This is a **minor version bump** (v0.11.0) with intentional breaking changes to the experimental Windsurf target:

1. **Default output location changed** — `--to windsurf` now defaults to global scope (`~/.codeium/windsurf/`). Use `--scope workspace` for the old behavior.
2. **AGENTS.md no longer generated** — old files are left in place (not deleted).
3. **`mcp-setup.md` replaced by `mcp_config.json`** — proper machine-readable integration. Old files left in place.
4. **Env var secrets included with warning** — previously redacted, now included (required for the config file to work).
5. **`--output` semantics changed** — `--output` now specifies the direct target directory (not a parent where `.windsurf/` is created).

## Proposed Solution

### Phase 0: Extract Shared Utilities (prerequisite)

**Files:** `src/utils/resolve-output.ts` (new), `src/utils/secrets.ts` (new)

#### 0a. Extract `resolveTargetOutputRoot` to shared utility

Both `install.ts` and `convert.ts` have near-identical `resolveTargetOutputRoot` functions that are already diverging (`hasExplicitOutput` exists in install.ts but not convert.ts). Adding scope would make the duplication worse.

- [x] Create `src/utils/resolve-output.ts` with a unified function:

```typescript
import os from "os"
import path from "path"
import type { TargetScope } from "../targets"

export function resolveTargetOutputRoot(options: {
  targetName: string
  outputRoot: string
  codexHome: string
  piHome: string
  hasExplicitOutput: boolean
  scope?: TargetScope
}): string {
  const { targetName, outputRoot, codexHome, piHome, hasExplicitOutput, scope } = options
  if (targetName === "codex") return codexHome
  if (targetName === "pi") return piHome
  if (targetName === "droid") return path.join(os.homedir(), ".factory")
  if (targetName === "cursor") {
    const base = hasExplicitOutput ? outputRoot : process.cwd()
    return path.join(base, ".cursor")
  }
  if (targetName === "gemini") {
    const base = hasExplicitOutput ? outputRoot : process.cwd()
    return path.join(base, ".gemini")
  }
  if (targetName === "copilot") {
    const base = hasExplicitOutput ? outputRoot : process.cwd()
    return path.join(base, ".github")
  }
  if (targetName === "kiro") {
    const base = hasExplicitOutput ? outputRoot : process.cwd()
    return path.join(base, ".kiro")
  }
  if (targetName === "windsurf") {
    if (hasExplicitOutput) return outputRoot
    if (scope === "global") return path.join(os.homedir(), ".codeium", "windsurf")
    return path.join(process.cwd(), ".windsurf")
  }
  return outputRoot
}
```

- [x] Update `install.ts` to import and call `resolveTargetOutputRoot` from shared utility
- [x] Update `convert.ts` to import and call `resolveTargetOutputRoot` from shared utility
- [x] Add `hasExplicitOutput` tracking to `convert.ts` (currently missing)

### Research Insights (Phase 0)

**Architecture review:** Both commands will call the same function with the same signature. This eliminates the divergence and ensures scope resolution has a single source of truth. The `--also` loop in both commands also uses this function with `handler.defaultScope`.

**Pattern review:** This follows the same extraction pattern as `resolveTargetHome` in `src/utils/resolve-home.ts`.

#### 0b. Extract `hasPotentialSecrets` to shared utility

Currently in `sync.ts:20-31`. The same regex pattern also appears in `claude-to-windsurf.ts:223` as `redactEnvValue`. Extract to avoid a third copy.

- [x] Create `src/utils/secrets.ts`:

```typescript
const SENSITIVE_PATTERN = /key|token|secret|password|credential|api_key/i

export function hasPotentialSecrets(
  servers: Record<string, { env?: Record<string, string> }>,
): boolean {
  for (const server of Object.values(servers)) {
    if (server.env) {
      for (const key of Object.keys(server.env)) {
        if (SENSITIVE_PATTERN.test(key)) return true
      }
    }
  }
  return false
}
```

- [x] Update `sync.ts` to import from shared utility
- [x] Use in new windsurf converter

### Phase 1: Types and TargetHandler

**Files:** `src/types/windsurf.ts`, `src/targets/index.ts`

#### 1a. Update WindsurfBundle type

```typescript
// src/types/windsurf.ts
export type WindsurfMcpServerEntry = {
  command?: string
  args?: string[]
  env?: Record<string, string>
  serverUrl?: string
  headers?: Record<string, string>
}

export type WindsurfMcpConfig = {
  mcpServers: Record<string, WindsurfMcpServerEntry>
}

export type WindsurfBundle = {
  agentWorkflows: WindsurfWorkflow[]
  commandWorkflows: WindsurfWorkflow[]
  skillDirs: WindsurfSkillDir[]
  mcpConfig: WindsurfMcpConfig | null
}
```

- [x] Remove `agentsMd: string | null`
- [x] Replace `mcpSetupDoc: string | null` with `mcpConfig: WindsurfMcpConfig | null`
- [x] Add `WindsurfMcpServerEntry` (supports both stdio and HTTP/SSE) and `WindsurfMcpConfig` types

### Research Insights (Phase 1a)

**Windsurf docs confirm** three transport types: stdio (`command` + `args`), Streamable HTTP (`serverUrl`), and SSE (`serverUrl` or `url`). The `WindsurfMcpServerEntry` type must support all three — making `command` optional and adding `serverUrl` and `headers` fields.

**TypeScript reviewer:** Consider making `WindsurfMcpServerEntry` a discriminated union if strict typing is desired. However, since this mirrors JSON config structure, a flat type with optional fields is pragmatically simpler.

#### 1b. Add TargetScope to TargetHandler

```typescript
// src/targets/index.ts
export type TargetScope = "global" | "workspace"

export type TargetHandler<TBundle = unknown> = {
  name: string
  implemented: boolean
  /**
   * Default scope when --scope is not provided.
   * Only meaningful when supportedScopes is defined.
   * Falls back to "workspace" if absent.
   */
  defaultScope?: TargetScope
  /** Valid scope values. If absent, the --scope flag is rejected for this target. */
  supportedScopes?: TargetScope[]
  convert: (plugin: ClaudePlugin, options: ClaudeToOpenCodeOptions) => TBundle | null
  write: (outputRoot: string, bundle: TBundle) => Promise<void>
}
```

- [x] Add `TargetScope` type export
- [x] Add `defaultScope?` and `supportedScopes?` to `TargetHandler` with JSDoc
- [x] Set windsurf target: `defaultScope: "global"`, `supportedScopes: ["global", "workspace"]`
- [x] No changes to other targets (they have no scope fields, flag is ignored)

### Research Insights (Phase 1b)

**Simplicity review:** Argued this is premature generalization (only 1 of 8 targets uses scopes). Recommended handling scope as windsurf-specific with `if (targetName !== "windsurf")` guard instead. **Decision: keep generic approach** per brainstorm decision "Generic with windsurf as first adopter", but add JSDoc documenting the invariant.

**TypeScript review:** Suggested a `ScopeConfig` grouped object to prevent `defaultScope` without `supportedScopes`. The JSDoc approach is simpler and sufficient for now.

**Architecture review:** Adding optional fields to `TargetHandler` follows Open/Closed Principle — existing targets are unaffected. Clean extension.

### Phase 2: Converter Changes

**Files:** `src/converters/claude-to-windsurf.ts`

#### 2a. Remove AGENTS.md generation

- [x] Remove `buildAgentsMd()` function
- [x] Remove `agentsMd` from return value

#### 2b. Replace MCP setup doc with MCP config

- [x] Remove `buildMcpSetupDoc()` function
- [x] Remove `redactEnvValue()` helper
- [x] Add `buildMcpConfig()` that returns `WindsurfMcpConfig | null`
- [x] Include **all** env vars (including secrets) — no redaction
- [x] Use shared `hasPotentialSecrets()` from `src/utils/secrets.ts`
- [x] Include **both** stdio and HTTP/SSE servers (Windsurf supports all transport types)

```typescript
function buildMcpConfig(
  servers?: Record<string, ClaudeMcpServer>,
): WindsurfMcpConfig | null {
  if (!servers || Object.keys(servers).length === 0) return null

  const result: Record<string, WindsurfMcpServerEntry> = {}
  for (const [name, server] of Object.entries(servers)) {
    if (server.command) {
      // stdio transport
      const entry: WindsurfMcpServerEntry = { command: server.command }
      if (server.args?.length) entry.args = server.args
      if (server.env && Object.keys(server.env).length > 0) entry.env = server.env
      result[name] = entry
    } else if (server.url) {
      // HTTP/SSE transport
      const entry: WindsurfMcpServerEntry = { serverUrl: server.url }
      if (server.headers && Object.keys(server.headers).length > 0) entry.headers = server.headers
      if (server.env && Object.keys(server.env).length > 0) entry.env = server.env
      result[name] = entry
    } else {
      console.warn(`Warning: MCP server "${name}" has no command or URL. Skipping.`)
      continue
    }
  }

  if (Object.keys(result).length === 0) return null

  // Warn about secrets (don't redact — they're needed for the config to work)
  if (hasPotentialSecrets(result)) {
    console.warn(
      "Warning: MCP servers contain env vars that may include secrets (API keys, tokens).\n" +
      "   These will be written to mcp_config.json. Review before sharing the config file.",
    )
  }

  return { mcpServers: result }
}
```

### Research Insights (Phase 2)

**Windsurf docs (critical correction):** Windsurf supports **stdio, Streamable HTTP, and SSE** transports in `mcp_config.json`. HTTP/SSE servers use `serverUrl` (not `url`). The original plan incorrectly planned to skip HTTP/SSE servers. This is now corrected — all transport types are included.

**All 5 review agents flagged:** The original code sample was missing `result[name] = entry` — the entry was built but never stored. Fixed above.

**Security review:** The warning message should enumerate which specific env var names triggered detection. Enhanced version:

```typescript
if (hasPotentialSecrets(result)) {
  const flagged = Object.entries(result)
    .filter(([, s]) => s.env && Object.keys(s.env).some(k => SENSITIVE_PATTERN.test(k)))
    .map(([name]) => name)
  console.warn(
    `Warning: MCP servers contain env vars that may include secrets: ${flagged.join(", ")}.\n` +
    "   These will be written to mcp_config.json. Review before sharing the config file.",
  )
}
```

**Windsurf env var interpolation:** Windsurf supports `${env:VARIABLE_NAME}` syntax in `mcp_config.json`. Future enhancement: write env var references instead of literal values for secrets. Out of scope for v0.11.0 (requires more research on which fields support interpolation).

### Phase 3: Writer Changes

**Files:** `src/targets/windsurf.ts`, `src/utils/files.ts`

#### 3a. Simplify writer — remove AGENTS.md and double-nesting guard

The writer always writes directly into `outputRoot`. The CLI resolves the correct output root based on scope.

- [x] Remove AGENTS.md writing block (lines 10-17)
- [x] Remove `resolveWindsurfPaths()` — no longer needed
- [x] Write workflows, skills, and MCP config directly into `outputRoot`

### Research Insights (Phase 3a)

**Pattern review (dissent):** Every other writer (kiro, copilot, gemini, droid) has a `resolve*Paths()` function with a double-nesting guard. Removing it makes Windsurf the only target where the CLI fully owns nesting. This creates an inconsistency in the `write()` contract.

**Resolution:** Accept the divergence — Windsurf has genuinely different semantics (global vs workspace). Add a JSDoc comment on `TargetHandler.write()` documenting that some writers may apply additional nesting while the Windsurf writer expects the final resolved path. Long-term, other targets could migrate to this pattern in a separate refactor.

#### 3b. Replace MCP setup doc with JSON config merge

Follow Kiro pattern (`src/targets/kiro.ts:68-92`) with security hardening:

- [x] Read existing `mcp_config.json` if present
- [x] Backup before overwrite (`backupFile()`)
- [x] Parse existing JSON (warn and replace if corrupted; add `!Array.isArray()` guard)
- [x] Merge at `mcpServers` key: plugin entries overwrite same-name entries, user entries preserved
- [x] Preserve all other top-level keys in existing file
- [x] Write merged result with **restrictive permissions** (`0o600`)
- [x] Emit warning when writing to workspace scope (Windsurf `mcp_config.json` is global-only per docs)

```typescript
// MCP config merge with security hardening
if (bundle.mcpConfig) {
  const mcpPath = path.join(outputRoot, "mcp_config.json")
  const backupPath = await backupFile(mcpPath)
  if (backupPath) {
    console.log(`Backed up existing mcp_config.json to ${backupPath}`)
  }

  let existingConfig: Record<string, unknown> = {}
  if (await pathExists(mcpPath)) {
    try {
      const parsed = await readJson<unknown>(mcpPath)
      if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
        existingConfig = parsed as Record<string, unknown>
      }
    } catch {
      console.warn("Warning: existing mcp_config.json could not be parsed and will be replaced.")
    }
  }

  const existingServers =
    existingConfig.mcpServers &&
    typeof existingConfig.mcpServers === "object" &&
    !Array.isArray(existingConfig.mcpServers)
      ? (existingConfig.mcpServers as Record<string, unknown>)
      : {}
  const merged = { ...existingConfig, mcpServers: { ...existingServers, ...bundle.mcpConfig.mcpServers } }
  await writeJsonSecure(mcpPath, merged)  // 0o600 permissions
}
```

### Research Insights (Phase 3b)

**Security review (HIGH):** The current `writeJson()` in `src/utils/files.ts` uses default umask (`0o644`) — world-readable. The sync targets all use `{ mode: 0o600 }` for secret-containing files. The Windsurf writer (and Kiro writer) must do the same.

**Implementation:** Add a `writeJsonSecure()` helper or add a `mode` parameter to `writeJson()`:

```typescript
// src/utils/files.ts
export async function writeJsonSecure(filePath: string, data: unknown): Promise<void> {
  const content = JSON.stringify(data, null, 2)
  await ensureDir(path.dirname(filePath))
  await fs.writeFile(filePath, content + "\n", { encoding: "utf8", mode: 0o600 })
}
```

**Security review (MEDIUM):** Backup files inherit default permissions. Ensure `backupFile()` also sets `0o600` on the backup copy when the source may contain secrets.

**Security review (MEDIUM):** Workspace `mcp_config.json` could be committed to git. After writing to workspace scope, emit a warning:

```
Warning: .windsurf/mcp_config.json may contain secrets. Ensure it is in .gitignore.
```

**TypeScript review:** The `readJson<Record<string, unknown>>` assertion is unsafe — a valid JSON array or string passes parsing but fails the type. Added `!Array.isArray()` guard.

**TypeScript review:** The `bundle.mcpConfig` null check is sufficient — when non-null, `mcpServers` is guaranteed to have entries (the converter returns null for empty servers). Simplified from `bundle.mcpConfig && Object.keys(...)`.

**Windsurf docs (important):** `mcp_config.json` is a **global configuration only** — Windsurf has no per-project MCP config support. Writing it to `.windsurf/` in workspace scope may not be discovered by Windsurf. Emit a warning for workspace scope but still write the file for forward-compatibility.

#### 3c. Updated writer structure

```typescript
export async function writeWindsurfBundle(outputRoot: string, bundle: WindsurfBundle): Promise<void> {
  await ensureDir(outputRoot)

  // Write agent workflows
  if (bundle.agentWorkflows.length > 0) {
    const agentDir = path.join(outputRoot, "workflows", "agents")
    await ensureDir(agentDir)
    for (const workflow of bundle.agentWorkflows) {
      validatePathSafe(workflow.name, "agent workflow")
      const content = formatFrontmatter({ description: workflow.description }, `# ${workflow.name}\n\n${workflow.body}`)
      await writeText(path.join(agentDir, `${workflow.name}.md`), content + "\n")
    }
  }

  // Write command workflows
  if (bundle.commandWorkflows.length > 0) {
    const cmdDir = path.join(outputRoot, "workflows", "commands")
    a
Download .txt
gitextract_7sovbsfr/

├── .claude/
│   └── commands/
│       └── triage-prs.md
├── .claude-plugin/
│   └── marketplace.json
├── .cursor-plugin/
│   ├── CHANGELOG.md
│   └── marketplace.json
├── .github/
│   ├── .release-please-manifest.json
│   ├── release-please-config.json
│   └── workflows/
│       ├── ci.yml
│       ├── deploy-docs.yml
│       ├── release-pr.yml
│       └── release-preview.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── LICENSE
├── PRIVACY.md
├── README.md
├── SECURITY.md
├── docs/
│   ├── brainstorms/
│   │   ├── 2026-02-14-copilot-converter-target-brainstorm.md
│   │   ├── 2026-02-17-copilot-skill-naming-brainstorm.md
│   │   ├── 2026-03-14-ce-plan-rewrite-requirements.md
│   │   ├── 2026-03-15-ce-ideate-skill-requirements.md
│   │   ├── 2026-03-16-issue-grounded-ideation-requirements.md
│   │   ├── 2026-03-17-release-automation-requirements.md
│   │   └── 2026-03-18-auto-memory-integration-requirements.md
│   ├── plans/
│   │   ├── 2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md
│   │   ├── 2026-02-08-feat-pr-triage-and-merge-plan.md
│   │   ├── 2026-02-08-feat-simplify-plugin-settings-plan.md
│   │   ├── 2026-02-08-refactor-reduce-plugin-context-token-usage-plan.md
│   │   ├── 2026-02-09-refactor-dspy-ruby-skill-update-plan.md
│   │   ├── 2026-02-12-feat-add-cursor-cli-target-provider-plan.md
│   │   ├── 2026-02-14-feat-add-copilot-converter-target-plan.md
│   │   ├── 2026-02-14-feat-add-gemini-cli-target-provider-plan.md
│   │   ├── 2026-02-14-feat-auto-detect-install-and-gemini-sync-plan.md
│   │   ├── 2026-02-25-feat-windsurf-global-scope-support-plan.md
│   │   ├── 2026-03-01-feat-ce-command-aliases-backwards-compatible-deprecation-plan.md
│   │   ├── 2026-03-01-fix-setup-skill-non-claude-llm-fallback-plan.md
│   │   ├── 2026-03-03-feat-sync-claude-mcp-all-supported-providers-plan.md
│   │   ├── 2026-03-15-001-feat-ce-ideate-skill-plan.md
│   │   ├── 2026-03-16-001-feat-issue-grounded-ideation-plan.md
│   │   ├── 2026-03-17-001-feat-release-automation-migration-beta-plan.md
│   │   ├── 2026-03-18-001-feat-auto-memory-integration-beta-plan.md
│   │   └── feature_opencode-commands-as-md-and-config-merge.md
│   ├── solutions/
│   │   ├── adding-converter-target-providers.md
│   │   ├── codex-skill-prompt-entrypoints.md
│   │   ├── plugin-versioning-requirements.md
│   │   ├── skill-design/
│   │   │   ├── beta-skills-framework.md
│   │   │   ├── claude-permissions-optimizer-classification-fix.md
│   │   │   ├── compound-refresh-skill-improvements.md
│   │   │   └── script-first-skill-architecture.md
│   │   └── workflow/
│   │       └── manual-release-please-github-releases.md
│   └── specs/
│       ├── claude-code.md
│       ├── codex.md
│       ├── copilot.md
│       ├── cursor.md
│       ├── gemini.md
│       ├── kiro.md
│       ├── opencode.md
│       └── windsurf.md
├── package.json
├── plugins/
│   ├── coding-tutor/
│   │   ├── .claude-plugin/
│   │   │   └── plugin.json
│   │   ├── .cursor-plugin/
│   │   │   └── plugin.json
│   │   ├── README.md
│   │   ├── commands/
│   │   │   ├── quiz-me.md
│   │   │   ├── sync-tutorials.md
│   │   │   └── teach-me.md
│   │   └── skills/
│   │       └── coding-tutor/
│   │           ├── SKILL.md
│   │           └── scripts/
│   │               ├── create_tutorial.py
│   │               ├── index_tutorials.py
│   │               ├── quiz_priority.py
│   │               └── setup_tutorials.py
│   └── compound-engineering/
│       ├── .claude-plugin/
│       │   └── plugin.json
│       ├── .cursor-plugin/
│       │   └── plugin.json
│       ├── .mcp.json
│       ├── AGENTS.md
│       ├── CHANGELOG.md
│       ├── CLAUDE.md
│       ├── LICENSE
│       ├── README.md
│       ├── agents/
│       │   ├── design/
│       │   │   ├── design-implementation-reviewer.md
│       │   │   ├── design-iterator.md
│       │   │   └── figma-design-sync.md
│       │   ├── docs/
│       │   │   └── ankane-readme-writer.md
│       │   ├── research/
│       │   │   ├── best-practices-researcher.md
│       │   │   ├── framework-docs-researcher.md
│       │   │   ├── git-history-analyzer.md
│       │   │   ├── issue-intelligence-analyst.md
│       │   │   ├── learnings-researcher.md
│       │   │   └── repo-research-analyst.md
│       │   ├── review/
│       │   │   ├── agent-native-reviewer.md
│       │   │   ├── architecture-strategist.md
│       │   │   ├── code-simplicity-reviewer.md
│       │   │   ├── data-integrity-guardian.md
│       │   │   ├── data-migration-expert.md
│       │   │   ├── deployment-verification-agent.md
│       │   │   ├── dhh-rails-reviewer.md
│       │   │   ├── julik-frontend-races-reviewer.md
│       │   │   ├── kieran-python-reviewer.md
│       │   │   ├── kieran-rails-reviewer.md
│       │   │   ├── kieran-typescript-reviewer.md
│       │   │   ├── pattern-recognition-specialist.md
│       │   │   ├── performance-oracle.md
│       │   │   ├── schema-drift-detector.md
│       │   │   └── security-sentinel.md
│       │   └── workflow/
│       │       ├── bug-reproduction-validator.md
│       │       ├── lint.md
│       │       ├── pr-comment-resolver.md
│       │       └── spec-flow-analyzer.md
│       └── skills/
│           ├── agent-browser/
│           │   ├── SKILL.md
│           │   ├── references/
│           │   │   ├── authentication.md
│           │   │   ├── commands.md
│           │   │   ├── profiling.md
│           │   │   ├── proxy-support.md
│           │   │   ├── session-management.md
│           │   │   ├── snapshot-refs.md
│           │   │   └── video-recording.md
│           │   └── templates/
│           │       ├── authenticated-session.sh
│           │       ├── capture-workflow.sh
│           │       └── form-automation.sh
│           ├── agent-native-architecture/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── action-parity-discipline.md
│           │       ├── agent-execution-patterns.md
│           │       ├── agent-native-testing.md
│           │       ├── architecture-patterns.md
│           │       ├── dynamic-context-injection.md
│           │       ├── files-universal-interface.md
│           │       ├── from-primitives-to-domain-tools.md
│           │       ├── mcp-tool-design.md
│           │       ├── mobile-patterns.md
│           │       ├── product-implications.md
│           │       ├── refactoring-to-prompt-native.md
│           │       ├── self-modification.md
│           │       ├── shared-workspace-architecture.md
│           │       └── system-prompt-design.md
│           ├── agent-native-audit/
│           │   └── SKILL.md
│           ├── andrew-kane-gem-writer/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── database-adapters.md
│           │       ├── module-organization.md
│           │       ├── rails-integration.md
│           │       ├── resources.md
│           │       └── testing-patterns.md
│           ├── ce-brainstorm/
│           │   └── SKILL.md
│           ├── ce-compound/
│           │   └── SKILL.md
│           ├── ce-compound-refresh/
│           │   └── SKILL.md
│           ├── ce-ideate/
│           │   └── SKILL.md
│           ├── ce-plan/
│           │   └── SKILL.md
│           ├── ce-plan-beta/
│           │   └── SKILL.md
│           ├── ce-review/
│           │   └── SKILL.md
│           ├── ce-work/
│           │   └── SKILL.md
│           ├── changelog/
│           │   └── SKILL.md
│           ├── claude-permissions-optimizer/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── extract-commands.mjs
│           ├── compound-docs/
│           │   ├── SKILL.md
│           │   ├── assets/
│           │   │   ├── critical-pattern-template.md
│           │   │   └── resolution-template.md
│           │   ├── references/
│           │   │   └── yaml-schema.md
│           │   └── schema.yaml
│           ├── create-agent-skill/
│           │   └── SKILL.md
│           ├── create-agent-skills/
│           │   ├── SKILL.md
│           │   ├── references/
│           │   │   ├── api-security.md
│           │   │   ├── be-clear-and-direct.md
│           │   │   ├── best-practices.md
│           │   │   ├── common-patterns.md
│           │   │   ├── core-principles.md
│           │   │   ├── executable-code.md
│           │   │   ├── iteration-and-testing.md
│           │   │   ├── official-spec.md
│           │   │   ├── recommended-structure.md
│           │   │   ├── skill-structure.md
│           │   │   ├── using-scripts.md
│           │   │   ├── using-templates.md
│           │   │   └── workflows-and-validation.md
│           │   ├── templates/
│           │   │   ├── router-skill.md
│           │   │   └── simple-skill.md
│           │   └── workflows/
│           │       ├── add-reference.md
│           │       ├── add-script.md
│           │       ├── add-template.md
│           │       ├── add-workflow.md
│           │       ├── audit-skill.md
│           │       ├── create-domain-expertise-skill.md
│           │       ├── create-new-skill.md
│           │       ├── get-guidance.md
│           │       ├── upgrade-to-router.md
│           │       └── verify-skill.md
│           ├── deepen-plan/
│           │   └── SKILL.md
│           ├── deepen-plan-beta/
│           │   └── SKILL.md
│           ├── deploy-docs/
│           │   └── SKILL.md
│           ├── dhh-rails-style/
│           │   ├── SKILL.md
│           │   └── references/
│           │       ├── architecture.md
│           │       ├── controllers.md
│           │       ├── frontend.md
│           │       ├── gems.md
│           │       ├── models.md
│           │       └── testing.md
│           ├── document-review/
│           │   └── SKILL.md
│           ├── dspy-ruby/
│           │   ├── SKILL.md
│           │   ├── assets/
│           │   │   ├── config-template.rb
│           │   │   ├── module-template.rb
│           │   │   └── signature-template.rb
│           │   └── references/
│           │       ├── core-concepts.md
│           │       ├── observability.md
│           │       ├── optimization.md
│           │       ├── providers.md
│           │       └── toolsets.md
│           ├── every-style-editor/
│           │   ├── SKILL.md
│           │   └── references/
│           │       └── EVERY_WRITE_STYLE.md
│           ├── feature-video/
│           │   └── SKILL.md
│           ├── file-todos/
│           │   ├── SKILL.md
│           │   └── assets/
│           │       └── todo-template.md
│           ├── frontend-design/
│           │   └── SKILL.md
│           ├── gemini-imagegen/
│           │   ├── SKILL.md
│           │   ├── requirements.txt
│           │   └── scripts/
│           │       ├── compose_images.py
│           │       ├── edit_image.py
│           │       ├── gemini_images.py
│           │       ├── generate_image.py
│           │       └── multi_turn_chat.py
│           ├── generate_command/
│           │   └── SKILL.md
│           ├── git-worktree/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── worktree-manager.sh
│           ├── heal-skill/
│           │   └── SKILL.md
│           ├── lfg/
│           │   └── SKILL.md
│           ├── orchestrating-swarms/
│           │   └── SKILL.md
│           ├── proof/
│           │   └── SKILL.md
│           ├── rclone/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       └── check_setup.sh
│           ├── report-bug/
│           │   └── SKILL.md
│           ├── reproduce-bug/
│           │   └── SKILL.md
│           ├── resolve-pr-parallel/
│           │   ├── SKILL.md
│           │   └── scripts/
│           │       ├── get-pr-comments
│           │       └── resolve-pr-thread
│           ├── resolve-todo-parallel/
│           │   └── SKILL.md
│           ├── resolve_parallel/
│           │   └── SKILL.md
│           ├── setup/
│           │   └── SKILL.md
│           ├── slfg/
│           │   └── SKILL.md
│           ├── test-browser/
│           │   └── SKILL.md
│           ├── test-xcode/
│           │   └── SKILL.md
│           └── triage/
│               └── SKILL.md
├── scripts/
│   └── release/
│       ├── preview.ts
│       ├── sync-metadata.ts
│       └── validate.ts
├── src/
│   ├── commands/
│   │   ├── convert.ts
│   │   ├── install.ts
│   │   ├── list.ts
│   │   └── sync.ts
│   ├── converters/
│   │   ├── claude-to-codex.ts
│   │   ├── claude-to-copilot.ts
│   │   ├── claude-to-droid.ts
│   │   ├── claude-to-gemini.ts
│   │   ├── claude-to-kiro.ts
│   │   ├── claude-to-openclaw.ts
│   │   ├── claude-to-opencode.ts
│   │   ├── claude-to-pi.ts
│   │   ├── claude-to-qwen.ts
│   │   └── claude-to-windsurf.ts
│   ├── index.ts
│   ├── parsers/
│   │   ├── claude-home.ts
│   │   └── claude.ts
│   ├── release/
│   │   ├── components.ts
│   │   ├── config.ts
│   │   ├── metadata.ts
│   │   └── types.ts
│   ├── sync/
│   │   ├── codex.ts
│   │   ├── commands.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── json-config.ts
│   │   ├── kiro.ts
│   │   ├── mcp-transports.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   ├── registry.ts
│   │   ├── skills.ts
│   │   └── windsurf.ts
│   ├── targets/
│   │   ├── codex.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── index.ts
│   │   ├── kiro.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   └── windsurf.ts
│   ├── templates/
│   │   └── pi/
│   │       └── compat-extension.ts
│   ├── types/
│   │   ├── claude.ts
│   │   ├── codex.ts
│   │   ├── copilot.ts
│   │   ├── droid.ts
│   │   ├── gemini.ts
│   │   ├── kiro.ts
│   │   ├── openclaw.ts
│   │   ├── opencode.ts
│   │   ├── pi.ts
│   │   ├── qwen.ts
│   │   └── windsurf.ts
│   └── utils/
│       ├── codex-agents.ts
│       ├── codex-content.ts
│       ├── detect-tools.ts
│       ├── files.ts
│       ├── frontmatter.ts
│       ├── resolve-home.ts
│       ├── resolve-output.ts
│       ├── secrets.ts
│       └── symlink.ts
├── tests/
│   ├── claude-home.test.ts
│   ├── claude-parser.test.ts
│   ├── cli.test.ts
│   ├── codex-agents.test.ts
│   ├── codex-converter.test.ts
│   ├── codex-writer.test.ts
│   ├── converter.test.ts
│   ├── copilot-converter.test.ts
│   ├── copilot-writer.test.ts
│   ├── detect-tools.test.ts
│   ├── droid-converter.test.ts
│   ├── droid-writer.test.ts
│   ├── fixtures/
│   │   ├── custom-paths/
│   │   │   ├── .claude-plugin/
│   │   │   │   └── plugin.json
│   │   │   ├── agents/
│   │   │   │   └── default-agent.md
│   │   │   ├── commands/
│   │   │   │   └── default-command.md
│   │   │   ├── custom-agents/
│   │   │   │   └── custom-agent.md
│   │   │   ├── custom-commands/
│   │   │   │   └── custom-command.md
│   │   │   ├── custom-hooks/
│   │   │   │   └── hooks.json
│   │   │   ├── custom-skills/
│   │   │   │   └── custom-skill/
│   │   │   │       └── SKILL.md
│   │   │   ├── hooks/
│   │   │   │   └── hooks.json
│   │   │   └── skills/
│   │   │       └── default-skill/
│   │   │           └── SKILL.md
│   │   ├── invalid-command-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── invalid-hooks-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── invalid-mcp-path/
│   │   │   └── .claude-plugin/
│   │   │       └── plugin.json
│   │   ├── mcp-file/
│   │   │   ├── .claude-plugin/
│   │   │   │   └── plugin.json
│   │   │   └── .mcp.json
│   │   └── sample-plugin/
│   │       ├── .claude-plugin/
│   │       │   └── plugin.json
│   │       ├── agents/
│   │       │   ├── agent-one.md
│   │       │   └── security-reviewer.md
│   │       ├── commands/
│   │       │   ├── command-one.md
│   │       │   ├── disabled-command.md
│   │       │   ├── model-command.md
│   │       │   ├── nested/
│   │       │   │   └── command-two.md
│   │       │   ├── pattern-command.md
│   │       │   ├── skill-command.md
│   │       │   └── todo-command.md
│   │       ├── hooks/
│   │       │   └── hooks.json
│   │       └── skills/
│   │           ├── disabled-skill/
│   │           │   └── SKILL.md
│   │           └── skill-one/
│   │               └── SKILL.md
│   ├── frontmatter.test.ts
│   ├── gemini-converter.test.ts
│   ├── gemini-writer.test.ts
│   ├── kiro-converter.test.ts
│   ├── kiro-writer.test.ts
│   ├── openclaw-converter.test.ts
│   ├── openclaw-writer.test.ts
│   ├── opencode-writer.test.ts
│   ├── pi-converter.test.ts
│   ├── pi-writer.test.ts
│   ├── qwen-converter.test.ts
│   ├── release-components.test.ts
│   ├── release-config.test.ts
│   ├── release-metadata.test.ts
│   ├── release-preview.test.ts
│   ├── resolve-output.test.ts
│   ├── sync-codex.test.ts
│   ├── sync-copilot.test.ts
│   ├── sync-droid.test.ts
│   ├── sync-gemini.test.ts
│   ├── sync-kiro.test.ts
│   ├── sync-openclaw.test.ts
│   ├── sync-pi.test.ts
│   ├── sync-qwen.test.ts
│   ├── sync-windsurf.test.ts
│   ├── windsurf-converter.test.ts
│   └── windsurf-writer.test.ts
└── tsconfig.json
Download .txt
SYMBOL INDEX (559 symbols across 93 files)

FILE: plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py
  function get_tutorials_repo_path (line 17) | def get_tutorials_repo_path():
  function get_repo_name (line 22) | def get_repo_name():
  function check_uncommitted_changes (line 36) | def check_uncommitted_changes():
  function slugify (line 51) | def slugify(text):
  function create_tutorial (line 56) | def create_tutorial(topic, concepts=None, output_dir=None):
  function main (line 173) | def main():

FILE: plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py
  function get_tutorials_directory (line 20) | def get_tutorials_directory():
  function extract_frontmatter (line 25) | def extract_frontmatter(filepath):
  function index_tutorials (line 81) | def index_tutorials(tutorials_dir=None):
  function format_human_readable (line 122) | def format_human_readable(tutorials):
  function main (line 154) | def main():

FILE: plugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py
  function get_tutorials_directory (line 18) | def get_tutorials_directory():
  function parse_frontmatter (line 39) | def parse_frontmatter(filepath):
  function parse_date (line 81) | def parse_date(date_value):
  function calculate_priority (line 88) | def calculate_priority(tutorial, today):
  function main (line 121) | def main():

FILE: plugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py
  function get_tutorials_repo_path (line 19) | def get_tutorials_repo_path():
  function setup_tutorials_repo (line 46) | def setup_tutorials_repo(create_github=False):
  function main (line 99) | def main():

FILE: plugins/compound-engineering/skills/claude-permissions-optimizer/scripts/extract-commands.mjs
  function flag (line 21) | function flag(name, fallback) {
  function flagAll (line 26) | function flagAll(name) {
  function loadAllowlist (line 53) | async function loadAllowlist(filePath) {
  function isAllowed (line 81) | function isAllowed(command) {
  function matchGlob (line 89) | function matchGlob(pattern, command) {
  constant RED_PATTERNS (line 115) | const RED_PATTERNS = [
  constant GREEN_BASES (line 194) | const GREEN_BASES = new Set([
  constant GREEN_COMPOUND (line 204) | const GREEN_COMPOUND = [
  constant YELLOW_BASES (line 241) | const YELLOW_BASES = new Set([
  constant YELLOW_COMPOUND (line 248) | const YELLOW_COMPOUND = [
  function classify (line 269) | function classify(command) {
  constant GLOBAL_RISK_FLAGS (line 307) | const GLOBAL_RISK_FLAGS = new Set([
  constant CONTEXTUAL_RISK_FLAGS (line 316) | const CONTEXTUAL_RISK_FLAGS = {
  function isRiskFlag (line 321) | function isRiskFlag(token, base) {
  function normalize (line 331) | function normalize(command) {
  function listDirs (line 430) | async function listDirs(dir) {
  function listJsonlFiles (line 439) | async function listJsonlFiles(dir) {
  function processFile (line 450) | async function processFile(filePath, sessionId) {

FILE: plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb
  type FeatureFlags (line 82) | module FeatureFlags

FILE: plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb
  class BasicClassifier (line 19) | class BasicClassifier < DSPy::Module
    method initialize (line 20) | def initialize
    method forward (line 25) | def forward(text:)
  class ReasoningClassifier (line 38) | class ReasoningClassifier < DSPy::Module
    method initialize (line 39) | def initialize
    method forward (line 44) | def forward(text:)
  class InstrumentedModule (line 53) | class InstrumentedModule < DSPy::Module
    method initialize (line 58) | def initialize
    method forward (line 64) | def forward(query:)
    method setup_metrics (line 71) | def setup_metrics
    method manage_context (line 77) | def manage_context
    method log_completion (line 85) | def log_completion
    method load_user_context (line 90) | def load_user_context = nil
    method save_updated_context (line 91) | def save_updated_context(_result) = nil
  class SearchTool (line 99) | class SearchTool < DSPy::Tools::Base
    method call (line 104) | def call(query:, max_results: 5)
  class FinishTool (line 110) | class FinishTool < DSPy::Tools::Base
    method call (line 115) | def call(answer:)
  class ResearchAgent (line 120) | class ResearchAgent < DSPy::Module
    method initialize (line 121) | def initialize
    method forward (line 131) | def forward(question:)
  class SmartRouter (line 138) | class SmartRouter < DSPy::Module
    method initialize (line 139) | def initialize
    method forward (line 145) | def forward(text:)
    method fast_model (line 163) | def fast_model
    method powerful_model (line 170) | def powerful_model
  class ConfiguredAgent (line 180) | class ConfiguredAgent < DSPy::Module
    method initialize (line 181) | def initialize
    method forward (line 195) | def forward(question:)
  class TokenTrackingModule (line 207) | class TokenTrackingModule < DSPy::Module
    method initialize (line 210) | def initialize
    method forward (line 216) | def forward(query:)
    method track_tokens (line 220) | def track_tokens(_event, attrs)
    method token_usage (line 224) | def token_usage
  class RerankTool (line 234) | class RerankTool < DSPy::Tools::Base
    method call (line 242) | def call(query:, items: [])
  class AnalysisPipeline (line 268) | class AnalysisPipeline < DSPy::Module
    method initialize (line 269) | def initialize
    method forward (line 276) | def forward(text:)
  class TracedModule (line 285) | class TracedModule < DSPy::Module
    method initialize (line 286) | def initialize
    method forward (line 291) | def forward(query:)

FILE: plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb
  class SentimentAnalysis (line 20) | class SentimentAnalysis < DSPy::Signature
    class Sentiment (line 23) | class Sentiment < T::Enum
  class EventScheduler (line 49) | class EventScheduler < DSPy::Signature
  class SmartSearch (line 74) | class SmartSearch < DSPy::Signature
  class EntityExtraction (line 99) | class EntityExtraction < DSPy::Signature
    class EntityType (line 102) | class EntityType < T::Enum
    class Entity (line 111) | class Entity < T::Struct
  class FlexibleClassification (line 132) | class FlexibleClassification < DSPy::Signature
    class Category (line 135) | class Category < T::Enum
  class DocumentParser (line 157) | class DocumentParser < DSPy::Signature
    class NodeType (line 160) | class NodeType < T::Enum
    class TreeNode (line 169) | class TreeNode < T::Struct
  class ImageAnalysis (line 192) | class ImageAnalysis < DSPy::Signature

FILE: plugins/compound-engineering/skills/gemini-imagegen/scripts/compose_images.py
  function compose_images (line 28) | def compose_images(
  function main (line 109) | def main():

FILE: plugins/compound-engineering/skills/gemini-imagegen/scripts/edit_image.py
  function edit_image (line 26) | def edit_image(
  function main (line 96) | def main():

FILE: plugins/compound-engineering/skills/gemini-imagegen/scripts/gemini_images.py
  class GeminiImageGenerator (line 31) | class GeminiImageGenerator:
    method __init__ (line 37) | def __init__(self, api_key: str | None = None, model: Model = FLASH):
    method _build_config (line 51) | def _build_config(
    method generate (line 74) | def generate(
    method edit (line 115) | def edit(
    method compose (line 160) | def compose(
    method chat (line 211) | def chat(self) -> "ImageChat":
  class ImageChat (line 216) | class ImageChat:
    method __init__ (line 219) | def __init__(self, client: genai.Client, model: Model):
    method send (line 228) | def send(
    method reset (line 257) | def reset(self):

FILE: plugins/compound-engineering/skills/gemini-imagegen/scripts/generate_image.py
  function generate_image (line 25) | def generate_image(
  function main (line 87) | def main():

FILE: plugins/compound-engineering/skills/gemini-imagegen/scripts/multi_turn_chat.py
  class ImageChat (line 35) | class ImageChat:
    method __init__ (line 38) | def __init__(
    method _init_chat (line 58) | def _init_chat(self):
    method send_message (line 69) | def send_message(self, message: str, image: Image.Image | None = None)...
    method save_image (line 94) | def save_image(self, filename: str | None = None) -> str | None:
    method load_image (line 108) | def load_image(self, path: str) -> Image.Image:
  function main (line 115) | def main():

FILE: scripts/release/preview.ts
  function parseArgs (line 5) | function parseArgs(argv: string[]): {
  function formatPreview (line 46) | function formatPreview(preview: Awaited<ReturnType<typeof buildReleasePr...

FILE: scripts/release/validate.ts
  type ReleasePleaseManifest (line 7) | type ReleasePleaseManifest = Record<string, string>

FILE: src/commands/convert.ts
  method run (line 79) | async run({ args }) {
  function parseExtraTargets (line 214) | function parseExtraTargets(value: unknown): string[] {
  function resolveOutputRoot (line 222) | function resolveOutputRoot(value: unknown): string {

FILE: src/commands/install.ts
  method run (line 81) | async run({ args }) {
  type ResolvedPluginPath (line 222) | type ResolvedPluginPath = {
  function resolvePluginPath (line 227) | async function resolvePluginPath(input: string): Promise<ResolvedPluginP...
  function parseExtraTargets (line 240) | function parseExtraTargets(value: unknown): string[] {
  function resolveOutputRoot (line 248) | function resolveOutputRoot(value: unknown): string {
  function resolveGitHubPluginPath (line 258) | async function resolveGitHubPluginPath(pluginName: string): Promise<Reso...
  function resolveGitHubSource (line 282) | function resolveGitHubSource(): string {
  function cloneGitHubRepo (line 288) | async function cloneGitHubRepo(source: string, destination: string): Pro...

FILE: src/commands/list.ts
  method run (line 11) | async run() {

FILE: src/commands/sync.ts
  type SyncTarget (line 16) | type SyncTarget = SyncTargetName | "all"
  function isValidTarget (line 18) | function isValidTarget(value: string): value is SyncTarget {
  method run (line 39) | async run({ args }) {

FILE: src/converters/claude-to-codex.ts
  type ClaudeToCodexOptions (line 11) | type ClaudeToCodexOptions = ClaudeToOpenCodeOptions
  constant CODEX_DESCRIPTION_MAX_LENGTH (line 13) | const CODEX_DESCRIPTION_MAX_LENGTH = 1024
  function convertClaudeToCodex (line 15) | function convertClaudeToCodex(
  function convertAgent (line 103) | function convertAgent(
  function convertCommandSkill (line 127) | function convertCommandSkill(
  function renderPrompt (line 153) | function renderPrompt(
  function renderWorkflowPrompt (line 168) | function renderWorkflowPrompt(skill: ClaudeSkill): string {
  function isCanonicalCodexWorkflowSkill (line 180) | function isCanonicalCodexWorkflowSkill(name: string): boolean {
  function isDeprecatedCodexWorkflowAlias (line 184) | function isDeprecatedCodexWorkflowAlias(name: string): boolean {
  function toCanonicalWorkflowSkillName (line 188) | function toCanonicalWorkflowSkillName(name: string): string | null {
  function shouldApplyCompoundWorkflowModel (line 193) | function shouldApplyCompoundWorkflowModel(plugin: ClaudePlugin): boolean {
  function sanitizeDescription (line 197) | function sanitizeDescription(value: string, maxLength = CODEX_DESCRIPTIO...
  function uniqueName (line 204) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/converters/claude-to-copilot.ts
  type ClaudeToCopilotOptions (line 11) | type ClaudeToCopilotOptions = ClaudeToOpenCodeOptions
  constant COPILOT_BODY_CHAR_LIMIT (line 13) | const COPILOT_BODY_CHAR_LIMIT = 30_000
  function convertClaudeToCopilot (line 15) | function convertClaudeToCopilot(
  function convertAgent (line 46) | function convertAgent(agent: ClaudeAgent, usedNames: Set<string>): Copil...
  function convertCommandToSkill (line 79) | function convertCommandToSkill(
  function transformContentForCopilot (line 106) | function transformContentForCopilot(body: string): string {
  function convertMcpServers (line 140) | function convertMcpServers(
  function prefixEnvVars (line 169) | function prefixEnvVars(env: Record<string, string>): Record<string, stri...
  function flattenCommandName (line 181) | function flattenCommandName(name: string): string {
  function normalizeName (line 185) | function normalizeName(value: string): string {
  function uniqueName (line 198) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/converters/claude-to-droid.ts
  type ClaudeToDroidOptions (line 6) | type ClaudeToDroidOptions = ClaudeToOpenCodeOptions
  constant CLAUDE_TO_DROID_TOOLS (line 8) | const CLAUDE_TO_DROID_TOOLS: Record<string, string> = {
  constant VALID_DROID_TOOLS (line 26) | const VALID_DROID_TOOLS = new Set([
  function convertClaudeToDroid (line 42) | function convertClaudeToDroid(
  function convertCommand (line 56) | function convertCommand(command: ClaudeCommand): DroidCommandFile {
  function convertAgent (line 73) | function convertAgent(agent: ClaudeAgent): DroidAgentFile {
  function mapAgentTools (line 101) | function mapAgentTools(agent: ClaudeAgent): string[] | undefined {
  function transformContentForDroid (line 122) | function transformContentForDroid(body: string): string {
  function flattenCommandName (line 157) | function flattenCommandName(name: string): string {
  function normalizeName (line 163) | function normalizeName(value: string): string {

FILE: src/converters/claude-to-gemini.ts
  type ClaudeToGeminiOptions (line 6) | type ClaudeToGeminiOptions = ClaudeToOpenCodeOptions
  constant GEMINI_DESCRIPTION_MAX_LENGTH (line 8) | const GEMINI_DESCRIPTION_MAX_LENGTH = 1024
  function convertClaudeToGemini (line 10) | function convertClaudeToGemini(
  function convertAgentToSkill (line 40) | function convertAgentToSkill(agent: ClaudeAgent, usedNames: Set<string>)...
  function convertCommand (line 61) | function convertCommand(command: ClaudeCommand, usedNames: Set<string>):...
  function transformContentForGemini (line 86) | function transformContentForGemini(body: string): string {
  function convertMcpServers (line 110) | function convertMcpServers(
  function resolveCommandPath (line 136) | function resolveCommandPath(name: string): string[] {
  function toToml (line 144) | function toToml(description: string, prompt: string): string {
  function formatTomlString (line 157) | function formatTomlString(value: string): string {
  function normalizeName (line 161) | function normalizeName(value: string): string {
  function sanitizeDescription (line 174) | function sanitizeDescription(value: string, maxLength = GEMINI_DESCRIPTI...
  function uniqueName (line 181) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/converters/claude-to-kiro.ts
  type ClaudeToKiroOptions (line 15) | type ClaudeToKiroOptions = ClaudeToOpenCodeOptions
  constant KIRO_SKILL_NAME_MAX_LENGTH (line 17) | const KIRO_SKILL_NAME_MAX_LENGTH = 64
  constant KIRO_SKILL_NAME_PATTERN (line 18) | const KIRO_SKILL_NAME_PATTERN = /^[a-z][a-z0-9-]*$/
  constant KIRO_DESCRIPTION_MAX_LENGTH (line 19) | const KIRO_DESCRIPTION_MAX_LENGTH = 1024
  constant CLAUDE_TO_KIRO_TOOLS (line 21) | const CLAUDE_TO_KIRO_TOOLS: Record<string, string> = {
  function convertClaudeToKiro (line 32) | function convertClaudeToKiro(
  function convertAgentToKiroAgent (line 72) | function convertAgentToKiroAgent(agent: ClaudeAgent, knownAgentNames: st...
  function convertCommandToSkill (line 103) | function convertCommandToSkill(
  function transformContentForKiro (line 135) | function transformContentForKiro(body: string, knownAgentNames: string[]...
  function convertMcpServers (line 173) | function convertMcpServers(
  function buildSteeringFiles (line 198) | function buildSteeringFiles(plugin: ClaudePlugin, knownAgentNames: strin...
  function resolveInstructionPath (line 215) | function resolveInstructionPath(root: string): string | null {
  function normalizeName (line 225) | function normalizeName(value: string): string {
  function sanitizeDescription (line 254) | function sanitizeDescription(value: string, maxLength = KIRO_DESCRIPTION...
  function uniqueName (line 261) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/converters/claude-to-openclaw.ts
  type ClaudeToOpenClawOptions (line 16) | type ClaudeToOpenClawOptions = ClaudeToOpenCodeOptions
  function convertClaudeToOpenClaw (line 18) | function convertClaudeToOpenClaw(
  function buildManifest (line 62) | function buildManifest(plugin: ClaudePlugin, skillDirs: string[]): OpenC...
  function buildPackageJson (line 75) | function buildPackageJson(plugin: ClaudePlugin): Record<string, unknown> {
  function convertAgentToSkill (line 99) | function convertAgentToSkill(agent: ClaudeAgent): OpenClawSkillFile {
  function convertCommandToSkill (line 119) | function convertCommandToSkill(command: ClaudeCommand): OpenClawSkillFile {
  function convertCommand (line 139) | function convertCommand(command: ClaudeCommand): OpenClawCommandRegistra...
  function buildOpenClawConfig (line 148) | function buildOpenClawConfig(
  function generateEntryPoint (line 173) | function generateEntryPoint(commands: OpenClawCommandRegistration[]): st...
  function rewritePaths (line 232) | function rewritePaths(body: string): string {
  function formatDisplayName (line 239) | function formatDisplayName(name: string): string {

FILE: src/converters/claude-to-opencode.ts
  type PermissionMode (line 16) | type PermissionMode = "none" | "broad" | "from-commands"
  type ClaudeToOpenCodeOptions (line 18) | type ClaudeToOpenCodeOptions = {
  constant TOOL_MAP (line 24) | const TOOL_MAP: Record<string, string> = {
  type HookEventMapping (line 41) | type HookEventMapping = {
  constant HOOK_EVENT_MAP (line 48) | const HOOK_EVENT_MAP: Record<string, HookEventMapping> = {
  function convertClaudeToOpenCode (line 64) | function convertClaudeToOpenCode(
  function convertAgent (line 89) | function convertAgent(agent: ClaudeAgent, options: ClaudeToOpenCodeOptio...
  function convertCommands (line 116) | function convertCommands(commands: ClaudeCommand[]): OpenCodeCommandFile...
  function convertMcp (line 132) | function convertMcp(servers: Record<string, ClaudeMcpServer>): Record<st...
  function convertHooks (line 157) | function convertHooks(hooks: ClaudeHooks) {
  function renderHookHandlers (line 192) | function renderHookHandlers(
  function renderHookStatements (line 217) | function renderHookStatements(
  function rewriteClaudePaths (line 257) | function rewriteClaudePaths(body: string): string {
  constant CLAUDE_FAMILY_ALIASES (line 265) | const CLAUDE_FAMILY_ALIASES: Record<string, string> = {
  function normalizeModel (line 271) | function normalizeModel(model: string): string {
  function inferTemperature (line 287) | function inferTemperature(agent: ClaudeAgent): number | undefined {
  function applyPermissions (line 304) | function applyPermissions(
  function normalizeTool (line 405) | function normalizeTool(raw: string): string | null {
  function parseToolSpec (line 409) | function parseToolSpec(raw: string): { tool: string | null; pattern?: st...
  function normalizePattern (line 422) | function normalizePattern(tool: string, pattern: string): string {

FILE: src/converters/claude-to-pi.ts
  type ClaudeToPiOptions (line 12) | type ClaudeToPiOptions = ClaudeToOpenCodeOptions
  constant PI_DESCRIPTION_MAX_LENGTH (line 14) | const PI_DESCRIPTION_MAX_LENGTH = 1024
  function convertClaudeToPi (line 16) | function convertClaudeToPi(
  function convertPrompt (line 48) | function convertPrompt(command: ClaudeCommand, usedNames: Set<string>) {
  function convertAgent (line 64) | function convertAgent(agent: ClaudeAgent, usedNames: Set<string>): PiGen...
  function transformContentForPi (line 93) | function transformContentForPi(body: string): string {
  function appendCompatibilityNoteIfNeeded (line 133) | function appendCompatibilityNoteIfNeeded(body: string): string {
  function convertMcpToMcporter (line 148) | function convertMcpToMcporter(servers: Record<string, ClaudeMcpServer>):...
  function normalizeName (line 173) | function normalizeName(value: string): string {
  function sanitizeDescription (line 186) | function sanitizeDescription(value: string, maxLength = PI_DESCRIPTION_M...
  function uniqueName (line 193) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/converters/claude-to-qwen.ts
  type ClaudeToQwenOptions (line 12) | type ClaudeToQwenOptions = {
  function convertClaudeToQwen (line 17) | function convertClaudeToQwen(plugin: ClaudePlugin, options: ClaudeToQwen...
  function convertAgent (line 50) | function convertAgent(agent: ClaudeAgent, options: ClaudeToQwenOptions):...
  function convertCommands (line 78) | function convertCommands(commands: ClaudeCommand[]): QwenCommandFile[] {
  function convertMcp (line 97) | function convertMcp(servers: Record<string, ClaudeMcpServer>): Record<st...
  function extractSettings (line 119) | function extractSettings(mcpServers?: Record<string, ClaudeMcpServer>): ...
  function formatSettingName (line 142) | function formatSettingName(envVar: string): string {
  function generateContextFile (line 149) | function generateContextFile(plugin: ClaudePlugin): string {
  function rewriteQwenPaths (line 195) | function rewriteQwenPaths(body: string): string {
  constant CLAUDE_FAMILY_ALIASES (line 201) | const CLAUDE_FAMILY_ALIASES: Record<string, string> = {
  function normalizeModel (line 207) | function normalizeModel(model: string): string {
  function inferTemperature (line 223) | function inferTemperature(agent: ClaudeAgent): number | undefined {

FILE: src/converters/claude-to-windsurf.ts
  type ClaudeToWindsurfOptions (line 7) | type ClaudeToWindsurfOptions = ClaudeToOpenCodeOptions
  constant WINDSURF_WORKFLOW_CHAR_LIMIT (line 9) | const WINDSURF_WORKFLOW_CHAR_LIMIT = 12_000
  function convertClaudeToWindsurf (line 11) | function convertClaudeToWindsurf(
  function convertAgentToSkill (line 48) | function convertAgentToSkill(
  function convertCommandToWorkflow (line 71) | function convertCommandToWorkflow(
  function transformContentForWindsurf (line 108) | function transformContentForWindsurf(body: string, knownAgentNames: stri...
  function buildMcpConfig (line 134) | function buildMcpConfig(servers?: Record<string, ClaudeMcpServer>): Wind...
  function normalizeName (line 171) | function normalizeName(value: string): string {
  function sanitizeDescription (line 189) | function sanitizeDescription(value: string): string {
  function uniqueName (line 193) | function uniqueName(base: string, used: Set<string>): string {

FILE: src/parsers/claude-home.ts
  type ClaudeHomeConfig (line 8) | interface ClaudeHomeConfig {
  function loadClaudeHome (line 14) | async function loadClaudeHome(claudeHome?: string): Promise<ClaudeHomeCo...
  function loadPersonalSkills (line 26) | async function loadPersonalSkills(skillsDir: string): Promise<ClaudeSkil...
  function loadSettingsMcp (line 69) | async function loadSettingsMcp(
  function loadPersonalCommands (line 81) | async function loadPersonalCommands(commandsDir: string): Promise<Claude...
  function deriveCommandName (line 109) | function deriveCommandName(commandsDir: string, filePath: string): string {
  function parseAllowedTools (line 115) | function parseAllowedTools(value: unknown): string[] | undefined {

FILE: src/parsers/claude.ts
  constant PLUGIN_MANIFEST (line 14) | const PLUGIN_MANIFEST = path.join(".claude-plugin", "plugin.json")
  function loadClaudePlugin (line 16) | async function loadClaudePlugin(inputPath: string): Promise<ClaudePlugin> {
  function resolveClaudeRoot (line 39) | async function resolveClaudeRoot(inputPath: string): Promise<string> {
  function loadAgents (line 57) | async function loadAgents(agentsDirs: string[]): Promise<ClaudeAgent[]> {
  function loadCommands (line 77) | async function loadCommands(commandsDirs: string[]): Promise<ClaudeComma...
  function loadSkills (line 101) | async function loadSkills(skillsDirs: string[]): Promise<ClaudeSkill[]> {
  function loadHooks (line 122) | async function loadHooks(root: string, hooksField?: ClaudeManifest["hook...
  function loadMcpServers (line 148) | async function loadMcpServers(
  function parseAllowedTools (line 169) | function parseAllowedTools(value: unknown): string[] | undefined {
  function resolveComponentDirs (line 183) | function resolveComponentDirs(
  function toPathList (line 195) | function toPathList(value?: string | string[]): string[] {
  function collectMarkdownFiles (line 201) | async function collectMarkdownFiles(dirs: string[]): Promise<string[]> {
  function collectFiles (line 206) | async function collectFiles(dirs: string[]): Promise<string[]> {
  function mergeHooks (line 216) | function mergeHooks(hooksList: ClaudeHooks[]): ClaudeHooks {
  function loadMcpPaths (line 229) | async function loadMcpPaths(
  function unwrapMcpServers (line 244) | function unwrapMcpServers(raw: Record<string, unknown>): Record<string, ...
  function mergeMcpConfigs (line 251) | function mergeMcpConfigs(configs: Record<string, ClaudeMcpServer>[]): Re...
  function resolveWithinRoot (line 255) | function resolveWithinRoot(root: string, entry: string, label: string): ...

FILE: src/release/components.ts
  constant RELEASE_COMPONENTS (line 11) | const RELEASE_COMPONENTS: ReleaseComponent[] = [
  constant FILE_COMPONENT_MAP (line 19) | const FILE_COMPONENT_MAP: Array<{ component: ReleaseComponent; prefixes:...
  constant SCOPES_TO_COMPONENTS (line 42) | const SCOPES_TO_COMPONENTS: Record<string, ReleaseComponent> = {
  constant NON_RELEASABLE_TYPES (line 51) | const NON_RELEASABLE_TYPES = new Set(["docs", "chore", "test", "ci", "bu...
  constant PATCH_TYPES (line 52) | const PATCH_TYPES = new Set(["fix", "perf", "refactor", "revert"])
  type VersionSources (line 54) | type VersionSources = Record<ReleaseComponent, string>
  type RootPackageJson (line 56) | type RootPackageJson = {
  type PluginManifest (line 60) | type PluginManifest = {
  type MarketplaceManifest (line 64) | type MarketplaceManifest = {
  function parseReleaseIntent (line 70) | function parseReleaseIntent(rawTitle: string): ParsedReleaseIntent {
  function inferBumpFromIntent (line 93) | function inferBumpFromIntent(intent: ParsedReleaseIntent): BumpLevel | n...
  function detectComponentsFromFiles (line 102) | function detectComponentsFromFiles(files: string[]): Map<ReleaseComponen...
  function resolveComponentWarnings (line 125) | function resolveComponentWarnings(
  function applyOverride (line 153) | function applyOverride(
  function bumpVersion (line 161) | function bumpVersion(version: string, bump: BumpLevel | null): string | ...
  function loadCurrentVersions (line 183) | async function loadCurrentVersions(cwd = process.cwd()): Promise<Version...
  function buildReleasePreview (line 199) | async function buildReleasePreview(options: {

FILE: src/release/config.ts
  type ReleasePleasePackageConfig (line 3) | type ReleasePleasePackageConfig = {
  type ReleasePleaseConfig (line 8) | type ReleasePleaseConfig = {
  function validateReleasePleaseConfig (line 12) | function validateReleasePleaseConfig(config: ReleasePleaseConfig): strin...

FILE: src/release/metadata.ts
  type ClaudePluginManifest (line 6) | type ClaudePluginManifest = {
  type CursorPluginManifest (line 12) | type CursorPluginManifest = {
  type MarketplaceManifest (line 17) | type MarketplaceManifest = {
  type SyncOptions (line 29) | type SyncOptions = {
  type FileUpdate (line 35) | type FileUpdate = {
  type MetadataSyncResult (line 40) | type MetadataSyncResult = {
  type CompoundEngineeringCounts (line 44) | type CompoundEngineeringCounts = {
  constant COMPOUND_ENGINEERING_DESCRIPTION (line 50) | const COMPOUND_ENGINEERING_DESCRIPTION =
  constant COMPOUND_ENGINEERING_MARKETPLACE_DESCRIPTION (line 53) | const COMPOUND_ENGINEERING_MARKETPLACE_DESCRIPTION =
  function resolveExpectedVersion (line 56) | function resolveExpectedVersion(
  function countMarkdownFiles (line 63) | async function countMarkdownFiles(root: string): Promise<number> {
  function countSkillDirectories (line 81) | async function countSkillDirectories(root: string): Promise<number> {
  function countMcpServers (line 99) | async function countMcpServers(pluginRoot: string): Promise<number> {
  function getCompoundEngineeringCounts (line 105) | async function getCompoundEngineeringCounts(root: string): Promise<Compo...
  function buildCompoundEngineeringDescription (line 116) | async function buildCompoundEngineeringDescription(_root: string): Promi...
  function buildCompoundEngineeringMarketplaceDescription (line 120) | async function buildCompoundEngineeringMarketplaceDescription(_root: str...
  function syncReleaseMetadata (line 124) | async function syncReleaseMetadata(options: SyncOptions = {}): Promise<M...

FILE: src/release/types.ts
  type ReleaseComponent (line 1) | type ReleaseComponent = "cli" | "compound-engineering" | "coding-tutor" ...
  type BumpLevel (line 3) | type BumpLevel = "patch" | "minor" | "major"
  type BumpOverride (line 5) | type BumpOverride = BumpLevel | "auto"
  type ConventionalReleaseType (line 7) | type ConventionalReleaseType =
  type ParsedReleaseIntent (line 21) | type ParsedReleaseIntent = {
  type ComponentDecision (line 29) | type ComponentDecision = {
  type ReleasePreview (line 39) | type ReleasePreview = {

FILE: src/sync/codex.ts
  constant CURRENT_START_MARKER (line 9) | const CURRENT_START_MARKER = "# BEGIN compound-plugin Claude Code MCP"
  constant CURRENT_END_MARKER (line 10) | const CURRENT_END_MARKER = "# END compound-plugin Claude Code MCP"
  constant LEGACY_MARKER (line 11) | const LEGACY_MARKER = "# MCP servers synced from Claude Code"
  function syncToCodex (line 13) | async function syncToCodex(
  function escapeForRegex (line 66) | function escapeForRegex(value: string): string {

FILE: src/sync/commands.ts
  type WindsurfSyncScope (line 16) | type WindsurfSyncScope = "global" | "workspace"
  constant HOME_SYNC_PLUGIN_ROOT (line 18) | const HOME_SYNC_PLUGIN_ROOT = path.join(process.cwd(), ".compound-sync-h...
  constant DEFAULT_SYNC_OPTIONS (line 20) | const DEFAULT_SYNC_OPTIONS: ClaudeToOpenCodeOptions = {
  constant DEFAULT_QWEN_SYNC_OPTIONS (line 26) | const DEFAULT_QWEN_SYNC_OPTIONS: ClaudeToQwenOptions = {
  function hasCommands (line 31) | function hasCommands(config: ClaudeHomeConfig): boolean {
  function buildClaudeHomePlugin (line 35) | function buildClaudeHomePlugin(config: ClaudeHomeConfig): ClaudePlugin {
  function syncOpenCodeCommands (line 50) | async function syncOpenCodeCommands(
  function syncCodexCommands (line 69) | async function syncCodexCommands(
  function syncPiCommands (line 85) | async function syncPiCommands(
  function syncDroidCommands (line 101) | async function syncDroidCommands(
  function syncCopilotCommands (line 114) | async function syncCopilotCommands(
  function syncGeminiCommands (line 128) | async function syncGeminiCommands(
  function syncKiroCommands (line 141) | async function syncKiroCommands(
  function syncWindsurfCommands (line 154) | async function syncWindsurfCommands(
  function syncQwenCommands (line 171) | async function syncQwenCommands(
  function warnUnsupportedOpenClawCommands (line 192) | function warnUnsupportedOpenClawCommands(config: ClaudeHomeConfig): void {

FILE: src/sync/copilot.ts
  type CopilotMcpServer (line 9) | type CopilotMcpServer = {
  type CopilotMcpConfig (line 19) | type CopilotMcpConfig = {
  function syncToCopilot (line 23) | async function syncToCopilot(
  function convertMcpForCopilot (line 41) | function convertMcpForCopilot(
  function prefixEnvVars (line 68) | function prefixEnvVars(env: Record<string, string>): Record<string, stri...

FILE: src/sync/droid.ts
  type DroidMcpServer (line 8) | type DroidMcpServer = {
  function syncToDroid (line 18) | async function syncToDroid(
  function convertMcpForDroid (line 34) | function convertMcpForDroid(

FILE: src/sync/gemini.ts
  type GeminiMcpServer (line 9) | type GeminiMcpServer = {
  function syncToGemini (line 17) | async function syncToGemini(
  function syncGeminiSkills (line 35) | async function syncGeminiSkills(
  function getGeminiSharedSkillsDir (line 63) | function getGeminiSharedSkillsDir(outputRoot: string): string | null {
  function canonicalizePath (line 68) | async function canonicalizePath(targetPath: string): Promise<string> {
  function isWithinDir (line 76) | async function isWithinDir(candidate: string, canonicalParentDir: string...
  function removeGeminiMirrorConflicts (line 82) | async function removeGeminiMirrorConflicts(
  function convertMcpForGemini (line 118) | function convertMcpForGemini(

FILE: src/sync/json-config.ts
  type JsonObject (line 4) | type JsonObject = Record<string, unknown>
  function isJsonObject (line 6) | function isJsonObject(value: unknown): value is JsonObject {
  function mergeJsonConfigAtKey (line 10) | async function mergeJsonConfigAtKey(options: {
  function readJsonObjectSafe (line 29) | async function readJsonObjectSafe(configPath: string): Promise<JsonObjec...

FILE: src/sync/kiro.ts
  function syncToKiro (line 9) | async function syncToKiro(
  function convertMcpForKiro (line 25) | function convertMcpForKiro(

FILE: src/sync/mcp-transports.ts
  function getTransportType (line 3) | function getTransportType(server: ClaudeMcpServer): string {
  function hasExplicitSseTransport (line 7) | function hasExplicitSseTransport(server: ClaudeMcpServer): boolean {
  function hasExplicitHttpTransport (line 12) | function hasExplicitHttpTransport(server: ClaudeMcpServer): boolean {
  function hasExplicitRemoteTransport (line 17) | function hasExplicitRemoteTransport(server: ClaudeMcpServer): boolean {

FILE: src/sync/openclaw.ts
  function syncToOpenClaw (line 6) | async function syncToOpenClaw(

FILE: src/sync/opencode.ts
  function syncToOpenCode (line 9) | async function syncToOpenCode(
  function convertMcpForOpenCode (line 28) | function convertMcpForOpenCode(

FILE: src/sync/pi.ts
  type McporterServer (line 9) | type McporterServer = {
  type McporterConfig (line 17) | type McporterConfig = {
  function syncToPi (line 21) | async function syncToPi(
  function convertMcpToMcporter (line 41) | function convertMcpToMcporter(servers: Record<string, ClaudeMcpServer>):...

FILE: src/sync/qwen.ts
  function syncToQwen (line 10) | async function syncToQwen(
  function convertMcpForQwen (line 26) | function convertMcpForQwen(

FILE: src/sync/registry.ts
  function getCopilotHomeRoot (line 15) | function getCopilotHomeRoot(home: string): string {
  function getGeminiHomeRoot (line 19) | function getGeminiHomeRoot(home: string): string {
  type SyncTargetName (line 23) | type SyncTargetName =
  type SyncTargetDefinition (line 35) | type SyncTargetDefinition = {
  function isSyncTargetName (line 127) | function isSyncTargetName(value: string): value is SyncTargetName {
  function getSyncTarget (line 131) | function getSyncTarget(name: SyncTargetName): SyncTargetDefinition {
  function getDefaultSyncRegistryContext (line 139) | function getDefaultSyncRegistryContext(): { home: string; cwd: string } {

FILE: src/sync/skills.ts
  function syncSkills (line 6) | async function syncSkills(

FILE: src/sync/windsurf.ts
  function syncToWindsurf (line 10) | async function syncToWindsurf(
  function convertMcpForWindsurf (line 26) | function convertMcpForWindsurf(

FILE: src/targets/codex.ts
  function writeCodexBundle (line 8) | async function writeCodexBundle(outputRoot: string, bundle: CodexBundle)...
  function copyCodexSkillDir (line 48) | async function copyCodexSkillDir(
  function resolveCodexRoot (line 83) | function resolveCodexRoot(outputRoot: string): string {
  function renderCodexConfig (line 87) | function renderCodexConfig(mcpServers?: Record<string, ClaudeMcpServer>)...
  function formatTomlString (line 123) | function formatTomlString(value: string): string {
  function formatTomlKey (line 127) | function formatTomlKey(value: string): string {
  function formatTomlInlineTable (line 132) | function formatTomlInlineTable(entries: Record<string, string>): string {

FILE: src/targets/copilot.ts
  function writeCopilotBundle (line 5) | async function writeCopilotBundle(outputRoot: string, bundle: CopilotBun...
  function resolveCopilotPaths (line 40) | function resolveCopilotPaths(outputRoot: string) {

FILE: src/targets/droid.ts
  function writeDroidBundle (line 5) | async function writeDroidBundle(outputRoot: string, bundle: DroidBundle)...
  function resolveDroidPaths (line 32) | function resolveDroidPaths(outputRoot: string) {

FILE: src/targets/gemini.ts
  function writeGeminiBundle (line 5) | async function writeGeminiBundle(outputRoot: string, bundle: GeminiBundl...
  function resolveGeminiPaths (line 53) | function resolveGeminiPaths(outputRoot: string) {

FILE: src/targets/index.ts
  type TargetScope (line 33) | type TargetScope = "global" | "workspace"
  function isTargetScope (line 35) | function isTargetScope(value: string): value is TargetScope {
  function validateScope (line 43) | function validateScope(
  type TargetHandler (line 59) | type TargetHandler<TBundle = unknown> = {

FILE: src/targets/kiro.ts
  function writeKiroBundle (line 5) | async function writeKiroBundle(outputRoot: string, bundle: KiroBundle): ...
  function resolveKiroPaths (line 95) | function resolveKiroPaths(outputRoot: string) {
  function validatePathSafe (line 118) | function validatePathSafe(name: string, label: string): void {

FILE: src/targets/openclaw.ts
  function writeOpenClawBundle (line 6) | async function writeOpenClawBundle(outputRoot: string, bundle: OpenClawB...
  function resolveOpenClawPaths (line 46) | function resolveOpenClawPaths(outputRoot: string) {
  function rewritePathsInDir (line 56) | async function rewritePathsInDir(dir: string): Promise<void> {
  function mergeOpenClawConfig (line 71) | async function mergeOpenClawConfig(

FILE: src/targets/opencode.ts
  function mergeOpenCodeConfig (line 6) | async function mergeOpenCodeConfig(
  function writeOpenCodeBundle (line 57) | async function writeOpenCodeBundle(outputRoot: string, bundle: OpenCodeB...
  function resolveOpenCodePaths (line 101) | function resolveOpenCodePaths(outputRoot: string) {

FILE: src/targets/pi.ts
  constant PI_AGENTS_BLOCK_START (line 13) | const PI_AGENTS_BLOCK_START = "<!-- BEGIN COMPOUND PI TOOL MAP -->"
  constant PI_AGENTS_BLOCK_END (line 14) | const PI_AGENTS_BLOCK_END = "<!-- END COMPOUND PI TOOL MAP -->"
  constant PI_AGENTS_BLOCK_BODY (line 16) | const PI_AGENTS_BLOCK_BODY = `## Compound Engineering (Pi compatibility)
  function writePiBundle (line 28) | async function writePiBundle(outputRoot: string, bundle: PiBundle): Prom...
  function resolvePiPaths (line 62) | function resolvePiPaths(outputRoot: string) {
  function ensurePiAgentsBlock (line 97) | async function ensurePiAgentsBlock(filePath: string): Promise<void> {
  function buildPiAgentsBlock (line 112) | function buildPiAgentsBlock(): string {
  function upsertBlock (line 116) | function upsertBlock(existing: string, block: string): string {

FILE: src/targets/qwen.ts
  function writeQwenBundle (line 5) | async function writeQwenBundle(outputRoot: string, bundle: QwenBundle): ...
  function resolveQwenPaths (line 48) | function resolveQwenPaths(outputRoot: string) {

FILE: src/targets/windsurf.ts
  function writeWindsurfBundle (line 13) | async function writeWindsurfBundle(outputRoot: string, bundle: WindsurfB...
  function validatePathSafe (line 96) | function validatePathSafe(name: string, label: string): void {
  function formatWorkflowContent (line 102) | function formatWorkflowContent(name: string, description: string, body: ...

FILE: src/templates/pi/compat-extension.ts
  constant PI_COMPAT_EXTENSION_SOURCE (line 1) | const PI_COMPAT_EXTENSION_SOURCE = `import fs from "node:fs"

FILE: src/types/claude.ts
  type ClaudeMcpServer (line 1) | type ClaudeMcpServer = {
  type ClaudeManifest (line 10) | type ClaudeManifest = {
  type ClaudeAgent (line 27) | type ClaudeAgent = {
  type ClaudeCommand (line 36) | type ClaudeCommand = {
  type ClaudeSkill (line 47) | type ClaudeSkill = {
  type ClaudePlugin (line 56) | type ClaudePlugin = {
  type ClaudeHookCommand (line 66) | type ClaudeHookCommand = {
  type ClaudeHookPrompt (line 72) | type ClaudeHookPrompt = {
  type ClaudeHookAgent (line 77) | type ClaudeHookAgent = {
  type ClaudeHookEntry (line 82) | type ClaudeHookEntry = ClaudeHookCommand | ClaudeHookPrompt | ClaudeHook...
  type ClaudeHookMatcher (line 84) | type ClaudeHookMatcher = {
  type ClaudeHooks (line 89) | type ClaudeHooks = {

FILE: src/types/codex.ts
  type CodexPrompt (line 4) | type CodexPrompt = {
  type CodexSkillDir (line 9) | type CodexSkillDir = {
  type CodexGeneratedSkill (line 14) | type CodexGeneratedSkill = {
  type CodexBundle (line 19) | type CodexBundle = {

FILE: src/types/copilot.ts
  type CopilotAgent (line 1) | type CopilotAgent = {
  type CopilotGeneratedSkill (line 6) | type CopilotGeneratedSkill = {
  type CopilotSkillDir (line 11) | type CopilotSkillDir = {
  type CopilotMcpServer (line 16) | type CopilotMcpServer = {
  type CopilotBundle (line 26) | type CopilotBundle = {

FILE: src/types/droid.ts
  type DroidCommandFile (line 1) | type DroidCommandFile = {
  type DroidAgentFile (line 6) | type DroidAgentFile = {
  type DroidSkillDir (line 11) | type DroidSkillDir = {
  type DroidBundle (line 16) | type DroidBundle = {

FILE: src/types/gemini.ts
  type GeminiSkill (line 1) | type GeminiSkill = {
  type GeminiSkillDir (line 6) | type GeminiSkillDir = {
  type GeminiCommand (line 11) | type GeminiCommand = {
  type GeminiMcpServer (line 16) | type GeminiMcpServer = {
  type GeminiBundle (line 24) | type GeminiBundle = {

FILE: src/types/kiro.ts
  type KiroAgent (line 1) | type KiroAgent = {
  type KiroAgentConfig (line 7) | type KiroAgentConfig = {
  type KiroSkill (line 17) | type KiroSkill = {
  type KiroSkillDir (line 22) | type KiroSkillDir = {
  type KiroSteeringFile (line 27) | type KiroSteeringFile = {
  type KiroMcpServer (line 32) | type KiroMcpServer = {
  type KiroBundle (line 40) | type KiroBundle = {

FILE: src/types/openclaw.ts
  type OpenClawPluginManifest (line 1) | type OpenClawPluginManifest = {
  type OpenClawConfigSchema (line 10) | type OpenClawConfigSchema = {
  type OpenClawConfigProperty (line 17) | type OpenClawConfigProperty = {
  type OpenClawUiHint (line 23) | type OpenClawUiHint = {
  type OpenClawSkillFile (line 29) | type OpenClawSkillFile = {
  type OpenClawCommandRegistration (line 36) | type OpenClawCommandRegistration = {
  type OpenClawBundle (line 44) | type OpenClawBundle = {

FILE: src/types/opencode.ts
  type OpenCodePermission (line 1) | type OpenCodePermission = "allow" | "ask" | "deny"
  type OpenCodeConfig (line 3) | type OpenCodeConfig = {
  type OpenCodeAgentConfig (line 13) | type OpenCodeAgentConfig = {
  type OpenCodeMcpServer (line 22) | type OpenCodeMcpServer = {
  type OpenCodeAgentFile (line 31) | type OpenCodeAgentFile = {
  type OpenCodePluginFile (line 36) | type OpenCodePluginFile = {
  type OpenCodeCommandFile (line 41) | type OpenCodeCommandFile = {
  type OpenCodeBundle (line 46) | type OpenCodeBundle = {

FILE: src/types/pi.ts
  type PiPrompt (line 1) | type PiPrompt = {
  type PiSkillDir (line 6) | type PiSkillDir = {
  type PiGeneratedSkill (line 11) | type PiGeneratedSkill = {
  type PiExtensionFile (line 16) | type PiExtensionFile = {
  type PiMcporterServer (line 21) | type PiMcporterServer = {
  type PiMcporterConfig (line 30) | type PiMcporterConfig = {
  type PiBundle (line 34) | type PiBundle = {

FILE: src/types/qwen.ts
  type QwenExtensionConfig (line 1) | type QwenExtensionConfig = {
  type QwenMcpServer (line 12) | type QwenMcpServer = {
  type QwenSetting (line 22) | type QwenSetting = {
  type QwenAgentFile (line 29) | type QwenAgentFile = {
  type QwenSkillDir (line 35) | type QwenSkillDir = {
  type QwenCommandFile (line 40) | type QwenCommandFile = {
  type QwenBundle (line 45) | type QwenBundle = {

FILE: src/types/windsurf.ts
  type WindsurfWorkflow (line 1) | type WindsurfWorkflow = {
  type WindsurfGeneratedSkill (line 7) | type WindsurfGeneratedSkill = {
  type WindsurfSkillDir (line 12) | type WindsurfSkillDir = {
  type WindsurfMcpServerEntry (line 17) | type WindsurfMcpServerEntry = {
  type WindsurfMcpConfig (line 26) | type WindsurfMcpConfig = {
  type WindsurfBundle (line 30) | type WindsurfBundle = {

FILE: src/utils/codex-agents.ts
  constant CODEX_AGENTS_BLOCK_START (line 4) | const CODEX_AGENTS_BLOCK_START = "<!-- BEGIN COMPOUND CODEX TOOL MAP -->"
  constant CODEX_AGENTS_BLOCK_END (line 5) | const CODEX_AGENTS_BLOCK_END = "<!-- END COMPOUND CODEX TOOL MAP -->"
  constant CODEX_AGENTS_BLOCK_BODY (line 7) | const CODEX_AGENTS_BLOCK_BODY = `## Compound Codex Tool Mapping (Claude ...
  function ensureCodexAgentsFile (line 28) | async function ensureCodexAgentsFile(codexHome: string): Promise<void> {
  function buildCodexAgentsBlock (line 45) | function buildCodexAgentsBlock(): string {
  function upsertBlock (line 49) | function upsertBlock(existing: string, block: string): string {

FILE: src/utils/codex-content.ts
  type CodexInvocationTargets (line 1) | type CodexInvocationTargets = {
  type CodexTransformOptions (line 6) | type CodexTransformOptions = {
  function transformContentForCodex (line 22) | function transformContentForCodex(
  function normalizeCodexName (line 73) | function normalizeCodexName(value: string): string {

FILE: src/utils/detect-tools.ts
  type DetectedTool (line 5) | type DetectedTool = {
  function detectInstalledTools (line 11) | async function detectInstalledTools(
  function getDetectedTargetNames (line 31) | async function getDetectedTargetNames(

FILE: src/utils/files.ts
  function backupFile (line 4) | async function backupFile(filePath: string): Promise<string | null> {
  function pathExists (line 17) | async function pathExists(filePath: string): Promise<boolean> {
  function ensureDir (line 26) | async function ensureDir(dirPath: string): Promise<void> {
  function readText (line 30) | async function readText(filePath: string): Promise<string> {
  function readJson (line 34) | async function readJson<T>(filePath: string): Promise<T> {
  function writeText (line 39) | async function writeText(filePath: string, content: string): Promise<voi...
  function writeTextSecure (line 44) | async function writeTextSecure(filePath: string, content: string): Promi...
  function writeJson (line 50) | async function writeJson(filePath: string, data: unknown): Promise<void> {
  function writeJsonSecure (line 56) | async function writeJsonSecure(filePath: string, data: unknown): Promise...
  function walkFiles (line 63) | async function walkFiles(root: string): Promise<string[]> {
  function resolveCommandPath (line 83) | async function resolveCommandPath(dir: string, name: string, ext: string...
  function copyDir (line 93) | async function copyDir(sourceDir: string, targetDir: string): Promise<vo...

FILE: src/utils/frontmatter.ts
  type FrontmatterResult (line 3) | type FrontmatterResult = {
  function parseFrontmatter (line 8) | function parseFrontmatter(raw: string): FrontmatterResult {
  function formatFrontmatter (line 33) | function formatFrontmatter(data: Record<string, unknown>, body: string):...
  function formatYamlLine (line 46) | function formatYamlLine(key: string, value: unknown): string {
  function formatYamlValue (line 54) | function formatYamlValue(value: unknown): string {

FILE: src/utils/resolve-home.ts
  function expandHome (line 4) | function expandHome(value: string): string {
  function resolveTargetHome (line 12) | function resolveTargetHome(value: unknown, defaultPath: string): string {

FILE: src/utils/resolve-output.ts
  function resolveTargetOutputRoot (line 5) | function resolveTargetOutputRoot(options: {

FILE: src/utils/secrets.ts
  constant SENSITIVE_PATTERN (line 1) | const SENSITIVE_PATTERN = /key|token|secret|password|credential|api_key/i
  function hasPotentialSecrets (line 4) | function hasPotentialSecrets(
  function findServersWithPotentialSecrets (line 18) | function findServersWithPotentialSecrets(

FILE: src/utils/symlink.ts
  function forceSymlink (line 7) | async function forceSymlink(source: string, target: string): Promise<voi...
  function isValidSkillName (line 34) | function isValidSkillName(name: string): boolean {

FILE: tests/cli.test.ts
  function exists (line 6) | async function exists(filePath: string): Promise<boolean> {
  function runGit (line 15) | async function runGit(args: string[], cwd: string, env?: NodeJS.ProcessE...

FILE: tests/codex-agents.test.ts
  function readFile (line 11) | async function readFile(filePath: string): Promise<string> {

FILE: tests/codex-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/copilot-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/droid-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/gemini-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/kiro-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/opencode-writer.test.ts
  function exists (line 9) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/pi-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {

FILE: tests/release-metadata.test.ts
  function makeFixtureRoot (line 19) | async function makeFixtureRoot(): Promise<string> {

FILE: tests/windsurf-writer.test.ts
  function exists (line 8) | async function exists(filePath: string): Promise<boolean> {
Condensed preview — 376 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,590K chars).
[
  {
    "path": ".claude/commands/triage-prs.md",
    "chars": 6040,
    "preview": "---\nname: triage-prs\ndescription: Triage all open PRs with parallel agents, label, group, and review one-by-one\nargument"
  },
  {
    "path": ".claude-plugin/marketplace.json",
    "chars": 1554,
    "preview": "{\n  \"name\": \"compound-engineering-plugin\",\n  \"owner\": {\n    \"name\": \"Kieran Klaassen\",\n    \"url\": \"https://github.com/ki"
  },
  {
    "path": ".cursor-plugin/CHANGELOG.md",
    "chars": 420,
    "preview": "# Changelog\n\n## [1.0.1](https://github.com/EveryInc/compound-engineering-plugin/compare/cursor-marketplace-v1.0.0...curs"
  },
  {
    "path": ".cursor-plugin/marketplace.json",
    "chars": 745,
    "preview": "{\n  \"name\": \"compound-engineering\",\n  \"owner\": {\n    \"name\": \"Kieran Klaassen\",\n    \"email\": \"kieran@every.to\",\n    \"url"
  },
  {
    "path": ".github/.release-please-manifest.json",
    "chars": 157,
    "preview": "{\n  \".\": \"2.46.0\",\n  \"plugins/compound-engineering\": \"2.46.0\",\n  \"plugins/coding-tutor\": \"1.2.1\",\n  \".claude-plugin\": \"1"
  },
  {
    "path": ".github/release-please-config.json",
    "chars": 1772,
    "preview": "{\n  \"$schema\": \"https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json\",\n  \"include-compon"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 990,
    "preview": "name: CI\n\non:\n  push:\n    branches: [main]\n  pull_request:\n  workflow_dispatch:\n\njobs:\n  pr-title:\n    if: github.event_"
  },
  {
    "path": ".github/workflows/deploy-docs.yml",
    "chars": 796,
    "preview": "name: Deploy Documentation to GitHub Pages\n\non:\n  push:\n    branches: [main]\n    paths:\n      - 'plugins/compound-engine"
  },
  {
    "path": ".github/workflows/release-pr.yml",
    "chars": 2465,
    "preview": "name: Release PR\n\non:\n  push:\n    branches: [main]\n  workflow_dispatch:\n\npermissions:\n  contents: write\n  pull-requests:"
  },
  {
    "path": ".github/workflows/release-preview.yml",
    "chars": 3324,
    "preview": "name: Release Preview\n\non:\n  workflow_dispatch:\n    inputs:\n      title:\n        description: \"Conventional title to eva"
  },
  {
    "path": ".gitignore",
    "chars": 56,
    "preview": ".DS_Store\n*.log\nnode_modules/\n.codex/\ntodos/\n.worktrees\n"
  },
  {
    "path": "AGENTS.md",
    "chars": 6310,
    "preview": "# Agent Instructions\n\nThis repository primarily houses the `compound-engineering` coding-agent plugin and the Claude Cod"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 3272,
    "preview": "# Changelog\n\n## [2.46.0](https://github.com/EveryInc/compound-engineering-plugin/compare/cli-v2.45.0...cli-v2.46.0) (202"
  },
  {
    "path": "CLAUDE.md",
    "chars": 11,
    "preview": "@AGENTS.md\n"
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2025 Every\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "PRIVACY.md",
    "chars": 1962,
    "preview": "# Privacy & Data Handling\n\nThis repository contains:\n- a plugin package (`plugins/compound-engineering`) made of markdow"
  },
  {
    "path": "README.md",
    "chars": 9353,
    "preview": "# Compound Marketplace\n\n[![Build Status](https://github.com/EveryInc/compound-engineering-plugin/actions/workflows/ci.ym"
  },
  {
    "path": "SECURITY.md",
    "chars": 909,
    "preview": "# Security Policy\n\n## Supported Versions\n\nSecurity fixes are applied to the latest version on `main`.\n\n## Reporting a Vu"
  },
  {
    "path": "docs/brainstorms/2026-02-14-copilot-converter-target-brainstorm.md",
    "chars": 5295,
    "preview": "---\ndate: 2026-02-14\ntopic: copilot-converter-target\n---\n\n# Add GitHub Copilot Converter Target\n\n## What We're Building\n"
  },
  {
    "path": "docs/brainstorms/2026-02-17-copilot-skill-naming-brainstorm.md",
    "chars": 1393,
    "preview": "---\ndate: 2026-02-17\ntopic: copilot-skill-naming\n---\n\n# Copilot Skill Naming: Preserve Namespace\n\n## What We're Building"
  },
  {
    "path": "docs/brainstorms/2026-03-14-ce-plan-rewrite-requirements.md",
    "chars": 7547,
    "preview": "---\ndate: 2026-03-14\ntopic: ce-plan-rewrite\n---\n\n# Rewrite `ce:plan` to Separate Planning from Implementation\n\n## Proble"
  },
  {
    "path": "docs/brainstorms/2026-03-15-ce-ideate-skill-requirements.md",
    "chars": 9169,
    "preview": "---\ndate: 2026-03-15\ntopic: ce-ideate-skill\n---\n\n# ce:ideate — Open-Ended Ideation Skill\n\n## Problem Frame\n\nThe ce:brain"
  },
  {
    "path": "docs/brainstorms/2026-03-16-issue-grounded-ideation-requirements.md",
    "chars": 6642,
    "preview": "---\ndate: 2026-03-16\ntopic: issue-grounded-ideation\n---\n\n# Issue-Grounded Ideation Mode for ce:ideate\n\n## Problem Frame\n"
  },
  {
    "path": "docs/brainstorms/2026-03-17-release-automation-requirements.md",
    "chars": 9248,
    "preview": "---\ndate: 2026-03-17\ntopic: release-automation\n---\n\n# Release Automation and Changelog Ownership\n\n## Problem Frame\n\nThe "
  },
  {
    "path": "docs/brainstorms/2026-03-18-auto-memory-integration-requirements.md",
    "chars": 3718,
    "preview": "---\ndate: 2026-03-18\ntopic: auto-memory-integration\n---\n\n# Auto Memory Integration for ce:compound and ce:compound-refre"
  },
  {
    "path": "docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md",
    "chars": 7582,
    "preview": "---\ntitle: Convert .local.md Settings for OpenCode and Codex\ntype: feat\ndate: 2026-02-08\n---\n\n# Convert .local.md Settin"
  },
  {
    "path": "docs/plans/2026-02-08-feat-pr-triage-and-merge-plan.md",
    "chars": 5494,
    "preview": "---\ntitle: PR Triage, Review & Merge\ntype: feat\ndate: 2026-02-08\n---\n\n# PR Triage, Review & Merge\n\n## Overview\n\nReview a"
  },
  {
    "path": "docs/plans/2026-02-08-feat-simplify-plugin-settings-plan.md",
    "chars": 9550,
    "preview": "---\ntitle: Simplify Plugin Settings with .local.md Pattern\ntype: feat\ndate: 2026-02-08\n---\n\n# Simplify Plugin Settings\n\n"
  },
  {
    "path": "docs/plans/2026-02-08-refactor-reduce-plugin-context-token-usage-plan.md",
    "chars": 9600,
    "preview": "---\ntitle: Reduce compound-engineering plugin context token usage\ntype: refactor\ndate: 2026-02-08\n---\n\n# Reduce compound"
  },
  {
    "path": "docs/plans/2026-02-09-refactor-dspy-ruby-skill-update-plan.md",
    "chars": 5325,
    "preview": "---\ntitle: \"refactor: Update dspy-ruby skill to DSPy.rb v0.34.3 API\"\ntype: refactor\ndate: 2026-02-09\n---\n\n# Update dspy-"
  },
  {
    "path": "docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md",
    "chars": 12728,
    "preview": "---\ntitle: Add Cursor CLI as a Target Provider\ntype: feat\ndate: 2026-02-12\n---\n\n# Add Cursor CLI as a Target Provider\n\n#"
  },
  {
    "path": "docs/plans/2026-02-14-feat-add-copilot-converter-target-plan.md",
    "chars": 11585,
    "preview": "---\ntitle: \"feat: Add GitHub Copilot converter target\"\ntype: feat\ndate: 2026-02-14\nstatus: complete\n---\n\n# feat: Add Git"
  },
  {
    "path": "docs/plans/2026-02-14-feat-add-gemini-cli-target-provider-plan.md",
    "chars": 15800,
    "preview": "---\ntitle: Add Gemini CLI as a Target Provider\ntype: feat\nstatus: completed\ncompleted_date: 2026-02-14\ncompleted_by: \"Cl"
  },
  {
    "path": "docs/plans/2026-02-14-feat-auto-detect-install-and-gemini-sync-plan.md",
    "chars": 11857,
    "preview": "---\ntitle: Auto-detect install targets and add Gemini sync\ntype: feat\nstatus: completed\ndate: 2026-02-14\ncompleted_date:"
  },
  {
    "path": "docs/plans/2026-02-25-feat-windsurf-global-scope-support-plan.md",
    "chars": 30075,
    "preview": "---\ntitle: Windsurf Global Scope Support\ntype: feat\nstatus: completed\ndate: 2026-02-25\ndeepened: 2026-02-25\nprior: docs/"
  },
  {
    "path": "docs/plans/2026-03-01-feat-ce-command-aliases-backwards-compatible-deprecation-plan.md",
    "chars": 13326,
    "preview": "---\ntitle: \"feat: Add ce:* command aliases with backwards-compatible deprecation of workflows:*\"\ntype: feat\nstatus: acti"
  },
  {
    "path": "docs/plans/2026-03-01-fix-setup-skill-non-claude-llm-fallback-plan.md",
    "chars": 8071,
    "preview": "---\ntitle: \"fix: Setup skill fails silently on non-Claude LLMs due to AskUserQuestion dependency\"\ntype: fix\nstatus: acti"
  },
  {
    "path": "docs/plans/2026-03-03-feat-sync-claude-mcp-all-supported-providers-plan.md",
    "chars": 23092,
    "preview": "---\ntitle: \"feat: Sync Claude MCP servers to all supported providers\"\ntype: feat\ndate: 2026-03-03\nstatus: completed\ndeep"
  },
  {
    "path": "docs/plans/2026-03-15-001-feat-ce-ideate-skill-plan.md",
    "chars": 28231,
    "preview": "---\ntitle: \"feat: Add ce:ideate open-ended ideation skill\"\ntype: feat\nstatus: completed\ndate: 2026-03-15\norigin: docs/br"
  },
  {
    "path": "docs/plans/2026-03-16-001-feat-issue-grounded-ideation-plan.md",
    "chars": 16442,
    "preview": "---\ntitle: \"feat: Add issue-grounded ideation mode to ce:ideate\"\ntype: feat\nstatus: active\ndate: 2026-03-16\norigin: docs"
  },
  {
    "path": "docs/plans/2026-03-17-001-feat-release-automation-migration-beta-plan.md",
    "chars": 39052,
    "preview": "---\ntitle: \"feat: Migrate repo releases to manual release-please with centralized changelog\"\ntype: feat\nstatus: active\nd"
  },
  {
    "path": "docs/plans/2026-03-18-001-feat-auto-memory-integration-beta-plan.md",
    "chars": 12938,
    "preview": "---\ntitle: \"feat: Integrate auto memory as data source for ce:compound and ce:compound-refresh\"\ntype: feat\nstatus: compl"
  },
  {
    "path": "docs/plans/feature_opencode-commands-as-md-and-config-merge.md",
    "chars": 35434,
    "preview": "# Feature: OpenCode Commands as .md Files, Config Merge, and Permissions Default Fix\n\n**Type:** feature + bug fix (conso"
  },
  {
    "path": "docs/solutions/adding-converter-target-providers.md",
    "chars": 24123,
    "preview": "---\ntitle: Adding New Converter Target Providers\ncategory: architecture\ntags: [converter, target-provider, plugin-conver"
  },
  {
    "path": "docs/solutions/codex-skill-prompt-entrypoints.md",
    "chars": 6280,
    "preview": "---\ntitle: Codex Conversion Skills, Prompts, and Canonical Entry Points\ncategory: architecture\ntags: [codex, converter, "
  },
  {
    "path": "docs/solutions/plugin-versioning-requirements.md",
    "chars": 3915,
    "preview": "---\ntitle: Plugin Versioning and Documentation Requirements\ncategory: workflow\ntags: [versioning, changelog, readme, plu"
  },
  {
    "path": "docs/solutions/skill-design/beta-skills-framework.md",
    "chars": 5284,
    "preview": "---\ntitle: \"Beta skills framework: parallel skills with -beta suffix for safe rollouts\"\ncategory: skill-design\ndate: 202"
  },
  {
    "path": "docs/solutions/skill-design/claude-permissions-optimizer-classification-fix.md",
    "chars": 16855,
    "preview": "---\ntitle: Classification bugs in claude-permissions-optimizer extract-commands script\ncategory: logic-errors\ndate: 2026"
  },
  {
    "path": "docs/solutions/skill-design/compound-refresh-skill-improvements.md",
    "chars": 8372,
    "preview": "---\ntitle: \"ce:compound-refresh skill redesign for autonomous maintenance without live user context\"\ncategory: skill-des"
  },
  {
    "path": "docs/solutions/skill-design/script-first-skill-architecture.md",
    "chars": 5344,
    "preview": "---\ntitle: \"Offload data processing to bundled scripts to reduce token consumption\"\ncategory: \"skill-design\"\ndate: \"2026"
  },
  {
    "path": "docs/solutions/workflow/manual-release-please-github-releases.md",
    "chars": 8239,
    "preview": "---\ntitle: \"Manual release-please with GitHub Releases for multi-component plugin and marketplace releases\"\ncategory: wo"
  },
  {
    "path": "docs/specs/claude-code.md",
    "chars": 4517,
    "preview": "# Claude Code Plugin Spec\n\nLast verified: 2026-01-21\n\n## Primary sources\n\n```\nhttps://docs.claude.com/en/docs/claude-cod"
  },
  {
    "path": "docs/specs/codex.md",
    "chars": 4100,
    "preview": "# Codex Spec (Config, Prompts, Skills, MCP)\n\nLast verified: 2026-01-21\n\n## Primary sources\n\n```\nhttps://developers.opena"
  },
  {
    "path": "docs/specs/copilot.md",
    "chars": 4169,
    "preview": "# GitHub Copilot Spec (Agents, Skills, MCP)\n\nLast verified: 2026-02-14\n\n## Primary sources\n\n```\nhttps://docs.github.com/"
  },
  {
    "path": "docs/specs/cursor.md",
    "chars": 3223,
    "preview": "# Cursor Spec (Rules, Commands, Skills, MCP)\n\nLast verified: 2026-02-12\n\n## Primary sources\n\n```\nhttps://docs.cursor.com"
  },
  {
    "path": "docs/specs/gemini.md",
    "chars": 3692,
    "preview": "# Gemini CLI Spec (GEMINI.md, Commands, Skills, MCP, Settings)\n\nLast verified: 2026-02-14\n\n## Primary sources\n\n```\nhttps"
  },
  {
    "path": "docs/specs/kiro.md",
    "chars": 6006,
    "preview": "# Kiro CLI Spec (Custom Agents, Skills, Steering, MCP, Settings)\n\nLast verified: 2026-02-17\n\n## Primary sources\n\n```\nhtt"
  },
  {
    "path": "docs/specs/opencode.md",
    "chars": 3384,
    "preview": "# OpenCode Spec (Config, Agents, Plugins)\n\nLast verified: 2026-01-21\n\n## Primary sources\n\n```\nhttps://opencode.ai/docs/c"
  },
  {
    "path": "docs/specs/windsurf.md",
    "chars": 13004,
    "preview": "# Windsurf Editor Global Configuration Guide\n\n> **Purpose**: Technical reference for programmatically creating and manag"
  },
  {
    "path": "package.json",
    "chars": 1025,
    "preview": "{\n  \"name\": \"@every-env/compound-plugin\",\n  \"version\": \"2.46.0\",\n  \"type\": \"module\",\n  \"private\": false,\n  \"bin\": {\n    "
  },
  {
    "path": "plugins/coding-tutor/.claude-plugin/plugin.json",
    "chars": 310,
    "preview": "{\n  \"name\": \"coding-tutor\",\n  \"version\": \"1.2.1\",\n  \"description\": \"Personalized coding tutorials that use your actual c"
  },
  {
    "path": "plugins/coding-tutor/.cursor-plugin/plugin.json",
    "chars": 563,
    "preview": "{\n  \"name\": \"coding-tutor\",\n  \"displayName\": \"Coding Tutor\",\n  \"version\": \"1.2.1\",\n  \"description\": \"Personalized coding"
  },
  {
    "path": "plugins/coding-tutor/README.md",
    "chars": 1810,
    "preview": "# Coding Tutor\n\nYour personal AI tutor that creates tutorials tailored to you - using real code from your projects, buil"
  },
  {
    "path": "plugins/coding-tutor/commands/quiz-me.md",
    "chars": 37,
    "preview": "Quiz me using the coding-tutor skill\n"
  },
  {
    "path": "plugins/coding-tutor/commands/sync-tutorials.md",
    "chars": 910,
    "preview": "# Sync Coding Tutor Tutorials\n\nCommit and push your tutorials to the GitHub repository for backup and mobile reading.\n\n#"
  },
  {
    "path": "plugins/coding-tutor/commands/teach-me.md",
    "chars": 48,
    "preview": "Teach me something using the coding-tutor skill\n"
  },
  {
    "path": "plugins/coding-tutor/skills/coding-tutor/SKILL.md",
    "chars": 12011,
    "preview": "---\nname: coding-tutor\ndescription: Personalized coding tutorials that build on your existing knowledge and use your act"
  },
  {
    "path": "plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py",
    "chars": 6392,
    "preview": "#!/usr/bin/env python3\n\"\"\"\nCreate a new coding tutorial template with proper frontmatter.\n\nUsage:\n    python create_tuto"
  },
  {
    "path": "plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py",
    "chars": 6398,
    "preview": "#!/usr/bin/env python3\n\"\"\"\nIndex all tutorials by extracting their YAML frontmatter.\n\nUsage:\n    python index_tutorials."
  },
  {
    "path": "plugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py",
    "chars": 5536,
    "preview": "#!/usr/bin/env python3\n\"\"\"\nPrioritize tutorials for quizzing based on spaced repetition.\n\nUsage: python3 quiz_priority.p"
  },
  {
    "path": "plugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py",
    "chars": 3660,
    "preview": "#!/usr/bin/env python3\n\"\"\"\nSet up the central tutorials repository for coding-tutor.\n\nUsage:\n    python setup_tutorials."
  },
  {
    "path": "plugins/compound-engineering/.claude-plugin/plugin.json",
    "chars": 869,
    "preview": "{\n  \"name\": \"compound-engineering\",\n  \"version\": \"2.46.0\",\n  \"description\": \"AI-powered development tools for code revie"
  },
  {
    "path": "plugins/compound-engineering/.cursor-plugin/plugin.json",
    "chars": 854,
    "preview": "{\n  \"name\": \"compound-engineering\",\n  \"displayName\": \"Compound Engineering\",\n  \"version\": \"2.46.0\",\n  \"description\": \"AI"
  },
  {
    "path": "plugins/compound-engineering/.mcp.json",
    "chars": 189,
    "preview": "{\n  \"mcpServers\": {\n    \"context7\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.context7.com/mcp\",\n      \"headers\""
  },
  {
    "path": "plugins/compound-engineering/AGENTS.md",
    "chars": 7092,
    "preview": "# Plugin Instructions\n\nThese instructions apply when working under `plugins/compound-engineering/`.\nThey supplement the "
  },
  {
    "path": "plugins/compound-engineering/CHANGELOG.md",
    "chars": 35432,
    "preview": "# Changelog\n\nThis file is no longer the canonical changelog for compound-engineering releases.\n\nHistorical entries are p"
  },
  {
    "path": "plugins/compound-engineering/CLAUDE.md",
    "chars": 11,
    "preview": "@AGENTS.md\n"
  },
  {
    "path": "plugins/compound-engineering/LICENSE",
    "chars": 1072,
    "preview": "MIT License\n\nCopyright (c) 2025 Kieran Klaassen\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "plugins/compound-engineering/README.md",
    "chars": 9388,
    "preview": "# Compounding Engineering Plugin\n\nAI-powered development tools that get smarter with every use. Make each unit of engine"
  },
  {
    "path": "plugins/compound-engineering/agents/design/design-implementation-reviewer.md",
    "chars": 5152,
    "preview": "---\nname: design-implementation-reviewer\ndescription: \"Visually compares live UI implementation against Figma designs an"
  },
  {
    "path": "plugins/compound-engineering/agents/design/design-iterator.md",
    "chars": 11181,
    "preview": "---\nname: design-iterator\ndescription: \"Iteratively refines UI design through N screenshot-analyze-improve cycles. Use P"
  },
  {
    "path": "plugins/compound-engineering/agents/design/figma-design-sync.md",
    "chars": 9190,
    "preview": "---\nname: figma-design-sync\ndescription: \"Detects and fixes visual differences between a web implementation and its Figm"
  },
  {
    "path": "plugins/compound-engineering/agents/docs/ankane-readme-writer.md",
    "chars": 3502,
    "preview": "---\nname: ankane-readme-writer\ndescription: \"Creates or updates README files following Ankane-style template for Ruby ge"
  },
  {
    "path": "plugins/compound-engineering/agents/research/best-practices-researcher.md",
    "chars": 7824,
    "preview": "---\nname: best-practices-researcher\ndescription: \"Researches and synthesizes external best practices, documentation, and"
  },
  {
    "path": "plugins/compound-engineering/agents/research/framework-docs-researcher.md",
    "chars": 6010,
    "preview": "---\nname: framework-docs-researcher\ndescription: \"Gathers comprehensive documentation and best practices for frameworks,"
  },
  {
    "path": "plugins/compound-engineering/agents/research/git-history-analyzer.md",
    "chars": 4111,
    "preview": "---\nname: git-history-analyzer\ndescription: \"Performs archaeological analysis of git history to trace code evolution, id"
  },
  {
    "path": "plugins/compound-engineering/agents/research/issue-intelligence-analyst.md",
    "chars": 15610,
    "preview": "---\nname: issue-intelligence-analyst\ndescription: \"Fetches and analyzes GitHub issues to surface recurring themes, pain "
  },
  {
    "path": "plugins/compound-engineering/agents/research/learnings-researcher.md",
    "chars": 11050,
    "preview": "---\nname: learnings-researcher\ndescription: \"Searches docs/solutions/ for relevant past solutions by frontmatter metadat"
  },
  {
    "path": "plugins/compound-engineering/agents/research/repo-research-analyst.md",
    "chars": 5945,
    "preview": "---\nname: repo-research-analyst\ndescription: \"Conducts thorough research on repository structure, documentation, convent"
  },
  {
    "path": "plugins/compound-engineering/agents/review/agent-native-reviewer.md",
    "chars": 8439,
    "preview": "---\nname: agent-native-reviewer\ndescription: \"Reviews code to ensure agent-native parity — any action a user can take, a"
  },
  {
    "path": "plugins/compound-engineering/agents/review/architecture-strategist.md",
    "chars": 4428,
    "preview": "---\nname: architecture-strategist\ndescription: \"Analyzes code changes from an architectural perspective for pattern comp"
  },
  {
    "path": "plugins/compound-engineering/agents/review/code-simplicity-reviewer.md",
    "chars": 4205,
    "preview": "---\nname: code-simplicity-reviewer\ndescription: \"Final review pass to ensure code is as simple and minimal as possible. "
  },
  {
    "path": "plugins/compound-engineering/agents/review/data-integrity-guardian.md",
    "chars": 4192,
    "preview": "---\nname: data-integrity-guardian\ndescription: \"Reviews database migrations, data models, and persistent data code for s"
  },
  {
    "path": "plugins/compound-engineering/agents/review/data-migration-expert.md",
    "chars": 4988,
    "preview": "---\nname: data-migration-expert\ndescription: \"Validates data migrations, backfills, and production data transformations "
  },
  {
    "path": "plugins/compound-engineering/agents/review/deployment-verification-agent.md",
    "chars": 5718,
    "preview": "---\nname: deployment-verification-agent\ndescription: \"Produces Go/No-Go deployment checklists with SQL verification quer"
  },
  {
    "path": "plugins/compound-engineering/agents/review/dhh-rails-reviewer.md",
    "chars": 4120,
    "preview": "---\nname: dhh-rails-reviewer\ndescription: \"Brutally honest Rails code review from DHH's perspective. Use when reviewing "
  },
  {
    "path": "plugins/compound-engineering/agents/review/julik-frontend-races-reviewer.md",
    "chars": 11114,
    "preview": "---\nname: julik-frontend-races-reviewer\ndescription: \"Reviews JavaScript and Stimulus code for race conditions, timing i"
  },
  {
    "path": "plugins/compound-engineering/agents/review/kieran-python-reviewer.md",
    "chars": 5570,
    "preview": "---\nname: kieran-python-reviewer\ndescription: \"Reviews Python code with an extremely high quality bar for Pythonic patte"
  },
  {
    "path": "plugins/compound-engineering/agents/review/kieran-rails-reviewer.md",
    "chars": 4987,
    "preview": "---\nname: kieran-rails-reviewer\ndescription: \"Reviews Rails code with an extremely high quality bar for conventions, cla"
  },
  {
    "path": "plugins/compound-engineering/agents/review/kieran-typescript-reviewer.md",
    "chars": 5457,
    "preview": "---\nname: kieran-typescript-reviewer\ndescription: \"Reviews TypeScript code with an extremely high quality bar for type s"
  },
  {
    "path": "plugins/compound-engineering/agents/review/pattern-recognition-specialist.md",
    "chars": 4583,
    "preview": "---\nname: pattern-recognition-specialist\ndescription: \"Analyzes code for design patterns, anti-patterns, naming conventi"
  },
  {
    "path": "plugins/compound-engineering/agents/review/performance-oracle.md",
    "chars": 5804,
    "preview": "---\nname: performance-oracle\ndescription: \"Analyzes code for performance bottlenecks, algorithmic complexity, database q"
  },
  {
    "path": "plugins/compound-engineering/agents/review/schema-drift-detector.md",
    "chars": 4943,
    "preview": "---\nname: schema-drift-detector\ndescription: \"Detects unrelated schema.rb changes in PRs by cross-referencing against in"
  },
  {
    "path": "plugins/compound-engineering/agents/review/security-sentinel.md",
    "chars": 5687,
    "preview": "---\nname: security-sentinel\ndescription: \"Performs security audits for vulnerabilities, input validation, auth/authz, ha"
  },
  {
    "path": "plugins/compound-engineering/agents/workflow/bug-reproduction-validator.md",
    "chars": 4837,
    "preview": "---\nname: bug-reproduction-validator\ndescription: \"Systematically reproduces and validates bug reports to confirm whethe"
  },
  {
    "path": "plugins/compound-engineering/agents/workflow/lint.md",
    "chars": 796,
    "preview": "---\nname: lint\ndescription: \"Use this agent when you need to run linting and code quality checks on Ruby and ERB files. "
  },
  {
    "path": "plugins/compound-engineering/agents/workflow/pr-comment-resolver.md",
    "chars": 3925,
    "preview": "---\nname: pr-comment-resolver\ndescription: \"Addresses PR review comments by implementing requested changes and reporting"
  },
  {
    "path": "plugins/compound-engineering/agents/workflow/spec-flow-analyzer.md",
    "chars": 6432,
    "preview": "---\nname: spec-flow-analyzer\ndescription: \"Analyzes specifications and feature descriptions for user flow completeness a"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/SKILL.md",
    "chars": 25143,
    "preview": "---\nname: agent-browser\ndescription: Browser automation using Vercel's agent-browser CLI. Use when you need to interact "
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/authentication.md",
    "chars": 8409,
    "preview": "# Authentication Patterns\n\nLogin flows, session persistence, OAuth, 2FA, and authenticated browsing.\n\n**Related**: [comm"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/commands.md",
    "chars": 10063,
    "preview": "# Command Reference\n\nComplete reference for all agent-browser commands. For quick start and common patterns, see SKILL.m"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/profiling.md",
    "chars": 3400,
    "preview": "# Profiling\n\nCapture Chrome DevTools performance profiles during browser automation for performance analysis.\n\n**Related"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/proxy-support.md",
    "chars": 4971,
    "preview": "# Proxy Support\n\nProxy configuration for geo-testing, rate limiting avoidance, and corporate environments.\n\n**Related**:"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/session-management.md",
    "chars": 4337,
    "preview": "# Session Management\n\nMultiple isolated browser sessions with state persistence and concurrent browsing.\n\n**Related**: ["
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/snapshot-refs.md",
    "chars": 4249,
    "preview": "# Snapshot and Refs\n\nCompact element references that reduce context usage dramatically for AI agents.\n\n**Related**: [com"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/references/video-recording.md",
    "chars": 3569,
    "preview": "# Video Recording\n\nCapture browser automation as video for debugging, documentation, or verification.\n\n**Related**: [com"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/templates/authenticated-session.sh",
    "chars": 3678,
    "preview": "#!/bin/bash\n# Template: Authenticated Session Workflow\n# Purpose: Login once, save state, reuse for subsequent runs\n# Us"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/templates/capture-workflow.sh",
    "chars": 1832,
    "preview": "#!/bin/bash\n# Template: Content Capture Workflow\n# Purpose: Extract content from web pages (text, screenshots, PDF)\n# Us"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-browser/templates/form-automation.sh",
    "chars": 1838,
    "preview": "#!/bin/bash\n# Template: Form Automation Workflow\n# Purpose: Fill and submit web forms with validation\n# Usage: ./form-au"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/SKILL.md",
    "chars": 23171,
    "preview": "---\nname: agent-native-architecture\ndescription: Build applications where agents are first-class citizens. Use this skil"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/action-parity-discipline.md",
    "chars": 11004,
    "preview": "<overview>\nA structured discipline for ensuring agents can do everything users can do. Every UI action should have an eq"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/agent-execution-patterns.md",
    "chars": 13289,
    "preview": "<overview>\nAgent execution patterns for building robust agent loops. This covers how agents signal completion, track par"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/agent-native-testing.md",
    "chars": 16721,
    "preview": "<overview>\nTesting agent-native apps requires different approaches than traditional unit testing. You're testing whether"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/architecture-patterns.md",
    "chars": 15415,
    "preview": "<overview>\nArchitectural patterns for building agent-native systems. These patterns emerge from the five core principles"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/dynamic-context-injection.md",
    "chars": 9606,
    "preview": "<overview>\nHow to inject dynamic runtime context into agent system prompts. The agent needs to know what exists in the a"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/files-universal-interface.md",
    "chars": 9894,
    "preview": "<overview>\nFiles are the universal interface for agent-native applications. Agents are naturally fluent with file operat"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md",
    "chars": 11768,
    "preview": "<overview>\nStart with pure primitives: bash, file operations, basic storage. This proves the architecture works and reve"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/mcp-tool-design.md",
    "chars": 15642,
    "preview": "<overview>\nHow to design MCP tools following prompt-native principles. Tools should be primitives that enable capability"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/mobile-patterns.md",
    "chars": 25481,
    "preview": "<overview>\nMobile is a first-class platform for agent-native apps. It has unique constraints and opportunities. This gui"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/product-implications.md",
    "chars": 12950,
    "preview": "<overview>\nAgent-native architecture has consequences for how products feel, not just how they're built. This document c"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/refactoring-to-prompt-native.md",
    "chars": 8554,
    "preview": "<overview>\nHow to refactor existing agent code to follow prompt-native principles. The goal: move behavior from code int"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/self-modification.md",
    "chars": 7846,
    "preview": "<overview>\nSelf-modification is the advanced tier of agent native engineering: agents that can evolve their own code, pr"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/shared-workspace-architecture.md",
    "chars": 19894,
    "preview": "<overview>\nAgents and users should work in the same data space, not separate sandboxes. When the agent writes a file, th"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-architecture/references/system-prompt-design.md",
    "chars": 6506,
    "preview": "<overview>\nHow to write system prompts for prompt-native agents. The system prompt is where features live—it defines beh"
  },
  {
    "path": "plugins/compound-engineering/skills/agent-native-audit/SKILL.md",
    "chars": 8163,
    "preview": "---\nname: agent-native-audit\ndescription: Run comprehensive agent-native architecture review with scored principles\nargu"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/SKILL.md",
    "chars": 4863,
    "preview": "---\nname: andrew-kane-gem-writer\ndescription: This skill should be used when writing Ruby gems following Andrew Kane's p"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/references/database-adapters.md",
    "chars": 4348,
    "preview": "# Database Adapter Patterns\n\n## Abstract Base Class Pattern\n\n```ruby\n# lib/strong_migrations/adapters/abstract_adapter.r"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/references/module-organization.md",
    "chars": 2160,
    "preview": "# Module Organization Patterns\n\n## Simple Gem Layout\n\n```\nlib/\n├── gemname.rb          # Entry point, config, errors\n└──"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/references/rails-integration.md",
    "chars": 3792,
    "preview": "# Rails Integration Patterns\n\n## The Golden Rule\n\n**Never require Rails gems directly.** This causes loading order issue"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/references/resources.md",
    "chars": 5380,
    "preview": "# Andrew Kane Resources\n\n## Primary Documentation\n\n- **Gem Patterns Article**: https://ankane.org/gem-patterns\n  - Kane'"
  },
  {
    "path": "plugins/compound-engineering/skills/andrew-kane-gem-writer/references/testing-patterns.md",
    "chars": 4734,
    "preview": "# Testing Patterns\n\n## Minitest Setup\n\nKane exclusively uses Minitest—never RSpec.\n\n```ruby\n# test/test_helper.rb\nrequir"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-brainstorm/SKILL.md",
    "chars": 18444,
    "preview": "---\nname: ce:brainstorm\ndescription: 'Explore requirements and approaches through collaborative dialogue before writing "
  },
  {
    "path": "plugins/compound-engineering/skills/ce-compound/SKILL.md",
    "chars": 14666,
    "preview": "---\nname: ce:compound\ndescription: Document a recently solved problem to compound your team's knowledge\nargument-hint: \""
  },
  {
    "path": "plugins/compound-engineering/skills/ce-compound-refresh/SKILL.md",
    "chars": 32509,
    "preview": "---\nname: ce:compound-refresh\ndescription: Refresh stale or drifting learnings and pattern docs in docs/solutions/ by re"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-ideate/SKILL.md",
    "chars": 16839,
    "preview": "---\nname: ce:ideate\ndescription: \"Generate and critically evaluate grounded improvement ideas for the current project. U"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-plan/SKILL.md",
    "chars": 22671,
    "preview": "---\nname: ce:plan\ndescription: Transform feature descriptions into well-structured project plans following conventions\na"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-plan-beta/SKILL.md",
    "chars": 29819,
    "preview": "---\nname: ce:plan-beta\ndescription: \"[BETA] Transform feature descriptions or requirements into structured implementatio"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-review/SKILL.md",
    "chars": 19070,
    "preview": "---\nname: ce:review\ndescription: Perform exhaustive code reviews using multi-agent analysis, ultra-thinking, and worktre"
  },
  {
    "path": "plugins/compound-engineering/skills/ce-work/SKILL.md",
    "chars": 22484,
    "preview": "---\nname: ce:work\ndescription: Execute work plans efficiently while maintaining quality and finishing features\nargument-"
  },
  {
    "path": "plugins/compound-engineering/skills/changelog/SKILL.md",
    "chars": 4666,
    "preview": "---\nname: changelog\ndescription: Create engaging changelogs for recent merges to main branch\nargument-hint: \"[optional: "
  },
  {
    "path": "plugins/compound-engineering/skills/claude-permissions-optimizer/SKILL.md",
    "chars": 8158,
    "preview": "---\nname: claude-permissions-optimizer\ncontext: fork\ndescription: Optimize Claude Code permissions by finding safe Bash "
  },
  {
    "path": "plugins/compound-engineering/skills/claude-permissions-optimizer/scripts/extract-commands.mjs",
    "chars": 25614,
    "preview": "#!/usr/bin/env node\n\n// Extracts, normalizes, and pre-classifies Bash commands from Claude Code sessions.\n// Filters aga"
  },
  {
    "path": "plugins/compound-engineering/skills/compound-docs/SKILL.md",
    "chars": 14603,
    "preview": "---\nname: compound-docs\ndescription: Capture solved problems as categorized documentation with YAML frontmatter for fast"
  },
  {
    "path": "plugins/compound-engineering/skills/compound-docs/assets/critical-pattern-template.md",
    "chars": 871,
    "preview": "# Critical Pattern Template\n\nUse this template when adding a pattern to `docs/solutions/patterns/critical-patterns.md`:\n"
  },
  {
    "path": "plugins/compound-engineering/skills/compound-docs/assets/resolution-template.md",
    "chars": 3162,
    "preview": "---\nmodule: [Module name or \"System\" for system-wide]\ndate: [YYYY-MM-DD]\nproblem_type: [build_error|test_failure|runtime"
  },
  {
    "path": "plugins/compound-engineering/skills/compound-docs/references/yaml-schema.md",
    "chars": 3078,
    "preview": "# YAML Frontmatter Schema\n\n**See `.claude/skills/codify-docs/schema.yaml` for the complete schema specification.**\n\n## R"
  },
  {
    "path": "plugins/compound-engineering/skills/compound-docs/schema.yaml",
    "chars": 6902,
    "preview": "# CORA Documentation Schema\n# This schema MUST be validated before writing any documentation file\n\nrequired_fields:\n  mo"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skill/SKILL.md",
    "chars": 313,
    "preview": "---\nname: create-agent-skill\ndescription: Create or edit Claude Code skills with expert guidance on structure and best p"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/SKILL.md",
    "chars": 9436,
    "preview": "---\nname: create-agent-skills\ndescription: Expert guidance for creating Claude Code skills and slash commands. Use when "
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/api-security.md",
    "chars": 6189,
    "preview": "<overview>\nWhen building skills that make API calls requiring credentials (API keys, tokens, secrets), follow this proto"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/be-clear-and-direct.md",
    "chars": 13000,
    "preview": "<golden_rule>\nShow your skill to someone with minimal context and ask them to follow the instructions. If they're confus"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/best-practices.md",
    "chars": 9242,
    "preview": "# Skill Authoring Best Practices\n\nSource: [platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices](htt"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/common-patterns.md",
    "chars": 14375,
    "preview": "<overview>\nThis reference documents common patterns for skill authoring, including templates, examples, terminology cons"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/core-principles.md",
    "chars": 12689,
    "preview": "<overview>\nCore principles guide skill authoring decisions. These principles ensure skills are efficient, effective, and"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/executable-code.md",
    "chars": 4330,
    "preview": "<when_to_use_scripts>\nEven if Claude could write a script, pre-made scripts offer advantages:\n- More reliable than gener"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/iteration-and-testing.md",
    "chars": 13464,
    "preview": "<overview>\nSkills improve through iteration and testing. This reference covers evaluation-driven development, Claude A/B"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/official-spec.md",
    "chars": 4993,
    "preview": "# Official Skill Specification (2026)\n\nSource: [code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills)\n"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/recommended-structure.md",
    "chars": 3942,
    "preview": "# Recommended Skill Structure\n\nThe optimal structure for complex skills separates routing, workflows, and knowledge.\n\n<s"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/skill-structure.md",
    "chars": 4407,
    "preview": "# Skill Structure Reference\n\nSkills have three structural components: YAML frontmatter (metadata), standard markdown bod"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/using-scripts.md",
    "chars": 2975,
    "preview": "# Using Scripts in Skills\n\n<purpose>\nScripts are executable code that Claude runs as-is rather than regenerating each ti"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/using-templates.md",
    "chars": 2882,
    "preview": "# Using Templates in Skills\n\n<purpose>\nTemplates are reusable output structures that Claude copies and fills in. They en"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/references/workflows-and-validation.md",
    "chars": 11815,
    "preview": "<overview>\nThis reference covers patterns for complex workflows, validation loops, and feedback cycles in skill authorin"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/templates/router-skill.md",
    "chars": 1494,
    "preview": "---\nname: {{SKILL_NAME}}\ndescription: {{What it does}} Use when {{trigger conditions}}.\n---\n\n<essential_principles>\n## {"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/templates/simple-skill.md",
    "chars": 636,
    "preview": "---\nname: {{SKILL_NAME}}\ndescription: {{What it does}} Use when {{trigger conditions}}.\n---\n\n<objective>\n{{Clear stateme"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/add-reference.md",
    "chars": 2264,
    "preview": "# Workflow: Add a Reference to Existing Skill\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/reco"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/add-script.md",
    "chars": 2155,
    "preview": "# Workflow: Add a Script to a Skill\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/using-scripts."
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/add-template.md",
    "chars": 1922,
    "preview": "# Workflow: Add a Template to a Skill\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/using-templa"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/add-workflow.md",
    "chars": 3141,
    "preview": "# Workflow: Add a Workflow to Existing Skill\n\n## Interaction Method\n\nIf `AskUserQuestion` is available, use it for all p"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/audit-skill.md",
    "chars": 3546,
    "preview": "# Workflow: Audit a Skill\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/recommended-structure.md"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/create-domain-expertise-skill.md",
    "chars": 17886,
    "preview": "# Workflow: Create Exhaustive Domain Expertise Skill\n\n<objective>\nBuild a comprehensive execution skill that does real w"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/create-new-skill.md",
    "chars": 5932,
    "preview": "# Workflow: Create a New Skill\n\n## Interaction Method\n\nIf `AskUserQuestion` is available, use it for all prompts below.\n"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/get-guidance.md",
    "chars": 3048,
    "preview": "# Workflow: Get Guidance on Skill Design\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/core-prin"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/upgrade-to-router.md",
    "chars": 3781,
    "preview": "# Workflow: Upgrade Skill to Router Pattern\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/recomm"
  },
  {
    "path": "plugins/compound-engineering/skills/create-agent-skills/workflows/verify-skill.md",
    "chars": 5178,
    "preview": "# Workflow: Verify Skill Content Accuracy\n\n<required_reading>\n**Read these reference files NOW:**\n1. references/skill-st"
  },
  {
    "path": "plugins/compound-engineering/skills/deepen-plan/SKILL.md",
    "chars": 17739,
    "preview": "---\nname: deepen-plan\ndescription: Enhance a plan with parallel research agents for each section to add depth, best prac"
  },
  {
    "path": "plugins/compound-engineering/skills/deepen-plan-beta/SKILL.md",
    "chars": 19398,
    "preview": "---\nname: deepen-plan-beta\ndescription: \"[BETA] Stress-test an existing implementation plan and selectively strengthen w"
  },
  {
    "path": "plugins/compound-engineering/skills/deploy-docs/SKILL.md",
    "chars": 2731,
    "preview": "---\nname: deploy-docs\ndescription: Validate and prepare documentation for GitHub Pages deployment\ndisable-model-invocati"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/SKILL.md",
    "chars": 6812,
    "preview": "---\nname: dhh-rails-style\ndescription: This skill should be used when writing Ruby and Rails code in DHH's distinctive 3"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/architecture.md",
    "chars": 13122,
    "preview": "# Architecture - DHH Rails Style\n\n<routing>\n## Routing\n\nEverything maps to CRUD. Nested resources for related actions:\n\n"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/controllers.md",
    "chars": 6395,
    "preview": "# Controllers - DHH Rails Style\n\n<rest_mapping>\n## Everything Maps to CRUD\n\nCustom actions become new resources. Instead"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/frontend.md",
    "chars": 10691,
    "preview": "# Frontend - DHH Rails Style\n\n<turbo_patterns>\n## Turbo Patterns\n\n**Turbo Streams** for partial updates:\n```erb\n<%# app/"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/gems.md",
    "chars": 5668,
    "preview": "# Gems - DHH Rails Style\n\n<what_they_use>\n## What 37signals Uses\n\n**Core Rails stack:**\n- turbo-rails, stimulus-rails, i"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/models.md",
    "chars": 7504,
    "preview": "# Models - DHH Rails Style\n\n<model_concerns>\n## Concerns for Horizontal Behavior\n\nModels heavily use concerns. A typical"
  },
  {
    "path": "plugins/compound-engineering/skills/dhh-rails-style/references/testing.md",
    "chars": 6999,
    "preview": "# Testing - DHH Rails Style\n\n## Core Philosophy\n\n\"Minitest with fixtures - simple, fast, deterministic.\" The approach pr"
  },
  {
    "path": "plugins/compound-engineering/skills/document-review/SKILL.md",
    "chars": 3803,
    "preview": "---\nname: document-review\ndescription: This skill should be used to refine requirements or plan documents before proceed"
  },
  {
    "path": "plugins/compound-engineering/skills/dspy-ruby/SKILL.md",
    "chars": 23392,
    "preview": "---\nname: dspy-ruby\ndescription: Build type-safe LLM applications with DSPy.rb — Ruby's programmatic prompt framework wi"
  },
  {
    "path": "plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb",
    "chars": 6844,
    "preview": "# frozen_string_literal: true\n\n# =============================================================================\n# DSPy.rb"
  },
  {
    "path": "plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb",
    "chars": 7964,
    "preview": "# frozen_string_literal: true\n\n# =============================================================================\n# DSPy.rb"
  },
  {
    "path": "plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb",
    "chars": 6626,
    "preview": "# frozen_string_literal: true\n\n# =============================================================================\n# DSPy.rb"
  },
  {
    "path": "plugins/compound-engineering/skills/dspy-ruby/references/core-concepts.md",
    "chars": 17911,
    "preview": "# DSPy.rb Core Concepts\n\n## Signatures\n\nSignatures define the interface between application code and language models. Th"
  }
]

// ... and 176 more files (download for full content)

About this extraction

This page contains the full source code of the EveryInc/compound-engineering-plugin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 376 files (2.4 MB), approximately 637.2k tokens, and a symbol index with 559 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!