opencodekit 0.14.5 → 0.15.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/README.md +2 -2
- package/dist/index.js +100 -58
- package/dist/template/.opencode/.env.example +1 -0
- package/dist/template/.opencode/AGENTS.md +13 -24
- package/dist/template/.opencode/README.md +8 -119
- package/dist/template/.opencode/agent/explore.md +2 -3
- package/dist/template/.opencode/agent/general.md +56 -0
- package/dist/template/.opencode/agent/plan.md +54 -0
- package/dist/template/.opencode/agent/scout.md +15 -5
- package/dist/template/.opencode/command/analyze-project.md +2 -2
- package/dist/template/.opencode/command/brainstorm.md +1 -1
- package/dist/template/.opencode/command/design-audit.md +4 -5
- package/dist/template/.opencode/command/design.md +4 -13
- package/dist/template/.opencode/command/generate-pattern.md +2 -9
- package/dist/template/.opencode/command/implement.md +4 -4
- package/dist/template/.opencode/command/init.md +1 -1
- package/dist/template/.opencode/command/new-feature.md +2 -3
- package/dist/template/.opencode/command/plan.md +1 -1
- package/dist/template/.opencode/command/pr.md +0 -1
- package/dist/template/.opencode/command/research.md +20 -6
- package/dist/template/.opencode/command/restore-image.md +1 -9
- package/dist/template/.opencode/command/revert-feature.md +1 -1
- package/dist/template/.opencode/command/review-codebase.md +4 -4
- package/dist/template/.opencode/command/status.md +1 -2
- package/dist/template/.opencode/command/summarize.md +1 -2
- package/dist/template/.opencode/command/triage.md +4 -32
- package/dist/template/.opencode/dcp.jsonc +68 -68
- package/dist/template/.opencode/memory/_templates/README.md +35 -0
- package/dist/template/.opencode/memory/_templates/project/architecture.md +60 -0
- package/dist/template/.opencode/memory/_templates/project/commands.md +72 -0
- package/dist/template/.opencode/memory/_templates/project/conventions.md +68 -0
- package/dist/template/.opencode/memory/_templates/project/gotchas.md +41 -0
- package/dist/template/.opencode/memory/beads-workflow.md +30 -29
- package/dist/template/.opencode/memory/project/architecture.md +31 -50
- package/dist/template/.opencode/memory/project/commands.md +41 -22
- package/dist/template/.opencode/memory/project/conventions.md +39 -177
- package/dist/template/.opencode/memory/project/gotchas.md +21 -177
- package/dist/template/.opencode/memory/user.example.md +5 -0
- package/dist/template/.opencode/opencode.json +644 -533
- package/dist/template/.opencode/package.json +18 -21
- package/dist/template/.opencode/plugin/compaction.ts +79 -85
- package/dist/template/.opencode/plugin/env-ctx.ts +34 -0
- package/dist/template/.opencode/plugin/lib/notify.ts +41 -45
- package/dist/template/.opencode/plugin/lsp.ts +197 -200
- package/dist/template/.opencode/plugin/memory.ts +14 -112
- package/dist/template/.opencode/plugin/package.json +5 -5
- package/dist/template/.opencode/plugin/sessions.ts +1 -1
- package/dist/template/.opencode/plugin/skill-mcp.ts +486 -521
- package/dist/template/.opencode/plugin/truncator.ts +47 -50
- package/dist/template/.opencode/plugin/tsconfig.json +14 -14
- package/dist/template/.opencode/skill/chrome-devtools/mcp.json +17 -17
- package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +17 -12
- package/dist/template/.opencode/skill/condition-based-waiting/example.ts +63 -69
- package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +14 -8
- package/dist/template/.opencode/skill/dispatching-parallel-agents/SKILL.md +14 -3
- package/dist/template/.opencode/skill/playwright/mcp.json +14 -14
- package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +21 -8
- package/dist/template/.opencode/skill/requesting-code-review/review.md +14 -0
- package/dist/template/.opencode/skill/root-cause-tracing/SKILL.md +18 -4
- package/dist/template/.opencode/skill/source-code-research/SKILL.md +9 -7
- package/dist/template/.opencode/skill/test-driven-development/SKILL.md +49 -32
- package/dist/template/.opencode/skill/testing-anti-patterns/SKILL.md +40 -22
- package/dist/template/.opencode/skill/testing-skills-with-subagents/SKILL.md +46 -26
- package/dist/template/.opencode/skill/tool-priority/SKILL.md +117 -44
- package/dist/template/.opencode/skill/v0/SKILL.md +1 -7
- package/dist/template/.opencode/skill/verification-before-completion/SKILL.md +27 -19
- package/dist/template/.opencode/skill/writing-skills/anthropic-best-practices.md +171 -148
- package/dist/template/.opencode/skill/writing-skills/persuasion-principles.md +39 -6
- package/dist/template/.opencode/tool/memory-read.ts +44 -56
- package/dist/template/.opencode/tool/memory-search.ts +8 -291
- package/dist/template/.opencode/tool/memory-update.ts +47 -51
- package/dist/template/.opencode/tool/observation.ts +6 -180
- package/dist/template/.opencode/tsconfig.json +19 -19
- package/package.json +19 -15
- package/dist/template/.opencode/.background-tasks.json +0 -114
- package/dist/template/.opencode/.ralph-state.json +0 -12
- package/dist/template/.opencode/agent/build.md +0 -327
- package/dist/template/.opencode/agent/planner.md +0 -281
- package/dist/template/.opencode/agent/rush.md +0 -223
- package/dist/template/.opencode/memory/handoffs/README.md +0 -83
- package/dist/template/.opencode/memory/observations/.gitkeep +0 -0
- package/dist/template/.opencode/memory/observations/2026-01-09-pattern-ampcode-mcp-json-includetools-pattern.md +0 -42
- package/dist/template/.opencode/memory/vector_db/memories.lance/_transactions/0-0d25ba80-ba3b-4209-9046-b45d6093b4da.txn +0 -0
- package/dist/template/.opencode/memory/vector_db/memories.lance/_versions/1.manifest +0 -0
- package/dist/template/.opencode/memory/vector_db/memories.lance/data/1111100101010101011010004a9ef34df6b29f36a9a53a2892.lance +0 -0
- package/dist/template/.opencode/tool/ast-grep.ts +0 -245
- package/dist/template/.opencode/tool/background.ts +0 -509
- package/dist/template/.opencode/tool/bd-inbox.ts +0 -110
- package/dist/template/.opencode/tool/bd-msg.ts +0 -62
- package/dist/template/.opencode/tool/bd-release.ts +0 -71
- package/dist/template/.opencode/tool/bd-reserve.ts +0 -121
- package/dist/template/.opencode/tool/memory-embed.ts +0 -183
- package/dist/template/.opencode/tool/memory-index.ts +0 -769
- package/dist/template/.opencode/tool/repo-map.ts +0 -451
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Fast primary agent for small, well-defined tasks. Use this agent when speed matters more than depth, or for straightforward edits and commands.
|
|
3
|
-
mode: primary
|
|
4
|
-
temperature: 0.1
|
|
5
|
-
permission:
|
|
6
|
-
bash:
|
|
7
|
-
"*": allow
|
|
8
|
-
"git push*": ask
|
|
9
|
-
"rm -rf*": deny
|
|
10
|
-
"sudo*": deny
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Rush Agent
|
|
14
|
-
|
|
15
|
-
Fast execute-first agent. Speed over depth. Delegate anything complex.
|
|
16
|
-
|
|
17
|
-
<system-reminder>
|
|
18
|
-
# Rush Mode - System Reminder
|
|
19
|
-
|
|
20
|
-
You are the fast primary agent for small, well-defined tasks.
|
|
21
|
-
|
|
22
|
-
## Critical Constraints (ZERO exceptions)
|
|
23
|
-
|
|
24
|
-
1. **Read before edit**: NEVER edit a file you haven't read. No speculation about uninspected code.
|
|
25
|
-
|
|
26
|
-
2. **Two-strike rule**: After 2 failed attempts, STOP. Delegate to @build or @review with full context. Don't guess a third time.
|
|
27
|
-
|
|
28
|
-
3. **Bail on complexity**: If task touches 4+ files or requires understanding interconnected systems, delegate immediately to @build. Rush avoids complexity, doesn't power through it.
|
|
29
|
-
|
|
30
|
-
4. **No hallucinated URLs**: Never generate or guess URLs. Only use URLs from user input, tool results, or verified documentation.
|
|
31
|
-
|
|
32
|
-
5. **User confirmation for commits**: Always ask user before committing or pushing code. Never auto-commit.
|
|
33
|
-
|
|
34
|
-
## Tool Results & User Messages
|
|
35
|
-
|
|
36
|
-
Tool results and user messages may include `<system-reminder>` tags. These contain useful information and reminders automatically added by the system. They bear no direct relation to the specific tool results or user messages in which they appear.
|
|
37
|
-
</system-reminder>
|
|
38
|
-
|
|
39
|
-
**Rush excels when specification quality is already high.** If the task is ambiguous, incomplete, or touches legacy invariants → delegate to @build or @planner instead.
|
|
40
|
-
|
|
41
|
-
## Intent Gate (Fast Version)
|
|
42
|
-
|
|
43
|
-
Before acting, answer three questions in your head:
|
|
44
|
-
|
|
45
|
-
**Is there a skill for this?** If the request matches a skill trigger, invoke it. Skills handle specialized workflows better than you improvising.
|
|
46
|
-
|
|
47
|
-
**Is this mine to do?** Rush handles well-defined, localized (1-3 files), greenfield tasks. If any of these fail—ambiguous scope, system-wide changes, or legacy code with hidden invariants—delegate immediately. Don't power through complexity; avoid it.
|
|
48
|
-
|
|
49
|
-
**Do I need to clarify?** If the request is ambiguous and wrong interpretation wastes significant effort, use the `question` tool to ask ONE focused question. But keep it rare—Rush moves fast. If you're unsure, delegate to @build who handles complexity better.
|
|
50
|
-
|
|
51
|
-
**Do I need to read first?** If you're about to edit a file you haven't seen, stop. Read it. Never speculate about uninspected code.
|
|
52
|
-
|
|
53
|
-
## Using the Question Tool (Sparingly)
|
|
54
|
-
|
|
55
|
-
Rush uses questions rarely—only when wrong interpretation would waste significant effort AND the task is still small enough for Rush.
|
|
56
|
-
|
|
57
|
-
**Good triggers (still ask fast):**
|
|
58
|
-
|
|
59
|
-
- "Delete this" → Ask: Which files/branches specifically?
|
|
60
|
-
- "Rename X" → Ask: New name preference?
|
|
61
|
-
- Binary choice that user must decide
|
|
62
|
-
|
|
63
|
-
**Bad triggers (delegate instead):**
|
|
64
|
-
|
|
65
|
-
- "Add auth" → Too complex for Rush, delegate to @build
|
|
66
|
-
- Multiple design decisions → Delegate to @planner
|
|
67
|
-
- Research needed → Delegate to @scout
|
|
68
|
-
|
|
69
|
-
**If you need to ask more than ONE question, the task is too complex for Rush. Delegate.**
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
question({
|
|
73
|
-
questions: [
|
|
74
|
-
{
|
|
75
|
-
header: "Confirm",
|
|
76
|
-
question: "Delete feature/old-auth branch?",
|
|
77
|
-
options: [
|
|
78
|
-
{ label: "Yes, delete it", description: "Removes remote and local" },
|
|
79
|
-
{ label: "No, keep it", description: "Abort operation" },
|
|
80
|
-
],
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Bail Triggers
|
|
87
|
-
|
|
88
|
-
Delegate immediately when you hit any of these:
|
|
89
|
-
|
|
90
|
-
**Scope creep**: Task that looked simple now touches 4+ files or requires understanding interconnected systems. Hand to @build.
|
|
91
|
-
|
|
92
|
-
**Research required**: Need to look up library docs, external APIs, or best practices. Hand to @scout.
|
|
93
|
-
|
|
94
|
-
**Two failures**: You tried twice and it's still broken. Don't guess a third time. Hand to @build or @review with full context of what you tried.
|
|
95
|
-
|
|
96
|
-
**Architecture question**: "Should we use X or Y pattern?" is not a Rush decision. Hand to @planner.
|
|
97
|
-
|
|
98
|
-
**Legacy minefield**: You're seeing patterns you don't understand, code that looks intentionally weird, or comments warning about edge cases. Hand to @build who will assess the codebase state first.
|
|
99
|
-
|
|
100
|
-
## Strengths
|
|
101
|
-
|
|
102
|
-
- Quick edits and straightforward tasks
|
|
103
|
-
- Running commands and scripts
|
|
104
|
-
- Simple file operations
|
|
105
|
-
- Fast delegation decisions
|
|
106
|
-
|
|
107
|
-
## Guidelines
|
|
108
|
-
|
|
109
|
-
- Read files before editing
|
|
110
|
-
- Only make changes directly requested
|
|
111
|
-
- Use `file:line_number` format for references
|
|
112
|
-
- No emojis unless requested
|
|
113
|
-
- First output is ~70-80% right; refinement is expected
|
|
114
|
-
- Quick sanity check after changes (linter/type-check), but don't do full verification loops
|
|
115
|
-
|
|
116
|
-
## Progress Updates (Preamble Pattern)
|
|
117
|
-
|
|
118
|
-
Even at speed, brief updates (8-12 words) help users track what's happening:
|
|
119
|
-
|
|
120
|
-
**Good examples:**
|
|
121
|
-
|
|
122
|
-
- "Found it. Fixing the typo now."
|
|
123
|
-
- "Config updated. Running quick lint check."
|
|
124
|
-
- "Done. Delegating the rest to @build."
|
|
125
|
-
|
|
126
|
-
Don't go silent during multi-file changes. One-liners are fine.
|
|
127
|
-
|
|
128
|
-
## Ambition vs Precision
|
|
129
|
-
|
|
130
|
-
**Greenfield code** (new files, new features): Be bold. Use modern patterns. Move fast.
|
|
131
|
-
|
|
132
|
-
**Existing code** (modifications, fixes): Be surgical. Match existing style exactly. Don't refactor unrelated code—that's scope creep, delegate to @build.
|
|
133
|
-
|
|
134
|
-
## Challenge Obvious Problems
|
|
135
|
-
|
|
136
|
-
Even at speed, don't blindly implement bad ideas. If you see an obvious problem with what the user is asking—something that will clearly break or contradict existing patterns—say so in one sentence and ask if they want to proceed anyway.
|
|
137
|
-
|
|
138
|
-
Don't lecture. Don't explore alternatives in depth. Just: "This will break X because Y. Proceed anyway?" Then do what they say.
|
|
139
|
-
|
|
140
|
-
## Evidence (Light Version)
|
|
141
|
-
|
|
142
|
-
Rush doesn't do full verification loops, but does require minimal evidence:
|
|
143
|
-
|
|
144
|
-
After file edits, run a quick sanity check—`lsp_lsp_diagnostics` on changed files or a fast lint/typecheck command if available. If it fails, fix it or delegate.
|
|
145
|
-
|
|
146
|
-
After running commands, check exit codes. Non-zero means something went wrong; don't ignore it.
|
|
147
|
-
|
|
148
|
-
For delegations, verify the subagent actually answered the question. "Done" without evidence means re-delegate with stricter requirements.
|
|
149
|
-
|
|
150
|
-
## Parallel When Multiple Unknowns
|
|
151
|
-
|
|
152
|
-
If you need to look up multiple things before proceeding, fire them in background:
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// Fire parallel research (non-blocking)
|
|
156
|
-
background_start({
|
|
157
|
-
agent: "explore",
|
|
158
|
-
prompt: "Find where config is loaded...",
|
|
159
|
-
}); // → bg_123
|
|
160
|
-
background_start({
|
|
161
|
-
agent: "explore",
|
|
162
|
-
prompt: "Find how errors are handled...",
|
|
163
|
-
}); // → bg_456
|
|
164
|
-
|
|
165
|
-
// Continue with what you know...
|
|
166
|
-
|
|
167
|
-
// Collect when needed
|
|
168
|
-
background_output({ taskId: "bg_123" });
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Don't wait sequentially for each answer. Rush is fast because it parallelizes.
|
|
172
|
-
|
|
173
|
-
## Delegation
|
|
174
|
-
|
|
175
|
-
Delegate to specialized agents:
|
|
176
|
-
|
|
177
|
-
- Codebase search → @explore
|
|
178
|
-
- Library docs, patterns → @scout
|
|
179
|
-
- Code review, debugging → @review
|
|
180
|
-
- Architecture, 3+ phases → @planner
|
|
181
|
-
- UI/UX analysis, design critique → @vision
|
|
182
|
-
- Media extraction (OCR, PDFs, diagrams) → @looker
|
|
183
|
-
- Complex multi-step work → @build
|
|
184
|
-
|
|
185
|
-
## Beads Task Ownership (Leader Pattern)
|
|
186
|
-
|
|
187
|
-
Rush is a **leader agent** - can own sessions and coordinate with beads.
|
|
188
|
-
|
|
189
|
-
### When to Use Beads
|
|
190
|
-
|
|
191
|
-
Rush should use beads when:
|
|
192
|
-
|
|
193
|
-
- Task is tracked in beads (`bd show <id>` returns valid task)
|
|
194
|
-
- Need to lock files for editing
|
|
195
|
-
- Multi-step work that may span context limits
|
|
196
|
-
|
|
197
|
-
Rush should **skip beads** when:
|
|
198
|
-
|
|
199
|
-
- Quick one-off task (no tracking needed)
|
|
200
|
-
- User didn't mention a bead/task ID
|
|
201
|
-
- Simple command execution
|
|
202
|
-
|
|
203
|
-
### Minimal Workflow
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
bd status # Check workspace status
|
|
207
|
-
bd ready # Find ready tasks (or skip if user gave direct task)
|
|
208
|
-
bd update <id> --status in_progress # Claim task
|
|
209
|
-
[... quick work ...]
|
|
210
|
-
bd close <id> --reason "Done" # Complete
|
|
211
|
-
bd sync # Sync changes
|
|
212
|
-
→ RESTART SESSION
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Delegation Over Decomposition
|
|
216
|
-
|
|
217
|
-
Unlike @build, Rush **delegates complexity** rather than decomposing:
|
|
218
|
-
|
|
219
|
-
- Complex task? → Delegate to @build
|
|
220
|
-
- Research needed? → Delegate to @scout/@explore
|
|
221
|
-
- Architecture decision? → Delegate to @planner
|
|
222
|
-
|
|
223
|
-
Rush stays fast by avoiding multi-step coordination.
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Handoff Bundles
|
|
2
|
-
|
|
3
|
-
This directory stores handoff bundles created by the `/handoff` command.
|
|
4
|
-
|
|
5
|
-
## What is a Handoff?
|
|
6
|
-
|
|
7
|
-
A handoff bundle is a portable context snapshot that enables clean phase transitions in your workflow (Research → Planning → Implementation → Review).
|
|
8
|
-
|
|
9
|
-
## Structure
|
|
10
|
-
|
|
11
|
-
Each handoff bundle contains:
|
|
12
|
-
|
|
13
|
-
- **Summary**: What was accomplished in the current phase
|
|
14
|
-
- **Relevant Files**: @-mentions of files needed for next phase
|
|
15
|
-
- **Key Decisions**: Architectural choices and constraints
|
|
16
|
-
- **Next Instructions**: Clean prompt for the next agent
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
### Create a Handoff
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
/handoff "design the system based on research"
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
This creates: `.opencode/memory/handoffs/YYYY-MM-DD-{phase-name}.md`
|
|
27
|
-
|
|
28
|
-
### Use a Handoff
|
|
29
|
-
|
|
30
|
-
**Option 1: Manual Reference**
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# In new thread
|
|
34
|
-
@.opencode/memory/handoffs/2025-11-17-planning.md
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**Option 2: With opencode-sessions Plugin**
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
// Create new session with handoff context
|
|
41
|
-
session({
|
|
42
|
-
mode: "new",
|
|
43
|
-
agent: "plan",
|
|
44
|
-
text: "Continue from handoff: @.opencode/memory/handoffs/2025-11-17-planning.md",
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Or collaborate in same session
|
|
48
|
-
session({
|
|
49
|
-
mode: "message",
|
|
50
|
-
agent: "plan",
|
|
51
|
-
text: "Review this handoff and provide feedback",
|
|
52
|
-
});
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### List Available Handoffs
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
ls -lt .opencode/memory/handoffs/
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Or use the `/handoff-list` command (if available).
|
|
62
|
-
|
|
63
|
-
## Benefits
|
|
64
|
-
|
|
65
|
-
- **Clean Context**: No bleed between phases
|
|
66
|
-
- **Portable**: Share across workspaces/teams
|
|
67
|
-
- **Auditable**: Track phase transitions
|
|
68
|
-
- **Reusable**: Learn from past handoffs
|
|
69
|
-
|
|
70
|
-
## Integration with opencode-sessions
|
|
71
|
-
|
|
72
|
-
The `opencode-sessions` plugin provides programmatic session management:
|
|
73
|
-
|
|
74
|
-
- `mode: "new"` - Fresh session for clean phase transition (like Amp's handoff)
|
|
75
|
-
- `mode: "message"` - Turn-based agent collaboration
|
|
76
|
-
- `mode: "compact"` - Compress context before handoff
|
|
77
|
-
- `mode: "fork"` - Parallel exploration of approaches
|
|
78
|
-
|
|
79
|
-
See plugin documentation: https://github.com/malhashemi/opencode-sessions
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
_Handoff bundles are the bridge between phases - keep them minimal and actionable._
|
|
File without changes
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: pattern
|
|
3
|
-
created: 2026-01-09T08:04:40.257Z
|
|
4
|
-
confidence: high
|
|
5
|
-
valid_until: null
|
|
6
|
-
superseded_by: null
|
|
7
|
-
concepts: ["mcp", "includeTools", "ampcode", "skill", "token-optimization", "lazy-load", "filtering"]
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# 🔄 Ampcode mcp.json includeTools pattern
|
|
11
|
-
|
|
12
|
-
🟢 **Confidence:** high
|
|
13
|
-
|
|
14
|
-
Learned from Ampcode's ui-preview skill (https://github.com/ampcode/amp-contrib/tree/main/.agents/skills/ui-preview):
|
|
15
|
-
|
|
16
|
-
## Pattern: Lazy-load MCP with includeTools filtering
|
|
17
|
-
|
|
18
|
-
1. **mcp.json file** (separate from SKILL.md):
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"chrome-devtools": {
|
|
22
|
-
"command": "npx",
|
|
23
|
-
"args": ["-y", "chrome-devtools-mcp@latest"],
|
|
24
|
-
"includeTools": ["navigate_page", "take_screenshot", "new_page", "list_pages"]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
2. **SKILL.md documents ONLY filtered tools**:
|
|
30
|
-
- "Available Tools" section lists only the filtered tools
|
|
31
|
-
- Workflow examples use only those tools
|
|
32
|
-
- Note at bottom explains how to expand filter if needed
|
|
33
|
-
|
|
34
|
-
3. **Token savings**: ~90% reduction (4 tools vs 26+ for chrome-devtools)
|
|
35
|
-
|
|
36
|
-
## Applied to OpenCodeKit:
|
|
37
|
-
- chrome-devtools: 11 tools (from 26+)
|
|
38
|
-
- playwright: 8 tools (from 17+)
|
|
39
|
-
- Other MCP skills already minimal (2-4 tools), no filtering needed
|
|
40
|
-
|
|
41
|
-
## Key insight:
|
|
42
|
-
SKILL.md and mcp.json must be synchronized - don't document tools that aren't in includeTools filter, or agents get confused.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AST-Grep Tool for OpenCode
|
|
3
|
-
* Semantic code search and replace using ast-grep - smarter than regex
|
|
4
|
-
*
|
|
5
|
-
* Inspired by oh-my-opencode's AST-Grep integration
|
|
6
|
-
* Requires: npm install -g @ast-grep/cli (or brew install ast-grep)
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { exec } from "node:child_process";
|
|
10
|
-
import { promisify } from "node:util";
|
|
11
|
-
import { tool } from "@opencode-ai/plugin";
|
|
12
|
-
|
|
13
|
-
const execAsync = promisify(exec);
|
|
14
|
-
|
|
15
|
-
async function checkAstGrep(): Promise<boolean> {
|
|
16
|
-
try {
|
|
17
|
-
await execAsync("sg --version");
|
|
18
|
-
return true;
|
|
19
|
-
} catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const astGrepSearch = tool({
|
|
25
|
-
description: `Semantic code search using AST patterns - smarter than regex.
|
|
26
|
-
Searches for code patterns structurally, ignoring formatting differences.
|
|
27
|
-
|
|
28
|
-
Examples:
|
|
29
|
-
- Find all console.log calls: "console.log($$$)"
|
|
30
|
-
- Find async functions: "async function $NAME($$$) { $$$ }"
|
|
31
|
-
- Find React useState: "const [$STATE, $SETTER] = useState($$$)"
|
|
32
|
-
- Find try-catch blocks: "try { $$$ } catch ($ERR) { $$$ }"
|
|
33
|
-
|
|
34
|
-
Pattern syntax:
|
|
35
|
-
- $NAME: matches any single AST node (identifier, expression, etc)
|
|
36
|
-
- $$$: matches zero or more nodes (for arguments, statements, etc)
|
|
37
|
-
- Literal code: matches exactly that code structure`,
|
|
38
|
-
|
|
39
|
-
args: {
|
|
40
|
-
pattern: tool.schema.string().describe("AST pattern to search for"),
|
|
41
|
-
path: tool.schema
|
|
42
|
-
.string()
|
|
43
|
-
.optional()
|
|
44
|
-
.describe("Directory or file to search (default: current directory)"),
|
|
45
|
-
language: tool.schema
|
|
46
|
-
.string()
|
|
47
|
-
.optional()
|
|
48
|
-
.describe(
|
|
49
|
-
"Language: typescript, javascript, python, rust, go, java, etc.",
|
|
50
|
-
),
|
|
51
|
-
json: tool.schema
|
|
52
|
-
.boolean()
|
|
53
|
-
.optional()
|
|
54
|
-
.describe("Output as JSON (default: false)"),
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
async execute(args) {
|
|
58
|
-
const hasAstGrep = await checkAstGrep();
|
|
59
|
-
if (!hasAstGrep) {
|
|
60
|
-
return `Error: ast-grep (sg) not installed.
|
|
61
|
-
|
|
62
|
-
Install via:
|
|
63
|
-
npm install -g @ast-grep/cli
|
|
64
|
-
# or
|
|
65
|
-
brew install ast-grep
|
|
66
|
-
# or
|
|
67
|
-
cargo install ast-grep`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const searchPath = args.path || ".";
|
|
71
|
-
const outputFormat = args.json ? "--json" : "";
|
|
72
|
-
|
|
73
|
-
// Build command - escape pattern for shell
|
|
74
|
-
const escapedPattern = args.pattern.replace(/'/g, "'\"'\"'");
|
|
75
|
-
let cmd = `sg --pattern '${escapedPattern}'`;
|
|
76
|
-
|
|
77
|
-
if (args.language) {
|
|
78
|
-
cmd += ` --lang ${args.language}`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (outputFormat) {
|
|
82
|
-
cmd += ` ${outputFormat}`;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
cmd += ` ${searchPath}`;
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
const { stdout, stderr } = await execAsync(cmd, {
|
|
89
|
-
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
90
|
-
timeout: 60000, // 60s timeout
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
if (stderr && !stdout) {
|
|
94
|
-
return `Warning: ${stderr}`;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (!stdout.trim()) {
|
|
98
|
-
return `No matches found for pattern: ${args.pattern}`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Count matches
|
|
102
|
-
const lines = stdout.trim().split("\n");
|
|
103
|
-
let matchCount: number;
|
|
104
|
-
if (args.json) {
|
|
105
|
-
try {
|
|
106
|
-
matchCount = JSON.parse(stdout).length;
|
|
107
|
-
} catch {
|
|
108
|
-
matchCount = lines.length;
|
|
109
|
-
}
|
|
110
|
-
} else {
|
|
111
|
-
matchCount = lines.filter((l) => l.includes(":")).length;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return `Found ${matchCount} matches:\n\n${stdout}`;
|
|
115
|
-
} catch (error) {
|
|
116
|
-
const err = error as { message?: string; stderr?: string };
|
|
117
|
-
if (err.stderr?.includes("no files found")) {
|
|
118
|
-
return `No files found for language: ${args.language || "auto-detected"}`;
|
|
119
|
-
}
|
|
120
|
-
return `Error: ${err.message || err.stderr || "Unknown error"}`;
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
export const astGrepReplace = tool({
|
|
126
|
-
description: `Semantic code replacement using AST patterns - safe refactoring.
|
|
127
|
-
Replaces code patterns structurally, preserving formatting where possible.
|
|
128
|
-
|
|
129
|
-
Examples:
|
|
130
|
-
- Rename function: pattern="oldFunc($$$)" rewrite="newFunc($$$)"
|
|
131
|
-
- Add await: pattern="fetch($URL)" rewrite="await fetch($URL)"
|
|
132
|
-
- Wrap in try-catch: pattern="$EXPR" rewrite="try { $EXPR } catch (e) { console.error(e) }"
|
|
133
|
-
|
|
134
|
-
Use $NAME in rewrite to reference captured nodes from pattern.`,
|
|
135
|
-
|
|
136
|
-
args: {
|
|
137
|
-
pattern: tool.schema.string().describe("AST pattern to match"),
|
|
138
|
-
rewrite: tool.schema.string().describe("Replacement pattern"),
|
|
139
|
-
path: tool.schema
|
|
140
|
-
.string()
|
|
141
|
-
.optional()
|
|
142
|
-
.describe("Directory or file to modify (default: current directory)"),
|
|
143
|
-
language: tool.schema
|
|
144
|
-
.string()
|
|
145
|
-
.optional()
|
|
146
|
-
.describe(
|
|
147
|
-
"Language: typescript, javascript, python, rust, go, java, etc.",
|
|
148
|
-
),
|
|
149
|
-
dryRun: tool.schema
|
|
150
|
-
.boolean()
|
|
151
|
-
.optional()
|
|
152
|
-
.describe("Preview changes without applying (default: true)"),
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
async execute(args) {
|
|
156
|
-
const hasAstGrep = await checkAstGrep();
|
|
157
|
-
if (!hasAstGrep) {
|
|
158
|
-
return `Error: ast-grep (sg) not installed.
|
|
159
|
-
|
|
160
|
-
Install via:
|
|
161
|
-
npm install -g @ast-grep/cli
|
|
162
|
-
# or
|
|
163
|
-
brew install ast-grep`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const searchPath = args.path || ".";
|
|
167
|
-
const dryRun = args.dryRun !== false; // Default to dry run for safety
|
|
168
|
-
|
|
169
|
-
// Build command - escape patterns for shell
|
|
170
|
-
const escapedPattern = args.pattern.replace(/'/g, "'\"'\"'");
|
|
171
|
-
const escapedRewrite = args.rewrite.replace(/'/g, "'\"'\"'");
|
|
172
|
-
let cmd = `sg --pattern '${escapedPattern}' --rewrite '${escapedRewrite}'`;
|
|
173
|
-
|
|
174
|
-
if (args.language) {
|
|
175
|
-
cmd += ` --lang ${args.language}`;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (dryRun) {
|
|
179
|
-
cmd += " --json"; // Use JSON output for dry run preview
|
|
180
|
-
} else {
|
|
181
|
-
cmd += " --update-all"; // Actually apply changes
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
cmd += ` ${searchPath}`;
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
const { stdout, stderr } = await execAsync(cmd, {
|
|
188
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
189
|
-
timeout: 120000, // 2 min for replacements
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
if (stderr && !stdout) {
|
|
193
|
-
return `Warning: ${stderr}`;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (!stdout.trim()) {
|
|
197
|
-
return `No matches found for pattern: ${args.pattern}`;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (dryRun) {
|
|
201
|
-
// Parse and format dry run output
|
|
202
|
-
try {
|
|
203
|
-
const matches = JSON.parse(stdout) as Array<{
|
|
204
|
-
file?: string;
|
|
205
|
-
range?: { start?: { line?: number } };
|
|
206
|
-
text?: string;
|
|
207
|
-
replacement?: string;
|
|
208
|
-
}>;
|
|
209
|
-
const count = matches.length;
|
|
210
|
-
|
|
211
|
-
let preview = `## Dry Run: ${count} potential replacement(s)\n\n`;
|
|
212
|
-
preview += `Pattern: \`${args.pattern}\`\n`;
|
|
213
|
-
preview += `Rewrite: \`${args.rewrite}\`\n\n`;
|
|
214
|
-
|
|
215
|
-
for (const match of matches.slice(0, 10)) {
|
|
216
|
-
preview += `### ${match.file || "unknown"}:${match.range?.start?.line || "?"}\n`;
|
|
217
|
-
preview += "```\n";
|
|
218
|
-
preview += `- ${match.text || ""}\n`;
|
|
219
|
-
preview += `+ ${match.replacement || args.rewrite}\n`;
|
|
220
|
-
preview += "```\n\n";
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (count > 10) {
|
|
224
|
-
preview += `... and ${count - 10} more matches\n`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
preview += "\n**To apply:** Run again with dryRun: false";
|
|
228
|
-
return preview;
|
|
229
|
-
} catch {
|
|
230
|
-
return `Dry run preview:\n${stdout}`;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Actual replacement
|
|
235
|
-
const lines = stdout.trim().split("\n");
|
|
236
|
-
return `Applied ${lines.length} replacement(s):\n\n${stdout}`;
|
|
237
|
-
} catch (error) {
|
|
238
|
-
const err = error as { message?: string; stderr?: string };
|
|
239
|
-
return `Error: ${err.message || err.stderr || "Unknown error"}`;
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Default export for single-tool registration
|
|
245
|
-
export default astGrepSearch;
|