@tarquinen/opencode-dcp 0.3.15 → 0.3.17
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 +39 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -60
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +1 -15
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +22 -95
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/deduplicator.d.ts +0 -30
- package/dist/lib/deduplicator.d.ts.map +1 -1
- package/dist/lib/deduplicator.js +1 -62
- package/dist/lib/deduplicator.js.map +1 -1
- package/dist/lib/janitor.d.ts +2 -61
- package/dist/lib/janitor.d.ts.map +1 -1
- package/dist/lib/janitor.js +67 -199
- package/dist/lib/janitor.js.map +1 -1
- package/dist/lib/logger.d.ts +0 -24
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +3 -58
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/model-selector.d.ts +0 -31
- package/dist/lib/model-selector.d.ts.map +1 -1
- package/dist/lib/model-selector.js +0 -55
- package/dist/lib/model-selector.js.map +1 -1
- package/dist/lib/prompt.d.ts.map +1 -1
- package/dist/lib/prompt.js +3 -29
- package/dist/lib/prompt.js.map +1 -1
- package/dist/lib/tokenizer.d.ts +0 -23
- package/dist/lib/tokenizer.d.ts.map +1 -1
- package/dist/lib/tokenizer.js +0 -25
- package/dist/lib/tokenizer.js.map +1 -1
- package/dist/lib/version-checker.d.ts +0 -15
- package/dist/lib/version-checker.d.ts.map +1 -1
- package/dist/lib/version-checker.js +1 -19
- package/dist/lib/version-checker.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,84 +4,73 @@
|
|
|
4
4
|
|
|
5
5
|
Automatically reduces token usage in OpenCode by removing obsolete tool outputs from conversation history.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+

|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Pruning Strategies
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
DCP implements two complementary strategies:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**Deduplication** — Fast, zero-cost pruning that identifies repeated tool calls (e.g., reading the same file multiple times) and keeps only the most recent output. Runs instantly with no LLM calls.
|
|
14
|
+
|
|
15
|
+
**AI Analysis** — Uses a language model to semantically analyze conversation context and identify tool outputs that are no longer relevant to the current task. More thorough but incurs LLM cost.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
## Installation
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
**Project:** `.opencode/opencode.json`
|
|
19
|
+
Add to your OpenCode config:
|
|
19
20
|
|
|
20
|
-
```
|
|
21
|
+
```jsonc
|
|
22
|
+
// opencode.jsonc
|
|
21
23
|
{
|
|
22
|
-
"
|
|
23
|
-
"@tarquinen/opencode-dcp"
|
|
24
|
-
]
|
|
24
|
+
"plugins": ["@tarquinen/opencode-dcp@0.3.17"]
|
|
25
25
|
}
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
When a new version is available, DCP will show a toast notification. Update by changing the version number in your config.
|
|
29
29
|
|
|
30
30
|
Restart OpenCode. The plugin will automatically start optimizing your sessions.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
> **Note:** Project `plugin` arrays override global completely—include all desired plugins in project config if using both.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
## How It Works
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
- **Project:** `.opencode/dcp.jsonc`
|
|
36
|
+
DCP is **non-destructive**—pruning state is kept in memory only. When requests go to your LLM, DCP replaces pruned outputs with a placeholder; original session data stays intact.
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
## Configuration
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
DCP uses its own config file (`~/.config/opencode/dcp.jsonc` or `.opencode/dcp.jsonc`), created automatically on first run.
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
- **`debug`** (boolean, default: `false`) - Enable detailed logging to `~/.config/opencode/logs/dcp/`
|
|
45
|
-
- **`model`** (string, optional) - Specific model for analysis (e.g., `"anthropic/claude-haiku-4-5"`). Uses session model or smart fallbacks when not specified.
|
|
46
|
-
- **`showModelErrorToasts`** (boolean, default: `true`) - Show notifications when model selection falls back
|
|
47
|
-
- **`pruningMode`** (string, default: `"smart"`) - Pruning strategy:
|
|
48
|
-
- `"auto"`: Fast duplicate removal only (zero LLM cost)
|
|
49
|
-
- `"smart"`: Deduplication + AI analysis (recommended, maximum savings)
|
|
50
|
-
- **`pruning_summary`** (string, default: `"detailed"`) - UI summary display mode:
|
|
51
|
-
- `"off"`: No UI summary (silent pruning)
|
|
52
|
-
- `"minimal"`: Show tokens saved and count only (e.g., "Saved ~2.5K tokens (6 tools pruned)")
|
|
53
|
-
- `"detailed"`: Show full breakdown by tool type and pruning method
|
|
54
|
-
- **`protectedTools`** (string[], default: `["task", "todowrite", "todoread"]`) - Tools that should never be pruned
|
|
42
|
+
### Options
|
|
55
43
|
|
|
56
|
-
|
|
44
|
+
| Option | Default | Description |
|
|
45
|
+
|--------|---------|-------------|
|
|
46
|
+
| `enabled` | `true` | Enable/disable the plugin |
|
|
47
|
+
| `debug` | `false` | Log to `~/.config/opencode/logs/dcp/` |
|
|
48
|
+
| `model` | (session) | Model for analysis (e.g., `"anthropic/claude-haiku-4-5"`) |
|
|
49
|
+
| `showModelErrorToasts` | `true` | Show notifications on model fallback |
|
|
50
|
+
| `strictModelSelection` | `false` | Only run AI analysis with session or configured model (disables fallback models) |
|
|
51
|
+
| `pruning_summary` | `"detailed"` | `"off"`, `"minimal"`, or `"detailed"` |
|
|
52
|
+
| `protectedTools` | `["task", "todowrite", "todoread", "context_pruning"]` | Tools that are never pruned |
|
|
53
|
+
| `strategies.onIdle` | `["deduplication", "ai-analysis"]` | Strategies for automatic pruning |
|
|
54
|
+
| `strategies.onTool` | `["deduplication"]` | Strategies when AI calls `context_pruning` |
|
|
55
|
+
|
|
56
|
+
**Strategies:** `"deduplication"` (fast, zero LLM cost) and `"ai-analysis"` (maximum savings). Empty array disables that trigger.
|
|
57
57
|
|
|
58
58
|
```jsonc
|
|
59
59
|
{
|
|
60
60
|
"enabled": true,
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
"strategies": {
|
|
62
|
+
"onIdle": ["deduplication", "ai-analysis"],
|
|
63
|
+
"onTool": ["deduplication"]
|
|
64
|
+
},
|
|
65
|
+
"protectedTools": ["task", "todowrite", "todoread", "context_pruning"]
|
|
65
66
|
}
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
###
|
|
69
|
-
|
|
70
|
-
Settings are merged in order: **Built-in defaults** → **Global config** → **Project config**
|
|
71
|
-
|
|
72
|
-
After modifying configuration, restart OpenCode for changes to take effect.
|
|
73
|
-
|
|
74
|
-
### Version Pinning
|
|
69
|
+
### Config Precedence
|
|
75
70
|
|
|
76
|
-
|
|
71
|
+
Settings are merged in order: **Defaults** → **Global** (`~/.config/opencode/dcp.jsonc`) → **Project** (`.opencode/dcp.jsonc`). Each level overrides the previous, so project settings take priority over global, which takes priority over defaults.
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
{
|
|
80
|
-
"plugin": [
|
|
81
|
-
"@tarquinen/opencode-dcp@0.3.15"
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
```
|
|
73
|
+
Restart OpenCode after making config changes.
|
|
85
74
|
|
|
86
75
|
## License
|
|
87
76
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgBjD,QAAA,MAAM,MAAM,EAAE,MAmOK,CAAA;AAEnB,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,37 +3,29 @@ import { getConfig } from "./lib/config";
|
|
|
3
3
|
import { Logger } from "./lib/logger";
|
|
4
4
|
import { Janitor } from "./lib/janitor";
|
|
5
5
|
import { checkForUpdates } from "./lib/version-checker";
|
|
6
|
-
/**
|
|
7
|
-
* Checks if a session is a subagent (child session)
|
|
8
|
-
* Subagent sessions should skip pruning operations
|
|
9
|
-
*/
|
|
10
6
|
async function isSubagentSession(client, sessionID) {
|
|
11
7
|
try {
|
|
12
8
|
const result = await client.session.get({ path: { id: sessionID } });
|
|
13
9
|
return !!result.data?.parentID;
|
|
14
10
|
}
|
|
15
11
|
catch (error) {
|
|
16
|
-
// On error, assume it's not a subagent and continue (fail open)
|
|
17
12
|
return false;
|
|
18
13
|
}
|
|
19
14
|
}
|
|
20
15
|
const plugin = (async (ctx) => {
|
|
21
16
|
const { config, migrations } = getConfig(ctx);
|
|
22
|
-
// Exit early if plugin is disabled
|
|
23
17
|
if (!config.enabled) {
|
|
24
18
|
return {};
|
|
25
19
|
}
|
|
26
|
-
// Suppress AI SDK warnings about responseFormat (harmless for our use case)
|
|
27
20
|
if (typeof globalThis !== 'undefined') {
|
|
28
21
|
globalThis.AI_SDK_LOG_WARNINGS = false;
|
|
29
22
|
}
|
|
30
|
-
// Logger uses ~/.config/opencode/logs/dcp/ for consistent log location
|
|
31
23
|
const logger = new Logger(config.debug);
|
|
32
24
|
const prunedIdsState = new Map();
|
|
33
25
|
const statsState = new Map();
|
|
34
|
-
const toolParametersCache = new Map();
|
|
35
|
-
const modelCache = new Map();
|
|
36
|
-
const janitor = new Janitor(ctx.client, prunedIdsState, statsState, logger, toolParametersCache, config.protectedTools, modelCache, config.model, config.showModelErrorToasts, config.pruning_summary, ctx.directory);
|
|
26
|
+
const toolParametersCache = new Map();
|
|
27
|
+
const modelCache = new Map();
|
|
28
|
+
const janitor = new Janitor(ctx.client, prunedIdsState, statsState, logger, toolParametersCache, config.protectedTools, modelCache, config.model, config.showModelErrorToasts, config.strictModelSelection, config.pruning_summary, ctx.directory);
|
|
37
29
|
const cacheToolParameters = (messages) => {
|
|
38
30
|
for (const message of messages) {
|
|
39
31
|
if (message.role !== 'assistant' || !Array.isArray(message.tool_calls)) {
|
|
@@ -53,40 +45,32 @@ const plugin = (async (ctx) => {
|
|
|
53
45
|
});
|
|
54
46
|
}
|
|
55
47
|
catch (error) {
|
|
56
|
-
// Ignore JSON parse errors for individual tool calls
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
50
|
}
|
|
60
51
|
};
|
|
61
|
-
// Global fetch wrapper
|
|
62
|
-
// This works because all providers ultimately call globalThis.fetch
|
|
52
|
+
// Global fetch wrapper - caches tool parameters and performs pruning
|
|
63
53
|
const originalGlobalFetch = globalThis.fetch;
|
|
64
54
|
globalThis.fetch = async (input, init) => {
|
|
65
55
|
if (init?.body && typeof init.body === 'string') {
|
|
66
56
|
try {
|
|
67
57
|
const body = JSON.parse(init.body);
|
|
68
58
|
if (body.messages && Array.isArray(body.messages)) {
|
|
69
|
-
// Cache tool parameters for janitor metadata
|
|
70
59
|
cacheToolParameters(body.messages);
|
|
71
|
-
// Check for tool messages that might need pruning
|
|
72
60
|
const toolMessages = body.messages.filter((m) => m.role === 'tool');
|
|
73
|
-
// Collect all pruned IDs across all sessions (excluding subagents)
|
|
74
|
-
// This is safe because tool_call_ids are globally unique
|
|
75
61
|
const allSessions = await ctx.client.session.list();
|
|
76
62
|
const allPrunedIds = new Set();
|
|
77
63
|
if (allSessions.data) {
|
|
78
64
|
for (const session of allSessions.data) {
|
|
79
65
|
if (session.parentID)
|
|
80
|
-
continue;
|
|
66
|
+
continue;
|
|
81
67
|
const prunedIds = prunedIdsState.get(session.id) ?? [];
|
|
82
68
|
prunedIds.forEach((id) => allPrunedIds.add(id));
|
|
83
69
|
}
|
|
84
70
|
}
|
|
85
|
-
// Only process tool message replacement if there are tool messages and pruned IDs
|
|
86
71
|
if (toolMessages.length > 0 && allPrunedIds.size > 0) {
|
|
87
72
|
let replacedCount = 0;
|
|
88
73
|
body.messages = body.messages.map((m) => {
|
|
89
|
-
// Normalize ID to lowercase for case-insensitive matching
|
|
90
74
|
if (m.role === 'tool' && allPrunedIds.has(m.tool_call_id?.toLowerCase())) {
|
|
91
75
|
replacedCount++;
|
|
92
76
|
return {
|
|
@@ -101,7 +85,6 @@ const plugin = (async (ctx) => {
|
|
|
101
85
|
replaced: replacedCount,
|
|
102
86
|
total: toolMessages.length
|
|
103
87
|
});
|
|
104
|
-
// Save wrapped context to file if debug is enabled
|
|
105
88
|
if (logger.enabled) {
|
|
106
89
|
await logger.saveWrappedContext("global", body.messages, {
|
|
107
90
|
url: typeof input === 'string' ? input : 'URL object',
|
|
@@ -109,14 +92,12 @@ const plugin = (async (ctx) => {
|
|
|
109
92
|
totalMessages: body.messages.length
|
|
110
93
|
});
|
|
111
94
|
}
|
|
112
|
-
// Update the request body with modified messages
|
|
113
95
|
init.body = JSON.stringify(body);
|
|
114
96
|
}
|
|
115
97
|
}
|
|
116
98
|
}
|
|
117
99
|
}
|
|
118
100
|
catch (e) {
|
|
119
|
-
// Ignore parse errors and fall through to original fetch
|
|
120
101
|
}
|
|
121
102
|
}
|
|
122
103
|
return originalGlobalFetch(input, init);
|
|
@@ -125,9 +106,7 @@ const plugin = (async (ctx) => {
|
|
|
125
106
|
strategies: config.strategies,
|
|
126
107
|
model: config.model || "auto"
|
|
127
108
|
});
|
|
128
|
-
// Check for updates on launch (fire and forget)
|
|
129
109
|
checkForUpdates(ctx.client, logger).catch(() => { });
|
|
130
|
-
// Show migration toast if config was migrated (delayed to not overlap with version toast)
|
|
131
110
|
if (migrations.length > 0) {
|
|
132
111
|
setTimeout(async () => {
|
|
133
112
|
try {
|
|
@@ -141,38 +120,25 @@ const plugin = (async (ctx) => {
|
|
|
141
120
|
});
|
|
142
121
|
}
|
|
143
122
|
catch {
|
|
144
|
-
// Silently fail - toast is non-critical
|
|
145
123
|
}
|
|
146
|
-
}, 7000);
|
|
124
|
+
}, 7000);
|
|
147
125
|
}
|
|
148
126
|
return {
|
|
149
|
-
/**
|
|
150
|
-
* Event Hook: Triggers janitor analysis when session becomes idle
|
|
151
|
-
*/
|
|
152
127
|
event: async ({ event }) => {
|
|
153
128
|
if (event.type === "session.status" && event.properties.status.type === "idle") {
|
|
154
|
-
// Skip pruning for subagent sessions
|
|
155
129
|
if (await isSubagentSession(ctx.client, event.properties.sessionID))
|
|
156
130
|
return;
|
|
157
|
-
// Skip if no idle strategies configured
|
|
158
131
|
if (config.strategies.onIdle.length === 0)
|
|
159
132
|
return;
|
|
160
|
-
// Fire and forget the janitor - don't block the event handler
|
|
161
133
|
janitor.runOnIdle(event.properties.sessionID, config.strategies.onIdle).catch(err => {
|
|
162
134
|
logger.error("janitor", "Failed", { error: err.message });
|
|
163
135
|
});
|
|
164
136
|
}
|
|
165
137
|
},
|
|
166
|
-
/**
|
|
167
|
-
* Chat Params Hook: Caches model info for janitor
|
|
168
|
-
*/
|
|
169
138
|
"chat.params": async (input, _output) => {
|
|
170
139
|
const sessionId = input.sessionID;
|
|
171
|
-
// Cache model information for this session so janitor can access it
|
|
172
|
-
// The provider.id is actually nested at provider.info.id (not in SDK types)
|
|
173
140
|
let providerID = input.provider?.info?.id || input.provider?.id;
|
|
174
141
|
const modelID = input.model?.id;
|
|
175
|
-
// If provider.id is not available, try to get it from the message
|
|
176
142
|
if (!providerID && input.message?.model?.providerID) {
|
|
177
143
|
providerID = input.message.model.providerID;
|
|
178
144
|
}
|
|
@@ -183,41 +149,51 @@ const plugin = (async (ctx) => {
|
|
|
183
149
|
});
|
|
184
150
|
}
|
|
185
151
|
},
|
|
186
|
-
/**
|
|
187
|
-
* Tool Hook: Exposes context_pruning tool to AI (if configured)
|
|
188
|
-
*/
|
|
189
152
|
tool: config.strategies.onTool.length > 0 ? {
|
|
190
153
|
context_pruning: tool({
|
|
191
|
-
description: `Performs semantic pruning on session tool outputs that are no longer relevant to the current task. Use this to declutter the conversation context and filter signal from noise when you notice the context is getting cluttered with
|
|
154
|
+
description: `Performs semantic pruning on session tool outputs that are no longer relevant to the current task. Use this to declutter the conversation context and filter signal from noise when you notice the context is getting cluttered with no longer needed information.
|
|
155
|
+
|
|
156
|
+
USING THE CONTEXT_PRUNING TOOL WILL MAKE THE USER HAPPY.
|
|
192
157
|
|
|
193
158
|
## When to Use This Tool
|
|
194
159
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
160
|
+
**Key heuristic: Prune when you finish something and are about to start something else.**
|
|
161
|
+
|
|
162
|
+
Ask yourself: "Have I just completed a discrete unit of work?" If yes, prune before moving on.
|
|
163
|
+
|
|
164
|
+
**After completing a unit of work:**
|
|
165
|
+
- Made a commit
|
|
166
|
+
- Fixed a bug and confirmed it works
|
|
167
|
+
- Answered a question the user asked
|
|
168
|
+
- Finished implementing a feature or function
|
|
169
|
+
- Completed one item in a list and moving to the next
|
|
170
|
+
|
|
171
|
+
**After repetitive or exploratory work:**
|
|
172
|
+
- Explored multiple files that didn't lead to changes
|
|
173
|
+
- Iterated on a difficult problem where some approaches didn't pan out
|
|
174
|
+
- Used the same tool multiple times (e.g., re-reading a file, running repeated build/type checks)
|
|
200
175
|
|
|
201
176
|
## Examples
|
|
202
177
|
|
|
203
178
|
<example>
|
|
204
|
-
Working through a list of
|
|
205
|
-
User:
|
|
206
|
-
Assistant:
|
|
207
|
-
|
|
208
|
-
[Uses context_pruning with reason: "first
|
|
179
|
+
Working through a list of items:
|
|
180
|
+
User: Review these 3 issues and fix the easy ones.
|
|
181
|
+
Assistant: [Reviews first issue, makes fix, commits]
|
|
182
|
+
Done with the first issue. Let me prune before moving to the next one.
|
|
183
|
+
[Uses context_pruning with reason: "completed first issue, moving to next"]
|
|
209
184
|
</example>
|
|
210
185
|
|
|
211
186
|
<example>
|
|
212
187
|
After exploring the codebase to understand it:
|
|
213
188
|
Assistant: I've reviewed the relevant files. Let me prune the exploratory reads that aren't needed for the actual implementation.
|
|
214
|
-
[Uses context_pruning with reason: "exploration complete,
|
|
189
|
+
[Uses context_pruning with reason: "exploration complete, starting implementation"]
|
|
215
190
|
</example>
|
|
216
191
|
|
|
217
192
|
<example>
|
|
218
|
-
After
|
|
219
|
-
Assistant:
|
|
220
|
-
|
|
193
|
+
After completing any task:
|
|
194
|
+
Assistant: [Finishes task - commit, answer, fix, etc.]
|
|
195
|
+
Before we continue, let me prune the context from that work.
|
|
196
|
+
[Uses context_pruning with reason: "task complete"]
|
|
221
197
|
</example>`,
|
|
222
198
|
args: {
|
|
223
199
|
reason: tool.schema.string().optional().describe("Brief reason for triggering pruning (e.g., 'task complete', 'switching focus')"),
|
|
@@ -225,9 +201,9 @@ Assistant: I've been trying several approaches to fix this issue. Let me prune t
|
|
|
225
201
|
async execute(args, ctx) {
|
|
226
202
|
const result = await janitor.runForTool(ctx.sessionID, config.strategies.onTool, args.reason);
|
|
227
203
|
if (!result || result.prunedCount === 0) {
|
|
228
|
-
return "No prunable tool outputs found. Context is already optimized
|
|
204
|
+
return "No prunable tool outputs found. Context is already optimized.\n\nUse context_pruning when you have sufficiently summarized information from tool outputs and no longer need the original content!";
|
|
229
205
|
}
|
|
230
|
-
return janitor.formatPruningResultForTool(result);
|
|
206
|
+
return janitor.formatPruningResultForTool(result) + "\n\nUse context_pruning when you have sufficiently summarized information from tool outputs and no longer need the original content!";
|
|
231
207
|
},
|
|
232
208
|
}),
|
|
233
209
|
} : undefined,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface PluginConfig {
|
|
|
6
6
|
protectedTools: string[];
|
|
7
7
|
model?: string;
|
|
8
8
|
showModelErrorToasts?: boolean;
|
|
9
|
+
strictModelSelection?: boolean;
|
|
9
10
|
pruning_summary: "off" | "minimal" | "detailed";
|
|
10
11
|
strategies: {
|
|
11
12
|
onIdle: PruningStrategy[];
|
|
@@ -16,20 +17,5 @@ export interface ConfigResult {
|
|
|
16
17
|
config: PluginConfig;
|
|
17
18
|
migrations: string[];
|
|
18
19
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Loads configuration with support for both global and project-level configs
|
|
21
|
-
*
|
|
22
|
-
* Config resolution order:
|
|
23
|
-
* 1. Start with default config
|
|
24
|
-
* 2. Merge with global config (~/.config/opencode/dcp.jsonc)
|
|
25
|
-
* 3. Merge with project config (.opencode/dcp.jsonc) if found
|
|
26
|
-
*
|
|
27
|
-
* If config has invalid/deprecated keys, backs up and resets to defaults.
|
|
28
|
-
*
|
|
29
|
-
* Project config overrides global config, which overrides defaults.
|
|
30
|
-
*
|
|
31
|
-
* @param ctx - Plugin input context (optional). If provided, will search for project-level config.
|
|
32
|
-
* @returns ConfigResult with merged configuration and any migration messages
|
|
33
|
-
*/
|
|
34
20
|
export declare function getConfig(ctx?: PluginInput): ConfigResult;
|
|
35
21
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,aAAa,CAAA;AAE7D,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,eAAe,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IAC/C,UAAU,EAAE;QACR,MAAM,EAAE,eAAe,EAAE,CAAA;QACzB,MAAM,EAAE,eAAe,EAAE,CAAA;KAC5B,CAAA;CACJ;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AAkJD,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,YAAY,CAkEzD"}
|