opencodekit 0.17.2 → 0.17.4
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/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +42 -0
- package/dist/template/.opencode/agent/explore.md +8 -0
- package/dist/template/.opencode/agent/scout.md +8 -0
- package/dist/template/.opencode/command/create.md +23 -1
- package/dist/template/.opencode/command/plan.md +8 -0
- package/dist/template/.opencode/command/research.md +26 -0
- package/dist/template/.opencode/command/review-codebase.md +43 -1
- package/dist/template/.opencode/command/ship.md +26 -33
- package/dist/template/.opencode/command/start.md +15 -0
- package/dist/template/.opencode/command/status.md +23 -1
- package/dist/template/.opencode/command/verify.md +21 -0
- package/dist/template/.opencode/dcp.jsonc +81 -80
- package/dist/template/.opencode/memory/project/gotchas.md +37 -1
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/opencode.json +29 -5
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/skill/context-management/SKILL.md +44 -10
- package/dist/template/.opencode/skill/obsidian/SKILL.md +182 -0
- package/dist/template/.opencode/skill/obsidian/mcp.json +22 -0
- package/dist/template/.opencode/skill/structured-edit/SKILL.md +168 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -759,7 +759,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
759
759
|
// package.json
|
|
760
760
|
var package_default = {
|
|
761
761
|
name: "opencodekit",
|
|
762
|
-
version: "0.17.
|
|
762
|
+
version: "0.17.4",
|
|
763
763
|
description: "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
764
764
|
keywords: ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
|
|
765
765
|
license: "MIT",
|
|
@@ -132,6 +132,48 @@ For major tracked work:
|
|
|
132
132
|
- Use available tools to remove noise
|
|
133
133
|
- Persist important decisions and state to memory
|
|
134
134
|
|
|
135
|
+
### Token Budget
|
|
136
|
+
|
|
137
|
+
| Phase | Target | Action |
|
|
138
|
+
| ----------------- | ------- | ------------------------------------------ |
|
|
139
|
+
| Starting work | <50k | Load only essential AGENTS.md + task spec |
|
|
140
|
+
| Mid-task | 50-100k | Distill completed reads, keep active files |
|
|
141
|
+
| Approaching limit | >100k | Aggressive distill, prune remaining noise |
|
|
142
|
+
| Near capacity | >150k | Session restart with handoff |
|
|
143
|
+
|
|
144
|
+
### Tools
|
|
145
|
+
|
|
146
|
+
- `distill` — Extract key info from tool outputs, then remove raw output (preferred)
|
|
147
|
+
- `prune` — Remove tool outputs entirely (noise only, no preservation)
|
|
148
|
+
|
|
149
|
+
### Rules
|
|
150
|
+
|
|
151
|
+
1. **Distill at turn START** — not end (you know what's needed)
|
|
152
|
+
2. **Batch operations** — accumulate candidates before acting
|
|
153
|
+
3. **Protected content** — AGENTS.md, .opencode/, .beads/, config files
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Edit Protocol
|
|
158
|
+
|
|
159
|
+
`str_replace` failures are the #1 source of LLM coding failures. Use structured edits:
|
|
160
|
+
|
|
161
|
+
1. **LOCATE** — Use LSP tools (goToDefinition, findReferences) to find exact positions
|
|
162
|
+
2. **READ** — Get fresh file content around target (offset: line-10, limit: 30)
|
|
163
|
+
3. **VERIFY** — Confirm expected content exists before editing
|
|
164
|
+
4. **EDIT** — Include 2-3 unique context lines before/after
|
|
165
|
+
5. **CONFIRM** — Read back to verify edit succeeded
|
|
166
|
+
|
|
167
|
+
### File Size Guidance
|
|
168
|
+
|
|
169
|
+
| Size | Strategy |
|
|
170
|
+
| ------------- | --------------------------------- |
|
|
171
|
+
| < 100 lines | Full rewrite often easier |
|
|
172
|
+
| 100-400 lines | Structured edit with good context |
|
|
173
|
+
| > 400 lines | Strongly prefer structured edits |
|
|
174
|
+
|
|
175
|
+
**Use the `structured-edit` skill for complex edits.**
|
|
176
|
+
|
|
135
177
|
---
|
|
136
178
|
|
|
137
179
|
## Output Style
|
|
@@ -35,6 +35,14 @@ Find relevant files, symbols, and usage paths quickly for the caller.
|
|
|
35
35
|
- Prefer semantic lookup (LSP) before broad text search when it improves precision
|
|
36
36
|
- Stop when you can answer with concrete evidence or when additional search only repeats confirmed paths
|
|
37
37
|
|
|
38
|
+
## Before You Explore
|
|
39
|
+
|
|
40
|
+
- **Be certain**: Only explore what's needed for the task at hand
|
|
41
|
+
- **Don't over-explore**: Stop when you have enough evidence to answer
|
|
42
|
+
- **Use LSP first**: Start with goToDefinition/findReferences before grep
|
|
43
|
+
- **Stay scoped**: Don't explore files outside the task scope
|
|
44
|
+
- **Cite evidence**: Every finding needs file:line reference
|
|
45
|
+
|
|
38
46
|
## Workflow
|
|
39
47
|
|
|
40
48
|
1. Discover candidate files with `glob` or `workspaceSymbol`
|
|
@@ -45,6 +45,14 @@ Find trustworthy external references quickly and return concise, cited guidance.
|
|
|
45
45
|
- Cite every non-trivial claim
|
|
46
46
|
- Prefer high-signal synthesis over long dumps
|
|
47
47
|
|
|
48
|
+
## Before You Scout
|
|
49
|
+
|
|
50
|
+
- **Verify memory first**: Always check memory-search before external research
|
|
51
|
+
- **Use source hierarchy**: Official docs > source code > maintainer articles > community posts
|
|
52
|
+
- **Don't over-research**: Stop when you have medium+ confidence
|
|
53
|
+
- **Cite everything**: Every claim needs a source
|
|
54
|
+
- **Synthesize don't dump**: Return recommendations, not raw facts
|
|
55
|
+
|
|
48
56
|
## Source Quality Hierarchy
|
|
49
57
|
|
|
50
58
|
Rank sources in this order:
|
|
@@ -26,7 +26,29 @@ skill({ name: "prd" }); // PRD template guidance
|
|
|
26
26
|
| `<description>` | required | What to build/fix (quoted string) |
|
|
27
27
|
| `--type` | auto-detected | Override: epic, feature, task, bug |
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
## Determine Input Type
|
|
30
|
+
|
|
31
|
+
| Input Type | Detection | Action |
|
|
32
|
+
| ----------- | -------------------- | ----------------------------- |
|
|
33
|
+
| Quoted text | `"description here"` | Create PRD from description |
|
|
34
|
+
| Short form | Simple string | Ask for more detail if needed |
|
|
35
|
+
| `--type` | Flag provided | Use provided type |
|
|
36
|
+
|
|
37
|
+
## Before You Create
|
|
38
|
+
|
|
39
|
+
- **Be certain**: Only create beads you're confident have clear scope
|
|
40
|
+
- **Don't over-spec**: If the description is vague, ask clarifying questions first
|
|
41
|
+
- **Check duplicates**: Always run Phase 1 duplicate check
|
|
42
|
+
- **No implementation**: This command creates specs only, don't write code
|
|
43
|
+
- **Verify PRD**: Before saving, verify all sections are filled (no placeholders)
|
|
44
|
+
|
|
45
|
+
## Available Tools
|
|
46
|
+
|
|
47
|
+
| Tool | Use When |
|
|
48
|
+
| --------- | -------------------------------------------- |
|
|
49
|
+
| `explore` | Finding patterns in codebase, affected files |
|
|
50
|
+
| `scout` | External research, best practices |
|
|
51
|
+
| `br` | Creating and managing beads |
|
|
30
52
|
|
|
31
53
|
## Phase 1: Duplicate Check
|
|
32
54
|
|
|
@@ -28,6 +28,14 @@ skill({ name: "writing-plans" }); // TDD plan format
|
|
|
28
28
|
| `<bead-id>` | required | The bead to plan |
|
|
29
29
|
| `--create-beads` | false | Create child beads for each phase |
|
|
30
30
|
|
|
31
|
+
## Before You Plan
|
|
32
|
+
|
|
33
|
+
- **Be certain**: Only create tasks you're confident about
|
|
34
|
+
- **Don't over-plan**: If the PRD is clear, trust it
|
|
35
|
+
- **Budget context**: Target ~50% context per execution
|
|
36
|
+
- **Split signals**: Create child beads for complex work
|
|
37
|
+
- **Vertical slices**: Each task should cover one feature end-to-end
|
|
38
|
+
|
|
31
39
|
## Phase 1: Guards
|
|
32
40
|
|
|
33
41
|
```bash
|
|
@@ -28,6 +28,32 @@ skill({ name: "deep-research" });
|
|
|
28
28
|
|
|
29
29
|
Default depth: ~30 tool calls for moderate exploration.
|
|
30
30
|
|
|
31
|
+
## Determine Input Type
|
|
32
|
+
|
|
33
|
+
| Input Type | Detection | Action |
|
|
34
|
+
| ---------- | --------------------------- | --------------------------------- |
|
|
35
|
+
| Bead ID | Matches `br-xxx` or numeric | Research within that bead context |
|
|
36
|
+
| Topic | String | Standalone research |
|
|
37
|
+
|
|
38
|
+
## Before You Research
|
|
39
|
+
|
|
40
|
+
- **Be certain**: Only research what you need for implementation
|
|
41
|
+
- **Don't over-research**: Stop when you have enough to proceed
|
|
42
|
+
- **Use source priority**: Codebase → Docs → Source → GitHub → Web
|
|
43
|
+
- **Verify confidence**: Medium+ confidence required before stopping
|
|
44
|
+
- **Document findings**: Write to research.md for beads, report for topics
|
|
45
|
+
|
|
46
|
+
## Available Tools
|
|
47
|
+
|
|
48
|
+
| Tool | Use When |
|
|
49
|
+
| ------------ | ------------------------------- |
|
|
50
|
+
| `explore` | Codebase patterns, LSP analysis |
|
|
51
|
+
| `scout` | External docs, best practices |
|
|
52
|
+
| `context7` | Official API references |
|
|
53
|
+
| `opensrc` | Package source code inspection |
|
|
54
|
+
| `codesearch` | Real-world usage examples |
|
|
55
|
+
| `grepsearch` | GitHub code search |
|
|
56
|
+
|
|
31
57
|
## Phase 1: Load Context
|
|
32
58
|
|
|
33
59
|
If argument is a bead ID:
|
|
@@ -13,7 +13,49 @@ skill({ name: "beads" });
|
|
|
13
13
|
skill({ name: "requesting-code-review" });
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Determine Input Type
|
|
17
|
+
|
|
18
|
+
| Input Type | Detection | Action |
|
|
19
|
+
| --------------------- | ---------------------------- | -------------------------- |
|
|
20
|
+
| No arguments | Default | Review uncommitted changes |
|
|
21
|
+
| Commit hash (40-char) | SHA pattern | `git show <hash>` |
|
|
22
|
+
| Branch name | String, not matching above | `git diff main...HEAD` |
|
|
23
|
+
| PR URL/number | Contains "github.com" or "#" | `gh pr diff` |
|
|
24
|
+
|
|
25
|
+
## Before You Review
|
|
26
|
+
|
|
27
|
+
- **Be certain**: Only flag issues you can verify with tools
|
|
28
|
+
- **Don't invent problems**: If an edge case isn't specified, don't flag it
|
|
29
|
+
- **Don't be a zealot about style**: Unless it violates project conventions, don't flag
|
|
30
|
+
- **Review the changes**: Don't review pre-existing code that wasn't modified
|
|
31
|
+
- **Investigate first**: If unsure, use explore/scout agents before flagging
|
|
32
|
+
|
|
33
|
+
## Available Tools
|
|
34
|
+
|
|
35
|
+
| Tool | Use When |
|
|
36
|
+
| ------------ | --------------------------------------- |
|
|
37
|
+
| `explore` | Finding patterns in codebase, prior art |
|
|
38
|
+
| `scout` | External research, best practices |
|
|
39
|
+
| `lsp` | Finding symbol definitions, references |
|
|
40
|
+
| `grep` | Finding code patterns |
|
|
41
|
+
| `codesearch` | Real-world usage examples |
|
|
42
|
+
|
|
43
|
+
## Phase 1: Gather Context
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git status --short
|
|
47
|
+
git diff --cached # staged
|
|
48
|
+
git diff # unstaged
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For each changed file:
|
|
52
|
+
|
|
53
|
+
- Read the full file to understand context
|
|
54
|
+
- Don't rely on diff alone — code that looks wrong in isolation may be correct
|
|
55
|
+
|
|
56
|
+
If bead provided, read `.beads/artifacts/$ID/prd.md` to review against spec.
|
|
57
|
+
|
|
58
|
+
## Phase 2: Determine Scope
|
|
17
59
|
|
|
18
60
|
| Input | Scope | How to Get Code |
|
|
19
61
|
| ------------------------ | --------------------- | ------------------------- |
|
|
@@ -19,39 +19,32 @@ skill({ name: "beads" });
|
|
|
19
19
|
skill({ name: "verification-before-completion" });
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- STOP → report to user with: what found, proposed change, impact
|
|
49
|
-
|
|
50
|
-
**Rule Priority:**
|
|
51
|
-
|
|
52
|
-
1. Rule 4 applies → STOP (user decision required)
|
|
53
|
-
2. Rules 1-3 apply → Fix automatically, track deviation
|
|
54
|
-
3. Genuinely unsure → Treat as Rule 4 (ask)
|
|
22
|
+
## Determine Input Type
|
|
23
|
+
|
|
24
|
+
| Input Type | Detection | Action |
|
|
25
|
+
| ---------- | --------------------------- | -------------------------- |
|
|
26
|
+
| Bead ID | Matches `br-xxx` or numeric | Ship that bead |
|
|
27
|
+
| Path | File/directory path | Not supported for ship |
|
|
28
|
+
| `all` | Keyword | Ship all in_progress beads |
|
|
29
|
+
|
|
30
|
+
## Before You Ship
|
|
31
|
+
|
|
32
|
+
- **Be certain**: Only ship if all tasks pass verification
|
|
33
|
+
- **Don't skip gates**: Build, test, lint, typecheck are non-negotiable
|
|
34
|
+
- **Run the review**: Always spawn review agent before closing
|
|
35
|
+
- **Verify goals**: Tasks completing ≠ goals achieved (use goal-backward verification)
|
|
36
|
+
- **Commit before close**: Per-task commits required, don't ship without git history
|
|
37
|
+
- **Ask before closing**: Never close bead without user confirmation
|
|
38
|
+
|
|
39
|
+
## Available Tools
|
|
40
|
+
|
|
41
|
+
| Tool | Use When |
|
|
42
|
+
| --------- | ----------------------------------------- |
|
|
43
|
+
| `explore` | Finding patterns in codebase, prior art |
|
|
44
|
+
| `scout` | External research, best practices |
|
|
45
|
+
| `lsp` | Finding symbol definitions, references |
|
|
46
|
+
| `grep` | Finding code patterns |
|
|
47
|
+
| `task` | Spawning subagents for parallel execution |
|
|
55
48
|
|
|
56
49
|
## Phase 1: Guards
|
|
57
50
|
|
|
@@ -26,6 +26,21 @@ skill({ name: "prd-task" }); // PRD → executable tasks
|
|
|
26
26
|
| `<bead-id>` | required | The bead to start |
|
|
27
27
|
| `--worktree` | false | Create isolated git worktree |
|
|
28
28
|
|
|
29
|
+
## Determine Input Type
|
|
30
|
+
|
|
31
|
+
| Input Type | Detection | Action |
|
|
32
|
+
| ---------- | --------------------------- | ----------------------- |
|
|
33
|
+
| Bead ID | Matches `br-xxx` or numeric | Start that bead |
|
|
34
|
+
| Path | File/directory path | Not supported for start |
|
|
35
|
+
|
|
36
|
+
## Before You Start
|
|
37
|
+
|
|
38
|
+
- **Be certain**: Only start beads with valid PRD (check Phase 2)
|
|
39
|
+
- **Check workspace**: Don't start if uncommitted changes exist (Phase 1)
|
|
40
|
+
- **One task at a time**: Warn if other tasks in progress
|
|
41
|
+
- **Validate spec**: Verify prd.md exists and has real content
|
|
42
|
+
- **Ask about workspace**: Let user choose branch/worktree strategy
|
|
43
|
+
|
|
29
44
|
## Phase 1: Pre-flight
|
|
30
45
|
|
|
31
46
|
```bash
|
|
@@ -23,7 +23,29 @@ Quick project status dashboard. Runs read-only commands and reports state.
|
|
|
23
23
|
skill({ name: "beads" });
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
## Determine Input Type
|
|
27
|
+
|
|
28
|
+
| Input Type | Detection | Action |
|
|
29
|
+
| ------------ | ------------- | ------------------- |
|
|
30
|
+
| No arguments | Default | Show full dashboard |
|
|
31
|
+
| `--git` | Flag provided | Git state only |
|
|
32
|
+
| `--sessions` | Flag provided | Sessions only |
|
|
33
|
+
|
|
34
|
+
## Before You Status
|
|
35
|
+
|
|
36
|
+
- **Be certain**: This is a read-only command, no changes are made
|
|
37
|
+
- **Use actual data**: Don't invent data, use real command output
|
|
38
|
+
- **No modifications**: Don't create beads or modify state from status
|
|
39
|
+
- **Single recommendation**: Only suggest ONE next action
|
|
40
|
+
|
|
41
|
+
## Available Tools
|
|
42
|
+
|
|
43
|
+
| Tool | Use When |
|
|
44
|
+
| --------------- | --------------------------------- |
|
|
45
|
+
| `br` | Task status and stats |
|
|
46
|
+
| `git` | Git state and history |
|
|
47
|
+
| `list_sessions` | Recent sessions |
|
|
48
|
+
| `action-queue` | Pending approvals and ready tasks |
|
|
27
49
|
|
|
28
50
|
## Phase 1: Gather State (Parallel)
|
|
29
51
|
|
|
@@ -23,6 +23,21 @@ skill({ name: "verification-before-completion" });
|
|
|
23
23
|
| `--quick` | false | Gates only, skip coherence check |
|
|
24
24
|
| `--fix` | false | Auto-fix lint/format issues |
|
|
25
25
|
|
|
26
|
+
## Determine Input Type
|
|
27
|
+
|
|
28
|
+
| Input Type | Detection | Action |
|
|
29
|
+
| ---------- | --------------------------- | ----------------------------------- |
|
|
30
|
+
| Bead ID | Matches `br-xxx` or numeric | Check implementation vs PRD in bead |
|
|
31
|
+
| Path | File/directory path | Verify that specific path |
|
|
32
|
+
| `all` | Keyword | Verify all in-progress work |
|
|
33
|
+
|
|
34
|
+
## Before You Verify
|
|
35
|
+
|
|
36
|
+
- **Be certain**: Only flag issues you can verify with tools
|
|
37
|
+
- **Don't invent problems**: If an edge case isn't in the PRD, don't flag it
|
|
38
|
+
- **Run the gates**: Build, test, lint, typecheck are non-negotiable
|
|
39
|
+
- **Use project conventions**: Check `package.json` scripts first
|
|
40
|
+
|
|
26
41
|
## Phase 1: Gather Context
|
|
27
42
|
|
|
28
43
|
```bash
|
|
@@ -32,6 +47,12 @@ ls .beads/artifacts/$ARGUMENTS/
|
|
|
32
47
|
|
|
33
48
|
Read the PRD and any other artifacts (plan.md, research.md, design.md).
|
|
34
49
|
|
|
50
|
+
**Verify guards:**
|
|
51
|
+
|
|
52
|
+
- [ ] Bead is `in_progress`
|
|
53
|
+
- [ ] `prd.md` exists
|
|
54
|
+
- [ ] You have read the full PRD
|
|
55
|
+
|
|
35
56
|
## Phase 2: Completeness
|
|
36
57
|
|
|
37
58
|
Extract all requirements/tasks from the PRD and verify each is implemented:
|
|
@@ -1,82 +1,83 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json",
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"debug": false,
|
|
5
|
+
// "minimal" shows prune activity without noise; "detailed" shows token counts
|
|
6
|
+
"pruneNotification": "detailed",
|
|
7
|
+
// "chat" (in-conversation) or "toast" (system notification)
|
|
8
|
+
"pruneNotificationType": "toast",
|
|
9
|
+
// Commands: /dcp context, /dcp stats, /dcp sweep
|
|
10
|
+
"commands": {
|
|
11
|
+
"enabled": true,
|
|
12
|
+
// Protect these from /dcp sweep
|
|
13
|
+
"protectedTools": ["observation", "memory-update", "memory-search"]
|
|
14
|
+
},
|
|
15
|
+
"turnProtection": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"turns": 4
|
|
18
|
+
},
|
|
19
|
+
// Protected file patterns - never auto-prune reads of these files
|
|
20
|
+
"protectedFilePatterns": [
|
|
21
|
+
"**/.env*",
|
|
22
|
+
"**/AGENTS.md",
|
|
23
|
+
"**/.opencode/**",
|
|
24
|
+
"**/.beads/**",
|
|
25
|
+
"**/package.json",
|
|
26
|
+
"**/tsconfig.json",
|
|
27
|
+
"**/biome.json"
|
|
28
|
+
],
|
|
29
|
+
"tools": {
|
|
30
|
+
"settings": {
|
|
31
|
+
"nudgeEnabled": true,
|
|
32
|
+
"nudgeFrequency": 10,
|
|
33
|
+
// v2.0.1: percentage support - 80% of model's context (most models = 128k)
|
|
34
|
+
"contextLimit": "80%",
|
|
35
|
+
// Protect state-modifying and critical workflow tools
|
|
36
|
+
// LSP excluded: ephemeral exploration, prune after understanding
|
|
37
|
+
"protectedTools": [
|
|
38
|
+
"write",
|
|
39
|
+
"edit",
|
|
40
|
+
"memory-update",
|
|
41
|
+
"observation",
|
|
42
|
+
"skill",
|
|
43
|
+
"skill_mcp",
|
|
44
|
+
"task",
|
|
45
|
+
"batch",
|
|
46
|
+
"todowrite",
|
|
47
|
+
"todoread"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
// v2.0.0: permission model - "allow", "ask", or "deny"
|
|
51
|
+
"prune": {
|
|
52
|
+
"permission": "allow"
|
|
53
|
+
},
|
|
54
|
+
"distill": {
|
|
55
|
+
"permission": "allow",
|
|
56
|
+
"showDistillation": false
|
|
57
|
+
},
|
|
58
|
+
"compress": {
|
|
59
|
+
// v2.1.1: compress can have boundary matching issues - use ask for safety
|
|
60
|
+
"permission": "ask",
|
|
61
|
+
"showCompression": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// Auto strategies - TOP LEVEL, not under tools
|
|
65
|
+
"strategies": {
|
|
66
|
+
// Dedup = zero LLM cost, high impact - always enable
|
|
67
|
+
"deduplication": {
|
|
68
|
+
"enabled": true,
|
|
69
|
+
"protectedTools": []
|
|
70
|
+
},
|
|
71
|
+
// Supersede writes = zero cost, removes redundant write inputs after read
|
|
72
|
+
// Note: default changed to false in beta, we explicitly enable
|
|
73
|
+
"supersedeWrites": {
|
|
74
|
+
"enabled": true
|
|
75
|
+
},
|
|
76
|
+
// Purge error inputs after N turns
|
|
77
|
+
"purgeErrors": {
|
|
78
|
+
"enabled": true,
|
|
79
|
+
"turns": 4,
|
|
80
|
+
"protectedTools": []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
82
83
|
}
|
|
@@ -1,12 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
purpose: Footguns, edge cases, and warnings discovered during development
|
|
3
|
-
updated: 2026-02-
|
|
3
|
+
updated: 2026-02-12
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Gotchas
|
|
7
7
|
|
|
8
8
|
Track unexpected behaviors, edge cases, and warnings here. Update when you hit something surprising.
|
|
9
9
|
|
|
10
|
+
## LLM Coding (Harness Problem)
|
|
11
|
+
|
|
12
|
+
The edit tool (`str_replace`) is the #1 source of failures in LLM coding. Models fail at reproducing content with exact whitespace/encoding, not at understanding tasks.
|
|
13
|
+
|
|
14
|
+
### Edit Tool Failures
|
|
15
|
+
|
|
16
|
+
- **Whitespace mismatch** — Tabs vs spaces, trailing spaces, line endings (CRLF vs LF)
|
|
17
|
+
- **Content changed** — File modified since last read
|
|
18
|
+
- **Multiple matches** — Same string appears twice, edit fails
|
|
19
|
+
- **Stale context** — Editing from memory instead of fresh read
|
|
20
|
+
|
|
21
|
+
### Mitigation Strategies
|
|
22
|
+
|
|
23
|
+
1. **Always read fresh** before editing — no assumptions
|
|
24
|
+
2. **Use LSP tools** to locate symbols precisely (goToDefinition, findReferences)
|
|
25
|
+
3. **Include unique context** — 2-3 lines before/after for uniqueness
|
|
26
|
+
4. **Prefer smaller files** — <400 lines reduces edit complexity
|
|
27
|
+
5. **Verify after edit** — read back to confirm success
|
|
28
|
+
|
|
29
|
+
### File Size Guidance
|
|
30
|
+
|
|
31
|
+
| Size | Strategy |
|
|
32
|
+
| ------------- | ------------------------------------------ |
|
|
33
|
+
| < 100 lines | Full rewrite often easier than str_replace |
|
|
34
|
+
| 100-400 lines | Structured edit with good context |
|
|
35
|
+
| > 400 lines | Strongly prefer structured edits |
|
|
36
|
+
|
|
37
|
+
**Use the `structured-edit` skill for reliable edits.**
|
|
38
|
+
|
|
39
|
+
### Context Hygiene
|
|
40
|
+
|
|
41
|
+
- Distill large tool outputs immediately after use
|
|
42
|
+
- Prune irrelevant reads before proceeding
|
|
43
|
+
- Token budget: <50k start → 50-100k mid → >150k restart session
|
|
44
|
+
- Subagent outputs can leak tokens — be aggressive about distilling
|
|
45
|
+
|
|
10
46
|
## OpenCode Config
|
|
11
47
|
|
|
12
48
|
- **`compaction` key invalid**: Not in official schema at opencode.ai/config.json. Remove if present.
|
|
Binary file
|
|
Binary file
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
"agent": {
|
|
4
4
|
"build": {
|
|
5
5
|
"description": "Primary development agent with full codebase access",
|
|
6
|
-
"model": "opencode/
|
|
6
|
+
"model": "opencode/minimax-m2.5-free"
|
|
7
7
|
},
|
|
8
8
|
"compaction": {
|
|
9
9
|
"description": "Session summarizer for context continuity across compactions"
|
|
10
10
|
},
|
|
11
11
|
"explore": {
|
|
12
12
|
"description": "Fast codebase search specialist",
|
|
13
|
-
"model": "opencode/minimax-m2.
|
|
13
|
+
"model": "opencode/minimax-m2.5-free"
|
|
14
14
|
},
|
|
15
15
|
"general": {
|
|
16
16
|
"description": "General-purpose subagent for fast, well-defined tasks; delegates complexity quickly",
|
|
17
|
-
"model": "opencode/
|
|
17
|
+
"model": "opencode/minimax-m2.5-free"
|
|
18
18
|
},
|
|
19
19
|
"looker": {
|
|
20
20
|
"description": "Media extraction specialist for images, PDFs, diagrams",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scout": {
|
|
36
36
|
"description": "External research specialist for library docs and patterns",
|
|
37
|
-
"model": "opencode/
|
|
37
|
+
"model": "opencode/kimi-k2.5-free"
|
|
38
38
|
},
|
|
39
39
|
"vision": {
|
|
40
40
|
"description": "Visual content specialist for multimodal analysis and UI/UX guidance",
|
|
@@ -156,6 +156,30 @@
|
|
|
156
156
|
"@franlol/opencode-md-table-formatter@0.0.3"
|
|
157
157
|
],
|
|
158
158
|
"provider": {
|
|
159
|
+
"modal": {
|
|
160
|
+
"options": {
|
|
161
|
+
"baseURL": "https://api.us-west-2.modal.direct/v1",
|
|
162
|
+
"apiKey": "{env:MODAL_API_KEY}"
|
|
163
|
+
},
|
|
164
|
+
"name": "Modal",
|
|
165
|
+
"models": {
|
|
166
|
+
"zai-org/GLM-5-FP8": {
|
|
167
|
+
"name": "GLM-5",
|
|
168
|
+
"reasoning": true,
|
|
169
|
+
"options": {
|
|
170
|
+
"reasoningEffort": "high",
|
|
171
|
+
"reasoningSummary": "true",
|
|
172
|
+
"temperature": 1,
|
|
173
|
+
"top_k": 40,
|
|
174
|
+
"top_p": 0.95,
|
|
175
|
+
"maxOutputTokens": 131072,
|
|
176
|
+
"thinking": {
|
|
177
|
+
"type": "enabled"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
159
183
|
"github-copilot": {
|
|
160
184
|
"models": {
|
|
161
185
|
"claude-haiku-4.5": {
|
|
@@ -997,7 +1021,7 @@
|
|
|
997
1021
|
"options": {
|
|
998
1022
|
"reasoningEffort": "high",
|
|
999
1023
|
"reasoningSummary": "true",
|
|
1000
|
-
"temperature": 1
|
|
1024
|
+
"temperature": 1,
|
|
1001
1025
|
"top_k": 40,
|
|
1002
1026
|
"top_p": 0.95,
|
|
1003
1027
|
"maxOutputTokens": 131072,
|
|
@@ -1,20 +1,47 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: context-management
|
|
3
|
-
description: Use when context is growing large, needing to prune/distill tool outputs, or managing conversation size - covers
|
|
3
|
+
description: Use when context is growing large, needing to prune/distill tool outputs, or managing conversation size - covers DCP slash commands and context budgets
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Context Management
|
|
7
7
|
|
|
8
|
-
Manage conversation context to prevent degradation. Uses
|
|
8
|
+
Manage conversation context to prevent degradation. Uses DCP plugin.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## DCP Integration
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
| --------- | ----------------------------- | ---------------------------------------- |
|
|
14
|
-
| `distill` | Extract key info, then remove | Large outputs with valuable details |
|
|
15
|
-
| `prune` | Remove tool outputs (no save) | Noise, irrelevant reads, superseded info |
|
|
12
|
+
This project uses the **DCP (Dynamic Context Pruning)** plugin. Prefer slash commands over tool calls for better reliability.
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
### Slash Commands (Recommended)
|
|
15
|
+
|
|
16
|
+
| Command | Purpose | When to Use |
|
|
17
|
+
| ----------------------- | ---------------------------------------- | ----------------------------------- |
|
|
18
|
+
| `/dcp compress [focus]` | Collapse conversation range into summary | Phase complete, research done |
|
|
19
|
+
| `/dcp sweep [count]` | Prune all tools since last user message | Cleanup noise, quick prune |
|
|
20
|
+
| `/dcp distill [focus]` | Distill key findings before removing | Large outputs with valuable details |
|
|
21
|
+
| `/dcp context` | Show token breakdown by category | Check context usage |
|
|
22
|
+
| `/dcp stats` | Show cumulative pruning stats | Review efficiency |
|
|
23
|
+
|
|
24
|
+
### Tool Calls (Fallback)
|
|
25
|
+
|
|
26
|
+
Use tool calls when slash commands aren't suitable:
|
|
27
|
+
|
|
28
|
+
| Tool | Purpose | When to Use |
|
|
29
|
+
| ---------- | ----------------------------- | ---------------------------------------- |
|
|
30
|
+
| `distill` | Extract key info, then remove | Large outputs with valuable details |
|
|
31
|
+
| `prune` | Remove tool outputs (no save) | Noise, irrelevant reads, superseded info |
|
|
32
|
+
| `compress` | Collapse conversation range | When slash command fails |
|
|
33
|
+
|
|
34
|
+
**Note:** Compress tool has boundary matching issues. Prefer `/dcp compress` slash command.
|
|
35
|
+
|
|
36
|
+
## DCP Auto-Strategies
|
|
37
|
+
|
|
38
|
+
DCP runs these automatically (zero LLM cost):
|
|
39
|
+
|
|
40
|
+
- **Deduplication** — removes duplicate tool calls (same tool + same args)
|
|
41
|
+
- **Supersede Writes** — removes write inputs when file is later read
|
|
42
|
+
- **Purge Errors** — removes errored tool inputs after 4 turns
|
|
43
|
+
|
|
44
|
+
You don't need to manually prune these.
|
|
18
45
|
|
|
19
46
|
## When to Evaluate
|
|
20
47
|
|
|
@@ -94,8 +121,15 @@ Auto-protected from pruning:
|
|
|
94
121
|
## Quick Reference
|
|
95
122
|
|
|
96
123
|
```
|
|
97
|
-
|
|
98
|
-
|
|
124
|
+
DCP SLASH COMMANDS (preferred):
|
|
125
|
+
/dcp compress [focus] → Collapse range into summary
|
|
126
|
+
/dcp distill [focus] → Distill key findings
|
|
127
|
+
/dcp sweep [count] → Prune all since last user
|
|
128
|
+
/dcp context → Show token breakdown
|
|
129
|
+
|
|
130
|
+
TOOL CALLS (fallback):
|
|
131
|
+
distill({ targets: [{ id, distillation }] })
|
|
132
|
+
prune({ ids: [...] })
|
|
99
133
|
|
|
100
134
|
BUDGET: <50k start → 50-100k mid → >100k distill → >150k restart
|
|
101
135
|
TIMING: Manage at turn START, not turn END
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: obsidian
|
|
3
|
+
description: Use when working with Obsidian vault via MCP - read/write notes, search, tag management, and vault operations
|
|
4
|
+
mcp:
|
|
5
|
+
server: @mauricio.wolff/mcp-obsidian
|
|
6
|
+
args: ["{env:OBSIDIAN_VAULT_PATH}"]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Obsidian Vault (MCP)
|
|
10
|
+
|
|
11
|
+
MCP server for safe Obsidian vault access. Read/write notes, search, manage tags.
|
|
12
|
+
|
|
13
|
+
## Available Tools
|
|
14
|
+
|
|
15
|
+
### Read Operations
|
|
16
|
+
|
|
17
|
+
| Tool | Purpose | Arguments |
|
|
18
|
+
| --------------------- | --------------------------------- | ------------------------------------------------- |
|
|
19
|
+
| `read_note` | Read note with parsed frontmatter | `path`, `prettyPrint` |
|
|
20
|
+
| `read_multiple_notes` | Batch read (max 10) | `paths[]`, `includeContent`, `includeFrontmatter` |
|
|
21
|
+
| `get_frontmatter` | Extract only frontmatter | `path` |
|
|
22
|
+
| `get_notes_info` | Get metadata without content | `paths[]` |
|
|
23
|
+
| `list_directory` | List files and directories | `path` |
|
|
24
|
+
|
|
25
|
+
### Write Operations
|
|
26
|
+
|
|
27
|
+
| Tool | Purpose | Arguments |
|
|
28
|
+
| -------------------- | ------------------------------------- | ---------------------------------------- |
|
|
29
|
+
| `write_note` | Write note (overwrite/append/prepend) | `path`, `content`, `frontmatter`, `mode` |
|
|
30
|
+
| `update_frontmatter` | Update frontmatter only | `path`, `frontmatter`, `merge` |
|
|
31
|
+
| `delete_note` | Delete note (requires confirmation) | `path`, `confirmPath` |
|
|
32
|
+
| `move_note` | Move/rename note | `oldPath`, `newPath`, `overwrite` |
|
|
33
|
+
|
|
34
|
+
### Search & Tags
|
|
35
|
+
|
|
36
|
+
| Tool | Purpose | Arguments |
|
|
37
|
+
| -------------- | ----------------------------- | ------------------------------------------------------ |
|
|
38
|
+
| `search_notes` | Search by content/frontmatter | `query`, `limit`, `searchContent`, `searchFrontmatter` |
|
|
39
|
+
| `manage_tags` | Add/remove/list tags | `path`, `operation`, `tags[]` |
|
|
40
|
+
|
|
41
|
+
## Write Modes
|
|
42
|
+
|
|
43
|
+
| Mode | Description |
|
|
44
|
+
| ----------- | ------------------------------------- |
|
|
45
|
+
| `overwrite` | Replace entire file content (default) |
|
|
46
|
+
| `append` | Add content to end of file |
|
|
47
|
+
| `prepend` | Add content to beginning of file |
|
|
48
|
+
|
|
49
|
+
## Usage Examples
|
|
50
|
+
|
|
51
|
+
### Read Notes
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Read a single note
|
|
55
|
+
skill_mcp({
|
|
56
|
+
skill_name: "obsidian",
|
|
57
|
+
tool_name: "read_note",
|
|
58
|
+
arguments: '{"path": "projects/project-ideas.md"}',
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Read multiple notes
|
|
62
|
+
skill_mcp({
|
|
63
|
+
skill_name: "obsidian",
|
|
64
|
+
tool_name: "read_multiple_notes",
|
|
65
|
+
arguments: '{"paths": ["note1.md", "note2.md"], "includeContent": true}',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// List directory
|
|
69
|
+
skill_mcp({
|
|
70
|
+
skill_name: "obsidian",
|
|
71
|
+
tool_name: "list_directory",
|
|
72
|
+
arguments: '{"path": "Projects"}',
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Write Notes
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// Create new note (overwrite)
|
|
80
|
+
skill_mcp({
|
|
81
|
+
skill_name: "obsidian",
|
|
82
|
+
tool_name: "write_note",
|
|
83
|
+
arguments: `{
|
|
84
|
+
"path": "meeting-notes.md",
|
|
85
|
+
"content": "# Team Meeting\\n\\n## Agenda\\n- Project updates",
|
|
86
|
+
"frontmatter": {"title": "Team Meeting", "date": "2025-02-13", "tags": ["meetings", "team"]},
|
|
87
|
+
"mode": "overwrite"
|
|
88
|
+
}`,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Append to existing note
|
|
92
|
+
skill_mcp({
|
|
93
|
+
skill_name: "obsidian",
|
|
94
|
+
tool_name: "write_note",
|
|
95
|
+
arguments:
|
|
96
|
+
'{"path": "daily-log.md", "content": "\\n\\n## 3:00 PM\\n- Completed review", "mode": "append"}',
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Search & Tags
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// Search notes
|
|
104
|
+
skill_mcp({
|
|
105
|
+
skill_name: "obsidian",
|
|
106
|
+
tool_name: "search_notes",
|
|
107
|
+
arguments: '{"query": "machine learning", "limit": 5, "searchContent": true}',
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Add tags
|
|
111
|
+
skill_mcp({
|
|
112
|
+
skill_name: "obsidian",
|
|
113
|
+
tool_name: "manage_tags",
|
|
114
|
+
arguments: '{"path": "research-notes.md", "operation": "add", "tags": ["important", "ai"]}',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// List tags
|
|
118
|
+
skill_mcp({
|
|
119
|
+
skill_name: "obsidian",
|
|
120
|
+
tool_name: "manage_tags",
|
|
121
|
+
arguments: '{"path": "research-notes.md", "operation": "list"}',
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Delete (Safe)
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Delete requires confirmation (both paths must match)
|
|
129
|
+
skill_mcp({
|
|
130
|
+
skill_name: "obsidian",
|
|
131
|
+
tool_name: "delete_note",
|
|
132
|
+
arguments: '{"path": "old-draft.md", "confirmPath": "old-draft.md"}',
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Configuration
|
|
137
|
+
|
|
138
|
+
### Environment Variable
|
|
139
|
+
|
|
140
|
+
Set your vault path:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
export OBSIDIAN_VAULT_PATH="/path/to/your/obsidian/vault"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Or configure in opencode.json:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcp": {
|
|
151
|
+
"obsidian": {
|
|
152
|
+
"command": "npx",
|
|
153
|
+
"args": ["@mauricio.wolff/mcp-obsidian", "/path/to/vault"]
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Security
|
|
160
|
+
|
|
161
|
+
- Path traversal protection: prevents access outside vault
|
|
162
|
+
- Auto-excludes: `.obsidian`, `.git`, `node_modules`
|
|
163
|
+
- Frontmatter validation: blocks dangerous objects
|
|
164
|
+
- Confirmation required for deletions
|
|
165
|
+
|
|
166
|
+
## Common Use Cases
|
|
167
|
+
|
|
168
|
+
| Task | Tool | Example |
|
|
169
|
+
| -------------------- | ---------------- | ----------------------------------------------------------------------------- |
|
|
170
|
+
| List vault files | `list_directory` | `list_directory({ path: "" })` |
|
|
171
|
+
| Read specific note | `read_note` | `read_note({ path: "tasks/project.md" })` |
|
|
172
|
+
| Create/update note | `write_note` | `write_note({ path: "new.md", content: "...", mode: "overwrite" })` |
|
|
173
|
+
| Search notes | `search_notes` | `search_notes({ query: "API", limit: 10 })` |
|
|
174
|
+
| Add tags | `manage_tags` | `manage_tags({ path: "note.md", operation: "add", tags: ["urgent"] })` |
|
|
175
|
+
| Append to daily note | `write_note` | `write_note({ path: "daily/2025-02-13.md", content: "...", mode: "append" })` |
|
|
176
|
+
|
|
177
|
+
## Tips
|
|
178
|
+
|
|
179
|
+
- Use `prettyPrint: true` for debugging, `false` (default) for production
|
|
180
|
+
- Batch reads with `read_multiple_notes` (max 10)
|
|
181
|
+
- Search supports content and frontmatter filtering
|
|
182
|
+
- Frontmatter is auto-parsed on read
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"obsidian": {
|
|
3
|
+
"command": "npx",
|
|
4
|
+
"args": ["-y", "@mauricio.wolff/mcp-obsidian", "{env:OBSIDIAN_VAULT_PATH}"],
|
|
5
|
+
"env": {
|
|
6
|
+
"OBSIDIAN_VAULT_PATH": "{env:OBSIDIAN_VAULT_PATH}"
|
|
7
|
+
},
|
|
8
|
+
"includeTools": [
|
|
9
|
+
"read_note",
|
|
10
|
+
"read_multiple_notes",
|
|
11
|
+
"get_frontmatter",
|
|
12
|
+
"get_notes_info",
|
|
13
|
+
"list_directory",
|
|
14
|
+
"write_note",
|
|
15
|
+
"update_frontmatter",
|
|
16
|
+
"delete_note",
|
|
17
|
+
"move_note",
|
|
18
|
+
"search_notes",
|
|
19
|
+
"manage_tags"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: structured-edit
|
|
3
|
+
description: Use when editing files to reduce str_replace failures - combines LSP location with read-verify-edit pattern for reliable edits
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Structured Edit Protocol
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The `str_replace` edit tool is the #1 source of failures in LLM coding. Models reproduce content with subtle differences (whitespace, encoding, line endings) causing "string not found" errors.
|
|
11
|
+
|
|
12
|
+
**Core principle:** Don't guess content — locate, read, verify, then edit.
|
|
13
|
+
|
|
14
|
+
## Why This Exists
|
|
15
|
+
|
|
16
|
+
`str_replace` failures happen when:
|
|
17
|
+
|
|
18
|
+
| Cause | Example |
|
|
19
|
+
| -------------------- | ------------------------------------------ |
|
|
20
|
+
| Whitespace mismatch | Tabs vs spaces, trailing spaces |
|
|
21
|
+
| Content changed | File modified since last read |
|
|
22
|
+
| Multiple matches | Same string appears twice in file |
|
|
23
|
+
| Encoding differences | Line endings (CRLF vs LF), invisible chars |
|
|
24
|
+
| Stale context | Editing from memory instead of fresh read |
|
|
25
|
+
|
|
26
|
+
**Result:** Wasted tokens on retries, frustrated developers, broken workflows.
|
|
27
|
+
|
|
28
|
+
## The Protocol
|
|
29
|
+
|
|
30
|
+
### Step 1: LOCATE
|
|
31
|
+
|
|
32
|
+
Use LSP to find exact positions instead of guessing:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// Find where a function is defined
|
|
36
|
+
lsp({ operation: "goToDefinition", filePath, line, character });
|
|
37
|
+
|
|
38
|
+
// Find all references to a symbol
|
|
39
|
+
lsp({ operation: "findReferences", filePath, line, character });
|
|
40
|
+
|
|
41
|
+
// Get all symbols in a file
|
|
42
|
+
lsp({ operation: "documentSymbol", filePath, line: 1, character: 1 });
|
|
43
|
+
|
|
44
|
+
// Search for symbol across workspace
|
|
45
|
+
lsp({ operation: "workspaceSymbol", filePath, line: 1, character: 1 });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Step 2: READ
|
|
49
|
+
|
|
50
|
+
Get fresh file content at the located position:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// Read context around target line
|
|
54
|
+
read({ filePath, offset: line - 10, limit: 30 });
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Always include context** — don't just read the target line.
|
|
58
|
+
|
|
59
|
+
### Step 3: VERIFY
|
|
60
|
+
|
|
61
|
+
Confirm expected content exists at the location:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// Check that what you expect is actually there
|
|
65
|
+
if (!content.includes(expectedSubstring)) {
|
|
66
|
+
// STOP — investigate before proceeding
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 4: EDIT
|
|
71
|
+
|
|
72
|
+
Apply minimal, scoped change with unique context:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// Include enough surrounding lines for uniqueness
|
|
76
|
+
edit({
|
|
77
|
+
filePath,
|
|
78
|
+
oldString: " // unique context before\n targetLine\n // unique context after",
|
|
79
|
+
newString: " // unique context before\n modifiedLine\n // unique context after",
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Guidelines:**
|
|
84
|
+
|
|
85
|
+
- Include 2-3 lines before/after for uniqueness
|
|
86
|
+
- Never use just the target line
|
|
87
|
+
- Keep oldString minimal but unique
|
|
88
|
+
|
|
89
|
+
### Step 5: CONFIRM
|
|
90
|
+
|
|
91
|
+
Verify the edit succeeded:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// Read back the modified section
|
|
95
|
+
read({ filePath, offset: line - 5, limit: 15 });
|
|
96
|
+
|
|
97
|
+
// Confirm content matches intent
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Red Flags — STOP
|
|
101
|
+
|
|
102
|
+
If you catch yourself:
|
|
103
|
+
|
|
104
|
+
- Editing without reading first
|
|
105
|
+
- Assuming content hasn't changed
|
|
106
|
+
- Using large multi-line oldString values
|
|
107
|
+
- Skipping the verify step
|
|
108
|
+
- Guessing line numbers without LSP
|
|
109
|
+
|
|
110
|
+
**STOP.** Return to Step 1.
|
|
111
|
+
|
|
112
|
+
## Best Practices
|
|
113
|
+
|
|
114
|
+
### File Size Matters
|
|
115
|
+
|
|
116
|
+
From research on the "harness problem":
|
|
117
|
+
|
|
118
|
+
| File Size | Strategy |
|
|
119
|
+
| ------------- | ------------------------------------------ |
|
|
120
|
+
| < 100 lines | Full rewrite often easier than str_replace |
|
|
121
|
+
| 100-400 lines | Structured edit with good context |
|
|
122
|
+
| > 400 lines | Strongly prefer structured edits |
|
|
123
|
+
|
|
124
|
+
**Prefer smaller files** — composition over monoliths.
|
|
125
|
+
|
|
126
|
+
### Unique Context Selection
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// BAD: Non-unique, whitespace-sensitive
|
|
130
|
+
oldString: "return result;";
|
|
131
|
+
|
|
132
|
+
// GOOD: Unique with surrounding context
|
|
133
|
+
oldString: " // Calculate final value\n const result = compute(input);\n return result;";
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### When to Use LSP vs Direct
|
|
137
|
+
|
|
138
|
+
| Scenario | Approach |
|
|
139
|
+
| ------------------------- | --------------------- |
|
|
140
|
+
| Finding function/class | LSP goToDefinition |
|
|
141
|
+
| Finding all usages | LSP findReferences |
|
|
142
|
+
| Modifying specific symbol | LSP + structured edit |
|
|
143
|
+
| Large refactoring | Consider full rewrite |
|
|
144
|
+
| Simple one-line change | Direct edit OK |
|
|
145
|
+
|
|
146
|
+
## Integration with Other Skills
|
|
147
|
+
|
|
148
|
+
**Use with:**
|
|
149
|
+
|
|
150
|
+
- `verification-before-completion` — Always verify edits succeeded
|
|
151
|
+
- `systematic-debugging` — When edit failures indicate deeper issues
|
|
152
|
+
- `defense-in-depth` — Add validation after structural changes
|
|
153
|
+
|
|
154
|
+
## Quick Reference
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
LOCATE → lsp({ operation: "goToDefinition" | "findReferences", ... })
|
|
158
|
+
READ → read({ filePath, offset: line-10, limit: 30 })
|
|
159
|
+
VERIFY → Check expected content exists
|
|
160
|
+
EDIT → edit({ oldString: "...unique context...", newString: "..." })
|
|
161
|
+
CONFIRM → read() again to verify success
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## The Bottom Line
|
|
165
|
+
|
|
166
|
+
**Don't trust your memory. Don't guess content. Locate, read, verify, edit, confirm.**
|
|
167
|
+
|
|
168
|
+
This protocol eliminates the #1 source of LLM coding failures.
|
package/package.json
CHANGED