opencodekit 0.17.3 → 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.
@@ -11,7 +11,7 @@
11
11
  "type-check": "tsc --noEmit"
12
12
  },
13
13
  "dependencies": {
14
- "@opencode-ai/plugin": "1.1.60"
14
+ "@opencode-ai/plugin": "1.1.62"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/node": "^25.1.0",
@@ -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 distill and prune tools with context budgets
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 distill and prune tools.
8
+ Manage conversation context to prevent degradation. Uses DCP plugin.
9
9
 
10
- ## The Two Tools
10
+ ## DCP Integration
11
11
 
12
- | Tool | Purpose | When to Use |
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
- **Distill is the favored tool.** It preserves knowledge while freeing context. Prune is for pure noise removal.
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
- DISTILL: Save + remove → distill({ targets: [{ id, distillation }] })
98
- PRUNE: Remove noiseprune({ ids: [...] })
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.17.3",
3
+ "version": "0.17.4",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
6
6
  "license": "MIT",