@every-env/compound-plugin 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/deploy-docs.yml +3 -3
- package/.github/workflows/publish.yml +37 -0
- package/README.md +12 -3
- package/docs/index.html +13 -13
- package/docs/pages/changelog.html +39 -0
- package/docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md +143 -0
- package/docs/plans/2026-02-08-feat-simplify-plugin-settings-plan.md +195 -0
- package/docs/plans/2026-02-08-refactor-reduce-plugin-context-token-usage-plan.md +212 -0
- package/docs/plans/2026-02-09-refactor-dspy-ruby-skill-update-plan.md +104 -0
- package/docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md +306 -0
- package/docs/specs/cursor.md +85 -0
- package/package.json +1 -1
- package/plugins/compound-engineering/.claude-plugin/plugin.json +2 -2
- package/plugins/compound-engineering/CHANGELOG.md +64 -0
- package/plugins/compound-engineering/README.md +5 -3
- package/plugins/compound-engineering/agents/design/design-implementation-reviewer.md +16 -1
- package/plugins/compound-engineering/agents/design/design-iterator.md +28 -1
- package/plugins/compound-engineering/agents/design/figma-design-sync.md +19 -1
- package/plugins/compound-engineering/agents/docs/ankane-readme-writer.md +16 -1
- package/plugins/compound-engineering/agents/research/best-practices-researcher.md +16 -1
- package/plugins/compound-engineering/agents/research/framework-docs-researcher.md +16 -1
- package/plugins/compound-engineering/agents/research/git-history-analyzer.md +16 -1
- package/plugins/compound-engineering/agents/research/learnings-researcher.md +22 -1
- package/plugins/compound-engineering/agents/research/repo-research-analyst.md +22 -1
- package/plugins/compound-engineering/agents/review/agent-native-reviewer.md +16 -1
- package/plugins/compound-engineering/agents/review/architecture-strategist.md +16 -1
- package/plugins/compound-engineering/agents/review/code-simplicity-reviewer.md +16 -1
- package/plugins/compound-engineering/agents/review/data-integrity-guardian.md +16 -1
- package/plugins/compound-engineering/agents/review/data-migration-expert.md +16 -1
- package/plugins/compound-engineering/agents/review/deployment-verification-agent.md +16 -1
- package/plugins/compound-engineering/agents/review/dhh-rails-reviewer.md +22 -1
- package/plugins/compound-engineering/agents/review/julik-frontend-races-reviewer.md +20 -21
- package/plugins/compound-engineering/agents/review/kieran-python-reviewer.md +30 -1
- package/plugins/compound-engineering/agents/review/kieran-rails-reviewer.md +30 -1
- package/plugins/compound-engineering/agents/review/kieran-typescript-reviewer.md +30 -1
- package/plugins/compound-engineering/agents/review/pattern-recognition-specialist.md +16 -1
- package/plugins/compound-engineering/agents/review/performance-oracle.md +28 -1
- package/plugins/compound-engineering/agents/review/schema-drift-detector.md +16 -1
- package/plugins/compound-engineering/agents/review/security-sentinel.md +22 -1
- package/plugins/compound-engineering/agents/workflow/bug-reproduction-validator.md +16 -1
- package/plugins/compound-engineering/agents/workflow/every-style-editor.md +1 -1
- package/plugins/compound-engineering/agents/workflow/pr-comment-resolver.md +16 -1
- package/plugins/compound-engineering/agents/workflow/spec-flow-analyzer.md +22 -1
- package/plugins/compound-engineering/commands/agent-native-audit.md +1 -0
- package/plugins/compound-engineering/commands/changelog.md +1 -0
- package/plugins/compound-engineering/commands/create-agent-skill.md +1 -0
- package/plugins/compound-engineering/commands/deploy-docs.md +1 -0
- package/plugins/compound-engineering/commands/generate_command.md +1 -0
- package/plugins/compound-engineering/commands/heal-skill.md +1 -0
- package/plugins/compound-engineering/commands/lfg.md +1 -0
- package/plugins/compound-engineering/commands/report-bug.md +1 -0
- package/plugins/compound-engineering/commands/reproduce-bug.md +1 -0
- package/plugins/compound-engineering/commands/resolve_parallel.md +1 -0
- package/plugins/compound-engineering/commands/slfg.md +1 -0
- package/plugins/compound-engineering/commands/{xcode-test.md → test-xcode.md} +2 -1
- package/plugins/compound-engineering/commands/triage.md +1 -0
- package/plugins/compound-engineering/commands/workflows/brainstorm.md +6 -1
- package/plugins/compound-engineering/commands/workflows/compound.md +1 -0
- package/plugins/compound-engineering/commands/workflows/review.md +23 -21
- package/plugins/compound-engineering/commands/workflows/work.md +29 -15
- package/plugins/compound-engineering/skills/compound-docs/SKILL.md +1 -0
- package/plugins/compound-engineering/skills/dspy-ruby/SKILL.md +539 -396
- package/plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb +159 -331
- package/plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb +210 -236
- package/plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb +173 -95
- package/plugins/compound-engineering/skills/dspy-ruby/references/core-concepts.md +552 -143
- package/plugins/compound-engineering/skills/dspy-ruby/references/observability.md +366 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/optimization.md +440 -460
- package/plugins/compound-engineering/skills/dspy-ruby/references/providers.md +305 -225
- package/plugins/compound-engineering/skills/dspy-ruby/references/toolsets.md +502 -0
- package/plugins/compound-engineering/skills/file-todos/SKILL.md +1 -0
- package/plugins/compound-engineering/skills/orchestrating-swarms/SKILL.md +1 -0
- package/plugins/compound-engineering/skills/setup/SKILL.md +168 -0
- package/plugins/compound-engineering/skills/skill-creator/SKILL.md +1 -0
- package/src/commands/convert.ts +10 -5
- package/src/commands/install.ts +10 -5
- package/src/converters/claude-to-codex.ts +9 -3
- package/src/converters/claude-to-cursor.ts +166 -0
- package/src/converters/claude-to-droid.ts +174 -0
- package/src/converters/claude-to-opencode.ts +9 -2
- package/src/parsers/claude.ts +4 -0
- package/src/targets/cursor.ts +48 -0
- package/src/targets/droid.ts +50 -0
- package/src/targets/index.ts +18 -0
- package/src/types/claude.ts +2 -0
- package/src/types/cursor.ts +29 -0
- package/src/types/droid.ts +20 -0
- package/tests/claude-parser.test.ts +24 -2
- package/tests/codex-converter.test.ts +100 -0
- package/tests/converter.test.ts +76 -0
- package/tests/cursor-converter.test.ts +347 -0
- package/tests/cursor-writer.test.ts +137 -0
- package/tests/droid-converter.test.ts +277 -0
- package/tests/droid-writer.test.ts +100 -0
- package/tests/fixtures/sample-plugin/commands/disabled-command.md +7 -0
- package/tests/fixtures/sample-plugin/skills/disabled-skill/SKILL.md +7 -0
- package/plugins/compound-engineering/commands/technical_review.md +0 -7
- /package/{plugins/compound-engineering → .claude}/commands/release-docs.md +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Reduce compound-engineering plugin context token usage
|
|
3
|
+
type: refactor
|
|
4
|
+
date: 2026-02-08
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Reduce compound-engineering Plugin Context Token Usage
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
## Problem Statement
|
|
14
|
+
|
|
15
|
+
### How Context Loading Works
|
|
16
|
+
|
|
17
|
+
Claude Code uses progressive disclosure for plugin content:
|
|
18
|
+
|
|
19
|
+
| Level | What Loads | When |
|
|
20
|
+
|-------|-----------|------|
|
|
21
|
+
| **Always in context** | `description` frontmatter from skills, commands, and agents | Session startup (unless `disable-model-invocation: true`) |
|
|
22
|
+
| **On invocation** | Full SKILL.md / command body / agent body | When triggered |
|
|
23
|
+
| **On demand** | Reference files in skill directories | When Claude reads them |
|
|
24
|
+
|
|
25
|
+
The total budget for ALL descriptions combined is **2% of context window** (~16,000 chars fallback). When exceeded, components are **silently excluded**.
|
|
26
|
+
|
|
27
|
+
### Current State: 316% of Budget
|
|
28
|
+
|
|
29
|
+
| Component | Count | Always-Loaded Chars | % of 16K Budget |
|
|
30
|
+
|-----------|------:|--------------------:|----------------:|
|
|
31
|
+
| Agent descriptions | 29 | ~41,400 | 259% |
|
|
32
|
+
| Skill descriptions | 16 | ~5,450 | 34% |
|
|
33
|
+
| Command descriptions | 24 | ~3,700 | 23% |
|
|
34
|
+
| **Total** | **69** | **~50,500** | **316%** |
|
|
35
|
+
|
|
36
|
+
### Root Cause: Bloated Agent Descriptions
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
40
|
+
Examples of the problem:
|
|
41
|
+
|
|
42
|
+
- `design-iterator.md`: 2,488 chars in description (should be ~200)
|
|
43
|
+
- `spec-flow-analyzer.md`: 2,289 chars in description
|
|
44
|
+
- `security-sentinel.md`: 1,986 chars in description
|
|
45
|
+
- `kieran-rails-reviewer.md`: 1,822 chars in description
|
|
46
|
+
- Average agent description: ~1,400 chars (should be 100-250)
|
|
47
|
+
|
|
48
|
+
Compare to Anthropic's official examples at 100-200 chars:
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
# Official (140 chars)
|
|
52
|
+
description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code.
|
|
53
|
+
|
|
54
|
+
# Current plugin (1,822 chars)
|
|
55
|
+
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..."
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Secondary Cause: No `disable-model-invocation` on Manual Commands
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
The official docs explicitly state:
|
|
63
|
+
> 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.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Proposed Solution
|
|
68
|
+
|
|
69
|
+
Three changes, ordered by impact:
|
|
70
|
+
|
|
71
|
+
### Phase 1: Trim Agent Descriptions (saves ~35,600 chars)
|
|
72
|
+
|
|
73
|
+
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).
|
|
74
|
+
|
|
75
|
+
**Before** (agent frontmatter):
|
|
76
|
+
```yaml
|
|
77
|
+
---
|
|
78
|
+
name: kieran-rails-reviewer
|
|
79
|
+
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 ..."
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
Detailed system prompt...
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**After** (agent frontmatter):
|
|
86
|
+
```yaml
|
|
87
|
+
---
|
|
88
|
+
name: kieran-rails-reviewer
|
|
89
|
+
description: Review Rails code with Kieran's strict conventions. Use after implementing features, modifying code, or creating new Rails components.
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
<examples>
|
|
93
|
+
<example>
|
|
94
|
+
Context: The user has just implemented a new controller action with turbo streams.
|
|
95
|
+
user: "I've added a new update action to the posts controller"
|
|
96
|
+
...
|
|
97
|
+
</example>
|
|
98
|
+
</examples>
|
|
99
|
+
|
|
100
|
+
Detailed system prompt...
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The examples move into the body (which only loads when the agent is actually invoked).
|
|
104
|
+
|
|
105
|
+
**Impact:** ~41,400 chars → ~5,800 chars (86% reduction)
|
|
106
|
+
|
|
107
|
+
### Phase 2: Add `disable-model-invocation: true` to Manual Commands (saves ~3,100 chars)
|
|
108
|
+
|
|
109
|
+
Commands that should only run when explicitly invoked by the user:
|
|
110
|
+
|
|
111
|
+
| Command | Reason |
|
|
112
|
+
|---------|--------|
|
|
113
|
+
| `/deploy-docs` | Side effect: deploys |
|
|
114
|
+
| `/release-docs` | Side effect: regenerates docs |
|
|
115
|
+
| `/changelog` | Side effect: generates changelog |
|
|
116
|
+
| `/lfg` | Side effect: autonomous workflow |
|
|
117
|
+
| `/slfg` | Side effect: swarm workflow |
|
|
118
|
+
| `/triage` | Side effect: categorizes findings |
|
|
119
|
+
| `/resolve_parallel` | Side effect: resolves TODOs |
|
|
120
|
+
| `/resolve_todo_parallel` | Side effect: resolves todos |
|
|
121
|
+
| `/resolve_pr_parallel` | Side effect: resolves PR comments |
|
|
122
|
+
| `/feature-video` | Side effect: records video |
|
|
123
|
+
| `/test-browser` | Side effect: runs browser tests |
|
|
124
|
+
| `/xcode-test` | Side effect: builds/tests iOS |
|
|
125
|
+
| `/reproduce-bug` | Side effect: runs reproduction |
|
|
126
|
+
| `/report-bug` | Side effect: creates bug report |
|
|
127
|
+
| `/agent-native-audit` | Side effect: runs audit |
|
|
128
|
+
| `/heal-skill` | Side effect: modifies skill files |
|
|
129
|
+
| `/generate_command` | Side effect: creates files |
|
|
130
|
+
| `/create-agent-skill` | Side effect: creates files |
|
|
131
|
+
|
|
132
|
+
Keep these **without** the flag (Claude should know about them):
|
|
133
|
+
- `/workflows:plan` — Claude might suggest planning
|
|
134
|
+
- `/workflows:work` — Claude might suggest starting work
|
|
135
|
+
- `/workflows:review` — Claude might suggest review
|
|
136
|
+
- `/workflows:brainstorm` — Claude might suggest brainstorming
|
|
137
|
+
- `/workflows:compound` — Claude might suggest documenting
|
|
138
|
+
- `/deepen-plan` — Claude might suggest deepening a plan
|
|
139
|
+
|
|
140
|
+
**Impact:** ~3,700 chars → ~600 chars for commands in context
|
|
141
|
+
|
|
142
|
+
### Phase 3: Add `disable-model-invocation: true` to Manual Skills (saves ~1,000 chars)
|
|
143
|
+
|
|
144
|
+
Skills that are manual workflows:
|
|
145
|
+
|
|
146
|
+
| Skill | Reason |
|
|
147
|
+
|-------|--------|
|
|
148
|
+
| `skill-creator` | Only invoked manually |
|
|
149
|
+
| `orchestrating-swarms` | Only invoked manually |
|
|
150
|
+
| `git-worktree` | Only invoked manually |
|
|
151
|
+
| `resolve-pr-parallel` | Side effect |
|
|
152
|
+
| `compound-docs` | Only invoked manually |
|
|
153
|
+
| `file-todos` | Only invoked manually |
|
|
154
|
+
|
|
155
|
+
Keep without the flag (Claude should auto-invoke):
|
|
156
|
+
- `dhh-rails-style` — Claude should use when writing Rails code
|
|
157
|
+
- `frontend-design` — Claude should use when building UI
|
|
158
|
+
- `brainstorming` — Claude should suggest before implementation
|
|
159
|
+
- `agent-browser` — Claude should use for browser tasks
|
|
160
|
+
- `gemini-imagegen` — Claude should use for image generation
|
|
161
|
+
- `create-agent-skills` — Claude should use when creating skills
|
|
162
|
+
- `every-style-editor` — Claude should use for editing
|
|
163
|
+
- `dspy-ruby` — Claude should use for DSPy.rb
|
|
164
|
+
- `agent-native-architecture` — Claude should use for agent-native design
|
|
165
|
+
- `andrew-kane-gem-writer` — Claude should use for gem writing
|
|
166
|
+
- `rclone` — Claude should use for cloud uploads
|
|
167
|
+
- `document-review` — Claude should use for doc review
|
|
168
|
+
|
|
169
|
+
**Impact:** ~5,450 chars → ~4,000 chars for skills in context
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Projected Result
|
|
174
|
+
|
|
175
|
+
| Component | Before (chars) | After (chars) | Reduction |
|
|
176
|
+
|-----------|---------------:|-------------:|-----------:|
|
|
177
|
+
| Agent descriptions | ~41,400 | ~5,800 | -86% |
|
|
178
|
+
| Command descriptions | ~3,700 | ~600 | -84% |
|
|
179
|
+
| Skill descriptions | ~5,450 | ~4,000 | -27% |
|
|
180
|
+
| **Total** | **~50,500** | **~10,400** | **-79%** |
|
|
181
|
+
| **% of 16K budget** | **316%** | **65%** | -- |
|
|
182
|
+
|
|
183
|
+
From 316% of budget (components silently dropped) to 65% of budget (room for growth).
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Acceptance Criteria
|
|
188
|
+
|
|
189
|
+
- [x] All 29 agent description fields are under 250 characters
|
|
190
|
+
- [x] All `<example>` blocks moved from description to agent body
|
|
191
|
+
- [x] 18 manual commands have `disable-model-invocation: true`
|
|
192
|
+
- [x] 6 manual skills have `disable-model-invocation: true`
|
|
193
|
+
- [x] Total always-loaded description content is under 16,000 characters
|
|
194
|
+
- [ ] Run `/context` to verify no "excluded skills" warnings
|
|
195
|
+
- [x] All agents still function correctly (examples are in body, not lost)
|
|
196
|
+
- [x] All commands still invocable via `/command-name`
|
|
197
|
+
- [x] Update plugin version in plugin.json and marketplace.json
|
|
198
|
+
- [x] Update CHANGELOG.md
|
|
199
|
+
|
|
200
|
+
## Implementation Notes
|
|
201
|
+
|
|
202
|
+
- Agent examples should use `<examples><example>...</example></examples>` tags in the body — Claude understands these natively
|
|
203
|
+
- Description format: "[What it does]. Use [when/trigger condition]." — two sentences max
|
|
204
|
+
- The `lint` agent at 115 words shows compact agents work great
|
|
205
|
+
- Test with `claude --plugin-dir ./plugins/compound-engineering` after changes
|
|
206
|
+
- The `SLASH_COMMAND_TOOL_CHAR_BUDGET` env var can override the default budget for testing
|
|
207
|
+
|
|
208
|
+
## References
|
|
209
|
+
|
|
210
|
+
- [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"
|
|
211
|
+
- [Subagents docs](https://code.claude.com/docs/en/sub-agents) — description field used for automatic delegation
|
|
212
|
+
- [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"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "refactor: Update dspy-ruby skill to DSPy.rb v0.34.3 API"
|
|
3
|
+
type: refactor
|
|
4
|
+
date: 2026-02-09
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Update dspy-ruby Skill to DSPy.rb v0.34.3 API
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
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.).
|
|
12
|
+
|
|
13
|
+
## Solution
|
|
14
|
+
|
|
15
|
+
Use the engineering skill as base (already has correct API), enhance with official docs content, rewrite all reference files and templates.
|
|
16
|
+
|
|
17
|
+
### Source Priority (when conflicts arise)
|
|
18
|
+
|
|
19
|
+
1. **Official docs** (`../dspy.rb/docs/src/`) — source of truth for API correctness
|
|
20
|
+
2. **Engineering skill** (`../engineering/.../dspy-rb/SKILL.md`) — source of truth for structure/style
|
|
21
|
+
3. **NavigationContext brainstorm** — for Typed Context pattern only
|
|
22
|
+
|
|
23
|
+
## Files to Update
|
|
24
|
+
|
|
25
|
+
### Core (SKILL.md)
|
|
26
|
+
|
|
27
|
+
1. **`skills/dspy-ruby/SKILL.md`** — Copy from engineering base, then:
|
|
28
|
+
- Fix frontmatter: `name: dspy-rb` → `name: dspy-ruby`, keep long description format
|
|
29
|
+
- 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)
|
|
30
|
+
- Update Resources section with 5 references + 3 assets using markdown links
|
|
31
|
+
- Fix any backtick references to markdown link format
|
|
32
|
+
|
|
33
|
+
### References (rewrite from themed doc batches)
|
|
34
|
+
|
|
35
|
+
2. **`references/core-concepts.md`** — Rewrite
|
|
36
|
+
- Source: `core-concepts/signatures.md`, `modules.md`, `predictors.md`, `advanced/complex-types.md`
|
|
37
|
+
- 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)
|
|
38
|
+
|
|
39
|
+
3. **`references/toolsets.md`** — NEW
|
|
40
|
+
- Source: `core-concepts/toolsets.md`, `toolsets-guide.md`
|
|
41
|
+
- Cover: Tools::Base, Tools::Toolset DSL, type safety with Sorbet sigs, schema generation, built-in toolsets, testing
|
|
42
|
+
|
|
43
|
+
4. **`references/providers.md`** — Rewrite
|
|
44
|
+
- Source: `llms.txt.erb`, engineering SKILL.md, `core-concepts/module-runtime-context.md`
|
|
45
|
+
- Cover: per-provider adapters, RubyLLM unified adapter, Rails initializer, fiber-local LM context (`DSPy.with_lm`), feature-flagged model selection, compatibility matrix
|
|
46
|
+
|
|
47
|
+
5. **`references/optimization.md`** — Rewrite
|
|
48
|
+
- Source: `optimization/miprov2.md`, `gepa.md`, `evaluation.md`, `production/storage.md`
|
|
49
|
+
- Cover: MIPROv2 (dspy-miprov2 gem, AutoMode presets), GEPA (dspy-gepa gem, feedback maps), Evaluation (DSPy::Evals, built-in metrics, DSPy::Example), Storage (ProgramStorage)
|
|
50
|
+
|
|
51
|
+
6. **`references/observability.md`** — NEW
|
|
52
|
+
- Source: `production/observability.md`, `core-concepts/events.md`, `advanced/observability-interception.md`
|
|
53
|
+
- Cover: event system (module-scoped + global), dspy-o11y gems, Langfuse (env vars), score reporting (DSPy.score()), observation types, DSPy::Context.with_span
|
|
54
|
+
|
|
55
|
+
### Assets (rewrite to current API)
|
|
56
|
+
|
|
57
|
+
7. **`assets/signature-template.rb`** — T::Enum classes, `description:` kwarg, Date/Time types, defaults, union types, `.call()` / `result.field` usage examples
|
|
58
|
+
|
|
59
|
+
8. **`assets/module-template.rb`** — `.call()` API, `result.field`, Tools::Base, lifecycle callbacks, `DSPy.with_lm`, `configure_predictor`
|
|
60
|
+
|
|
61
|
+
9. **`assets/config-template.rb`** — RubyLLM adapter, `structured_outputs: true`, `after_initialize` Rails pattern, dspy-o11y env vars, feature-flagged model selection
|
|
62
|
+
|
|
63
|
+
### Metadata
|
|
64
|
+
|
|
65
|
+
10. **`.claude-plugin/plugin.json`** — Version `2.31.0` → `2.31.1`
|
|
66
|
+
|
|
67
|
+
11. **`CHANGELOG.md`** — Add `[2.31.1] - 2026-02-09` entry under `### Changed`
|
|
68
|
+
|
|
69
|
+
## Verification
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# No old API patterns
|
|
73
|
+
grep -n '\.forward(\|result\[:\|T\.enum(\[\|DSPy::Tool[^s]' plugins/compound-engineering/skills/dspy-ruby/SKILL.md
|
|
74
|
+
|
|
75
|
+
# No backtick references
|
|
76
|
+
grep -E '`(references|assets|scripts)/' plugins/compound-engineering/skills/dspy-ruby/SKILL.md
|
|
77
|
+
|
|
78
|
+
# Frontmatter correct
|
|
79
|
+
head -4 plugins/compound-engineering/skills/dspy-ruby/SKILL.md
|
|
80
|
+
|
|
81
|
+
# JSON valid
|
|
82
|
+
cat plugins/compound-engineering/.claude-plugin/plugin.json | jq .
|
|
83
|
+
|
|
84
|
+
# All files exist
|
|
85
|
+
ls plugins/compound-engineering/skills/dspy-ruby/{references,assets}/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Success Criteria
|
|
89
|
+
|
|
90
|
+
- [x] All API patterns updated (`.call()`, `result.field`, `T::Enum`, `Tools::Base`)
|
|
91
|
+
- [x] New features covered: events, callbacks, fiber-local LM, GEPA, evals, BAML/TOON, storage, score API, RubyLLM, typed context
|
|
92
|
+
- [x] 5 reference files present (core-concepts, toolsets, providers, optimization, observability)
|
|
93
|
+
- [x] 3 asset templates updated to current API
|
|
94
|
+
- [x] YAML frontmatter: `name: dspy-ruby`, description has "what" and "when"
|
|
95
|
+
- [x] All reference links use `[file.md](./references/file.md)` format
|
|
96
|
+
- [x] Writing style: imperative form, no "you should"
|
|
97
|
+
- [x] Version bumped to `2.31.1`, CHANGELOG updated
|
|
98
|
+
- [x] Verification commands all pass
|
|
99
|
+
|
|
100
|
+
## Source Materials
|
|
101
|
+
|
|
102
|
+
- Engineering skill: `/Users/vicente/Workspaces/vicente.services/engineering/plugins/engineering-skills/skills/dspy-rb/SKILL.md`
|
|
103
|
+
- Official docs: `/Users/vicente/Workspaces/vicente.services/dspy.rb/docs/src/`
|
|
104
|
+
- NavigationContext brainstorm: `/Users/vicente/Workspaces/vicente.services/observo/observo-server/docs/brainstorms/2026-02-09-typed-navigation-context-brainstorm.md`
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Add Cursor CLI as a Target Provider
|
|
3
|
+
type: feat
|
|
4
|
+
date: 2026-02-12
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Add Cursor CLI as a Target Provider
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
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.
|
|
14
|
+
|
|
15
|
+
## Component Mapping
|
|
16
|
+
|
|
17
|
+
| Claude Code | Cursor Equivalent | Notes |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `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 |
|
|
20
|
+
| `commands/*.md` | `.cursor/commands/*.md` | Plain markdown files; Cursor commands have no frontmatter support -- description becomes a markdown heading |
|
|
21
|
+
| `skills/*/SKILL.md` | `.cursor/skills/*/SKILL.md` | **Identical standard** -- copy directly |
|
|
22
|
+
| MCP servers | `.cursor/mcp.json` | Same JSON structure (`mcpServers` key), compatible format |
|
|
23
|
+
| `hooks/` | No equivalent | Cursor has no hook system; emit `console.warn` and skip |
|
|
24
|
+
| `.claude/` paths | `.cursor/` paths | Content rewriting needed |
|
|
25
|
+
|
|
26
|
+
### Key Design Decisions
|
|
27
|
+
|
|
28
|
+
**1. Agents use `alwaysApply: false` (Agent Requested mode)**
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
**2. Commands are plain markdown (no frontmatter)**
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
**3. Flattened command names with deduplication**
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
40
|
+
### Rules (`.mdc`) Frontmatter Format
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
---
|
|
44
|
+
description: "What this rule does and when it applies"
|
|
45
|
+
globs: ""
|
|
46
|
+
alwaysApply: false
|
|
47
|
+
---
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- `description` (string): Used by the AI to decide relevance -- maps from agent `description`
|
|
51
|
+
- `globs` (string): Comma-separated file patterns for auto-attachment -- leave empty for converted agents
|
|
52
|
+
- `alwaysApply` (boolean): Set `false` for Agent Requested mode
|
|
53
|
+
|
|
54
|
+
### MCP Servers (`.cursor/mcp.json`)
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"server-name": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "package-name"],
|
|
62
|
+
"env": { "KEY": "value" }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Supports both local (command-based) and remote (url-based) servers. Pass through `headers` for remote servers.
|
|
69
|
+
|
|
70
|
+
## Acceptance Criteria
|
|
71
|
+
|
|
72
|
+
- [x] `bun run src/index.ts convert --to cursor ./plugins/compound-engineering` produces valid Cursor config
|
|
73
|
+
- [x] Agents convert to `.cursor/rules/*.mdc` with `alwaysApply: false` and populated `description`
|
|
74
|
+
- [x] Commands convert to `.cursor/commands/*.md` as plain markdown (no frontmatter)
|
|
75
|
+
- [x] Flattened command names that collide are deduplicated (`plan`, `plan-2`, etc.)
|
|
76
|
+
- [x] Skills copied to `.cursor/skills/` (identical format)
|
|
77
|
+
- [x] MCP servers written to `.cursor/mcp.json` with backup of existing file
|
|
78
|
+
- [x] Content transformation rewrites `.claude/` and `~/.claude/` paths to `.cursor/` and `~/.cursor/`
|
|
79
|
+
- [x] `/workflows:plan` transformed to `/plan` (flat command names)
|
|
80
|
+
- [x] `Task agent-name(args)` transformed to natural-language skill reference
|
|
81
|
+
- [x] Plugins with hooks emit `console.warn` about unsupported hooks
|
|
82
|
+
- [x] Writer does not double-nest `.cursor/.cursor/` (follows droid writer pattern)
|
|
83
|
+
- [x] `model` and `allowedTools` fields silently dropped (no Cursor equivalent)
|
|
84
|
+
- [x] Converter and writer tests pass
|
|
85
|
+
- [x] Existing tests still pass (`bun test`)
|
|
86
|
+
|
|
87
|
+
## Implementation
|
|
88
|
+
|
|
89
|
+
### Phase 1: Types
|
|
90
|
+
|
|
91
|
+
**Create `src/types/cursor.ts`**
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
export type CursorRule = {
|
|
95
|
+
name: string
|
|
96
|
+
content: string // Full .mdc file with YAML frontmatter
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type CursorCommand = {
|
|
100
|
+
name: string
|
|
101
|
+
content: string // Plain markdown (no frontmatter)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type CursorSkillDir = {
|
|
105
|
+
name: string
|
|
106
|
+
sourceDir: string
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type CursorBundle = {
|
|
110
|
+
rules: CursorRule[]
|
|
111
|
+
commands: CursorCommand[]
|
|
112
|
+
skillDirs: CursorSkillDir[]
|
|
113
|
+
mcpServers?: Record<string, {
|
|
114
|
+
command?: string
|
|
115
|
+
args?: string[]
|
|
116
|
+
env?: Record<string, string>
|
|
117
|
+
url?: string
|
|
118
|
+
headers?: Record<string, string>
|
|
119
|
+
}>
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Phase 2: Converter
|
|
124
|
+
|
|
125
|
+
**Create `src/converters/claude-to-cursor.ts`**
|
|
126
|
+
|
|
127
|
+
Core functions:
|
|
128
|
+
|
|
129
|
+
1. **`convertClaudeToCursor(plugin, options)`** -- main entry point
|
|
130
|
+
- Convert each agent to a `.mdc` rule via `convertAgentToRule()`
|
|
131
|
+
- Convert each command (including `disable-model-invocation` ones) via `convertCommand()`
|
|
132
|
+
- Pass skills through as directory references
|
|
133
|
+
- Convert MCP servers to JSON-compatible object
|
|
134
|
+
- Emit `console.warn` if `plugin.hooks` has entries
|
|
135
|
+
|
|
136
|
+
2. **`convertAgentToRule(agent, usedNames)`** -- agent -> `.mdc` rule
|
|
137
|
+
- Frontmatter fields: `description` (from agent description), `globs: ""`, `alwaysApply: false`
|
|
138
|
+
- Body: agent body with content transformations applied
|
|
139
|
+
- Prepend capabilities section if present
|
|
140
|
+
- Deduplicate names via `uniqueName()`
|
|
141
|
+
- Silently drop `model` field (no Cursor equivalent)
|
|
142
|
+
|
|
143
|
+
3. **`convertCommand(command, usedNames)`** -- command -> plain `.md`
|
|
144
|
+
- Flatten namespace: `workflows:plan` -> `plan`
|
|
145
|
+
- Deduplicate flattened names via `uniqueName()`
|
|
146
|
+
- Emit as plain markdown: description as `<!-- description -->` comment, then body
|
|
147
|
+
- Include `argument-hint` as a `## Arguments` section if present
|
|
148
|
+
- Body: apply `transformContentForCursor()` transformations
|
|
149
|
+
- Silently drop `allowedTools` (no Cursor equivalent)
|
|
150
|
+
|
|
151
|
+
4. **`transformContentForCursor(body)`** -- content rewriting
|
|
152
|
+
- `.claude/` -> `.cursor/` and `~/.claude/` -> `~/.cursor/`
|
|
153
|
+
- `Task agent-name(args)` -> `Use the agent-name skill to: args` (same as codex)
|
|
154
|
+
- `/workflows:command` -> `/command` (flatten slash commands)
|
|
155
|
+
- `@agent-name` references -> `the agent-name rule` (use codex's suffix-matching pattern)
|
|
156
|
+
- Skip file paths (containing `/`) and common non-command patterns
|
|
157
|
+
|
|
158
|
+
5. **`convertMcpServers(servers)`** -- MCP config
|
|
159
|
+
- Map each `ClaudeMcpServer` entry to Cursor-compatible JSON
|
|
160
|
+
- Pass through: `command`, `args`, `env`, `url`, `headers`
|
|
161
|
+
- Drop `type` field (Cursor infers transport from `command` vs `url`)
|
|
162
|
+
|
|
163
|
+
### Phase 3: Writer
|
|
164
|
+
|
|
165
|
+
**Create `src/targets/cursor.ts`**
|
|
166
|
+
|
|
167
|
+
Output structure:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
.cursor/
|
|
171
|
+
├── rules/
|
|
172
|
+
│ ├── agent-name-1.mdc
|
|
173
|
+
│ └── agent-name-2.mdc
|
|
174
|
+
├── commands/
|
|
175
|
+
│ ├── command-1.md
|
|
176
|
+
│ └── command-2.md
|
|
177
|
+
├── skills/
|
|
178
|
+
│ └── skill-name/
|
|
179
|
+
│ └── SKILL.md
|
|
180
|
+
└── mcp.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Core function: `writeCursorBundle(outputRoot, bundle)`
|
|
184
|
+
|
|
185
|
+
- `resolveCursorPaths(outputRoot)` -- detect if path already ends in `.cursor` to avoid double-nesting (follow droid writer pattern at `src/targets/droid.ts:31-50`)
|
|
186
|
+
- Write rules to `rules/` as `.mdc` files
|
|
187
|
+
- Write commands to `commands/` as `.md` files
|
|
188
|
+
- Copy skill directories to `skills/` via `copyDir()`
|
|
189
|
+
- Write `mcp.json` via `writeJson()` with `backupFile()` for existing files
|
|
190
|
+
|
|
191
|
+
### Phase 4: Wire into CLI
|
|
192
|
+
|
|
193
|
+
**Modify `src/targets/index.ts`**
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { convertClaudeToCursor } from "../converters/claude-to-cursor"
|
|
197
|
+
import { writeCursorBundle } from "./cursor"
|
|
198
|
+
import type { CursorBundle } from "../types/cursor"
|
|
199
|
+
|
|
200
|
+
// Add to targets:
|
|
201
|
+
cursor: {
|
|
202
|
+
name: "cursor",
|
|
203
|
+
implemented: true,
|
|
204
|
+
convert: convertClaudeToCursor as TargetHandler<CursorBundle>["convert"],
|
|
205
|
+
write: writeCursorBundle as TargetHandler<CursorBundle>["write"],
|
|
206
|
+
},
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Modify `src/commands/convert.ts`**
|
|
210
|
+
|
|
211
|
+
- Update `--to` description: `"Target format (opencode | codex | droid | cursor)"`
|
|
212
|
+
- Add to `resolveTargetOutputRoot`: `if (targetName === "cursor") return path.join(outputRoot, ".cursor")`
|
|
213
|
+
|
|
214
|
+
**Modify `src/commands/install.ts`**
|
|
215
|
+
|
|
216
|
+
- Same two changes as convert.ts
|
|
217
|
+
|
|
218
|
+
### Phase 5: Tests
|
|
219
|
+
|
|
220
|
+
**Create `tests/cursor-converter.test.ts`**
|
|
221
|
+
|
|
222
|
+
Test cases (use inline `ClaudePlugin` fixtures, following codex converter test pattern):
|
|
223
|
+
|
|
224
|
+
- Agent converts to rule with `.mdc` frontmatter (`alwaysApply: false`, `description` populated)
|
|
225
|
+
- Agent with empty description gets default description text
|
|
226
|
+
- Agent with capabilities prepended to body
|
|
227
|
+
- Agent `model` field silently dropped
|
|
228
|
+
- Agent with empty body gets default body text
|
|
229
|
+
- Command converts with flattened name (`workflows:plan` -> `plan`)
|
|
230
|
+
- Command name collision after flattening is deduplicated (`plan`, `plan-2`)
|
|
231
|
+
- Command with `disable-model-invocation` is still included
|
|
232
|
+
- Command `allowedTools` silently dropped
|
|
233
|
+
- Command with `argument-hint` gets Arguments section
|
|
234
|
+
- Skills pass through as directory references
|
|
235
|
+
- MCP servers convert to JSON config (local and remote)
|
|
236
|
+
- MCP `headers` pass through for remote servers
|
|
237
|
+
- Content transformation: `.claude/` paths -> `.cursor/`
|
|
238
|
+
- Content transformation: `~/.claude/` paths -> `~/.cursor/`
|
|
239
|
+
- Content transformation: `Task agent(args)` -> natural language
|
|
240
|
+
- Content transformation: slash commands flattened
|
|
241
|
+
- Hooks present -> `console.warn` emitted
|
|
242
|
+
- Plugin with zero agents produces empty rules array
|
|
243
|
+
- Plugin with only skills works correctly
|
|
244
|
+
|
|
245
|
+
**Create `tests/cursor-writer.test.ts`**
|
|
246
|
+
|
|
247
|
+
Test cases (use temp directories, following droid writer test pattern):
|
|
248
|
+
|
|
249
|
+
- Full bundle writes rules, commands, skills, mcp.json
|
|
250
|
+
- Rules written as `.mdc` files in `rules/` directory
|
|
251
|
+
- Commands written as `.md` files in `commands/` directory
|
|
252
|
+
- Skills copied to `skills/` directory
|
|
253
|
+
- MCP config written as valid JSON `mcp.json`
|
|
254
|
+
- Existing `mcp.json` is backed up before overwrite
|
|
255
|
+
- Output root already ending in `.cursor` does NOT double-nest
|
|
256
|
+
- Empty bundle (no rules, commands, skills, or MCP) produces no output
|
|
257
|
+
|
|
258
|
+
### Phase 6: Documentation
|
|
259
|
+
|
|
260
|
+
**Create `docs/specs/cursor.md`**
|
|
261
|
+
|
|
262
|
+
Document the Cursor CLI spec as a reference, following `docs/specs/codex.md` pattern:
|
|
263
|
+
|
|
264
|
+
- Rules format (`.mdc` with `description`, `globs`, `alwaysApply` frontmatter)
|
|
265
|
+
- Commands format (plain markdown, no frontmatter)
|
|
266
|
+
- Skills format (identical SKILL.md standard)
|
|
267
|
+
- MCP server configuration (`.cursor/mcp.json`)
|
|
268
|
+
- CLI permissions (`.cursor/cli.json` -- for reference, not converted)
|
|
269
|
+
- Config file locations (project-level vs global)
|
|
270
|
+
|
|
271
|
+
**Update `README.md`**
|
|
272
|
+
|
|
273
|
+
Add `cursor` to the supported targets in the CLI usage section.
|
|
274
|
+
|
|
275
|
+
## What We're NOT Doing
|
|
276
|
+
|
|
277
|
+
- Not converting hooks (Cursor has no hook system -- warn and skip)
|
|
278
|
+
- Not generating `.cursor/cli.json` permissions (user-specific, not plugin-scoped)
|
|
279
|
+
- Not creating `AGENTS.md` (Cursor reads it natively, but not part of plugin conversion)
|
|
280
|
+
- Not using `globs` field intelligently (would require analyzing agent content to guess file patterns)
|
|
281
|
+
- Not adding sync support (follow-up task)
|
|
282
|
+
- Not transforming content inside copied SKILL.md files (known limitation -- skills may reference `.claude/` paths internally)
|
|
283
|
+
- Not clearing old output before writing (matches existing target behavior -- re-runs accumulate)
|
|
284
|
+
|
|
285
|
+
## Complexity Assessment
|
|
286
|
+
|
|
287
|
+
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:
|
|
288
|
+
|
|
289
|
+
1. The `.mdc` frontmatter format (different from all other targets)
|
|
290
|
+
2. Agents map to "rules" rather than a direct equivalent
|
|
291
|
+
3. Commands are plain markdown (no frontmatter) unlike other targets
|
|
292
|
+
4. Name deduplication needed for flattened command namespaces
|
|
293
|
+
|
|
294
|
+
Skills being identical across platforms simplifies things significantly. MCP config is nearly 1:1.
|
|
295
|
+
|
|
296
|
+
## References
|
|
297
|
+
|
|
298
|
+
- Cursor Rules: `.cursor/rules/*.mdc` with `description`, `globs`, `alwaysApply` frontmatter
|
|
299
|
+
- Cursor Commands: `.cursor/commands/*.md` (plain markdown, no frontmatter)
|
|
300
|
+
- Cursor Skills: `.cursor/skills/*/SKILL.md` (open standard, identical to Claude Code)
|
|
301
|
+
- Cursor MCP: `.cursor/mcp.json` with `mcpServers` key
|
|
302
|
+
- Cursor CLI: `cursor-agent` command (launched August 2025)
|
|
303
|
+
- Existing codex converter: `src/converters/claude-to-codex.ts` (has `uniqueName()` deduplication pattern)
|
|
304
|
+
- Existing droid writer: `src/targets/droid.ts` (has double-nesting guard pattern)
|
|
305
|
+
- Existing codex plan: `docs/plans/2026-02-08-feat-convert-local-md-settings-for-opencode-codex-plan.md`
|
|
306
|
+
- Target provider checklist: `AGENTS.md` section "Adding a New Target Provider"
|